/** * Helpers purs de l'onglet Contact transporteur (M4 Transport, ERP-168) — miroir * de `providerContact.ts` (M3), avec deux spécificités M4 : * - RG-4.08 : un bloc est valide dès qu'AU MOINS UN champ est rempli (n'importe * lequel) — ≠ M3 qui n'exigeait que le nom. * - les téléphones partent au back dans le tableau virtuel `phones` (max 2), * pas en `phonePrimary` / `phoneSecondary` (mappés par le CarrierContactProcessor). * Testables sans Vue ni API. */ import type { CarrierContactFormDraft } 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() !== '' } /** * RG-4.08 : un bloc Contact est VIDE tant qu'aucun de ses champs n'est rempli * (prénom / nom / fonction / téléphone(s) / email). Sert le gating « + Nouveau * contact » (on n'ajoute pas de bloc tant que le précédent est vide) et reflète la * garde back (CarrierContactProcessor + CHECK chk_carrier_contact_filled). */ export function isCarrierContactBlank(contact: CarrierContactFormDraft): boolean { return ![ contact.firstName, contact.lastName, contact.jobTitle, contact.phonePrimary, contact.phoneSecondary, contact.email, ].some(isFilled) } /** * Payload de la sous-ressource contacts (groupe `carrier:write:contacts`). Les * chaînes vides partent à null (le serveur normalise/trim). Les téléphones sont * regroupés dans le tableau `phones` (numéros non vides, max 2 — RG-4.08) ; le 2e * numéro n'est inclus que s'il a été révélé (`hasSecondaryPhone`). */ export function buildCarrierContactPayload(contact: CarrierContactFormDraft): Record { const phones = [ contact.phonePrimary, contact.hasSecondaryPhone ? contact.phoneSecondary : null, ].filter((phone): phone is string => isFilled(phone)) return { firstName: contact.firstName || null, lastName: contact.lastName || null, jobTitle: contact.jobTitle || null, email: contact.email || null, phones, } }