src/PaymentBundle/Listener/PaymentCompleteListener.php line 54

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. /*
  4.  * This file is part of SolidInvoice project.
  5.  *
  6.  * (c) Pierre du Plessis <open-source@solidworx.co>
  7.  *
  8.  * This source file is subject to the MIT license that is bundled
  9.  * with this source code in the file LICENSE.
  10.  */
  11. namespace SolidInvoice\PaymentBundle\Listener;
  12. use Brick\Math\Exception\MathException;
  13. use Doctrine\Persistence\ManagerRegistry;
  14. use Generator;
  15. use SolidInvoice\ClientBundle\Entity\Credit;
  16. use SolidInvoice\CoreBundle\Response\FlashResponse;
  17. use SolidInvoice\InvoiceBundle\Entity\Invoice;
  18. use SolidInvoice\InvoiceBundle\Model\Graph;
  19. use SolidInvoice\PaymentBundle\Entity\Payment;
  20. use SolidInvoice\PaymentBundle\Event\PaymentCompleteEvent;
  21. use SolidInvoice\PaymentBundle\Event\PaymentEvents;
  22. use SolidInvoice\PaymentBundle\Model\Status;
  23. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  24. use Symfony\Component\HttpFoundation\RedirectResponse;
  25. use Symfony\Component\Routing\RouterInterface;
  26. use Symfony\Component\Workflow\StateMachine;
  27. class PaymentCompleteListener implements EventSubscriberInterface
  28. {
  29.     /**
  30.      * @return array<string, string>
  31.      */
  32.     public static function getSubscribedEvents(): array
  33.     {
  34.         return [
  35.             PaymentEvents::PAYMENT_COMPLETE => 'onPaymentComplete',
  36.         ];
  37.     }
  38.     public function __construct(
  39.         private readonly StateMachine $invoiceStateMachine,
  40.         private readonly ManagerRegistry $registry,
  41.         private readonly RouterInterface $router
  42.     ) {
  43.     }
  44.     /**
  45.      * @throws MathException
  46.      */
  47.     public function onPaymentComplete(PaymentCompleteEvent $event): void
  48.     {
  49.         $payment $event->getPayment();
  50.         $status = (string) $payment->getStatus();
  51.         if ('credit' === $payment->getMethod()?->getGatewayName()) {
  52.             $creditRepository $this->registry->getRepository(Credit::class);
  53.             $creditRepository->deductCredit(
  54.                 $payment->getClient(),
  55.                 $payment->getTotalAmount(),
  56.             );
  57.         }
  58.         if (($invoice $event->getPayment()->getInvoice()) instanceof Invoice) {
  59.             $em $this->registry->getManager();
  60.             if (Status::STATUS_CAPTURED === $status && $em->getRepository(Invoice::class)->isFullyPaid($invoice)) {
  61.                 $this->invoiceStateMachine->apply($invoiceGraph::TRANSITION_PAY);
  62.             } else {
  63.                 $paymentRepository $this->registry->getRepository(Payment::class);
  64.                 $invoiceTotal $invoice->getTotal();
  65.                 $totalPaid $paymentRepository->getTotalPaidForInvoice($invoice);
  66.                 $invoice->setBalance($invoiceTotal->minus($totalPaid));
  67.                 $em $this->registry->getManager();
  68.                 $em->persist($invoice);
  69.                 $em->flush();
  70.             }
  71.             $router $this->router;
  72.             $event->setResponse(
  73.                 new class($router->generate('_view_invoice_external', ['uuid' => $invoice->getUuid()]), $status) extends RedirectResponse implements FlashResponse {
  74.                     public function __construct(
  75.                         string $route,
  76.                         private readonly string $paymentStatus
  77.                     ) {
  78.                         parent::__construct($route);
  79.                     }
  80.                     public function getFlash(): Generator
  81.                     {
  82.                         yield from PaymentCompleteListener::addFlashMessage($this->paymentStatus);
  83.                     }
  84.                 }
  85.             );
  86.         }
  87.     }
  88.     public static function addFlashMessage(string $status): Generator
  89.     {
  90.         match ($status) {
  91.             Status::STATUS_CAPTURED => yield FlashResponse::FLASH_SUCCESS => 'payment.flash.status.success',
  92.             Status::STATUS_CANCELLED => yield FlashResponse::FLASH_DANGER => 'payment.flash.status.cancelled',
  93.             Status::STATUS_PENDING => yield FlashResponse::FLASH_WARNING => 'payment.flash.status.pending',
  94.             Status::STATUS_EXPIRED => yield FlashResponse::FLASH_DANGER => 'payment.flash.status.expired',
  95.             Status::STATUS_FAILED => yield FlashResponse::FLASH_DANGER => 'payment.flash.status.failed',
  96.             Status::STATUS_NEW => yield FlashResponse::FLASH_WARNING => 'payment.flash.status.new',
  97.             Status::STATUS_SUSPENDED => yield FlashResponse::FLASH_DANGER => 'payment.flash.status.suspended',
  98.             Status::STATUS_AUTHORIZED => yield FlashResponse::FLASH_INFO => 'payment.flash.status.authorized',
  99.             Status::STATUS_REFUNDED => yield FlashResponse::FLASH_WARNING => 'payment.flash.status.refunded',
  100.             default => yield FlashResponse::FLASH_DANGER => 'payment.flash.status.unknown',
  101.         };
  102.     }
  103. }