<?php
namespace App\EventListener;
use App\Entity\Customer\Customer;
use App\Entity\Vignette\Availability;
use App\Entity\Vignette\Vignette;
use App\Manager\Cart\CartManager;
use App\Model\VignetteAvailabilityModel;
use App\Service\Customer\VehicleService;
use App\Service\CustomerService;
use App\Service\ShoppingCartService;
use App\Service\SystemService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use App\Entity\Vignette\VignetteApi;
use App\Events\Cart\CartEvent;
use App\Manager\Vignette\VignetteApiManager;
use App\Service\VignetteOrderService;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Messenger\TraceableMessageBus;
use Symfony\Component\Translation\IdentityTranslator;
class CartListener
{
/** @var \Doctrine\ORM\EntityManager|object|null */
private $entityManager;
/** @var Request|null */
private $request;
/** @var object|IdentityTranslator|null */
private $translator;
/** @var object|TraceableMessageBus|null */
private $traceableMessageBus;
/** @var ContainerInterface */
private $container;
public function __construct(RequestStack $requestStack, ContainerInterface $container)
{
$this->request = $requestStack->getCurrentRequest();
$this->entityManager = $container->get('doctrine.orm.default_entity_manager');
$this->translator = $container->get('translator');
$this->traceableMessageBus = $container->get('messenger.default_bus');
$this->container = $container;
}
public function onKernelRequest(GetResponseEvent $event)
{
ShoppingCartService::checkShoppingCart($event->getRequest()->getSession(), $this->entityManager, $this->traceableMessageBus);
}
/**
* @param CartEvent $cartEvent
* @throws \Exception
*/
public function beforeCartSubmitInitRoVignettesToWs(CartEvent $cartEvent)
{
if ($roVignettes = $cartEvent->getRoVignettes()) {
$isCreditCard = $cartEvent->isPaymentMethodCreditCard();
foreach ($roVignettes as $roVignette) {
$roVignette = json_decode(json_encode($roVignette));
$availabilityWsId = VignetteAvailabilityModel::getAvailabilityWsIdByUrl($roVignette->availability);
$availability = $this->entityManager->getRepository(Availability::class)->findAvailabilityByWsId($availabilityWsId);
if (VignetteAvailabilityModel::isAvailabilityEligibleForCnairAlert($availability) && $roVignette->email_allowed == 1) {
$roVignette->email = $cartEvent->getCustomerEmail();
}
if (!isset($roVignette->isInitialized) || !$roVignette->isInitialized) {
$this->initRoVignette($roVignette, $isCreditCard, $cartEvent->getPartnerVignetteAPIKey());
}
}
$session = $this->request->getSession();
if (!$session->getFlashBag()->has('vignette-init-error')) {
VignetteOrderService::checkIfVignetteGlobalOrderIsValidForProcessingOrder($session, $this->translator);
}
}
}
/**
* @param $roVignette
* @param $isCreditCard
* @throws \Exception
*/
private function initRoVignette($roVignette, $isCreditCard, $partnerVignetteAPIKey)
{
$apiServiceRepository = $this->entityManager->getRepository(VignetteApi::class);
if ($apiServiceRepository->verifyVignette($roVignette, $isCreditCard, $partnerVignetteAPIKey)) {
$apiServiceResponse = json_decode($apiServiceRepository->getLastResponse());
if (isset($roVignette->vignette_alert) && $roVignette->vignette_alert == 1 ) {
$apiServiceResponse->vignette_alert = 1;
} else {
$apiServiceResponse->vignette_alert = 0;
}
if (isset($roVignette->email_allowed) && $roVignette->email_allowed == 1 ) {
$apiServiceResponse->email_allowed = 1;
} else {
$apiServiceResponse->email_allowed = 0;
}
$vignetteOrderService = new VignetteOrderService();
if (isset($roVignette->chassis_number) && $roVignette->chassis_number) {
if (self::verifyIfVinHasChanged($roVignette->chassis_number, $apiServiceResponse)) {
$message = SystemService::retrieveMessage('vin_changed', $this->translator);
$message = str_replace('%RegistrationPlate%', $roVignette->registration_number, $message);
$message = str_replace('%InitialVIN%', $roVignette->chassis_number, $message);
$message = str_replace('%NewVIN%', $apiServiceResponse->chassis_number, $message);
$this->request->getSession()->getFlashBag()->set('vignette-vin-changed', $message);
$this->updateRoadAssistanceVinForRegistrationPlateIfAvailable($roVignette->registration_number, $apiServiceResponse->chassis_number);
}
}
$vignetteOrderService->storeVignetteInFinalGlobalOrderSession($this->request, $apiServiceResponse);
} else {
$vignetteApiError = VignetteApiManager::retrieveApiErrorResponse($roVignette, $this->entityManager, $this->translator);
$this->manageSpecialErrorUpdates($roVignette);
$this->request->getSession()->getFlashBag()->set('vignette-init-error', implode(',', $vignetteApiError));
}
}
/**
* @param $registrationPlate
* @param $newVin
* @return void
*/
public function updateRoadAssistanceVinForRegistrationPlateIfAvailable($registrationPlate, $newVin)
{
$session = $this->request->getSession();
if ($allRoadAssistance = CartManager::getCartData($session, 'allRoadAssistance')) {
foreach ($allRoadAssistance as &$roadAssistance) {
if ($registrationPlate == $roadAssistance['registrationPlate']
&& $roadAssistance['vin'] != $newVin) {
$roadAssistance['vin'] = $newVin;
break;
}
}
CartManager::setToCart($session, 'allRoadAssistance', $allRoadAssistance);
}
}
/**
* @param $initialVin
* @param $apiServiceResponse
* @return bool
*/
private static function verifyIfVinHasChanged($initialVin, $apiServiceResponse): bool
{
$hasChanged = false;
if ($apiServiceResponse && isset($apiServiceResponse->chassis_number)
&& $apiServiceResponse->chassis_number) {
if ($initialVin != $apiServiceResponse->chassis_number) {
$hasChanged = true;
}
}
return $hasChanged;
}
/**
* @param $roVignette
* @throws \Exception
*/
private function manageSpecialErrorUpdates($roVignette)
{
$apiServiceRepository = $this->entityManager->getRepository(VignetteApi::class);
$apiStatusCode = $apiServiceRepository->getLastResponseCode();
$specialErrors = json_decode($apiServiceRepository->getLastResponse());
if ($apiStatusCode && $apiStatusCode == Response::HTTP_CONFLICT) {
if ($this->container->has('security.token_storage')) {
$customer = CustomerService::retrieveCustomerBySecurityToken($this->container->get('security.token_storage'));
if ($customer && $customer instanceof Customer) {
$params = array();
$params['registrationPlate'] = $roVignette->registration_number;
if (isset($roVignette->chassis_number) && $roVignette->chassis_number) {
$params['vin'] = $roVignette->chassis_number;
}
$params['validUntil'] = isset($specialErrors->valid_until) ? new \DateTime($specialErrors->valid_until) : null;
VehicleService::updateVehicleRoVignetteExpiresAtIfAvailable($params, $customer, $this->entityManager);
}
}
}
}
}