feat: integrate with new bpn-connect api for ical feeds
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace EP\EpProducts\Service;
|
||||
|
||||
/***************************************************************
|
||||
@@ -26,20 +27,20 @@ namespace EP\EpProducts\Service;
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use EP\EpProducts\Domain\Model\Contingent;
|
||||
use EP\EpProducts\BpnConnect\ApiClient;
|
||||
use EP\EpProducts\Domain\Model\Hotel;
|
||||
use EP\EpProducts\Domain\Repository\ContingentRepository;
|
||||
use Kigkonsult\Icalcreator\Vcalendar;
|
||||
use League\Period\Period;
|
||||
use TYPO3\CMS\Core\SingletonInterface;
|
||||
|
||||
class IcalService implements SingletonInterface
|
||||
{
|
||||
private const FEED_HORIZON = 'P1Y';
|
||||
private const SUMMARY_UNAVAILABLE = 'Unavailable';
|
||||
|
||||
/**
|
||||
* @var ContingentRepository
|
||||
* @var ApiClient
|
||||
*/
|
||||
protected $contingentRepository;
|
||||
protected $apiClient;
|
||||
|
||||
/**
|
||||
* @var Vcalendar
|
||||
@@ -47,11 +48,11 @@ class IcalService implements SingletonInterface
|
||||
protected $vcalendar;
|
||||
|
||||
/**
|
||||
* @param ContingentRepository $contingentRepository
|
||||
* @param ApiClient $apiClient
|
||||
*/
|
||||
public function __construct(ContingentRepository $contingentRepository)
|
||||
public function __construct(ApiClient $apiClient)
|
||||
{
|
||||
$this->contingentRepository = $contingentRepository;
|
||||
$this->apiClient = $apiClient;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,90 +61,73 @@ class IcalService implements SingletonInterface
|
||||
*/
|
||||
public function createContingentsFeed(Hotel $hotel): string
|
||||
{
|
||||
$now = new \DateTime('now');
|
||||
try {
|
||||
$events = $this->contingentRepository->getEvents(
|
||||
$now,
|
||||
null,
|
||||
['hotel' => $hotel]
|
||||
);
|
||||
}
|
||||
catch (DBALException $e) {
|
||||
$events = [];
|
||||
$calendarRows = [];
|
||||
$hotelCode = trim((string) $hotel->getCode());
|
||||
|
||||
if ($hotelCode !== '') {
|
||||
$dateFrom = new \DateTimeImmutable('today');
|
||||
$dateTo = $dateFrom->add(new \DateInterval(self::FEED_HORIZON))->sub(new \DateInterval('P1D'));
|
||||
|
||||
try {
|
||||
$calendar = $this->apiClient->getCalendar($hotelCode, $dateFrom, $dateTo);
|
||||
$calendarRows = isset($calendar['data']) && is_array($calendar['data']) ? $calendar['data'] : [];
|
||||
} catch (\Throwable $e) {
|
||||
$calendarRows = [];
|
||||
}
|
||||
}
|
||||
|
||||
$this->createCalendarInstance();
|
||||
|
||||
$this->generateOccupancyItems($events);
|
||||
$this->generateBlockedItems($events);
|
||||
$this->generateUnavailableItems($calendarRows);
|
||||
|
||||
try {
|
||||
$feed = $this->vcalendar->vtimezonePopulate()->createCalendar();
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
$feed = '';
|
||||
}
|
||||
|
||||
return $feed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $events
|
||||
*/
|
||||
protected function generateOccupancyItems(array $events): void
|
||||
{
|
||||
$occupancy = null;
|
||||
|
||||
foreach ($events as $event) {
|
||||
/** @var Contingent $event */
|
||||
if (null === $occupancy) {
|
||||
$item = [
|
||||
'from' => $event->getBegin(),
|
||||
'occupancy' => $event->getOccupancy(),
|
||||
];
|
||||
} elseif ($occupancy !== $event->getOccupancy()) {
|
||||
$item['to'] = $event->getEnd();
|
||||
$this->addOccupancyItem($item);
|
||||
$item = [
|
||||
'from' => $event->getBegin(),
|
||||
'occupancy' => $event->getOccupancy(),
|
||||
];
|
||||
}
|
||||
|
||||
$occupancy = $event->getOccupancy();
|
||||
}
|
||||
|
||||
if (isset($event) && !isset($item['to'])) {
|
||||
$item['to'] = $event->getEnd();
|
||||
$this->addOccupancyItem($item);
|
||||
return $this->vcalendar->vtimezonePopulate()->createCalendar();
|
||||
} catch (\Exception $e) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $events
|
||||
* @param array $calendarRows
|
||||
*/
|
||||
protected function generateBlockedItems(array $events): void
|
||||
protected function generateUnavailableItems(array $calendarRows): void
|
||||
{
|
||||
$item = null;
|
||||
usort($calendarRows, function (array $left, array $right): int {
|
||||
return strcmp((string) ($left['date'] ?? ''), (string) ($right['date'] ?? ''));
|
||||
});
|
||||
|
||||
foreach ($events as $event) {
|
||||
/** @var Contingent $event */
|
||||
$isBlocked = Contingent::STATUS_BLOCKED === $event->getStatus() || Contingent::STATUS_ONREQUEST === $event->getStatus();
|
||||
$isUnavailable = 0 === $event->getAvailable();
|
||||
if (null === $item && ($isBlocked || $isUnavailable)) {
|
||||
$item = [
|
||||
'from' => $event->getBegin(),
|
||||
];
|
||||
} elseif (true === is_array($item) && Contingent::STATUS_OK === $event->getStatus()) {
|
||||
$item['to'] = $event->getEnd();
|
||||
$this->addBlockedItem($item);
|
||||
$item = null;
|
||||
$blockStart = null;
|
||||
$lastDate = null;
|
||||
|
||||
foreach ($calendarRows as $row) {
|
||||
if (!isset($row['date'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$date = new \DateTimeImmutable($row['date']);
|
||||
$lastDate = $date;
|
||||
|
||||
if ($this->isUnavailableStatus($row['status'] ?? 'OK')) {
|
||||
if (null === $blockStart) {
|
||||
$blockStart = $date;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (null !== $blockStart) {
|
||||
$this->addBlockedItem([
|
||||
'from' => $blockStart,
|
||||
'to' => $date,
|
||||
]);
|
||||
$blockStart = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($event) && null !== $item && !isset($item['to'])) {
|
||||
$item['to'] = $event->getEnd();
|
||||
$this->addBlockedItem($item);
|
||||
if (null !== $blockStart && null !== $lastDate) {
|
||||
$this->addBlockedItem([
|
||||
'from' => $blockStart,
|
||||
'to' => $lastDate->add(new \DateInterval('P1D')),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,34 +141,21 @@ class IcalService implements SingletonInterface
|
||||
->newVevent()
|
||||
->setDtstart($item['from'])
|
||||
->setDtend($item['to'])
|
||||
->setSummary('Unavailable')
|
||||
->setSummary(self::SUMMARY_UNAVAILABLE)
|
||||
;
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $item
|
||||
* @param mixed $status
|
||||
* @return bool
|
||||
*/
|
||||
protected function addOccupancyItem(array $item): void
|
||||
protected function isUnavailableStatus($status): bool
|
||||
{
|
||||
if (0 === $item['occupancy']) {
|
||||
return;
|
||||
}
|
||||
$status = strtoupper(trim((string) $status));
|
||||
|
||||
$summary = sprintf('Part-occupied:%d', $item['occupancy']);
|
||||
|
||||
try {
|
||||
$this->vcalendar
|
||||
->newVevent()
|
||||
->setDtstart($item['from'])
|
||||
->setDtend($item['to'])
|
||||
->setSummary($summary)
|
||||
;
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
}
|
||||
return in_array($status, [ 'BLOCKED', 'ON_REQUEST', 'ONREQUEST' ], true);
|
||||
}
|
||||
|
||||
protected function createCalendarInstance(): void
|
||||
|
||||
Reference in New Issue
Block a user