src/Subscriber/Order/OrderSubscriber.php line 58

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Subscriber\Order;
  4. use App\Event\Cinema\CinemaContextChangedEvent;
  5. use App\Event\Order\OrderClosedEvent;
  6. use App\Event\Order\OrderCompletedEvent;
  7. use App\Event\Order\OrderPaymentTransactionCancelledEvent;
  8. use App\Event\Order\OrderPaymentTransactionExceptionEvent;
  9. use App\Event\Order\OrderPaymentTransactionHandledEvent;
  10. use App\Event\Order\OrderPaymentTransactionReceivedEvent;
  11. use App\Manager\OrderManager;
  12. use App\Model\Order\Item\ScreeningItem;
  13. use App\Model\Order\Order;
  14. use App\Service\Order\OrderPaymentLogBuilderService;
  15. use App\Subscriber\Order\Model\OrderPaymentTransactionExceptionFlowModel;
  16. use App\Subscriber\Order\Model\OrderPaymentTransactionFlowModel;
  17. use Doctrine\Common\Collections\ArrayCollection;
  18. use Psr\Log\LoggerInterface;
  19. use Ramsey\Uuid\Uuid;
  20. use Ramsey\Uuid\UuidInterface;
  21. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  22. class OrderSubscriber implements EventSubscriberInterface
  23. {
  24.     private OrderManager $orderManager;
  25.     private UuidInterface $currentCinemaId;
  26.     private LoggerInterface $paymentLogger;
  27.     private ArrayCollection $transactionFlowModelCollection;
  28.     private OrderPaymentLogBuilderService $paymentLogBuilderService;
  29.     public function __construct(
  30.         OrderManager                  $orderManager,
  31.         LoggerInterface               $paymentLogger,
  32.         OrderPaymentLogBuilderService $orderPaymentLogBuilderService
  33.     ) {
  34.         $this->orderManager                   $orderManager;
  35.         $this->paymentLogger                  $paymentLogger;
  36.         $this->paymentLogBuilderService       $orderPaymentLogBuilderService;
  37.         $this->transactionFlowModelCollection = new ArrayCollection();
  38.     }
  39.     public static function getSubscribedEvents(): array
  40.     {
  41.         return [
  42.             OrderCompletedEvent::class                   => 'onOrderCompleted',
  43.             CinemaContextChangedEvent::class             => 'onCinemaContextChanged',
  44.             OrderPaymentTransactionReceivedEvent::class  => 'onOrderPaymentTransactionReceived',
  45.             OrderPaymentTransactionExceptionEvent::class => 'onOrderPaymentTransactionException',
  46.             OrderClosedEvent::class                      => 'onOrderClosed',
  47.             OrderPaymentTransactionCancelledEvent::class => 'onOrderTransactionCancelled',
  48.             OrderPaymentTransactionHandledEvent::class   => 'onOrderTransactionHandled',
  49.         ];
  50.     }
  51.     public function onCinemaContextChanged(CinemaContextChangedEvent $event): void
  52.     {
  53.         $this->currentCinemaId $event->getCinemaId();
  54.     }
  55.     public function onOrderCompleted(OrderCompletedEvent $event): void
  56.     {
  57.         $order $this->orderManager->get($event->getOrder()->getId());
  58.         if ($order !== null) {
  59.             $this->createOrderNotification($order$event->getSalesDocumentId());
  60.         }
  61.     }
  62.     private function createOrderNotification(Order $orderUuid $salesDocumentId): void
  63.     {
  64.         if ($order->getStatus() === Order::CLOSED) {
  65.             $this->orderManager->createOrderAlias($order$this->currentCinemaId$salesDocumentId);
  66.         }
  67.     }
  68.     public function onOrderPaymentTransactionReceived(OrderPaymentTransactionReceivedEvent $event): void
  69.     {
  70.         $this->getTransactionFlowModel($event->getOrder())
  71.              ->setOrderId($event->getOrder()->getId())
  72.              ->setTransactionId($event->getPaymentProviderResponse()->getTransactionId())
  73.              ->setCinemaId($event->getPaymentProviderResponse()->getCinemaId())
  74.              ->setValueToPay($event->getOrder()->getPriceToPay())
  75.              ->setPaymentChannel($event->getPaymentChannel())
  76.              ->setTransactionStatus($event->getPaymentProviderResponse()->getStatus())
  77.              ->setBookingIds(array_unique(array_map(static function (ScreeningItem $screeningItem) {
  78.                      return (string)$screeningItem->getId();
  79.                  }, $event->getOrder()->getScreeningItems()?->toArray() ?? []
  80.                  )
  81.              ))
  82.         ;
  83.     }
  84.     public function onOrderPaymentTransactionException(OrderPaymentTransactionExceptionEvent $event): void
  85.     {
  86.         $exceptionFlowModel = new OrderPaymentTransactionExceptionFlowModel(
  87.             $event->getException(),
  88.             $event->getAdditionalMessage()
  89.         );
  90.         $this->getTransactionFlowModel($event->getOrder())
  91.              ->getExceptionCollection()
  92.              ->add($exceptionFlowModel);
  93.     }
  94.     public function onOrderClosed(OrderClosedEvent $event): void
  95.     {
  96.         $this->getTransactionFlowModel($event->getOrder())
  97.              ->setIsOrderClosed(true);
  98.     }
  99.     public function onOrderTransactionCancelled(OrderPaymentTransactionCancelledEvent $event): void
  100.     {
  101.         $this->getTransactionFlowModel($event->getOrder())
  102.              ->setIsPaymentTransactionCancelled(true)
  103.              ->setPaymentTransactionCancelDetails($event->getReason());
  104.     }
  105.     public function onOrderTransactionHandled(OrderPaymentTransactionHandledEvent $event): void
  106.     {
  107.         $transactionFlowModel $this->getTransactionFlowModel($event->getOrder());
  108.         $log $this->paymentLogBuilderService->build($transactionFlowModel);
  109.         if ($transactionFlowModel->getExceptionCollection()->isEmpty()) {
  110.             $this->paymentLogger->info($log);
  111.         } else {
  112.             $this->paymentLogger->error($log);
  113.         }
  114.     }
  115.     private function getTransactionFlowModel(Order $order): OrderPaymentTransactionFlowModel
  116.     {
  117.         $transactionFlowModel $this->transactionFlowModelCollection->filter(
  118.             static function (OrderPaymentTransactionFlowModel $flowModel) use ($order) {
  119.                 return (string)$flowModel->getOrderId() === (string)$order->getId();
  120.             }
  121.         )->first();
  122.         if ($transactionFlowModel === false) {
  123.             $transactionFlowModel = new OrderPaymentTransactionFlowModel();
  124.             $this->transactionFlowModelCollection->add($transactionFlowModel);
  125.             return $transactionFlowModel;
  126.         }
  127.         assert($transactionFlowModel instanceof OrderPaymentTransactionFlowModel);
  128.         return $transactionFlowModel;
  129.     }
  130. }