feat(rtt) : allow payment on closed phase last exercise
This commit is contained in:
@@ -12,8 +12,10 @@ use App\Entity\EmployeeRttPayment;
|
||||
use App\Repository\EmployeeRepository;
|
||||
use App\Repository\EmployeeRttPaymentRepository;
|
||||
use App\Service\AuditLogger;
|
||||
use App\Service\Contracts\EmployeeContractPhaseResolver;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Psr\Clock\ClockInterface;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
|
||||
|
||||
@@ -24,6 +26,8 @@ final readonly class EmployeeRttPaymentProcessor implements ProcessorInterface
|
||||
private EmployeeRttPaymentRepository $rttPaymentRepository,
|
||||
private EntityManagerInterface $entityManager,
|
||||
private AuditLogger $auditLogger,
|
||||
private EmployeeContractPhaseResolver $phaseResolver,
|
||||
private ClockInterface $clock,
|
||||
) {}
|
||||
|
||||
public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): EmployeeRttPaymentInput
|
||||
@@ -48,6 +52,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 +89,44 @@ 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->resolveExerciseYearForDate($this->clock->now());
|
||||
}
|
||||
|
||||
/**
|
||||
* Map a date to the RTT exercise year it belongs to (Juin N-1 → Mai N convention).
|
||||
*/
|
||||
private function resolveExerciseYearForDate(DateTimeImmutable $date): int
|
||||
{
|
||||
$year = (int) $date->format('Y');
|
||||
$month = (int) $date->format('n');
|
||||
|
||||
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->resolveExerciseYearForDate($phase->endDate)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw new UnprocessableEntityHttpException(
|
||||
'RTT payment is only allowed on the current exercise or the last exercise of a closed contract phase.'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user