custom/plugins/MoorlProductAccessories/src/Core/Service/ProductAccessoriesService.php line 62

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace MoorlProductAccessories\Core\Service;
  3. use MoorlProductAccessories\Core\Content\Accessory\AccessoryCollection;
  4. use MoorlProductAccessories\Core\Content\Accessory\AccessoryEntity;
  5. use MoorlProductAccessories\Core\Content\Category\CategoryCollection;
  6. use Shopware\Core\Checkout\Cart\Price\Struct\CalculatedPrice;
  7. use Shopware\Core\Checkout\Cart\Price\Struct\ListPrice;
  8. use Shopware\Core\Content\Media\Pathname\UrlGeneratorInterface;
  9. use Shopware\Core\Content\Product\SalesChannel\Price\AbstractProductPriceCalculator;
  10. use Shopware\Core\Content\Product\SalesChannel\SalesChannelProductEntity;
  11. use Shopware\Core\Framework\Context;
  12. use Shopware\Core\Framework\DataAbstractionLayer\DefinitionInstanceRegistry;
  13. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  14. use Shopware\Core\System\SalesChannel\Entity\SalesChannelRepositoryInterface;
  15. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  16. use Shopware\Core\System\SystemConfig\SystemConfigService;
  17. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  18. use Symfony\Component\HttpFoundation\RequestStack;
  19. class ProductAccessoriesService
  20. {
  21.     private Context $context;
  22.     private SalesChannelContext $salesChannelContext;
  23.     private DefinitionInstanceRegistry $definitionInstanceRegistry;
  24.     private SystemConfigService $systemConfigService;
  25.     private SalesChannelRepositoryInterface $salesChannelProductRepository;
  26.     private AbstractProductPriceCalculator $productPriceCalculator;
  27.     private UrlGeneratorInterface $urlGenerator;
  28.     public function __construct(
  29.         DefinitionInstanceRegistry $definitionInstanceRegistry,
  30.         SystemConfigService $systemConfigService,
  31.         SalesChannelRepositoryInterface $salesChannelProductRepository,
  32.         AbstractProductPriceCalculator $productPriceCalculator,
  33.         UrlGeneratorInterface $urlGenerator
  34.     )
  35.     {
  36.         $this->definitionInstanceRegistry $definitionInstanceRegistry;
  37.         $this->systemConfigService $systemConfigService;
  38.         $this->salesChannelProductRepository $salesChannelProductRepository;
  39.         $this->productPriceCalculator $productPriceCalculator;
  40.         $this->urlGenerator $urlGenerator;
  41.     }
  42.     public function getProduct(string $productIdSalesChannelContext $salesChannelContext): ?SalesChannelProductEntity
  43.     {
  44.         $this->salesChannelContext $salesChannelContext;
  45.         $criteria = new Criteria([$productId]);
  46.         $this->enrichProductCriteria($criteria);
  47.         $product $this->salesChannelProductRepository->search($criteria$salesChannelContext)->get($productId);
  48.         $this->enrichProductEntity($product);
  49.         return $product;
  50.     }
  51.     public function enrichProductEntity(SalesChannelProductEntity $product): void
  52.     {
  53.         if ($product->getExtension('moorlPa')) {
  54.             $accessoryCollection $product->getExtension('moorlPa');
  55.         } else {
  56.             $accessoryCollection = new AccessoryCollection();
  57.         }
  58.         $productStreams $product->getStreams();
  59.         if ($productStreams) {
  60.             foreach ($productStreams as $productStream) {
  61.                 if ($productStream->getExtension('moorlPa')) {
  62.                     $accessoryCollection->merge($productStream->getExtension('moorlPa'));
  63.                 }
  64.             }
  65.         }
  66.         /* Deprecated: Use product streams */
  67.         $categories $product->getCategories();
  68.         if ($categories) {
  69.             /** @var CategoryCollection|null $excluded */
  70.             $excluded $product->getExtension('moorlPaCategories');
  71.             foreach ($categories as $category) {
  72.                 if ($excluded && $excluded->has($category->getId())) {
  73.                     continue;
  74.                 }
  75.                 if ($category->getExtension('moorlPa')) {
  76.                     $accessoryCollection->merge($category->getExtension('moorlPa'));
  77.                 }
  78.             }
  79.         }
  80.         $product->removeExtension('moorlPa');
  81.         $product->addExtension('moorlPa'$accessoryCollection->getCategories());
  82.     }
  83.     public function handlePrice(AccessoryEntity $accessory): void
  84.     {
  85.         $product $accessory->getAccessory();
  86.         $this->productPriceCalculator->calculate([$product], $this->salesChannelContext);
  87.         $accessory->setCalculatedPrice($product->getCalculatedPrice());
  88.         /* Early return - no price manipulation*/
  89.         if (!$this->systemConfigService->get('MoorlProductAccessories.config.bundles')) {
  90.             return;
  91.         }
  92.         if ($accessory->getCustomPrice() && $accessory->getPrice() === null) {
  93.             /* Deprecated calculation */
  94.             $oldCalculatedPrice $product->getCalculatedPrice();
  95.             $listPrice $oldCalculatedPrice->getListPrice();
  96.             if (!$listPrice) {
  97.                 $listPrice ListPrice::createFromUnitPrice(
  98.                     $accessory->getRawPrice(),
  99.                     $oldCalculatedPrice->getUnitPrice()
  100.                 );
  101.             } else {
  102.                 $listPrice ListPrice::createFromUnitPrice(
  103.                     $accessory->getRawPrice(),
  104.                     $listPrice->getPrice()
  105.                 );
  106.             }
  107.             $accessory->setCalculatedPrice(new CalculatedPrice(
  108.                 $accessory->getRawPrice(),
  109.                 $accessory->getRawPrice(),
  110.                 $oldCalculatedPrice->getCalculatedTaxes(),
  111.                 $oldCalculatedPrice->getTaxRules(),
  112.                 $oldCalculatedPrice->getQuantity(),
  113.                 $oldCalculatedPrice->getReferencePrice(),
  114.                 $listPrice
  115.             ));
  116.         } else if ($accessory->getCustomPrice() && $accessory->getPrice()) {
  117.             /* New calculation */
  118.             $oldCalculatedPrice $product->getCalculatedPrice();
  119.             $product->setPrice($accessory->getPrice());
  120.             $this->productPriceCalculator->calculate([$product], $this->salesChannelContext);
  121.             $newCalculatedPrice $product->getCalculatedPrice();
  122.             $listPrice $oldCalculatedPrice->getListPrice();
  123.             if (!$listPrice) {
  124.                 $listPrice ListPrice::createFromUnitPrice(
  125.                     $newCalculatedPrice->getUnitPrice(),
  126.                     $oldCalculatedPrice->getUnitPrice()
  127.                 );
  128.             } else {
  129.                 $listPrice ListPrice::createFromUnitPrice(
  130.                     $newCalculatedPrice->getUnitPrice(),
  131.                     $listPrice->getPrice()
  132.                 );
  133.             }
  134.             $accessory->setCalculatedPrice(new CalculatedPrice(
  135.                 $newCalculatedPrice->getUnitPrice(),
  136.                 $newCalculatedPrice->getTotalPrice(),
  137.                 $newCalculatedPrice->getCalculatedTaxes(),
  138.                 $newCalculatedPrice->getTaxRules(),
  139.                 $newCalculatedPrice->getQuantity(),
  140.                 $newCalculatedPrice->getReferencePrice(),
  141.                 $listPrice
  142.             ));
  143.         }
  144.     }
  145.     public function enrichProductCriteria(?Criteria $criteria null): Criteria
  146.     {
  147.         if (!$criteria) {
  148.             $criteria = new Criteria();
  149.         }
  150.         $criteria->addAssociations([
  151.             'moorlPaCategories',
  152.             'moorlPa.accessory.cover.media',
  153.             'moorlPa.accessory.options',
  154.             'streams.moorlPa.accessory.cover.media',
  155.             'streams.moorlPa.accessory.options',
  156.             /* Deprecated: Use product streams */
  157.             'categories.moorlPa.accessory.cover.media',
  158.             'categories.moorlPa.accessory.options',
  159.         ]);
  160.         return $criteria;
  161.     }
  162.     /**
  163.      * @param SalesChannelContext $salesChannelContext
  164.      */
  165.     public function setSalesChannelContext(SalesChannelContext $salesChannelContext): void
  166.     {
  167.         $this->salesChannelContext $salesChannelContext;
  168.         $this->context $salesChannelContext->getContext();
  169.     }
  170. }