<?php declare(strict_types=1);namespace Fgits\AutoInvoice\Subscriber;use Fgits\AutoInvoice\ScheduledTask\Export\AutoInvoiceExportTask;use Fgits\AutoInvoice\ScheduledTask\OrderScan\AutoInvoiceOrderScanTask;use Fgits\AutoInvoice\Service\CustomFields\OrderCustomFields;use Fgits\AutoInvoice\Service\DB\Order as DBOrder;use Fgits\AutoInvoice\Service\FgitsLibrary\ScheduledTask;use Fgits\AutoInvoice\Service\FgitsLibrary\Utility;use Fgits\AutoInvoice\Service\OrderProcessor;use Psr\Log\LoggerInterface;use Shopware\Core\Checkout\Cart\Event\CheckoutOrderPlacedEvent;use Shopware\Core\Checkout\Cart\Exception\OrderDeliveryNotFoundException;use Shopware\Core\Checkout\Cart\Exception\OrderNotFoundException;use Shopware\Core\Checkout\Cart\Exception\OrderTransactionNotFoundException;use Shopware\Core\Checkout\Order\Aggregate\OrderDelivery\OrderDeliveryEntity;use Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionEntity;use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;use Shopware\Core\System\StateMachine\Event\StateMachineStateChangeEvent;use Shopware\Core\System\SystemConfig\SystemConfigService;use Symfony\Component\DependencyInjection\ContainerInterface;use Symfony\Component\EventDispatcher\EventSubscriberInterface;use Symfony\Component\HttpFoundation\Session\SessionInterface;/** * Copyright (c) 2020. GOLLE IT. * * @author Andrey Grigorkin <andrey@golle-it.de> */class OrderSubscriber implements EventSubscriberInterface{ private DBOrder $dbOrder; private OrderCustomFields $orderCustomFields; private ScheduledTask $scheduledTask; private OrderProcessor $orderProcessor; private EntityRepositoryInterface $orderRepository; private EntityRepositoryInterface $orderDeliveryRepository; private EntityRepositoryInterface $orderTransactionRepository; private Utility $utility; private SessionInterface $session; private ContainerInterface $container; private SystemConfigService $systemConfigService; private LoggerInterface $logger; /** * OrderSubscriber constructor. * * @param DBOrder $dbOrder * @param OrderCustomFields $orderCustomFields * @param ScheduledTask $scheduledTask * @param OrderProcessor $orderProcessor * @param EntityRepositoryInterface $orderRepository * @param EntityRepositoryInterface $orderDeliveryRepository * @param EntityRepositoryInterface $orderTransactionRepository * @param Utility $utility * @param SessionInterface $session * @param ContainerInterface $container * @param SystemConfigService $systemConfigService * @param LoggerInterface $logger */ public function __construct( DBOrder $dbOrder, OrderCustomFields $orderCustomFields, ScheduledTask $scheduledTask, OrderProcessor $orderProcessor, EntityRepositoryInterface $orderRepository, EntityRepositoryInterface $orderDeliveryRepository, EntityRepositoryInterface $orderTransactionRepository, Utility $utility, SessionInterface $session, ContainerInterface $container, SystemConfigService $systemConfigService, LoggerInterface $logger ) { $this->dbOrder = $dbOrder; $this->orderCustomFields = $orderCustomFields; $this->scheduledTask = $scheduledTask; $this->orderProcessor = $orderProcessor; $this->orderRepository = $orderRepository; $this->orderDeliveryRepository = $orderDeliveryRepository; $this->orderTransactionRepository = $orderTransactionRepository; $this->utility = $utility; $this->session = $session; $this->container = $container; $this->systemConfigService = $systemConfigService; $this->logger = $logger; } public static function getSubscribedEvents(): array { return [ CheckoutOrderPlacedEvent::class => [['scheduleScheduledTasks'], ['onOrderPlaced']], 'state_machine.order_transaction.state_changed' => 'onOrderTransactionStateChanged', 'state_machine.order_delivery.state_changed' => 'onOrderDeliveryStateChanged', 'state_machine.order.state_changed' => [['onOrderStateChanged'], ['onOrderStateChangedTickets']] ]; } public function scheduleScheduledTasks(): void { $this->scheduledTask->schedule(AutoInvoiceExportTask::getTaskName()); $this->scheduledTask->schedule(AutoInvoiceOrderScanTask::getTaskName()); } /** * Gets invoked when an order is created. * * @param CheckoutOrderPlacedEvent $event */ public function onOrderPlaced(CheckoutOrderPlacedEvent $event): void { $this->session->set('fgits_autoinvoice_latest_order_id', $event->getOrder()->getId()); $config = $this->systemConfigService->get('fgitsAutoinvoiceSW6.config', $event->getSalesChannelId()); if (!$config['active']) { return; } $request = $this->container->get('request_stack')->getCurrentRequest(); if ($config['changeCheckoutEmail'] && isset($request) && $request->get('fgitsChangeCheckoutEmail')) { $this->orderCustomFields->setCheckoutEmail($event->getOrder(), $request->get('fgitsChangeCheckoutEmail')); } if ($config['sendCustomerInvoice'] && isset($request) && !$request->get('fgitsSendCustomerInvoice')) { $this->orderCustomFields->setCustomerNoInvoice($event->getOrder()); } $context = $this->utility->getContext($event->getOrder(), $event->getContext()); $order = $this->dbOrder->getOrderById($event->getOrderId(), $this->utility->getOrderAssociations(), $context); try { $this->orderProcessor->processOrder($order, $context, true); } catch (\Exception $e) { $this->logger->error('[#fgits] fgitsAutoinvoiceSW6: ' . __CLASS__ . '::' . __FUNCTION__ . '(): Order #' . $order->getOrderNumber() . ': ' . print_r($e->getMessage(), true)); } } /** * Gets invoked when the payment status is changed. * * @param StateMachineStateChangeEvent $event */ public function onOrderTransactionStateChanged(StateMachineStateChangeEvent $event): void { $config = $this->systemConfigService->get('fgitsAutoinvoiceSW6.config', $event->getSalesChannelId()); if (!$config['active'] || empty($config['conditionPaymentStatus'])) { return; } $orderTransactionId = $event->getTransition()->getEntityId(); $criteria = new Criteria([$orderTransactionId]); $criteria->addAssociation('paymentMethod'); $criteria->addAssociation('order.orderCustomer'); $criteria->addAssociation('order.transactions'); /** @var OrderTransactionEntity|null $orderTransaction */ $orderTransaction = $this->orderTransactionRepository->search($criteria, $event->getContext())->first(); if ($orderTransaction === null) { throw new OrderTransactionNotFoundException($orderTransactionId); } if ($orderTransaction->getPaymentMethod() === null) { throw new OrderTransactionNotFoundException($orderTransactionId); } if ($orderTransaction->getOrder() === null) { throw new OrderNotFoundException($orderTransactionId); } $context = $this->utility->getContext($orderTransaction->getOrder(), $event->getContext()); $order = $this->dbOrder->getOrderById($orderTransaction->getOrderId(), $this->utility->getOrderAssociations(), $context); $order->fgitsAutoinvoiceOrderTransactionId = $orderTransactionId; try { $this->orderProcessor->processOrder($order, $context); } catch (\Exception $e) { $this->logger->error('[#fgits] fgitsAutoinvoiceSW6: ' . __CLASS__ . '::' . __FUNCTION__ . '(): Order #' . $order->getOrderNumber() . ': ' . print_r($e->getMessage(), true)); } } /** * Gets invoked when the delivery status is changed. * * @param StateMachineStateChangeEvent $event */ public function onOrderDeliveryStateChanged(StateMachineStateChangeEvent $event): void { $config = $this->systemConfigService->get('fgitsAutoinvoiceSW6.config', $event->getSalesChannelId()); if (!$config['active'] || empty($config['conditionDeliveryStatus'])) { return; } $orderDeliveryId = $event->getTransition()->getEntityId(); $criteria = new Criteria([$orderDeliveryId]); $criteria->addAssociation('order.orderCustomer'); $criteria->addAssociation('order.transactions'); /** @var OrderDeliveryEntity|null $orderDelivery */ $orderDelivery = $this->orderDeliveryRepository->search($criteria, $event->getContext())->first(); if ($orderDelivery === null) { throw new OrderDeliveryNotFoundException($orderDeliveryId); } if ($orderDelivery->getOrder() === null) { throw new OrderNotFoundException($orderDeliveryId); } $context = $this->utility->getContext($orderDelivery->getOrder(), $event->getContext()); $order = $this->dbOrder->getOrderById($orderDelivery->getOrderId(), $this->utility->getOrderAssociations(), $context); try { $this->orderProcessor->processOrder($order, $context); } catch (\Exception $e) { $this->logger->error('[#fgits] fgitsAutoinvoiceSW6: ' . __CLASS__ . '::' . __FUNCTION__ . '(): Order #' . $order->getOrderNumber() . ': ' . print_r($e->getMessage(), true)); } } /** * Gets invoked when the order status is changed. * * @param StateMachineStateChangeEvent $event */ public function onOrderStateChanged(StateMachineStateChangeEvent $event): void { $config = $this->systemConfigService->get('fgitsAutoinvoiceSW6.config', $event->getSalesChannelId()); if (!$config['active'] || empty($config['conditionOrderStatus'])) { return; } $orderId = $event->getTransition()->getEntityId(); $criteria = new Criteria([$orderId]); $criteria->addAssociation('orderCustomer'); $criteria->addAssociation('transactions'); $order = $this->orderRepository->search($criteria, $event->getContext())->first(); if ($order === null) { throw new OrderNotFoundException($orderId); } $context = $this->utility->getContext($order, $event->getContext()); $order = $this->dbOrder->getOrderById($orderId, $this->utility->getOrderAssociations(), $context); try { $this->orderProcessor->processOrder($order, $context); } catch (\Exception $e) { $this->logger->error('[#fgits] fgitsAutoinvoiceSW6: ' . __CLASS__ . '::' . __FUNCTION__ . '(): Order #' . $order->getOrderNumber() . ': ' . print_r($e->getMessage(), true)); } } /** * Gets invoked when the order status is changed. * * @param StateMachineStateChangeEvent $event */ public function onOrderStateChangedTickets(StateMachineStateChangeEvent $event): void { $config = $this->systemConfigService->get('FgitsTicketsV3.config', $event->getSalesChannelId()); if (!$this->utility->isPluginActive('FgitsTicketsV3') || !$config['extrasActive'] || ($config['extrasActionOnCancel'] == 'none' && $config['extrasActionOnReopen'] == 'none')) { return; } if ($event->getNextState()->getTechnicalName() == 'cancelled') { $ticketsExtras = $this->utility->getService('Fgits\FgitsTicketsV3\Service\Extras'); switch ($config['extrasActionOnCancel']) { case 'deactivate': $ticketsExtras->deactivateTickets($event->getTransition()->getEntityId(), $event->getContext()); break; case 'delete': $ticketsExtras->deleteTickets($event->getTransition()->getEntityId(), $event->getContext()); break; } } elseif ($event->getNextState()->getTechnicalName() == 'open' && $event->getPreviousState()->getTechnicalName() == 'cancelled' && ($config['extrasActionOnReopen'] == 'activate' || $config['extrasActionOnReopen'] == 'send')) { $ticketsExtras = $this->utility->getService('Fgits\FgitsTicketsV3\Service\Extras'); $ticketsExtras->activateTickets($event->getTransition()->getEntityId(), $event->getContext()); if ($config['extrasActionOnReopen'] == 'send') { $orderId = $event->getTransition()->getEntityId(); $criteria = new Criteria([$orderId]); $criteria->addAssociation('orderCustomer'); $criteria->addAssociation('transactions'); $order = $this->orderRepository->search($criteria, $event->getContext())->first(); if ($order === null) { throw new OrderNotFoundException($orderId); } $context = $this->utility->getContext($order, $event->getContext()); $order = $this->dbOrder->getOrderById($orderId, $this->utility->getOrderAssociations(), $context); $ticketsExtras->sendTickets($order, $context); } } }}