refactor: update price handling in CuttingResultPriceResolver and HomepageService for improved data structure and consistency
This commit is contained in:
parent
38d6f3a22b
commit
bd51f9abe0
@ -53,7 +53,11 @@ public function latestPricesForVariant(int $productVariantId): array
|
||||
$price = $this->resolve($productVariantId, $priceType);
|
||||
|
||||
if ($price !== null) {
|
||||
$prices[] = $price;
|
||||
$prices[] = [
|
||||
'price_type' => $price->price_type->value,
|
||||
'price' => (int) $price->price,
|
||||
'price_formatted' => $price->price_formatted,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,9 +67,9 @@ public function latestPricesForVariant(int $productVariantId): array
|
||||
|
||||
public function latestPricesForVariants(array $variantIds): Collection
|
||||
{
|
||||
return $this->cacheRemember('prices:variants:'.md5(implode(',', $variantIds)), 900, function () use ($variantIds) {
|
||||
$cached = $this->cacheRemember('prices:variants:'.md5(implode(',', $variantIds)), 900, function () use ($variantIds) {
|
||||
if (empty($variantIds)) {
|
||||
return collect();
|
||||
return [];
|
||||
}
|
||||
|
||||
$cuttingPrices = CuttingResultPrice::query()
|
||||
@ -83,24 +87,34 @@ public function latestPricesForVariants(array $variantIds): Collection
|
||||
->get()
|
||||
->groupBy(fn (ProductPrice $price) => $price->variant_id.'-'.$price->type->value);
|
||||
|
||||
$results = collect();
|
||||
// Store only plain arrays — never Eloquent models — to avoid
|
||||
// __PHP_Incomplete_Class when Redis deserializes across requests.
|
||||
$results = [];
|
||||
foreach ($variantIds as $variantId) {
|
||||
foreach (PriceType::cases() as $priceType) {
|
||||
$key = $variantId.'-'.$priceType->value;
|
||||
if ($cuttingPrices->has($key)) {
|
||||
$results->push($cuttingPrices->get($key));
|
||||
$cp = $cuttingPrices->get($key);
|
||||
$results[$variantId][] = [
|
||||
'price_type' => $cp->price_type->value,
|
||||
'price' => (int) $cp->price,
|
||||
'price_formatted' => $cp->price_formatted,
|
||||
];
|
||||
} elseif ($productPrices->has($key)) {
|
||||
$pp = $productPrices->get($key)->first();
|
||||
$cp = new CuttingResultPrice;
|
||||
$cp->product_variant_id = $variantId;
|
||||
$cp->price_type = $priceType;
|
||||
$cp->price = $pp->price;
|
||||
$results->push($cp);
|
||||
$results[$variantId][] = [
|
||||
'price_type' => $priceType->value,
|
||||
'price' => (int) $pp->price,
|
||||
'price_formatted' => 'Rp '.number_format((int) $pp->price, 0, ',', '.'),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $results->groupBy('product_variant_id');
|
||||
return $results;
|
||||
});
|
||||
|
||||
// Rebuild as a Collection keyed by variant ID (matching original contract)
|
||||
return collect(is_array($cached) ? $cached : [])->map(fn ($prices) => collect($prices));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Services\System;
|
||||
|
||||
use App\Enums\PriceType;
|
||||
use App\Models\Category;
|
||||
use App\Models\Product;
|
||||
use App\Models\SystemConfiguration;
|
||||
@ -51,7 +52,7 @@ public function pageData(): array
|
||||
});
|
||||
}
|
||||
|
||||
private function getProducts()
|
||||
private function getProducts(): array
|
||||
{
|
||||
$products = Product::getActiveWithVariantsAndCategories();
|
||||
|
||||
@ -61,22 +62,39 @@ private function getProducts()
|
||||
|
||||
$allPricesByVariant = $this->cuttingResultPriceResolver->latestPricesForVariants($allVariantIds);
|
||||
|
||||
// Convert entirely to plain arrays — never store Eloquent models in
|
||||
// Redis, as PHP serialize/unserialize can produce __PHP_Incomplete_Class
|
||||
// and json_encode may produce {} instead of [] for keyed collections.
|
||||
return $products->map(function ($product) use ($allPricesByVariant) {
|
||||
$product->variants->each(function ($variant) use ($allPricesByVariant) {
|
||||
$variant->setAttribute('images', MediaPresenter::collection($variant, 'images'));
|
||||
$variants = $product->variants->map(function ($variant) use ($allPricesByVariant) {
|
||||
$variantPrices = $allPricesByVariant->get($variant->id, collect());
|
||||
$variant->setAttribute(
|
||||
'prices',
|
||||
$variantPrices->map(fn ($price) => [
|
||||
'type' => $price->price_type->value,
|
||||
'type_label' => $price->price_type->label(),
|
||||
'price' => (int) $price->price,
|
||||
'price_formatted' => $price->price_formatted,
|
||||
])->values()->all(),
|
||||
);
|
||||
});
|
||||
|
||||
return $product;
|
||||
})->values();
|
||||
return [
|
||||
'id' => $variant->id,
|
||||
'name' => $variant->name,
|
||||
'stock' => $variant->stock,
|
||||
'images' => MediaPresenter::collection($variant, 'images'),
|
||||
'prices' => $variantPrices->map(fn ($price) => [
|
||||
'type' => $price['price_type'],
|
||||
'type_label' => PriceType::from($price['price_type'])->label(),
|
||||
'price' => $price['price'],
|
||||
'price_formatted' => $price['price_formatted'],
|
||||
])->values()->all(),
|
||||
];
|
||||
})->values()->all();
|
||||
|
||||
return [
|
||||
'id' => $product->id,
|
||||
'name' => $product->name,
|
||||
'description' => $product->description,
|
||||
'slug' => $product->slug ?? null,
|
||||
'categories' => $product->categories->map(fn ($cat) => [
|
||||
'id' => $cat->id,
|
||||
'name' => $cat->name,
|
||||
'slug' => $cat->slug,
|
||||
])->values()->all(),
|
||||
'variants' => $variants,
|
||||
];
|
||||
})->values()->all();
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user