fix(transport) : tableau prix — colonne Fournisseurs/Clients, fusion adresses sites/livraisons, renomme Transport (ERP-193)
This commit is contained in:
@@ -145,18 +145,18 @@
|
||||
groupe (Fond Mouvant / Benne) fusionné en rowspan ; séparateur
|
||||
é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">
|
||||
<!-- Répartition (table-fixed) : « Type de transport » un peu plus
|
||||
large ; Transporteurs et Adresse livraisons larges ; Forfait /
|
||||
Tonne / Indexation / État réduits. -->
|
||||
<!-- Répartition (table-fixed) : « Transport » étroit (libellé
|
||||
court Benne / Fond mouvant) ; Fournisseurs/Clients et
|
||||
Adresse sites/livraisons larges ; Forfait / Tonne /
|
||||
Indexation / État réduits. -->
|
||||
<colgroup>
|
||||
<col class="w-[170px]" />
|
||||
<col class="w-[20%]" />
|
||||
<col class="w-[120px]" />
|
||||
<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-[24%]" />
|
||||
<col class="w-[9%]" />
|
||||
<col class="w-[9%]" />
|
||||
<col class="w-[9%]" />
|
||||
<col class="w-[9%]" />
|
||||
</colgroup>
|
||||
<thead>
|
||||
<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-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.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.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>
|
||||
@@ -187,9 +186,13 @@
|
||||
>
|
||||
{{ group.label }}
|
||||
</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.apro }}</td>
|
||||
<td class="px-3 py-4 text-[14px]" :class="dataBorder(group, i, gi)">{{ row.delivery }}</td>
|
||||
<td class="px-3 py-4 text-[14px]" :class="dataBorder(group, i, gi)">{{ row.party }}</td>
|
||||
<!-- Adresse sites / livraisons : code du site (département) puis
|
||||
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.tonne }}</td>
|
||||
<td class="px-3 py-4 text-[14px]" :class="dataBorder(group, i, gi)">{{ row.indexation }}</td>
|
||||
@@ -197,7 +200,7 @@
|
||||
</tr>
|
||||
</template>
|
||||
<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') }}
|
||||
</td>
|
||||
</tr>
|
||||
@@ -346,6 +349,8 @@ function countryOptionsFor(country: string): SelectOption[] {
|
||||
const PRICE_GROUP_ORDER = ['FOND_MOUVANT', 'BENNE'] as const
|
||||
|
||||
interface PriceRowView {
|
||||
/** Fournisseur ou client lié au prix (raison sociale). */
|
||||
party: string
|
||||
apro: string
|
||||
delivery: string
|
||||
forfait: string
|
||||
@@ -383,13 +388,15 @@ function siteCode(relation: Relation): string {
|
||||
|
||||
/**
|
||||
* Construit une ligne d'affichage depuis un prix embarqué (maquette Prix) :
|
||||
* - « Adresse sites » = le CODE du site (département, ex: 86 / 17 / 82) ;
|
||||
* - « Adresse livraisons » = l'adresse (voie) du client/fournisseur ;
|
||||
* - « Fournisseurs / Clients » = le fournisseur OU le client lié (raison sociale) ;
|
||||
* - « 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`.
|
||||
*/
|
||||
function toPriceRow(price: CarrierPriceRead): PriceRowView {
|
||||
const isClient = price.direction === 'CLIENT'
|
||||
return {
|
||||
party: labelOfRelation(isClient ? price.client : price.supplier),
|
||||
apro: isClient ? siteCode(price.departureSite) : siteCode(price.deliverySite),
|
||||
delivery: isClient ? labelOfRelation(price.clientDeliveryAddress) : labelOfRelation(price.supplierSupplyAddress),
|
||||
forfait: price.pricingUnit === 'FORFAIT' ? formatAmount(price.price) : '',
|
||||
|
||||
@@ -27,6 +27,10 @@ describe('carrierMappers', () => {
|
||||
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', () => {
|
||||
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')
|
||||
|
||||
@@ -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
|
||||
* condensée (voie · CP · ville). Chaîne vide si la relation est un IRI nu / absente.
|
||||
* Libellé d'affichage d'une relation embarquée : `companyName` (client/fournisseur)
|
||||
* à 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 {
|
||||
if (!relation || typeof relation === 'string') {
|
||||
return ''
|
||||
}
|
||||
const companyName = relation.companyName as string | undefined
|
||||
if (companyName) {
|
||||
return companyName
|
||||
}
|
||||
const name = relation.name as string | undefined
|
||||
if (name) {
|
||||
return name
|
||||
|
||||
Reference in New Issue
Block a user