custom/plugins/PickwareErpStarter/src/Stock/ProductAvailableUpdater.php line 41

Open in your IDE?
  1. <?php
  2. /*
  3.  * Copyright (c) Pickware GmbH. All rights reserved.
  4.  * This file is part of software that is released under a proprietary license.
  5.  * You must not copy, modify, distribute, make publicly available, or execute
  6.  * its contents or parts thereof without express permission by the copyright
  7.  * holder, unless otherwise permitted by law.
  8.  */
  9. declare(strict_types=1);
  10. namespace Pickware\PickwareErpStarter\Stock;
  11. use Doctrine\DBAL\Connection;
  12. use Pickware\DalBundle\RetryableTransaction;
  13. use Shopware\Core\Content\Product\ProductEvents;
  14. use Shopware\Core\Defaults;
  15. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
  16. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  17. class ProductAvailableUpdater implements EventSubscriberInterface
  18. {
  19.     /**
  20.      * @var Connection
  21.      */
  22.     private $db;
  23.     public function __construct(Connection $db)
  24.     {
  25.         $this->db $db;
  26.     }
  27.     public static function getSubscribedEvents(): array
  28.     {
  29.         return [
  30.             ProductAvailableStockUpdatedEvent::EVENT_NAME => 'productAvailableStockUpdated',
  31.             ProductEvents::PRODUCT_WRITTEN_EVENT => 'productWritten',
  32.         ];
  33.     }
  34.     public function productAvailableStockUpdated(ProductAvailableStockUpdatedEvent $event): void
  35.     {
  36.         $this->recalculateProductAvailable($event->getProductIds());
  37.     }
  38.     public function productWritten(EntityWrittenEvent $event): void
  39.     {
  40.         if ($event->getContext()->getVersionId() !== Defaults::LIVE_VERSION) {
  41.             return;
  42.         }
  43.         $productIds = [];
  44.         foreach ($event->getWriteResults() as $writeResult) {
  45.             $payload $writeResult->getPayload();
  46.             if (isset($payload['parentId'])
  47.                 || isset($payload['versionId'])
  48.                 || isset($payload['isCloseout'])
  49.                 || isset($payload['minPurchase'])
  50.             ) {
  51.                 $productIds[] = $payload['id'];
  52.             }
  53.         }
  54.         $this->recalculateProductAvailable($productIds);
  55.     }
  56.     public function recalculateProductAvailable(array $productIds): void
  57.     {
  58.         if (count($productIds) === 0) {
  59.             return;
  60.         }
  61.         RetryableTransaction::retryable($this->db, function () use ($productIds): void {
  62.             $this->db->executeStatement(
  63.                 'UPDATE `product`
  64.                 LEFT JOIN `product` AS `parent`
  65.                     ON `parent`.`id` = `product`.`parent_id` AND `parent`.`version_id` = `product`.`version_id`
  66.                 SET `product`.`available` =
  67.                     IF(
  68.                         -- If product is in closeout ...
  69.                         COALESCE(`product`.`is_closeout`, `parent`.`is_closeout`, 0),
  70.                         -- ... it is available if more stock is available than the minimum purchase ...
  71.                         `product`.`available_stock` >= COALESCE(`product`.`min_purchase`, `parent`.`min_purchase`, 1),
  72.                         -- ... else it is available always
  73.                         1
  74.                     )
  75.                 WHERE `product`.`version_id` = :liveVersionId
  76.                     AND (`product`.`id` IN (:productIds) OR `product`.`parent_id` IN (:productIds))',
  77.                 [
  78.                     'liveVersionId' => hex2bin(Defaults::LIVE_VERSION),
  79.                     'productIds' => array_map('hex2bin'$productIds),
  80.                 ],
  81.                 [
  82.                     'productIds' => Connection::PARAM_STR_ARRAY,
  83.                 ],
  84.             );
  85.         });
  86.     }
  87. }