feat(selfop): simplify turnover diagnostics and add zero stock filter
This commit is contained in:
@@ -2,7 +2,7 @@ import type { TurnoverQuery, TurnoverSort } from './turnoverTypes'
|
||||
import { turnoverSortOptions } from './turnoverSorting'
|
||||
export const turnoverSorts: TurnoverSort[] = turnoverSortOptions.map(option => option.value)
|
||||
const detailOnly = ['salesWindowDays', 'salesWindowEndDate', 'attention', 'coverageSelection', 'coverageBucket', 'bucketRuleVersion']
|
||||
const turnoverOnly = ['groupBy', 'baseWindowDays', 'focus', 'turnoverStatus', 'snapshotContext']
|
||||
const turnoverOnly = ['hideZeroInventory', 'groupBy', 'baseWindowDays', 'focus', 'turnoverStatus', 'snapshotContext']
|
||||
function scalar(q: Record<string, unknown>, key: string) {
|
||||
const v = q[key]
|
||||
if (v == null) return undefined
|
||||
@@ -24,6 +24,7 @@ export function yesterdayBeijing(now = new Date()) {
|
||||
return new Date(Date.parse(`${date}T00:00:00Z`) - 86400000).toISOString().slice(0, 10)
|
||||
}
|
||||
export function validateTurnover(q: TurnoverQuery, latestDate = yesterdayBeijing()) {
|
||||
if (q.hideZeroInventory != null && typeof q.hideZeroInventory !== 'boolean') throw new Error('隐藏零库存参数无效')
|
||||
if (!q.warehouseCode.trim()) throw new Error('请选择可用仓库')
|
||||
if (!/^\d{4}-\d{2}-\d{2}$/.test(q.endDate) || !Number.isFinite(Date.parse(q.endDate)) || new Date(q.endDate).toISOString().slice(0, 10) !== q.endDate || q.endDate > latestDate) throw new Error('截止日必须是已结束的北京时间日期')
|
||||
if (!Number.isInteger(q.baseWindowDays) || q.baseWindowDays < 1 || q.baseWindowDays > 366) throw new Error('统计区间须为1至366个完整自然日')
|
||||
@@ -38,11 +39,16 @@ export function validateTurnover(q: TurnoverQuery, latestDate = yesterdayBeijing
|
||||
}
|
||||
export function turnoverRoute(q: Record<string, unknown>): Partial<TurnoverQuery> {
|
||||
if (inventoryView(q) !== 'TURNOVER') throw new Error('当前为库存明细入口')
|
||||
const allowed = new Set(['view', 'warehouseCode', 'sku', 'customerCode', 'endDate', 'baseWindowDays', 'groupBy', 'focus', 'coverageDaysThreshold', 'turnoverStatus', 'sortBy', 'snapshotContext', 'current', 'size'])
|
||||
const allowed = new Set(['view', 'warehouseCode', 'hideZeroInventory', 'sku', 'customerCode', 'endDate', 'baseWindowDays', 'groupBy', 'focus', 'coverageDaysThreshold', 'turnoverStatus', 'sortBy', 'snapshotContext', 'current', 'size'])
|
||||
for (const key of Object.keys(q)) if (!allowed.has(key)) throw new Error(`库存周转不接受参数 ${key}`)
|
||||
const result: Record<string, string | number> = {}
|
||||
const result: Record<string, string | number | boolean> = {}
|
||||
for (const key of allowed) {
|
||||
const value = scalar(q, key)
|
||||
if (key === 'hideZeroInventory' && value != null) {
|
||||
if (!['true', 'false'].includes(value)) throw new Error('隐藏零库存参数无效')
|
||||
result[key] = value === 'true'
|
||||
continue
|
||||
}
|
||||
if (value != null && key !== 'view') result[key] = ['baseWindowDays', 'coverageDaysThreshold', 'current', 'size'].includes(key) ? Number(value) : value
|
||||
}
|
||||
return result as Partial<TurnoverQuery>
|
||||
|
||||
Reference in New Issue
Block a user