fix(commercial) : masque Relation / Prestation de triage selon la categorie (formulaire client)
Les champs « Relation » (depend du distributeur/courtier) et « Prestation de triage » du bloc principal sont masques par defaut et reveles uniquement quand une categorie ordinaire (autre que Distributeur/Courtier) est selectionnee. Masquer ces champs reinitialise leurs valeurs (pas de relation/triage fantome soumis). Applique a la creation et a l'edition.
This commit is contained in:
@@ -41,6 +41,7 @@
|
|||||||
@update:model-value="(v: (string | number)[]) => main.categoryIris = v.map(String)"
|
@update:model-value="(v: (string | number)[]) => main.categoryIris = v.map(String)"
|
||||||
/>
|
/>
|
||||||
<MalioSelect
|
<MalioSelect
|
||||||
|
v-if="showRelationAndTriage"
|
||||||
:model-value="main.relationType"
|
:model-value="main.relationType"
|
||||||
:options="relationOptions"
|
:options="relationOptions"
|
||||||
:label="t('commercial.clients.form.main.relation')"
|
:label="t('commercial.clients.form.main.relation')"
|
||||||
@@ -49,7 +50,7 @@
|
|||||||
@update:model-value="onRelationChange"
|
@update:model-value="onRelationChange"
|
||||||
/>
|
/>
|
||||||
<MalioSelect
|
<MalioSelect
|
||||||
v-if="main.relationType === 'courtier'"
|
v-if="showRelationAndTriage && main.relationType === 'courtier'"
|
||||||
:model-value="main.brokerIri"
|
:model-value="main.brokerIri"
|
||||||
:options="brokerOptions"
|
:options="brokerOptions"
|
||||||
:label="t('commercial.clients.form.main.brokerName')"
|
:label="t('commercial.clients.form.main.brokerName')"
|
||||||
@@ -59,7 +60,7 @@
|
|||||||
@update:model-value="(v: string | number | null) => main.brokerIri = v === null ? null : String(v)"
|
@update:model-value="(v: string | number | null) => main.brokerIri = v === null ? null : String(v)"
|
||||||
/>
|
/>
|
||||||
<MalioSelect
|
<MalioSelect
|
||||||
v-if="main.relationType === 'distributeur'"
|
v-if="showRelationAndTriage && main.relationType === 'distributeur'"
|
||||||
:model-value="main.distributorIri"
|
:model-value="main.distributorIri"
|
||||||
:options="distributorOptions"
|
:options="distributorOptions"
|
||||||
:label="t('commercial.clients.form.main.distributorName')"
|
:label="t('commercial.clients.form.main.distributorName')"
|
||||||
@@ -69,6 +70,7 @@
|
|||||||
@update:model-value="(v: string | number | null) => main.distributorIri = v === null ? null : String(v)"
|
@update:model-value="(v: string | number | null) => main.distributorIri = v === null ? null : String(v)"
|
||||||
/>
|
/>
|
||||||
<MalioCheckbox
|
<MalioCheckbox
|
||||||
|
v-if="showRelationAndTriage"
|
||||||
v-model="main.triageService"
|
v-model="main.triageService"
|
||||||
:label="t('commercial.clients.form.main.triageService')"
|
:label="t('commercial.clients.form.main.triageService')"
|
||||||
group-class="self-center"
|
group-class="self-center"
|
||||||
@@ -381,7 +383,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onMounted, reactive, ref } from 'vue'
|
import { computed, onMounted, reactive, ref, watch } from 'vue'
|
||||||
import { useClient } from '~/modules/commercial/composables/useClient'
|
import { useClient } from '~/modules/commercial/composables/useClient'
|
||||||
import { useClientReferentials, type CategoryOption, type RefOption } from '~/modules/commercial/composables/useClientReferentials'
|
import { useClientReferentials, type CategoryOption, type RefOption } from '~/modules/commercial/composables/useClientReferentials'
|
||||||
import { useClientFormErrors } from '~/modules/commercial/composables/useClientFormErrors'
|
import { useClientFormErrors } from '~/modules/commercial/composables/useClientFormErrors'
|
||||||
@@ -423,6 +425,7 @@ import {
|
|||||||
isRibBlank,
|
isRibBlank,
|
||||||
isRibComplete,
|
isRibComplete,
|
||||||
isRibRequiredForPaymentType,
|
isRibRequiredForPaymentType,
|
||||||
|
showsRelationAndTriageFields,
|
||||||
} from '~/modules/commercial/utils/clientFormRules'
|
} from '~/modules/commercial/utils/clientFormRules'
|
||||||
import {
|
import {
|
||||||
emptyAddress,
|
emptyAddress,
|
||||||
@@ -554,6 +557,28 @@ const relationOptions = computed<RefOption[]>(() => [
|
|||||||
{ value: 'courtier', label: t('commercial.clients.form.main.relationBroker') },
|
{ value: 'courtier', label: t('commercial.clients.form.main.relationBroker') },
|
||||||
])
|
])
|
||||||
|
|
||||||
|
// Codes des categories selectionnees (resolus depuis l'union referentiel + embed).
|
||||||
|
const selectedCategoryCodes = computed(() =>
|
||||||
|
main.categoryIris
|
||||||
|
.map(iri => mainCategoryOptions.value.find(c => c.value === iri)?.code)
|
||||||
|
.filter((code): code is string => code !== undefined),
|
||||||
|
)
|
||||||
|
|
||||||
|
// « Relation » + « Prestation de triage » masques par defaut, reveles des qu'une
|
||||||
|
// categorie ordinaire (autre que Distributeur/Courtier) est selectionnee.
|
||||||
|
const showRelationAndTriage = computed(() => showsRelationAndTriageFields(selectedCategoryCodes.value))
|
||||||
|
|
||||||
|
// Masquer ces champs reinitialise leurs valeurs : pas de relation/triage fantome
|
||||||
|
// soumis pour un client Distributeur/Courtier.
|
||||||
|
watch(showRelationAndTriage, (visible) => {
|
||||||
|
if (!visible) {
|
||||||
|
main.relationType = null
|
||||||
|
main.distributorIri = null
|
||||||
|
main.brokerIri = null
|
||||||
|
main.triageService = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
// Distributeur / courtier : referentiel charge a la demande UNION valeur courante.
|
// Distributeur / courtier : referentiel charge a la demande UNION valeur courante.
|
||||||
const currentDistributorOption = computed<RefOption[]>(() => {
|
const currentDistributorOption = computed<RefOption[]>(() => {
|
||||||
const d = client.value?.distributor
|
const d = client.value?.distributor
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
@update:model-value="(v: (string | number)[]) => main.categoryIris = v.map(String)"
|
@update:model-value="(v: (string | number)[]) => main.categoryIris = v.map(String)"
|
||||||
/>
|
/>
|
||||||
<MalioSelect
|
<MalioSelect
|
||||||
|
v-if="showRelationAndTriage"
|
||||||
:model-value="main.relationType"
|
:model-value="main.relationType"
|
||||||
:options="relationOptions"
|
:options="relationOptions"
|
||||||
:label="t('commercial.clients.form.main.relation')"
|
:label="t('commercial.clients.form.main.relation')"
|
||||||
@@ -43,7 +44,7 @@
|
|||||||
@update:model-value="onRelationChange"
|
@update:model-value="onRelationChange"
|
||||||
/>
|
/>
|
||||||
<MalioSelect
|
<MalioSelect
|
||||||
v-if="main.relationType === 'courtier'"
|
v-if="showRelationAndTriage && main.relationType === 'courtier'"
|
||||||
:model-value="main.brokerIri"
|
:model-value="main.brokerIri"
|
||||||
:options="referentials.brokers.value"
|
:options="referentials.brokers.value"
|
||||||
:label="t('commercial.clients.form.main.brokerName')"
|
:label="t('commercial.clients.form.main.brokerName')"
|
||||||
@@ -53,7 +54,7 @@
|
|||||||
@update:model-value="(v: string | number | null) => main.brokerIri = v === null ? null : String(v)"
|
@update:model-value="(v: string | number | null) => main.brokerIri = v === null ? null : String(v)"
|
||||||
/>
|
/>
|
||||||
<MalioSelect
|
<MalioSelect
|
||||||
v-if="main.relationType === 'distributeur'"
|
v-if="showRelationAndTriage && main.relationType === 'distributeur'"
|
||||||
:model-value="main.distributorIri"
|
:model-value="main.distributorIri"
|
||||||
:options="referentials.distributors.value"
|
:options="referentials.distributors.value"
|
||||||
:label="t('commercial.clients.form.main.distributorName')"
|
:label="t('commercial.clients.form.main.distributorName')"
|
||||||
@@ -63,6 +64,7 @@
|
|||||||
@update:model-value="(v: string | number | null) => main.distributorIri = v === null ? null : String(v)"
|
@update:model-value="(v: string | number | null) => main.distributorIri = v === null ? null : String(v)"
|
||||||
/>
|
/>
|
||||||
<MalioCheckbox
|
<MalioCheckbox
|
||||||
|
v-if="showRelationAndTriage"
|
||||||
v-model="main.triageService"
|
v-model="main.triageService"
|
||||||
:label="t('commercial.clients.form.main.triageService')"
|
:label="t('commercial.clients.form.main.triageService')"
|
||||||
group-class="self-center"
|
group-class="self-center"
|
||||||
@@ -397,6 +399,7 @@ import {
|
|||||||
isRibBlank,
|
isRibBlank,
|
||||||
isRibComplete,
|
isRibComplete,
|
||||||
isRibRequiredForPaymentType,
|
isRibRequiredForPaymentType,
|
||||||
|
showsRelationAndTriageFields,
|
||||||
} from '~/modules/commercial/utils/clientFormRules'
|
} from '~/modules/commercial/utils/clientFormRules'
|
||||||
import {
|
import {
|
||||||
emptyAddress,
|
emptyAddress,
|
||||||
@@ -489,6 +492,28 @@ const relationOptions = computed<RefOption[]>(() => [
|
|||||||
{ value: 'courtier', label: t('commercial.clients.form.main.relationBroker') },
|
{ value: 'courtier', label: t('commercial.clients.form.main.relationBroker') },
|
||||||
])
|
])
|
||||||
|
|
||||||
|
// Codes des categories selectionnees (resolus depuis les IRI du brouillon).
|
||||||
|
const selectedCategoryCodes = computed(() =>
|
||||||
|
main.categoryIris
|
||||||
|
.map(iri => referentials.categories.value.find(c => c.value === iri)?.code)
|
||||||
|
.filter((code): code is string => code !== undefined),
|
||||||
|
)
|
||||||
|
|
||||||
|
// « Relation » + « Prestation de triage » masques par defaut, reveles des qu'une
|
||||||
|
// categorie ordinaire (autre que Distributeur/Courtier) est selectionnee.
|
||||||
|
const showRelationAndTriage = computed(() => showsRelationAndTriageFields(selectedCategoryCodes.value))
|
||||||
|
|
||||||
|
// Masquer ces champs reinitialise leurs valeurs : pas de relation/triage fantome
|
||||||
|
// soumis pour un client Distributeur/Courtier.
|
||||||
|
watch(showRelationAndTriage, (visible) => {
|
||||||
|
if (!visible) {
|
||||||
|
main.relationType = null
|
||||||
|
main.distributorIri = null
|
||||||
|
main.brokerIri = null
|
||||||
|
main.triageService = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
// Validation du formulaire principal (gate le bouton « Valider ») :
|
// Validation du formulaire principal (gate le bouton « Valider ») :
|
||||||
// - companyName / >= 1 categorie obligatoires ;
|
// - companyName / >= 1 categorie obligatoires ;
|
||||||
// - relation Distributeur/Courtier optionnelle, mais le nom correspondant
|
// - relation Distributeur/Courtier optionnelle, mais le nom correspondant
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import {
|
|||||||
isRibBlank,
|
isRibBlank,
|
||||||
isRibComplete,
|
isRibComplete,
|
||||||
isRibRequiredForPaymentType,
|
isRibRequiredForPaymentType,
|
||||||
|
showsRelationAndTriageFields,
|
||||||
type AddressValidityDraft,
|
type AddressValidityDraft,
|
||||||
type ContactDraft,
|
type ContactDraft,
|
||||||
type ContactFillableDraft,
|
type ContactFillableDraft,
|
||||||
@@ -276,6 +277,23 @@ describe('hasAllRequiredAccountingFields (RG-1.30)', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
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)', () => {
|
describe('hasAtLeastOneInformationField (pas de validation a vide a la creation)', () => {
|
||||||
const blank = {
|
const blank = {
|
||||||
description: null,
|
description: null,
|
||||||
|
|||||||
@@ -53,6 +53,26 @@ export function buildClientFormTabKeys(
|
|||||||
return keys
|
return keys
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Codes de categorie « intermediaire » : un client dont la categorie est
|
||||||
|
* Distributeur ou Courtier n'a ni relation amont (il EST le distributeur /
|
||||||
|
* courtier) ni prestation de triage. Sert a conditionner l'affichage des champs
|
||||||
|
* « Relation » et « Prestation de triage » du formulaire principal.
|
||||||
|
*/
|
||||||
|
export const DISTRIBUTOR_BROKER_CATEGORY_CODES = ['DISTRIBUTEUR', 'COURTIER'] as const
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vrai des qu'au moins une categorie « ordinaire » (autre que Distributeur /
|
||||||
|
* Courtier) est selectionnee. Les champs « Relation » (depend du distributeur /
|
||||||
|
* courtier) et « Prestation de triage » du formulaire principal sont masques par
|
||||||
|
* defaut et reveles uniquement dans ce cas.
|
||||||
|
*/
|
||||||
|
export function showsRelationAndTriageFields(selectedCategoryCodes: string[]): boolean {
|
||||||
|
return selectedCategoryCodes.some(
|
||||||
|
code => !(DISTRIBUTOR_BROKER_CATEGORY_CODES as readonly string[]).includes(code),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/** Sous-ensemble d'un contact necessaire aux regles de nommage (RG-1.05/1.14). */
|
/** Sous-ensemble d'un contact necessaire aux regles de nommage (RG-1.05/1.14). */
|
||||||
export interface ContactDraft {
|
export interface ContactDraft {
|
||||||
firstName: string | null
|
firstName: string | null
|
||||||
|
|||||||
Reference in New Issue
Block a user