Files
Starseed/frontend/modules/logistique/composables/useWeighbridge.ts
T

75 lines
3.0 KiB
TypeScript

/**
* Pesée au pont bascule (M5, ERP-189) — déclenche une lecture de poids via
* `POST /api/weighbridge_readings` (spec-back § 4.2). Action autonome : le ticket
* n'existe pas encore quand on pèse depuis le formulaire principal.
*
* Deux modes :
* - AUTO (« Pesée bascule ») : le serveur résout le site courant, lit le poids
* (stub aléatoire au M5) et alloue le DSD. Peut échouer (RG-5.06 → 503) : le
* pont est indisponible, on invite l'utilisateur à passer en pesée manuelle.
* - MANUAL (« Pesée manuelle ») : poids + numéro de pesée saisis ; le serveur
* calcule le DSD = dernier + 1 (RG-5.04).
*
* Composable UI-agnostique : il appelle l'API (`useApi`, jamais `$fetch`) et
* renvoie la lecture, ou lève l'erreur — la gestion de la modal/de l'affichage
* reste à la charge de l'écran. `extractWeighbridgeError` factorise la lecture
* du message d'erreur 503 (RG-5.06) pour l'afficher dans la modal.
*/
/** Mode de pesée — miroir de l'enum back. */
export type WeighbridgeMode = 'AUTO' | 'MANUAL'
/** Lecture renvoyée par le pont bascule (spec-back § 4.2). */
export interface WeighbridgeReading {
weight: number
dsd: number
mode: WeighbridgeMode
/** Numéro de pesée saisi en mode MANUAL (absent en AUTO). */
manualNumber?: string
}
export function useWeighbridge() {
const api = useApi()
const { t } = useI18n()
/**
* Pesée bascule (AUTO). Le site courant est résolu serveur — rien à envoyer.
* `toast: false` : l'erreur (RG-5.06) est affichée inline dans la modal, pas
* en toast global.
*/
async function triggerAuto(): Promise<WeighbridgeReading> {
return await api.post<WeighbridgeReading>(
'/weighbridge_readings',
{ mode: 'AUTO' },
{ toast: false },
)
}
/**
* Pesée manuelle (MANUAL). Le DSD est calculé serveur (dernier + 1, RG-5.04) ;
* le `manualNumber` est la référence du ticket papier / autre bascule.
*/
async function triggerManual(weight: number, manualNumber: string): Promise<WeighbridgeReading> {
return await api.post<WeighbridgeReading>(
'/weighbridge_readings',
{ mode: 'MANUAL', weight, manualNumber },
{ toast: false },
)
}
/**
* Message d'erreur de pesée bascule (RG-5.06). Le back renvoie un 503
* `{ title, detail }` (« Pont bascule indisponible » / « Passez en pesée
* manuelle. ») — on privilégie le `detail`, puis le `title`, sinon un libellé
* générique invitant à la pesée manuelle.
*/
function extractWeighbridgeError(error: unknown): string {
const data = (error as { response?: { _data?: unknown } })?.response?._data as
| { detail?: string, title?: string }
| undefined
return data?.detail || data?.title || t('logistique.weighingTickets.form.weighbridge.unavailable')
}
return { triggerAuto, triggerManual, extractWeighbridgeError }
}