src/EventSubscriber/Shop/BeforeOrderCreateSubscriber.php line 46
<?phpdeclare(strict_types=1);namespace App\EventSubscriber\Shop;use ApiPlatform\Core\EventListener\EventPriorities;use App\Entity\Ledger\Account;use App\Entity\Shop\Order;use App\Exceptions\Shop\BuyerAlreadyHasAnyItemsException;use App\Services\Shop\OrderItemValidator;use App\Services\Transaction\CreateService;use App\Services\Transaction\Types\TypeCreatorInterface;use Symfony\Component\EventDispatcher\EventSubscriberInterface;use Symfony\Component\HttpFoundation\Request;use Symfony\Component\HttpKernel\Event\ViewEvent;use Symfony\Component\HttpKernel\KernelEvents;use Symfony\Component\Workflow\WorkflowInterface;class BeforeOrderCreateSubscriber implements EventSubscriberInterface{protected const COMMENT = 'Checkout order #%s';public function __construct(private readonly TypeCreatorInterface $payTypeCreator,private readonly OrderItemValidator $orderItemValidator,private readonly WorkflowInterface $orderStateMachine,private readonly CreateService $transactionService,private readonly Account $bankAccount,) {}public static function getSubscribedEvents(): array{return [KernelEvents::VIEW => [['validate', EventPriorities::PRE_WRITE + 1],['checkout', EventPriorities::PRE_WRITE],],];}/*** @throws BuyerAlreadyHasAnyItemsException*/public function validate(ViewEvent $event): void{if (!$this->support($event)) {return;}$this->orderItemValidator->validate($this->getOrder($event));}/*** @throws \Throwable*/public function checkout(ViewEvent $event): void{if (!$this->support($event)) {return;}$order = $this->getOrder($event);$payType = $this->payTypeCreator->createType($order->getBuyer()->getMainAccount(),$this->bankAccount,$order->getTotal(),sprintf(self::COMMENT, $order->getId()),);try {$this->transactionService->perform($payType);$this->orderStateMachine->apply($order, 'pay');} catch (\Throwable $e) {$this->orderStateMachine->apply($order, 'reject');throw $e;}}private function support(ViewEvent $event): bool{$method = $event->getRequest()->getMethod();$order = $event->getControllerResult();return $order instanceof Order && Request::METHOD_POST === $method;}private function getOrder(ViewEvent $event): Order{return $event->getControllerResult();}}