custom/plugins/PickwareErpStarter/src/SupplierOrder/IncomingStockUpdater.php line 44

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\SupplierOrder;
  11. use Doctrine\DBAL\Connection;
  12. use Pickware\DalBundle\EntityPreWriteValidationEvent;
  13. use Pickware\DalBundle\EntityPreWriteValidationEventDispatcher;
  14. use Pickware\PickwareErpStarter\SupplierOrder\Model\SupplierOrderDefinition;
  15. use Pickware\PickwareErpStarter\SupplierOrder\Model\SupplierOrderLineItemDefinition;
  16. use Shopware\Core\Defaults;
  17. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityDeletedEvent;
  18. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
  19. use Shopware\Core\Framework\DataAbstractionLayer\Write\Command\ChangeSetAware;
  20. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  21. class IncomingStockUpdater implements EventSubscriberInterface
  22. {
  23.     private Connection $db;
  24.     public function __construct(Connection $db)
  25.     {
  26.         $this->db $db;
  27.     }
  28.     public static function getSubscribedEvents(): array
  29.     {
  30.         return [
  31.             EntityPreWriteValidationEventDispatcher::getEventName(SupplierOrderLineItemDefinition::ENTITY_NAME) => 'requestChangeSet',
  32.             SupplierOrderLineItemDefinition::ENTITY_WRITTEN_EVENT => 'supplierOrderLineItemWritten',
  33.             SupplierOrderLineItemDefinition::ENTITY_DELETED_EVENT => 'supplierOrderLineItemDeleted',
  34.             SupplierOrderDefinition::ENTITY_WRITTEN_EVENT => 'supplierOrderWritten',
  35.         ];
  36.     }
  37.     public function requestChangeSet($event): void
  38.     {
  39.         if (!($event instanceof EntityPreWriteValidationEvent)) {
  40.             // The subscriber is probably instantiated in its old version (with the Shopware PreWriteValidationEvent) in
  41.             // the container and will be updated on the next container rebuild (next request). Early return.
  42.             return;
  43.         }
  44.         foreach ($event->getCommands() as $command) {
  45.             if ($command instanceof ChangeSetAware) {
  46.                 $command->requestChangeSet();
  47.             }
  48.         }
  49.     }
  50.     public function supplierOrderLineItemDeleted(EntityDeletedEvent $entityDeletedEvent): void
  51.     {
  52.         if ($entityDeletedEvent->getContext()->getVersionId() !== Defaults::LIVE_VERSION) {
  53.             return;
  54.         }
  55.         $productIds = [];
  56.         foreach ($entityDeletedEvent->getWriteResults() as $writeResult) {
  57.             $changeSet $writeResult->getChangeSet();
  58.             $productIds[] = bin2hex($changeSet->getBefore('product_id'));
  59.         }
  60.         if (count($productIds) === 0) {
  61.             return;
  62.         }
  63.         $this->recalculateIncomingStock($productIds);
  64.     }
  65.     public function supplierOrderLineItemWritten(EntityWrittenEvent $entityWrittenEvent): void
  66.     {
  67.         if ($entityWrittenEvent->getContext()->getVersionId() !== Defaults::LIVE_VERSION) {
  68.             return;
  69.         }
  70.         $supplierOrderLineItemIds = [];
  71.         foreach ($entityWrittenEvent->getWriteResults() as $writeResult) {
  72.             $payload $writeResult->getPayload();
  73.             $supplierOrderLineItemIds[] = $payload['id'];
  74.         }
  75.         if (count($supplierOrderLineItemIds) === 0) {
  76.             return;
  77.         }
  78.         $supplierOrderLineItemProductIds $this->db->fetchAllAssociative(
  79.             'SELECT DISTINCT LOWER(HEX(product_id)) AS productId
  80.             FROM pickware_erp_supplier_order_line_item
  81.             WHERE id IN (:supplierOrderLineItemIds)',
  82.             ['supplierOrderLineItemIds' => array_map('hex2bin'$supplierOrderLineItemIds)],
  83.             ['supplierOrderLineItemIds' => Connection::PARAM_STR_ARRAY],
  84.         );
  85.         $productIds array_filter(array_column($supplierOrderLineItemProductIds'productId'));
  86.         $this->recalculateIncomingStock($productIds);
  87.     }
  88.     public function supplierOrderWritten(EntityWrittenEvent $entityWrittenEvent): void
  89.     {
  90.         if ($entityWrittenEvent->getContext()->getVersionId() !== Defaults::LIVE_VERSION) {
  91.             return;
  92.         }
  93.         $supplierOrderIds = [];
  94.         foreach ($entityWrittenEvent->getWriteResults() as $writeResult) {
  95.             $payload $writeResult->getPayload();
  96.             $supplierOrderIds[] = $payload['id'];
  97.         }
  98.         if (count($supplierOrderIds) === 0) {
  99.             return;
  100.         }
  101.         $supplierOrderProductIds $this->db->fetchAllAssociative(
  102.             'SELECT DISTINCT LOWER(HEX(product_id)) AS productId
  103.             FROM pickware_erp_supplier_order_line_item
  104.             JOIN pickware_erp_supplier_order ON pickware_erp_supplier_order_line_item.supplier_order_id = pickware_erp_supplier_order.id
  105.             WHERE pickware_erp_supplier_order.id IN (:supplierOrderIds)',
  106.             ['supplierOrderIds' => array_map('hex2bin'$supplierOrderIds)],
  107.             ['supplierOrderIds' => Connection::PARAM_STR_ARRAY],
  108.         );
  109.         $productIds array_filter(array_column($supplierOrderProductIds'productId'));
  110.         $this->recalculateIncomingStock($productIds);
  111.     }
  112.     public function recalculateIncomingStock(array $productIds): void
  113.     {
  114.         if (count($productIds) === 0) {
  115.             return;
  116.         }
  117.         $this->db->executeStatement(
  118.             'UPDATE `pickware_erp_pickware_product`
  119.             LEFT JOIN `product`
  120.                 ON `product`.`id` = `pickware_erp_pickware_product`.`product_id`
  121.                 AND `product`.`version_id` = `pickware_erp_pickware_product`.`product_version_id`
  122.             LEFT JOIN (
  123.                 SELECT
  124.                     SUM(`supplierOrderLineItem`.`quantity`) AS `quantity`,
  125.                     `supplierOrderLineItem`.`product_id`,
  126.                     `supplierOrderLineItem`.`product_version_id`
  127.                 FROM `pickware_erp_supplier_order_line_item` AS `supplierOrderLineItem`
  128.                 INNER JOIN `pickware_erp_supplier_order` AS `supplierOrder`
  129.                     ON `supplierOrder`.`id` = `supplierOrderLineItem`.`supplier_order_id`
  130.                 LEFT JOIN `state_machine_state` AS `orderState`
  131.                     ON `orderState`.`id` = `supplierOrder`.`state_id`
  132.                 WHERE `orderState`.`technical_name` NOT IN (:completedSupplierOrderStateTechnicalNames)
  133.                 GROUP BY `supplierOrderLineItem`.`product_id`
  134.             ) AS `openSupplierOrderLineItems`
  135.                 ON `openSupplierOrderLineItems`.`product_id` = `product`.`id`
  136.                 AND `openSupplierOrderLineItems`.`product_version_id` = `product`.`version_id`
  137.             SET `pickware_erp_pickware_product`.`incoming_stock` = IFNULL(`openSupplierOrderLineItems`.`quantity`, 0)
  138.             WHERE `product`.`version_id` = :liveVersionId
  139.             AND `product`.`id` IN (:productIds)',
  140.             [
  141.                 'liveVersionId' => hex2bin(Defaults::LIVE_VERSION),
  142.                 'productIds' => array_map('hex2bin'$productIds),
  143.                 'completedSupplierOrderStateTechnicalNames' => [
  144.                     SupplierOrderStateMachine::STATE_DELIVERED,
  145.                     SupplierOrderStateMachine::STATE_CANCELLED,
  146.                     SupplierOrderStateMachine::STATE_COMPLETED,
  147.                 ],
  148.             ],
  149.             [
  150.                 'productIds' => Connection::PARAM_STR_ARRAY,
  151.                 'completedSupplierOrderStateTechnicalNames' => Connection::PARAM_STR_ARRAY,
  152.             ],
  153.         );
  154.     }
  155. }