custom/plugins/MadMykey/src/Subscriber/OrderSubscriber.php line 94

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Madco\Mykey\Subscriber;
  4. use Bodymed\Webshop\Constants as WebshopConstants;
  5. use Bodymed\Webshop\Core\Checkout\Customer\CustomerPharmacyCooperation\PharmacyCooperationService;
  6. use Bodymed\Webshop\Core\Content\BodymedCenter\BodymedCenterEntity;
  7. use Bodymed\Webshop\Core\Content\CustomerPartnerMap\CustomerPartnerMapEntity;
  8. use Bodymed\Webshop\Event\BeforePersistOrderCustomFields;
  9. use Bodymed\Webshop\StoreFront\Service\CustomerOriginDetector;
  10. use Bodymed\Webshop\StoreFront\Service\CustomerTypeChecker;
  11. use Madco\Mykey\Constants;
  12. use Madco\Mykey\Service\MykeyCustomerService;
  13. use Madco\Mykey\Service\MykeyPersister;
  14. use Madco\Mykey\Struct\CurrentMykeyAffiliate;
  15. use Madco\Mykey\Struct\CurrentMykeyPartner;
  16. use Shopware\Core\Checkout\Cart\Event\CheckoutOrderPlacedEvent;
  17. use Shopware\Core\Checkout\Customer\CustomerEntity;
  18. use Shopware\Core\Checkout\Order\OrderEntity;
  19. use Shopware\Core\Framework\Context;
  20. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  21. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  22. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  23. class OrderSubscriber implements EventSubscriberInterface
  24. {
  25.     private MykeyCustomerService $mykeyCustomerService;
  26.     private EntityRepositoryInterface $orderRepository;
  27.     private MykeyPersister $mykeyPersister;
  28.     private EntityRepositoryInterface $customerRepository;
  29.     private CustomerOriginDetector $customerOriginDetector;
  30.     private CustomerTypeChecker $customerTypeChecker;
  31.     private EntityRepositoryInterface $customerPharmacyCooperationRepository;
  32.     private PharmacyCooperationService $pharmacyCooperationService;
  33.     public function __construct(
  34.         MykeyCustomerService $mykeyCustomerService,
  35.         MykeyPersister $mykeyPersister,
  36.         EntityRepositoryInterface $orderRepository,
  37.         EntityRepositoryInterface $customerRepository,
  38.         CustomerOriginDetector $customerOriginDetector,
  39.         CustomerTypeChecker $customerTypeChecker,
  40.         PharmacyCooperationService $pharmacyCooperationService
  41.     ) {
  42.         $this->mykeyCustomerService $mykeyCustomerService;
  43.         $this->orderRepository $orderRepository;
  44.         $this->mykeyPersister $mykeyPersister;
  45.         $this->customerRepository $customerRepository;
  46.         $this->customerOriginDetector $customerOriginDetector;
  47.         $this->customerTypeChecker $customerTypeChecker;
  48.         $this->pharmacyCooperationService $pharmacyCooperationService;
  49.     }
  50.     public static function getSubscribedEvents(): array
  51.     {
  52.         return [
  53.             CheckoutOrderPlacedEvent::class => [
  54.                 ['completeOrderData'150],
  55.             ],
  56.             BeforePersistOrderCustomFields::class => 'onBeforePersistOrderCustomFields',
  57.         ];
  58.     }
  59.     public function onBeforePersistOrderCustomFields(BeforePersistOrderCustomFields $event): void
  60.     {
  61.         $order $event->getOrder();
  62.         $context $event->getContext();
  63.         $orderCustomer $order->getOrderCustomer();
  64.         $customerEntity $this->customerRepository->search(
  65.             new Criteria([$orderCustomer->getCustomerId()]),
  66.             $context
  67.         )->first();
  68.         $orderCustomFields $order->getCustomFields() ?? [];
  69.         $customerCustomFields $customerEntity->getCustomFields();
  70.         if (isset($customerCustomFields[WebshopConstants::CUSTOMER_ATTRIBUTE_ORIGIN])) {
  71.             $orderCustomFields[WebshopConstants::ORDER_CUSTOM_FIELD_CUSTOMER_ORIGIN] = $customerCustomFields[WebshopConstants::CUSTOMER_ATTRIBUTE_ORIGIN];
  72.         }
  73.         $order->setCustomFields($orderCustomFields);
  74.     }
  75.     public function completeOrderData(CheckoutOrderPlacedEvent $event): void
  76.     {
  77.         $context $event->getContext();
  78.         $order $event->getOrder();
  79.         $orderCustomer $order->getOrderCustomer();
  80.         $customerEntity $orderCustomer->getCustomer();
  81.         $mykeyPartnerData $context->getExtension(Constants::MYKEY_PARTNER_SESSION_ATTRIBUTE);
  82.         $mykeyAffiliateData $context->getExtension(Constants::MYKEY_AFFILIATE_SESSION_ATTRIBUTE);
  83.         $customerOriginReferrer null;
  84.         if ($mykeyPartnerData instanceof CurrentMykeyPartner) {
  85.             $this->mykeyPersister->persistPartnerCenter($mykeyPartnerData$customerEntity$context);
  86.             $customerOriginReferrer $mykeyPartnerData->getOrigin();
  87.         }
  88.         if ($mykeyAffiliateData instanceof CurrentMykeyAffiliate && null === $mykeyPartnerData) {
  89.             $this->mykeyPersister->persistAffiliateCenter($mykeyAffiliateData$customerEntity$context);
  90.             $customerOriginReferrer $mykeyAffiliateData->getOrigin();
  91.         }
  92.         $this->handleCustomerOrigin($customerEntity$customerOriginReferrer$context);
  93.         $customerEntity $this->customerRepository->search(new Criteria([$customerEntity->getId()]), $context)->first();
  94.         $partnerMap $this->mykeyCustomerService->getPartnerMapForCustomer($customerEntity);
  95.         if ($partnerMap) {
  96.             $this->updateOrderCustomFields($order$partnerMap$context);
  97.         }
  98.         if ($this->customerTypeChecker->isCustomerPartner()) {
  99.             $this->addOwnCenterDataToOrder($order$customerEntity$context);
  100.         }
  101.         if ($this->customerTypeChecker->isCustomerPharmacy()) {
  102.             $this->addPharmacyCooperationDataToOrder($order$customerEntity$context);
  103.         }
  104.     }
  105.     /**
  106.      * Schreibt die aktuellen mykey-Daten des Kunden in die Bestellung.
  107.      *
  108.      * @see https://madcode.atlassian.net/browse/BODYMED-295
  109.      */
  110.     private function updateOrderCustomFields(OrderEntity $orderCustomerPartnerMapEntity $partnerMapContext $context): void
  111.     {
  112.         $customFieldData $partnerMap->getOrderData();
  113.         $orderData = [
  114.             [
  115.                 'id' => $order->getId(),
  116.                 'customFields' => \array_merge($order->getCustomFields() ?? [], [
  117.                     Constants::MYKEY_ORDER_CUSTOM_FIELD_KEY => $customFieldData,
  118.                 ]),
  119.             ],
  120.         ];
  121.         if ($partnerMap->getAffiliateBodymedCenter()) {
  122.             $orderData[0]['customFields'][Constants::MYKEY_ORDER_AFFILIATE_CUSTOMER_NUMBER_FIELD_KEY] = $partnerMap->getAffiliateBodymedCenter()->getCustomerNumber();
  123.         }
  124.         $this->orderRepository->update($orderData$context);
  125.     }
  126.     private function handleCustomerOrigin(
  127.         CustomerEntity $customer,
  128.         ?string $customerOriginReferrer,
  129.         Context $context
  130.     ): void {
  131.         $customerOrigin $this->customerOriginDetector->detect(
  132.             $customer,
  133.             $customerOriginReferrer
  134.         );
  135.         $this->customerRepository->upsert([
  136.             [
  137.                 'id' => $customer->getId(),
  138.                 'customFields' => \array_merge($customer->getCustomFields() ?? [], [
  139.                     WebshopConstants::CUSTOMER_ATTRIBUTE_ORIGIN => $customerOrigin,
  140.                 ]),
  141.             ],
  142.         ], $context);
  143.     }
  144.     /**
  145.      * Schreibt die eigene CustomerNumber eines Partners (BodymedCenter) als "mykey_partner" in die Bestellung,
  146.      * damit diese Bestellung in der eigenen Statistik des Partners gelistet wird.
  147.      */
  148.     private function addOwnCenterDataToOrder(OrderEntity $orderCustomerEntity $customerContext $context): void
  149.     {
  150.         $orderData = [
  151.             'id' => $order->getId(),
  152.             'customFields' => \array_merge($order->getCustomFields() ?? [], [
  153.                 Constants::MYKEY_ORDER_AFFILIATE_CUSTOMER_NUMBER_FIELD_KEY => $customer->getCustomerNumber(),
  154.                 WebshopConstants::ORDER_CUSTOM_FIELD_CUSTOMER_ORIGIN => WebshopConstants::CUSTOMER_ORIGIN_CENTER,
  155.             ]),
  156.         ];
  157.         $this->orderRepository->update([
  158.             $orderData,
  159.         ], $context);
  160.     }
  161.     /**
  162.      * Schreibt die CustomerNumber des kooperierenden BodymedCenters als "mykey_partner" in die Bestellung,
  163.      * damit diese als Kooperationsverkauf gelistet wird.
  164.      */
  165.     private function addPharmacyCooperationDataToOrder(OrderEntity $orderCustomerEntity $customerContext $context): void
  166.     {
  167.         $cooperationCenter $this->pharmacyCooperationService->getCooperationCenterForCustomer($customer$context);
  168.         if ($cooperationCenter instanceof BodymedCenterEntity
  169.             && null !== $cooperationCenter->getCustomerNumber()
  170.         ) {
  171.             $orderData = [
  172.                 'id' => $order->getId(),
  173.                 'customFields' => \array_merge($order->getCustomFields() ?? [], [
  174.                     Constants::MYKEY_ORDER_AFFILIATE_CUSTOMER_NUMBER_FIELD_KEY => $cooperationCenter->getCustomerNumber(),
  175.                     WebshopConstants::ORDER_CUSTOM_FIELD_CUSTOMER_ORIGIN => WebshopConstants::CUSTOMER_ORIGIN_COOPERATION,
  176.                     WebshopConstants::ORDER_CUSTOM_FIELD_COOP_AFFILIATION => [
  177.                         'coop_customer_number' => $cooperationCenter->getCustomerNumber(),
  178.                         'coop_affiliate_id' => $cooperationCenter->getAffiliateId(),
  179.                         'coop_name' => $cooperationCenter->getName(),
  180.                     ]
  181.                 ]),
  182.             ];
  183.             $this->orderRepository->update([
  184.                 $orderData,
  185.             ], $context);
  186.         }
  187.     }
  188. }