Lot de correctifs sur l'écran Client (M1), + un retrait de règle métier et une petite fonctionnalité. ## Formulaire client (création / édition) - Boutons « ajouter un bloc » (Adresse, RIB) désactivés tant que le dernier bloc n'est pas valide. - Onglet Information : bouton Valider désactivé si aucun champ rempli (création) ; onglet Contact accessible dès la création (Information facultatif). - Champs « Relation » (Distributeur/Courtier) et « Prestation de triage » masqués par défaut, révélés seulement si une catégorie ordinaire (≠ Distributeur/Courtier) est sélectionnée. - Bloc RIB affiché uniquement si le type de règlement est LCR (création, édition, consultation) ; plus de RIB fantôme soumis. - Alignement du bas du textarea « Description » sur les autres champs. ## Recherche d'adresse (BAN) - Une erreur de l'API ne bloque plus définitivement la recherche : chaque frappe réessaie (le mode dégradé restait verrouillé). - Garde minimum 3 caractères avant l'appel à l'API. ## Répertoire client - Titres de colonne en noir 16px, corps + tags de site en 14px. ## Navigation - L'onglet actif est conservé au passage consultation ↔ édition (via history.state, hors URL). ## Règle métier - Retrait de RG-1.04 : l'onglet Information n'est plus obligatoire pour le rôle Commerciale — facultatif pour tous (back + tests + docs). Tests : suites front (Vitest) et back (PHPUnit) vertes hormis flakes d'infra connus. Reviewed-on: #76 Co-authored-by: tristan <tristan@yuno.malio.fr> Co-committed-by: tristan <tristan@yuno.malio.fr>
This commit was merged in pull request #76.
This commit is contained in:
@@ -7,14 +7,19 @@ import {
|
||||
canSelectDeliveryOrBilling,
|
||||
canSelectProspect,
|
||||
hasAllRequiredAccountingFields,
|
||||
hasAtLeastOneInformationField,
|
||||
hasAtLeastOneValidContact,
|
||||
isAddressValid,
|
||||
isBankRequiredForPaymentType,
|
||||
isBillingEmailRequired,
|
||||
isBlankRow,
|
||||
isContactBlank,
|
||||
isContactNamed,
|
||||
isRibBlank,
|
||||
isRibComplete,
|
||||
isRibRequiredForPaymentType,
|
||||
showsRelationAndTriageFields,
|
||||
type AddressValidityDraft,
|
||||
type ContactDraft,
|
||||
type ContactFillableDraft,
|
||||
} from '../clientFormRules'
|
||||
@@ -271,3 +276,96 @@ describe('hasAllRequiredAccountingFields (RG-1.30)', () => {
|
||||
})).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('showsRelationAndTriageFields (affichage Relation + Triage selon categorie)', () => {
|
||||
it('faux par defaut (aucune categorie selectionnee)', () => {
|
||||
expect(showsRelationAndTriageFields([])).toBe(false)
|
||||
})
|
||||
|
||||
it('faux si seules des categories Distributeur / Courtier sont selectionnees', () => {
|
||||
expect(showsRelationAndTriageFields(['DISTRIBUTEUR'])).toBe(false)
|
||||
expect(showsRelationAndTriageFields(['COURTIER'])).toBe(false)
|
||||
expect(showsRelationAndTriageFields(['DISTRIBUTEUR', 'COURTIER'])).toBe(false)
|
||||
})
|
||||
|
||||
it('vrai des qu\'une categorie ordinaire est selectionnee', () => {
|
||||
expect(showsRelationAndTriageFields(['CLIENT'])).toBe(true)
|
||||
expect(showsRelationAndTriageFields(['DISTRIBUTEUR', 'CLIENT'])).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('hasAtLeastOneInformationField (pas de validation a vide a la creation)', () => {
|
||||
const blank = {
|
||||
description: null,
|
||||
competitors: null,
|
||||
foundedAt: null,
|
||||
employeesCount: null,
|
||||
revenueAmount: null,
|
||||
profitAmount: null,
|
||||
directorName: null,
|
||||
}
|
||||
|
||||
it('faux quand aucun champ n\'est rempli (onglet vierge)', () => {
|
||||
expect(hasAtLeastOneInformationField(blank)).toBe(false)
|
||||
expect(hasAtLeastOneInformationField({ ...blank, description: ' ' })).toBe(false)
|
||||
})
|
||||
|
||||
it('vrai des qu\'un champ porte une valeur', () => {
|
||||
expect(hasAtLeastOneInformationField({ ...blank, description: 'Acteur majeur' })).toBe(true)
|
||||
expect(hasAtLeastOneInformationField({ ...blank, employeesCount: '42' })).toBe(true)
|
||||
expect(hasAtLeastOneInformationField({ ...blank, foundedAt: '2020-01-01' })).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('isAddressValid (gating « + Adresse » + validation onglet)', () => {
|
||||
/** Adresse de livraison valide (type + site + categorie ; pas de facturation). */
|
||||
function validDelivery(): AddressValidityDraft {
|
||||
return {
|
||||
isProspect: false,
|
||||
isDelivery: true,
|
||||
isBilling: false,
|
||||
categoryIris: ['/api/client_categories/1'],
|
||||
siteIris: ['/api/sites/1'],
|
||||
billingEmail: null,
|
||||
}
|
||||
}
|
||||
|
||||
it('vrai quand type + >= 1 site + >= 1 categorie (sans facturation)', () => {
|
||||
expect(isAddressValid(validDelivery())).toBe(true)
|
||||
})
|
||||
|
||||
it('faux si aucun drapeau (type d\'adresse non renseigne, amorce vierge)', () => {
|
||||
expect(isAddressValid({ ...validDelivery(), isDelivery: false })).toBe(false)
|
||||
})
|
||||
|
||||
it('faux si aucun site (RG-1.10)', () => {
|
||||
expect(isAddressValid({ ...validDelivery(), siteIris: [] })).toBe(false)
|
||||
})
|
||||
|
||||
it('faux si aucune categorie', () => {
|
||||
expect(isAddressValid({ ...validDelivery(), categoryIris: [] })).toBe(false)
|
||||
})
|
||||
|
||||
it('RG-1.11 : email de facturation obligatoire quand l\'adresse est de facturation', () => {
|
||||
const billing: AddressValidityDraft = { ...validDelivery(), isBilling: true }
|
||||
expect(isAddressValid({ ...billing, billingEmail: null })).toBe(false)
|
||||
expect(isAddressValid({ ...billing, billingEmail: ' ' })).toBe(false)
|
||||
expect(isAddressValid({ ...billing, billingEmail: 'facture@acme.fr' })).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('isRibComplete (gating « + RIB » + RG-1.13)', () => {
|
||||
it('vrai quand label + BIC + IBAN sont remplis', () => {
|
||||
expect(isRibComplete({ label: 'Compte courant', bic: 'BNPAFRPP', iban: 'FR1420041010050500013M02606' })).toBe(true)
|
||||
})
|
||||
|
||||
it('faux si un champ manque (null ou vide apres trim)', () => {
|
||||
expect(isRibComplete({ label: null, bic: 'BNPAFRPP', iban: 'FR14...' })).toBe(false)
|
||||
expect(isRibComplete({ label: 'Compte', bic: ' ', iban: 'FR14...' })).toBe(false)
|
||||
expect(isRibComplete({ label: 'Compte', bic: 'BNPAFRPP', iban: null })).toBe(false)
|
||||
})
|
||||
|
||||
it('faux pour un bloc totalement vide (amorce)', () => {
|
||||
expect(isRibComplete({ label: null, bic: null, iban: null })).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user