477f77a6b5
Auto Tag Develop / tag (push) Successful in 7s
## ERP-95 — Consultation fournisseur (lecture seule) Étape 6/7 (front). Dépend de #92 (contrat JSON figé) et #94 (blocs/types fournisseur). Bloque #96. > ⚠️ MR **stackée sur `feature/ERP-94-suppliers-new`** (ERP-94 pas encore mergée dans develop) pour garder le diff limité aux 5 fichiers d'ERP-95. À recibler sur `develop` une fois la 94 mergée. Squash au merge. ### Périmètre - `useSupplier(id)` : GET /api/suppliers/{id} en Hydra (embed contacts/adresses/ribs + scalaires compta si `accounting.view`), `archive()`/`restore()` via PATCH `isArchived` seul + rechargement complet. - `supplierConsultation` : mappers purs de l'embed (enum `addressType`, `bennes`/`triageProvider`, `volumeForecast`, gating compta par **omission de clé** → null) + helpers de permissions. - Page `[id]/index.vue` lecture seule : bloc principal + onglets Information / Contacts / Adresses / Comptabilité (si permission) / 4 coquilles « À venir » ; boutons Modifier (`manage`), Archiver/Restaurer (`archive`) ; flèche retour → répertoire. Miroir de l'écran Consultation client (M1). ### Tests - Vitest : `supplierConsultation.spec.ts` (mappers + permissions, gating compta) + `useSupplier.spec.ts` (GET/PATCH + propagation 403/409). `make nuxt-test` → 365/365 ✅. ESLint ✅. - `nuxi typecheck` non lancé sur l'hôte (régénère .nuxt/tailwind en chemins hôte et casse le conteneur dev-nuxt). Reviewed-on: #84 Co-authored-by: tristan <tristan@yuno.malio.fr> Co-committed-by: tristan <tristan@yuno.malio.fr>
72 lines
2.6 KiB
TypeScript
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),
|
|
}
|
|
}
|