<?php
namespace App\EventSubscriber;
use App\App;
use App\Controller\AdminFDPGammaController;
use App\Entity\CO2Criteria;
use App\Entity\FDPGamma;
use App\Entity\OTCData;
use App\Entity\Vehicle;
use App\Entity\Worklog;
use App\Event\IssueEvent;
use App\Event\OTCEvent;
use App\Event\WorklogEvent;
use App\Repository\CO2CriteriaRepository;
use App\Repository\FDPGammaRepository;
use App\Repository\OTCDataRepository;
use App\Repository\VehicleRepository;
use App\Services\CerfaService;
use App\Services\EmailService;
use DateTime;
use Doctrine\Bundle\DoctrineBundle\Registry;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\OptimisticLockException;
use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use App\Event\VehicleEvent;
use App\Event\COCEvent;
use App\Event\SAPEvent;
use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator;
use Symfony\Component\Routing\Router;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Validator\Constraints\Date;
class VehicleEventSubscriber implements EventSubscriberInterface
{
/** @var EntityManager $doctrine */
protected $em;
/** @var TraceableEventDispatcher $dispatcher */
private $dispatcher;
/** @var CerfaService $cerfaService */
private $cerfaService;
/** @var VehicleRepository $vehicleRepository */
private $vehicleRepository;
/** @var OTCDataRepository $otcDataRepository */
private $otcDataRepository;
/** @var CO2CriteriaRepository $co2CriteriaRepository */
private $co2CriteriaRepository;
/**
* @var AdminUrlGenerator $router
*/
private $router;
/**
* @var FDPGammaRepository
*/
private $FDPGammaRepository;
private $baseUrl = 'http://localhost';
public function __construct(
EventDispatcherInterface $dispatcher,
EntityManagerInterface $em,
AdminUrlGenerator $router,
CerfaService $cerfaService
) {
$this->dispatcher = $dispatcher;
$this->em = $em;
$this->router = $router;
$this->cerfaService = $cerfaService;
$this->vehicleRepository = $em->getRepository(Vehicle::class);
$this->otcDataRepository = $em->getRepository(OTCData::class);
$this->co2CriteriaRepository = $em->getRepository(CO2Criteria::class);
$this->FDPGammaRepository = $em->getRepository(FDPGamma::class);
}
public static function getSubscribedEvents()
{
return [
'iris.vehicle.sap' => [['handleSap'], ['handleStatus'], ['handleCerfaData']],
'iris.vehicle.cdfs' => [['handleCdfs'], ['handleStatus'], ['handleCerfaData']],
'iris.vehicle.coc' => [['handleCocFluxForOtc'], ['handleCO2Eligibility'], ['handleStatus'], ['handleCerfaData']],
//region
// 'iris.vehicle.ecoc' => [],
//endregion
'iris.vehicle.otc' => [['handleOtc']],
'iris.vehicle.force' => [['handleStatus']],
'iris.vehicle.cerfa' => [['handleCerfaData']],
];
}
public static function checkVehicleAAASend(Vehicle $vehicle)
{
if ($vehicle->getAAAStatus() != null && $vehicle->getRegisterStatus() == Vehicle::REGISTRABLE) {
if ($vehicle->getCerfaData() != null && $vehicle->getCerfaData()->getBlockUpdate() === true) {
return false;
}
$vehicle->setAAAStatus(Vehicle::AAA_READY);
return true;
}
return false;
}
/**
* @param SAPEvent $event
*/
public function handleSap(SAPEvent $event)
{
/** @var Vehicle $vehicle */
$vehicle = $event->getVehicle();
$isNewVehicle = $event->getIsNewVehicle();
$oldClient = $event->getOldClient();
if (!$isNewVehicle && $oldClient != null && $vehicle->getPositionRunNumber() == null) { // Se era un veicolo già presente e aveva già un clientInvoice e non aveva un positionRunNumber
if ($oldClient->getId() != $vehicle->getClientInvoice()->getId()) { // Se è cambiato il clientInvoice
if (
$vehicle->getClientInvoice()->getIsGrandCompte() || (
// DOP
$vehicle->getTechnicalData()->getAdministrativeSalesChannel() == 'Own Dealers'
&& $vehicle->getTechnicalData()->getAccountingDocumentType() == 'TZ'
&& $vehicle->getTechnicalData()->getAccountingDocumentDate() >= new DateTime('2018-07-01')
)
) {
$vehicle->setPositioned(true);
$vehicle->setClientPosition($vehicle->getClientInvoice());
if ($vehicle->getRegisterStatus() != Vehicle::NON_REGISTRABLE) {
if ($vehicle->getClientPosition()->getSivPartner()) {
$vehicle->setClientRegistration($vehicle->getClientPosition()->getSivPartner());
} else {
$vehicle->setClientRegistration($vehicle->getClientPosition());
}
}
} else {
$vehicle->setPositioned(false);
$vehicle->setClientPosition(null);
if ($vehicle->getRegisterStatus() != Vehicle::NON_REGISTRABLE) {
$vehicle->setClientRegistration(null);
self::checkVehicleAAASend($vehicle);
$vehicle->setRegisterStatus(Vehicle::NON_REGISTRABLE);
}
}
// Force recalculation of 3en1
if ($vehicle->getPrintableStatus() == Vehicle::PRINTED) {
$vehicle->setPrintableStatus(Vehicle::PRINTABLE);
}
self::checkVehicleAAASend($vehicle);
}
} elseif ($isNewVehicle && $vehicle->getClientInvoice()->getIsGrandCompte()) { // Se il veicolo è nuovo e il clientInvoice è un grandCompte (il veicolo ha sempre un clientInvoice)
$vehicle->setPositioned(true);
$vehicle->setClientPosition($vehicle->getClientInvoice());
}
/** @var FDPGamma $FDPGamma */
$FDPGamma = $this->FDPGammaRepository->findByVehicle($vehicle);
if (!$FDPGamma) {
$newFDPGamma = new FDPGamma();
$newFDPGamma->setFdp($vehicle->getTechnicalData()->getFDP());
$newFDPGamma->setGamma($vehicle->getTechnicalData()->getCGM());
$this->em->persist($newFDPGamma);
} else {
$vehicle->setInternalGamma($FDPGamma->getInternalGamma());
}
$this->em->flush();
$this->em->detach(isset($newFDPGamma) ? $newFDPGamma : $FDPGamma);
if (isset($newFDPGamma)) {
$url = $this->router->setController(AdminFDPGammaController::class)
->setAction('edit')
->setEntityId($newFDPGamma->getId())
->generateUrl();
if (strpos($url, $this->baseUrl) === 0) {
$relativeUrl = substr($url, strlen($this->baseUrl));
}
$event = new IssueEvent('Creating new FDP Gamma, please add manually the Internal Gamma', IssueEvent::SAP, $relativeUrl);
$this->dispatcher->dispatch($event, 'iris.issue');
}
}
public function handleStatus(VehicleEvent $event, $preventFlush = false)
{
$vehicle = $event->getVehicle();
// Regression on workflow
if (
$vehicle->getRegisterStatus() != Vehicle::REGISTERED &&
($vehicle->getPrintableStatus() == Vehicle::PRINTABLE || $vehicle->getPrintableStatus() == Vehicle::PRINTED) &&
(!$vehicle->getDateCOC() || !$vehicle->getDateOTC() || !$vehicle->getDateTechData())
) {
$vehicle->setPrintableStatus(Vehicle::INCOMPLETE);
$vehicle->setDatePrint3en1(null);
if ($vehicle->getRegisterStatus() == Vehicle::REGISTRABLE) {
$vehicle->setRegisterStatus(Vehicle::NON_REGISTRABLE);
$vehicle->setAAAStatus(Vehicle::AAA_READY);
}
}
if ((!$vehicle->getPrintableStatus() || $vehicle->getPrintableStatus() == Vehicle::INCOMPLETE) &&
($vehicle->getDateCOC() && $vehicle->getDateOTC() && $vehicle->getDateTechData())
) {
$vehicle->setPrintableStatus(Vehicle::PRINTABLE);
}
if (!$vehicle->getRegisterStatus() || $vehicle->getRegisterStatus() == Vehicle::NON_REGISTRABLE) {
if (($vehicle->getPrintableStatus() == Vehicle::PRINTABLE || $vehicle->getPrintableStatus() == Vehicle::PRINTED) && $vehicle->getPositioned()) {
$vehicle->setRegisterStatus(Vehicle::REGISTRABLE);
$vehicle->setAAAStatus(Vehicle::AAA_READY);
}
}
if (!$vehicle->getClientPosition() && $vehicle->getPositioned() && ($vehicle->getPrintableStatus() == Vehicle::PRINTABLE || $vehicle->getPrintableStatus() == Vehicle::PRINTED)) {
$vehicle->setClientPosition($vehicle->getClientInvoice());
}
if (
!$vehicle->getClientRegistration()
&& $vehicle->getClientPosition()
&& $vehicle->getRegisterStatus() == Vehicle::REGISTRABLE
) {
if ($vehicle->getClientPosition()->getSivPartner()) {
$vehicle->setClientRegistration($vehicle->getClientPosition()->getSivPartner());
} else {
$vehicle->setClientRegistration($vehicle->getClientPosition());
}
}
if ($preventFlush !== true) {
$this->em->flush();
}
$event->setVehicle($vehicle);
}
public function handleCdfs(VehicleEvent $event)
{
/** @var Vehicle $vehicle */
$vehicle = $event->getVehicle();
if ($vehicle->getClientPosition() && $vehicle->getPositioned() && $vehicle->getClientRegistration() != null) {
if ($vehicle->getClientPosition()->getSivPartner()) {
if ($vehicle->getClientRegistration()->getId() != $vehicle->getClientPosition()->getSivPartner()->getId()) {
$vehicle->setClientRegistration($vehicle->getClientPosition()->getSivPartner());
self::checkVehicleAAASend($vehicle);
}
} else {
if ($vehicle->getClientRegistration()->getId() != $vehicle->getClientPosition()->getId()) {
$vehicle->setClientRegistration($vehicle->getClientPosition());
self::checkVehicleAAASend($vehicle);
}
}
}
}
public function handleCocFluxForOtc(COCEvent $event)
{
$vehicle = $event->getVehicle();
$user = $event->getUser();
$numReception = $event->getNumReception();
$otc = $this->otcDataRepository->getOTCForNumReception($vehicle, $numReception);
if ($otc) {
$oldOtc = $vehicle->getOtc();
if ($oldOtc != null && $oldOtc->getId() != $otc->getId()) {
if ($vehicle->getPrintableStatus() == Vehicle::PRINTED) {
$vehicle->setPrintableStatus(Vehicle::PRINTABLE);
}
self::checkVehicleAAASend($vehicle);
}
$vehicle->setDateOtc($otc->getDateReception());
$vehicle->setOtc($otc);
$eventWorklog = new WorklogEvent($vehicle, 'otc', $user);
$this->dispatcher->dispatch($eventWorklog, 'iris.worklog');
} else {
$vehicle->setDateOtc(null);
$vehicle->setOtc(null);
if ($cerfa = $vehicle->getCerfaData()) {
$vehicle->setCerfaData(null);
$this->em->remove($cerfa);
}
}
$this->em->flush();
$event->setVehicle($vehicle);
}
public function handleCO2Eligibility(VehicleEvent $event)
{
$vehicle = $event->getVehicle();
if ($otc = $vehicle->getOtc()) {
if (($environmentalClass = $otc->getEnvironmentalClass()) && ($category = $otc->getCategory())) {
$CO2Eligibility = (bool)$this->co2CriteriaRepository->findOneBy(array('environmentalClass' => $environmentalClass, 'vehicleCategory' => $category));
$vehicle->setCO2Eligibility($CO2Eligibility);
}
}
$event->setVehicle($vehicle);
}
public function handleOtc(OTCEvent $otcEvent)
{
/** @var OTCData $otc */
$otc = $otcEvent->getOtc();
$otc = $this->em->merge($otc);
/** @var VehicleRepository $vehicleRepository */
$vehicles = $this->vehicleRepository->findForOtc($otc->getTvv(), $otc->getNumReception());
foreach ($vehicles as $vehicle) {
$vehicle->setDateOtc($otc->getDateReception());
$vehicle->setOtc($otc);
$user = $otcEvent->getUser();
$eventWorklog = new WorklogEvent($vehicle, 'otc', $user);
$this->dispatcher->dispatch($eventWorklog, 'iris.worklog');
if ($vehicle->getPrintableStatus() == Vehicle::PRINTED) {
$vehicle->setPrintableStatus(Vehicle::PRINTABLE);
}
self::checkVehicleAAASend($vehicle);
}
foreach ($vehicles as $vehicle) {
$vehicleEvent = new VehicleEvent($vehicle);
$this->handleCO2Eligibility($vehicleEvent);
$this->handleStatus($vehicleEvent, true);
$this->handleCerfaData($vehicleEvent, true);
}
$this->em->flush();
}
public static $counter = 0;
public function handleCerfaData(VehicleEvent $event, $preventFlush = false)
{
$vehicle = $event->getVehicle();
if ($vehicle->getPrintableStatus() == Vehicle::PRINTABLE) {
$flush = self::$counter++ % 500 == 0;
$this->cerfaService->generateCerfaForVehicle($vehicle, !$flush);
}
}
}