export const CONTRACT_NATURES = ['CDI', 'CDD', 'INTERIM'] as const export type ContractNature = (typeof CONTRACT_NATURES)[number] export const contractNatureLabel = (value?: ContractNature) => { if (value === 'CDD') return 'CDD' if (value === 'INTERIM') return 'Intérim' return 'CDI' } export const showsContractEndDate = (nature: ContractNature) => { return nature === 'CDD' || nature === 'INTERIM' } export const requiresContractEndDate = (nature: ContractNature) => { return nature === 'CDD' || nature === 'INTERIM' } export const isContractNature = (value: string): value is ContractNature => { return (CONTRACT_NATURES as readonly string[]).includes(value) } /** * Whether a contract + nature pair requires the per-day schedule (workDaysHours). * Mirrors EmployeeContractPeriodValidator::assertWorkDaysHours on the backend. */ export const requiresWorkDaysHours = ( contract: { trackingMode?: string | null; weeklyHours?: number | null } | null | undefined, nature: ContractNature ): boolean => { if (!contract) return false if (nature === 'INTERIM') return false if (contract.trackingMode === 'PRESENCE') return false if (contract.weeklyHours === 35 || contract.weeklyHours === 39) return false return true } const DAY_SHORT_LABELS: Record = { 1: 'Lun', 2: 'Mar', 3: 'Mer', 4: 'Jeu', 5: 'Ven' } /** * Compact human-readable summary of a per-day schedule, e.g. "Lun 2h, Jeu 2h". * Returns null when the schedule is empty/unset. */ export const formatWorkDaysHoursSummary = ( workDaysHours: Record | null | undefined ): string | null => { if (!workDaysHours) return null const entries = Object.entries(workDaysHours) .map(([iso, minutes]) => [Number(iso), Number(minutes)] as const) .filter(([iso, minutes]) => iso >= 1 && iso <= 5 && minutes > 0) .sort(([a], [b]) => a - b) if (entries.length === 0) return null return entries .map(([iso, minutes]) => { const h = Math.floor(minutes / 60) const m = minutes % 60 const suffix = m === 0 ? `${h}h` : `${h}h${String(m).padStart(2, '0')}` return `${DAY_SHORT_LABELS[iso]} ${suffix}` }) .join(', ') }