<?php
namespace App\EventSubscriber;
use App\Entity\Notification;
use App\Entity\UserTransaction;
use App\Event\ItemOnMarketPurchasedEvent;
use App\Event\ItemQuickSellEvent;
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 MarketEventSubscriber implements EventSubscriberInterface
{
private $notificationService;
private $em;
private $userWalletManager;
private $userTransactionManager;
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 onItemOnMarketPurchased(ItemOnMarketPurchasedEvent $event)
{
$userItem = $event->getUserItem();
$owner = $userItem->getUser();
$buyer = $event->getBuyer();
$itemPrice = $userItem->getPrice();
$buyerWallet = $this->userWalletManager->getWallet($buyer);
$ownerWallet = $this->userWalletManager->getWallet($owner);
if($itemPrice > $buyerWallet->getValue()){
throw new Exception('Not enough money');
}
try {
$this->em->getConnection()->beginTransaction();
$buyerWallet->substractValue($itemPrice);
$ownerWallet->addValue($itemPrice);
$this->userTransactionManager->create($buyer, $owner, $itemPrice, UserTransaction::TYPE_ITEM_MARKET_PURCHASED);
$this->userTransactionManager->create($owner, $buyer, (-1)*$itemPrice, UserTransaction::TYPE_ITEM_MARKET_SOLD);
$this->notificationService->create(
$owner,
Notification::TYPE_ITEM_SOLD,
[
'item_id' => $userItem->getItem()->getId(),
'item_name' => $userItem->getItem()->getName(),
'item_price' => $userItem->getPrice(),
'item_avatar' => $userItem->getItem()->getThumbnailUrl(),
]
);
$userItem->setUser($buyer);
$userItem->setOnMarket(false);
$this->em->persist($userItem);
$this->em->persist($buyerWallet);
$this->em->persist($ownerWallet);
$this->em->flush();
$this->em->getConnection()->commit();
} catch (\Exception $e){
$this->em->getConnection()->rollBack();
throw new Exception($e->getMessage());
}
}
public function onItemQuickSold(ItemQuickSellEvent $event)
{
$userItem = $event->getUserItem();
$userWallet = $this->userWalletManager->getWallet($userItem->getUser());
try {
$this->em->getConnection()->beginTransaction();
$quickSellPrice = $userItem->getItem()->getPrice()/2;
$userWallet->addValue($quickSellPrice);
$this->userTransactionManager->create(null, $userItem->getUser(), $quickSellPrice, UserTransaction::TYPE_MARKET_QUICK_SOLD);
$this->em->remove($userItem);
$this->em->persist($userWallet);
$this->em->flush();
$this->em->getConnection()->commit();
} catch (\Exception $e){
$this->em->getConnection()->rollBack();
throw new Exception($e->getMessage());
}
}
public static function getSubscribedEvents()
{
return [
ItemOnMarketPurchasedEvent::NAME => 'onItemOnMarketPurchased',
ItemQuickSellEvent::NAME => 'onItemQuickSold',
];
}
}