/** * Helpers purs de l'onglet Contact transporteur (M4 Transport, ERP-168). ERP-193 * (retour métier) : l'onglet Contact n'est plus obligatoire — la règle « prénom OU * nom » est retirée. Le gating « + Nouveau contact » repose désormais sur « le * dernier bloc n'est pas vide » (et non plus « nommé »). Spécificité M4 conservée : * les téléphones partent au back dans le tableau virtuel `phones` (max 2), 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() !== '' } /** * Un bloc Contact est VIDE tant qu'aucun champ comptant pour la validité n'est * rempli — prénom / nom / fonction / téléphone principal / email. `phoneSecondary` * est EXCLU (aligné M1/M2/M3 : un bloc ne portant qu'un 2e numéro reste vide). Sert * le filtrage des amorces vides à la soumission. */ export function isCarrierContactBlank(contact: CarrierContactFormDraft): boolean { return ![ contact.firstName, contact.lastName, contact.jobTitle, contact.phonePrimary, 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, } }