/** * Helpers purs de l'onglet Prix transporteur (M4 Transport, ERP-169 — RG-4.09→4.11). * Une ligne porte une branche CLIENT ou FOURNISSEUR selon `direction` ; les champs * de la branche INACTIVE doivent toujours partir à null (CHECK BDD * chk_carrier_price_client_branch / supplier_branch). Testables sans Vue ni API. */ import type { CarrierPriceFormDraft } from '~/modules/transport/types/carrierForm' /** Vrai si une chaîne porte au moins un caractère non-espace. */ function isFilled(value: string | null | undefined): boolean { return value !== null && value !== undefined && value.trim() !== '' } /** * Payload de la sous-ressource prix (groupe `carrier:write:prices`). Envoie les * communs + UNIQUEMENT la branche active (l'autre branche à null, exigée par les * CHECK BDD). Les relations partent en IRI (string|null). Le back re-valide * l'obligation conditionnelle + l'appartenance de l'adresse (422 inline). */ export function buildCarrierPricePayload(price: CarrierPriceFormDraft): Record { const common: Record = { direction: price.direction, containerType: price.containerType || null, pricingUnit: price.pricingUnit || null, price: price.price || null, priceState: price.priceState || null, } if (price.direction === 'CLIENT') { return { ...common, client: price.clientIri || null, clientDeliveryAddress: price.clientDeliveryAddressIri || null, departureSite: price.departureSiteIri || null, // Branche FOURNISSEUR forcée à null (CHECK chk_carrier_price_client_branch). supplier: null, supplierSupplyAddress: null, deliverySite: null, } } if (price.direction === 'FOURNISSEUR') { return { ...common, supplier: price.supplierIri || null, supplierSupplyAddress: price.supplierSupplyAddressIri || null, deliverySite: price.deliverySiteIri || null, // Branche CLIENT forcée à null (CHECK chk_carrier_price_supplier_branch). client: null, clientDeliveryAddress: null, departureSite: null, } } // Direction non choisie : on envoie les communs ; le back 422 sur `direction`. return common } /** * Pré-check léger du gating « + Nouveau prix » : direction choisie, prix rempli, et * branche active complète (client/adresse/site OU fournisseur/adresse/site). Le back * reste la couche autoritaire (RG-4.09→4.11) ; ce pré-check évite d'empiler des * blocs vides. */ export function isCarrierPriceValid(price: CarrierPriceFormDraft): boolean { if (!isFilled(price.price) || !isFilled(price.containerType) || !isFilled(price.pricingUnit) || !isFilled(price.priceState)) { return false } if (price.direction === 'CLIENT') { return isFilled(price.clientIri) && isFilled(price.clientDeliveryAddressIri) && isFilled(price.departureSiteIri) } if (price.direction === 'FOURNISSEUR') { return isFilled(price.supplierIri) && isFilled(price.supplierSupplyAddressIri) && isFilled(price.deliverySiteIri) } return false }