Files
Starseed/frontend/modules/commercial/composables/useSupplier.ts
T
tristan 59f4e33580
Pull Request — Quality gate / Backend (PHP CS + PHPUnit) (pull_request) Successful in 2m27s
Pull Request — Quality gate / Frontend (lint + Vitest + build) (pull_request) Successful in 1m29s
feat(commercial) : amélioration et validation stricte des champs date (ERP-148)
- MalioDate v1.7.10 : exposition de l'état de validité et de la saisie brute
  invalide (@update:valid / @update:rawValue).
- Validation back-autoritaire du format : foundedAt n'accepte plus que l'ISO
  strict Y-m-d (Context DateTimeNormalizer) + collectDenormalizationErrors sur
  Client et Supplier -> toute saisie non-ISO renvoie un 422 porté sur le champ.
- Front : la saisie invalide est transmise au back, le message technique de
  type-error est surchargé par une clé i18n via le code de violation
  (resolveViolationMessage / VIOLATION_MESSAGE_I18N), affiché inline.
- Réorganisation des utils de formulaire sous utils/forms/.
- Tests back (cas piège 12/25/2026) + tests front (résolveur i18n).
2026-06-12 10:39:23 +02:00

72 lines
2.6 KiB
TypeScript

import { ref } from 'vue'
import type { SupplierDetail } from '~/modules/commercial/utils/forms/supplierConsultation'
/**
* Chargement et actions d'archivage d'un fournisseur unique (ecran « Consultation
* fournisseur », ERP-95). Miroir de `useClient` (M1). Lit le detail embarque via
* `GET /api/suppliers/{id}` (contacts / adresses / ribs sous `supplier:item:read` /
* `supplier:read:accounting`) et expose les bascules d'archivage (PATCH `isArchived`
* SEUL — tout autre champ => 422).
*
* L'en-tete `Accept: application/ld+json` est impose pour obtenir le payload
* Hydra complet (sans lui, API Platform 4 renvoie une representation reduite).
*
* Etat 100 % local a l'instance (refs) — aucune persistance URL. Les erreurs
* d'archivage/restauration (notamment le 409 d'homonyme actif a la restauration)
* sont PROPAGEES a l'appelant, qui decide du toast a afficher.
*/
export function useSupplier(id: number | string) {
const api = useApi()
const supplier = ref<SupplierDetail | null>(null)
const loading = ref(false)
const error = ref(false)
/** Recupere le detail complet (embed contacts/adresses/ribs + comptabilite). */
function fetchDetail(): Promise<SupplierDetail> {
return api.get<SupplierDetail>(
`/suppliers/${id}`,
{},
{ headers: { Accept: 'application/ld+json' }, toast: false },
)
}
/** Charge le detail du fournisseur. En cas d'echec : `error = true`, `supplier = null`. */
async function load(): Promise<void> {
loading.value = true
error.value = false
try {
supplier.value = await fetchDetail()
}
catch {
error.value = true
supplier.value = null
}
finally {
loading.value = false
}
}
/**
* Bascule l'archivage (PATCH `isArchived` SEUL — tout autre champ => 422),
* puis RECHARGE le detail complet : la reponse du PATCH ne porte que le groupe
* `supplier:read` (ni l'embed contacts/adresses/ribs ni les libelles des
* referentiels comptables), un simple merge laisserait l'affichage incoherent.
* Toute erreur (notamment le 409 d'homonyme actif a la restauration) est
* propagee a l'appelant AVANT le rechargement.
*/
async function setArchived(isArchived: boolean): Promise<void> {
await api.patch(`/suppliers/${id}`, { isArchived }, { toast: false })
supplier.value = await fetchDetail()
}
return {
supplier,
loading,
error,
load,
archive: () => setArchived(true),
restore: () => setArchived(false),
}
}