custom/plugins/ZeobvBundleProducts/src/Core/Subscriber/OrderDeliveryPositionSubscriber.php line 77

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Zeobv\BundleProducts\Core\Subscriber;
  4. use Throwable;
  5. use Psr\Log\LoggerInterface;
  6. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  7. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  8. use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemEntity;
  9. use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemCollection;
  10. use Shopware\Core\Framework\Context;
  11. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenContainerEvent;
  12. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
  13. use Shopware\Core\Framework\DataAbstractionLayer\EntityWriteResult;
  14. use Shopware\Core\Checkout\Order\OrderDefinition;
  15. use Shopware\Core\Checkout\Order\OrderEntity;
  16. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  17. /**
  18.  * Shopware doesn't create order_delivery_positions for child line items by default. This subscriber aims to fix that.
  19.  *
  20.  * Class OrderDeliveryPositionSubscriber
  21.  *
  22.  * @package Zeobv\BundleProducts\Core\Subscriber
  23.  */
  24. class OrderDeliveryPositionSubscriber implements EventSubscriberInterface
  25. {
  26.     /**
  27.      * @var EntityRepositoryInterface
  28.      */
  29.     protected $orderRepository;
  30.     /**
  31.      * @var EntityRepositoryInterface
  32.      */
  33.     protected $orderDeliveryPositionRepository;
  34.     /**
  35.      * @var LoggerInterface
  36.      */
  37.     protected $logger;
  38.     /**
  39.      * OrderDeliveryPositionSubscriber constructor.
  40.      *
  41.      * @param EntityRepositoryInterface $orderRepository
  42.      * @param EntityRepositoryInterface $orderDeliveryPositionRepository
  43.      * @param LoggerInterface $logger
  44.      */
  45.     public function __construct(
  46.         EntityRepositoryInterface $orderRepository,
  47.         EntityRepositoryInterface $orderDeliveryPositionRepository,
  48.         LoggerInterface           $logger
  49.     ) {
  50.         $this->orderRepository $orderRepository;
  51.         $this->orderDeliveryPositionRepository $orderDeliveryPositionRepository;
  52.         $this->logger $logger;
  53.     }
  54.     /**
  55.      * @return array
  56.      */
  57.     public static function getSubscribedEvents(): array
  58.     {
  59.         return [
  60.             'order.written' => 'onOrderWritten'
  61.         ];
  62.     }
  63.     /**
  64.      * @param EntityWrittenEvent $event
  65.      */
  66.     public function onOrderWritten(EntityWrittenEvent $event): void
  67.     {
  68.         foreach ($event->getWriteResults() as $writeResult) {
  69.             if ($writeResult->getOperation() !== EntityWriteResult::OPERATION_INSERT || $writeResult->getEntityName() !== OrderDefinition::ENTITY_NAME) {
  70.                 continue;
  71.             }
  72.             try {
  73.                 $orderId $writeResult->getPrimaryKey();
  74.                 if (is_array($orderId)) {
  75.                     $this->logger->error(
  76.                         'Unexpected primary key received from write result. Skipping order delivery position creation. Json encoded primary key: ' json_encode(
  77.                             $writeResult->getPrimaryKey()
  78.                         )
  79.                     );
  80.                     continue;
  81.                 }
  82.                 $order $this->getOrder($orderId$event->getContext());
  83.                 if ($order === null) {
  84.                     continue;
  85.                 }
  86.                 $childLineItems $order->getLineItems()->filter(function (OrderLineItemEntity $lineItem) {
  87.                     return $lineItem->getParentId() !== null;
  88.                 });
  89.                 if ($childLineItems->count() < 1) {
  90.                     continue;
  91.                 }
  92.                 $this->createOrderDeliveryPositionsForOrderLineItems(
  93.                     $childLineItems,
  94.                     $order->getDeliveries()->first()->getId(),
  95.                     $event->getContext()
  96.                 );
  97.             } catch (Throwable $e) {
  98.                 $this->logger->error($e->getMessage());
  99.             }
  100.         }
  101.     }
  102.     /**
  103.      * @param string $orderId
  104.      * @param Context $context
  105.      *
  106.      * @return OrderEntity|null
  107.      */
  108.     protected function getOrder(string $orderIdContext $context): ?OrderEntity
  109.     {
  110.         $criteria = new Criteria([$orderId]);
  111.         $criteria->addAssociations(['lineItems''deliveries']);
  112.         return $this->orderRepository->search($criteria$context)->first();
  113.     }
  114.     /**
  115.      * @param OrderLineItemCollection $orderLineItemCollection
  116.      * @param string $orderDeliveryId
  117.      * @param Context $context
  118.      *
  119.      * @return EntityWrittenContainerEvent
  120.      */
  121.     protected function createOrderDeliveryPositionsForOrderLineItems(
  122.         OrderLineItemCollection $orderLineItemCollection,
  123.         string                  $orderDeliveryId,
  124.         Context                 $context
  125.     ): EntityWrittenContainerEvent
  126.     {
  127.         $orderDeliveryPositionsData $orderLineItemCollection->map(
  128.             function (OrderLineItemEntity $orderLineItem) use ($orderDeliveryId) {
  129.                 return [
  130.                     'orderId' => $orderLineItem->getOrderId(),
  131.                     'orderDeliveryId' => $orderDeliveryId,
  132.                     'orderLineItemId' => $orderLineItem->getId(),
  133.                     'price' => $orderLineItem->getPrice(),
  134.                     'unitPrice' => $orderLineItem->getUnitPrice(),
  135.                     'totalPrice' => $orderLineItem->getTotalPrice(),
  136.                     'quantity' => $orderLineItem->getQuantity(),
  137.                 ];
  138.             }
  139.         );
  140.         return $this->orderDeliveryPositionRepository->create(array_values($orderDeliveryPositionsData), $context);
  141.     }
  142. }