<?php declare(strict_types=1);
namespace System4InterfacePlugin\Subscriber;
use Shopware\Core\Checkout\Cart\Event\CheckoutOrderPlacedEvent;
use Shopware\Core\Checkout\Cart\Order\CartConvertedEvent;
use Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionDefinition;
use Shopware\Core\Checkout\Order\OrderEntity;
use Shopware\Core\Checkout\Order\OrderStates;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\System\StateMachine\Event\StateMachineTransitionEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use System4InterfacePlugin\Services\OrderService;
use Shopware\Core\Framework\Context;
use Shopware\Core\Defaults;
class OrderSubscriber implements EventSubscriberInterface
{
/**
* @var EntityRepository
*/
private $orderRepository;
/**
* @var OrderService
*/
private $orderService;
/**
* @var CartConvertedEvent
*/
protected $cartConvertedEvent;
public function __construct(
EntityRepository $orderRepository,
OrderService $orderService
) {
$this->orderRepository = $orderRepository;
$this->orderService = $orderService;
}
public static function getSubscribedEvents()
{
return [
CheckoutOrderPlacedEvent::class => 'onOrderPlaced',
StateMachineTransitionEvent::class => 'onStateChanged'
];
}
public function onOrderPlaced(CheckoutOrderPlacedEvent $event)
{
$order = $event->getOrder();
$this->orderRepository->update([
[
'id' => $order->getId(),
'customFields' => ['system4_erp_status' => "Not Received"]
]
], Context::createDefaultContext());
$orderTransaction = $order->getTransactions()->first();
if ($orderTransaction->getPaymentMethod() && $orderTransaction->getPaymentMethod()->isSynchronous()) {
$order = $this->getOrder($event, $order->getId());
$response = $this->orderService->sendOrderPayload($order, $order->getOrderCustomer()->getCustomer());
}
}
public function onStateChanged(StateMachineTransitionEvent $event)
{
if ($event->getEntityName() !== OrderTransactionDefinition::ENTITY_NAME) {
return;
}
$to = $event->getToPlace()->getTechnicalName();
$from = $event->getFromPlace()->getTechnicalName();
if ($from === OrderStates::STATE_OPEN && $to !== OrderStates::STATE_CANCELLED) {
$order = $this->getOrderTransaction($event, $event->getEntityId());
$this->orderRepository->update([
[
'id' => $order->getId(),
'customFields' => ['system4_erp_status' => "Not Received"]
]
], Context::createDefaultContext());
$orderTransaction = $order->getTransactions()->first();
if ($orderTransaction->getPaymentMethod()->isAsynchronous()) {
$response = $this->orderService->sendOrderPayload($order, $order->getOrderCustomer()->getCustomer());
}
}
}
private function getOrder(CheckoutOrderPlacedEvent $event, string $id): ?OrderEntity
{
$criteria = new Criteria([$id]);
$criteria->addAssociation('orderCustomer.customer');
$criteria->addAssociation('lineItems');
$criteria->addAssociation('transactions.paymentMethod');
$criteria->addAssociation('billingAddress.country');
$criteria->addAssociation('deliveries.shippingMethod');
$criteria->addAssociation('deliveries.shippingOrderAddress.country');
$criteria->addAssociation('currency');
$criteria->addAssociation('language.translationCode');
return $this->orderRepository->search($criteria, $event->getContext())->first();
}
private function getOrderTransaction(StateMachineTransitionEvent $event, string $id): ?OrderEntity
{
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('transactions.id', $id));
$criteria->addAssociation('orderCustomer.customer');
$criteria->addAssociation('lineItems');
$criteria->addAssociation('transactions.paymentMethod');
$criteria->addAssociation('billingAddress.country');
$criteria->addAssociation('deliveries.shippingMethod');
$criteria->addAssociation('deliveries.shippingOrderAddress.country');
return $this->orderRepository->search($criteria, $event->getContext())->first();
}
}