-
Notifications
You must be signed in to change notification settings - Fork 82
Expanded the product availability section #3190
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
8b3e1f5
506f3f5
2fcdf0c
6ccb073
4ec36b7
b3ef778
4538d61
ca36bc1
3914776
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| services: | ||
| App\ProductCatalog\Availability\ProductAvailabilityPurchasableWithoutStockStrategy: | ||
| tags: | ||
| - { name: ibexa.product_catalog.availability.strategy } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| <?php declare(strict_types=1); | ||
|
|
||
| namespace App\ProductCatalog\Availability; | ||
|
|
||
| use Ibexa\Contracts\ProductCatalog\ProductAvailabilityStrategyInterface; | ||
| use Ibexa\Contracts\ProductCatalog\Values\Availability\AvailabilityContextInterface; | ||
| use Ibexa\Contracts\ProductCatalog\Values\Availability\AvailabilityInterface; | ||
| use Ibexa\Contracts\ProductCatalog\Values\ProductInterface; | ||
| use Ibexa\ProductCatalog\Local\Persistence\Legacy\ProductAvailability\HandlerInterface; | ||
| use Ibexa\ProductCatalog\Local\Repository\Values\Availability; | ||
|
|
||
| final class ProductAvailabilityPurchasableWithoutStockStrategy implements ProductAvailabilityStrategyInterface | ||
| { | ||
| private HandlerInterface $handler; | ||
|
|
||
| public function __construct(HandlerInterface $handler) | ||
| { | ||
| $this->handler = $handler; | ||
| } | ||
|
|
||
| public function accept(AvailabilityContextInterface $context): bool | ||
| { | ||
| return $context instanceof PurchasableWithoutStockAvailabilityContext; | ||
| } | ||
|
|
||
| public function getProductAvailability( | ||
| ProductInterface $product, | ||
| AvailabilityContextInterface $context | ||
| ): AvailabilityInterface { | ||
| $productAvailability = $this->handler->find($product->getCode()); | ||
|
|
||
| $rawAvailableFlag = $productAvailability->isAvailable(); | ||
| $stock = $productAvailability->getStock(); | ||
| $isInfinite = $productAvailability->isInfinite(); | ||
|
|
||
| $computedAvailable = $this->calculateAvailability( | ||
| $rawAvailableFlag, | ||
| $stock, | ||
| $isInfinite, | ||
| ); | ||
|
|
||
| return new Availability( | ||
| $product, | ||
| $rawAvailableFlag, | ||
| $computedAvailable, | ||
| $isInfinite, | ||
| $stock, | ||
| ); | ||
| } | ||
|
|
||
| private function calculateAvailability( | ||
|
Check warning on line 51 in code_samples/pim/availability/src/ProductAvailabilityPurchasableWithoutStockStrategy.php
|
||
| bool $rawAvailable, | ||
| ?int $stock, | ||
| bool $isInfinite | ||
| ): bool { | ||
| if ($rawAvailable === false) { | ||
| return false; | ||
| } | ||
|
|
||
| if ($isInfinite) { | ||
| return true; | ||
| } | ||
|
|
||
| if ($stock === null) { | ||
| return true; | ||
| } | ||
|
|
||
| return $stock >= 0; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| <?php declare(strict_types=1); | ||
|
|
||
| namespace App\ProductCatalog\Availability; | ||
|
|
||
| use Ibexa\Contracts\ProductCatalog\Values\Availability\AvailabilityContextInterface; | ||
|
|
||
| final class PurchasableWithoutStockAvailabilityContext implements AvailabilityContextInterface | ||
| { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| --- | ||
| description: Implement custom availability strategies to handle different business scenarios, for example pre-orders or per-region availability. | ||
| --- | ||
|
|
||
| # Create custom availability strategy | ||
|
|
||
| The product catalog uses an availability strategy to calculate [computed availability](products.md#availability-and-computed-availability) for a product, deciding whether the customers can order it. | ||
|
mnocon marked this conversation as resolved.
Outdated
|
||
| The default is based on the product availability and stock amount. | ||
|
Check notice on line 8 in docs/pim/create_custom_availability_strategy.md
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "default availability strategy"?
mnocon marked this conversation as resolved.
Outdated
|
||
|
|
||
| You can replace this logic with a custom strategy to handle specific business scenarios, for example preorders, minimum order quantities, or per-region availability. | ||
|
Check failure on line 10 in docs/pim/create_custom_availability_strategy.md
|
||
|
|
||
| The following example implements an availability strategy which allows buying products when they're set as available, without taking their stock into account. | ||
| You could use it for [virtual products](products.md#product-types) or in preorder scenarios. | ||
|
Check failure on line 13 in docs/pim/create_custom_availability_strategy.md
|
||
|
|
||
| ## Create custom availability context | ||
|
|
||
| Use an availability context to pass the parameters needed by the strategy to evaluate computed availability. | ||
| To do it, create a class implementing the [`AvailabilityContextInterface`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-ProductCatalog-Values-Availability-AvailabilityContextInterface.html) interface: | ||
|
mnocon marked this conversation as resolved.
Outdated
|
||
|
|
||
| ``` php | ||
| [[= include_file('code_samples/pim/availability/src/PurchasableWithoutStockAvailabilityContext.php') =]] | ||
| ``` | ||
|
|
||
| ## Create custom availability strategy | ||
|
|
||
| Create a class implementing [`ProductAvailabilityStrategyInterface`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-ProductCatalog-ProductAvailabilityStrategyInterface.html): | ||
|
mnocon marked this conversation as resolved.
Outdated
|
||
|
|
||
| ``` php | ||
| [[= include_file('code_samples/pim/availability/src/ProductAvailabilityPurchasableWithoutStockStrategy.php') =]] | ||
| ``` | ||
|
|
||
| The strategy has two methods: | ||
|
|
||
| - `accept()` decides if the strategy can handle the provided availability context | ||
| - `getProductAvailability()` returns an [`AvailabilityInterface`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-ProductCatalog-Values-Availability-AvailabilityInterface.html) object | ||
|
|
||
| When constructing the `AvailabilityInterface` object, provide the stock amount, the availability flag, and the result of your custom availability logic. | ||
|
|
||
| ## Register strategy as a service | ||
|
Check notice on line 39 in docs/pim/create_custom_availability_strategy.md
|
||
|
|
||
| If you're not using [autowiring]([[= symfony_doc =]]/service_container/autowiring.html), tag the strategy service with `ibexa.product_catalog.availability.strategy`: | ||
|
Check notice on line 41 in docs/pim/create_custom_availability_strategy.md
|
||
|
|
||
| ``` yaml | ||
| [[= include_file('code_samples/pim/availability/config/custom_services.yaml') =]] | ||
| ``` | ||
|
|
||
| ## Use custom context | ||
|
|
||
| To evaluate product availability using a custom strategy, pass the custom context as the second argument to [`ProductAvailabilityServiceInterface::getAvailability()`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-ProductCatalog-ProductAvailabilityServiceInterface.html): | ||
|
Check notice on line 49 in docs/pim/create_custom_availability_strategy.md
|
||
|
|
||
| ```php | ||
| [[= include_code('code_samples/api/product_catalog/src/Command/ProductCommand.php', 122, 127, remove_indent=True) =]] | ||
| ``` | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.