fix(commercial) : conserver le RIB au changement de type de règlement hors-LCR (ERP-121) (#86)
Auto Tag Develop / tag (push) Successful in 11s

## Contexte — ERP-121

Le passage d'un tiers de **LCR** vers **virement** (ou autre) supprimait ses RIB en base : au changement de type de règlement, le front marquait les `ClientRib` / `SupplierRib` existants pour suppression puis envoyait des `DELETE`. Le métier veut **conserver** le RIB (coordonnée bancaire du tiers, découplée du mode de règlement) pour un éventuel retour en LCR.

## Décisions métier (validées)

1. **Affichage hors-LCR** : RIB **totalement masqué**, ré-affiché au retour LCR — jamais supprimé en base.
2. **RGPD / IBAN** : conservation telle quelle, hors-scope de ce ticket.
3. **Données déjà perdues** : acceptable, le fix ne vaut que pour l'avenir.

## Modifications (100% frontend — clients **et** fournisseurs)

- `new.vue` / `[id]/edit.vue` : `onPaymentTypeChange` ne marque plus les RIB pour suppression et ne jette plus la saisie ; ils sont seulement masqués (`visibleRibs`) et réapparaissent au retour LCR.
- `submitAccounting` ne (re)soumet les RIB que **sous LCR** ; seules les suppressions **explicites** (corbeille d'un bloc) restent en `DELETE`.
- Consultation `[id]/index.vue` : RIB dormants masqués hors-LCR via le helper pur type-safe `paymentTypeCodeOf` (+ tests Vitest).

## Back

**Aucune modification** : la seule règle est `LCR → ≥1 RIB` (RG-1.13 / RG-2.08) ; rien n'interdit un RIB sur un tiers non-LCR. Le guard `Client/SupplierRibProcessor` (refus de supprimer le dernier RIB sous LCR) reste inchangé. **Pas de migration.**

## Vérifications

-  Vitest : **384/384** (`make nuxt-test`)
-  ESLint : clean sur les 10 fichiers
- ⏭️ PHPUnit non lancé : aucun fichier back modifié

Reviewed-on: #86
Co-authored-by: tristan <tristan@yuno.malio.fr>
Co-committed-by: tristan <tristan@yuno.malio.fr>
This commit was merged in pull request #86.
This commit is contained in:
2026-06-11 10:05:40 +00:00
committed by Autin
parent 431d831c8b
commit a442d124a3
10 changed files with 252 additions and 147 deletions
@@ -9,6 +9,7 @@ import {
mapAddressView,
mapContactToDraft,
mapRibToDraft,
paymentTypeCodeOf,
referentialOptionOf,
relationOf,
showArchiveAction,
@@ -233,3 +234,17 @@ describe('showArchiveAction / showRestoreAction', () => {
expect(showRestoreAction(can([]), true)).toBe(false)
})
})
describe('paymentTypeCodeOf (ERP-121 : RIB masques hors-LCR en consultation)', () => {
it('retourne le code metier quand le type de reglement est embarque', () => {
expect(paymentTypeCodeOf({ '@id': '/api/payment_types/1', code: 'LCR' })).toBe('LCR')
expect(paymentTypeCodeOf({ '@id': '/api/payment_types/2', code: 'VIREMENT' })).toBe('VIREMENT')
})
it('retourne null pour un IRI nu, un objet sans code, ou une relation absente', () => {
expect(paymentTypeCodeOf('/api/payment_types/1')).toBeNull()
expect(paymentTypeCodeOf({ '@id': '/api/payment_types/1' })).toBeNull()
expect(paymentTypeCodeOf(null)).toBeNull()
expect(paymentTypeCodeOf(undefined)).toBeNull()
})
})
@@ -9,6 +9,7 @@ import {
mapAddressView,
mapContactToDraft,
mapRibToDraft,
paymentTypeCodeOf,
referentialOptionOf,
showArchiveAction,
showRestoreAction,
@@ -222,3 +223,17 @@ describe('showArchiveAction / showRestoreAction', () => {
expect(showRestoreAction(can([]), true)).toBe(false)
})
})
describe('paymentTypeCodeOf (ERP-121 : RIB masques hors-LCR en consultation)', () => {
it('retourne le code metier quand le type de reglement est embarque', () => {
expect(paymentTypeCodeOf({ '@id': '/api/payment_types/1', code: 'LCR' })).toBe('LCR')
expect(paymentTypeCodeOf({ '@id': '/api/payment_types/2', code: 'VIREMENT' })).toBe('VIREMENT')
})
it('retourne null pour un IRI nu, un objet sans code, ou une relation absente', () => {
expect(paymentTypeCodeOf('/api/payment_types/1')).toBeNull()
expect(paymentTypeCodeOf({ '@id': '/api/payment_types/1' })).toBeNull()
expect(paymentTypeCodeOf(null)).toBeNull()
expect(paymentTypeCodeOf(undefined)).toBeNull()
})
})
@@ -293,6 +293,21 @@ export function referentialOptionOf(relation: Relation): SelectOption[] {
return [{ value: relation['@id'], label }]
}
/**
* Code metier d'un referentiel embarque (ex: PaymentType.code = 'LCR' / 'VIREMENT'),
* ou null si la relation est absente / serialisee en IRI nu. Type-safe : la branche
* chaine (IRI nu) et l'absence sont court-circuitees avant l'acces au code. Sert a
* conditionner l'affichage selon le type de reglement courant (ERP-121 : RIB masques
* hors-LCR en consultation).
*/
export function paymentTypeCodeOf(relation: Relation): string | null {
if (!relation || typeof relation === 'string') {
return null
}
return (relation.code as string | undefined) ?? null
}
/** Vue d'une adresse (brouillon + options de select propres a l'adresse). */
export function mapAddressView(address: AddressRead): AddressView {
return {
@@ -268,6 +268,21 @@ export function referentialOptionOf(relation: Relation): SelectOption[] {
return [{ value: relation['@id'], label }]
}
/**
* Code metier d'un referentiel embarque (ex: PaymentType.code = 'LCR' / 'VIREMENT'),
* ou null si la relation est absente / serialisee en IRI nu. Type-safe : la branche
* chaine (IRI nu) et l'absence sont court-circuitees avant l'acces au code. Sert a
* conditionner l'affichage selon le type de reglement courant (ERP-121 : RIB masques
* hors-LCR en consultation).
*/
export function paymentTypeCodeOf(relation: Relation): string | null {
if (!relation || typeof relation === 'string') {
return null
}
return (relation.code as string | undefined) ?? null
}
/** Vue d'une adresse (brouillon + options de select propres a l'adresse). */
export function mapAddressView(address: AddressRead): AddressView {
return {