<?php declare(strict_types=1);
namespace CioFixDuplicateDiscounts\Subscriber;
use Shopware\Core\Checkout\Cart\LineItem\LineItem;
use Shopware\Core\Checkout\Cart\LineItem\LineItemCollection;
use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemCollection;
use Shopware\Storefront\Page\Account\Order\AccountOrderPageLoadedEvent;
use Shopware\Storefront\Page\Checkout\Cart\CheckoutCartPageLoadedEvent;
use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent;
use Shopware\Storefront\Page\Checkout\Finish\CheckoutFinishPageLoadedEvent;
use Shopware\Storefront\Page\Checkout\Offcanvas\OffcanvasCartPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class FixDuplicateDiscounts implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
OffcanvasCartPageLoadedEvent::class => 'onCartEvents',
CheckoutCartPageLoadedEvent::class => 'onCartEvents',
CheckoutConfirmPageLoadedEvent::class => 'onCartEvents',
CheckoutFinishPageLoadedEvent::class => 'onOrderEvents',
AccountOrderPageLoadedEvent::class => 'onOrderEvents'
];
}
/**
* @param OffcanvasCartPageLoadedEvent|CheckoutCartPageLoadedEvent|CheckoutConfirmPageLoadedEvent $event
* @return void
*/
public function onCartEvents($event)
{
$this->removeDuplicateDiscount($event->getPage()->getCart()->getLineItems());
}
/**
* @param CheckoutFinishPageLoadedEvent|AccountOrderPageLoadedEvent $event
* @return void
*/
public function onOrderEvents($event)
{
if ($event instanceof AccountOrderPageLoadedEvent) {
foreach ($event->getPage()->getOrders() as $order) {
$this->removeDuplicateDiscount($order->getLineItems());
}
} else {
$this->removeDuplicateDiscount($event->getPage()->getOrder()->getLineItems());
}
}
/**
* @param LineItemCollection|OrderLineItemCollection $lineItemCollection
* @return void
*/
public function removeDuplicateDiscount($lineItemCollection)
{
$voucherItems = [];
$labels = [];
foreach ($lineItemCollection as $lineItem) {
if ($lineItem->getType() == LineItem::PROMOTION_LINE_ITEM_TYPE) {
$voucherItems[] =
[
'id' => $lineItem->getId(),
'label' => $lineItem->getLabel(),
'price' => $lineItem->getPrice()->getUnitPrice()
];
$labels[] = $lineItem->getLabel();
}
}
$idsToRemove = [];
foreach ($voucherItems as $voucherItem) {
if ($voucherItem['price'] == 0) {
if (in_array($voucherItem['label'], $labels))
$idsToRemove[] = $voucherItem['id'];
}
}
foreach ($idsToRemove as $id) {
$lineItemCollection->remove($id);
}
}
}