src/App/Subscriber/ManageCreditsHistorySubscriber.php line 30

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace App\Subscriber;
  3. use App\Entity\CreditHistory;
  4. use App\Entity\PaymentVxsOrder;
  5. use App\Entity\User;
  6. use App\Event\CreditsEvent;
  7. use App\Event\Recurring\MembershipPaymentCancelledEvent;
  8. use App\Event\Recurring\MembershipPaymentEventInterface;
  9. use App\Event\Recurring\MembershipPaymentReceivedEvent;
  10. use App\Model\ChangeCard;
  11. use Doctrine\DBAL\Connection;
  12. use Doctrine\Persistence\ManagerRegistry;
  13. use DomainException;
  14. use LogicException;
  15. use RuntimeException;
  16. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  17. class ManageCreditsHistorySubscriber implements EventSubscriberInterface
  18. {
  19.     private ManagerRegistry $doctrine;
  20.     public function __construct(ManagerRegistry $doctrine)
  21.     {
  22.         $this->doctrine $doctrine;
  23.     }
  24.     public function onCredits(CreditsEvent $event): void
  25.     {
  26.         /** @var Connection $connection */
  27.         $connection $this->doctrine->getConnection();
  28.         if (!$connection->isTransactionActive()) {
  29.             throw new RuntimeException('You must start DB transaction in order to use this event');
  30.         }
  31.         if (!($event->getUser() instanceof User)) {
  32.             throw new RuntimeException('The event must have a user.');
  33.         }
  34.         $creditsRelated $event->getRelatedEntity();
  35.         $creditHistory = new CreditHistory();
  36.         $creditHistory->setUser($event->getUser());
  37.         $creditHistory->setRelatedEntity($creditsRelated$event->getAction());
  38.         if (null !== $event->getBillAt()) {
  39.             $creditHistory->setLastModified(clone $event->getBillAt());
  40.         }
  41.         $credits $event->getCredits();
  42.         if (in_array($event->getAction(), [CreditsEvent::ACTION_CHARGEBACKCreditsEvent::ACTION_REFUND], true)) {
  43.             $credits *= -1;
  44.             if (!($creditsRelated instanceof PaymentVxsOrder)) {
  45.                 throw new DomainException('Other related entities refund is not implemented.');
  46.             }
  47.             $refundedCreditsHistory $this->doctrine->getRepository(CreditHistory::class)
  48.                 ->findOneBy(['vxsOrder' => $creditsRelated]);
  49.             if (null === $refundedCreditsHistory) {
  50.                 throw new LogicException('Can not find CreditsHistory to refund.');
  51.             }
  52.             $refundedCreditsHistory->setRefunded(true);
  53.         }
  54.         $creditHistory->setCredits($credits);
  55.         if (=== $credits
  56.             && $creditsRelated instanceof PaymentVxsOrder
  57.             && $event->getAction() === CreditsEvent::ACTION_CREDITS
  58.             && $creditsRelated->getAmountFloat() === ChangeCard::CREDIT_CHANGE_AMOUNT
  59.         ) {
  60.             $creditHistory->setRelatedEntity($creditsRelated$event->getAction() . '-change-card');
  61.         }
  62.         $this->doctrine->getManager()->persist($creditHistory);
  63.         $this->doctrine->getManager()->flush();
  64.     }
  65.     public function onPaymentReceived(MembershipPaymentReceivedEvent $event): void
  66.     {
  67.         if (!($event->getUser() instanceof User)) {
  68.             throw new RuntimeException('The event must have a user.');
  69.         }
  70.         $action MembershipPaymentEventInterface::ACTION_MEMBERSHIP_NEW;
  71.         if (count($event->getCreditsMembership()->getVxsOrders()) > 1) {
  72.             $action MembershipPaymentEventInterface::ACTION_MEMBERSHIP_REBILL;
  73.         }
  74.         $this->writeMembershipCreditsHistory($event->getUser(), $event->getVxsOrder(), $action);
  75.     }
  76.     public function onPaymentCancelled(MembershipPaymentCancelledEvent $event): void
  77.     {
  78.         if (!($event->getUser() instanceof User)) {
  79.             throw new RuntimeException('The event must have a user.');
  80.         }
  81.         $action MembershipPaymentEventInterface::ACTION_MEMBERSHIP_REFUND;
  82.         if ($event->isChargeback()) {
  83.             $action MembershipPaymentEventInterface::ACTION_MEMBERSHIP_CHARGEBACK;
  84.         }
  85.         $this->writeMembershipCreditsHistory($event->getUser(), $event->getVxsOrder(), $action);
  86.     }
  87.     private function writeMembershipCreditsHistory(User $userPaymentVxsOrder $vxsOrderstring $action): void
  88.     {
  89.         /** @var Connection $connection */
  90.         $connection $this->doctrine->getConnection();
  91.         if (!$connection->isTransactionActive()) {
  92.             throw new RuntimeException('You must start DB transaction in order to use this event');
  93.         }
  94.         $creditHistory = new CreditHistory();
  95.         $creditHistory->setUser($user);
  96.         $creditHistory->setRelatedEntity($vxsOrder$action);
  97.         $creditHistory->setCredits(0);
  98.         $this->doctrine->getManager()->persist($creditHistory);
  99.         $this->doctrine->getManager()->flush();
  100.     }
  101.     /**
  102.      * @return array<string, array<int|string, array<int|string, int|string>|int|string>|string>
  103.      */
  104.     public static function getSubscribedEvents(): array
  105.     {
  106.         return [
  107.             CreditsEvent::class => 'onCredits',
  108.             MembershipPaymentReceivedEvent::class => 'onPaymentReceived',
  109.             MembershipPaymentCancelledEvent::class => 'onPaymentCancelled',
  110.         ];
  111.     }
  112. }