Gestion du changement de type de contrat + correction du calcule des RTT sur un contrat qui commence en milieu de semaine (#19)
Auto Tag Develop / tag (push) Has been cancelled

| Numéro du ticket | Titre du ticket |
|------------------|-----------------|
|                  |                 |

## Description de la PR

## Modification du .env

## Check list

- [x] Pas de régression
- [x] TU/TI/TF rédigée
- [x] TU/TI/TF OK
- [x] CHANGELOG modifié

Reviewed-on: #19
Co-authored-by: tristan <tristan@yuno.malio.fr>
Co-committed-by: tristan <tristan@yuno.malio.fr>
This commit was merged in pull request #19.
This commit is contained in:
2026-05-22 06:42:33 +00:00
committed by Autin
parent b541f9ded8
commit abdaf809f8
40 changed files with 5021 additions and 153 deletions
+35 -5
View File
@@ -12,8 +12,10 @@ use App\Entity\EmployeeRttPayment;
use App\Repository\EmployeeRepository;
use App\Repository\EmployeeRttPaymentRepository;
use App\Service\AuditLogger;
use DateTimeImmutable;
use App\Service\Contracts\EmployeeContractPhaseResolver;
use App\Service\Exercise\ExerciseYearResolver;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Clock\ClockInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
@@ -24,6 +26,9 @@ final readonly class EmployeeRttPaymentProcessor implements ProcessorInterface
private EmployeeRttPaymentRepository $rttPaymentRepository,
private EntityManagerInterface $entityManager,
private AuditLogger $auditLogger,
private EmployeeContractPhaseResolver $phaseResolver,
private ClockInterface $clock,
private ExerciseYearResolver $exerciseYearResolver,
) {}
public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): EmployeeRttPaymentInput
@@ -48,6 +53,8 @@ final readonly class EmployeeRttPaymentProcessor implements ProcessorInterface
$year = $data->year ?? $this->resolveCurrentExerciseYear();
$this->assertYearAllowedForPayment($employee, $year);
$payment = $this->rttPaymentRepository->findOneByEmployeeYearMonth($employee, $year, $data->month);
if (null === $payment) {
@@ -83,10 +90,33 @@ final readonly class EmployeeRttPaymentProcessor implements ProcessorInterface
private function resolveCurrentExerciseYear(): int
{
$today = new DateTimeImmutable('today');
$year = (int) $today->format('Y');
$month = (int) $today->format('n');
return $this->exerciseYearResolver->forDate($this->clock->now());
}
return $month >= 6 ? $year + 1 : $year;
/**
* Allow payment when the requested exercise is either the current one
* or the last exercise of a closed contract phase (the one containing
* the phase end date). Reject any other exercise (past or future).
*/
private function assertYearAllowedForPayment(Employee $employee, int $year): void
{
$currentExerciseYear = $this->resolveCurrentExerciseYear();
if ($year === $currentExerciseYear) {
return;
}
$phases = $this->phaseResolver->resolvePhases($employee);
foreach ($phases as $phase) {
if ($phase->isCurrent || null === $phase->endDate) {
continue;
}
if ($year === $this->exerciseYearResolver->forDate($phase->endDate)) {
return;
}
}
throw new UnprocessableEntityHttpException(
'RTT payment is only allowed on the current exercise or the last exercise of a closed contract phase.'
);
}
}