src/StoreFront/Subscriber/OrderSubscriber.php line 174

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Bodymed\Webshop\StoreFront\Subscriber;
  4. use Bodymed\Webshop\BusinessEvent\OrderShopOwnerNotification;
  5. use Bodymed\Webshop\Constants;
  6. use Bodymed\Webshop\Core\Checkout\Customer\CustomerPharmacyCooperation\CustomerPharmacyCooperationEntity;
  7. use Bodymed\Webshop\Core\Checkout\Order\NomsOrderSync\NomsOrderSyncService;
  8. use Bodymed\Webshop\Event\BeforePersistOrderCustomFields;
  9. use Bodymed\Webshop\Messenger\Messages\Order\AddOrderToSyncQueue;
  10. use Bodymed\Webshop\Messenger\Messages\Order\OrderPlaced;
  11. use Bodymed\Webshop\Core\Content\BodymedCenter\BodymedCenterEntity;
  12. use Bodymed\Webshop\Messenger\Stamp\OrderIdStamp;
  13. use Bodymed\Webshop\Nessync\Messenger\OrderNotifier;
  14. use Shopware\Core\Checkout\Cart\Event\CheckoutOrderPlacedEvent;
  15. use Shopware\Core\Checkout\Order\Aggregate\OrderCustomer\OrderCustomerEntity;
  16. use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemEntity;
  17. use Shopware\Core\Checkout\Order\OrderEntity;
  18. use Shopware\Core\Framework\Context;
  19. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
  20. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  21. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  22. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  23. use Shopware\Core\Framework\Event\EventData\MailRecipientStruct;
  24. use Shopware\Core\System\SystemConfig\SystemConfigService;
  25. use Symfony\Component\Messenger\Envelope;
  26. use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
  27. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  28. use Symfony\Component\Messenger\MessageBusInterface;
  29. class OrderSubscriber implements EventSubscriberInterface
  30. {
  31.     public function __construct(
  32.         private MessageBusInterface $bus,
  33.         private EntityRepository $orderCustomerRepository,
  34.         private EntityRepository $orderAddressRepository,
  35.         private EntityRepository $orderRepository,
  36.         private EventDispatcherInterface $eventDispatcher,
  37.         private SystemConfigService $systemConfigService,
  38.         private NomsOrderSyncService $nomsOrderSyncService,
  39.     ) {
  40.     }
  41.     public static function getSubscribedEvents(): array
  42.     {
  43.         return [
  44.             CheckoutOrderPlacedEvent::class => [
  45.                 ['completeOrderData'100],
  46.                 ['addOrderToSyncQueue', -100],
  47.                 ['sendShopOwnerNotification'PHP_INT_MIN]
  48.             ],
  49.         ];
  50.     }
  51.     public function completeOrderData(CheckoutOrderPlacedEvent $event): void
  52.     {
  53.         $context $event->getContext();
  54.         $order $event->getOrder();
  55.         $orderCustomer $order->getOrderCustomer();
  56.         $orderCustomerCustomFields $orderCustomer->getCustomer()->getCustomFields();
  57.         $this->updateOrderAddress($order$context);
  58.         /* @var $order OrderEntity */
  59.         $order $this->refreshOrder($order->getId(), $context);
  60.         /**
  61.          * Schreibt in den OrderCustomer die UserServiceId des Kunden
  62.          */
  63.         if (isset($orderCustomerCustomFields[Constants::CUSTOMER_ATTRIBUTE_BODYMED_USER_ID])) {
  64.             $userServiceId $orderCustomerCustomFields[Constants::CUSTOMER_ATTRIBUTE_BODYMED_USER_ID];
  65.             if (!empty($userServiceId)) {
  66.                 $orderCustomerCustomFields[Constants::USER_SERVICE_ID_KEY] = $userServiceId;
  67.                 $this->orderCustomerRepository->update([[
  68.                     'id' => $orderCustomer->getId(),
  69.                     'customFields' => $orderCustomerCustomFields,
  70.                 ]], $context);
  71.             }
  72.         }
  73.         $this->extendOrderCustomFields($order$context);
  74.     }
  75.     /**
  76.      * Schreibt die Email des Kunden in die CustomFields von
  77.      * BillingAddress und ShippingAddresses
  78.      *
  79.      * @see https://madcode.atlassian.net/browse/BODYMED-412
  80.      */
  81.     private function updateOrderAddress(OrderEntity $orderContext $context): void
  82.     {
  83.         $customerEmail $order->getOrderCustomer()->getCustomer()->getEmail();
  84.         $orderAddresses = [];
  85.         foreach ($order->getDeliveries() as $delivery) {
  86.             $orderAddresses[] = [
  87.                 'id' => $delivery->getShippingOrderAddress()->getId(),
  88.                 'customFields' => \array_merge($delivery->getShippingOrderAddress()->getCustomFields() ?? [], [
  89.                     Constants::ORDER_DELIVERY_NOTIFICATION_EMAIL_ADDRESS_KEY => $customerEmail,
  90.                 ])
  91.             ];
  92.         }
  93.         $billingAddress $this->orderAddressRepository->search(
  94.             new Criteria([$order->getBillingAddressId()]),
  95.             $context
  96.         )->first();
  97.         if ($billingAddress) {
  98.             $orderAddresses[] = [
  99.                 'id' => $billingAddress->getId(),
  100.                 'customFields' => \array_merge($billingAddress->getCustomFields() ?? [], [
  101.                     Constants::ORDER_DELIVERY_NOTIFICATION_EMAIL_ADDRESS_KEY => $customerEmail,
  102.                 ])
  103.             ];
  104.         }
  105.         $this->orderAddressRepository->update($orderAddresses$context);
  106.     }
  107.     public function addOrderToSyncQueue(CheckoutOrderPlacedEvent $event): void
  108.     {
  109.         $context $event->getContext();
  110.         $order $event->getOrder();
  111.         $salesChannelId $event->getSalesChannelId();
  112.         $this->nomsOrderSyncService->createForNewOrder($order->getId(), $context);
  113.     }
  114.     /**
  115.      * Bietet Erweiterungspunkt, um customFields der Order vor dem Speichern zu befüllen
  116.      */
  117.     private function extendOrderCustomFields(OrderEntity $orderContext $context): void
  118.     {
  119.         $this->eventDispatcher->dispatch(new BeforePersistOrderCustomFields(
  120.             $order,
  121.             $context
  122.         ));
  123.         $this->orderRepository->upsert([
  124.             [
  125.                 'id' => $order->getId(),
  126.                 'customFields' => $order->getCustomFields(),
  127.             ],
  128.         ], $context);
  129.     }
  130.     private function refreshOrder(string $orderIdContext $context): OrderEntity
  131.     {
  132.         $criteria = new Criteria([$orderId]);
  133.         $criteria
  134.             ->addAssociation('deliveries.shippingMethod')
  135.             ->addAssociation('deliveries.shippingOrderAddress.country')
  136.             ->addAssociation('transactions.paymentMethod')
  137.             ->addAssociation('lineItems')
  138.             ->addAssociation('lineItems.children')
  139.             ->addAssociation('currency')
  140.             ->addAssociation('addresses.country');
  141.         /* @var $orderEntity OrderEntity */
  142.         $orderEntity $this->orderRepository->search($criteria$context)->first();
  143.         $orderEntity->setOrderCustomer(
  144.             $this->fetchCustomer($orderEntity->getId(), $context)
  145.         );
  146.         return $orderEntity;
  147.     }
  148.     public function sendShopOwnerNotification(CheckoutOrderPlacedEvent $event): void
  149.     {
  150.         $adminMail $this->systemConfigService->getString('core.basicInformation.email'$event->getSalesChannelId());
  151.         $receivers = [
  152.             $adminMail => $event->getOrder()->getOrderCustomer()->getCustomer()->getEmail(),
  153.         ];
  154.         $shopOwnerNotificationEvent = new OrderShopOwnerNotification(
  155.             $event->getOrder(),
  156.             $event->getContext(),
  157.             $event->getSalesChannelId(),
  158.             new MailRecipientStruct($receivers),
  159.         );
  160.         $this->eventDispatcher->dispatch($shopOwnerNotificationEvent);
  161.     }
  162.     private function fetchCustomer(string $orderIdContext $context): OrderCustomerEntity
  163.     {
  164.         $criteria = new Criteria();
  165.         $criteria->addFilter(new EqualsFilter('orderId'$orderId));
  166.         $criteria->addAssociation('customer');
  167.         $criteria->addAssociation('salutation');
  168.         return $this->orderCustomerRepository
  169.             ->search($criteria$context)
  170.             ->first();
  171.     }
  172. }