feat(front) : referentiels + blocs reutilisables contact/adresse/placeholder (ERP-63)
- useClientReferentials : chargement des selects (categories, sites, modes TVA, delais/types de reglement, banques) en ?pagination=false + listes distributeurs/courtiers via ?categoryCode=DISTRIBUTEUR|COURTIER. - ClientContactBlock / ClientAddressBlock : blocs reutilises par 1.11/1.12. L'adresse gere la saisie assistee BAN (via le stub) avec bascule en mode degrade (ville/adresse en saisie libre). - TabPlaceholderBlank : frame vide des onglets non implementes.
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
import { ref } from 'vue'
|
||||
|
||||
/**
|
||||
* Charge les referentiels (listes courtes) alimentant les selects de l'ecran
|
||||
* « Ajouter un client » : categories, sites, modes de TVA, delais et types de
|
||||
* reglement, banques, et les listes distributeurs / courtiers.
|
||||
*
|
||||
* Toutes les collections sont recuperees en entier via l'echappatoire prevue
|
||||
* `?pagination=false` (referentiels de quelques dizaines d'entrees max), avec
|
||||
* l'en-tete `Accept: application/ld+json` impose par API Platform 4 pour obtenir
|
||||
* l'enveloppe Hydra (`member`). Les valeurs d'option sont les IRI Hydra (`@id`)
|
||||
* pour pouvoir etre renvoyees telles quelles dans les payloads POST/PATCH
|
||||
* (relations ManyToOne / ManyToMany).
|
||||
*
|
||||
* Etat 100 % local a l'instance (refs) — aucune persistance URL.
|
||||
*/
|
||||
|
||||
/** Option generique au format attendu par MalioSelect / MalioSelectCheckbox ({ label, value }). */
|
||||
export interface RefOption {
|
||||
value: string
|
||||
label: string
|
||||
}
|
||||
|
||||
/** Option de type de reglement enrichie de son code stable (RG-1.12 / RG-1.13). */
|
||||
export interface PaymentTypeOption extends RefOption {
|
||||
code: string
|
||||
}
|
||||
|
||||
/** Option de categorie enrichie de son code stable (filtrage RG-1.29 cote adresse). */
|
||||
export interface CategoryOption extends RefOption {
|
||||
code: string
|
||||
}
|
||||
|
||||
/** Option de client (distributeur / courtier) — value = IRI du client lie. */
|
||||
export type ClientOption = RefOption
|
||||
|
||||
interface HydraMember {
|
||||
'@id': string
|
||||
}
|
||||
|
||||
interface CategoryMember extends HydraMember {
|
||||
code: string
|
||||
name: string
|
||||
}
|
||||
|
||||
interface SiteMember extends HydraMember {
|
||||
name: string
|
||||
}
|
||||
|
||||
interface ReferentialMember extends HydraMember {
|
||||
code: string
|
||||
label: string
|
||||
}
|
||||
|
||||
interface ClientMember extends HydraMember {
|
||||
companyName: string
|
||||
}
|
||||
|
||||
const LD_JSON_HEADERS = { Accept: 'application/ld+json' }
|
||||
|
||||
export function useClientReferentials() {
|
||||
const api = useApi()
|
||||
|
||||
const categories = ref<CategoryOption[]>([])
|
||||
const sites = ref<RefOption[]>([])
|
||||
const tvaModes = ref<RefOption[]>([])
|
||||
const paymentDelays = ref<RefOption[]>([])
|
||||
const paymentTypes = ref<PaymentTypeOption[]>([])
|
||||
const banks = ref<RefOption[]>([])
|
||||
const distributors = ref<ClientOption[]>([])
|
||||
const brokers = ref<ClientOption[]>([])
|
||||
|
||||
/** Recupere une collection complete (pagination desactivee) en Hydra. */
|
||||
async function fetchAll<T extends HydraMember>(
|
||||
url: string,
|
||||
query: Record<string, string | string[]> = {},
|
||||
): Promise<T[]> {
|
||||
const res = await api.get<{ member?: T[] }>(
|
||||
url,
|
||||
{ pagination: 'false', ...query },
|
||||
{ headers: LD_JSON_HEADERS, toast: false },
|
||||
)
|
||||
return res.member ?? []
|
||||
}
|
||||
|
||||
/**
|
||||
* Charge en parallele les referentiels communs (hors distributeurs/courtiers,
|
||||
* charges a la demande selon la relation choisie). Les selects compta ne sont
|
||||
* pertinents que si l'utilisateur a acces a l'onglet, mais le cout est
|
||||
* negligeable et simplifie l'orchestration.
|
||||
*/
|
||||
async function loadCommon(): Promise<void> {
|
||||
const [cats, sitesList, tva, delays, types, banksList] = await Promise.all([
|
||||
fetchAll<CategoryMember>('/categories'),
|
||||
fetchAll<SiteMember>('/sites'),
|
||||
fetchAll<ReferentialMember>('/tva_modes'),
|
||||
fetchAll<ReferentialMember>('/payment_delays'),
|
||||
fetchAll<ReferentialMember>('/payment_types'),
|
||||
fetchAll<ReferentialMember>('/banks'),
|
||||
])
|
||||
|
||||
categories.value = cats.map(c => ({ value: c['@id'], label: c.name, code: c.code }))
|
||||
sites.value = sitesList.map(s => ({ value: s['@id'], label: s.name }))
|
||||
tvaModes.value = tva.map(t => ({ value: t['@id'], label: t.label }))
|
||||
paymentDelays.value = delays.map(d => ({ value: d['@id'], label: d.label }))
|
||||
paymentTypes.value = types.map(t => ({ value: t['@id'], label: t.label, code: t.code }))
|
||||
banks.value = banksList.map(b => ({ value: b['@id'], label: b.label }))
|
||||
}
|
||||
|
||||
/** Liste des clients pouvant etre choisis comme distributeur (code DISTRIBUTEUR). */
|
||||
async function loadDistributors(): Promise<void> {
|
||||
if (distributors.value.length > 0) {
|
||||
return
|
||||
}
|
||||
const clients = await fetchAll<ClientMember>('/clients', { categoryCode: 'DISTRIBUTEUR' })
|
||||
distributors.value = clients.map(c => ({ value: c['@id'], label: c.companyName }))
|
||||
}
|
||||
|
||||
/** Liste des clients pouvant etre choisis comme courtier (code COURTIER). */
|
||||
async function loadBrokers(): Promise<void> {
|
||||
if (brokers.value.length > 0) {
|
||||
return
|
||||
}
|
||||
const clients = await fetchAll<ClientMember>('/clients', { categoryCode: 'COURTIER' })
|
||||
brokers.value = clients.map(c => ({ value: c['@id'], label: c.companyName }))
|
||||
}
|
||||
|
||||
return {
|
||||
categories,
|
||||
sites,
|
||||
tvaModes,
|
||||
paymentDelays,
|
||||
paymentTypes,
|
||||
banks,
|
||||
distributors,
|
||||
brokers,
|
||||
loadCommon,
|
||||
loadDistributors,
|
||||
loadBrokers,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user