<?php declare(strict_types=1);
namespace FourtwosixThemeExtension\Subscriber;
use FourtwosixThemeExtension\Constant\Constant;
use FourtwosixThemeExtension\Core\Content\FourtwosixStockPrice\FourtwosixStockPriceEntity;
use Shopware\Core\Checkout\Cart\Price\Struct\CalculatedPrice;
use Shopware\Core\Checkout\Cart\Price\Struct\ListPrice;
use Shopware\Core\Content\Product\Events\ProductListingResultEvent;
use Shopware\Core\Content\Product\SalesChannel\SalesChannelProductEntity;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\Struct\ArrayStruct;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Shopware\Core\System\Tax\Aggregate\TaxRule\TaxRuleEntity;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class ProductListingSubscriber implements EventSubscriberInterface
{
protected EntityRepositoryInterface $ftsStockPrice;
protected EntityRepositoryInterface $taxRuleRepository;
protected SystemConfigService $systemConfigService;
public function __construct(
EntityRepositoryInterface $ftsStockPrice,
EntityRepositoryInterface $taxRuleRepository,
SystemConfigService $systemConfigService,
) {
$this->ftsStockPrice = $ftsStockPrice;
$this->taxRuleRepository = $taxRuleRepository;
$this->systemConfigService = $systemConfigService;
}
public static function getSubscribedEvents(): array
{
return [
ProductListingResultEvent::class => "onProductListingLoadedEvent",
];
}
/**
* @param ProductListingResultEvent $event
* @return void
*/
public function onProductListingLoadedEvent(ProductListingResultEvent $event)
{
$eventResults = $event->getResult();
$productIds = array_keys($eventResults->getElements());
$context = $event->getSalesChannelContext();
$criteria = new Criteria();
$criteria->addFilter(new EqualsAnyFilter('productId', $productIds));
$stockPriceElements = $this->ftsStockPrice->search($criteria, $context->getContext())->getElements();
if (!$stockPriceElements) {
return;
}
$mainTaxId = $this->systemConfigService->get('FourtwosixThemeExtension.config.ftsStockDiscountMandatoryFieldTaxId');
$activeBillingCountryId = $context->getCustomer()?->getActiveBillingAddress()?->getCountryId();
// Default taxRate is 19 for DE
$taxRate = 19;
if (!is_null($activeBillingCountryId)) {
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('taxId', $mainTaxId));
$criteria->addFilter(new EqualsFilter('countryId', $activeBillingCountryId));
/** @var TaxRuleEntity $taxRatesPerCountry */
$taxRatesPerCountry = $this->taxRuleRepository->search($criteria, $context->getContext())->first();
$taxRate = $taxRatesPerCountry->getTaxRate();
}
/** @var FourtwosixStockPriceEntity $stockPriceElement */
foreach ($stockPriceElements as $stockPriceElement) {
$productId = $stockPriceElement->getProductId();
$stockProduct = $stockPriceElement->getProduct();
/** @var SalesChannelProductEntity $product */
$product = $eventResults->get($productId);
// Here recreate the listPrice for discount in FTS stock but not in promotion
$originalCalculatedPrice = $product->getCalculatedPrice();
$unitPrice = $originalCalculatedPrice->getUnitPrice();
// override if null ------------------------------------------------
$listPrice = $originalCalculatedPrice->getListPrice();
if (!$listPrice) {
$listPrice = ListPrice::createFromUnitPrice($stockPriceElement->getNetPrice(), $unitPrice);
}
// Update the calculated price with new listPrice ------------------
$calculatedPrice = new CalculatedPrice(
$unitPrice,
$unitPrice,
$originalCalculatedPrice->getCalculatedTaxes(),
$originalCalculatedPrice->getTaxRules(),
referencePrice: $originalCalculatedPrice->getReferencePrice(),
listPrice: $listPrice,
);
$product->setCalculatedPrice($calculatedPrice);
$product->addExtension(Constant::FTS_STOCK_DISCOUNT_PLP_DISCOUNTED_PRICE,
new ArrayStruct([
'netPrice' => $stockPriceElement->getNetPrice(),
'stock' => $stockProduct,
'taxRate' => $taxRate,
]));
}
}
}