src/EventSubscriber/Shipping/CarrierRatesSubscriber.php line 113

Open in your IDE?
  1. <?php
  2. namespace App\EventSubscriber\Shipping;
  3. use App\Ecommerce\Model\Order;
  4. use App\Model\Customer;
  5. use App\Model\Product;
  6. use App\Repository\OrderRepository;
  7. use Factory\CartBundle\Classes\Traits\Controller\GetCartTrait;
  8. use Factory\Shipping\CustomerServiceBundle\Classes\CSCarrier;
  9. use Factory\ShippingBundle\Classes\Carrier\DeAddress;
  10. use Factory\ShippingBundle\Classes\Carrier\SimplePackage;
  11. use Factory\ShippingBundle\Classes\Carrier\UsAddress;
  12. use Factory\ShippingBundle\Classes\ShippingEvents;
  13. use Factory\ShippingBundle\Contract\Carrier\AddressContract;
  14. use Factory\ShippingBundle\Contract\Carrier\PackageContract;
  15. use Factory\ShippingBundle\Event\ShippingEvent;
  16. use Pimcore;
  17. use Pimcore\Bundle\EcommerceFrameworkBundle\Factory;
  18. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  19. use Pimcore\Model\DataObject\Data\QuantityValue;
  20. use Symfony\Component\HttpFoundation\Request;
  21. use Symfony\Component\HttpFoundation\RequestStack;
  22. use Pimcore\Model\WebsiteSetting;
  23. use Pimcore\Model\DataObject\PriceSystemRule;
  24. class CarrierRatesSubscriber implements EventSubscriberInterface
  25. {
  26.     use GetCartTrait;
  27.     /**
  28.      * @var RequestStack
  29.      */
  30.     protected $requestStack;
  31.     /**
  32.      * @var OrderRepository
  33.      */
  34.     protected $orderRepository;
  35.     public static function getSubscribedEvents()
  36.     {
  37.         return [
  38.             ShippingEvents::GET_SINGLE_CARRIER_RATES_BEFORE => [
  39.                 ['updatePackageAndAddress'10]
  40.             ],
  41.             ShippingEvents::UPDATE_CARRIER_LIST => [
  42.                 ['updateCarriers'20]
  43.             ]
  44.         ];
  45.     }
  46.     public function __construct(RequestStack $requestStackOrderRepository $orderRepository)
  47.     {
  48.         $this->requestStack $requestStack;
  49.         $this->orderRepository $orderRepository;
  50.     }
  51.     /**
  52.      * This method is used by GetCartTrait
  53.      *
  54.      * @param string $serviceName
  55.      *
  56.      * @return object
  57.      */
  58.     protected function get(string $serviceName)
  59.     {
  60.         return Pimcore::getContainer()->get($serviceName);
  61.     }
  62.     /**
  63.      * @return null|Customer
  64.      */
  65.     protected function getUser()
  66.     {
  67.         $env Factory::getInstance()->getEnvironment();
  68.         if ($env->getCurrentUserId() > 0) {
  69.             return Customer::getById($env->getCurrentUserId());
  70.         }
  71.         return null;
  72.     }
  73.     public function updatePackageAndAddress(ShippingEvent $event)
  74.     {
  75.         if ($this->isRequestFromCsr()) {
  76.             // Pass to next listener
  77.             return;
  78.         }
  79.         $event->setArgument(
  80.             'package',
  81.             $this->getPackage($event->getArgument('package'), $event)
  82.         );
  83.         $event->setArgument(
  84.             'sourceAddress',
  85.             $this->getSourceAddress($event->getArgument('sourceAddress'), $event'default')
  86.         );
  87.         $event->setArgument(
  88.             'destinationAddress',
  89.             $this->getDestinationAddress($event->getArgument('destinationAddress'), $event)
  90.         );
  91.         $event->setArgument(
  92.             'options',
  93.             $this->getOptions($event->getArgument('options'), $event)
  94.         );
  95.     }
  96.     public function updateCarriers(ShippingEvent $event) {
  97.         $updatedCarrierList $event->getSubject();
  98.         $unsetCSShipping false;
  99.         if ($this->isQuoteProcess()) {
  100.             $user $this->getUser();
  101.             if ($user === null) {
  102.                 return;
  103.             }
  104.             $addressId $this->getRequest()->cookies->get('__billing_address_id');
  105.             if ($addressId == 'customer') {
  106.                 $address $user->getDefaultBillingAddressObject();
  107.             } else {
  108.                 $address $user->getAddress($addressId);
  109.             }
  110.             $division $this->getRequest()->cookies->get('__division');
  111.             $isEU false;
  112.             if ($address !== null && $division == 'Neuroscience') {
  113.                 $orderPriceSystemRule $this->getAddressPricingRule($division);
  114.                 $countryCode $address->getCountry();
  115.                 $isEU $this->getAddressIsEU($orderPriceSystemRule$countryCode);
  116.             }
  117.             if ($isEU) {
  118.                 foreach ($event->getSubject() as $key => $carrier) {
  119.                     if (!$carrier instanceof CSCarrier) {
  120.                         unset($updatedCarrierList[$key]);
  121.                     }
  122.                 }
  123.             } else {
  124.                 $unsetCSShipping true;
  125.             }
  126.         } else {
  127.             $unsetCSShipping true;
  128.         }
  129.         if ($unsetCSShipping) {
  130.             foreach ($event->getSubject() as $key => $carrier) {
  131.                 if ($carrier instanceof CSCarrier) {
  132.                     unset($updatedCarrierList[$key]);
  133.                 }
  134.             }
  135.         }
  136.         $event->setSubject($updatedCarrierList);
  137.     }
  138.     private function getAddressPricingRule($division)
  139.     {
  140.         $priceSystemRule = new PriceSystemRule\Listing();
  141.         $priceSystemRule->addConditionParam("`Name` LIKE ?"'%'.$division.'%');
  142.         return $priceSystemRule->current();
  143.     }
  144.     private function getAddressIsEU($orderPriceSystemRule$countryCode)
  145.     {
  146.         $actions $orderPriceSystemRule->getActions();
  147.         foreach ($actions as $action) {
  148.             if ($action->getLabel() == 'Europe') {
  149.                 if (in_array($countryCode$action->getCountries())) {
  150.                     return true;
  151.                 }
  152.                 return false;
  153.             }
  154.         }
  155.         return false;
  156.     }
  157.     protected function getPackage(PackageContract $packageShippingEvent $event)
  158.     {
  159.         $weights = [];
  160.         foreach ($this->getPackageItems() as $item) {
  161.             $weights[] = [
  162.                 'weight' => $item->getProduct()->getWeight(),
  163.                 'quantity' => $item->getCount()
  164.             ];
  165.         }
  166.         $package->setWeight($this->addQuantityValues($weights,'lb'));
  167.         return $package;
  168.     }
  169.     protected function getSourceAddress(AddressContract $sourceAddressShippingEvent $eventstring $destRegion 'default')
  170.     {
  171.         if ($setting WebsiteSetting::getByName($destRegion.'_storage_city')) {
  172.             $sourceAddress->setCity($setting->getData() ?? '');
  173.         }
  174.         if ($setting WebsiteSetting::getByName($destRegion.'_storage_zip_code')) {
  175.             $sourceAddress->setZipCode($setting->getData() ?? '');
  176.         }
  177.         if ($setting WebsiteSetting::getByName($destRegion.'_storage_country')) {
  178.             $sourceAddress->setCountryCode($setting->getData() ?? '');
  179.         }
  180.         return $sourceAddress;
  181.     }
  182.     protected function getDestinationAddress(AddressContract $destinationAddressShippingEvent $event)
  183.     {
  184.         $address $this->getAddress();
  185.         $destinationAddress->setCity($address->getCity());
  186.         $destinationAddress->setZipCode($address->getZipCode());
  187.         $destinationAddress->setCountryCode($address->getCountry());
  188.         $destinationAddress->setState($address->getState());
  189.         return $destinationAddress;
  190.     }
  191.     protected function getOptions(array $optionsShippingEvent $event)
  192.     {
  193.         return [];
  194.     }
  195.     protected function getAddress()
  196.     {
  197.         if ($this->isOrderingQuoteProcess()) {
  198.             $addressId $this->getRequest()->cookies->get('__order_shipping_address_id');
  199.         } else {
  200.             $addressId $this->getRequest()->cookies->get('__shipping_address_id');
  201.         }
  202.         if (!$user $this->getUser()) {
  203.             throw new \Exception("Couldn't get customer info!");
  204.         }
  205.         $address $user->getDefaultShippingAddressObject();
  206.         if ($addressId == 'delivery') {
  207.             $address $this->getAddressFromOrder();
  208.         } else {
  209.             $address $user->getAddress($addressId);
  210.         }
  211.         if (!$address) {
  212.             throw new \Exception("Customer must have default shipping address!");
  213.         }
  214.         return $address;
  215.     }
  216.     protected function getAddressFromOrder()
  217.     {
  218.         $order $this->getOrderFromReferer();
  219.         if (!$order) {
  220.             return null;
  221.         }
  222.         return $this->orderRepository->createAddressFromOrder('delivery'$order);
  223.     }
  224.     protected function getOrderFromReferer()
  225.     {
  226.         $httpReferer $this->getRequest()->server->get('HTTP_REFERER');
  227.         if (preg_match('/\/(order\-quote|checkout|quote)\/(\d+)\/(.*)$/'$httpReferer$matches)) {
  228.             return Order::getById($matches[2]);
  229.         }
  230.         if (preg_match('/\/(order\-quote|checkout|quote)\/(\w+)\/(.*)$/'$httpReferer$matches)) {
  231.             $path base64_decode(hex2bin($matches[2]));
  232.             return Order::getByPath($path);
  233.         }
  234.         return null;
  235.     }
  236.     /**
  237.      * @param  array $values
  238.      *
  239.      * @return QuantityValue
  240.      */
  241.     private function addQuantityValues(array $valuesstring $unit)
  242.     {
  243.         $value 0;
  244.         foreach ($values as $val) {
  245.             $value += $this->convert($val['weight'], $unit)->getValue() * $val['quantity'];
  246.         }
  247.         return new QuantityValue($value$unit);
  248.     }
  249.     /**
  250.      * @return Product[]
  251.      */
  252.     private function getPackageItems()
  253.     {
  254.         if ($this->isOrderingQuoteProcess()) {
  255.             $order $this->getOrderFromReferer();
  256.             return $order->getItems();
  257.         }
  258.         $division $this->getRequest()->cookies->get('__division');
  259.         $cartName $division.'_cart';
  260.         $cart $this->getCart($cartName);
  261.         return $cart->getItems();
  262.     }
  263.     /**
  264.      * @return boolean
  265.      */
  266.     private function isOrderingQuoteProcess(): bool
  267.     {
  268.         $httpReferer $this->getRequest()->server->get('HTTP_REFERER');
  269.         return preg_match('/\/(order\-quote)\/(.*)/'$httpReferer$matches);
  270.     }
  271.     /**
  272.      * @return boolean
  273.      */
  274.     private function isQuoteProcess(): bool
  275.     {
  276.         $httpReferer $this->getRequest()->server->get('HTTP_REFERER');
  277.         return preg_match('/\/(quote)\/(.*)/'$httpReferer$matches);
  278.     }
  279.     private function isRequestFromCsr()
  280.     {
  281.         return !!$this->getRequest()->get('order');
  282.     }
  283.     protected function getRequest(): Request
  284.     {
  285.         return $this->requestStack->getCurrentRequest();
  286.     }
  287.     /**
  288.      * @param QuantityValue $value
  289.      * @param string $targetUnit
  290.      *
  291.      * @return QuantityValue
  292.      */
  293.     private function convert(QuantityValue $valuestring $targetUnit)
  294.     {
  295.         return $value;
  296.     }
  297. }