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',
|
'variants.definitions.productAttribute.attribute.options',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$this->filterProductDetailAttributeOptions($product);
|
||||||
|
|
||||||
$selectedVariant = $variantId !== null
|
$selectedVariant = $variantId !== null
|
||||||
? $product->variants->firstWhere('id', $variantId)
|
? $product->variants->firstWhere('id', $variantId)
|
||||||
: $product->variants->first(fn (ProductVariant $variant) => $variant->stock > 0);
|
: $product->variants->first(fn (ProductVariant $variant) => $variant->stock > 0);
|
||||||
@@ -313,4 +315,36 @@ class ProductService
|
|||||||
|
|
||||||
return $product;
|
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,
|
'precio' => 100.00,
|
||||||
]);
|
]);
|
||||||
$productAttributes = $this->syncVariantAttributes($product);
|
$productAttributes = $this->syncVariantAttributes($product);
|
||||||
|
$this->colorAttr->options()->create([
|
||||||
|
'value' => 'Verde',
|
||||||
|
'label' => 'Verde',
|
||||||
|
]);
|
||||||
|
|
||||||
$variant = $product->createVariant([
|
$variant = $product->createVariant([
|
||||||
'stock' => 0,
|
'stock' => 0,
|
||||||
@@ -479,6 +483,23 @@ class ProductControllerTest extends TestCase
|
|||||||
$response->assertJsonPath('data.variant.definitions.color', 'Rojo');
|
$response->assertJsonPath('data.variant.definitions.color', 'Rojo');
|
||||||
$response->assertJsonCount(1, 'data.variant.images');
|
$response->assertJsonCount(1, 'data.variant.images');
|
||||||
$this->assertStringContainsString($variantAttachment->path, $response->json('data.variant.images.0'));
|
$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
|
public function test_it_returns_requested_variant_in_product_detail(): void
|
||||||
|
|||||||
Reference in New Issue
Block a user