import type { Ref } from 'vue' import type { Absence } from '~/services/dto/absence' import type { ContractPhase } from '~/services/dto/contract-phase' import type { EmployeeLeaveSummary } from '~/services/dto/employee-leave-summary' import type { Employee } from '~/services/dto/employee' import { CONTRACT_TYPES } from '~/services/dto/contract' import { listAbsences } from '~/services/absences' import { getEmployeeLeaveSummary, updateFractionedDays, updatePaidLeaveDays } from '~/services/employee-leave-summary' import { listPublicHolidays } from '~/services/public-holidays' export type LeaveYearOption = { value: number label: string } export const useEmployeeLeave = ( employee: Ref, reloadEmployee: () => Promise, selectedPhase: Ref, ) => { const employeeAbsences = ref([]) const leaveSummary = ref(null) const publicHolidays = ref>({}) const isLeaveLoading = ref(false) const leaveDataLoaded = ref(false) const selectedLeaveYear = ref(null) const isForfaitOnPhase = computed(() => selectedPhase.value?.contractType === CONTRACT_TYPES.FORFAIT ) const computeLeaveYearForDate = (date: Date): number => { if (isForfaitOnPhase.value) return date.getFullYear() return date.getMonth() >= 5 ? date.getFullYear() + 1 : date.getFullYear() } const currentLeaveYear = computed(() => { if (!employee.value) return null return computeLeaveYearForDate(new Date()) }) const formatLeaveYearLabel = (year: number, isForfait: boolean): string => { if (isForfait) return String(year) return `Juin ${year - 1} → Mai ${year}` } const availableLeaveYears = computed(() => { if (!employee.value || !selectedPhase.value || currentLeaveYear.value === null) return [] const isForfait = isForfaitOnPhase.value const phase = selectedPhase.value // Plage = exercices intersectant la phase. const phaseStartYear = computeLeaveYearForDate(new Date(`${phase.startDate}T00:00:00`)) const phaseEndYear = phase.endDate ? computeLeaveYearForDate(new Date(`${phase.endDate}T00:00:00`)) : currentLeaveYear.value // Hard floor : data-start-date (env RTT_START_DATE) — le logiciel n'a pas // d'historique avant cette date, inutile de proposer des années antérieures. let dataFloor: number | null = null const dataStart = leaveSummary.value?.dataStartDate if (dataStart) { const dataStartDate = new Date(`${dataStart.substring(0, 10)}T00:00:00`) if (!Number.isNaN(dataStartDate.getTime())) { dataFloor = computeLeaveYearForDate(dataStartDate) } } const minYear = dataFloor !== null ? Math.max(phaseStartYear, dataFloor) : phaseStartYear const maxYear = phaseEndYear const years: LeaveYearOption[] = [] for (let y = maxYear; y >= minYear; y -= 1) { years.push({ value: y, label: formatLeaveYearLabel(y, isForfait) }) } return years }) const initSelectedLeaveYear = () => { if (selectedLeaveYear.value !== null) return if (currentLeaveYear.value !== null) { selectedLeaveYear.value = currentLeaveYear.value } } const loadLeaveData = async () => { if (!employee.value || isLeaveLoading.value) return initSelectedLeaveYear() if (selectedLeaveYear.value === null) return isLeaveLoading.value = true try { const isForfait = isForfaitOnPhase.value const leaveYear = selectedLeaveYear.value let from = isForfait ? `${leaveYear}-01-01` : `${leaveYear - 1}-06-01` let to = isForfait ? `${leaveYear}-12-31` : `${leaveYear}-05-31` const phase = selectedPhase.value if (phase?.startDate && phase.startDate > from) from = phase.startDate if (phase?.endDate && phase.endDate < to) to = phase.endDate const holidayYears = isForfait ? [leaveYear] : [leaveYear - 1, leaveYear] const [absences, summary, ...holidayResults] = await Promise.all([ listAbsences({ from, to, employeeId: employee.value.id }), getEmployeeLeaveSummary(employee.value.id, leaveYear, selectedPhase.value?.id), ...holidayYears.map((y) => listPublicHolidays('metropole', y)) ]) employeeAbsences.value = absences leaveSummary.value = summary publicHolidays.value = Object.assign({}, ...holidayResults) leaveDataLoaded.value = true } finally { isLeaveLoading.value = false } } const setSelectedLeaveYear = async (year: number) => { if (selectedLeaveYear.value === year) return selectedLeaveYear.value = year leaveDataLoaded.value = false await loadLeaveData() } const resetLoaded = () => { leaveDataLoaded.value = false selectedLeaveYear.value = null } watch(() => selectedPhase.value?.id, () => { // Reset l'année car la plage a peut-être changé. selectedLeaveYear.value = null leaveDataLoaded.value = false // Le rechargement effectif est piloté par useEmployeeDetailPage. }) const submitFractionedDays = async (days: number) => { if (!employee.value) return const year = leaveSummary.value?.year ?? undefined await updateFractionedDays(employee.value.id, days, year) await reloadEmployee() } const submitPaidLeaveDays = async (days: number) => { if (!employee.value) return const year = leaveSummary.value?.year ?? undefined await updatePaidLeaveDays(employee.value.id, days, year) await reloadEmployee() } return { employeeAbsences, leaveSummary, publicHolidays, isLeaveLoading, leaveDataLoaded, selectedLeaveYear, currentLeaveYear, availableLeaveYears, setSelectedLeaveYear, loadLeaveData, resetLoaded, submitFractionedDays, submitPaidLeaveDays } }