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

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