custom/plugins/fourtwosixProductShippingPrice/src/Subscriber/SetShippingPrice.php line 159

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace fourtwosix\ProductShippingPrice\Subscriber;
  4. use Shopware\Core\Checkout\Cart\Price\Struct\CartPrice;
  5. use Shopware\Core\Checkout\Cart\Event\CheckoutOrderPlacedEvent;
  6. use Shopware\Core\Checkout\Cart\Tax\Struct\CalculatedTax;
  7. use Shopware\Core\Checkout\Cart\Price\Struct\CalculatedPrice;
  8. use Shopware\Storefront\Page\Checkout\Cart\CheckoutCartPageLoadedEvent;
  9. use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent;
  10. use Shopware\Storefront\Page\Checkout\Finish\CheckoutFinishPageLoadedEvent;
  11. use Shopware\Storefront\Page\Checkout\Offcanvas\OffcanvasCartPageLoadedEvent;
  12. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  13. use Shopware\Core\Framework\Struct\ArrayEntity;
  14. class SetShippingPrice implements EventSubscriberInterface
  15. {
  16.     private $productRepo;
  17.     private $orderRepo;
  18.     private $orderDeliveriesRepo;
  19.     public function __construct(
  20.         $productRepo,
  21.         $orderRepo,
  22.         $orderDeliveriesRepo
  23.     ) {
  24.         $this->productRepo $productRepo;
  25.         $this->orderRepo $orderRepo;
  26.         $this->orderDeliveriesRepo $orderDeliveriesRepo;
  27.     }
  28.     public static function getSubscribedEvents(): array
  29.     {
  30.         return [
  31.             // Visualization hooks
  32.             OffcanvasCartPageLoadedEvent::class => 'onDisplayContent',
  33.             CheckoutCartPageLoadedEvent::class => 'onDisplayContent',
  34.             CheckoutConfirmPageLoadedEvent::class => 'onDisplayContent',
  35.             CheckoutFinishPageLoadedEvent::class => 'onDisplayContentFinish',
  36.             // True shipping costs set ->> 9999 to set priority higher then mails
  37.             CheckoutOrderPlacedEvent::class => ['onOrder', -9999],
  38.         ];
  39.     }
  40.     public function onOrder(CheckoutOrderPlacedEvent $event)
  41.     {
  42.         $order $event->getOrder();
  43.         // Load additional price from products
  44.         $totalAdditionalShippingPrice 0;
  45.         $shippingCostByTaxRate = [];
  46.         ## LOHOFF.IT - USE EXISTING METHOD ##
  47.         $totalAdditionalShippingPrice $this->calculateShippingPriceFromObjectWithLineItems($order);
  48.         // On one line item there is only one tax...
  49.         foreach ($order->getShippingCosts()->getTaxRules() as $calculatedTax) {
  50.             if (!isset($shippingCostByTaxRate[$calculatedTax->getTaxRate()])) {
  51.                 $shippingCostByTaxRate[$calculatedTax->getTaxRate()] = 0;
  52.             }
  53.             $shippingCostByTaxRate[$calculatedTax->getTaxRate()] += (
  54.                 $totalAdditionalShippingPrice *
  55.                 $calculatedTax->getPercentage() /
  56.                 100
  57.             );
  58.         }
  59.         // Eventually add the additional price
  60.         if ($totalAdditionalShippingPrice 0) {
  61.             $oldShippingCosts $order->getShippingCosts();
  62.             $shippingTotal $order->getShippingTotal();
  63.             $calculatedShippingCosts $shippingTotal $totalAdditionalShippingPrice;
  64.             $calculatedNetShippingCosts 0;
  65.             $calculatedShippingTaxes $oldShippingCosts->getCalculatedTaxes();
  66.             foreach ($calculatedShippingTaxes as $key => $calculatedTax) {
  67.                 $taxShippingCost 0;
  68.                 if (isset($shippingCostByTaxRate[$calculatedTax->getTaxRate()])) {
  69.                     $taxShippingCost $shippingCostByTaxRate[$calculatedTax->getTaxRate()];
  70.                 }
  71.                 $taxNetShippingCosts round($taxShippingCost / (+ ($calculatedTax->getTaxRate() / 100)), 2);
  72.                 $calculatedNetShippingCosts += $taxNetShippingCosts;
  73.                 $increment = new CalculatedTax(
  74.                     ($taxShippingCost $taxNetShippingCosts),
  75.                     $calculatedTax->getTaxRate(),
  76.                     $taxShippingCost
  77.                 );
  78.                 $calculatedShippingTaxes->get($key)->increment($increment);
  79.             }
  80.             $calculatedPriceTaxes $order->getPrice();
  81.             foreach ($calculatedPriceTaxes->getCalculatedTaxes() as $key => $calculatedTax) {
  82.                 $taxShippingCost 0;
  83.                 if (isset($shippingCostByTaxRate[$calculatedTax->getTaxRate()])) {
  84.                     $taxShippingCost $shippingCostByTaxRate[$calculatedTax->getTaxRate()];
  85.                 }
  86.                 $taxNetShippingCosts round($taxShippingCost / (+ ($calculatedTax->getTaxRate() / 100)), 2);
  87.                 $increment = new CalculatedTax(
  88.                     ($taxShippingCost $taxNetShippingCosts),
  89.                     $calculatedTax->getTaxRate(),
  90.                     $taxShippingCost
  91.                 );
  92.                 $calculatedPriceTaxes->getCalculatedTaxes()->get($key)->increment($increment);
  93.             }
  94.             $order->setShippingCosts(new CalculatedPrice(
  95.                 $calculatedShippingCosts,
  96.                 $calculatedShippingCosts,
  97.                 $calculatedShippingTaxes,
  98.                 $oldShippingCosts->getTaxRules()
  99.             ));
  100.             $order->setPrice(new CartPrice(
  101.                 (float)number_format($order->getPrice()->getNetPrice() + $calculatedNetShippingCosts2),
  102.                 $order->getPositionPrice() + $calculatedShippingCosts,
  103.                 $order->getPositionPrice(),
  104.                 $calculatedPriceTaxes->getCalculatedTaxes(),
  105.                 $calculatedPriceTaxes->getTaxRules(),
  106.                 $calculatedPriceTaxes->getTaxStatus()
  107.             ));
  108.             $newPayload = [
  109.                 "id" => $order->getId(),
  110.                 "versionId" => $order->getVersionId(),
  111.                 "shippingCosts" => $order->getShippingCosts(),
  112.                 "price" => $order->getPrice()
  113.             ];
  114.             $this->orderRepo->update([
  115.                 $newPayload
  116.             ], $event->getContext());
  117.             $order->getDeliveries()->first()->setShippingCosts(new CalculatedPrice(
  118.                 $calculatedShippingCosts,
  119.                 $calculatedShippingCosts,
  120.                 $calculatedShippingTaxes,
  121.                 $oldShippingCosts->getTaxRules()
  122.             ));
  123.             // Let's also update the OrderDeliveries entity
  124.             $newPayload = [
  125.                 "id" => $order->getDeliveries()->first()->getId(),
  126.                 "versionId" => $order->getDeliveries()->first()->getVersionId(),
  127.                 "shippingCosts" => $order->getDeliveries()->first()->getShippingCosts()
  128.             ];
  129.             $this->orderDeliveriesRepo->update([
  130.                 $newPayload
  131.             ], $event->getContext());
  132.         }
  133.     }
  134.     public function onDisplayContent($event)
  135.     {
  136.         $cart $event->getPage()->getCart();
  137.         $total_shipping_price $this->calculateShippingPriceFromObjectWithLineItems($cart);
  138.         $extensions = new ArrayEntity();
  139.         $extensions['total_shipping_price'] = $total_shipping_price;
  140.         $event->getPage()->addExtension("shippingStruct",$extensions);
  141.     }
  142.     public function onDisplayContentFinish($event)
  143.     {
  144.         $order $event->getPage()->getOrder();
  145.         $total_shipping_price $this->calculateShippingPriceFromObjectWithLineItems($order);
  146.         $extensions = new ArrayEntity();
  147.         $extensions['total_shipping_price'] = $total_shipping_price;
  148.         $extensions['total_shipping_price_already_in_total'] = $total_shipping_price;
  149.         $event->getPage()->addExtension("shippingStruct",$extensions);
  150.     }
  151.     private function calculateShippingPriceFromObjectWithLineItems($cartOrOrder) {
  152.         $total_additional_shipping_price 0;
  153.         foreach ($cartOrOrder->getLineItems() as $lineItem) {
  154.             ## LOHOFF.IT - ONLY TRY TO GET CUSTOM FIELD IF LINEITEM IS OF TYPE PRODUCT ##
  155.             if (($lineItem->getType() === 'product') && (
  156.                 isset($lineItem->getPayload()["customFields"]["shipping_price"]) && (
  157.                     /* @fourtwosix-edit: if the switch doesn't exists, then it's an old product that doesn't have the switch */
  158.                     !isset($lineItem->getPayload()["customFields"]["shipping_price_deactivate"]) || 
  159.                     !$lineItem->getPayload()["customFields"]["shipping_price_deactivate"]
  160.                 )
  161.             )) {
  162.                 $total_additional_shipping_price += (
  163.                     $lineItem->getPayload()["customFields"]["shipping_price"] *
  164.                     $lineItem->getQuantity()
  165.                 );
  166.             }
  167.         }
  168.         return $total_additional_shipping_price;
  169.     }
  170. }