custom/plugins/DvsnBundle/src/Subscriber/Core/Checkout/Cart/Order/OrderConverterSubscriber.php line 49

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. /**
  3.  * digitvision
  4.  *
  5.  * @category  digitvision
  6.  * @package   Shopware\Plugins\DvsnBundle
  7.  * @copyright (c) 2021 digitvision
  8.  */
  9. namespace Dvsn\Bundle\Subscriber\Core\Checkout\Cart\Order;
  10. use Dvsn\Bundle\Service\Cart\LineItemFactoryServiceInterface;
  11. use Shopware\Core\Checkout\Cart\LineItem\LineItem;
  12. use Shopware\Core\Checkout\Cart\Order\CartConvertedEvent;
  13. use Shopware\Core\Checkout\Cart\Price\QuantityPriceCalculator;
  14. use Shopware\Core\Checkout\Cart\Price\Struct\QuantityPriceDefinition;
  15. use Shopware\Core\System\SystemConfig\SystemConfigService;
  16. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  17. class OrderConverterSubscriber implements EventSubscriberInterface
  18. {
  19.     private QuantityPriceCalculator $quantityPriceCalculator;
  20.     private SystemConfigService $systemConfigService;
  21.     public function __construct(
  22.         QuantityPriceCalculator $quantityPriceCalculator,
  23.         SystemConfigService $systemConfigService
  24.     ) {
  25.         $this->quantityPriceCalculator $quantityPriceCalculator;
  26.         $this->systemConfigService $systemConfigService;
  27.     }
  28.     /**
  29.      * {@inheritDoc}
  30.      */
  31.     public static function getSubscribedEvents(): array
  32.     {
  33.         return [
  34.             CartConvertedEvent::class => 'onCartConverted'
  35.         ];
  36.     }
  37.     /**
  38.      * ...
  39.      *
  40.      * @param CartConvertedEvent $event
  41.      */
  42.     public function onCartConverted(CartConvertedEvent $event): void
  43.     {
  44.         if ((boolean) $this->systemConfigService->get('DvsnBundle.config.status'$event->getSalesChannelContext()->getSalesChannel()->getId()) === false) {
  45.             return;
  46.         }
  47.         if ($this->hasBundles($event->getConvertedCart()) === false) {
  48.             return;
  49.         }
  50.         if ((boolean) $this->systemConfigService->get('DvsnBundle.config.orderFlattenBundle'$event->getSalesChannelContext()->getSalesChannel()->getId()) === true) {
  51.             $this->flattenBundle($event);
  52.             if ((boolean) $this->systemConfigService->get('DvsnBundle.config.dropParentContainer'$event->getSalesChannelContext()->getSalesChannel()->getId()) === true) {
  53.                 $this->removeParent($event);
  54.             }
  55.         }
  56.         $this->resetLineItemType($event);
  57.         $this->fixLineItemPositions($event);
  58.     }
  59.     /**
  60.      * ...
  61.      *
  62.      * @param array $cart
  63.      *
  64.      * @return bool
  65.      */
  66.     private function hasBundles(array $cart): bool
  67.     {
  68.         foreach ($cart['lineItems'] as $lineItem) {
  69.             if ($lineItem['type'] === LineItemFactoryServiceInterface::BUNDLE_LINE_ITEM_TYPE) {
  70.                 return true;
  71.             }
  72.         }
  73.         return false;
  74.     }
  75.     /**
  76.      * ...
  77.      *
  78.      * @param CartConvertedEvent $event
  79.      */
  80.     private function resetLineItemType(CartConvertedEvent $event): void
  81.     {
  82.         // get the cart
  83.         $cart $event->getConvertedCart();
  84.         // loop every line item to make them products
  85.         foreach ($cart['lineItems'] as $i => $lineItem) {
  86.             switch ($lineItem['type']) {
  87.                 case LineItemFactoryServiceInterface::BUNDLE_PRODUCT_LINE_ITEM_TYPE:
  88.                     $cart['lineItems'][$i]['type'] = LineItem::PRODUCT_LINE_ITEM_TYPE;
  89.                     $cart['lineItems'][$i]['productId'] = $lineItem['payload']['dvsnBundleProductId'];
  90.                     break;
  91.             }
  92.         }
  93.         // save back
  94.         $event->setConvertedCart($cart);
  95.     }
  96.     /**
  97.      * ...
  98.      *
  99.      * @param CartConvertedEvent $event
  100.      */
  101.     private function flattenBundle(CartConvertedEvent $event): void
  102.     {
  103.         // get the cart
  104.         $cart $event->getConvertedCart();
  105.         // flatten the bundle items
  106.         foreach ($cart['lineItems'] as $i => $lineItem) {
  107.             switch ($lineItem['type']) {
  108.                 case LineItemFactoryServiceInterface::BUNDLE_LINE_ITEM_TYPE:
  109.                     $cart['lineItems'][$i]['priceDefinition'] = new QuantityPriceDefinition(
  110.                         0,
  111.                         $event->getSalesChannelContext()->buildTaxRules($lineItem['payload']['taxId']),
  112.                         $lineItem['quantity']
  113.                     );
  114.                     $cart['lineItems'][$i]['price'] = $this->quantityPriceCalculator->calculate(
  115.                         $lineItem['priceDefinition'],
  116.                         $event->getSalesChannelContext()
  117.                     );
  118.                     break;
  119.                 case LineItemFactoryServiceInterface::BUNDLE_PRODUCT_LINE_ITEM_TYPE:
  120.                 case LineItemFactoryServiceInterface::BUNDLE_DISCOUNT_LINE_ITEM_TYPE:
  121.                     $cart['lineItems'][$i]['payload']['dvsnBundleFormerParentId'] = $cart['lineItems'][$i]['parentId'];
  122.                     unset($cart['lineItems'][$i]['parentId']);
  123.                     break;
  124.             }
  125.         }
  126.         // save back
  127.         $event->setConvertedCart($cart);
  128.     }
  129.     /**
  130.      * ...
  131.      *
  132.      * @param CartConvertedEvent $event
  133.      */
  134.     private function removeParent(CartConvertedEvent $event): void
  135.     {
  136.         $cart $event->getConvertedCart();
  137.         foreach ($cart['lineItems'] as $i => $lineItem) {
  138.             if ($lineItem['type'] !== LineItemFactoryServiceInterface::BUNDLE_LINE_ITEM_TYPE) {
  139.                 continue;
  140.             }
  141.             unset($cart['lineItems'][$i]);
  142.             foreach ($cart['deliveries'] as $deliveryId => $delivery) {
  143.                 $positions = [];
  144.                 foreach ($delivery['positions'] as $j => $position) {
  145.                     if ($position['orderLineItemId'] !== $lineItem['id']) {
  146.                         $positions[] = $position;
  147.                         continue;
  148.                     }
  149.                     foreach ($cart['lineItems'] as $childLineItem) {
  150.                         if (!isset($childLineItem['payload']) || !is_array($childLineItem['payload']) || !isset($childLineItem['payload']['dvsnBundleFormerParentId'])) {
  151.                             continue;
  152.                         }
  153.                         if ($childLineItem['payload']['dvsnBundleFormerParentId'] !== $lineItem['id']) {
  154.                             continue;
  155.                         }
  156.                         $positions[] = [
  157.                             'id' => null,
  158.                             'price' => $childLineItem['price'],
  159.                             'orderLineItemId' => $childLineItem['id'],
  160.                             'orderLineItemVersionId' => $position['orderLineItemVersionId']
  161.                         ];
  162.                     }
  163.                 }
  164.                 $cart['deliveries'][$deliveryId]['positions'] = $positions;
  165.             }
  166.         }
  167.         $event->setConvertedCart($cart);
  168.     }
  169.     /**
  170.      * ...
  171.      *
  172.      * @param CartConvertedEvent $event
  173.      */
  174.     private function fixLineItemPositions(CartConvertedEvent $event): void
  175.     {
  176.         // get the cart
  177.         $cart $event->getConvertedCart();
  178.         // fix every position
  179.         foreach ($cart['lineItems'] as $key => $lineItem) {
  180.             // set position
  181.             $cart['lineItems'][$key]['position'] = $key 1;
  182.         }
  183.         // save back
  184.         $event->setConvertedCart($cart);
  185.     }
  186. }