Files
SIRH/src/State/EmployeeOvertimeContingentProvider.php
T
tristan 0a9b26d31e
Auto Tag Develop / tag (push) Successful in 6s
feat(overtime-contingent) : heures supp structurelles (>35h) ajoutées au contingent
Les heures contractuelles au-delà de 35h (ex. 39h → 17,33h décimales = 17h20/mois)
sont payées chaque mois sans transiter par les paiements RTT (référence 39h). Elles
manquaient au contingent. Ajout via StructuralOvertimeContingentCalculator :
(weeklyHours-35)×260 min/mois, généralisé aux contrats non-forfait/non-intérim >35h,
proratisé aux jours sous contrat. Branché sur l'encart fiche et l'export PDF.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 08:57:26 +02:00

64 lines
2.6 KiB
PHP

<?php
declare(strict_types=1);
namespace App\State;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProviderInterface;
use App\ApiResource\EmployeeOvertimeContingent;
use App\Entity\Employee;
use App\Repository\EmployeeRepository;
use App\Repository\EmployeeRttPaymentRepository;
use App\Service\WorkHours\OvertimePaidContingentCalculator;
use App\Service\WorkHours\StructuralOvertimeContingentCalculator;
use DateTimeImmutable;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
final readonly class EmployeeOvertimeContingentProvider implements ProviderInterface
{
public function __construct(
private RequestStack $requestStack,
private EmployeeRttPaymentRepository $rttPaymentRepository,
private OvertimePaidContingentCalculator $calculator,
private StructuralOvertimeContingentCalculator $structuralCalculator,
private EmployeeRepository $employeeRepository,
) {}
public function provide(Operation $operation, array $uriVariables = [], array $context = []): EmployeeOvertimeContingent
{
$employeeId = (int) ($uriVariables['id'] ?? 0);
if ($employeeId <= 0) {
throw new UnprocessableEntityHttpException('id must be a positive integer.');
}
$employee = $this->employeeRepository->find($employeeId);
if (!$employee instanceof Employee) {
throw new NotFoundHttpException('Employee not found.');
}
$request = $this->requestStack->getCurrentRequest();
$year = (int) $request?->query->get('year', (string) (int) new DateTimeImmutable('now')->format('Y'));
if ($year < 2000 || $year > 2100) {
throw new UnprocessableEntityHttpException('year must be between 2000 and 2100.');
}
// Année civile Y = exercice Y (mois 1-5) + exercice Y+1 (mois 6-12).
$payments = array_merge(
$this->rttPaymentRepository->findByEmployeeAndYear($employee, $year),
$this->rttPaymentRepository->findByEmployeeAndYear($employee, $year + 1),
);
$output = new EmployeeOvertimeContingent();
$output->year = $year;
$output->paidMinutes = $this->calculator->totalBaseMinutes($payments, $year)
+ $this->structuralCalculator->totalStructuralMinutes($employee, $year);
$output->isDriver = $employee->getIsDriver();
$output->capHours = $this->calculator->capHours($output->isDriver);
return $output;
}
}