<?php
declare(strict_types=1);
namespace Wbfk\Offer\Subscriber;
use Shopware\Core\Checkout\Customer\CustomerEntity;
use Shopware\Core\Checkout\Order\OrderEntity;
use Shopware\Core\Content\Flow\Events\FlowSendMailActionEvent;
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\Event\OrderAware;
use Shopware\Core\System\User\UserEntity;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Wbfk\Offer\Core\Entity\Offer\OfferEntity;
class MailSubscriber implements EventSubscriberInterface
{
protected const ACCOUNT_MANAGER = 'wbfkAccountManager';
protected const ASSIGNEE_OF_ORDER = 'wbfkAssigneeOfOrder';
protected const CUSTOMER_AND_ACCOUNT_MANAGER = 'wbfkCustomerAndAccountManager';
protected const CUSTOMER_AND_ASSIGNEE_OF_ORDER = 'wbfkCustomerAndAssigneeOfOrder';
protected const RECIPIENT_TYPES = [
self::ACCOUNT_MANAGER,
self::ASSIGNEE_OF_ORDER,
self::CUSTOMER_AND_ACCOUNT_MANAGER,
self::CUSTOMER_AND_ASSIGNEE_OF_ORDER,
];
public function __construct(
protected readonly EntityRepository $customerRepository,
protected readonly EntityRepository $offerRepository
)
{
}
public static function getSubscribedEvents()
{
return [
FlowSendMailActionEvent::class => 'onFlowSendMailAction',
];
}
public function onFlowSendMailAction(FlowSendMailActionEvent $event): void
{
$context = $event->getContext();
$flowConfig = $event->getFlowEvent()->getConfig();
$recipientType = $flowConfig['recipient']['type'];
if(!in_array($recipientType, self::RECIPIENT_TYPES)) {
return;
}
$triggeredEvent = $event->getFlowEvent()->getEvent();
/** @var OrderEntity|null $order */
$order = null;
if($triggeredEvent instanceof OrderAware) {
$order = $triggeredEvent->getOrder();
}
if(!isset($order)) {
return;
}
$event->getDataBag()->set('recipients', []);
$this->handleAccountManager($recipientType, $event, $order);
$this->handleAssigneeOfOrder($recipientType, $event, $order);
$this->handleCustomer($recipientType, $event, $order);
}
protected function handleAccountManager(
string $recipientType,
FlowSendMailActionEvent $event,
OrderEntity $order
): void
{
if ($recipientType !== self::ACCOUNT_MANAGER &&
$recipientType !== self::CUSTOMER_AND_ACCOUNT_MANAGER) {
return;
}
$customer = $order->getOrderCustomer()?->getCustomer();
if(!isset($customer)) {
return;
}
$accountManager = $this->getAccountManagerFromCustomer($customer, $event->getContext());
if(!isset($accountManager)) {
return;
}
$email = $accountManager->getEmail();
if($recipientType === self::CUSTOMER_AND_ACCOUNT_MANAGER) {
$event->getDataBag()->set('recipientsBcc', $email);
return;
}
$name = $accountManager->getFirstName().' '.$accountManager->getLastName();
$this->addRecipient($event, $email, $name);
}
protected function handleAssigneeOfOrder(
string $recipientType,
FlowSendMailActionEvent $event,
OrderEntity $order
): void
{
if ($recipientType !== self::ASSIGNEE_OF_ORDER &&
$recipientType !== self::CUSTOMER_AND_ASSIGNEE_OF_ORDER) {
return;
}
$offer = $this->getOfferFromOrder($order, $event->getContext());
$assignee = $offer?->getAssignee();
if(!isset($offer) || !isset($assignee)) {
return;
}
$name = $assignee->getFirstName().' '.$assignee->getLastName();
$this->addRecipient($event, $assignee->getEmail(), $name);
}
protected function handleCustomer(
string $recipientType,
FlowSendMailActionEvent $event,
OrderEntity $order
): void
{
if ($recipientType !== self::CUSTOMER_AND_ACCOUNT_MANAGER &&
$recipientType !== self::CUSTOMER_AND_ASSIGNEE_OF_ORDER) {
return;
}
$orderCustomer = $order->getOrderCustomer();
if(!isset($orderCustomer)) {
return;
}
$name = $orderCustomer->getFirstName().' '.$orderCustomer->getLastName();
$this->addRecipient($event, $orderCustomer->getEmail(), $name);
}
protected function getOfferFromOrder(OrderEntity $order, Context $context): OfferEntity|null
{
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('orderId', $order->getId()));
$criteria->addAssociation('assignee');
$criteria->setLimit(1);
return $this->offerRepository->search(
$criteria,
$context
)->first();
}
protected function getAccountManagerFromCustomer(CustomerEntity $customer, Context $context): UserEntity|null
{
$criteria = new Criteria([$customer->getId()]);
$criteria->addAssociation('wbfkCustomerExtension.accountManager');
$criteria->setLimit(1);
$customer = $this->customerRepository->search(
$criteria,
$context
)->first();
return $customer?->getExtension('wbfkCustomerExtension')?->getAccountManager();
}
protected function addRecipient(FlowSendMailActionEvent $event, string $email, string $name): void
{
$recipients = $event->getDataBag()->get('recipients') ?? [];
$recipients[$email] = $name;
$event->getDataBag()->set('recipients', $recipients);
}
}