custom/plugins/PickwareDhl/src/PreferredDelivery/Subscriber/TransferPreferredDeliveryServiceInformationSubscriber.php line 67

Open in your IDE?
  1. <?php
  2. /*
  3.  * Copyright (c) Pickware GmbH. All rights reserved.
  4.  * This file is part of software that is released under a proprietary license.
  5.  * You must not copy, modify, distribute, make publicly available, or execute
  6.  * its contents or parts thereof without express permission by the copyright
  7.  * holder, unless otherwise permitted by law.
  8.  */
  9. declare(strict_types=1);
  10. namespace Pickware\PickwareDhl\PreferredDelivery\Subscriber;
  11. use DateTime;
  12. use Pickware\DalBundle\EntityManager;
  13. use Pickware\PickwareDhl\PickwareDhl;
  14. use Pickware\PickwareDhl\SalesChannelContext\Model\SalesChannelApiContextDefinition;
  15. use Pickware\PickwareDhl\SalesChannelContext\Model\SalesChannelApiContextEntity;
  16. use Pickware\ShippingBundle\Config\Model\ShippingMethodConfigDefinition;
  17. use Pickware\ShippingBundle\Config\Model\ShippingMethodConfigEntity;
  18. use Pickware\ShippingBundle\Shipment\ShipmentBlueprintCreatedEvent;
  19. use Shopware\Core\Checkout\Cart\Order\CartConvertedEvent;
  20. use Shopware\Core\Checkout\Order\OrderDefinition;
  21. use Shopware\Core\Checkout\Order\OrderEntity;
  22. use Shopware\Core\Framework\Context;
  23. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  24. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  25. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  26. class TransferPreferredDeliveryServiceInformationSubscriber implements EventSubscriberInterface
  27. {
  28.     public const CUSTOM_FIELD_PREFIX 'pickware_dhl_';
  29.     public const PREFERRED_DAY 'preferred_day';
  30.     public const PREFERRED_LOCATION 'preferred_location';
  31.     public const PREFERRED_NEIGHBOUR 'preferred_neighbour';
  32.     public const NO_NEIGHBOUR_DELIVERY 'no_neighbour_delivery';
  33.     public const PREFERRED_DELIVERY_SERVICES__STOREFRONT_CONFIG_MAPPING = [
  34.         self::PREFERRED_DAY => 'showPreferredDay',
  35.         self::PREFERRED_LOCATION => 'showPreferredLocation',
  36.         self::PREFERRED_NEIGHBOUR => 'showPreferredNeighbour',
  37.         self::NO_NEIGHBOUR_DELIVERY => 'showNoNeighbourDelivery',
  38.     ];
  39.     public const PREFERRED_DELIVERY_SERVICES__SHIPMENT_CONFIG_MAPPING = [
  40.         self::PREFERRED_DAY => 'preferredDay',
  41.         self::PREFERRED_LOCATION => 'preferredLocation',
  42.         self::PREFERRED_NEIGHBOUR => 'preferredNeighbour',
  43.         self::NO_NEIGHBOUR_DELIVERY => 'noNeighbourDelivery',
  44.     ];
  45.     private EntityManager $entityManager;
  46.     public function __construct(EntityManager $entityManager)
  47.     {
  48.         $this->entityManager $entityManager;
  49.     }
  50.     public static function getSubscribedEvents(): array
  51.     {
  52.         return [
  53.             CartConvertedEvent::class => 'onCartConverted',
  54.             ShipmentBlueprintCreatedEvent::EVENT_NAME => 'onShipmentBlueprintCreated',
  55.         ];
  56.     }
  57.     public function onCartConverted(CartConvertedEvent $event): void
  58.     {
  59.         /** @var SalesChannelApiContextEntity $pickwareSalesChannelContext */
  60.         $pickwareSalesChannelContext $this->entityManager->findOneBy(
  61.             SalesChannelApiContextDefinition::class,
  62.             (new Criteria())->addFilter(new EqualsFilter('salesChannelContextToken'$event->getSalesChannelContext()->getToken())),
  63.             $event->getContext(),
  64.         );
  65.         if (!$pickwareSalesChannelContext) {
  66.             return;
  67.         }
  68.         $shippingMethodConfigCriteria = new Criteria();
  69.         $shippingMethodConfigCriteria->addFilter(new EqualsFilter(
  70.             'shippingMethodId',
  71.             $event->getSalesChannelContext()->getShippingMethod()->getId(),
  72.         ));
  73.         /** @var ShippingMethodConfigEntity $shippingMethodConfiguration */
  74.         $shippingMethodConfiguration $this->entityManager->findOneBy(
  75.             ShippingMethodConfigDefinition::class,
  76.             $shippingMethodConfigCriteria,
  77.             $event->getContext(),
  78.         );
  79.         if ($shippingMethodConfiguration === null || $shippingMethodConfiguration->getCarrierTechnicalName() !== PickwareDhl::CARRIER_TECHNICAL_NAME_DHL) {
  80.             return;
  81.         }
  82.         $preferredDeliverySettings $pickwareSalesChannelContext->getValue(['dhl_preferred_delivery']) ?? [];
  83.         // This filters out all settings configured by the user for which either no mapping to a shipment config exists
  84.         // or the shipment config is configured such that the setting should not be enabled.
  85.         $filteredPreferredDeliverySettings array_filter($preferredDeliverySettings, function ($key) use ($shippingMethodConfiguration) {
  86.             if (!array_key_exists($keyself::PREFERRED_DELIVERY_SERVICES__STOREFRONT_CONFIG_MAPPING)) {
  87.                 return false;
  88.             }
  89.             return $shippingMethodConfiguration->getStorefrontConfig()[self::PREFERRED_DELIVERY_SERVICES__STOREFRONT_CONFIG_MAPPING[$key]] ?? null;
  90.         }, ARRAY_FILTER_USE_KEY);
  91.         if (array_key_exists(self::NO_NEIGHBOUR_DELIVERY$filteredPreferredDeliverySettings)) {
  92.             $filteredPreferredDeliverySettings[self::NO_NEIGHBOUR_DELIVERY] = (bool) $filteredPreferredDeliverySettings[self::NO_NEIGHBOUR_DELIVERY];
  93.         }
  94.         $convertedCart $event->getConvertedCart();
  95.         $convertedCart['customFields'] = $convertedCart['customFields'] ?? [];
  96.         foreach ($filteredPreferredDeliverySettings as $settingKey => $settingValue) {
  97.             $convertedCart['customFields'][self::CUSTOM_FIELD_PREFIX $settingKey] = $settingValue;
  98.         }
  99.         $event->setConvertedCart($convertedCart);
  100.         $this->removePreferredDeliveryServiceInformationFromContext($pickwareSalesChannelContext$event->getContext());
  101.     }
  102.     public function onShipmentBlueprintCreated(ShipmentBlueprintCreatedEvent $event): void
  103.     {
  104.         /** @var OrderEntity $order */
  105.         $order $this->entityManager->getByPrimaryKey(
  106.             OrderDefinition::class,
  107.             $event->getOrderId(),
  108.             $event->getContext(),
  109.         );
  110.         $preferredServicesInformation = [];
  111.         foreach ($order->getCustomFields() ?? [] as $key => $value) {
  112.             if (!str_starts_with($keyself::CUSTOM_FIELD_PREFIX)) {
  113.                 continue;
  114.             }
  115.             $keyWithoutPrefix str_replace(self::CUSTOM_FIELD_PREFIX''$key);
  116.             if (in_array($keyWithoutPrefixarray_keys(self::PREFERRED_DELIVERY_SERVICES__SHIPMENT_CONFIG_MAPPING))) {
  117.                 $preferredServicesInformation[$keyWithoutPrefix] = $value;
  118.             }
  119.         }
  120.         // The custom field stores this as a datetime value (with hours, minutes and seconds) to ease configuring it
  121.         // in the custom fields of the order. The shipment config itself should only process dates in Y-m-d format.
  122.         if (isset($preferredServicesInformation[self::PREFERRED_DAY])) {
  123.             $preferredServicesInformation[self::PREFERRED_DAY] = (new DateTime(
  124.                 $preferredServicesInformation[self::PREFERRED_DAY],
  125.             ))->format('Y-m-d');
  126.         }
  127.         $shipmentBlueprint $event->getShipmentBlueprint();
  128.         $shipmentConfig $shipmentBlueprint->getShipmentConfig();
  129.         foreach ($preferredServicesInformation as $key => $value) {
  130.             $shipmentConfig[self::PREFERRED_DELIVERY_SERVICES__SHIPMENT_CONFIG_MAPPING[$key]] = $value;
  131.         }
  132.         $shipmentBlueprint->setShipmentConfig($shipmentConfig);
  133.     }
  134.     private function removePreferredDeliveryServiceInformationFromContext(
  135.         SalesChannelApiContextEntity $pickwareSalesChannelContextEntity,
  136.         Context                      $context
  137.     ): void {
  138.         $contextPayload $pickwareSalesChannelContextEntity->getPayload();
  139.         unset($contextPayload['dhl_preferred_delivery']);
  140.         $this->entityManager->update(
  141.             SalesChannelApiContextDefinition::class,
  142.             [[
  143.                 'id' => $pickwareSalesChannelContextEntity->getId(),
  144.                 'salesChannelContextToken' => $pickwareSalesChannelContextEntity->getSalesChannelContextToken(),
  145.                 'payload' => $contextPayload,
  146.             ],
  147.             ],
  148.             $context,
  149.         );
  150.     }
  151. }