暂估价(0 价)→ 确认进价 · 设计方案

调货「先卖后定价」场景 · 分支 feature/jiu_20260623 · 2026-06-23
从朋友处调货,价格未定时以 进价 0(暂估) 入库并照常审核、出库售卖;价格确定后,对该入库单执行 「确认进价」——系统前向补偿真实成本(不反审核、不撤销任何已发生的动作):回填库存成本、已出库成本快照, 并按差额补一条应付流水。售价 / 应收完全不受影响。

1. 背景与取舍

老系统做法是「入库价填 0 → 出库 → 反审核入库单改价 → 重审」。新系统已审核单据只读、无反审核、流水不可变、库存成本一旦落地无修改接口——强行复刻反审核在「货已出库」时几乎无法回滚干净,且违反现有不可变设计。

故改用会计上的「暂估入库 → 实际成本确认」模型:不反审核,以一次前向调整补齐成本与应付。关键前提是新系统的序列号数据模型让这件事变得精确——

用户确认的口径:①不填预估、直接填 0;②确认后补成本 + 补应付流水;③调货单独建单据类型,复用普通入库单;④利润统计遇到无进价的行须跳过并单独说明。

简化决策:不新增 schema 字段(遵循「禁止为每个业务字段改表结构」)。约定 成本待定 = 成本为 0 / unit_price 为 NULL。调货白酒成本不会真为 0,歧义可忽略。

2. 核心动作:确认进价

接口:POST /api/v1/stock-in/orders/:id/confirm-cost,body {"items":[{"item_id":N,"unit_price":50.0}]}。 仅 approved 单可确认(draft 直接编辑即可);权限 管理员/超管;后端实现 StockService.ConfirmStockInCost

一个事务内,对每个有变化的明细(旧价→新价,差额 diff = (new-old)×qty)前向写补偿:

1. 入库明细 StockInItem.unit_price / total_price 改为真实值 2. 剩余库存 Inventory.unit_price NULL → 真实值 (按 stock_in_item_id;已全出则无行) 3. 已出库行 StockOutItem.unit_price / total_price 回填 (按 product_id;不动 sale_price) 4. 入库单总额 StockInOrder.total_amount += Σ diff 5. 应付差额 新增 FinanceRecord{type:payable, amount:Σdiff, ref_type:stock_in_cost_adjust} 6. 参考进价 Product.purchase_price 同步(按 product_id)

幂等 / 可重复:以「旧价→新价」差额计算,多次修正各补一条差额流水(如 0→50 补 +500,再 50→60 补 +100)。

应付余额语义balance 是该往来单位「应收 + 应付」混合的滚动总账(沿用既有 partnerLastBalance),确认流水在此基础上累加差额。

3. 影响矩阵

数据0 价入库审核后确认进价后
入库明细 unit_price0→ 真实价
库存批次 unit_priceNULL(待定)→ 真实价
已出库行 unit_price(成本快照)0→ 真实价(按 product_id)
出库 sale_price / 应收正常不变
入库单 total_amount0→ Σ 真实小计
对供应商应付+0补一条 +差额 流水

4. 边界

5. 前端

6. 利润口径(前瞻约定)

系统当前利润/毛利报表,本次新建(YAGNI)。约定:未来任何利润/毛利统计,须排除成本待定(unit_price ≤ 0 / NULL)的出库行,并单独列「N 笔成本待定,未计入利润」。 本设计的「待定价」标识即为该口径提供可识别依据。

7. 关键文件