fix: Utiliser l'année réelle sélectionnée dans le calendrier au lieu de supposer

Problème: Le système supposait l'année basée sur le contexte, ce qui causait des erreurs.

Solution:
- Ajout de formatDateFrWithYear() pour retourner DD/MM/YYYY
- Le calendrier DatePickerCalendar retourne maintenant des dates avec l'année complète
- parseFrenchedDate() supporte maintenant DD/MM/YYYY et DD/MM
- Si l'année est dans la date (DD/MM/YYYY), elle est utilisée directement
- Plus besoin de supposer l'année basée sur oct/nov/déc -> jan/fev/mar
- Les dates de début et fin se calculent correctement à partir des vraies dates ISO

Cela garantit que:
1. Les dates en janvier 2026 restent bien en 2026
2. Les champs date début/date fin se remplissent avec les bonnes années
3. Aucune supposition erronée n'est faite
This commit is contained in:
odentas 2025-12-19 17:58:33 +01:00
parent ec3d0b3ad7
commit c2a54ecd89
4 changed files with 29 additions and 20 deletions

View file

@ -9,6 +9,7 @@ import {
hasMultipleMoons,
convertIsoDatesToGroups,
formatDateFr,
formatDateFrWithYear,
parseFrenchedDate,
} from "@/lib/dateFormatter";
@ -188,8 +189,8 @@ export default function DatePickerCalendar({
return;
}
// Convertir en format input (DD/MM)
const inputFormat = selectedIsos.map(iso => formatDateFr(iso)).join(", ");
// Convertir en format input avec année (DD/MM/YYYY)
const inputFormat = selectedIsos.map(iso => formatDateFrWithYear(iso)).join(", ");
// Détecter multi-mois
const isMultiMonth = hasMultipleMoons(selectedIsos);

View file

@ -607,7 +607,8 @@ export function NouveauCDDUForm({
// Si un nombre global est fourni, l'utiliser; sinon utiliser la somme des quantités; sinon calculer le nombre de dates
const quantity = result.globalQuantity || result.totalQuantities || result.selectedDates.length;
// Convertir les dates sélectionnées en ISO (result.selectedDates sont au format "12/10, 13/10...")
// Convertir les dates sélectionnées en ISO
// Les dates viennent maintenant du calendrier au format DD/MM/YYYY, donc pas besoin de yearContext
const currentYearContext = dateDebut || new Date().toISOString().slice(0, 10);
const currentIsos = result.selectedDates
.map(d => parseFrenchedDate(d.trim(), currentYearContext))

View file

@ -31,30 +31,37 @@ export function formatDateFr(isoStr: string): string {
}
/**
* Convertit une date française (DD/MM) en ISO (YYYY-MM-DD)
* Nécessite l'année de contexte
*
* Logique intelligente : si le mois de la date est janvier/février/mars (1-3)
* et que le mois du contexte est octobre/novembre/décembre (10-12),
* on suppose que c'est l'année suivante.
* Formate une date ISO (YYYY-MM-DD) en format français avec année (DD/MM/YYYY)
*/
export function formatDateFrWithYear(isoStr: string): string {
if (!isoStr || isoStr.length < 10) return "";
const [year, month, day] = isoStr.split("-");
return `${day}/${month}/${year}`;
}
/**
* Convertit une date française (DD/MM ou DD/MM/YYYY) en ISO (YYYY-MM-DD)
* Si l'année est fournie dans frStr, elle est utilisée
* Sinon, nécessite l'année de contexte
*/
export function parseFrenchedDate(frStr: string, yearContext: string): string {
const cleaned = frStr.trim();
if (!cleaned || !cleaned.includes("/")) return "";
const [day, month] = cleaned.split("/");
if (!day || !month) return "";
const parts = cleaned.split("/");
let year = yearContext.split("-")[0];
const monthNum = parseInt(month, 10);
const contextMonthNum = parseInt(yearContext.split("-")[1], 10);
// Si la date est en janvier/février/mars ET que le contexte est en oct/nov/déc
// alors c'est probablement l'année suivante
if (monthNum >= 1 && monthNum <= 3 && contextMonthNum >= 10 && contextMonthNum <= 12) {
year = String(parseInt(year, 10) + 1);
// Format DD/MM/YYYY
if (parts.length === 3) {
const [day, month, year] = parts;
if (!day || !month || !year) return "";
return `${year}-${month.padStart(2, "0")}-${day.padStart(2, "0")}`;
}
// Format DD/MM - utiliser le contexte
const [day, month] = parts;
if (!day || !month) return "";
const year = yearContext.split("-")[0];
return `${year}-${month.padStart(2, "0")}-${day.padStart(2, "0")}`;
}

File diff suppressed because one or more lines are too long