c1e45cd582
Auto Tag Develop / tag (push) Successful in 8s
Empilée sur ERP-141 (#103). ## Périmètre ERP-142 Onglet **Contact** de l'écran `/providers/new` — saisie multi-contacts (blocs ajoutables) via la sous-ressource contacts. - **`ProviderContactBlock.vue`** (miroir `SupplierContactBlock`) : Nom / Prénom / Fonction / Email / Téléphone (x1, +1 révélable, **max 2**), erreurs 422 par champ (prop `:errors`). - **`useProviderForm`** étendu : état `contacts`, `canAddContact` (RG-3.04), `addContact`/`removeContact`, `submitContacts` (POST `/providers/{id}/contacts` pour les nouveaux, PATCH `/provider_contacts/{id}` pour les existants, groupe `provider:write:contacts`), `submitRows` (erreurs collectées **par ligne**, non bloquant). - **RG-3.04** : « + Nouveau contact » désactivé tant que le bloc courant est vide (≥1 champ parmi prénom/nom/fonction/tél/email — aligné back). - **RG-3.12** : onglet non validable vide ; une amorce vide est soumise pour déclencher la 422 `firstName` inline. - Suppression d'un bloc → modal de confirmation. - Helpers purs `utils/forms/providerContact.ts` (`isProviderContactBlank`, `buildProviderContactPayload`). - i18n `technique.providers.form.contact/confirmDelete` + `toast.updateSuccess`. ## Vérifications - Vitest : 418/418 (16 nouveaux : helpers, bloc, workflow contacts). - ESLint : OK. - `nuxi typecheck` : 0 erreur sur les fichiers source du ticket. - Golden path navigateur : bloc Contact rendu, « Nouveau contact » désactivé tant que vide puis activé après saisie, révélation du 2e téléphone (max 2). Reviewed-on: #104 Co-authored-by: tristan <tristan@yuno.malio.fr> Co-committed-by: tristan <tristan@yuno.malio.fr>
58 lines
2.2 KiB
TypeScript
58 lines
2.2 KiB
TypeScript
/**
|
|
* Helpers purs de l'onglet Contact prestataire (M3 Technique, ERP-142) — miroir
|
|
* reduit de `supplierFormRules.ts` / `supplierEdit.ts` (M2). Testables sans Vue
|
|
* ni API : detection de bloc vide (RG-3.04) et construction du payload de
|
|
* sous-ressource contacts.
|
|
*/
|
|
|
|
import type { ProviderContactFormDraft } from '~/modules/technique/types/providerForm'
|
|
|
|
/** Vrai si une chaine porte au moins un caractere non-espace. */
|
|
function isFilled(value: string | null | undefined): boolean {
|
|
return value !== null && value !== undefined && value.trim() !== ''
|
|
}
|
|
|
|
/**
|
|
* RG-3.04 : un bloc Contact est VIDE tant qu'aucun des champs comptant pour la
|
|
* validite n'est rempli — prenom / nom / fonction / telephone principal / email.
|
|
*
|
|
* `phoneSecondary` est volontairement EXCLU : le back (CHECK
|
|
* `chk_provider_contact_name` + `ProviderContactProcessor`) ne le compte pas non
|
|
* plus, un bloc ne portant qu'un 2e numero reste invalide. Garder la meme
|
|
* definition cote front evite tout drift (un bloc « vide » front == bloc rejete
|
|
* back).
|
|
*/
|
|
export function isProviderContactBlank(contact: ProviderContactFormDraft): boolean {
|
|
return ![
|
|
contact.firstName,
|
|
contact.lastName,
|
|
contact.jobTitle,
|
|
contact.phonePrimary,
|
|
contact.email,
|
|
].some(isFilled)
|
|
}
|
|
|
|
/**
|
|
* RG-3.12 : l'onglet Contact ne peut etre finalise que s'il reste au moins un
|
|
* bloc non vide (au moins un contact valide).
|
|
*/
|
|
export function hasAtLeastOneFilledContact(contacts: ProviderContactFormDraft[]): boolean {
|
|
return contacts.some(contact => !isProviderContactBlank(contact))
|
|
}
|
|
|
|
/**
|
|
* Payload de la sous-ressource contacts (groupe `provider:write:contacts`). Les
|
|
* chaines vides sont envoyees a null (le serveur normalise/trim de toute facon).
|
|
* `phoneSecondary` n'est envoye que si le 2e numero a ete revele (max 2 tel).
|
|
*/
|
|
export function buildProviderContactPayload(contact: ProviderContactFormDraft): Record<string, unknown> {
|
|
return {
|
|
firstName: contact.firstName || null,
|
|
lastName: contact.lastName || null,
|
|
jobTitle: contact.jobTitle || null,
|
|
phonePrimary: contact.phonePrimary || null,
|
|
phoneSecondary: contact.hasSecondaryPhone ? (contact.phoneSecondary || null) : null,
|
|
email: contact.email || null,
|
|
}
|
|
}
|