diff --git a/Classes/EventListener/Order/Stock/ProcessOrderCheckStock.php b/Classes/EventListener/Order/Stock/ProcessOrderCheckStock.php new file mode 100644 index 00000000..b0563840 --- /dev/null +++ b/Classes/EventListener/Order/Stock/ProcessOrderCheckStock.php @@ -0,0 +1,93 @@ +getCart(); + $cartProducts = $cart->getProducts(); + + foreach ($cartProducts as $cartProduct) { + if ($cartProduct->getProductType() !== 'CartProducts') { + continue; + } + + $querySettings = $this->productRepository->createQuery()->getQuerySettings(); + $querySettings->setRespectStoragePage(false); + $this->productRepository->setDefaultQuerySettings($querySettings); + $product = $this->productRepository->findByIdentifier($cartProduct->getProductId()); + + if (!$product instanceof Product || !$product->isHandleStock()) { + continue; + } + + $compareQuantity = $cartProduct->getQuantity(); + + if (!$product->isHandleStockInVariants()) { + $quantityInStock = $product->getStock(); + if ($compareQuantity > $quantityInStock) { + $this->falseAvailability($event, $product->getTitle(), $product->getSku(), $quantityInStock); + } + continue; + } + + foreach ($product->getBeVariants() as $beVariant) { + foreach ($cartProduct->getBeVariants() as $cartBeVariant) { + if($cartBeVariant->getSku() !== $beVariant->getSku()) { + continue; + } + $quantityInStock = $beVariant->getStock(); + if ($compareQuantity > $quantityInStock) { + $this->falseAvailability($event, $product->getTitle(), $beVariant->getSku(), $quantityInStock); + } + } + } + } + } + + protected function falseAvailability( + ProcessOrderCheckStockEvent $event, + string $title, + string $sku, + int $quantityInStock + ): void + { + $event->setNotEveryProductAvailable(); + $event->addInsufficientStockMessage( + GeneralUtility::makeInstance( + FlashMessage::class, + LocalizationUtility::translate( + 'tx_cart.error.stock_handling.order', + 'cart', + [$title, $sku, $quantityInStock] + ), + '', + ContextualFeedbackSeverity::ERROR + ) + ); + } +} diff --git a/Configuration/Services.yaml b/Configuration/Services.yaml index 70f2448b..2060d0bd 100644 --- a/Configuration/Services.yaml +++ b/Configuration/Services.yaml @@ -66,6 +66,13 @@ services: identifier: 'cart-products--check-product-availability' event: Extcode\Cart\Event\CheckProductAvailabilityEvent + Extcode\CartProducts\EventListener\Order\Stock\ProcessOrderCheckStock: + tags: + - name: event.listener + identifier: 'cart-products--process-order-check-stock' + event: Extcode\Cart\Event\ProcessOrderCheckStockEvent + + Extcode\CartProducts\Reaction\UpdateStockReaction: tags: ['reactions.reaction'] public: true diff --git a/Documentation/Changelog/5.0/Feature-138-ListenToProcessOrderCheckStockEvent.rst b/Documentation/Changelog/5.0/Feature-138-ListenToProcessOrderCheckStockEvent.rst new file mode 100644 index 00000000..5567ab6c --- /dev/null +++ b/Documentation/Changelog/5.0/Feature-138-ListenToProcessOrderCheckStockEvent.rst @@ -0,0 +1,34 @@ +.. include:: ../../Includes.txt + +====================================================== +Breaking: #138 - Listen to ProcessOrderCheckStockEvent +====================================================== + +See :issue:`138` + +Description +=========== + +`EXT:cart` v9 will have an extended :php:`Extcode\Cart\Domain\Model\Cart\Cart\ProcessOrderCheckStockEvent`. +This allows product extensions as `EXT:cart_product` to set a flag if any +product of an order is not available in sufficient amount (means: less articles +in stock than what a customer wants to order). + +The new Event Listener :php:`Extcode\CartProducts\EventListener\Order\Stock\ProcessOrderCheckStock` +checks whether the stock of any article is lower than what a customer wants to +order. This situation can happen when customer B ordered the same product +after customer A put the article into the cart. Customer A will get in this case +a message that the article is no longer available in the desired amount and the +order can not be finished until customer A adapts the amount. + +Impact +====== + +Negative effects are not expected. This feature works out of the box when +stock handling is activated. As long as flash messages are shown in the order +form it's not necessary to adapt anything. + +It is of course possible to override the displayed message which has the key +`tx_cart.error.stock_handling.order` (in EXT:cart). + +.. index:: Backend diff --git a/Documentation/Changelog/5.0/Index.rst b/Documentation/Changelog/5.0/Index.rst new file mode 100644 index 00000000..d4775fc4 --- /dev/null +++ b/Documentation/Changelog/5.0/Index.rst @@ -0,0 +1,30 @@ +.. include:: ../../Includes.txt + +5.0 Changes +=========== + +**Table of contents** + +.. contents:: + :local: + :depth: 1 + +Breaking Changes +^^^^^^^^^^^^^^^^ + +.. toctree:: + :maxdepth: 1 + :titlesonly: + :glob: + + Breaking-* + +Features +^^^^^^^^ + +.. toctree:: + :maxdepth: 1 + :titlesonly: + :glob: + + Feature-* diff --git a/Documentation/Changelog/Index.rst b/Documentation/Changelog/Index.rst index deee5fa0..da592ad2 100644 --- a/Documentation/Changelog/Index.rst +++ b/Documentation/Changelog/Index.rst @@ -7,6 +7,7 @@ ChangeLog :maxdepth: 5 :titlesonly: + 5.0/Index 4.0/Index 3.0/Index 2.4/Index