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);
|
$price = $this->resolve($productVariantId, $priceType);
|
||||||
|
|
||||||
if ($price !== null) {
|
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
|
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)) {
|
if (empty($variantIds)) {
|
||||||
return collect();
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
$cuttingPrices = CuttingResultPrice::query()
|
$cuttingPrices = CuttingResultPrice::query()
|
||||||
@ -83,24 +87,34 @@ public function latestPricesForVariants(array $variantIds): Collection
|
|||||||
->get()
|
->get()
|
||||||
->groupBy(fn (ProductPrice $price) => $price->variant_id.'-'.$price->type->value);
|
->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 ($variantIds as $variantId) {
|
||||||
foreach (PriceType::cases() as $priceType) {
|
foreach (PriceType::cases() as $priceType) {
|
||||||
$key = $variantId.'-'.$priceType->value;
|
$key = $variantId.'-'.$priceType->value;
|
||||||
if ($cuttingPrices->has($key)) {
|
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)) {
|
} elseif ($productPrices->has($key)) {
|
||||||
$pp = $productPrices->get($key)->first();
|
$pp = $productPrices->get($key)->first();
|
||||||
$cp = new CuttingResultPrice;
|
$results[$variantId][] = [
|
||||||
$cp->product_variant_id = $variantId;
|
'price_type' => $priceType->value,
|
||||||
$cp->price_type = $priceType;
|
'price' => (int) $pp->price,
|
||||||
$cp->price = $pp->price;
|
'price_formatted' => 'Rp '.number_format((int) $pp->price, 0, ',', '.'),
|
||||||
$results->push($cp);
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
namespace App\Services\System;
|
||||||
|
|
||||||
|
use App\Enums\PriceType;
|
||||||
use App\Models\Category;
|
use App\Models\Category;
|
||||||
use App\Models\Product;
|
use App\Models\Product;
|
||||||
use App\Models\SystemConfiguration;
|
use App\Models\SystemConfiguration;
|
||||||
@ -51,7 +52,7 @@ public function pageData(): array
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getProducts()
|
private function getProducts(): array
|
||||||
{
|
{
|
||||||
$products = Product::getActiveWithVariantsAndCategories();
|
$products = Product::getActiveWithVariantsAndCategories();
|
||||||
|
|
||||||
@ -61,22 +62,39 @@ private function getProducts()
|
|||||||
|
|
||||||
$allPricesByVariant = $this->cuttingResultPriceResolver->latestPricesForVariants($allVariantIds);
|
$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) {
|
return $products->map(function ($product) use ($allPricesByVariant) {
|
||||||
$product->variants->each(function ($variant) use ($allPricesByVariant) {
|
$variants = $product->variants->map(function ($variant) use ($allPricesByVariant) {
|
||||||
$variant->setAttribute('images', MediaPresenter::collection($variant, 'images'));
|
|
||||||
$variantPrices = $allPricesByVariant->get($variant->id, collect());
|
$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;
|
return [
|
||||||
})->values();
|
'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