<?php declare(strict_types=1);
namespace TTAlternateProduct\Subscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Shopware\Core\System\SalesChannel\Entity\SalesChannelRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
class AlternateProductSubscriber implements EventSubscriberInterface
{
protected SalesChannelRepositoryInterface $salesChannelProductRepository;
public function __construct(
SalesChannelRepositoryInterface $salesChannelProductRepository
){
$this->salesChannelProductRepository = $salesChannelProductRepository;
}
public static function getSubscribedEvents()
{
return [
ProductPageLoadedEvent::class => 'onProductPageLoaded'
];
}
/**
* @throws Exception
*/
public function onProductPageLoaded(ProductPageLoadedEvent $event): void
{
$page = $event->getPage();
$product = $page->getProduct();
$criteria = new Criteria();
$criteria->addAssociation('crossSellings.assignedProducts.product');
$criteria->addFilter(new EqualsFilter('productNumber', $product->getProductNumber()));
$criteria->addFilter(new EqualsFilter('crossSellings.name', 'sinnvolle Alternative'));
$crossSellings = $this->salesChannelProductRepository->search($criteria, $event->getSalesChannelContext())->first();
if($crossSellings != null){
$crossSellings = $crossSellings->getCrossSellings();
}
$productAlternate = null;
if($crossSellings){
foreach($crossSellings as $crossSelling){
if($crossSelling->getName() == 'sinnvolle Alternative'){
$productAlternate = $crossSelling->getAssignedProducts()->getElements();
break;
}
}
}
if($productAlternate){
$productAlternate = end($productAlternate)->getProductId();
}
if(!isset($productAlternate) || $productAlternate == null) {
return;
}
$criteria = new Criteria();
$criteria->addAssociation('cover');
$criteria->addFilter(new EqualsFilter('id', $productAlternate));
$productAlternate = $this->salesChannelProductRepository->search($criteria, $event->getSalesChannelContext())->first();
if($productAlternate && $productAlternate->getActive() && $productAlternate->getAvailable()) {
//OR-519 Sinnvolle Alternative Bug
//OR-559 get correct price final of product
$price = $product->getCalculatedPrices()->first()->getUnitPrice();
$priceAlternate = $productAlternate->getCalculatedPrices()->first()->getUnitPrice();
//OR-559 calculate percentage
$percentageBase = 100;
$percentageLess = ($priceAlternate * 100) / $price;
$percantageResult = number_format(ceil($percentageBase - $percentageLess),0,'','');
//Show if price alternate < price origin
if((float)$price > (float)$priceAlternate && $percantageResult > 1) {
$page->assign(['productAlternate' => $productAlternate,'percantageResult' => $percantageResult]);
}
}
}
}