From 41a32b08f2c05b90991f12c612cef108faebe877 Mon Sep 17 00:00:00 2001 From: Yoga Pangestu Date: Sat, 15 Aug 2026 14:59:06 +0700 Subject: [PATCH] feat: refactor getForRestock and getForTransaction methods to improve media handling and streamline data retrieval --- .../Master/Product/ProductVariantService.php | 85 +++++++++++++------ 1 file changed, 57 insertions(+), 28 deletions(-) diff --git a/app/Services/Admin/Master/Product/ProductVariantService.php b/app/Services/Admin/Master/Product/ProductVariantService.php index c3a1bbd..8850688 100644 --- a/app/Services/Admin/Master/Product/ProductVariantService.php +++ b/app/Services/Admin/Master/Product/ProductVariantService.php @@ -14,6 +14,7 @@ use App\Services\StockMutationService; use Illuminate\Support\Facades\DB; use Illuminate\Validation\ValidationException; +use Spatie\MediaLibrary\MediaCollections\Models\Media; class ProductVariantService { @@ -26,7 +27,7 @@ public function __construct( public function getForRestock(): array { - return Product::query() + $products = Product::query() ->select(['id', 'name', 'status']) ->with([ 'productVariants:id,product_id,name,stock,reject_stock', @@ -34,28 +35,42 @@ public function getForRestock(): array ]) ->active() ->orderBy('name') - ->get() - ->each(function (Product $product) { - $product->productVariants->each(function (ProductVariant $variant) { - $media = $variant->getFirstMedia('images'); - $variant->photo_url = $media - ? $this->s3Service->getTemporaryUrl($media->getPath()) - : null; + ->get(); - $capitalPrice = $variant->productPrices - ->first(fn ($price) => $price->type === PriceType::CAPITAL); - $variant->capital_price = $capitalPrice?->price ?? 0; + $allVariantIds = $products->pluck('productVariants.*.id')->flatten()->filter()->all(); - $rejectPrice = $variant->productPrices - ->first(fn ($price) => $price->type === PriceType::REJECT); - $variant->reject_price = $rejectPrice?->price ?? 0; - }); - })->toArray(); + if ($allVariantIds !== []) { + $mediaByVariant = Media::query() + ->whereIn('mediable_id', $allVariantIds) + ->where('mediable_type', ProductVariant::class) + ->where('collection_name', 'images') + ->get() + ->groupBy('mediable_id'); + } else { + $mediaByVariant = collect(); + } + + return $products->each(function (Product $product) use ($mediaByVariant) { + $product->productVariants->each(function (ProductVariant $variant) use ($mediaByVariant) { + $media = $mediaByVariant->get($variant->id, collect())->first(); + $variant->photo_url = $media + ? $this->s3Service->getTemporaryUrl($media->getPath()) + : null; + + $capitalPrice = $variant->productPrices + ->first(fn ($price) => $price->type === PriceType::CAPITAL); + $variant->capital_price = $capitalPrice?->price ?? 0; + + $rejectPrice = $variant->productPrices + ->first(fn ($price) => $price->type === PriceType::REJECT); + $variant->reject_price = $rejectPrice?->price ?? 0; + }); + })->toArray(); } public function getForTransaction(): array { - return Product::query() + $products = Product::query() ->select(['id', 'name', 'status']) ->with([ 'productVariants:id,product_id,name,stock,reject_stock', @@ -63,18 +78,32 @@ public function getForTransaction(): array ]) ->active() ->orderBy('name') - ->get() - ->each(function (Product $product) { - $product->productVariants->each(function (ProductVariant $variant) { - $media = $variant->getFirstMedia('images'); - $variant->photo_url = $media - ? $this->s3Service->getTemporaryUrl($media->getPath()) - : null; + ->get(); - $prices = $variant->productPrices->mapWithKeys(fn ($p) => [$p->type->value => $p->price]); - $variant->prices = $prices; - }); - })->toArray(); + $allVariantIds = $products->pluck('productVariants.*.id')->flatten()->filter()->all(); + + if ($allVariantIds !== []) { + $mediaByVariant = Media::query() + ->whereIn('mediable_id', $allVariantIds) + ->where('mediable_type', ProductVariant::class) + ->where('collection_name', 'images') + ->get() + ->groupBy('mediable_id'); + } else { + $mediaByVariant = collect(); + } + + return $products->each(function (Product $product) use ($mediaByVariant) { + $product->productVariants->each(function (ProductVariant $variant) use ($mediaByVariant) { + $media = $mediaByVariant->get($variant->id, collect())->first(); + $variant->photo_url = $media + ? $this->s3Service->getTemporaryUrl($media->getPath()) + : null; + + $prices = $variant->productPrices->mapWithKeys(fn ($p) => [$p->type->value => $p->price]); + $variant->prices = $prices; + }); + })->toArray(); } public function getForEdit(ProductVariant $variant): array