feat(commercial) : catégories de type Adresse pour les blocs adresse (client + fournisseur) (#147)
Auto Tag Develop / tag (push) Successful in 12s
Auto Tag Develop / tag (push) Successful in 12s
## Objectif Introduit un `CategoryType` dédié **ADRESSE** (module Catalog) consommé par le champ « Catégorie » des blocs adresse, en remplacement de la réutilisation détournée des types CLIENT / FOURNISSEUR. ## Changements **Backend** - Migration de seed du type ADRESSE + 6 catégories : Siège, Contact issues, Facturation, Livraison, Approvisionnement, Méthaniseur (idempotente, réversible) ; fixtures alignées. - `ClientAddress` : validation blacklist (DISTRIBUTEUR/COURTIER) remplacée par une whitelist « catégories de type ADRESSE uniquement ». - `SupplierAddress` : type requis FOURNISSEUR → ADRESSE (le bloc principal fournisseur reste en FOURNISSEUR). **Frontend** - Ref dédiée `addressCategories` (`?typeCode=ADRESSE`) dans les composables référentiels client et fournisseur. - Pages new/edit client et fournisseur câblées sur les blocs adresse. **Tests** - `CategoryAdresseSeedTest` (miroir du test PRESTATAIRE). - Adaptation des tests d'adresse client/fournisseur (sémantique whitelist ADRESSE) + helper `createAddressCategory()`. ## Vérifications - Back : suites Catalog + Architecture + adresse/fournisseur vertes (le flake JWT connu du hook est sans rapport, tests verts en isolation). - Front : Vitest vert (composables référentiels + ciblés). - php-cs-fixer : 0 correction ; eslint : OK. Reviewed-on: #147 Co-authored-by: tristan <tristan@yuno.malio.fr> Co-committed-by: tristan <tristan@yuno.malio.fr>
This commit was merged in pull request #147.
This commit is contained in:
@@ -77,4 +77,23 @@ describe('useClientReferentials.loadCommon (resilience ERP-102)', () => {
|
||||
// Le libelle d'un site est son numero de departement (2 premiers chiffres du code postal).
|
||||
expect(refs.sites.value).toEqual([{ value: '/api/sites/1', label: '86' }])
|
||||
})
|
||||
|
||||
it('separe les categories CLIENT (formulaire) des categories ADRESSE (blocs adresse)', async () => {
|
||||
// Le mock distingue les deux appels /categories par leur filtre typeCode.
|
||||
mockGet.mockImplementation((url: string, query?: Record<string, unknown>) => {
|
||||
if (url === '/categories' && query?.typeCode === 'CLIENT') {
|
||||
return Promise.resolve({ member: [{ '@id': '/api/categories/1', code: 'SECTEUR', name: 'Secteur' }] })
|
||||
}
|
||||
if (url === '/categories' && query?.typeCode === 'ADRESSE') {
|
||||
return Promise.resolve({ member: [{ '@id': '/api/categories/9', code: 'SIEGE', name: 'Siège' }] })
|
||||
}
|
||||
return Promise.resolve({ member: [] })
|
||||
})
|
||||
|
||||
const refs = useClientReferentials()
|
||||
await refs.loadCommon()
|
||||
|
||||
expect(refs.categories.value).toEqual([{ value: '/api/categories/1', label: 'Secteur', code: 'SECTEUR' }])
|
||||
expect(refs.addressCategories.value).toEqual([{ value: '/api/categories/9', label: 'Siège', code: 'SIEGE' }])
|
||||
})
|
||||
})
|
||||
|
||||
@@ -23,6 +23,16 @@ describe('useSupplierReferentials', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('charge les categories d\'adresse filtrees sur le type ADRESSE', async () => {
|
||||
await useSupplierReferentials().loadCommon()
|
||||
|
||||
expect(mockGet).toHaveBeenCalledWith(
|
||||
'/categories',
|
||||
expect.objectContaining({ pagination: 'false', typeCode: 'ADRESSE' }),
|
||||
expect.objectContaining({ toast: false }),
|
||||
)
|
||||
})
|
||||
|
||||
it('mappe les categories en options { value: IRI, label: name, code }', async () => {
|
||||
mockGet.mockImplementation((url: string) => {
|
||||
if (url === '/categories') {
|
||||
|
||||
@@ -68,6 +68,9 @@ export function useClientReferentials() {
|
||||
const api = useApi()
|
||||
|
||||
const categories = ref<CategoryOption[]>([])
|
||||
// Taxonomie dediee aux blocs adresse (type ADRESSE), distincte des categories
|
||||
// CLIENT du formulaire principal.
|
||||
const addressCategories = ref<CategoryOption[]>([])
|
||||
const sites = ref<RefOption[]>([])
|
||||
const tvaModes = ref<RefOption[]>([])
|
||||
const paymentDelays = ref<RefOption[]>([])
|
||||
@@ -109,6 +112,9 @@ export function useClientReferentials() {
|
||||
// de type CLIENT (pas FOURNISSEUR) -> on filtre la collection cote API.
|
||||
fetchAll<CategoryMember>('/categories', { typeCode: 'CLIENT' })
|
||||
.then((cats) => { categories.value = cats.map(c => ({ value: c['@id'], label: c.name, code: c.code })) }),
|
||||
// Categories des blocs adresse : taxonomie dediee type ADRESSE.
|
||||
fetchAll<CategoryMember>('/categories', { typeCode: 'ADRESSE' })
|
||||
.then((cats) => { addressCategories.value = cats.map(c => ({ value: c['@id'], label: c.name, code: c.code })) }),
|
||||
fetchAll<SiteMember>('/sites')
|
||||
// Libelle = numero de departement (2 premiers chiffres du code
|
||||
// postal du site), ex: 86100 -> « 86 ». Le code postal est deja
|
||||
@@ -151,6 +157,7 @@ export function useClientReferentials() {
|
||||
|
||||
return {
|
||||
categories,
|
||||
addressCategories,
|
||||
sites,
|
||||
tvaModes,
|
||||
paymentDelays,
|
||||
|
||||
@@ -62,6 +62,9 @@ export function useSupplierReferentials() {
|
||||
const api = useApi()
|
||||
|
||||
const categories = ref<CategoryOption[]>([])
|
||||
// Taxonomie dediee aux blocs adresse (type ADRESSE), distincte des categories
|
||||
// FOURNISSEUR du formulaire principal.
|
||||
const addressCategories = ref<CategoryOption[]>([])
|
||||
const sites = ref<RefOption[]>([])
|
||||
const tvaModes = ref<RefOption[]>([])
|
||||
const paymentDelays = ref<RefOption[]>([])
|
||||
@@ -97,6 +100,9 @@ export function useSupplierReferentials() {
|
||||
// categories de type FOURNISSEUR (RG-2.10) -> on filtre cote API.
|
||||
fetchAll<CategoryMember>('/categories', { typeCode: 'FOURNISSEUR' })
|
||||
.then((cats) => { categories.value = cats.map(c => ({ value: c['@id'], label: c.name, code: c.code })) }),
|
||||
// Categories des blocs adresse : taxonomie dediee type ADRESSE.
|
||||
fetchAll<CategoryMember>('/categories', { typeCode: 'ADRESSE' })
|
||||
.then((cats) => { addressCategories.value = cats.map(c => ({ value: c['@id'], label: c.name, code: c.code })) }),
|
||||
fetchAll<SiteMember>('/sites')
|
||||
// Libelle = numero de departement (2 premiers chiffres du code
|
||||
// postal du site), ex: 86100 -> « 86 ».
|
||||
@@ -121,6 +127,7 @@ export function useSupplierReferentials() {
|
||||
|
||||
return {
|
||||
categories,
|
||||
addressCategories,
|
||||
sites,
|
||||
tvaModes,
|
||||
paymentDelays,
|
||||
|
||||
Reference in New Issue
Block a user