<?php
declare(strict_types=1);
namespace Wbfk\MultipleDeliveries\Subscriber;
use Shopware\Core\Checkout\Order\Aggregate\OrderDelivery\OrderDeliveryEntity;
use Shopware\Core\Checkout\Order\Aggregate\OrderDelivery\OrderDeliveryStates;
use Shopware\Core\Checkout\Order\Aggregate\OrderDeliveryPosition\OrderDeliveryPositionCollection;
use Shopware\Core\Checkout\Order\OrderEntity;
use Shopware\Core\Content\MailTemplate\Service\Event\MailBeforeValidateEvent;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class MailBeforeValidateEventSubscriber implements EventSubscriberInterface
{
public const OPEN_STATES = [OrderDeliveryStates::STATE_OPEN, OrderDeliveryStates::STATE_PARTIALLY_SHIPPED];
public function __construct(private readonly EntityRepository $deliveryPositionRepository)
{
}
/**
* @inheritDoc
*/
public static function getSubscribedEvents(): array
{
return [
MailBeforeValidateEvent::class => 'addShippedDeliveryToTemplateData',
];
}
public function addShippedDeliveryToTemplateData(MailBeforeValidateEvent $event): void
{
if (($event->getTemplateData()['eventName'] ?? null) !== 'state_enter.order_delivery.state.shipped') {
return;
}
$shippedDeliveryId = $event->getContext()->getExtension('deliveryInformation')?->get('deliveryId') ?? null;
/** @var OrderEntity $order */
$order = $event->getTemplateData()['order'];
$shippedDelivery = $shippedDeliveryId ? $order->getDeliveries()->get($shippedDeliveryId) : $order->getDeliveries()->first();
$this->addDeliveryPositions($shippedDelivery, $event->getContext());
$event->addTemplateData('shippedDelivery', $shippedDelivery);
$event->addTemplateData('isAllDeliveriesShipped', $this->isAllDeliveriesShipped($order));
}
private function addDeliveryPositions(OrderDeliveryEntity $delivery, Context $context): void
{
$criteria = new Criteria();
$criteria->addAssociation('orderLineItem.product');
$criteria->getAssociation('orderLineItem')->addAssociation('cover');
$criteria->addSorting(new FieldSorting('createdAt'));
$criteria->addFilter(new EqualsFilter('orderDeliveryId', $delivery->getId()));
/** @var OrderDeliveryPositionCollection $positions */
$positions = $this->deliveryPositionRepository->search($criteria, $context)->getEntities();
$delivery->setPositions($positions);
}
private function isAllDeliveriesShipped(OrderEntity $order): bool
{
/** @var OrderDeliveryEntity $delivery */
foreach ($order->getDeliveries() as $delivery) {
if (in_array($delivery->getStateMachineState()->getTechnicalName(), self::OPEN_STATES)) {
return false;
}
}
return true;
}
}