feat: add filtering for product detail attribute options based on available variant values
This commit is contained in:
@@ -293,6 +293,8 @@ class ProductService
|
||||
'variants.definitions.productAttribute.attribute.options',
|
||||
]);
|
||||
|
||||
$this->filterProductDetailAttributeOptions($product);
|
||||
|
||||
$selectedVariant = $variantId !== null
|
||||
? $product->variants->firstWhere('id', $variantId)
|
||||
: $product->variants->first(fn (ProductVariant $variant) => $variant->stock > 0);
|
||||
@@ -313,4 +315,36 @@ class ProductService
|
||||
|
||||
return $product;
|
||||
}
|
||||
|
||||
protected function filterProductDetailAttributeOptions(Product $product): void
|
||||
{
|
||||
$availableValuesByAttributeId = [];
|
||||
|
||||
foreach ($product->variants as $variant) {
|
||||
foreach ($variant->definitions as $definition) {
|
||||
$attributeId = $definition->productAttribute?->attribute_id;
|
||||
|
||||
if ($attributeId === null || $definition->value === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$availableValuesByAttributeId[$attributeId][$definition->value] = true;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($product->attributes as $attribute) {
|
||||
if (! $attribute->relationLoaded('options')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$availableValues = $availableValuesByAttributeId[$attribute->id] ?? [];
|
||||
|
||||
$attribute->setRelation(
|
||||
'options',
|
||||
$attribute->options
|
||||
->filter(fn ($option): bool => array_key_exists($option->value, $availableValues))
|
||||
->values()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -405,6 +405,10 @@ class ProductControllerTest extends TestCase
|
||||
'precio' => 100.00,
|
||||
]);
|
||||
$productAttributes = $this->syncVariantAttributes($product);
|
||||
$this->colorAttr->options()->create([
|
||||
'value' => 'Verde',
|
||||
'label' => 'Verde',
|
||||
]);
|
||||
|
||||
$variant = $product->createVariant([
|
||||
'stock' => 0,
|
||||
@@ -479,6 +483,23 @@ class ProductControllerTest extends TestCase
|
||||
$response->assertJsonPath('data.variant.definitions.color', 'Rojo');
|
||||
$response->assertJsonCount(1, 'data.variant.images');
|
||||
$this->assertStringContainsString($variantAttachment->path, $response->json('data.variant.images.0'));
|
||||
|
||||
$colorAttribute = collect($response->json('data.attributes'))->firstWhere('codigo', 'color');
|
||||
$this->assertNotNull($colorAttribute);
|
||||
$this->assertEqualsCanonicalizing(
|
||||
['Azul', 'Rojo'],
|
||||
collect($colorAttribute['options'])->pluck('value')->all()
|
||||
);
|
||||
|
||||
$attributesResponse = $this->getJson("/api/tenants/{$this->tenant->codigo}/attributes");
|
||||
$attributesResponse->assertOk();
|
||||
|
||||
$masterColorAttribute = collect($attributesResponse->json('data'))->firstWhere('codigo', 'color');
|
||||
$this->assertNotNull($masterColorAttribute);
|
||||
$this->assertEqualsCanonicalizing(
|
||||
['Azul', 'Rojo', 'Verde'],
|
||||
collect($masterColorAttribute['options'])->pluck('value')->all()
|
||||
);
|
||||
}
|
||||
|
||||
public function test_it_returns_requested_variant_in_product_detail(): void
|
||||
|
||||
Reference in New Issue
Block a user