Gestion du changement de type de contrat + correction du calcule des RTT sur un contrat qui commence en milieu de semaine #19

Merged
tristan merged 55 commits from feat/contract-phase-view-selector into develop 2026-05-22 06:42:33 +00:00
4 changed files with 28 additions and 3 deletions
Showing only changes of commit e310f65d81 - Show all commits
+11 -3
View File
@@ -14,10 +14,16 @@ export const useEmployeeDetailPage = () => {
const showLeaveTab = computed(() => employee.value?.currentContractNature !== 'INTERIM') const showLeaveTab = computed(() => employee.value?.currentContractNature !== 'INTERIM')
const showRttTab = computed(() => phase.selectedPhase.value?.contractType !== CONTRACT_TYPES.FORFAIT) const showRttTab = computed(() => phase.selectedPhase.value?.contractType !== CONTRACT_TYPES.FORFAIT)
const isForfait = computed(() => phase.selectedPhase.value?.contractType === CONTRACT_TYPES.FORFAIT) const isForfait = computed(() => phase.selectedPhase.value?.contractType === CONTRACT_TYPES.FORFAIT)
// Jours à travailler du forfait : prorata exposé par le backend (218 sur année pleine,
// moins sur une entrée en cours d'année). Fallback 218 tant que le récap n'est pas chargé.
const forfaitWorkTargetDays = computed(() => {
const target = leave.leaveSummary.value?.forfaitWorkTargetDays
return (target === null || target === undefined) ? 218 : Math.round(target)
})
const employeeContractWorkLabel = computed(() => { const employeeContractWorkLabel = computed(() => {
const contract = employee.value?.contract const contract = employee.value?.contract
if (!contract) return '-' if (!contract) return '-'
if (contract.type === CONTRACT_TYPES.FORFAIT) return 'Forfait - 218 jours' if (contract.type === CONTRACT_TYPES.FORFAIT) return `Forfait - ${forfaitWorkTargetDays.value} jours`
if (contract.weeklyHours !== null && contract.weeklyHours !== undefined) return `${contract.weeklyHours} heures` if (contract.weeklyHours !== null && contract.weeklyHours !== undefined) return `${contract.weeklyHours} heures`
return contract.name || '-' return contract.name || '-'
}) })
@@ -75,8 +81,10 @@ export const useEmployeeDetailPage = () => {
if (!isForfait.value) return '' if (!isForfait.value) return ''
const presence = leave.leaveSummary.value?.presenceDaysToToday const presence = leave.leaveSummary.value?.presenceDaysToToday
if (presence === undefined || presence === null) return '' if (presence === undefined || presence === null) return ''
const remaining = 218 - presence const fmt = (n: number) => (Number.isInteger(n) ? String(n) : (Math.round(n * 100) / 100).toFixed(2).replace('.', ','))
return ` (${remaining} restants)` // restant à travailler = jours à travailler (prorata) jours de présence déjà effectués
const remaining = forfaitWorkTargetDays.value - presence
return ` (${fmt(presence)} présence · ${fmt(remaining)} restants)`
}) })
const rtt = useEmployeeRtt(employee, loadEmployee, phase.selectedPhase) const rtt = useEmployeeRtt(employee, loadEmployee, phase.selectedPhase)
const mileage = useEmployeeMileage(employee, loadEmployee) const mileage = useEmployeeMileage(employee, loadEmployee)
@@ -16,6 +16,7 @@ export type EmployeeLeaveSummary = {
previousYearPaidDays: number previousYearPaidDays: number
presenceDaysByMonth: Record<string, number> presenceDaysByMonth: Record<string, number>
presenceDaysToToday: number presenceDaysToToday: number
forfaitWorkTargetDays: number | null
dataStartDate: string | null dataStartDate: string | null
} }
+8
View File
@@ -42,6 +42,14 @@ final class EmployeeLeaveSummary
/** Cumul des jours de présence depuis le début de l'année de congé jusqu'à aujourd'hui (forfait). */ /** Cumul des jours de présence depuis le début de l'année de congé jusqu'à aujourd'hui (forfait). */
public float $presenceDaysToToday = 0.0; public float $presenceDaysToToday = 0.0;
/**
* FORFAIT uniquement : jours à travailler sur l'exercice = jours ouvrés de la période congés acquis.
* Vaut 218 sur une année pleine (252 34) et le prorata sur une entrée en cours d'année
* (ex. Grégory : 168 13 ≈ 155). Null pour les non-forfait. Le « restant à travailler »
* affiché = forfaitWorkTargetDays presenceDaysToToday.
*/
public ?float $forfaitWorkTargetDays = null;
/** Date de mise en service du logiciel (env RTT_START_DATE) — borne minimale pour les sélecteurs d'historique. */ /** Date de mise en service du logiciel (env RTT_START_DATE) — borne minimale pour les sélecteurs d'historique. */
public ?string $dataStartDate = null; public ?string $dataStartDate = null;
} }
@@ -133,6 +133,14 @@ final readonly class EmployeeLeaveSummaryProvider implements ProviderInterface
$summary->previousYearPaidDays = $paidLeaveDays; $summary->previousYearPaidDays = $paidLeaveDays;
[$periodFrom, $periodTo] = $this->resolvePeriodBounds($employee, $year, $phase); [$periodFrom, $periodTo] = $this->resolvePeriodBounds($employee, $year, $phase);
// Forfait : jours à travailler sur l'exercice = jours ouvrés de la période congés acquis.
// Année pleine → 218 (252 34) ; entrée en cours d'année → prorata (ex. 168 13 ≈ 155).
if (LeaveRuleCode::FORFAIT_218->value === $summary->ruleCode) {
$businessDaysInPeriod = $this->countBusinessDays($periodFrom, $periodTo, $this->buildRawPublicHolidayMap($periodFrom, $periodTo));
$summary->forfaitWorkTargetDays = $businessDaysInPeriod - $summary->acquiredDays;
}
// Forfait-only: leaves taken from N-1 stock do NOT decrement presence days. // Forfait-only: leaves taken from N-1 stock do NOT decrement presence days.
// For non-forfait, previousYearTakenDays is always 0, so the budget has no effect. // For non-forfait, previousYearTakenDays is always 0, so the budget has no effect.
$n1AbsencesBudget = $yearSummary['previousYearTakenDays']; $n1AbsencesBudget = $yearSummary['previousYearTakenDays'];