<?php
declare(strict_types=1);
namespace App\EventSubscriber;
use App\Entity\Vista\LoyaltyMember;
use App\Event\PaymentConcessionEvent;
use App\Event\PaymentTicketEvent;
use App\Event\RefundTicketEvent;
use App\Event\RefundTicketAnonymEvent;
use App\Repository\BookingRepository as BookingHelper;
use App\Helper\UserHelper;
use App\Repository\ConcessionRepository;
use App\Repository\MailingRepositoryInterface as MailingRepository;
use App\Repository\SessionRepositoryInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Yaml\Yaml;
class PaymentEventsSubscriber implements EventSubscriberInterface
{
/** @var MailingRepository */
protected $mailer;
/** @var UserHelper */
protected $userHelper;
/** @var BookingHelper */
protected $bookingHelper;
/** @var SessionRepositoryInterface */
protected $sessionRepository;
/** @var ConcessionRepository */
protected $concessionRepository;
/** @var LoggerInterface */
protected $logger;
/** @var string */
protected $rootDir;
public function __construct(
MailingRepository $mailer,
UserHelper $userHelper,
BookingHelper $bookingHelper,
SessionRepositoryInterface $sessionRepository,
ConcessionRepository $concessionRepository,
LoggerInterface $logger,
string $rootDir
) {
$this->mailer = $mailer;
$this->userHelper = $userHelper;
$this->sessionRepository = $sessionRepository;
$this->bookingHelper = $bookingHelper;
$this->concessionRepository = $concessionRepository;
$this->rootDir = $rootDir;
$this->logger = $logger;
}
/**
* @inheritdoc
*/
public static function getSubscribedEvents()
{
return [
PaymentTicketEvent::class => 'onTicketBought',
PaymentConcessionEvent::class => 'onConcessionBought',
RefundTicketEvent::class => 'onTicketRefund',
RefundTicketAnonymEvent::class => 'onTicketAnonymRefund',
];
}
/**
* @param PaymentConcessionEvent $event
*
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function onConcessionBought(PaymentConcessionEvent $event)
{
$transaction = $event->getTransaction();
$concessionItem = $this->concessionRepository->find($transaction->getConcessionItemId());
$user = $this->userHelper->requestUser($transaction->getMemberId());
$booking = $this->bookingHelper->getById($transaction->getVistaBookingId(), $transaction->getCinemaId());
$locale = null;
if ($headers = $transaction->getHeaders()) {
$locale = $headers['Accept-Language'] ?? null;
}
$this->mailer->sendEmailOnChargeCbc($booking, $concessionItem, $user, null, $locale);
$event->setResult($booking);
}
/**
* @param RefundTicketEvent $event
* @return void
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function onTicketRefund(RefundTicketEvent $event)
{
$this->logger->debug('onTicketRefund Event received');
if ($event->getIsCbcRefund()) {
if ($event->getResult()) {
$this->logger->debug('sending cbc refund success email');
if (!$this->mailer->sendEmailOnCbcRefundSuccess($event->getBooking(), $event->getUser())) {
$this->logger->error('error sending cbc refund success email');
}
} else {
$this->logger->debug('sending cbc refund failed email');
if (getenv('EMAIL_REPORT')) {
if (!$this->mailer->sendEmailOnCbcRefundFailed($event->getBooking(), $event->getUser(), getenv('EMAIL_REPORT'))) {
$this->logger->error('error sending cbc refund failed email');
}
} else {
$this->logger->warning('report email address not set');
}
}
} else {
if ($event->getResult()) {
$this->logger->debug('sending gift card refund success email');
$event->getUser()->setCardNumber($event->getGiftCardNumber());
if (!$this->mailer->sendEmailOnGiftCardRefundSuccess($event->getBooking(), $event->getUser())) {
$this->logger->error('error sending gift card refund success email');
}
} else {
$this->logger->debug('sending gift card refund failed email');
if (getenv('EMAIL_REPORT')) {
if (!$this->mailer->sendEmailOnGiftCardRefundFailed($event->getBooking(), $event->getUser(), getenv('EMAIL_REPORT'))) {
$this->logger->error('error sending gift card refund failed email');
}
} else {
$this->logger->warning('report email address not set');
}
}
}
}
/**
* @param RefundTicketAnonymEvent $event
* @return void
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function onTicketAnonymRefund(RefundTicketAnonymEvent $event)
{
$this->logger->debug('onTicketAnonymRefund Event received');
if ($event->getResult()) {
$this->logger->debug('sending anonym gift card refund success email');
if (!$this->mailer->sendEmailOnGiftCardRefundSuccess($event->getBooking(), null, $event->getEmail(), $event->getGiftCardNumber())) {
$this->logger->error('error sending anonym gift card refund success email');
}
} else {
$this->logger->debug('sending anonym gift card refund failed email');
if (getenv('EMAIL_REPORT')) {
if (!$this->mailer->sendEmailOnGiftCardRefundFailed($event->getBooking(), null, getenv('EMAIL_REPORT'))) {
$this->logger->error('error sending anonym gift card refund failed email');
}
} else {
$this->logger->warning('report anonym email address not set');
}
}
}
/**
* @param PaymentTicketEvent $event
* @return void
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function onTicketBought(PaymentTicketEvent $event)
{
$this->logger->debug('onTicketBought Event received');
$session=null;
$transaction = $event->getTransaction();
$booking = $this->bookingHelper->getById($transaction->getVistaBookingId(), $transaction->getCinemaId());
if (null === $booking) {
return;
}
if( $booking->getTicketsCount()>0){
$session = $this->sessionRepository->findOneBy([
'cinemaId' => $transaction->getCinemaId(),
'sessionId' => $booking->getTickets()[0]->getSessionId()
]);
if (!$session){
// read drive in cinema mapping config
$di_mapping = Yaml::parseFile($this->rootDir.'/config/drive_in_mapping.yml');
// search session with drive-in cinema id if not found with real cinema id
$cinemaId = $transaction->getCinemaId();
foreach ($di_mapping as $map) {
if ($cinemaId === $map['host_cinema_id']) {
$cinemaId = $map['drive_in_cinema_id'];
break;
}
}
$session = $this->sessionRepository->findOneBy([
'sessionId' => $booking->getTickets()[0]->getSessionId(),
'cinemaId' => $cinemaId
]);
}
} else {
$session = $this->sessionRepository->findOneBy([
'cinemaId' => $transaction->getCinemaId()
]);
if (!$session){
// read drive in cinema mapping config
$di_mapping = Yaml::parseFile($this->rootDir.'/config/drive_in_mapping.yml');
// search session with drive-in cinema id if not found with real cinema id
$cinemaId = $transaction->getCinemaId();
foreach ($di_mapping as $map) {
if ($cinemaId === $map['host_cinema_id']) {
$cinemaId = $map['drive_in_cinema_id'];
break;
}
}
$session = $this->sessionRepository->findOneBy([
'cinemaId' => $cinemaId
]);
}
}
$user = null;
if (null !== $transaction->getMemberId() and !empty($transaction->getMemberId())) {
$this->logger->debug('retrieving user');
$user = $this->userHelper->requestUser($transaction->getMemberId());
}
$locale = null;
if ($headers = $transaction->getHeaders()) {
$locale = $headers['Accept-Language'] ?? null;
}
if( $booking->getTicketsCount()>0){
if ($booking->isPaid()) {
$this->logger->debug('sending ticket email');
$this->mailer->sendEmailOnTicket($booking, $session, $user, $transaction->getEmail(), $locale);
} elseif (!$booking->isPaid() && $user instanceof LoyaltyMember) {
$this->logger->debug('sending reservation email');
$this->mailer->sendEmailOnReservation($booking, $session, $user, $transaction->getEmail());
}
} elseif ($booking->getConcessionsCount() > 0) {
if ($booking->isPaid()) {
$this->logger->debug('sending concessions email');
$this->mailer->sendEmailOnTicket($booking, $session, $user, $transaction->getEmail(), $locale);
}
}
$event->setResult($booking);
}
}