fix : correction calcule prorata congés avec un arrêt maladie long
Some checks failed
Auto Tag Develop / tag (push) Has been cancelled
Some checks failed
Auto Tag Develop / tag (push) Has been cancelled
This commit is contained in:
@@ -21,6 +21,7 @@ use App\Repository\EmployeeRepository;
|
||||
use App\Repository\WorkHourRepository;
|
||||
use App\Security\EmployeeScopeService;
|
||||
use App\Service\Leave\LeaveBalanceComputationService;
|
||||
use App\Service\Leave\LongMaladieService;
|
||||
use App\Service\Leave\SuspensionDaysCalculator;
|
||||
use App\Service\PublicHolidayServiceInterface;
|
||||
use DateTimeImmutable;
|
||||
@@ -42,6 +43,7 @@ final readonly class EmployeeLeaveSummaryProvider implements ProviderInterface
|
||||
private const float CDI_NON_FORFAIT_4H_ACQUIRED_SATURDAYS = 0.0;
|
||||
private const float CDI_NON_FORFAIT_4H_ACCRUAL_PER_MONTH = 0.83;
|
||||
private const float CDI_NON_FORFAIT_4H_SATURDAY_ACCRUAL_PER_MONTH = 0.0;
|
||||
private const float LONG_MALADIE_MONTHLY_ACCRUAL = 2.0;
|
||||
|
||||
public function __construct(
|
||||
private Security $security,
|
||||
@@ -52,6 +54,7 @@ final readonly class EmployeeLeaveSummaryProvider implements ProviderInterface
|
||||
private EmployeeContractPeriodRepository $periodRepository,
|
||||
private EmployeeLeaveBalanceRepository $leaveBalanceRepository,
|
||||
private LeaveBalanceComputationService $leaveBalanceComputationService,
|
||||
private LongMaladieService $longMaladieService,
|
||||
private PublicHolidayServiceInterface $publicHolidayService,
|
||||
private SuspensionDaysCalculator $suspensionDaysCalculator,
|
||||
private WorkHourRepository $workHourRepository,
|
||||
@@ -187,13 +190,29 @@ final readonly class EmployeeLeaveSummaryProvider implements ProviderInterface
|
||||
$suspensions = $this->suspensionDaysCalculator->applyFirstMonthGrace(
|
||||
$this->resolveSuspensionsForPeriod($employee, $effectiveFrom, $to)
|
||||
);
|
||||
|
||||
$longMaladiePeriods = [];
|
||||
$longMaladieReductionFactor = 1.0;
|
||||
if (LeaveRuleCode::CDI_CDD_NON_FORFAIT->value === $leavePolicy['ruleCode']
|
||||
&& 4 !== $employee->getContract()?->getWeeklyHours()
|
||||
&& null !== $accrualCalculationEnd
|
||||
) {
|
||||
$longMaladiePeriods = $this->longMaladieService->findReducedRatePeriods($employee, $effectiveFrom, $accrualCalculationEnd);
|
||||
if ([] !== $longMaladiePeriods) {
|
||||
$totalNormalAccrual = $leavePolicy['accrualPerMonth'] + $leavePolicy['saturdayAccrualPerMonth'];
|
||||
$longMaladieReductionFactor = self::LONG_MALADIE_MONTHLY_ACCRUAL / $totalNormalAccrual;
|
||||
}
|
||||
}
|
||||
|
||||
$generatedDays = $leavePolicy['accrualPerMonth'] > 0.0
|
||||
? $this->computeAccruedDaysFromStart(
|
||||
$leavePolicy['acquiredDays'],
|
||||
$leavePolicy['accrualPerMonth'],
|
||||
$effectiveFrom,
|
||||
$accrualCalculationEnd,
|
||||
$suspensions
|
||||
$suspensions,
|
||||
$longMaladiePeriods,
|
||||
$longMaladieReductionFactor
|
||||
)
|
||||
: 0.0;
|
||||
$generatedSaturdays = $leavePolicy['saturdayAccrualPerMonth'] > 0.0
|
||||
@@ -202,7 +221,9 @@ final readonly class EmployeeLeaveSummaryProvider implements ProviderInterface
|
||||
$leavePolicy['saturdayAccrualPerMonth'],
|
||||
$effectiveFrom,
|
||||
$accrualCalculationEnd,
|
||||
$suspensions
|
||||
$suspensions,
|
||||
$longMaladiePeriods,
|
||||
$longMaladieReductionFactor
|
||||
)
|
||||
: 0.0;
|
||||
$absences = $this->absenceRepository->findByEmployeeAndOverlappingDateRange($employee, $from, $to);
|
||||
@@ -375,12 +396,18 @@ final readonly class EmployeeLeaveSummaryProvider implements ProviderInterface
|
||||
return $year;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param list<ContractSuspension> $suspensions
|
||||
* @param list<array{start: DateTimeImmutable, end: DateTimeImmutable}> $longMaladiePeriods
|
||||
*/
|
||||
private function computeAccruedDaysFromStart(
|
||||
float $acquiredDays,
|
||||
float $accrualPerMonth,
|
||||
DateTimeImmutable $periodStart,
|
||||
?DateTimeImmutable $periodEnd,
|
||||
array $suspensions = []
|
||||
array $suspensions = [],
|
||||
array $longMaladiePeriods = [],
|
||||
float $longMaladieReductionFactor = 1.0
|
||||
): float {
|
||||
if ($accrualPerMonth <= 0.0) {
|
||||
return $acquiredDays;
|
||||
@@ -393,7 +420,8 @@ final readonly class EmployeeLeaveSummaryProvider implements ProviderInterface
|
||||
$periodStart = $this->normalizeDate($periodStart);
|
||||
$periodEnd = $this->normalizeDate($periodEnd);
|
||||
$publicHolidays = [] !== $suspensions ? $this->buildPublicHolidayMap($periodStart, $periodEnd) : [];
|
||||
$coveredMonths = 0.0;
|
||||
$normalMonths = 0.0;
|
||||
$reducedMonths = 0.0;
|
||||
$cursor = $periodStart->modify('first day of this month')->setTime(0, 0);
|
||||
while ($cursor <= $periodEnd) {
|
||||
$monthStart = $cursor > $periodStart ? $cursor : $periodStart;
|
||||
@@ -407,7 +435,7 @@ final readonly class EmployeeLeaveSummaryProvider implements ProviderInterface
|
||||
if ($suspendedDays > 0) {
|
||||
$businessDays = $this->countBusinessDays($monthStart, $monthEnd, $publicHolidays);
|
||||
$suspendedBusinessDays = $this->suspensionDaysCalculator->countSuspendedBusinessDays($monthStart, $monthEnd, $suspensions, $publicHolidays);
|
||||
$coveredMonths += max(0, $businessDays - $suspendedBusinessDays) / 22.0;
|
||||
$normalMonths += max(0, $businessDays - $suspendedBusinessDays) / 22.0;
|
||||
$cursor = $cursor->modify('first day of next month');
|
||||
|
||||
continue;
|
||||
@@ -416,12 +444,25 @@ final readonly class EmployeeLeaveSummaryProvider implements ProviderInterface
|
||||
|
||||
$coveredDays = ((int) $monthEnd->diff($monthStart)->format('%a')) + 1;
|
||||
$daysInMonth = (int) $cursor->format('t');
|
||||
$coveredMonths += $coveredDays / $daysInMonth;
|
||||
|
||||
if ([] !== $longMaladiePeriods) {
|
||||
$reducedDays = $this->longMaladieService->countReducedDaysInMonth($monthStart, $monthEnd, $longMaladiePeriods);
|
||||
if ($reducedDays > 0) {
|
||||
$normalDays = max(0, $coveredDays - $reducedDays);
|
||||
$normalMonths += $normalDays / $daysInMonth;
|
||||
$reducedMonths += min($coveredDays, $reducedDays) / $daysInMonth;
|
||||
$cursor = $cursor->modify('first day of next month');
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$normalMonths += $coveredDays / $daysInMonth;
|
||||
|
||||
$cursor = $cursor->modify('first day of next month');
|
||||
}
|
||||
|
||||
return min($acquiredDays, $coveredMonths * $accrualPerMonth);
|
||||
return min($acquiredDays, ($normalMonths + $reducedMonths * $longMaladieReductionFactor) * $accrualPerMonth);
|
||||
}
|
||||
|
||||
private function resolveAccrualCalculationEndDate(
|
||||
|
||||
Reference in New Issue
Block a user