<?php
namespace App\BookingProcess\ProcessEventSubscriber;
use App\BookingProcess\ProcessCruiseDataAdapter\CostaCruiseDataToQuoteAdapter;
use App\BookingProcess\ProcessEvent\BookingProcessEvents;
use App\BookingProcess\ProcessEvent\QuoteToBookingPostProcessEvent;
use App\BookingProcess\ProcessEvent\QuoteToBookingPreProcessEvent;
use App\BookingProcess\ProcessHelper\Company\Option\OptionHelperProvider;
use App\BookingProcess\ProcessQuoteToBooking\ReminderFactory;
use App\Entity\Booking\Booking;
use App\Entity\Booking\Quote;
use App\Entity\EventCodes;
use App\Helper\__Quote\QuoteEventHelper;
use App\Manager\Company\Costa\CostaBookingManager;
use App\Manager\CruiseData\Costa\CostaCruiseData;
use App\Repository\Booking\QuoteRepository;
use App\Repository\Cruise\Company\CompanyRepository;
use Crea\ToolsBundle\Manager\Level_0\ManagerTools\ManagerProviderInterface;
use Exception;
use Psr\Cache\InvalidArgumentException;
use stdClass;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class BookingProcessEventSubscriber implements EventSubscriberInterface
{
protected ManagerProviderInterface $managerProvider;
protected QuoteEventHelper $quoteEventHelper;
protected CostaCruiseDataToQuoteAdapter $costaCruiseDataToQuoteAdapter;
protected ReminderFactory $reminderFactory;
protected OptionHelperProvider $optionHelperProvider;
protected CostaBookingManager $costaBookingManager;
public function __construct(ManagerProviderInterface $managerProvider,
QuoteEventHelper $quoteEventHelper,
CostaCruiseDataToQuoteAdapter $costaCruiseDataToQuoteAdapter,
ReminderFactory $reminderFactory,
OptionHelperProvider $optionHelperProvider,
CostaBookingManager $costaBookingManager)
{
$this->managerProvider = $managerProvider;
$this->quoteEventHelper = $quoteEventHelper;
$this->costaCruiseDataToQuoteAdapter = $costaCruiseDataToQuoteAdapter;
$this->reminderFactory = $reminderFactory;
$this->optionHelperProvider = $optionHelperProvider;
$this->costaBookingManager = $costaBookingManager;
}
public static function getSubscribedEvents(): array
{
return [
BookingProcessEvents::QUOTE_TO_BOOKING_PRE_PROCESS => 'preProcess',
BookingProcessEvents::QUOTE_TO_BOOKING_POST_PROCESS => 'postProcess',
];
}
/**
* @throws Exception|InvalidArgumentException
*/
public function preProcess(QuoteToBookingPreProcessEvent $event): void
{
//init quote error field
$this->managerProvider->getManager(Quote::class)->update($event->getQuote(), [
'toBookingOnError' => false,
'toBookingExceptionEvents' => [],
], true);
//confirm option
switch ($event->getQuote()->getConverter()) {
case QuoteRepository::QUOTE_CONVERTER_FULLWEB:
case QuoteRepository::QUOTE_CONVERTER_B2B:
try {
if (null !== $optionHelper = $this->optionHelperProvider->getOptionHelper($event->getQuote())) {
$httpResult = $optionHelper->confirmOption($event->getQuote());
if (!$httpResult->isValid()) {
throw new Exception($httpResult->getData()["error"]);
}
else {
$this->quoteEventHelper->setQuoteProcessTransformationEvent($event->getQuote(), EventCodes::PROCESS_QUOTE_TRANSFORMATION_STEP_CONFIRM_OPTION_SUCCESS);
}
}
}
catch (\Throwable $e) {
$this->quoteEventHelper->setQuoteProcessTransformationEvent($event->getQuote(), EventCodes::PROCESS_QUOTE_TRANSFORMATION_STEP_CONFIRM_OPTION_ERROR, [], null, null, $e);
}
break;
}
//add included services in quote (Fullweb)
//after option confirmation because immediate confirm cruise (no booking number in this case because we have not set option)
if ($event->getQuote()->getConverter() === QuoteRepository::QUOTE_CONVERTER_FULLWEB) {
try {
switch ($event->getQuote()->getCruiseHistory()->getShip()->getCompany()->getCode()) {
case CompanyRepository::COMPANY_COSTA_CODE:
//booking number from fullweb cruise data
$fullwebCostaCruiseData = $this->costaCruiseDataToQuoteAdapter->getCostaCruiseData($event->getQuote());
$bookingNumber = $fullwebCostaCruiseData->getBookingNumber();
//get B2B cruise data from company COSTA
$response = $this->costaBookingManager->displayBooking($bookingNumber);
if (isset($response->error)) {
throw new Exception('Le numéro de réservation '.$bookingNumber.' n\'a pas été trouvé');
}
$B2BCostaCruiseData = new StdClass();
$B2BCostaCruiseData->data = $response->DisplayBookingResult;
//get included services
$this->costaCruiseDataToQuoteAdapter->setServices(
$event->getQuote(),
new CostaCruiseData(json_encode($B2BCostaCruiseData))
);
break;
}
$this->quoteEventHelper->setQuoteProcessTransformationEvent($event->getQuote(), EventCodes::PROCESS_QUOTE_TRANSFORMATION_STEP_FULLWEB_INCLUDED_SERVICES_SUCCESS);
}
catch (\Throwable $e) {
$this->quoteEventHelper->setQuoteProcessTransformationEvent($event->getQuote(), EventCodes::PROCESS_QUOTE_TRANSFORMATION_STEP_FULLWEB_INCLUDED_SERVICES_ERROR, [], null, null, $e);
}
}
}
/**
* @throws Exception
*/
public function postProcess(QuoteToBookingPostProcessEvent $event): void
{
//transfer errors from quote to booking
$this->managerProvider->getManager(Booking::class)->update(
$event->getBooking(),
['toBookingExceptionEvents' => $event->getBooking()->getQuote()->getToBookingExceptionEvents()],
true
);
//reminder new booking
switch($event->getBooking()->getQuote()->getConverter()){
case QuoteRepository::QUOTE_CONVERTER_MANUAL:
$this->reminderFactory->build($event->getBooking());
break;
}
}
}