<?php
namespace App\Controller\Admin;
use App\Entity\Appointment;
use App\Entity\EventLog;
use App\Form\AppointmentFileType;
use Doctrine\ORM\EntityManagerInterface;
use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Field\ArrayField;
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
use EasyCorp\Bundle\EasyAdminBundle\Field\BooleanField;
use EasyCorp\Bundle\EasyAdminBundle\Field\CollectionField;
use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField;
use EasyCorp\Bundle\EasyAdminBundle\Field\EmailField;
use EasyCorp\Bundle\EasyAdminBundle\Field\IdField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TelephoneField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextEditorField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Email;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\Translation\TranslatorInterface;
class AppointmentCrudController extends AbstractCrudController
{
public static function getEntityFqcn(): string
{
return Appointment::class;
}
public function configureCrud(Crud $crud): Crud
{
return $crud
->setDateTimeFormat('dd/MM/yyyy HH:mm')
->showEntityActionsAsDropdown()
->setDefaultSort([
'appointmentAt' => 'DESC',
])
->setSearchFields([
'vehicleType.name',
'card.cardNumber',
'plateNumber',
'phoneNumber',
'email',
])
->setPaginatorPageSize(200);
}
/**
* @Route("/%easyadmin_url%/live", name="admin_dashboard_live")
* @IsGranted("ROLE_SIVEC_WORKER")
*/
public function liveDashboard(): Response
{
/**
* "Live" features (without page refresh)
* Clock displaying current time
* Appointments list refresh (for instance if a new appointment is taken for the afternoon during the morning)
* Hide appointments after 30min of the initial datetime
*/
return $this->render('admin/index_live.html.twig', [
]);
}
public function configureActions(Actions $actions): Actions
{
$cancelAction = Action::new('cancel', 'Cancel', 'fa fa-window-close')
->linkToRoute('admin_appointment_cancel', function (Appointment $appointment) {
return ['id' => $appointment->getId()];
})
->addCssClass("btn btn-link pr-0 text-warning");
return $actions
->add(Crud::PAGE_INDEX, Action::DETAIL)
->add(Crud::PAGE_INDEX, $cancelAction)
->add(Crud::PAGE_DETAIL, $cancelAction)
->setPermission(Action::NEW, 'ROLE_SIVEC_OPERATOR')
->setPermission(Action::DELETE, 'ROLE_SUPER_ADMIN')
->setPermission(Action::EDIT, 'ROLE_SIVEC_OPERATOR')
->setPermission($cancelAction, 'ROLE_SIVEC_OPERATOR')
->reorder(Crud::PAGE_INDEX, [Action::DETAIL, Action::EDIT, 'cancel', Action::DELETE]);
}
public function configureFields(string $pageName): iterable
{
return [
IdField::new('id', 'Id')->hideOnForm(),
AssociationField::new('vehicleType'),
AssociationField::new('card')
->setHelp('Card number'),
TextField::new('confirmationToken'),
TextField::new('plateNumber')
->formatValue(function ($value) {
return strtoupper(str_replace(' ', '', $value));
}),
DateTimeField::new('appointmentAt')
->renderAsNativeWidget(false),
TextEditorField::new('comment')->hideOnIndex(),
TelephoneField::new('phoneNumber'),
EmailField::new('email'),
DateTimeField::new('createdAt')->hideOnForm(),
TextField::new('statusAsText', 'Status')->hideOnForm(),
BooleanField::new('isMaximumLimitAccepted')
->setRequired(true)
->renderAsSwitch(false),
BooleanField::new('isConditionsAccepted')
->setRequired(true)
->renderAsSwitch(false),
BooleanField::new('isConfirmed')
->setRequired(true)
->renderAsSwitch(false),
CollectionField::new('appointmentFiles')
->setTemplatePath('admin/field/appointment_file.html.twig')
->onlyOnDetail(),
];
}
public function deleteEntity(EntityManagerInterface $entityManager, $entityInstance): void
{
/**
* @var Appointment $entityInstance
*/
foreach ($entityInstance->getEventLogs() as $eventLog) {
$eventLog->setAppointment(null);
}
$eventLog = new EventLog();
$eventLog->setAction(EventLog::APPOINTMENT_DELETE);
$eventLog->setUser($this->getUser());
$entityManager->persist($eventLog);
parent::deleteEntity($entityManager, $entityInstance);
}
/**
* @Route("/%easyadmin_url%/appointment/{id}/cancel", name="admin_appointment_cancel")
* @IsGranted("ROLE_SIVEC_OPERATOR")
* @param EntityManagerInterface $entityManager
* @param MailerInterface $mailer
* @param TranslatorInterface $translator
* @param $id
* @return \Symfony\Component\HttpFoundation\RedirectResponse
* @throws \Symfony\Component\Mailer\Exception\TransportExceptionInterface
*/
public function cancelAppointment(Request $request, EntityManagerInterface $entityManager, MailerInterface $mailer, TranslatorInterface $translator, $id)
{
$appointment = $entityManager->getRepository(Appointment::class)->find($id);
if ($appointment and $appointment->getStatus() !== Appointment::STATUS_CANCELLED) {
$appointment->setStatus(Appointment::STATUS_CANCELLED);
$appointment->setCancelDate(new \DateTime());
$eventLog = new EventLog();
$eventLog->setAction(EventLog::APPOINTMENT_CANCEL);
$eventLog->setAppointment($appointment);
$eventLog->setUser($this->getUser());
$entityManager->persist($eventLog);
$entityManager->flush();
$this->addFlash('success', 'Le rendez-vous a été annulé');
if ($appointment->getEmail()) {
// Get email confirmation content
$emailTemplate = $this->renderView('mail/appointment_cancellation.html.twig', array(
'appointment' => $appointment,
));
$email = (new Email())
->from('noreply@sivec.lu')
->to($appointment->getEmail())
->subject($translator->trans('email.appointment_cancellation.subject'))
->html($emailTemplate);
$mailer->send($email);
$this->addFlash('success', 'Un email de notification a été envoyé');
}
} else {
$this->addFlash('warning', 'Le rendez-vous a déjà été annulé ou n\'existe pas');
}
return $this->redirect($request->headers->get('referer'));
}
}