clé 1..12 -> minutes structurelles payées (proratisées) */ public function monthlyStructuralMinutes(Employee $employee, int $civilYear): array { $accumulated = array_fill(1, 12, 0.0); foreach ($employee->getContractPeriods() as $period) { $contract = $period->getContract(); if (null === $contract) { continue; } $type = $contract->getType(); if (ContractType::FORFAIT === $type || ContractType::INTERIM === $type) { continue; } $weeklyHours = $contract->getWeeklyHours(); if (null === $weeklyHours || $weeklyHours <= 35) { continue; } $fullMonthlyMinutes = ($weeklyHours - 35) * self::MINUTES_PER_WEEKLY_HOUR_PER_MONTH; $periodStart = $period->getStartDate(); $periodEnd = $period->getEndDate(); for ($month = 1; $month <= 12; ++$month) { $monthStart = new DateTimeImmutable(sprintf('%04d-%02d-01', $civilYear, $month)); $monthEnd = $monthStart->modify('last day of this month'); $daysInMonth = (int) $monthEnd->format('d'); $overlapStart = $periodStart > $monthStart ? $periodStart : $monthStart; $overlapEnd = (null !== $periodEnd && $periodEnd < $monthEnd) ? $periodEnd : $monthEnd; if ($overlapStart > $overlapEnd) { continue; } $overlapDays = $overlapStart->diff($overlapEnd)->days + 1; $accumulated[$month] += $fullMonthlyMinutes * $overlapDays / $daysInMonth; } } $months = []; for ($month = 1; $month <= 12; ++$month) { $months[$month] = (int) round($accumulated[$month]); } return $months; } public function totalStructuralMinutes(Employee $employee, int $civilYear): int { return array_sum($this->monthlyStructuralMinutes($employee, $civilYear)); } }