Files
Starseed/frontend/modules/commercial/composables/useSupplier.ts
T
tristan 5722912413 feat(front) : page Consultation fournisseur (/suppliers/{id}) lecture seule (ERP-95)
- useSupplier(id) : GET /api/suppliers/{id} en Hydra (embed contacts/adresses/ribs
  + scalaires compta si accounting.view), archive()/restore() via PATCH isArchived seul
- supplierConsultation : mappers purs de l'embed (addressType, bennes, triageProvider,
  volumeForecast ; gating compta par omission de cle), helpers de permissions
- page [id]/index.vue : lecture seule, bloc principal + onglets (Information/Contacts/
  Adresses/Comptabilite selon permission/4 coquilles A venir), Modifier/Archiver/Restaurer,
  fleche retour repertoire ; miroir de l'ecran Consultation client (M1)
- tests Vitest : supplierConsultation (mappers + permissions) + useSupplier (GET/PATCH)
2026-06-11 08:13:35 +02:00

72 lines
2.6 KiB
TypeScript

import { ref } from 'vue'
import type { SupplierDetail } from '~/modules/commercial/utils/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),
}
}