fix(rtt) : anchor week contract type on first contracted day

Mid-week hire weeks (e.g. CDD starting Thursday) had their first day with no
contract, so the week was classified CUSTOM and the 25%/50% overtime bonuses
were disabled. Anchor the week's contract type/nature on the first contracted
day instead, so a 35h/39h hire week keeps its overtime tiers.
Dylan CHABOISSON week 12: 7h → 8h45 (7h × 1.25).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-20 17:10:10 +02:00
parent f3d94a8590
commit 066ed7746f
2 changed files with 98 additions and 3 deletions

View File

@@ -221,8 +221,9 @@ final readonly class RttRecoveryComputationService
continue;
}
$weekAnchorNature = $naturesByDate[$employeeId][$weekDays[0]] ?? ContractNature::CDI;
$weekAnchorContract = $employeeContractsByDate[$weekDays[0]] ?? null;
$weekAnchorDate = $this->resolveWeekAnchorDate($weekDays, $employeeContractsByDate);
$weekAnchorNature = $naturesByDate[$employeeId][$weekAnchorDate] ?? ContractNature::CDI;
$weekAnchorContract = $employeeContractsByDate[$weekAnchorDate] ?? null;
$isWeekPresenceTracking = TrackingMode::PRESENCE->value === $weekAnchorContract?->getTrackingMode();
$disableOvertimeBonuses = $this->hasDisabledOvertimeBonuses($weekAnchorContract, $weekAnchorNature);
$weekContractType = ContractType::resolve(
@@ -388,9 +389,29 @@ final readonly class RttRecoveryComputationService
}
/**
* @param list<string> $days
* @param array<string, ?Contract> $contractsByDate
*/
/**
* Date d'ancrage de la semaine pour résoudre le type/nature de contrat : premier jour
* de la semaine couvert par un contrat. Évite qu'une semaine d'embauche en milieu de
* semaine (premiers jours hors contrat) soit classée CUSTOM — ce qui désactiverait à
* tort les bonus 25 %/50 % d'un contrat 35h/39h. Fallback sur le 1er jour si aucun jour
* n'est contracté (semaine entièrement hors contrat → 0 de toute façon).
*
* @param list<string> $weekDays
* @param array<string, ?Contract> $contractsByDate
*/
private function resolveWeekAnchorDate(array $weekDays, array $contractsByDate): string
{
foreach ($weekDays as $date) {
if (null !== ($contractsByDate[$date] ?? null)) {
return $date;
}
}
return $weekDays[0];
}
private function computeWeeklyOvertimeReferenceMinutes(array $days, array $contractsByDate): int
{
$total = 0;