import type { Ref } from 'vue' import type { Absence } from '~/services/dto/absence' 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) => { const employeeAbsences = ref([]) const leaveSummary = ref(null) const publicHolidays = ref>({}) const isLeaveLoading = ref(false) const leaveDataLoaded = ref(false) const selectedLeaveYear = ref(null) const isForfaitContract = (emp: Employee | null) => emp?.contract?.type === CONTRACT_TYPES.FORFAIT const computeLeaveYearForDate = (emp: Employee | null, date: Date): number => { if (isForfaitContract(emp)) return date.getFullYear() return date.getMonth() >= 5 ? date.getFullYear() + 1 : date.getFullYear() } const currentLeaveYear = computed(() => { if (!employee.value) return null return computeLeaveYearForDate(employee.value, 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 || currentLeaveYear.value === null) return [] const isForfait = isForfaitContract(employee.value) const current = currentLeaveYear.value const startDates: string[] = [] for (const period of employee.value.contractHistory ?? []) { if (period.startDate) startDates.push(period.startDate) } if (employee.value.entryDate) startDates.push(employee.value.entryDate) let contractFloor = current for (const raw of startDates) { const date = new Date(`${raw.substring(0, 10)}T00:00:00`) if (Number.isNaN(date.getTime())) continue const leaveYear = computeLeaveYearForDate(employee.value, date) if (leaveYear < contractFloor) contractFloor = leaveYear } // 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(employee.value, dataStartDate) } } const minYear = dataFloor !== null ? Math.max(contractFloor, dataFloor) : contractFloor const years: LeaveYearOption[] = [] for (let y = current; 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 = isForfaitContract(employee.value) const leaveYear = selectedLeaveYear.value const from = isForfait ? `${leaveYear}-01-01` : `${leaveYear - 1}-06-01` const to = isForfait ? `${leaveYear}-12-31` : `${leaveYear}-05-31` 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), ...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 } 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 } }