diff --git a/code_samples/api/product_catalog/src/Command/ProductCommand.php b/code_samples/api/product_catalog/src/Command/ProductCommand.php index 530fabcd51..4f486d7c4b 100644 --- a/code_samples/api/product_catalog/src/Command/ProductCommand.php +++ b/code_samples/api/product_catalog/src/Command/ProductCommand.php @@ -2,6 +2,7 @@ namespace App\Command; +use App\ProductCatalog\Availability\PurchasableWithoutStockAvailabilityContext; use Ibexa\Contracts\Core\Repository\PermissionResolver; use Ibexa\Contracts\Core\Repository\UserService; use Ibexa\Contracts\ProductCatalog\Local\LocalProductServiceInterface; @@ -98,26 +99,34 @@ protected function execute(InputInterface $input, OutputInterface $output): int $product = $this->productService->getProduct('NEWMODIFIEDPRODUCT'); - $productAvailabilityCreateStruct = new ProductAvailabilityCreateStruct($product, true, true); + $productAvailabilityCreateStruct = new ProductAvailabilityCreateStruct($product, false, true); $this->productAvailabilityService->createProductAvailability($productAvailabilityCreateStruct); if ($this->productAvailabilityService->hasAvailability($product)) { $availability = $this->productAvailabilityService->getAvailability($product); - $output->write($availability->isAvailable() ? 'Available' : 'Unavailable'); - $output->writeln(' with stock ' . $availability->getStock()); - - $availability = $this->productAvailabilityService->getAvailability($product); + $output->writeln($availability->getAvailability() ? 'Available flag: true' : 'Available flag: false'); + $output->writeln($availability->getComputedAvailability() ? 'Can be ordered: true' : 'Can be ordered: false'); + $output->writeln('Stock: ' . $availability->getStock()); $productAvailabilityUpdateStruct = new ProductAvailabilityUpdateStruct($product, true, false, 80); $this->productAvailabilityService->updateProductAvailability($productAvailabilityUpdateStruct); - $output->write($availability->isAvailable() ? 'Available' : 'Unavailable'); + $output->writeln($availability->getAvailability() ? 'Available flag: true' : 'Available flag: false'); + $output->writeln($availability->getComputedAvailability() ? 'Can be ordered: true' : 'Can be ordered: false'); $output->writeln(' available now with stock ' . $availability->getStock()); } + $availability = $this->productAvailabilityService->getAvailability( + $product, + new PurchasableWithoutStockAvailabilityContext() + ); + + $canBeOrdered = $availability->getComputedAvailability(); + $output->writeln('Can be ordered: ' . ($canBeOrdered ? 'true' : 'false') . ', Stock: ' . $availability->getStock()); + $this->localProductService->deleteProduct($product); return self::SUCCESS; diff --git a/code_samples/pim/availability/config/custom_services.yaml b/code_samples/pim/availability/config/custom_services.yaml new file mode 100644 index 0000000000..8a99cbe0b3 --- /dev/null +++ b/code_samples/pim/availability/config/custom_services.yaml @@ -0,0 +1,4 @@ +services: + App\ProductCatalog\Availability\ProductAvailabilityPurchasableWithoutStockStrategy: + tags: + - { name: ibexa.product_catalog.availability.strategy } diff --git a/code_samples/pim/availability/src/ProductAvailabilityPurchasableWithoutStockStrategy.php b/code_samples/pim/availability/src/ProductAvailabilityPurchasableWithoutStockStrategy.php new file mode 100644 index 0000000000..384e2757ac --- /dev/null +++ b/code_samples/pim/availability/src/ProductAvailabilityPurchasableWithoutStockStrategy.php @@ -0,0 +1,70 @@ +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( + bool $rawAvailable, + ?int $stock, + bool $isInfinite + ): bool { + if ($rawAvailable === false) { + return false; + } + + if ($isInfinite) { + return true; + } + + if ($stock === null) { + return true; + } + + return $stock >= 0; + } +} diff --git a/code_samples/pim/availability/src/PurchasableWithoutStockAvailabilityContext.php b/code_samples/pim/availability/src/PurchasableWithoutStockAvailabilityContext.php new file mode 100644 index 0000000000..e8e8e547f6 --- /dev/null +++ b/code_samples/pim/availability/src/PurchasableWithoutStockAvailabilityContext.php @@ -0,0 +1,9 @@ +