<?php
declare(strict_types=1);
namespace App\Controller\V1\User;
use App\Entity\Local\Response\PaymentStartResponse;
use App\Entity\Vista\LoyaltyMember;
use App\Entity\Vista\MemberTransaction;
use App\Entity\Vista\Order;
use App\Helper\MPay24Helper;
use App\Helper\PaymentHelper;
use App\Helper\UserHelper;
use App\Repository\CinemaRepository;
use App\Repository\ConcessionRepository;
use App\Repository\OrderRepositoryInterface;
use App\Repository\RestrictionsRepository;
use App\Repository\UserBalanceRepository;
use App\Repository\UserBalanceTransactionRepository;
use DateTimeImmutable;
use FOS\RestBundle\Controller\AbstractFOSRestController;
use FOS\RestBundle\Controller\Annotations as Rest;
use Nelmio\ApiDocBundle\Annotation\Model;
use Nelmio\ApiDocBundle\Annotation\Security as NelmioSecurity;
use Swagger\Annotations as SWG;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use App\Security\Security as CoreSecurity;
use App\Repository\RewardRepository;
use App\Form\DataTransformer\VistaTimestampToDateTimeTransformer;
/**
* @Route("/users/balance")
* @NelmioSecurity(name="Bearer")
* @SWG\Tag(name="Balance_v1")
*/
class BalanceController extends AbstractFOSRestController
{
/** @var UserBalanceRepository */
protected $userBalanceRepository;
/** @var UserBalanceTransactionRepository */
protected $balanceTransactionRepository;
/** @var ConcessionRepository */
protected $concessionRepository;
/** @var UserHelper */
protected $userHelper;
/** @var MPay24Helper */
protected $MPay24Helper;
/** @var PaymentHelper */
protected $paymentHelper;
/** @var OrderRepositoryInterface */
protected $orderRepository;
/** @var RestrictionsRepository */
protected $restrictionsRepository;
/** @var CinemaRepository */
protected $cinemaRepository;
/** @var RewardRepository */
protected $rewardRepository;
public function __construct(
UserBalanceRepository $userBalanceRepository,
UserBalanceTransactionRepository $balanceTransactionRepository,
ConcessionRepository $concessionRepository,
UserHelper $userHelper,
MPay24Helper $MPay24Helper,
PaymentHelper $paymentHelper,
OrderRepositoryInterface $orderRepository,
RestrictionsRepository $restrictionsRepository,
CinemaRepository $cinemaRepository,
RewardRepository $rewardRepository
) {
$this->userBalanceRepository = $userBalanceRepository;
$this->balanceTransactionRepository = $balanceTransactionRepository;
$this->concessionRepository = $concessionRepository;
$this->userHelper = $userHelper;
$this->MPay24Helper = $MPay24Helper;
$this->paymentHelper = $paymentHelper;
$this->orderRepository = $orderRepository;
$this->restrictionsRepository = $restrictionsRepository;
$this->cinemaRepository = $cinemaRepository;
$this->rewardRepository = $rewardRepository;
}
/**
* @Route("", methods={"GET"})
* @Rest\View()
*
* @SWG\Response(
* response="200",
* description="Success",
* @Model(type=\App\Entity\Local\UserBalance::class))
*
* @param CoreSecurity $security
* @return \App\Entity\Local\UserBalance
*/
public function indexAction(CoreSecurity $security)
{
/** @var LoyaltyMember $securityUser */
$securityUser = $security->getUser();
/** @var LoyaltyMember $user */
$user = $this->userHelper->requestUser($securityUser->getMemberId());
return $this->userBalanceRepository->findByUser($user);
}
/**
* @Route("/transactions", methods={"GET"})
* @Rest\QueryParam(name="to", allowBlank=true)
* @Rest\QueryParam(name="limit", allowBlank=true)
* @Rest\View()
*
* @SWG\Response(
* response="200",
* description="Success",
* @SWG\Schema(type="array", items=@SWG\Items(ref=@Model(type=MemberTransaction::class))))
*
* @param CoreSecurity $security
* @param DateTimeImmutable|null $to
* @param string|null $limit
*
* @return MemberTransaction[]|array|null
* @throws \Throwable
*/
public function transactionsAction(CoreSecurity $security, ?\DateTimeImmutable $to, ?string $limit)
{
/** @var LoyaltyMember $user */
$user = $security->getUser();
$filter = [
'UserSessionId' => $user->getUserSessionId(),
'ReturnMemberTransactionDetails' => true,
];
if ($to == null) {
$to = new \DateTime('now');
}
$to = new \DateTime($to->format('Y-m-d 23:59:59'));
if (empty($limit)) $limit = "1500";
$filter['MaxResults'] = (int) $limit;
$filter['DateFrom'] = sprintf('/Date(%s)/', (new \DateTimeImmutable('-18 month'))->getTimestamp() * 1000);
$filter['DateTo'] = sprintf('/Date(%s)/', $to->getTimestamp() * 1000);
return $this->balanceTransactionRepository->findBy($filter);
}
/**
* @Route("/concessions", methods={"GET"})
* @Rest\View()
*
* @SWG\Response(
* response="200",
* description="Success",
* @SWG\Schema(type="array", items=@SWG\Items(ref=@Model(type=\App\Entity\Vista\ConcessionItem::class))))
*
* @param CoreSecurity $security
* @return \App\Entity\Vista\ConcessionItem[]
*/
public function concessionsAction(CoreSecurity $security)
{
/** @var LoyaltyMember $user */
$user = $this->userHelper->requestUser($security->getUser()->getMemberId());
return $this->concessionRepository->findByUser($user);
}
/**
* @Route("/concessions", methods={"POST"})
* @SWG\Parameter(
* name="concessionItem",
* in="body",
* type="object",
* @SWG\Schema(@SWG\Property(type="string", property="concessionId")))
* @Rest\View()
*
* @SWG\Response(
* response="201",
* description="success",
* @SWG\Schema(@Model(type=PaymentStartResponse::class)))
* @SWG\Response(
* response="400",
* description="Desired value of the card balance is bigger than maximum")
*
* @param CoreSecurity $security
* @param Request $request
* @return PaymentStartResponse
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
* @throws \GuzzleHttp\Exception\GuzzleException
* @throws \Symfony\Component\Serializer\Exception\ExceptionInterface
*/
public function rechargeAction(CoreSecurity $security, Request $request)
{
/**
* @var LoyaltyMember $user
*/
$user = $security->getUser();
$order = (new Order())->setCinemaId(getenv('VISTA_BACKOFFICE_ID'))
->setBookingDate(new \DateTimeImmutable())
;
$cinema = $this->cinemaRepository->find(getenv('VISTA_BACKOFFICE_ID'));
if (null === $cinema) {
throw new \InvalidArgumentException('Invalid VISTA_BACKOFFICE_ID');
}
$order->setCinemaName($cinema->getName());
$this->orderRepository->create($order);
$updatedUser = $this->userHelper->validate($user, $order->getUserSessionId());
$concessionItem = $this->concessionRepository->find($request->get('concessionId'));
$order->setConcessionItem($concessionItem);
if(getenv('CPAY_ADDRESS') || getenv('RAIFFEISEN_ADDRESS') || getenv('KOM_BANK_ADDRESS')) {
$transactionsToCancel = $this->paymentHelper->findCancelList($user->getMemberId());
foreach ($transactionsToCancel as $transaction) {
$orderToCheck = $this->orderRepository->findOneBy(['userSessionId' => $transaction->getUserSessionId()]);
if (null !== $orderToCheck && $this->paymentHelper->canBeCanceled($orderToCheck)) {
$this->orderRepository->cancel($orderToCheck);
}
}
} else { /* mpay24 */
$transactionsToCancel = $this->MPay24Helper->findCancelList($user->getMemberId());
foreach ($transactionsToCancel as $transaction) {
$orderToCheck = $this->orderRepository->findOneBy(['userSessionId' => $transaction->getUserSessionId()]);
if (null !== $orderToCheck && $this->MPay24Helper->canBeCanceled($orderToCheck)) {
$this->orderRepository->cancel($orderToCheck);
}
}
}
$result = $this->userBalanceRepository->startRecharge(
$updatedUser,
$order,
$concessionItem
);
$order->setOrderTotalValueInCents($result->Order->TotalValueCents);
$this->userHelper->validate($user, $order->getUserSessionId());
$restrictions = $this->restrictionsRepository->findOrCreate();
if(getenv('CPAY_ADDRESS')) { /* cPay */
$paymentPageUrl = (getenv('DEV_SIRMA') ? 'http://' . getenv('DEV_SIRMA') : getenv('SCHEME_AND_HTTP_HOST')) .
sprintf("/api/v1/orders/%s/payment/cpay-redirect/%s/%s/%s", $order->getUserSessionId(), $this->paymentHelper->startConcessionPayment($order, $updatedUser, $concessionItem), $order->getOrderTotalValueInCents(), $order->getCinemaId());
} else if(getenv('RAIFFEISEN_ADDRESS')) { /* Raiffeisen */
$paymentPageUrl = (getenv('DEV_SIRMA') ? 'http://' . getenv('DEV_SIRMA') : getenv('SCHEME_AND_HTTP_HOST')) .
sprintf("/api/v1/orders/ord-%s/payment/raiffeisen-redirect/%s/%s/%s", $order->getUserSessionId(), $this->paymentHelper->startConcessionPayment($order, $updatedUser, $concessionItem), $order->getOrderTotalValueInCents(), $order->getCinemaId());
} else if(getenv('KOM_BANK_ADDRESS')) { /* KomBank */
$paymentPageUrl = (getenv('DEV_SIRMA') ? 'http://' . getenv('DEV_SIRMA') : getenv('SCHEME_AND_HTTP_HOST')) .
sprintf("/api/v1/orders/%s/payment/kom-bank-redirect/%s/%s/%s", $order->getUserSessionId(), $this->paymentHelper->startConcessionPayment($order, $updatedUser, $concessionItem), $order->getOrderTotalValueInCents(), $order->getCinemaId());
} else { /* mpay24 */
$paymentPageUrl = $this->MPay24Helper->startConcessionPayment($order, $updatedUser, $concessionItem);
}
$response = (new PaymentStartResponse())
->setPaymentPageUrl($paymentPageUrl)
->setOrderId($order->getUserSessionId())
->setRestrictions($restrictions);
$order->setState(Order::STATE_PAYMENT_STARTED);
$this->orderRepository->save($order);
return $response;
}
}