<?php
namespace App\EventSubscriber;
use App\Entity\Notification;
use App\Entity\UserTransaction;
use App\Entity\UserWallet;
use App\Event\CashTransferredEvent;
use App\Service\NotificationService;
use App\Service\UserTransactionManager;
use App\Service\UserWalletManager;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Config\Definition\Exception\Exception;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class UserEventSubscriber implements EventSubscriberInterface
{
private $notificationService;
private $userWalletManager;
private $userTransactionManager;
private $em;
public function __construct(
NotificationService $notificationService,
EntityManagerInterface $entityManager,
UserWalletManager $userWalletManager,
UserTransactionManager $userTransactionManager
)
{
$this->notificationService = $notificationService;
$this->em = $entityManager;
$this->userWalletManager = $userWalletManager;
$this->userTransactionManager = $userTransactionManager;
}
public function onCashTransferred(CashTransferredEvent $event)
{
try {
$this->em->getConnection()->beginTransaction();
$this->userTransactionManager->create($event->getUserFrom(), $event->getUserTo(), UserTransaction::TYPE_CASH_TRANSFERRED, $event->getValue());
$userFromWallet = $this->userWalletManager->getWallet($event->getUserFrom());
$userToWallet = $this->userWalletManager->getWallet($event->getUserTo());
if(!$userFromWallet || $userFromWallet->getValue() < $event->getValue()){
throw new Exception('Not enough money');
}
$userFromWallet->substractValue($event->getValue());
if(!$userToWallet){
$userToWallet = new UserWallet();
$userToWallet->setUser($event->getUserTo());
}
$userToWallet->addValue($event->getValue());
$this->em->persist($userFromWallet);
$this->em->persist($userToWallet);
$this->em->flush();
$this->em->getConnection()->commit();
} catch (\Exception $e) {
$this->em->getConnection()->rollBack();
throw new Exception($e->getMessage());
}
$this->notificationService->create(
$event->getUserTo(),
Notification::TYPE_CASH_FROM_PARENT_ACCOUNT,
[
'user_id' => $event->getUserFrom()->getId(),
'user_name' => $event->getUserFrom()->getName(),
'user_avatar_url' => $event->getUserFrom()->getAvatarUrl(),
'amount' => $event->getValue()
]
);
}
public static function getSubscribedEvents()
{
return [
CashTransferredEvent::NAME => 'onCashTransferred'
];
}
}