Files
SIRH/frontend/utils/contract.ts
tristan 1fe7f2cdde
Some checks failed
Auto Tag Develop / tag (push) Has been cancelled
feat : agence d'intérim sur les contrats INTERIM + renommage Types d'absence en Types de statut + colonne Absence en Statut
- Nouvelle entité InterimAgency (table interim_agencies, API lecture seule)
- Sélecteur agence conditionnel dans les formulaires création employé et ajout contrat
- Affichage "Intérim (NomAgence)" sur la liste employés et l'historique contrat
- Date de fin obligatoire côté frontend pour CDD et INTERIM (aligné backend)
- Renommage "Types d'absence" → "Types de statut" (sidebar, page, titre)
- Renommage en-tête "Absence" → "Statut" sur les vues jour heures et conducteurs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 11:47:14 +02:00

62 lines
2.1 KiB
TypeScript

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<number, string> = { 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<number, number> | 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(', ')
}