|
|
|
|
@@ -206,20 +206,36 @@ final readonly class RttRecoveryComputationService
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$weekAnchorNature = $naturesByDate[$employeeId][$weekDays[0]] ?? ContractNature::CDI;
|
|
|
|
|
$weekAnchorContract = $employeeContractsByDate[$weekDays[0]] ?? null;
|
|
|
|
|
$isWeekPresenceTracking = TrackingMode::PRESENCE->value === $weekAnchorContract?->getTrackingMode();
|
|
|
|
|
$disableOvertimeBonuses = $this->hasDisabledOvertimeBonuses($weekAnchorContract, $weekAnchorNature);
|
|
|
|
|
$overtimeReferenceMinutes = $this->computeWeeklyOvertimeReferenceMinutes($weekDays, $employeeContractsByDate);
|
|
|
|
|
$weekAnchorNature = $naturesByDate[$employeeId][$weekDays[0]] ?? ContractNature::CDI;
|
|
|
|
|
$weekAnchorContract = $employeeContractsByDate[$weekDays[0]] ?? null;
|
|
|
|
|
$isWeekPresenceTracking = TrackingMode::PRESENCE->value === $weekAnchorContract?->getTrackingMode();
|
|
|
|
|
$disableOvertimeBonuses = $this->hasDisabledOvertimeBonuses($weekAnchorContract, $weekAnchorNature);
|
|
|
|
|
$weekContractType = ContractType::resolve(
|
|
|
|
|
$weekAnchorContract?->getName(),
|
|
|
|
|
$weekAnchorContract?->getTrackingMode(),
|
|
|
|
|
$weekAnchorContract?->getWeeklyHours()
|
|
|
|
|
);
|
|
|
|
|
$isCustomContract = ContractType::CUSTOM === $weekContractType;
|
|
|
|
|
$overtimeReferenceMinutes = $isCustomContract
|
|
|
|
|
? $this->computeWeeklyCustomReferenceMinutes($weekDays, $employeeContractsByDate)
|
|
|
|
|
: $this->computeWeeklyOvertimeReferenceMinutes($weekDays, $employeeContractsByDate);
|
|
|
|
|
$overtime25StartMinutes = $this->computeWeeklyOvertime25StartMinutes($weekDays, $employeeContractsByDate);
|
|
|
|
|
$weeklyOvertimeTotalMinutes = $isWeekPresenceTracking
|
|
|
|
|
? 0
|
|
|
|
|
: $weeklyTotalMinutes - $overtimeReferenceMinutes;
|
|
|
|
|
|
|
|
|
|
$base25 = ($isWeekPresenceTracking || $disableOvertimeBonuses) ? 0 : max(0, min($weeklyTotalMinutes, 43 * 60) - $overtime25StartMinutes);
|
|
|
|
|
$bonus25 = ($isWeekPresenceTracking || $disableOvertimeBonuses) ? 0 : (int) round($base25 * 0.25);
|
|
|
|
|
$base50 = ($isWeekPresenceTracking || $disableOvertimeBonuses) ? 0 : max(0, $weeklyTotalMinutes - 43 * 60);
|
|
|
|
|
$bonus50 = ($isWeekPresenceTracking || $disableOvertimeBonuses) ? 0 : (int) round($base50 * 0.5);
|
|
|
|
|
$base25 = ($isWeekPresenceTracking || $disableOvertimeBonuses || $isCustomContract) ? 0 : max(0, min($weeklyTotalMinutes, 43 * 60) - $overtime25StartMinutes);
|
|
|
|
|
$bonus25 = ($isWeekPresenceTracking || $disableOvertimeBonuses || $isCustomContract) ? 0 : (int) round($base25 * 0.25);
|
|
|
|
|
$base50 = ($isWeekPresenceTracking || $disableOvertimeBonuses || $isCustomContract) ? 0 : max(0, $weeklyTotalMinutes - 43 * 60);
|
|
|
|
|
$bonus50 = ($isWeekPresenceTracking || $disableOvertimeBonuses || $isCustomContract) ? 0 : (int) round($base50 * 0.5);
|
|
|
|
|
|
|
|
|
|
if ($isWeekPresenceTracking || $disableOvertimeBonuses) {
|
|
|
|
|
$totalMinutes = 0;
|
|
|
|
|
} elseif ($isCustomContract) {
|
|
|
|
|
$totalMinutes = max(0, $weeklyOvertimeTotalMinutes);
|
|
|
|
|
} else {
|
|
|
|
|
$totalMinutes = $weeklyOvertimeTotalMinutes + $bonus25 + $bonus50;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$results[$weekKey] = new WeekRecoveryDetail(
|
|
|
|
|
overtimeMinutes: $weeklyOvertimeTotalMinutes,
|
|
|
|
|
@@ -227,9 +243,7 @@ final readonly class RttRecoveryComputationService
|
|
|
|
|
bonus25Minutes: $bonus25,
|
|
|
|
|
base50Minutes: $base50,
|
|
|
|
|
bonus50Minutes: $bonus50,
|
|
|
|
|
totalMinutes: ($isWeekPresenceTracking || $disableOvertimeBonuses)
|
|
|
|
|
? 0
|
|
|
|
|
: $weeklyOvertimeTotalMinutes + $bonus25 + $bonus50,
|
|
|
|
|
totalMinutes: $totalMinutes,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -326,6 +340,23 @@ final readonly class RttRecoveryComputationService
|
|
|
|
|
return max(0, $end - $start);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param list<string> $days
|
|
|
|
|
* @param array<string, ?Contract> $contractsByDate
|
|
|
|
|
*/
|
|
|
|
|
private function computeWeeklyCustomReferenceMinutes(array $days, array $contractsByDate): int
|
|
|
|
|
{
|
|
|
|
|
$total = 0;
|
|
|
|
|
foreach ($days as $date) {
|
|
|
|
|
$isoDay = (int) new DateTimeImmutable($date)->format('N');
|
|
|
|
|
$contract = $contractsByDate[$date] ?? null;
|
|
|
|
|
$hours = $contract?->getWeeklyHours();
|
|
|
|
|
$total += $this->resolveDailyReferenceMinutes($hours, $isoDay);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $total;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param list<string> $days
|
|
|
|
|
* @param array<string, ?Contract> $contractsByDate
|
|
|
|
|
|