feat : ajout de l'impression des tableaux d'absence

This commit is contained in:
2026-02-06 16:20:09 +01:00
parent ee26fdd045
commit 03f5552dd4
7 changed files with 834 additions and 3 deletions

View File

@@ -0,0 +1,197 @@
<?php
declare(strict_types=1);
namespace App\State;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProviderInterface;
use App\Entity\Absence;
use App\Entity\Employee;
use DateInterval;
use DateTimeImmutable;
use Doctrine\ORM\EntityManagerInterface;
use Dompdf\Dompdf;
use Dompdf\Options;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Twig\Environment;
use Twig\Error\LoaderError;
use Twig\Error\RuntimeError;
use Twig\Error\SyntaxError;
class AbsencePrintProvider implements ProviderInterface
{
public function __construct(
private Environment $twig,
private readonly RequestStack $requestStack,
private EntityManagerInterface $entityManager,
) {}
/**
* @throws SyntaxError
* @throws RuntimeError
* @throws LoaderError
*/
public function provide(Operation $operation, array $uriVariables = [], array $context = []): Response
{
$request = $this->requestStack->getCurrentRequest();
if (!$request) {
return new Response('Missing request.', Response::HTTP_BAD_REQUEST);
}
$from = $request->query->get('from');
$to = $request->query->get('to');
if (!$from || !$to) {
return new Response('Missing from/to query params.', Response::HTTP_BAD_REQUEST);
}
$fromDate = DateTimeImmutable::createFromFormat('Y-m-d', $from);
$toDate = DateTimeImmutable::createFromFormat('Y-m-d', $to);
$siteIds = $this->parseIds($request->query->get('sites'));
$employees = $this->loadEmployees($siteIds);
$absences = $this->loadAbsences($fromDate, $toDate, $employees);
$days = $this->buildDays($fromDate, $toDate);
$absenceMap = $this->buildAbsenceMap($absences, $fromDate, $toDate);
$options = new Options();
$options->set('isRemoteEnabled', true);
$dompdf = new Dompdf($options);
$html = $this->twig->render('absence/print.html.twig', [
'from' => $fromDate,
'to' => $toDate,
'days' => $days,
'employees' => $employees,
'absenceMap' => $absenceMap,
]);
$dompdf->loadHtml($html);
$dompdf->setPaper('A3', 'landscape');
$dompdf->render();
$filename = 'test';
return new Response($dompdf->output(), Response::HTTP_OK, [
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'inline; filename="'.$filename.'"',
]);
}
private function parseIds(?string $value): array
{
if (null === $value || '' === trim($value)) {
return [];
}
$ids = [];
foreach (explode(',', $value) as $part) {
$id = (int) trim($part);
if ($id > 0) {
$ids[] = $id;
}
}
return array_values(array_unique($ids));
}
private function loadEmployees(array $siteIds): array
{
$qb = $this->entityManager
->getRepository(Employee::class)
->createQueryBuilder('e')
->leftJoin('e.site', 's')
->addSelect('s')
->orderBy('s.name', 'ASC')
->addOrderBy('e.lastName', 'ASC')
->addOrderBy('e.firstName', 'ASC')
;
if ([] !== $siteIds) {
$qb->andWhere('s.id IN (:siteIds)')
->setParameter('siteIds', $siteIds)
;
}
/** @var list<Employee> $result */
return $qb->getQuery()->getResult();
}
private function loadAbsences(DateTimeImmutable $from, DateTimeImmutable $to, array $employees): array
{
if ([] === $employees) {
return [];
}
$qb = $this->entityManager
->getRepository(Absence::class)
->createQueryBuilder('a')
->leftJoin('a.employee', 'e')
->leftJoin('a.type', 't')
->addSelect('e', 't')
->andWhere('a.startDate <= :to')
->andWhere('a.endDate >= :from')
->andWhere('a.employee IN (:employees)')
->setParameter('from', $from)
->setParameter('to', $to)
->setParameter('employees', $employees)
;
/** @var list<Absence> $result */
return $qb->getQuery()->getResult();
}
private function buildDays(DateTimeImmutable $from, DateTimeImmutable $to): array
{
$days = [];
$current = $from;
while ($current <= $to) {
$days[] = [
'date' => $current->format('Y-m-d'),
'label' => $current->format('d'),
];
$current = $current->add(new DateInterval('P1D'));
}
return $days;
}
private function buildAbsenceMap(array $absences, DateTimeImmutable $from, DateTimeImmutable $to): array
{
$map = [];
foreach ($absences as $absence) {
$employeeId = $absence->getEmployee()?->getId();
$type = $absence->getType();
if (!$employeeId || !$type) {
continue;
}
$absenceStart = DateTimeImmutable::createFromInterface($absence->getStartDate());
$absenceEnd = DateTimeImmutable::createFromInterface($absence->getEndDate());
$start = max($absenceStart, $from);
$end = min($absenceEnd, $to);
$current = $start;
while ($current <= $end) {
$dateKey = $current->format('Y-m-d');
$map[$employeeId][$dateKey] = [
'code' => (string) $type->getCode(),
'color' => (string) $type->getColor(),
];
$current = $current->add(new DateInterval('P1D'));
}
}
return $map;
}
}