fix(transport) : tableau prix — colonne Fournisseurs/Clients, fusion adresses sites/livraisons, renomme Transport (ERP-193)
This commit is contained in:
@@ -554,10 +554,9 @@
|
|||||||
"message": "Ce transporteur réapparaîtra dans le répertoire actif. Confirmer la restauration ?"
|
"message": "Ce transporteur réapparaîtra dans le répertoire actif. Confirmer la restauration ?"
|
||||||
},
|
},
|
||||||
"price": {
|
"price": {
|
||||||
"group": "Type de transport",
|
"group": "Transport",
|
||||||
"carrier": "Transporteurs",
|
"carrier": "Fournisseurs / Clients",
|
||||||
"aproOrSite": "Adresse sites",
|
"aproOrSite": "Adresse sites / livraisons",
|
||||||
"delivery": "Adresse livraisons",
|
|
||||||
"forfait": "Forfait (€)",
|
"forfait": "Forfait (€)",
|
||||||
"tonne": "Tonne (€)",
|
"tonne": "Tonne (€)",
|
||||||
"indexation": "Indexation",
|
"indexation": "Indexation",
|
||||||
|
|||||||
@@ -145,18 +145,18 @@
|
|||||||
groupe (Fond Mouvant / Benne) fusionné en rowspan ; séparateur
|
groupe (Fond Mouvant / Benne) fusionné en rowspan ; séparateur
|
||||||
épais entre les deux groupes. -->
|
épais entre les deux groupes. -->
|
||||||
<table class="w-full table-fixed border-separate border-spacing-0 overflow-hidden rounded-malio border border-black text-left text-black">
|
<table class="w-full table-fixed border-separate border-spacing-0 overflow-hidden rounded-malio border border-black text-left text-black">
|
||||||
<!-- Répartition (table-fixed) : « Type de transport » un peu plus
|
<!-- Répartition (table-fixed) : « Transport » étroit (libellé
|
||||||
large ; Transporteurs et Adresse livraisons larges ; Forfait /
|
court Benne / Fond mouvant) ; Fournisseurs/Clients et
|
||||||
Tonne / Indexation / État réduits. -->
|
Adresse sites/livraisons larges ; Forfait / Tonne /
|
||||||
|
Indexation / État réduits. -->
|
||||||
<colgroup>
|
<colgroup>
|
||||||
<col class="w-[170px]" />
|
<col class="w-[120px]" />
|
||||||
<col class="w-[20%]" />
|
<col class="w-[18%]" />
|
||||||
|
<col class="w-[30%]" />
|
||||||
|
<col class="w-[10%]" />
|
||||||
|
<col class="w-[10%]" />
|
||||||
|
<col class="w-[11%]" />
|
||||||
<col class="w-[11%]" />
|
<col class="w-[11%]" />
|
||||||
<col class="w-[24%]" />
|
|
||||||
<col class="w-[9%]" />
|
|
||||||
<col class="w-[9%]" />
|
|
||||||
<col class="w-[9%]" />
|
|
||||||
<col class="w-[9%]" />
|
|
||||||
</colgroup>
|
</colgroup>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -164,7 +164,6 @@
|
|||||||
<th class="border-b border-r border-black bg-m-surface px-3 py-3 text-center align-middle text-[16px] font-semibold">{{ t('transport.carriers.consultation.price.group') }}</th>
|
<th class="border-b border-r border-black bg-m-surface px-3 py-3 text-center align-middle text-[16px] font-semibold">{{ t('transport.carriers.consultation.price.group') }}</th>
|
||||||
<th class="border-b border-black bg-m-surface px-3 py-3 align-middle text-[16px] font-semibold">{{ t('transport.carriers.consultation.price.carrier') }}</th>
|
<th class="border-b border-black bg-m-surface px-3 py-3 align-middle text-[16px] font-semibold">{{ t('transport.carriers.consultation.price.carrier') }}</th>
|
||||||
<th class="border-b border-black bg-m-surface px-3 py-3 align-middle text-[16px] font-semibold">{{ t('transport.carriers.consultation.price.aproOrSite') }}</th>
|
<th class="border-b border-black bg-m-surface px-3 py-3 align-middle text-[16px] font-semibold">{{ t('transport.carriers.consultation.price.aproOrSite') }}</th>
|
||||||
<th class="border-b border-black bg-m-surface px-3 py-3 align-middle text-[16px] font-semibold">{{ t('transport.carriers.consultation.price.delivery') }}</th>
|
|
||||||
<th class="border-b border-black bg-m-surface px-3 py-3 align-middle text-[16px] font-semibold">{{ t('transport.carriers.consultation.price.forfait') }}</th>
|
<th class="border-b border-black bg-m-surface px-3 py-3 align-middle text-[16px] font-semibold">{{ t('transport.carriers.consultation.price.forfait') }}</th>
|
||||||
<th class="border-b border-black bg-m-surface px-3 py-3 align-middle text-[16px] font-semibold">{{ t('transport.carriers.consultation.price.tonne') }}</th>
|
<th class="border-b border-black bg-m-surface px-3 py-3 align-middle text-[16px] font-semibold">{{ t('transport.carriers.consultation.price.tonne') }}</th>
|
||||||
<th class="border-b border-black bg-m-surface px-3 py-3 align-middle text-[16px] font-semibold">{{ t('transport.carriers.consultation.price.indexation') }}</th>
|
<th class="border-b border-black bg-m-surface px-3 py-3 align-middle text-[16px] font-semibold">{{ t('transport.carriers.consultation.price.indexation') }}</th>
|
||||||
@@ -187,9 +186,13 @@
|
|||||||
>
|
>
|
||||||
{{ group.label }}
|
{{ group.label }}
|
||||||
</td>
|
</td>
|
||||||
<td class="px-3 py-4 text-[14px]" :class="dataBorder(group, i, gi)">{{ headerTitle }}</td>
|
<td class="px-3 py-4 text-[14px]" :class="dataBorder(group, i, gi)">{{ row.party }}</td>
|
||||||
<td class="px-3 py-4 text-[14px]" :class="dataBorder(group, i, gi)">{{ row.apro }}</td>
|
<!-- Adresse sites / livraisons : code du site (département) puis
|
||||||
<td class="px-3 py-4 text-[14px]" :class="dataBorder(group, i, gi)">{{ row.delivery }}</td>
|
adresse de livraison/appro, regroupés dans une seule cellule. -->
|
||||||
|
<td class="px-3 py-4 text-[14px]" :class="dataBorder(group, i, gi)">
|
||||||
|
<div v-if="row.apro" class="text-[12px] text-m-muted">{{ row.apro }}</div>
|
||||||
|
<div>{{ row.delivery }}</div>
|
||||||
|
</td>
|
||||||
<td class="px-3 py-4 text-[14px]" :class="dataBorder(group, i, gi)">{{ row.forfait }}</td>
|
<td class="px-3 py-4 text-[14px]" :class="dataBorder(group, i, gi)">{{ row.forfait }}</td>
|
||||||
<td class="px-3 py-4 text-[14px]" :class="dataBorder(group, i, gi)">{{ row.tonne }}</td>
|
<td class="px-3 py-4 text-[14px]" :class="dataBorder(group, i, gi)">{{ row.tonne }}</td>
|
||||||
<td class="px-3 py-4 text-[14px]" :class="dataBorder(group, i, gi)">{{ row.indexation }}</td>
|
<td class="px-3 py-4 text-[14px]" :class="dataBorder(group, i, gi)">{{ row.indexation }}</td>
|
||||||
@@ -197,7 +200,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
<tr v-if="!hasPrices">
|
<tr v-if="!hasPrices">
|
||||||
<td colspan="8" class="px-3 py-4 text-center text-[14px] text-m-muted">
|
<td colspan="7" class="px-3 py-4 text-center text-[14px] text-m-muted">
|
||||||
{{ t('transport.carriers.consultation.price.empty') }}
|
{{ t('transport.carriers.consultation.price.empty') }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -346,6 +349,8 @@ function countryOptionsFor(country: string): SelectOption[] {
|
|||||||
const PRICE_GROUP_ORDER = ['FOND_MOUVANT', 'BENNE'] as const
|
const PRICE_GROUP_ORDER = ['FOND_MOUVANT', 'BENNE'] as const
|
||||||
|
|
||||||
interface PriceRowView {
|
interface PriceRowView {
|
||||||
|
/** Fournisseur ou client lié au prix (raison sociale). */
|
||||||
|
party: string
|
||||||
apro: string
|
apro: string
|
||||||
delivery: string
|
delivery: string
|
||||||
forfait: string
|
forfait: string
|
||||||
@@ -383,13 +388,15 @@ function siteCode(relation: Relation): string {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Construit une ligne d'affichage depuis un prix embarqué (maquette Prix) :
|
* Construit une ligne d'affichage depuis un prix embarqué (maquette Prix) :
|
||||||
* - « Adresse sites » = le CODE du site (département, ex: 86 / 17 / 82) ;
|
* - « Fournisseurs / Clients » = le fournisseur OU le client lié (raison sociale) ;
|
||||||
* - « Adresse livraisons » = l'adresse (voie) du client/fournisseur ;
|
* - « Adresse sites / livraisons » = code du site (département) + adresse de
|
||||||
|
* livraison/appro du client/fournisseur, regroupés dans une seule colonne ;
|
||||||
* - le prix tombe dans Forfait € OU Tonne € selon `pricingUnit`.
|
* - le prix tombe dans Forfait € OU Tonne € selon `pricingUnit`.
|
||||||
*/
|
*/
|
||||||
function toPriceRow(price: CarrierPriceRead): PriceRowView {
|
function toPriceRow(price: CarrierPriceRead): PriceRowView {
|
||||||
const isClient = price.direction === 'CLIENT'
|
const isClient = price.direction === 'CLIENT'
|
||||||
return {
|
return {
|
||||||
|
party: labelOfRelation(isClient ? price.client : price.supplier),
|
||||||
apro: isClient ? siteCode(price.departureSite) : siteCode(price.deliverySite),
|
apro: isClient ? siteCode(price.departureSite) : siteCode(price.deliverySite),
|
||||||
delivery: isClient ? labelOfRelation(price.clientDeliveryAddress) : labelOfRelation(price.supplierSupplyAddress),
|
delivery: isClient ? labelOfRelation(price.clientDeliveryAddress) : labelOfRelation(price.supplierSupplyAddress),
|
||||||
forfait: price.pricingUnit === 'FORFAIT' ? formatAmount(price.price) : '',
|
forfait: price.pricingUnit === 'FORFAIT' ? formatAmount(price.price) : '',
|
||||||
|
|||||||
@@ -27,6 +27,10 @@ describe('carrierMappers', () => {
|
|||||||
expect(iriOf(undefined)).toBeNull()
|
expect(iriOf(undefined)).toBeNull()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('labelOfRelation : companyName (client/fournisseur) prioritaire sur name/adresse', () => {
|
||||||
|
expect(labelOfRelation({ '@id': '/api/suppliers/8', companyName: 'AAAAAAA', name: 'X' })).toBe('AAAAAAA')
|
||||||
|
})
|
||||||
|
|
||||||
it('labelOfRelation : name (site) à défaut adresse condensée', () => {
|
it('labelOfRelation : name (site) à défaut adresse condensée', () => {
|
||||||
expect(labelOfRelation({ '@id': '/api/sites/1', name: 'Châtellerault' })).toBe('Châtellerault')
|
expect(labelOfRelation({ '@id': '/api/sites/1', name: 'Châtellerault' })).toBe('Châtellerault')
|
||||||
expect(labelOfRelation({ '@id': '/api/client_addresses/8', street: '1 rue X', postalCode: '86000', city: 'Poitiers' })).toBe('1 rue X · 86000 · Poitiers')
|
expect(labelOfRelation({ '@id': '/api/client_addresses/8', street: '1 rue X', postalCode: '86000', city: 'Poitiers' })).toBe('1 rue X · 86000 · Poitiers')
|
||||||
|
|||||||
@@ -97,13 +97,18 @@ export function iriOf(relation: Relation): string | null {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Libellé d'affichage d'une relation embarquée : `name` (site) à défaut une adresse
|
* Libellé d'affichage d'une relation embarquée : `companyName` (client/fournisseur)
|
||||||
* condensée (voie · CP · ville). Chaîne vide si la relation est un IRI nu / absente.
|
* à défaut `name` (site), à défaut une adresse condensée (voie · CP · ville). Chaîne
|
||||||
|
* vide si la relation est un IRI nu / absente.
|
||||||
*/
|
*/
|
||||||
export function labelOfRelation(relation: Relation): string {
|
export function labelOfRelation(relation: Relation): string {
|
||||||
if (!relation || typeof relation === 'string') {
|
if (!relation || typeof relation === 'string') {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
|
const companyName = relation.companyName as string | undefined
|
||||||
|
if (companyName) {
|
||||||
|
return companyName
|
||||||
|
}
|
||||||
const name = relation.name as string | undefined
|
const name = relation.name as string | undefined
|
||||||
if (name) {
|
if (name) {
|
||||||
return name
|
return name
|
||||||
|
|||||||
Reference in New Issue
Block a user