<?php declare(strict_types=1);namespace Shopware\B2B\Cart\BridgePlatform;use Shopware\B2B\Order\BridgePlatform\OrderContextCreatedEvent;use Shopware\B2B\Order\Framework\OrderContext;use Shopware\Core\Checkout\Cart\Cart;use Shopware\Core\Checkout\Cart\Event\CheckoutOrderPlacedEvent;use Shopware\Core\Checkout\Cart\Order\CartConvertedEvent;use Shopware\Core\Checkout\Order\OrderEntity;use Shopware\Core\System\SalesChannel\SalesChannelContext;use Symfony\Component\EventDispatcher\EventDispatcherInterface;use Symfony\Component\EventDispatcher\EventSubscriberInterface;abstract class CartFinishSubscriber implements EventSubscriberInterface{ private const PRIORITY_EARLY = 10; /** * @var CartConvertedEvent */ protected $cartConvertedEvent; /** * @var EventDispatcherInterface */ protected $eventDispatcher; public function __construct(EventDispatcherInterface $eventDispatcher) { $this->eventDispatcher = $eventDispatcher; } public static function getSubscribedEvents(): array { return [ CartConvertedEvent::class => ['initializeState', self::PRIORITY_EARLY], CheckoutOrderPlacedEvent::class => ['handleCreatedOrder', self::PRIORITY_EARLY], ]; } public function initializeState(CartConvertedEvent $event): void { $this->cartConvertedEvent = $event; } public function handleCreatedOrder(CheckoutOrderPlacedEvent $event): void { $this->testStateValid($event); $orderContext = $this->onCartFinish( $this->cartConvertedEvent->getCart(), $event->getOrder(), $this->cartConvertedEvent->getSalesChannelContext() ); if ($orderContext) { $this->eventDispatcher->dispatch(new OrderContextCreatedEvent($orderContext)); } $this->reset(); } abstract protected function onCartFinish(Cart $cart, OrderEntity $orderEntity, SalesChannelContext $salesChannelContext): ?OrderContext; protected function getCartState(): CartState { return $this ->cartConvertedEvent ->getCart() ->getExtension(CartState::NAME); } /** * @internal */ protected function testStateValid(CheckoutOrderPlacedEvent $orderPlacedEvent): void { if (!$this->cartConvertedEvent) { throw new CartFinishException('Placing order without dispatching cart converted'); } $orderNumber = $this->cartConvertedEvent->getConvertedCart()['orderNumber']; if ($orderNumber !== $orderPlacedEvent->getOrder()->getOrderNumber()) { throw new CartFinishException('CheckoutOrderPlacedEvent contains different order number than CartConvertedEvent'); } $salesChannelContext = $this->cartConvertedEvent->getSalesChannelContext(); if ($salesChannelContext->getSalesChannel()->getId() !== $orderPlacedEvent->getSalesChannelId()) { throw new CartFinishException('SalesChannel id differs between events'); } } private function reset(): void { $this->cartConvertedEvent = null; }}