custom/plugins/WabsProductPreorder/src/Subscriber/FrontendSubscriber.php line 67

Open in your IDE?
  1. <?php
  2. namespace Wabs\ProductPreorder\Subscriber;
  3. use Shopware\Core\Checkout\Cart\Event\BeforeLineItemAddedEvent;
  4. use Shopware\Core\Checkout\Cart\Event\CheckoutOrderPlacedEvent;
  5. use Shopware\Core\Checkout\Order\OrderEntity;
  6. use Shopware\Core\Content\Product\Events\ProductListingCriteriaEvent;
  7. use Shopware\Core\Content\Product\ProductCollection;
  8. use Shopware\Core\Content\Product\ProductEntity;
  9. use Shopware\Core\Content\Product\ProductEvents;
  10. use Shopware\Core\Content\Product\SalesChannel\Price\AbstractProductPriceCalculator;
  11. use Shopware\Core\Content\Property\Aggregate\PropertyGroupOption\PropertyGroupOptionEntity;
  12. use Shopware\Core\Framework\Context;
  13. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
  14. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  15. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityLoadedEvent;
  16. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  17. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  18. use Shopware\Core\Framework\Struct\ArrayStruct;
  19. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  20. use Wabs\ProductPreorder\Service\Install\CustomFieldSetService\CustomFieldSetService;
  21. use Wabs\ProductPreorder\Service\Product\ProductPreorderService;
  22. class FrontendSubscriber implements EventSubscriberInterface
  23. {
  24.     private EntityRepositoryInterface $orderRepository;
  25.     private EntityRepositoryInterface $productRepository;
  26.     private EntityRepository $wareneingangRepository;
  27.     private ProductPreorderService $productPreorderService;
  28.     private AbstractProductPriceCalculator $preorderPriceCalculator;
  29.     /**
  30.      * @param EntityRepositoryInterface $orderRepository
  31.      * @param EntityRepositoryInterface $productRepository
  32.      * @param ProductPreorderService $productPreorderService
  33.      * @param AbstractProductPriceCalculator $preorderPriceCalculator
  34.      * @param EntityRepository $wareneingangRepository
  35.      */
  36.     public function __construct(
  37.         EntityRepositoryInterface $orderRepository,
  38.         EntityRepositoryInterface $productRepository,
  39.         ProductPreorderService $productPreorderService,
  40.         AbstractProductPriceCalculator $preorderPriceCalculator,
  41.         \Shopware\Core\Framework\DataAbstractionLayer\EntityRepository $wareneingangRepository
  42.     ) {
  43.         $this->orderRepository $orderRepository;
  44.         $this->productRepository $productRepository;
  45.         $this->productPreorderService $productPreorderService;
  46.         $this->preorderPriceCalculator $preorderPriceCalculator;
  47.         $this->wareneingangRepository $wareneingangRepository;
  48.     }
  49.     public static function getSubscribedEvents(): array
  50.     {
  51.         return [
  52.             CheckoutOrderPlacedEvent::class => 'onOrderPlaced',
  53.             BeforeLineItemAddedEvent::class => 'onBeforeLineItemAdded',
  54.             ProductEvents::PRODUCT_LOADED_EVENT => 'onProductLoaded',
  55.             ProductEvents::PRODUCT_LISTING_CRITERIA => 'addPropertiesAssociation'
  56.         ];
  57.     }
  58.     public function onOrderPlaced(CheckoutOrderPlacedEvent $event)
  59.     {
  60.         $order $event->getOrder();
  61.         if ($this->isPreorder($order$event->getContext())) {
  62.             $this->orderRepository->update([
  63.                 [
  64.                     'id' => $order->getId(),
  65.                     'customFields' => [
  66.                         CustomFieldSetService::WABS_PRODUCT_PREORDER_ORDER_IS_PREORDER_FIELD => true
  67.                     ]
  68.                 ]
  69.             ], $event->getContext());
  70.         }
  71.     }
  72.     private function isPreorder(OrderEntity $orderContext $context)
  73.     {
  74.         $orderLineItems $order->getLineItems();
  75.         $isPreorder true;
  76.         $productIds = [];
  77.         foreach ($orderLineItems as $orderLineItem) {
  78.             $productIds[] = $orderLineItem->getProductId();
  79.         }
  80.         try {
  81.             /** @var ProductCollection $products */
  82.             $products $this->productRepository->search(
  83.                 (new Criteria($productIds))->addAssociation('properties')->addAssociation('properties.group')
  84.                 , $context);
  85.         } catch (\Exception $e) {
  86.             return false;
  87.         }
  88.         if ($products->count()) {
  89.             foreach ($products as $product) {
  90.                 /** @var PropertyGroupOptionEntity $property */
  91.                 $productPreorder $this->productPreorderService->isPreorder($product);
  92.                 if (!$productPreorder) {
  93.                     $isPreorder false;
  94.                     break;
  95.                 }
  96.             }
  97.         }
  98.         return $isPreorder;
  99.     }
  100.     public function onBeforeLineItemAdded(BeforeLineItemAddedEvent $event)
  101.     {
  102.         $lineItem $event->getLineItem();
  103.         if ($lineItem->getType() === 'product') {
  104.             /** @var ProductEntity $product */
  105.             $product $this->productRepository->search((new Criteria([$lineItem->getReferencedId()]))->addAssociation('properties')->addAssociation('properties.group'),
  106.                 $event->getContext())->first();
  107.             if ($product && $product->getActive() &&
  108.                 (!$product->getReleaseDate() or $product->getReleaseDate() > new \DateTime("now"))) {
  109.                 $lineItem->setPayloadValue('isPreorder'$this->productPreorderService->isPreorder($product));
  110.             }
  111.         }
  112.     }
  113.     public function onProductLoaded(EntityLoadedEvent $event): void
  114.     {
  115.         if ($event->getContext()->getScope() !== Context::USER_SCOPE) {
  116.             return;
  117.         }
  118.         /** @var ProductEntity $product */
  119.         foreach ($event->getEntities() as $product) {
  120.             if (!$this->productPreorderService->isPreorder($product)) {
  121.                 continue;
  122.             }
  123.             $customFields $product->getCustomFields();
  124.             $totalOrderAmount $this->productPreorderService->getTotalOrderAmount($product$event->getContext());
  125.             $newPrice $this->productPreorderService->getNewPrice($customFields$totalOrderAmount);
  126.             if ($newPrice) {
  127.                 $product->setPrice($newPrice);
  128.                 $product->setCheapestPrice(null);
  129.             }
  130.             $product->addExtension('preorderData', new ArrayStruct([
  131.                 'totalOrderAmount' => $totalOrderAmount,
  132.                 'hasWareneingang' => $this->hasWareneingang($product$event->getContext())
  133.             ]));
  134.         }
  135.     }
  136.     public function addPropertiesAssociation(ProductListingCriteriaEvent $event)
  137.     {
  138.         $criteria $event->getCriteria();
  139.         $criteria->addAssociation('properties.group');
  140.     }
  141.     private function hasWareneingang(ProductEntity $productContext $context): bool
  142.     {
  143.         $criteria = new Criteria();
  144.         $criteria->addFilter(new EqualsFilter('igmProduktNummer'$product->getProductNumber()));
  145.         $criteria->addFilter(new EqualsFilter('isSync'1));
  146.         return $this->wareneingangRepository->search($criteria$context)->count() > 0;
  147.     }
  148. }