<?php
namespace CioOrderConfirmation\Subscriber;
use CioMasterdata\Definition\Masterdata\MasterdataEntity;
use CioMasterdata\Service\MasterdataService;
use CioOrderConfirmation\CioOrderConfirmation;
use CioOrderConfirmation\Event\AuthorizedReleaserBeforeSendMailEvent;
use CioOrderConfirmation\Event\CheckoutOrderReleaseProcessEvent;
use CioOrderConfirmation\Event\CheckoutOrderReleaseProcessOrderCustomerEvent;
use Shopware\Core\Checkout\Cart\Event\CheckoutOrderPlacedEvent;
use Shopware\Core\Checkout\Order\OrderDefinition;
use Shopware\Core\Content\Mail\Service\AbstractMailService;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\EntitySearchResult;
use Shopware\Core\Framework\Event\BusinessEventCollectorEvent;
use Shopware\Core\Framework\Event\BusinessEventDefinition;
use Shopware\Core\Framework\Event\EventData\MailRecipientStruct;
use Shopware\Core\System\SalesChannel\Context\AbstractSalesChannelContextFactory;
use Shopware\Core\System\SalesChannel\Context\SalesChannelContextService;
use Shopware\Core\System\StateMachine\StateMachineRegistry;
use Shopware\Core\System\StateMachine\Transition;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\ParameterBag;
use Symfony\Component\Routing\Router;
use Twig\Environment;
class OrderSubscriber implements EventSubscriberInterface
{
private ContainerInterface $container;
private Environment $twig;
private EventDispatcherInterface $eventDispatcher;
private SystemConfigService $systemConfigService;
private AbstractMailService $mailService;
private StateMachineRegistry $stateMachineRegistry;
private AbstractSalesChannelContextFactory $salesChannelContextFactory;
private MasterdataService $masterdataService;
public function __construct(ContainerInterface $container, Environment $twig, EventDispatcherInterface $eventDispatcher, SystemConfigService $systemConfigService, AbstractMailService $mailService, StateMachineRegistry $stateMachineRegistry, AbstractSalesChannelContextFactory $salesChannelContextFactory, MasterdataService $masterdataService)
{
$this->container = $container;
$this->twig = $twig;
$this->eventDispatcher = $eventDispatcher;
$this->systemConfigService = $systemConfigService;
$this->mailService = $mailService;
$this->stateMachineRegistry = $stateMachineRegistry;
$this->salesChannelContextFactory = $salesChannelContextFactory;
$this->masterdataService = $masterdataService;
}
public static function getSubscribedEvents()
{
return [
CheckoutOrderPlacedEvent::class => 'onCheckoutOrderPlacedEvent',
'collect.business-events' => 'onBusinessEvent'
];
}
public function onBusinessEvent(BusinessEventCollectorEvent $event)
{
$businessEventsCollection = $event->getCollection();
$businessEventsCollection->add(new BusinessEventDefinition(
CheckoutOrderReleaseProcessEvent::EVENT_NAME,
CheckoutOrderReleaseProcessEvent::class,
true,
false,
false,
[]
));
$businessEventsCollection->add(new BusinessEventDefinition(
CheckoutOrderReleaseProcessOrderCustomerEvent::EVENT_NAME,
CheckoutOrderReleaseProcessOrderCustomerEvent::class,
true,
false,
false,
[]
));
}
public function onCheckoutOrderPlacedEvent(CheckoutOrderPlacedEvent $event)
{
$order = $event->getOrder();
$customer = $order->getOrderCustomer()->getCustomer();
/** @var EntityRepositoryInterface $orderRepository */
$orderRepository = $this->container->get('order.repository');
$customerCustomFields = [];
if ($customer && is_array($customer->getCustomFields())) {
$customerCustomFields = $customer->getCustomFields();
}
$orderCustomFields = [];
if (is_array($order->getCustomFields())) {
$orderCustomFields = $order->getCustomFields();
}
// The recipient email is normally stored in the customer's CustomFields, the event allows to override this recipients mail address in other plugins. The plugin must ensure that an account exists for this email.
$event = new AuthorizedReleaserBeforeSendMailEvent($order, $customer, @$customerCustomFields['custom_customers_authorized_releaser'] ?: '');
$this->eventDispatcher->dispatch($event);
if ($releaseMailRecipientEmail = $event->getAuthorizedReleaserEmail()) {
$salesChannelContext = $this->salesChannelContextFactory->create('', $order->getSalesChannelId(), [SalesChannelContextService::LANGUAGE_ID => $order->getLanguageId()]);
$this->stateMachineRegistry->transition(
new Transition(
OrderDefinition::ENTITY_NAME,
$order->getId(),
CioOrderConfirmation::WAITING_FOR_RELEASE_STATE_TRANSITION_NAME,
'stateId'
), $salesChannelContext->getContext()
);
// Order is not released yet and save email of the account that is authorized for release on the order entity.
$orderCustomFields['custom_orders_release_state'] = false;
$orderCustomFields['custom_orders_authorized_releaser'] = $releaseMailRecipientEmail;
$orderCustomFields['noOrderConfirmation'] = false;
$orderRepository->update([[
'id' => $order->getId(),
'customFields' => $orderCustomFields
]], Context::createDefaultContext());
$url = $this->container->get('router')->generate('order.cio.release.form', [
'id' => $order->getOrderNumber()
], Router::ABSOLUTE_URL);
// send release mail with url
$masterDatas = $this->masterdataService->getMasterdatasForCustomer($customer);
$customerMasterdata = false;
if ($masterDatas instanceof EntitySearchResult) {
/** @var MasterdataEntity $customerMasterdata */
$customerMasterdata = $this->masterdataService->getMasterdatasForCustomer($customer)->first();
}
$customerVpNumber = ($customerMasterdata) ? $customerMasterdata->getVpNummer() : '';
$releaseProcessEvent = new CheckoutOrderReleaseProcessEvent($order, $customer, $releaseMailRecipientEmail ?: '', $url, $customerVpNumber);
$releaseProcessEvent->setMailStruct(new MailRecipientStruct([
$releaseMailRecipientEmail => $releaseMailRecipientEmail,
'Fachhandel@ewe.de' => 'Fachhandel@ewe.de'
]));
$this->eventDispatcher->dispatch($releaseProcessEvent);
// send notification for customer that the order is in checking process
$releaseProcessEvent = new CheckoutOrderReleaseProcessOrderCustomerEvent($order, $customer, $releaseMailRecipientEmail ?: '');
$releaseProcessEvent->setMailStruct(new MailRecipientStruct([$customer->getEmail() => $customer->getEmail()]));
$this->eventDispatcher->dispatch($releaseProcessEvent);
$mailData = new ParameterBag();
$mailData->set('recipients', [
$releaseMailRecipientEmail => $releaseMailRecipientEmail
]);
$mailData->set('senderName', $this->getConfigValue('releaseMailSender') ?: $order->getOrderCustomer()->getEmail());
$mailData->set('salesChannelId', $this->getConfigValue('releaseMailSalesChannelId') ?: $order->getSalesChannelId());
$mailData->set('subject', sprintf('Freigabe der Bestellung %s', $order->getOrderNumber()));
$plainMailContentTemplate = $this->twig->createTemplate($this->getConfigValue('releaseMailPlainTextContent') ?: 'The Plan-Text-Content should be set in the CioOrderConfirmation-Plugin');
$htmlMailContentTemplate = $this->twig->createTemplate($this->getConfigValue('releaseMailHtmlContent') ?: 'The HTML-Content should be set in the CioOrderConfirmation-Plugin');
$plainMailContent = $plainMailContentTemplate->render(['order' => $order, 'url' => $url]);
$htmlMailContent = $htmlMailContentTemplate->render(['order' => $order, 'url' => $url]);
$mailData->set('contentPlain', $plainMailContent);
$mailData->set('contentHtml', $htmlMailContent);
/*$this->mailService->send(
$mailData->all(), Context::createDefaultContext()
);*/
} else {
// Without an authorized releaser, the order does not have to be released first.
$orderRepository->update([[
'id' => $order->getId(),
'customFields' => $orderCustomFields
]], Context::createDefaultContext());
}
}
protected function getConfigValue(string $key)
{
return $this->systemConfigService->get('CioOrderConfirmation.config.' . $key);
}
}