<?php
namespace App\Controller;
use App\Entity\AAALog;
use App\Entity\Catalogue3en1;
use Doctrine\ORM\EntityManagerInterface;
use EasyCorp\Bundle\EasyAdminBundle\Config\Assets;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Config\MenuItem;
use EasyCorp\Bundle\EasyAdminBundle\Config\UserMenu;
use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator;
use EasyCorp\Bundle\EasyAdminBundle\Config\Dashboard;
use App\Entity\Seats;
use EasyCorp\Bundle\EasyAdminBundle\Security\Permission;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Routing\Annotation\Route;
use Doctrine\ORM\EntityManager;
use App\Repository\VehicleRepository;
use App\Repository\OTCDataRepository;
use App\Repository\JRNLogRepository;
use App\Repository\IssueRepository;
use App\Form\Type\PrintersChoiceType;
use App\Event\IssueEvent;
use App\Entity\Vehicle;
use App\Entity\User;
use App\Entity\Bus;
use App\Entity\COCData;
use App\Entity\Printer;
use App\Entity\Client;
use App\Entity\CO2Criteria;
use App\Entity\JRNLog;
use App\Entity\FDPGamma;
use App\Entity\OTCData;
use App\Entity\Issue;
use App\Entity\JobLog;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractDashboardController;
use EasyCorp\Bundle\EasyAdminBundle\Contracts\Controller\DashboardControllerInterface;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class DefaultController extends AbstractDashboardController implements DashboardControllerInterface
{
/** @var JRNLogRepository $repoJRNLog */
private $repoJRNLog;
/** @var VehicleRepository $repoVehicle */
private $repoVehicle;
/** @var MessageLogRepository $repoJob */
private $repoJob;
/** @var OTCDataRepository $repoOTC */
private $repoOTC;
/** @var IssueRepository $repoOTC */
private $repoIssue;
private $authenticationUtils;
private $kernel;
private $translator;
private $adminUrlGenerator;
private $messageBus;
/**
* @param EntityManager $em
*/
public function __construct(
private EntityManagerInterface $em,
AuthenticationUtils $authenticationUtils,
KernelInterface $kernel,
TranslatorInterface $translator,
AdminUrlGenerator $adminUrlGenerator,
MessageBusInterface $bus
) {
$this->authenticationUtils = $authenticationUtils;
$this->repoJRNLog = $em->getRepository(JRNLog::class);
$this->repoVehicle = $em->getRepository(Vehicle::class);
$this->repoOTC = $em->getRepository(OTCData::class);
$this->repoIssue = $em->getRepository(Issue::class);
$this->repoJob = $em->getRepository(JobLog::class);
$this->adminUrlGenerator = $adminUrlGenerator;
$this->kernel = $kernel;
$this->translator = $translator;
$this->messageBus = $bus;
}
public function configureDashboard(): Dashboard
{
return Dashboard::new()
->disableUrlSignatures();
}
public function configureCrud(): Crud
{
return Crud::new()
->overrideTemplates([
'layout' => 'base.html.twig',
'crud/index' => 'index.html.twig',
]);
}
public function configureAssets(): Assets
{
return Assets::new()
->addWebpackEncoreEntry('app');
}
public function configureMenuItems(): iterable
{
if($this->isGranted("ROLE_USERS")){
yield MenuItem::linkToDashboard('Dashboard', 'fa fa-home')->setPermission("ROLE_USERS");
yield MenuItem::subMenu('issue-list', 'fa fa-exclamation')->setSubItems([
MenuItem::linkToCrud('Alert', 'fa fa-warning', Issue::class)
->setAction('index')
->setController(AdminIssueController::class),
MenuItem::linkToCrud('Info', 'fa fa-info', Issue::class)
->setController(AdminWarningController::class)
]);
$flowSubMenu = [];
if($this->isGranted("ROLE_HOMOLOGATION") || $this->isGranted("ROLE_LOGISTIC_BUS")){
$flowSubMenu[] = MenuItem::linkToRoute('import-export', 'fa fa-cloud-download', 'import_export');
}
$flowSubMenu[] = MenuItem::linkToCrud('Log', 'fa fa-file-text', JobLog::class)->setAction('index')
->setPermission("ROLE_USERS");
if($this->isGranted("ROLE_MARKETING") || $this->isGranted("ROLE_LOGISTIC_BUS") || $this->isGranted("ROLE_LOGISTIC")){
$flowSubMenu[] = MenuItem::linkToCrud('JRNLog', 'fa fa-file-text', JRNLog::class)->setAction('index');
}
$flowSubMenu[] = MenuItem::linkToCrud('acvdifflog', 'fa fa-file-text', AAALog::class)->setAction('index')
->setController(AdminACVDiffController::class)
->setPermission("ROLE_SUPERADMIN");
$flowSubMenu[] = MenuItem::linkToCrud('avinvarlog', 'fa fa-file-text', AAALog::class)->setAction('index')
->setController(AdminAAALogController::class)
->setPermission("ROLE_SUPERADMIN");
yield MenuItem::subMenu('flow', 'fa fa-tasks')->setSubItems($flowSubMenu);
}
if($this->isGranted("ROLE_MARKETING") || $this->isGranted("ROLE_HOMOLOGATION") || $this->isGranted("ROLE_LOGISTIC") || $this->isGranted("ROLE_LOGISTIC_BUS")){
$vehicleSubMenu = [];
if($this->isGranted("ROLE_MARKETING") || $this->isGranted("ROLE_HOMOLOGATION") || $this->isGranted("ROLE_LOGISTIC") ){
$vehicleSubMenu[] = MenuItem::linkToCrud('Truck', 'fa fa-truck', Vehicle::class)
->setAction('index');
}
if($this->isGranted("ROLE_MARKETING") || $this->isGranted("ROLE_LOGISTIC_BUS")){
$vehicleSubMenu[] = MenuItem::linkToCrud('Bus', 'fa fa-bus', Bus::class)
->setAction('index');
}
yield MenuItem::subMenu('vehicles', 'fa fa-car')->setSubItems($vehicleSubMenu);
}
if($this->isGranted("ROLE_MARKETING") || $this->isGranted("ROLE_HOMOLOGATION") || $this->isGranted("ROLE_LOGISTIC")){
yield MenuItem::linkToCrud('customers', 'fa fa-user', Client::class)
->setAction('index');
}
yield MenuItem::subMenu('admin', 'fa fa-key')->setSubItems([
MenuItem::linkToCrud('users', 'fa fa-user', User::class),
MenuItem::linkToCrud('printers', 'fa fa-print', Printer::class)
])->setPermission("ROLE_ADMIN");
if($this->isGranted("ROLE_MARKETING") || $this->isGranted("ROLE_HOMOLOGATION")){
yield MenuItem::subMenu('parametrization', 'fa fa-cog')->setSubItems([
MenuItem::linkToCrud('Catalogue3en1', 'fa fa-cogs', Catalogue3en1::class)
->setAction('index')
->setPermission('ROLE_SUPERADMIN'),
MenuItem::linkToCrud('Seats', 'fa fa-street-view', Seats::class)
->setAction('index')
->setPermission("ROLE_HOMOLOGATION"),
MenuItem::linkToCrud('FDPGamma', 'fa fa-cogs', FDPGamma::class)
->setAction('index')
->setPermission("ROLE_MARKETING"),
MenuItem::linkToCrud('CO2Criteria', 'fa fa-leaf', CO2Criteria::class)
->setAction('index')
->setPermission("ROLE_HOMOLOGATION"),
]);
}
if($this->isGranted("ROLE_HOMOLOGATION")){
yield MenuItem::subMenu('homologation', 'fa fa-sitemap')->setSubItems([
MenuItem::linkToCrud('otc', 'fa fa-cogs', OTCData::class)->setAction('index'),
MenuItem::linkToCrud('coc', 'fa fa-cogs', COCData::class)->setAction('index'),
]);
}
}
public function configureUserMenu(UserInterface $user): UserMenu
{
$userMenuItems = [MenuItem::section(), MenuItem::linkToLogout('__ea__user.sign_out', 'fa-sign-out')];
$userMenuItems[] = MenuItem::linkToRoute('settings.label', 'settings', 'settings');
if ($this->isGranted(Permission::EA_EXIT_IMPERSONATION)) {
$userMenuItems[] = MenuItem::linkToExitImpersonation('__ea__user.exit_impersonation', 'fa-user-lock');
}
$userName = '';
if (method_exists($user, 'getUsername')) {
$userName = $user->getUsername();
} elseif (method_exists($user, 'getUserIdentifier')) {
$userName = $user->getUserIdentifier();
} elseif (method_exists($user, '__toString')) {
$userName = (string) $user;
}
return UserMenu::new()
->displayUserName()
->displayUserAvatar()
->setName($userName)
->setAvatarUrl(null)
->setMenuItems($userMenuItems);
}
/** @Route("/", name="homepage") */
public function homepage(): Response
{
return $this->redirectToRoute('easyadmin');
}
/** @Route("/admin", name="easyadmin") */
public function index(): Response
{
return $this->indexAction();
}
public function indexAction()
{
ini_set('max_execution_time', '300');
$panels = [
$this->isGranted("ROLE_MARKETING") || $this->isGranted("ROLE_LOGISTIC_BUS")
? $this->createJRNPanel() : false,
$this->isGranted("ROLE_LOGISTIC")
? $this->createCDFSPanel() : false,
$this->isGranted("ROLE_HOMOLOGATION") || $this->isGranted("ROLE_MARKETING") || $this->isGranted("ROLE_LOGISTIC")
? $this->createSAPPanel() : false,
$this->isGranted("ROLE_HOMOLOGATION")
? $this->createOTCPanel() : false,
$this->isGranted("ROLE_HOMOLOGATION") || $this->isGranted("ROLE_LOGISTIC")
? $this->create3en1Panel() : false,
$this->isGranted("ROLE_SUPERADMIN")
? $this->createErrorsPanel() : false,
$this->isGranted("ROLE_HOMOLOGATION") || $this->isGranted("ROLE_SUPERADMIN")
? $this->createECOCPanel() : false,
];
$panels = $this->removeUnusedPanels($panels);
$panels = $this->setConstantPanelRowCount($panels);
return $this->render('Default/index.html.twig', ["panels" => $panels]);
}
private function removeUnusedPanels($panels)
{
$panels = array_filter($panels);
foreach ($panels as &$panel) {
$panel["values"] = array_filter($panel["values"]);
$panel["alerts"] = array_filter(isset($panel["alerts"]) ? $panel["alerts"] : []);
}
return $panels;
}
private static function setConstantPanelRowCount($panels)
{
if (!count($panels)) return [];
$maxLines = max(array_map(function ($p) {
return count($p["values"]) + count($p["alerts"]);
}, $panels));
// Note: the line filler goes above the alert panels if these are present
foreach ($panels as &$panel)
$panel["values"] += array_fill(0, $maxLines - count($panel["alerts"]), []);
return $panels;
}
//region Top Level Panel Creators
private function createJRNPanel()
{
return [
"title" => [
"raw" => "JRN",
"link" => $this->adminUrlGenerator->setController(AdminJRNLogController::class)->generateUrl()
],
"values" => [
$this->getCountSinceLastUpdateForBrandSubPanel(JRNLog::IVECO, "IVECO"),
$this->getCountSinceLastUpdateForBrandSubPanel(JRNLog::IVECO_BUS, "IVECO BUS"),
$this->getCountSinceLastUpdateForBrandSubPanel(JRNLog::IRISBUS, "IRIS BUS"),
$this->getInfoLinkSubPanelIfOlderThan(IssueEvent::JRN, $this->repoJob->findLastCreatedAtImport("jrn")),
]
];
}
private function createCDFSPanel()
{
$lastCreatedAtImport = $this->repoJob->findLastCreatedAtImport("cdfs");
$formattedDate = $this->formatDate($lastCreatedAtImport);
$runNumber = $this->repoVehicle->findFirstRunNumberAfter($lastCreatedAtImport);
return [
"title" => ["raw" => "<span class=\"title-span\">CDFS:</span> {$formattedDate}, {$runNumber}"],
"values" => [
[
"value" => $this->repoVehicle->countCDFSImportAfter($lastCreatedAtImport),
"label" => "treated vehicles",
],
$this->getInfoLinkSubPanelIfOlderThan(IssueEvent::CDFS, $lastCreatedAtImport),
],
"alerts" => [$this->getNewIssueAlert(IssueEvent::CDFS, $lastCreatedAtImport)]
];
}
private function createSAPPanel()
{
$lastCreateDateSAPImport = $this->repoJob->findLastCreatedAtImport("sap");
$formattedDate = $this->formatDate($lastCreateDateSAPImport);
return [
"title" => ["raw" => "<span class=\"title-span\">SAP:</span> {$formattedDate}"],
"values" => [
[
"value" => $this->repoVehicle->countSAPImportAfter($lastCreateDateSAPImport),
"label" => "treated vehicles",
],
$this->getInfoLinkSubPanelIfOlderThan(IssueEvent::SAP, $lastCreateDateSAPImport),
],
"alerts" => [
$this->isGranted("ROLE_HOMOLOGATION") ? $this->getNewSapPersonAlert(IssueEvent::SAP_CLIENT, "Alert! New client") : false,
$this->isGranted("ROLE_MARKETING") ? $this->getNewSapPersonAlert(IssueEvent::SAP, "Alert! New FDP") : false,
]
];
}
private function createOTCPanel()
{
$lastCreateDateOTCImport = $this->repoJob->findLastCreatedAtImport("otc");
$formattedDate = $this->formatDate($lastCreateDateOTCImport);
$lastOTCNumReception = $this->repoOTC->findLastNumReception();
return [
"title" => ["raw" => "<span class=\"title-span\">OTC:</span> {$formattedDate}, {$lastOTCNumReception}"],
"values" => [
[
"value" => $this->repoVehicle->countOTCByNumReception($lastOTCNumReception),
"label" => "concerned vehicles",
"link" => $this->generateUrl_SearchByLastOTCNumber($lastOTCNumReception)
],
$this->getInfoLinkSubPanelIfOlderThan(IssueEvent::OTC, $lastCreateDateOTCImport),
]
];
}
private function create3en1Panel()
{
return [
"title" => ["raw" => "3en1"],
"values" => [[
"value" => $this->repoVehicle->countPrintableGrand(true),
"label" => "3en1 to print_KA",
"link" => $this->generateUrl_SearchByPrintableGrand(true)
], [
"value" => $this->repoVehicle->countPrintableGrand(false),
"label" => "3en1 to print_DEALERS",
"link" => $this->generateUrl_SearchByPrintableGrand(false)
]]
];
}
private function createErrorsPanel()
{
return [
"title" => ["label" => "Errors AAA"],
"values" => [
$this->getErrorSubPanelForError(IssueEvent::AAA_DEPOT, "Errors in sending"),
$this->getErrorSubPanelForError(IssueEvent::AAA_RETRAIT_REJE, "Errors REJE"),
$this->getErrorSubPanelForError(IssueEvent::AAA_RETRAIT_REJG, "Errors REJG"),
$this->getInfoLinkSubPanelIfOlderThan(IssueEvent::AAA, new \DateTime()),
]
];
}
private function createECOCPanel()
{
$job = $this->repoJob->findByLastEcocImport();
$lastECOCImportJob = !$job ? "" : $job->getCreatedAt();
$formattedDate = $this->formatDate($lastECOCImportJob);
return [
"title" => ["raw" => "<span class=\"title-span\">eCOC:</span> {$formattedDate}"],
"values" => [
[
"value" => $this->repoVehicle->countECOCImportAfter($lastECOCImportJob),
"label" => "treated vehicles",
],
$this->getInfoLinkSubPanelIfOlderThan(IssueEvent::ECOC_IMPORT, $lastECOCImportJob),
],
"alerts" => [$this->getNewIssueAlert(IssueEvent::ECOC_IMPORT, $lastECOCImportJob)]
];
}
//endregion
//region Generate Search URLs
private function generateUrl_SearchByLastOTCNumber($lastOTCNumReception)
{
return $this->adminUrlGenerator
->setController(AdminVehicleController::class)
->setAction('index')
->set("filters[otc--numReception][value]", $lastOTCNumReception)
->set("filters[otc--numReception][comparison]", "=");
}
private function generateUrl_SearchByPrintableGrand($isGrandCompte)
{
$adminUrlGenerator = $this->container->get(AdminUrlGenerator::class);
return $adminUrlGenerator
->setController(AdminVehicleController::class)
->setAction('index')
->set('filters[positioned]', "1")
->set('filters[clientInvoice--isGrandCompte]', $isGrandCompte ? "1" : "0")
->set('filters[printableStatus][comparison]', '=')
->set('filters[printableStatus][value]', 'printable');
}
private function generateUrl_ShowWarningList($queryType)
{
$adminUrlGenerator = $this->container->get(AdminUrlGenerator::class);
return $adminUrlGenerator
->setController(AdminWarningController::class)
->setAction('index')
->set('filters[type][value]', $queryType)
->set('filters[type][comparison]', '=');
}
private function generateUrl_GenericSearchQuery($query)
{
$adminUrlGenerator = $this->container->get(AdminUrlGenerator::class);
$adminUrlGenerator
->setController(AdminIssueController::class)
->setAction('index');
foreach($query as $key => $value){
$adminUrlGenerator
->set("filters[$key][comparison])","=")
->set("filters[$key][value])",$value);
}
return $adminUrlGenerator->generateUrl();
}
//endregion
//region Sub Panels Creators
private function getErrorSubPanelForError($type, $label)
{
return ($value = $this->repoIssue->countBy(["status" => Issue::STATUS_NEW, "type" => $type, "priority" => Issue::$PRIORITY_ERROR])) ? [
"value" => $value,
"label" => $label,
"alert" => true,
"link" => $this->generateUrl_GenericSearchQuery(["status" => Issue::STATUS_NEW, "type" => $type, "priority" => Issue::$PRIORITY_ERROR]),
] : false;
}
private function getInfoLinkSubPanelIfOlderThan($type, $createdAt)
{
return $this->repoIssue->countBy(["priority" => Issue::$PRIORITY_INFO, "type" => $type, "createdAt>=" => $createdAt]) ? [
"label" => "show.action",
"link" => $this->generateUrl_ShowWarningList($type),
] : false;
}
private function getCountSinceLastUpdateForBrandSubPanel($type, $label)
{
$lastImport = $this->repoJRNLog->findLastRegistrationDateByBrand($type);
return [
"value" => $this->repoJRNLog->countByBrandFromDate($type, $lastImport),
"label" => $label,
"date" => $lastImport
];
}
private function getNewSapPersonAlert($personType, $label)
{
return $this->repoIssue->countBy(["type" => $personType, "status" => Issue::STATUS_NEW, "priority" => Issue::$PRIORITY_ERROR]) ? [
"label" => $label,
"link" => $this->generateUrl_GenericSearchQuery(["type" => $personType]),
"alert" => true,
] : false;
}
private function getNewIssueAlert($type, $lastCreateDateImport)
{
return $this->repoIssue->countBy(["type" => $type, "status" => Issue::STATUS_NEW, "priority" => Issue::$PRIORITY_ERROR, "createdAt>=" => $lastCreateDateImport]) ? [
"label" => "Alert!",
"link" => $this->generateUrl_GenericSearchQuery(["type" => $type, "status" => Issue::STATUS_NEW])
] : false;
}
//endregion
private function formatDate($date)
{
return $date ? $date->format("d/m/Y H:i:s") : '';
}
/** @Route("/testsecure", name="testsecure") */
public function testAction()
{
return new Response('
<<!DOCTYPE html>
<html>
<head>
<title>IRIS</title>
</head>
<body>
<h1>This resource is secured</h1>
<p>You are: </p>' . print_r($this->getUser(), true) . '
</body>
</html>
');
}
/**
* @Route("/login", name="login")
*/
public function loginAction(Request $request)
{
// KEEP LOGIN BACKDOOR
// if (($this->getParameter('kernel.environment') == 'qua' ||
// $this->getParameter('kernel.environment') == 'prod' ||
// $this->getUser() instanceof User) &&
// strpos($request->getUri(), 'coolinternal.it') === false
// ) {
// return $this->redirectToRoute('homepage');
// }
$error = $this->authenticationUtils->getLastAuthenticationError();
$lastUsername = $this->authenticationUtils->getLastUsername();
return $this->render('login.html.twig', ['last_username' => $lastUsername, 'error' => $error]);
}
/**
* @Route("/logout", name="logout")
*/
public function logoutAction()
{
return;
}
/**
* @Route("/settings", name="settings")
* @param Request $request
* @return Response
*/
public function settingsAction(Request $request)
{
$user = $this->getUser();
$form = $this->createPrinterForm($user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->get('session')->getFlashBag()->set('success', $this->translator->trans('batch.success'));
$em = $this->em;
$em->flush();
}
return $this->render('Default/settings.html.twig', [
'base_dir' => realpath($this->kernel->getProjectDir() . '/..'),
'form' => $form->createView()
]);
}
private function createPrinterForm($user)
{
return $this->createFormBuilder($user)
->add('printer', PrintersChoiceType::class, ['expanded' => true, 'label' => 'printer.label'])
->add('send', SubmitType::class, ['label' => 'printer.save'])
->getForm();
}
}