<?php
declare(strict_types=1);
namespace App\Manager;
use App\Entity\Local\Response\SessionDetails;
use App\Entity\Local\Restrictions;
use App\Entity\Local\UserBalance;
use App\Entity\Vista\LoyaltyMember;
use App\Entity\Vista\Session;
use App\Entity\Vista\SessionTicketType;
use App\Repository\BookingRepository;
use App\Repository\RestrictionsRepository;
use App\Repository\SessionRepositoryInterface;
use App\Repository\TicketRepository;
use App\Repository\Vista\SessionVistaRepository;
use Doctrine\Common\Persistence\ManagerRegistry;
use Doctrine\ORM\EntityManager;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
//use Psr\Log\LoggerInterface;
class SessionDetailsManager
{
/**
* @var EntityManager
*/
private $em;
/** @var RestrictionsRepository */
protected $restrictionsRepository;
/** @var BookingRepository */
protected $bookingRepository;
/** @var SessionRepositoryInterface */
protected $sessionRepository;
/** @var TicketRepository */
protected $ticketRepository;
/** @var SessionVistaRepository */
protected $sessionVistaRepository;
// /** @var LoggerInterface */
// private $logger;
public function __construct(
ManagerRegistry $registry,
SessionRepositoryInterface $sessionRepository,
BookingRepository $bookingRepository,
TicketRepository $ticketRepository,
RestrictionsRepository $restrictionsRepository,
SessionVistaRepository $sessionVistaRepository
// LoggerInterface $logger
) {
$this->sessionRepository = $sessionRepository;
$this->bookingRepository = $bookingRepository;
$this->ticketRepository = $ticketRepository;
$this->restrictionsRepository = $restrictionsRepository;
$this->sessionVistaRepository = $sessionVistaRepository;
// $this->logger = $logger;
$this->em = $registry->getManager();
}
/**
* Calculate restrictions for user sy Session.
*
* @param LoyaltyMember $user
* @param int $cinemaId
* @param \DateTimeInterface $date
* @return Restrictions
* @throws \Throwable
*/
public function calculateRestrictions(LoyaltyMember $user, int $cinemaId, \DateTimeInterface $date)
{
$restrictions = $this->restrictionsRepository->findOrCreate();
$userRestrictions = clone $restrictions;
$bookings = $this->bookingRepository->findAllByUser($user, $cinemaId);
$tickets = $restrictions->getMaxReservedTickets();
$bonusCardTickets = $restrictions->getMaxBonusCardTickets();
foreach ($bookings as $booking) {
if ('0' !== $booking->getCancelledStatus()) {
continue;
}
foreach ($booking->getTickets() as $ticket) {
if ($date->format('Y-m-d') !== $ticket->getSessionDateTime()->format('Y-m-d')) {
continue;
}
if (strpos($ticket->getDescription(), 'CBC') !== false) {
$bonusCardTickets--;
$tickets--;
} else {
if (!$booking->isPaid()) {
$tickets--;
}
}
}
}
$tickets = max($tickets, 0);
$bonusCardTickets = min(max($bonusCardTickets, 0), $tickets);
$userRestrictions
->setMaxBonusCardTickets($bonusCardTickets)
->setMaxReservedBonusTickets($bonusCardTickets)
->setMaxTickets($restrictions->getMaxTickets())
->setMaxReservedTickets($tickets)
->setOriginalRestrictions($restrictions);
return $userRestrictions;
}
/**
* Check if session has child tickets.
*
* @param Session $session
*
* @return bool
*/
protected function hasChildTicketsOld(Session $session): bool
{
$tickets = $this->ticketRepository->findByCinemaIdSessionId($session->getCinemaId(), $session->getSessionId());
/** @var SessionTicketType $ticket */
foreach ($tickets as $ticket) {
if ($ticket->isChildOnlyTicket()) {
return true;
}
}
return false;
}
/**
* Check if session has reduced tickets.
*
* @param Session $session
*
* @return bool
*/
protected function hasReducedTickets(Session $session): bool
{
$tickets = $this->ticketRepository->findByCinemaIdSessionId($session->getCinemaId(), $session->getSessionId());
/** @var SessionTicketType $ticket */
$reducedTicketDesc = '';
switch (getenv('APP_COUNTRY')) {
case 'aut': $reducedTicketDesc = 'Ermäßigt'; break;
case 'rou': $reducedTicketDesc = 'Student'; break;
/*
case 'hrv': $countryName = 'Croatia'; break;
case 'svn': $countryName = 'Slovenia'; break;
case 'srb': $countryName = 'Serbia'; break;
case 'rks': $countryName = 'Kosovo'; break;
case 'alb': $countryName = 'Albania'; break;
case 'grc': $countryName = 'Greece'; break;
case 'mkd': $countryName = 'Macedonia'; break;
case 'bih': $countryName = 'Bosnia'; break;
case 'bil': $countryName = 'BosniaL'; break;
*/
default: return false;
}
foreach ($tickets as $ticket) {
if (stripos($ticket->getDescriptionAlt(), $reducedTicketDesc) !== false)
return true;
}
return false;
}
/**
* Check if session has tickets by type.
*
* @param array $tickets
* @param string $ticketsDesc
* @param string $ticketsNotDesc
* @param string $pckNotDesc
*
* @return bool
*/
protected function hasTicketsByTypeAndNot(array $tickets, string $ticketsDesc, string $ticketsNotDesc, string $pckNotDesc = "PCK"): bool
{
/** @var SessionTicketType $ticket */
foreach ($tickets as $ticket) {
if (
stripos($ticket->getDescriptionAlt(), $ticketsDesc) !== false &&
stripos($ticket->getDescriptionAlt(), $ticketsNotDesc) === false &&
stripos($ticket->getDescriptionAlt(), $pckNotDesc) === false
) {
return true;
}
}
return false;
}
/**
* Check if session has specific tickets.
*
* @param array $tickets
* @param string $ticketTypeDesc
*
* @return bool
*/
protected function hasTicketsByType(array $tickets, string $ticketTypeDesc): bool
{
/** @var SessionTicketType $ticket */
foreach ($tickets as $ticket) {
if (stripos($ticket->getDescriptionAlt(), $ticketTypeDesc) !== false)
return true;
}
return false;
}
/**
* @param string $id
*
* @return Session
*/
public function getById($id): Session
{
$session = $this->sessionRepository->findOneBy(['id' => $id]);
if (null === $session) {
throw new NotFoundHttpException(sprintf('Session with id %s does not exists', $id));
}
return $session;
}
/**
* @param string $cinemaId
* @param int $sessionId
*
* @throws NotFoundHttpException if session not found
* @return Session
*/
public function loadSession(string $cinemaId, int $sessionId): Session
{
$id = sprintf('%s-%s', $cinemaId, $sessionId);
$vistaSession = $this->sessionVistaRepository->find($id);
if (!$vistaSession) {
throw new NotFoundHttpException();
}
$this->em->getConnection()->beginTransaction();
try {
$session = $this->sessionRepository->findForUpdate($id);
if (null === $session) {
$this->em->getConnection()->rollBack();
throw new NotFoundHttpException();
}
$session->setSeatsAvailable($vistaSession->getSeatsAvailable());
if( $session->getSeatsTotal()>0 )
$seatsAvailablePercent = ($session->getSeatsAvailable() / $session->getSeatsTotal()) * 100;
else
$seatsAvailablePercent=100;
if ($seatsAvailablePercent < $session->getCinema()->getYellowSeatsAvailablePercent()) {
$session->setStatus(Session::STATUS_YELLOW);
}
$this->em->flush($session);
$this->em->getConnection()->commit();
return $session;
} catch (\Exception $e) {
$this->em->getConnection()->rollBack();
throw $e;
}
}
/**
* @param string $id
*
* @return SessionDetails
*/
public function getDetails($id)
{
$session = $this->getById($id);
$response = new SessionDetails();
//TAG:LANGUAGE
if( getenv('APP_COUNTRY') == 'aut' ||
getenv('APP_COUNTRY') == 'rou' ){
$response->setHasReducedTickets($this->hasReducedTickets($session));
} else {
$response->setHasReducedTickets(false);
}
// Fetch tickets from session and cinema
$tickets = $this->ticketRepository->findByCinemaIdSessionId($session->getCinemaId(), $session->getSessionId());
if (getenv('APP_COUNTRY') == 'grc') {
$response->setHasChildTickets(false);
} else {
$response->setHasChildTickets($this->hasTicketsByTypeAndNot($tickets, "Child", "Package Child", "PCK"));
}
$response->setHasRegularTickets($this->hasTicketsByTypeAndNot($tickets, "Regular", "Package Regular", "PCK"));
$response->setHasWheelchairTickets($this->hasTicketsByTypeAndNot($tickets, "Wheelchair", "Package Wheelchair", "PCK"));
$response->setHasPackageRegular($this->hasTicketsByType($tickets, "Package Regular"));
$response->setHasPackageClub($this->hasTicketsByType($tickets, "Package Club"));
$response->setHasPackageChild($this->hasTicketsByType($tickets, "Package Child"));
$response->setHasPackageReduced($this->hasTicketsByType($tickets, "Package Reduced"));
$response->setHasCBCTickets($this->hasTicketsByType($tickets, "CBC"));
$restrictions = $this->restrictionsRepository->findOrCreate();
if (
$session->getCinema() &&
$session->getCinema()->getShowPopupOnPurchaseTicketsScreen() &&
$session->getCinema()->getPurchaseTicketsScreenPopupText()
) {
$restrictions->setShowPopupOnPurchaseTicketsScreen($session->getCinema()->getShowPopupOnPurchaseTicketsScreen());
$restrictions->setPurchaseTicketsScreenPopupText($session->getCinema()->getPurchaseTicketsScreenPopupText());
}
$restrictions->setOriginalRestrictions(clone $restrictions);
$response->setRestrictions($restrictions);
$response->setSession($session);
$response->setScheduledFilm($session->getScheduledFilm());
return $response;
}
/**
* @param $id
* @param LoyaltyMember $user
* @param UserBalance $userBalance
*
* @return SessionDetails
* @throws \Throwable
*/
public function getDetailsForUser($id, LoyaltyMember $user, UserBalance $userBalance)
{
$session = $this->getById($id);
$response = new SessionDetails();
$response->setUserBalance($userBalance);
//TAG:LANGUAGE
if( getenv('APP_COUNTRY') == 'aut' ||
getenv('APP_COUNTRY') == 'rou' ){
$response->setHasReducedTickets($this->hasReducedTickets($session));
} else {
$response->setHasReducedTickets(false);
}
// Fetch tickets from session and cinema
$tickets = $this->ticketRepository->findByCinemaIdSessionId($session->getCinemaId(), $session->getSessionId());
$response->setHasRegularTickets($this->hasTicketsByTypeAndNot($tickets, "Regular", "Package Regular", "PCK"));
if (getenv('APP_COUNTRY') == 'grc') {
$response->setHasChildTickets(false);
} else {
$response->setHasChildTickets($this->hasTicketsByTypeAndNot($tickets, "Child", "Package Child", "PCK"));
}
$response->setHasWheelchairTickets($this->hasTicketsByTypeAndNot($tickets, "Wheelchair", "Package Wheelchair", "PCK"));
$response->setHasPackageRegular($this->hasTicketsByType($tickets, "Package Regular"));
$response->setHasPackageClub($this->hasTicketsByType($tickets, "Package Club"));
$response->setHasPackageChild($this->hasTicketsByType($tickets, "Package Child"));
$response->setHasPackageReduced($this->hasTicketsByType($tickets, "Package Reduced"));
$response->setHasCBCTickets($this->hasTicketsByType($tickets, "CBC"));
$restrictions = $this->calculateRestrictions($user, (int) $session->getCinemaId(), $session->getShowtime());
if (
$session->getCinema() &&
$session->getCinema()->getShowPopupOnPurchaseTicketsScreen() &&
$session->getCinema()->getPurchaseTicketsScreenPopupText()
) {
$restrictions->setShowPopupOnPurchaseTicketsScreen($session->getCinema()->getShowPopupOnPurchaseTicketsScreen());
$restrictions->setPurchaseTicketsScreenPopupText($session->getCinema()->getPurchaseTicketsScreenPopupText());
}
$response->setRestrictions($restrictions);
$response->setSession($session);
$response->setScheduledFilm($session->getScheduledFilm());
return $response;
}
}