feat(selfop): multi-owner turnover filters, CSV export and percentage

This commit is contained in:
2026-10-15 11:14:35 +08:00
parent 11e348a29f
commit 50b06dca10
9 changed files with 196 additions and 30 deletions
@@ -3,6 +3,14 @@ import { inventoryView, turnoverRoute, validateTurnover, yesterdayBeijing } from
import type { TurnoverQuery } from './turnoverTypes'
const valid: TurnoverQuery = { sourceAccount: 'primary', warehouseCode: 'W', groupBy: 'SKU', endDate: '2026-10-12', baseWindowDays: 30, focus: 'ALL', sortBy: 'PHYSICAL_DESC', current: 1, size: 20, includeOverview: true }
describe('inventory view and turnover query contract', () => {
it('normalizes repeated owner keys and validates the bounded selection', () => {
expect(turnoverRoute({ customerCodes: ['B', 'A', 'A'] }).customerCodes).toEqual(['A', 'B'])
expect(turnoverRoute({ customerCodes: 'A' }).customerCodes).toEqual(['A'])
expect(turnoverRoute({}).customerCodes).toEqual([])
for (const value of ['', [null], Array(101).fill('A')]) expect(() => turnoverRoute({ customerCodes: value })).toThrow()
expect(() => turnoverRoute({ customerCode: 'A' })).toThrow()
expect(() => inventoryView({ view: 'DETAIL', customerCodes: ['A'] })).toThrow()
})
it('parses only explicit booleans for the zero-inventory filter', () => {
expect(turnoverRoute({ hideZeroInventory: 'false' })).toMatchObject({ hideZeroInventory: false })
expect(turnoverRoute({ hideZeroInventory: 'true' })).toMatchObject({ hideZeroInventory: true })