feat(overtime-contingent) : contingent d'heures supplémentaires payées (#29)
Auto Tag Develop / tag (push) Successful in 7s
Auto Tag Develop / tag (push) Successful in 7s
## Résumé
Suivi par **année civile** (Janv–Déc) des heures supplémentaires payées des employés non-forfait (chauffeurs inclus) face au plafond légal (**350 h** chauffeurs / **220 h** autres).
- **Fiche employé** : encart header `Total H.payés {année} : X h / plafond h` (année civile courante, rouge si dépassement), via `GET /employees/{id}/overtime-contingent`.
- **Export PDF** `GET /overtime-contingent/print?year=&siteIds=` (ROLE_USER, périmètre `findScoped`) : groupé par site, colonnes Janv–Déc + colonne `Total payé / payable`. Drawer liste employés (année + sites).
- Heures payées = `base25 + base50` (hors majoration). Mapping exercice→civil : `mois ≥ 6 ? exercice−1 : exercice`.
- Cœur partagé pur `OvertimePaidContingentCalculator`.
- Ajout « Année civile » dans le titre des deux exports PDF (contingent H.supp. et heures de nuit).
## Tests
- 214 tests PHPUnit verts (calculateur : mapping civil, base-only, plafond ; builder : ventilation mensuelle, ligne à zéro).
## Hors périmètre (consigné)
- Bug latent `SalaryRecapPrintProvider` : rattachement des paiements RTT des mois Juin–Déc par année civile sur un stockage par exercice. À traiter séparément.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Reviewed-on: #29
Co-authored-by: tristan <tristan@yuno.malio.fr>
Co-committed-by: tristan <tristan@yuno.malio.fr>
This commit was merged in pull request #29.
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
<?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 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 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);
|
||||
$output->isDriver = $employee->getIsDriver();
|
||||
$output->capHours = $this->calculator->capHours($output->isDriver);
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user