<?php
declare (strict_types=1);
namespace Crehler\MojeBambinoEngine\Subscriber;
use Shopware\Core\Checkout\Cart\Price\QuantityPriceCalculator;
use Shopware\Core\Checkout\Cart\Price\Struct\QuantityPriceDefinition;
use Shopware\Core\Checkout\Cart\Tax\Struct\TaxRule;
use Shopware\Core\Checkout\Cart\Tax\Struct\TaxRuleCollection;
use Shopware\Core\Content\Product\Events\ProductListingResultEvent;
use Shopware\Core\Content\Product\ProductEntity;
use Shopware\Core\Content\Product\SalesChannel\Price\ProductPriceCalculator;
use Shopware\Core\Content\Product\SalesChannel\SalesChannelProductEntity;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class ProductListResultSubscriber implements EventSubscriberInterface
{
private EntityRepository $productRepository;
private QuantityPriceCalculator $quantityPriceCalculator;
public function __construct(
EntityRepository $productRepository,
QuantityPriceCalculator $quantityPriceCalculator
)
{
$this->productRepository = $productRepository;
$this->quantityPriceCalculator = $quantityPriceCalculator;
}
public static function getSubscribedEvents(): array
{
return [
ProductListingResultEvent::class => 'onProductListingResult',
];
}
public function onProductListingResult(ProductListingResultEvent $event): void
{
try {
$products = $event->getResult()->getEntities();
/** @var SalesChannelProductEntity $product */
foreach ($products as $product) {
$parentId = $product->getParentId();
if (!$parentId && $product->getChildCount()) {
$parentId = $product->getId();
}
if (!$parentId) {
continue;
}
$this->calculateVersionPrices($event, $product, $parentId);
}
} catch (\Throwable $exception) {
dd($exception);
}
}
private function calculateVersionPrices(ProductListingResultEvent $event, SalesChannelProductEntity $productEntity, string $parentId): void
{
$criteria = new Criteria([$parentId]);
$criteria->getAssociation('children')
->addFilter(new EqualsFilter('active', true));
/** @var SalesChannelProductEntity $parentProduct */
/** @var ProductEntity $child */
$parentProduct = $this->productRepository->search($criteria, $event->getContext())->first();
foreach ($parentProduct->getChildren() as $child) {
$taxRulesCollection = new TaxRuleCollection();
$taxRule = new TaxRule($child->getTax()->getTaxRate());
$taxRulesCollection->set($child->getTax()->getTaxRate(), $taxRule);
$priceDefinition = new QuantityPriceDefinition(
$child->getPrice()->getCurrencyPrice($event->getContext()->getCurrencyId())->getNet(),
$taxRulesCollection
);
$calculatedPrice = $this->quantityPriceCalculator->calculate($priceDefinition, $event->getSalesChannelContext());
$productEntity->getCalculatedPrices()->add($calculatedPrice);
}
$productEntity->getCalculatedPrices()->sort(fn($price1, $price2) => $price1->getUnitPrice() < $price2->getUnitPrice() ? -1 : 1);
}
}