custom/plugins/MyPaShopware/src/Subscriber/CartConversionSubscriber.php line 77

Open in your IDE?
  1. <?php
  2. namespace MyPa\Shopware\Subscriber;
  3. use MyPa\Shopware\Core\Content\ShippingOption\ShippingOptionEntity;
  4. use MyPa\Shopware\Defaults;
  5. use MyPa\Shopware\Service\Config\ConfigGenerator;
  6. use MyPa\Shopware\Service\Config\MyParcelCarriers;
  7. use MyParcelNL\Sdk\src\Model\Consignment\AbstractConsignment;
  8. use Psr\Log\LoggerInterface;
  9. use Shopware\Core\Checkout\Cart\Order\CartConvertedEvent;
  10. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
  11. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  12. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  13. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  14. class CartConversionSubscriber implements EventSubscriberInterface
  15. {
  16.     /**
  17.      * ShippingOptionEntity::FIELD_DELIVERY_TYPE is not needed because it will always be read from the checkout settings
  18.      * ShippingOptionEntity::FIELD_ONLY_RECIPIENT will only be read in defaults, not from checkout
  19.      */
  20.     private const SHIPPING_OPTIONS_WITH_DEFAULT = [
  21.         ShippingOptionEntity::FIELD_DELIVERY_DATE      => "",
  22.         ShippingOptionEntity::FIELD_REQUIRES_AGE_CHECK => "myParcelDefaultAgeCheck",
  23.         ShippingOptionEntity::FIELD_REQUIRES_SIGNATURE => "myParcelDefaultSignature",
  24.         ShippingOptionEntity::FIELD_ONLY_RECIPIENT     => "myParcelDefaultOnlyRecipient",
  25.         ShippingOptionEntity::FIELD_RETURN_IF_NOT_HOME => "myParcelDefaultReturnNotHome",
  26.         ShippingOptionEntity::FIELD_LARGE_FORMAT       => "myParcelDefaultLargeFormat",
  27.         ShippingOptionEntity::FIELD_PACKAGE_TYPE       => "myParcelDefaultPackageType",
  28.     ];
  29.     /**
  30.      * @var LoggerInterface
  31.      */
  32.     protected $logger;
  33.     /**
  34.      * @var ConfigGenerator
  35.      */
  36.     private $configReader;
  37.     /**
  38.      * @var EntityRepository
  39.      */
  40.     private $countryRepository;
  41.     /**
  42.      * @param LoggerInterface $logger
  43.      * @param ConfigGenerator $configReader
  44.      * @param EntityRepository $countryRepository
  45.      */
  46.     public function __construct(
  47.         LoggerInterface $logger,
  48.         ConfigGenerator $configReader,
  49.         EntityRepository $countryRepository
  50.     ){
  51.         $this->logger $logger;
  52.         $this->configReader $configReader;
  53.         $this->countryRepository $countryRepository;
  54.     }
  55.     /**
  56.      * @return string[]
  57.      */
  58.     public static function getSubscribedEvents()
  59.     {
  60.         return [
  61.             CartConvertedEvent::class => 'cartConverted',
  62.         ];
  63.     }
  64.     /**
  65.      * @param CartConvertedEvent $event
  66.      * @return void
  67.      */
  68.     public function cartConverted(CartConvertedEvent $event)
  69.     {
  70.         $myParcelExtension $event->getCart()->getExtension(Defaults::CART_EXTENSION_KEY);
  71.         if (null === $myParcelExtension) {
  72.             return;
  73.         }
  74.         $myParcelData $myParcelExtension->getVars();
  75.         $options $this->setGeneralDefaults($event->getSalesChannelContext()->getSalesChannelId());
  76.         //Cart extension data check if it is a myparcel shipping
  77.         if (!empty($myParcelData) && !empty($myParcelData['myparcel']['deliveryData'])) {
  78.             /** @var \stdClass $deliveryData */
  79.             $deliveryData $myParcelData['myparcel']['deliveryData'];
  80.             $deliveryData json_decode(json_encode($deliveryData), true);
  81.             foreach ($deliveryData as $key => $value) {
  82.                 switch ($key) {
  83.                     case 'deliveryType':
  84.                         $options[ShippingOptionEntity::FIELD_DELIVERY_TYPE] = AbstractConsignment::DELIVERY_TYPES_NAMES_IDS_MAP[$value ?? 'standard'];
  85.                         break;
  86.                     case 'date':
  87.                         $strDate \strtotime($value);
  88.                         if (!$strDate) {
  89.                             $strDate strtotime("+1 day");
  90.                         }
  91.                         $options[ShippingOptionEntity::FIELD_DELIVERY_DATE] = \date('Y-m-d'$strDate);
  92.                         break;
  93.                     case 'shipmentOptions':
  94.                         //Check if the option was even shown via 'allowSignature' and 'allowOnlyRecipient', otherwise use the given value
  95.                         $carrierId $deliveryData['carrier'];
  96.                         if (isset($value['only_recipient'])
  97.                             && $this->configReader->isSettingEnabled(
  98.                                 $event->getSalesChannelContext()->getSalesChannelId(),
  99.                                 'allowOnlyRecipient',
  100.                                 MyParcelCarriers::NPM_CARRIER_TO_CONFIG_CARRIER[$carrierId]
  101.                             )
  102.                         ) {
  103.                             $options[ShippingOptionEntity::FIELD_ONLY_RECIPIENT] = $value['only_recipient'];
  104.                         }
  105.                         if (isset($value['signature'])
  106.                             && $this->configReader->isSettingEnabled(
  107.                                 $event->getSalesChannelContext()->getSalesChannelId(),
  108.                                 'allowSignature',
  109.                                 MyParcelCarriers::NPM_CARRIER_TO_CONFIG_CARRIER[$carrierId]
  110.                             )
  111.                         ) {
  112.                             $options[ShippingOptionEntity::FIELD_REQUIRES_SIGNATURE] = $value['signature'];
  113.                         }
  114.                         break;
  115.                     case 'carrier':
  116.                         $options[ShippingOptionEntity::FIELD_CARRIER_ID] = Defaults::CARRIER_TO_ID[$value];
  117.                         break;
  118.                     case 'pickupLocation':
  119.                         $options[ShippingOptionEntity::FIELD_PICKUP_LOCATION_ID] = (int) $value['location_code'];
  120.                         $options[ShippingOptionEntity::FIELD_PICKUP_NAME] = $value['location_name'];
  121.                         $options[ShippingOptionEntity::FIELD_PICKUP_STREET] = $value['street'];
  122.                         $options[ShippingOptionEntity::FIELD_PICKUP_NUMBER] = $value['number'] . $value['number_suffix'];
  123.                         $options[ShippingOptionEntity::FIELD_PICKUP_POSTAL_CODE] = $value['postal_code'];
  124.                         $options[ShippingOptionEntity::FIELD_PICKUP_CITY] = $value['city'];
  125.                         $options[ShippingOptionEntity::FIELD_PICKUP_CC] = $value['cc'];
  126.                         $options[ShippingOptionEntity::FIELD_RETAIL_NETWORK_ID] = $value['retail_network_id'];
  127.                         $this->setShippingAddress($event$options);
  128.                         break;
  129.                     case 'packageType':
  130.                         $options[ShippingOptionEntity::FIELD_PACKAGE_TYPE] = AbstractConsignment::PACKAGE_TYPES_NAMES_IDS_MAP[$value ?? 'package'];
  131.                 }
  132.             }
  133.         }
  134.         //Rest of the data will be done in OrderPlacedSubscriber, this ferries the data there
  135.         $event->setConvertedCart(array_merge($event->getConvertedCart(), ['customFields' => [Defaults::MYPARCEL_DELIVERY_OPTIONS_KEY => $options]]));
  136.     }
  137.     /**
  138.      * Sets all the defaults for values that will not be filled but the implementation of createOrUpdateShippingOptions()
  139.      * still needs.
  140.      *
  141.      * @param string $salesChannelId
  142.      * @return array
  143.      */
  144.     private function setGeneralDefaults(string $salesChannelId): array
  145.     {
  146.         $options = [];
  147.         foreach (self::SHIPPING_OPTIONS_WITH_DEFAULT as $key => $value) {
  148.             switch ($key) {
  149.                 case ShippingOptionEntity::FIELD_DELIVERY_DATE:
  150.                     $options[ShippingOptionEntity::FIELD_DELIVERY_DATE] = \date('Y-m-d'strtotime("+1 day"));
  151.                     break;
  152.                 case ShippingOptionEntity::FIELD_REQUIRES_AGE_CHECK:
  153.                     $options[ShippingOptionEntity::FIELD_REQUIRES_AGE_CHECK] = $this->configReader->getConfigBool($salesChannelId$value);
  154.                     break;
  155.                 case ShippingOptionEntity::FIELD_REQUIRES_SIGNATURE:
  156.                     $options[ShippingOptionEntity::FIELD_REQUIRES_SIGNATURE] = $this->configReader->getConfigBool($salesChannelId$value);
  157.                     break;
  158.                 case ShippingOptionEntity::FIELD_ONLY_RECIPIENT:
  159.                     $options[ShippingOptionEntity::FIELD_ONLY_RECIPIENT] = $this->configReader->getConfigBool($salesChannelId$value);
  160.                     break;
  161.                 case ShippingOptionEntity::FIELD_RETURN_IF_NOT_HOME:
  162.                     $options[ShippingOptionEntity::FIELD_RETURN_IF_NOT_HOME] = $this->configReader->getConfigBool($salesChannelId$value);
  163.                     break;
  164.                 case ShippingOptionEntity::FIELD_LARGE_FORMAT:
  165.                     $options[ShippingOptionEntity::FIELD_LARGE_FORMAT] = $this->configReader->getConfigBool($salesChannelId$value);
  166.                     break;
  167.                 case ShippingOptionEntity::FIELD_PACKAGE_TYPE:
  168.                     $options[ShippingOptionEntity::FIELD_PACKAGE_TYPE] = $this->configReader->getConfigInt($salesChannelId$value);
  169.                     break;
  170.             }
  171.         }
  172.         return $options;
  173.     }
  174.     /**
  175.      * @param CartConvertedEvent $event
  176.      * @param $value
  177.      * @return void
  178.      */
  179.     protected function setShippingAddress(CartConvertedEvent $event, array $options): void
  180.     {
  181.         $cart $event->getConvertedCart();
  182.         // copy shippingOrderAddress to addresses when no separate billing address is used
  183.         $billingAddressId $cart['billingAddressId'];
  184.         $orderAddress $cart['deliveries'][0]['shippingOrderAddress'];
  185.         if (!isset($cart['addresses'])) {
  186.             $cart['addresses'] = [$orderAddress];
  187.         } elseif (!array_filter($cart['addresses'], function ($address) use ($billingAddressId) {
  188.             return $address['id'] === $billingAddressId;
  189.         })) {
  190.             $cart['addresses'][] = $orderAddress;
  191.         }
  192.         // find country by country code iso 2
  193.         $country $this->countryRepository->search(
  194.             (new Criteria())->addFilter(new EqualsFilter('iso'$options[ShippingOptionEntity::FIELD_PICKUP_CC])),
  195.             $event->getSalesChannelContext()->getContext()
  196.         )->first();
  197.         // manipulate shipping address, remove id to prevent it being stored in the account
  198.         $cart['deliveries'][0]['shippingOrderAddress']['id'] = null;
  199.         $cart['deliveries'][0]['shippingOrderAddress']['company'] = $options[ShippingOptionEntity::FIELD_PICKUP_NAME];
  200.         $cart['deliveries'][0]['shippingOrderAddress']['department'] = 'pickup point';
  201.         $cart['deliveries'][0]['shippingOrderAddress']['street'] = $options[ShippingOptionEntity::FIELD_PICKUP_STREET] . ' ' $options[ShippingOptionEntity::FIELD_PICKUP_NUMBER];
  202.         $cart['deliveries'][0]['shippingOrderAddress']['zipcode'] = $options[ShippingOptionEntity::FIELD_PICKUP_POSTAL_CODE];
  203.         $cart['deliveries'][0]['shippingOrderAddress']['city'] = $options[ShippingOptionEntity::FIELD_PICKUP_CITY];
  204.         if (isset($country)) {
  205.             $cart['deliveries'][0]['shippingOrderAddress']['countryId'] = $country->getId();
  206.         }
  207.         $event->setConvertedCart($cart);
  208.     }
  209. }