Merge pull request 'fix: 排除拣选位报表中的箱记录' (#63) from codex/picking-bin-pack-filter-1012 into main
This commit is contained in:
commit
c6c7feaeea
@ -11,7 +11,8 @@
|
||||
*
|
||||
* 口径:
|
||||
* 库存数量:rpt.jst_packInventoryInfo 按 wms_co_id + 仓位 + sku_id 汇总 qty
|
||||
* 统计范围:只统计拣选位(bin_group 为空);存货位(bin_group=存货)不纳入
|
||||
* 统计范围:只统计真实拣选仓位(pack_type=Bin 且 bin_group 为空);
|
||||
* 箱记录(pack_type=Pack)与存货位(bin_group=存货)不纳入
|
||||
* 销量: rpt.jst_Orders × rpt.jst_OrderItem,按 send_date,排除 Delete/Cancelled
|
||||
* 日销: 商品窗口销量 / 窗口天数(整档,不按仓位分摊)
|
||||
* 等级: 严格按商品日销判定,同一商品占多少个仓位都是同一等级
|
||||
@ -36,8 +37,9 @@ const PICKING_BIN_WINDOW_OPTIONS = [7, 15, 30, 60];
|
||||
const PICKING_BIN_DEFAULT_DAYS = 30;
|
||||
|
||||
/**
|
||||
* 仓位类型:本功能只统计拣选位(业务库 bin_group 为空即拣选位)。
|
||||
* 存货位(bin_group=存货)不纳入动销等级统计,取数在仓位库存表上直接过滤,
|
||||
* 仓位类型:本功能只统计真实拣选仓位(pack_type=Bin 且 bin_group 为空)。
|
||||
* 箱记录(pack_type=Pack)和存货位(bin_group=存货)不纳入动销等级统计,
|
||||
* 取数在仓位库存表上直接过滤,
|
||||
* 页面也不再提供类型切换。
|
||||
*/
|
||||
const BIN_TYPE_PICKING = '拣选';
|
||||
|
||||
@ -4,7 +4,8 @@
|
||||
* 拣选库位动销分析 —— 业务库取数
|
||||
*
|
||||
* 库存:rpt.jst_packInventoryInfo 按 wms_co_id + 仓位 + sku_id 汇总 qty(仓位为空的行不参与)
|
||||
* 范围:只统计拣选位(bin_group 为空);存货位(bin_group=存货)不纳入
|
||||
* 范围:只统计真实拣选仓位(pack_type=Bin 且 bin_group 为空);
|
||||
* 箱记录(pack_type=Pack)与存货位(bin_group=存货)不纳入
|
||||
* 销量:rpt.jst_Orders × rpt.jst_OrderItem,按 send_date,排除 Delete/Cancelled
|
||||
* 粒度:仓位 × 商品编码(一个仓位有 N 个商品就输出 N 行),列表与导出共用
|
||||
*
|
||||
@ -84,8 +85,8 @@ async function fetchPickingBinSkuRows(cloudDb, wmsCoIds, options = {}) {
|
||||
const binIn = buildInClause(wmsCoIds, 'w');
|
||||
const shipIn = buildInClause(wmsCoIds, 'v');
|
||||
|
||||
// 统计范围固定为拣选位:直接在仓位库存表上过滤 bin_group 为空,
|
||||
// 存货位(bin_group=存货)不参与动销等级统计。
|
||||
// 统计范围固定为真实拣选仓位:pack_type=Bin 且 bin_group 为空。
|
||||
// 仅过滤 bin_group 会把同样为空的 Pack 箱记录误标为拣选位。
|
||||
const sqlText = `
|
||||
WITH bin AS (
|
||||
SELECT p.wms_co_id AS wmsCoId,
|
||||
@ -97,6 +98,7 @@ async function fetchPickingBinSkuRows(cloudDb, wmsCoIds, options = {}) {
|
||||
WHERE p.wms_co_id IN (${binIn.clause})
|
||||
AND ISNULL(p.bin, '') <> ''
|
||||
AND ISNULL(p.qty, 0) <> 0
|
||||
AND p.pack_type = N'Bin'
|
||||
AND ISNULL(p.bin_group, '') = ''
|
||||
GROUP BY p.wms_co_id,
|
||||
LTRIM(RTRIM(p.bin)),
|
||||
|
||||
@ -116,19 +116,21 @@ test('fetchPickingBinSkuRows 按仓位×商品输出,等级与日销来自商
|
||||
// 商品销量按占用仓位数分摊(供求和),但等级依据的是未分摊的商品销量
|
||||
assert.ok(captured.sqlText.includes('/ NULLIF(sp.binCount, 0)'));
|
||||
assert.ok(captured.sqlText.includes('ISNULL(s.salesQty, 0) / @days AS DECIMAL(18, 4)'));
|
||||
// 统计范围固定为拣选位:bin_group 为空;只统计有库存的行
|
||||
// 统计范围固定为真实拣选仓位:pack_type=Bin 且 bin_group 为空;只统计有库存的行
|
||||
assert.ok(captured.sqlText.includes("p.pack_type = N'Bin'"));
|
||||
assert.ok(captured.sqlText.includes("ISNULL(p.bin_group, '') = ''"));
|
||||
assert.ok(captured.sqlText.includes('ISNULL(p.qty, 0) <> 0'));
|
||||
assert.ok(captured.sqlText.includes('HAVING ABS(SUM(CAST(b.binSkuQty AS DECIMAL(18, 2)))) > 0.0001'));
|
||||
});
|
||||
|
||||
test('fetchPickingBinSkuRows 只统计拣选位,不带类型参数', async () => {
|
||||
test('fetchPickingBinSkuRows 只统计真实拣选仓位,排除 Pack 箱记录且不带类型参数', async () => {
|
||||
let captured = null;
|
||||
const db = {
|
||||
query: async (sqlText, params) => { captured = { sqlText, params }; return []; },
|
||||
};
|
||||
await fetchPickingBinSkuRows(db, [101], { shipFrom: 'a', shipTo: 'b', days: 15 });
|
||||
// 存货位(bin_group=存货)被排除,且不再有 binType IN (...) 的可变过滤
|
||||
// Pack 箱记录和存货位被排除,且不再有 binType IN (...) 的可变过滤
|
||||
assert.ok(captured.sqlText.includes("p.pack_type = N'Bin'"));
|
||||
assert.ok(captured.sqlText.includes("ISNULL(p.bin_group, '') = ''"));
|
||||
assert.ok(!captured.sqlText.includes('b.binType IN'));
|
||||
assert.equal(captured.params.t0, undefined);
|
||||
|
||||
@ -14,7 +14,7 @@ export const PICKING_BIN_COLUMNS = [
|
||||
{
|
||||
key: 'binType',
|
||||
label: '类型',
|
||||
tip: '统计范围固定为拣选位(bin_group 为空的仓位);存货位不纳入动销分析,报表中不会出现',
|
||||
tip: '统计范围固定为真实拣选仓位(pack_type=Bin 且 bin_group 为空);箱记录和存货位不纳入动销分析',
|
||||
},
|
||||
{
|
||||
key: 'skuId',
|
||||
@ -63,7 +63,7 @@ export const PICKING_BIN_GRADE_COLORS = {
|
||||
};
|
||||
|
||||
export const PICKING_BIN_DESCRIPTION = [
|
||||
'【统计范围】只统计拣选位(bin_group 为空的仓位);存货位不纳入动销分析。',
|
||||
'【统计范围】只统计真实拣选仓位(pack_type=Bin 且 bin_group 为空);箱记录(pack_type=Pack)和存货位不纳入动销分析。',
|
||||
'',
|
||||
'【粒度】一行 = 一个「仓位 × 商品编码」组合。一个仓位放了 N 个商品就显示 N 行,列表与导出一致。',
|
||||
' 库存数量 = 该商品在这个仓位上的实际库存(同一仓位多行相加 = 仓位总库存)。',
|
||||
@ -86,5 +86,5 @@ export const PICKING_BIN_DESCRIPTION = [
|
||||
'',
|
||||
'数据来源:库存取 rpt.jst_packInventoryInfo(按仓库 + 仓位 + 商品汇总);',
|
||||
'销量取 rpt.jst_Orders × rpt.jst_OrderItem(按 send_date,排除 Delete/Cancelled),与「每日进销存」发货口径一致。',
|
||||
'统计范围:只取 bin_group 为空的拣选位,存货位(bin_group=存货)不参与统计。',
|
||||
'统计范围:只取 pack_type=Bin 且 bin_group 为空的真实拣选仓位,箱记录(pack_type=Pack)和存货位(bin_group=存货)不参与统计。',
|
||||
];
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user