086be7b4f0
Auto Tag Develop / tag (push) Successful in 14s
## ERP-208 — Fix ticket de pesée ### Bon de pesée (PDF) Ajout d'un **cartouche bordé en haut à droite** du bon de pesée, contenant le **type de contrepartie** (Client / Fournisseur / Autre, en gras au-dessus) et le **nom du tiers**. - `WeighingTicket::getCounterpartyName()` + `getCounterpartyTypeLabel()` (testés). - En-tête du template passé en table 2 colonnes (contrainte Dompdf CSS 2.1). ### Écran de saisie (Ajouter / Modifier) Les listes **Client / Fournisseur** sont **filtrées sur le site courant** (un tiers est rattaché à un site via les sites de ses adresses) et **rechargées au changement de site**. - Réutilise le filtre back existant `?siteId[]=` de /clients et /suppliers (aucun changement back sur le filtre). - Au switch de site : le tiers sélectionné est réinitialisé **uniquement** s'il sort du périmètre du nouveau site. - Portée limitée au ticket de pesée : les répertoires M1/M2 ne changent pas. ### Tests - Back : test unitaire `WeighingTicketCounterpartyNameTest` (nom + libellé) ; test PDF existant inchangé. - Front : specs référentiels + écrans Ajouter/Modifier (673/673). - Pas de migration, pas de RBAC, pas d'E2E. ### À vérifier en recette En **modification**, si le tiers d'un ticket n'a pas d'adresse sur le site courant, le select peut s'afficher vide (valeur conservée mais option filtrée). Reviewed-on: #155 Co-authored-by: tristan <tristan@yuno.malio.fr> Co-committed-by: tristan <tristan@yuno.malio.fr>
45 lines
1.9 KiB
TypeScript
45 lines
1.9 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
import { useWeighingTicketReferentials } from '../useWeighingTicketReferentials'
|
|
|
|
const mockApiGet = vi.hoisted(() => vi.fn())
|
|
vi.stubGlobal('useApi', () => ({ get: mockApiGet }))
|
|
|
|
/**
|
|
* Tests des référentiels Client/Fournisseur de l'écran ticket de pesée (M5).
|
|
* Contrat couvert (ERP-208) : `load(siteId)` filtre les deux endpoints par site
|
|
* courant via `siteId[]` ; sans site → listes complètes (param absent).
|
|
*/
|
|
describe('useWeighingTicketReferentials', () => {
|
|
beforeEach(() => {
|
|
mockApiGet.mockReset()
|
|
mockApiGet.mockResolvedValue({ member: [] })
|
|
})
|
|
|
|
it('passe siteId[] aux deux endpoints quand un site courant est fourni', async () => {
|
|
const { load } = useWeighingTicketReferentials()
|
|
await load(7)
|
|
|
|
const clientsCall = mockApiGet.mock.calls.find(c => c[0] === '/clients')
|
|
const suppliersCall = mockApiGet.mock.calls.find(c => c[0] === '/suppliers')
|
|
expect(clientsCall?.[1]).toMatchObject({ pagination: 'false', 'siteId[]': [7] })
|
|
expect(suppliersCall?.[1]).toMatchObject({ pagination: 'false', 'siteId[]': [7] })
|
|
})
|
|
|
|
it('ne passe pas siteId[] quand aucun site (liste complète)', async () => {
|
|
const { load } = useWeighingTicketReferentials()
|
|
await load(null)
|
|
|
|
const clientsCall = mockApiGet.mock.calls.find(c => c[0] === '/clients')
|
|
expect(clientsCall?.[1]).not.toHaveProperty('siteId[]')
|
|
expect(clientsCall?.[1]).toMatchObject({ pagination: 'false' })
|
|
})
|
|
|
|
it('mappe les membres Hydra en options { value: @id, label: companyName }', async () => {
|
|
mockApiGet.mockResolvedValue({ member: [{ '@id': '/api/clients/3', companyName: 'ACME' }] })
|
|
const { load, clients } = useWeighingTicketReferentials()
|
|
await load(7)
|
|
|
|
expect(clients.value).toEqual([{ value: '/api/clients/3', label: 'ACME' }])
|
|
})
|
|
})
|