faafd99ef8
Auto Tag Develop / tag (push) Successful in 8s
MR unique regroupant tout le module M5 « Tickets de pesée » (remplace les MR empilées #140/#141/#142/#143).
## Périmètre
- **ERP-188** — Page liste des tickets de pesée + export XLSX (colonnes Fournisseur/Client/Autre + Statut).
- **ERP-189** — Écran « Ajouter » (4 champs en haut, 2 blocs de pesée, pesée bascule/manuelle, date+heure horodatée à la validation).
- **ERP-190** — Écran « Modifier » + bouton Imprimer.
- **ERP-191** — i18n + libellés + branchement site courant.
- **ERP-192** — Bon de pesée PDF généré côté back (template Twig → Dompdf), endpoint `GET /api/weighing_tickets/{id}/print.pdf`.
- **ERP-193** — Cycle de vie brouillon/validé (status DRAFT/VALIDATED, numéro attribué à la validation), DSD saisi conservé en pesée manuelle, retours métier design.
## Vérifications
- Back : tests Logistique + architecture verts, php-cs-fixer propre, migrations appliquées (dev + test).
- Front : suite Vitest complète verte, ESLint propre.
Base : `develop` — contient les 16 commits du M5 (rien d'autre).
Reviewed-on: #144
Co-authored-by: tristan <tristan@yuno.malio.fr>
Co-committed-by: tristan <tristan@yuno.malio.fr>
52 lines
2.1 KiB
TypeScript
52 lines
2.1 KiB
TypeScript
/**
|
|
* Helpers de date purs / testables (partages inter-modules).
|
|
*/
|
|
|
|
/**
|
|
* Date du jour au format ISO `YYYY-MM-DD` en heure LOCALE.
|
|
*
|
|
* On NE passe PAS par `toISOString()` (UTC) : pres de minuit, le decalage de
|
|
* fuseau (FR = UTC+1/+2) renverrait la veille ou le lendemain. On lit donc les
|
|
* composantes locales. Parametre `now` injectable pour les tests.
|
|
*/
|
|
export function todayIso(now: Date = new Date()): string {
|
|
const year = now.getFullYear()
|
|
const month = String(now.getMonth() + 1).padStart(2, '0')
|
|
const day = String(now.getDate()).padStart(2, '0')
|
|
return `${year}-${month}-${day}`
|
|
}
|
|
|
|
/**
|
|
* Date-heure courante au format ISO LOCAL `YYYY-MM-DDTHH:mm:ss` (sans fuseau).
|
|
*
|
|
* C'est le format attendu par `MalioDateTime` (secondes incluses, pas d'offset
|
|
* horaire). Comme `todayIso`, on lit les composantes LOCALES (jamais
|
|
* `toISOString()`/UTC) pour ne pas décaler l'heure réelle. Paramètre `now`
|
|
* injectable pour les tests.
|
|
*/
|
|
export function nowIsoDateTime(now: Date = new Date()): string {
|
|
const hours = String(now.getHours()).padStart(2, '0')
|
|
const minutes = String(now.getMinutes()).padStart(2, '0')
|
|
const seconds = String(now.getSeconds()).padStart(2, '0')
|
|
return `${todayIso(now)}T${hours}:${minutes}:${seconds}`
|
|
}
|
|
|
|
/**
|
|
* Date courte française `JJ-MM-AAAA` à partir d'une valeur ISO (`YYYY-MM-DD` ou
|
|
* datetime `YYYY-MM-DDTHH:mm:ss±HH:mm`). Chaîne vide si absente ou non ISO.
|
|
*
|
|
* On lit les composantes DIRECTEMENT dans la chaîne (10 premiers caractères) au
|
|
* lieu de `new Date(value).getDate()` : un datetime porteur d'un offset (ex.
|
|
* `…T00:30:00+02:00`, ou `…Z`) basculerait d'un jour selon le fuseau du
|
|
* navigateur / du runner CI. Rendu ainsi déterministe et cohérent avec l'écran
|
|
* d'édition (slice de la chaîne brute) et l'export serveur (`format('d/m/Y')`).
|
|
*/
|
|
export function formatDateFr(value: string | null | undefined): string {
|
|
const match = value ? /^(\d{4})-(\d{2})-(\d{2})/.exec(value) : null
|
|
if (!match) {
|
|
return ''
|
|
}
|
|
const [, year, month, day] = match
|
|
return `${day}-${month}-${year}`
|
|
}
|