<?php
namespace App\Service\TessituraBundle;
use App\Service\TessituraBundle\Item\PackageItemPackage;
use App\Service\TessituraSDK\Entity\Remote\Package;
use App\Service\TessituraSDK\Entity\Remote\PackagePriceType;
use App\Service\TessituraSDK\Entity\Remote\Performance;
use App\Service\TessituraSDK\Entity\Remote\PriceType;
use App\Service\TessituraSDK\Entity\Remote\Zone;
use App\Service\TessituraSDK\Entity\User;
use App\Service\TessituraSDK\Resource\TXN\Packages;
use App\Service\TessituraSDK\Resource\TXN\Performances;
use App\Service\TessituraSDK\Resource\TXN\PriceTypes;
use App\Service\TessituraSDK\TessituraClient;
use Doctrine\ORM\EntityManager;
use Psr\Cache\CacheItemPoolInterface;
use Psr\Log\LoggerInterface;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\Cache\Adapter\TagAwareAdapterInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class PackageService
{
public const CACHE_PACKAGE_TTL = 24 * 60 * 60;
public const CACHE_PACKAGE_KEY = 'package';
/**
* @var LoggerInterface
*/
protected $logger;
/**
* @var TessituraClient
*/
protected $client;
/**
* @var EntityManager
*/
protected $em;
/**
* @var ContainerInterface
*/
protected $container;
/**
* @var TranslatorInterface
*/
protected $translator;
/**
* @var UrlGeneratorInterface
*/
protected $router;
/**
* @var Serializer
*/
protected $serializer;
/**
* @var \Symfony\Component\HttpFoundation\Request
*/
protected $request;
/**
* @var AccountService
*/
protected $account;
/**
* @var CacheItemPoolInterface|TagAwareAdapterInterface
*/
protected $cache;
/**
* @var ConstituentService
*/
protected $constituent;
private $webContentsCache = [];
/**
* CartService constructor.
*
* @param TessituraClient $client
* @param ContainerInterface $container
* @param ManagerRegistry $doctrine
* @param TranslatorInterface $translator
* @param UrlGeneratorInterface $router
* @param SerializerInterface $serializer
* @param LoggerInterface $logger
* @param RequestStack $requestStack
* @param AccountService $account
* @param ConstituentService $constituent
*/
public function __construct(
TessituraClient $client,
ContainerInterface $container,
ManagerRegistry $doctrine,
TranslatorInterface $translator,
UrlGeneratorInterface $router,
SerializerInterface $serializer,
LoggerInterface $logger,
RequestStack $requestStack,
ConstituentService $constituent
) {
$this->client = $client;
$this->container = $container;
$this->translator = $translator;
$this->router = $router;
$this->serializer = $serializer;
$this->logger = $logger;
$this->em = $doctrine->getManager();
$this->request = $requestStack->getCurrentRequest();
$this->cache = $container->get('cache.app');
$this->constituent = $constituent;
}
/**
* @param int $seasonId
*
* @return PackageItemPackage[]
*/
public function getAll($seasonIds)
{
/** @var Item\PackageItemPackage[] $items */
$items = [];
$startDate = new \DateTime('now');
$startDate->setTime(0, 0, 0);
if (is_array($seasonIds)) {
$seasonIds = implode(',', $seasonIds);
}
/** @var Package[] $packages */
$packages = $this->client->request(Packages::getAll([
'seasonIds' => $seasonIds,
]))->denormalize(Package::class . '[]');
if (!count($packages)) {
return $items;
}
$pricesRequests = [];
foreach ($packages as $package) {
$pricesRequests['price-' . $package->getId()] = Packages::getPrices($package->getId(), [
'asOfDateTime' => $startDate
->format('Y-m-d\TH:i:s\Z'),
'modeOfSaleId' => $this->getUser()->getModeOfSaleId()
]);
$pricesRequests['type-' . $package->getId()] = PriceTypes::getValidPriceTypes([
'packageId' => $package->getId(),
'modeOfSaleId' => $this->getUser()->getModeOfSaleId()
]);
}
$pricesResponses = $this->client->requestAsync($pricesRequests);
$packagePerformances = [];
$packageZones = [];
$packagePrices = [];
$perfomanceIds = [];
foreach ($pricesResponses as $key => $response) {
list($type, $packageId) = explode('-', $key);
/** @var PackagePriceType[] $priceType */
/** @var Zone[] $zones */
if ($type === 'type') {
$priceTypes = $response->denormalize(PriceType::class . '[]');
/** @var PriceType $priceType */
foreach ($priceTypes as $priceType) {
$packageZones[$packageId] = $priceType->getZones();
}
} elseif ($type === 'price') {
$priceTypes = $response->denormalize(PackagePriceType::class . '[]');
/** @var PackagePriceType $priceType */
foreach ($priceTypes as $priceType) {
$packagePerformances[$packageId][$priceType->getPerformanceId()] = true;
$packagePrices[$packageId][] = $priceType;
$perfomanceIds[$priceType->getPerformanceId()] = true;
}
}
}
$perfomanceIds = array_keys($perfomanceIds);
if (empty($perfomanceIds)) {
return $items;
}
/** @var Performance[] $performances */
$performances = $this->client->request(Performances::getAll([
'performanceIds' => implode(',', $perfomanceIds)
]))->denormalize(Performance::class . '[]');
$requests = [];
foreach ($packages as $package) {
/** @var Package $package */
if (!$package->getFixedSeatIndicator()) {
continue;
}
if (empty($packagePerformances[$package->getId()])) {
continue;
}
if (empty($packageZones[$package->getId()])) {
continue;
}
if (empty($packagePrices[$package->getId()])) {
continue;
}
$performanceItems = [];
foreach ($packagePerformances[$package->getId()] as $performanceId => $exists) {
/** @var Performance $foundPerformance */
$foundPerformance = array_reduce(
$performances,
function ($carry, $performance) use ($performanceId) {
/** @var Performance $performance */
if ($performance->getId() === $performanceId) {
$carry = $performance;
}
return $carry;
},
null
);
if ($foundPerformance->getProductionSeason()->getId() === 0) {
continue;
}
$performance = new Item\CartItemPerformance($this->container, $this->em);
$performance->setCartPerformance($foundPerformance->asCartPerformance());
$performanceItems[] = $performance;
}
usort($performanceItems, function ($a, $b) {
/** @var Item\CartItemPerformance $a */
/** @var Item\CartItemPerformance $b */
return $a->getCartPerformance()->getPerformanceDateTime() <=> $b->getCartPerformance()->getPerformanceDateTime();
});
$item = new PackageItemPackage($this->container, $this->em);
$item->setCartPackage($package->asCartPackage());
$item->setZones($packageZones[$package->getId()]);
$item->setPackagePriceTypes($packagePrices[$package->getId()]);
$item->setPerformances($performanceItems);
$items[] = $item;
}
return $items;
}
/**
* @return User
*/
public function getUser()
{
/** @var User $user */
$user = $this->container->get('security.token_storage')->getToken()->getUser();
return $user;
}
}