custom/static-plugins/GlobusSW6/src/Subscriber/Cart/CartActionSubscriber.php line 46

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace GlobusSW6\Subscriber\Cart;
  3. use GlobusSW6\Core\IaneoDefaults;
  4. use GlobusSW6\Service\Cart\ShippingMethodService;
  5. use Shopware\Core\Checkout\Cart\Event\BeforeLineItemAddedEvent;
  6. use Shopware\Core\Checkout\Cart\Event\BeforeLineItemRemovedEvent;
  7. use Shopware\Core\Checkout\Cart\LineItem\LineItem;
  8. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  9. use Psr\Log\LoggerInterface;
  10. class CartActionSubscriber implements EventSubscriberInterface
  11. {
  12.     /** @var LoggerInterface */
  13.     private LoggerInterface $logger;
  14.     /** @var ShippingMethodService */
  15.     private $shippingMethodService;
  16.     /**
  17.      * @param LoggerInterface $logger
  18.      * @param ShippingMethodService $shippingMethodService
  19.      */
  20.     public function __construct(LoggerInterface $loggerShippingMethodService $shippingMethodService)
  21.     {
  22.         $this->logger $logger;
  23.         $this->shippingMethodService $shippingMethodService;
  24.     }
  25.     public static function getSubscribedEvents(): array
  26.     {
  27.         return [
  28.             BeforeLineItemAddedEvent::class => 'beforeLineItemAdded',
  29.             BeforeLineItemRemovedEvent::class => 'beforeLineItemRemoved'
  30.         ];
  31.     }
  32.     /**
  33.      * @param BeforeLineItemAddedEvent $event
  34.      * @throws \Exception
  35.      *
  36.      * Note: currently (sw-6-4-5-1) only the before-events allow to add extensions to the cart
  37.      */
  38.     public function beforeLineItemAdded(BeforeLineItemAddedEvent $event): void
  39.     {
  40.         $cart $event->getCart();
  41.         $addedLI $event->getLineItem();
  42.         $cartLIs = clone $cart->getLineItems();
  43.         try {
  44.             $salesChannelId $event->getContext()->getSource()->getSalesChannelId();
  45.         } catch (\Throwable $t) {
  46.             $this->logger->info('Unable to detect salesChannelId. Use Baumarkt ID as fallback : ' $t->getMessage());
  47.             $salesChannelId IaneoDefaults::SALES_CHANNEL_BAUMARKT;
  48.         }
  49.         if ($addedLI->getType() !== 'product') {
  50.             return;
  51.         }
  52.         /** @var LineItem $cartLI */
  53.         foreach ($cartLIs as $key => $cartLI) {
  54.             $cartLiExtension $cartLI->getExtensions();
  55.             if (!array_key_exists('ianeoOrderType'$cartLiExtension) || $cartLiExtension['ianeoOrderType']['orderType'] === 'reserveInStore') {
  56.                 $cartLIs->remove($key);
  57.             }
  58.         }
  59.         $liExtensions $addedLI->getExtensions();
  60.         if (!array_key_exists('ianeoOrderType'$liExtensions)) {
  61.             return;
  62.         }
  63.         // reservation cart
  64.         if ($liExtensions['ianeoOrderType']['orderType'] === 'reserveInStore' && $cartLIs->count() === 0) {
  65.             $this->shippingMethodService->changeShippingMethod(IaneoDefaults::SHIPPING_METHOD_GLOBUS_PICKUP$cart$event->getSalesChannelContext());
  66.             return;
  67.         }
  68.         if ($liExtensions['ianeoOrderType']['orderType'] === 'reserveInStore' && $cartLIs->count() > 0) {
  69.             return;
  70.         }
  71.         $lineItemIds array_merge($cartLIs->getReferenceIds(), [$addedLI->getReferencedId()]);
  72.         $shippingMethods $this->shippingMethodService->getShippingMethods($lineItemIds$salesChannelId);
  73.         if (!array_key_exists($addedLI->getReferencedId(), $shippingMethods)) {
  74.             $this->logger->info('Unable to detect shippingMethod for ' $addedLI->getId());
  75.             throw new \Exception('Unable to detect shippingMethod for ' $addedLI->getId());
  76.         }
  77.         $shippingMethodofAddedLI $shippingMethods[$addedLI->getReferencedId()];
  78.         // check shipping method of cart and compare if with new lineitem. Select shipping method of higher priority
  79.         $extensions $cart->getExtensions();
  80.         if (!array_key_exists('selectedShippingMethod'$extensions)) {
  81.             $this->shippingMethodService->changeShippingMethod($shippingMethodofAddedLI$cart$event->getSalesChannelContext());
  82.         } else {
  83.             try {
  84.                 /** @var string $selectedShippingMethod */
  85.                 $selectedShippingMethod $extensions['selectedShippingMethod']['shippingMethod'];
  86.             } catch (\Throwable $t) {
  87.                 $selectedShippingMethod $extensions['selectedShippingMethod']; // handling of old carts that still have a wrong structure
  88.             }
  89.             if ($this->shippingMethodService->comparePriority($shippingMethodofAddedLI$selectedShippingMethod)) {
  90.                 $this->shippingMethodService->changeShippingMethod($shippingMethodofAddedLI$cart$event->getSalesChannelContext());
  91.             }
  92.         }
  93.     }
  94.     /**
  95.      * @param BeforeLineItemRemovedEvent $event
  96.      * @throws \Exception
  97.      *
  98.      * Note: currently (sw-6-4-5-1) only the before-events allow to add extensions to the cart
  99.      */
  100.     public function beforeLineItemRemoved(BeforeLineItemRemovedEvent $event): void
  101.     {
  102.         $removedLI $event->getLineItem();
  103.         $liExtensions $removedLI->getExtensions();
  104.         if (!array_key_exists('ianeoOrderType'$liExtensions)) {
  105.             return;
  106.         }
  107.         if ($liExtensions['ianeoOrderType']['orderType'] === 'reserveInStore') {
  108.             return;
  109.         }
  110.         if ($removedLI->getType() !== 'product') {
  111.             return;
  112.         }
  113.         try {
  114.             $salesChannelId $event->getContext()->getSource()->getSalesChannelId();
  115.         } catch (\Throwable $t) {
  116.             $this->logger->info('Unable to detect salesChannelId. Use Baumarkt ID as fallback : ' $t->getMessage());
  117.             $salesChannelId IaneoDefaults::SALES_CHANNEL_BAUMARKT;
  118.         }
  119.         $cart $event->getCart();
  120.         $cartLIs = clone $cart->getLineItems();
  121.         // remove non-product-type lineItems from calculation
  122.         foreach ($cartLIs as $id => $cartLI) {
  123.             $cartLiExtension $cartLI->getExtensions();
  124.             if (!array_key_exists('ianeoOrderType'$cartLiExtension)) {
  125.                 $cartLIs->remove($id);
  126.                 continue;
  127.             }
  128.             if ($cartLiExtension['ianeoOrderType']['orderType'] === 'reserveInStore' || $cartLI->getType() !== 'product') {
  129.                 $cartLIs->remove($id);
  130.                 continue;
  131.             }
  132.         }
  133.         if (count($cartLIs) === 0) {
  134.             // set cart shipping method to reserveInStore
  135.             $this->shippingMethodService->changeShippingMethod(IaneoDefaults::SHIPPING_METHOD_GLOBUS_DHL_BAUMARKT$cart$event->getSalesChannelContext());
  136.             return;
  137.         }
  138.         $shippingMethods $this->shippingMethodService->getShippingMethods($cartLIs->getReferenceIds(), $salesChannelId);
  139.         // check which shipping method now has highest priority
  140.         $highestPriorityShippingMethod $this->shippingMethodService->getHighestPriorityShippingMethod($shippingMethods);
  141.         if (is_null($highestPriorityShippingMethod)){
  142.             $this->logger->info('Unable to detect shippingMethod of highest priority: ' $cart->getToken());
  143.             throw new \Exception('Unable to detect shippingMethod of highest priority: ' $cart->getToken());
  144.         }
  145.         $extensions $cart->getExtensions();
  146.         if (!array_key_exists('selectedShippingMethod'$extensions)) {
  147.             $this->logger->info('No shippingMethod selected for cart: ' $cart->getToken());
  148.             throw new \Exception('No shippingMethod selected for cart: ' $cart->getToken());
  149.         }
  150.         if ($highestPriorityShippingMethod !== $extensions['selectedShippingMethod']['shippingMethod']) {
  151.             $this->shippingMethodService->changeShippingMethod($highestPriorityShippingMethod$cart$event->getSalesChannelContext());
  152.         }
  153.     }
  154. }