<?php
namespace App\EventSubscriber;
use App\Entity\CustomerQuotations;
use App\Repository\CustomerQuotationsRepository;
use App\Repository\ManufacturerRepository;
use App\Repository\UserRepository;
use App\Service\Helpers\DateHelper;
use App\Service\Log\QuotationLogService;
use CalendarBundle\CalendarEvents;
use CalendarBundle\Entity\Event;
use CalendarBundle\Event\CalendarEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class CalendarSubscriber implements EventSubscriberInterface
{
private const COLOR = [
CustomerQuotations::STATUS_PRODUCTION => "#ADAABF",
CustomerQuotations::STATUS_PRODUCED => "#92828D",
CustomerQuotations::STATUS_PRODUCTION_FINISHED => "#CEB5A7",
CustomerQuotations::STATUS_DELIVERED => "#EBEFBF",
CustomerQuotations::STATUS_TRANSPORT => "#EAF7CF",
CustomerQuotations::STATUS_FINISHED => "#FCD3DE",
CustomerQuotations::STATUS_ACCEPTED => "#FCD3DE",
CustomerQuotations::STATUS_WAITING_PAYMENT => "#FCD3DE",
];
private CustomerQuotationsRepository $quotationsRepo;
private QuotationLogService $logService;
private UrlGeneratorInterface $router;
private UserRepository $userRepo;
private TranslatorInterface $translator;
private DateHelper $dateHelper;
private ManufacturerRepository $manufacturerRepo;
public function __construct(
CustomerQuotationsRepository $quotationsRepo,
UserRepository $userRepo,
ManufacturerRepository $manufacturerRepo,
QuotationLogService $logService,
TranslatorInterface $translator,
UrlGeneratorInterface $router,
DateHelper $dateHelper
)
{
$this->quotationsRepo = $quotationsRepo;
$this->manufacturerRepo = $manufacturerRepo;
$this->userRepo = $userRepo;
$this->logService = $logService;
$this->translator = $translator;
$this->router = $router;
$this->dateHelper = $dateHelper;
}
public static function getSubscribedEvents(): array
{
return [
CalendarEvents::SET_DATA => 'onCalendarSetData',
];
}
public function onCalendarSetData(CalendarEvent $calendar)
{
$filters = $this->normalizeFilters($calendar->getFilters());
$quotations = $this->getQuotations($filters);
foreach ($quotations as $quotation) {
$event = $this->createEvent($quotation);
if ($event) {
$calendar->addEvent($event);
}
}
}
private function normalizeFilters(array $filters): array
{
$filters['status'] = $filters['status'] === "[]" ? null : $filters['status'];
$filters['manager'] = $filters['manager'] ? $this->userRepo->findByUuid($filters['manager']) : null;
if ($filters['status']) {
$filters['status'] = preg_replace('/\d+/u', "", (str_replace([""", "[", "{", "}", "]", ";", ":"], "", $filters['status'])));
$filters['status'] = explode(',', $filters['status']);
}
$filters['manufacturer'] = $filters['manufacturer'] ? $this->manufacturerRepo->findByUuid($filters['manufacturer']) : null;
return $filters;
}
private function getQuotations(array $filters)
{
$defaultStatuses = [
CustomerQuotations::STATUS_PRODUCTION,
CustomerQuotations::STATUS_PRODUCED,
CustomerQuotations::STATUS_PRODUCTION_FINISHED,
CustomerQuotations::STATUS_TRANSPORT,
CustomerQuotations::STATUS_DELIVERED,
CustomerQuotations::STATUS_FINISHED,
];
$filter = [
'inStatus' => $filters['status'] ?? $defaultStatuses,
'manager' => $filters['manager'],
'inquiryManufacturer' => $filters['manufacturer'],
];
if ($filters['quotation']) {
$quotations = [$this->quotationsRepo->findByUuid($filters['quotation'])];
} else {
$quotations = $this->quotationsRepo->getAll($filter);
}
return $quotations;
}
private function createEvent($quotation): ?Event
{
$orderInquiry = $quotation->getOrderInquiry();
$log = $this->logService->getRegisteredLogForStatus($quotation, CustomerQuotations::STATUS_PRODUCTION);
if (!$log || !$orderInquiry) {
return null;
}
$leadDays = $orderInquiry->getLeadTime();
$realLeadDays = null;
$producedDate = (clone $log->getDate())->modify('+' . $orderInquiry->getLeadTime() . ' day');
$actualProducedDate = null;
$eventTitle = '#' . $quotation->getOrderNumber() . ' ' .
$quotation->getCustomer()->getName() . ' ' .
$orderInquiry->getManufacturer()->getCode() . ' (' .
$this->translator->trans($quotation->getStatus()) . ')';
if ($orderInquiry->getDateProduced() &&
$orderInquiry->getDateProduced()->setTime(0, 0, 0) !== $producedDate->setTime(0, 0, 0)) {
$actualProducedDate = $orderInquiry->getDateProduced();
$realLeadDays = $this->dateHelper->diffInDaysBetweenTwoDates($log->getDate(), $actualProducedDate) + 1;
}
$orderEvent = new Event(
$eventTitle,
($actualProducedDate ?? $producedDate)
);
$orderEvent->setOptions([
'backgroundColor' => $actualProducedDate ? '#f2c5b0' : 'light-gray',
'borderColor' => self::COLOR[$quotation->getStatus()],
'id' => $quotation->getUuid(),
'extendedProps' => [
'inProductionDate' => ($log->getDate())->format('d.m.y'),
'deliveryDate' => $orderInquiry->getDeliveryTime() ? (clone $producedDate)->modify('+' . $orderInquiry->getDeliveryTime() . ' day')->format('d.m.y') : $producedDate->format('d.m.y'),
'actualDeliveryDate' => $orderInquiry->getDeliveryTime() ? (clone($actualProducedDate ?? $producedDate))->modify('+' . $orderInquiry->getDeliveryTime() . ' day')->format('d.m.y') : (clone($actualProducedDate ?? $producedDate))->format('d.m.y'),
'leadDays' => $leadDays . ' Days',
'realLeadDays' => ($realLeadDays ?? $leadDays) . ' Days',
'deliveryDays' => $orderInquiry->getDeliveryTime() . ' Days',
'deliveryComment' => $orderInquiry->getDeliveryComment() ?? "",
'direction' => $orderInquiry->getManufacturer()->getAddressDetails()['country'] . ' -> ' . $quotation->getCustomer()->getAddressDetails()['country'],
'orderNumber' => '#' . $quotation->getOrderNumber(),
'orderStatus' => $this->translator->trans($quotation->getStatus()),
'orderUrl' => $this->router->generate('quotations.open', [
'uuid' => $quotation->getUuid(),
]),
'customer' => $quotation->getCustomer()->getName(),
'customerUrl' => $this->router->generate('customers.open', [
'uuid' => $quotation->getCustomer()->getUuid(),
]),
'manufacturer' => $orderInquiry->getManufacturer()->getName() . ' ' . $orderInquiry->getManufacturer()->getCode(),
'manufacturerUrl' => $this->router->generate('manufacturers.open', [
'uuid' => $orderInquiry->getManufacturer()->getUuid(),
]),
]
]);
$orderEvent->addOption(
'url',
$this->router->generate('quotations.open', [
'uuid' => $quotation->getUuid(),
])
);
return $orderEvent;
}
}