|
|
e152f16ebc
|
feat(scrap): 报废一律需审批,不再按物料标记区分
业务规则变更:所有报废申请都必须由指定审批人审批通过后才能执行。
原逻辑走 resolve_approval_control 判定是否需审批,而 material_base 表中
仅 1/3012 个物料标记了 is_approval_required,意味着 99.97% 的报废申请会
走免审批分支——status 直接置 1、actual_approver_id 被赋为申请人自己、
审批人参数被静默丢弃。前端即便做了必填也只是摆设。
改动(规则收敛到单一来源):
· 新增 SCRAP_ALWAYS_REQUIRES_APPROVAL = True,作为唯一开关;
· submit_approval() 无审批人一律拒绝;恒置 status=0(待审批);
删除免审批自动通过分支;
· resolve_approval_control 仍调用,但仅用于生成提示文案,
不再参与是否审批的判定;
· /request/check-approval 返回 need_approval=SCRAP_ALWAYS_REQUIRES_APPROVAL,
否则该接口会继续返回 false,导致前端预检结果失真。
实测:不传审批人 → 拒绝;传审批人 → status=0 且 actual_approver_id 为空。
⚠ 注意:此前自动通过的单据今后一律进入审批队列。
|
2026-09-10 11:32:51 +08:00 |
|
|
|
ed351f96ec
|
refactor(scrap): 按单执行校验改用 SKU 主键匹配
架构要求以 SKU 为唯一校验键,原实现按 (source_table, stock_id) 匹配。
已核验数据前提:SKU 在同一库存表内唯一(0 重复),且不存在跨表重名
(stock_buy / stock_semi / stock_product 交叉 0 冲突),故 SKU 可安全
作为跨来源标识。
改动:
· 新增 _match_key():SKU 非空时以 'sku:<SKU>' 为键;个别历史库存行
SKU 为空,回退 'row:<table>#<id>',前缀区分确保绝不串键;
· _build_approved_index() 按 SKU 聚合,累加批准量并保留各行的
source_table + stock_id(rows 列表);
· 校验拆为两步并给出明确文案:SKU 是否在批准明细内、同 SKU 累计量
是否超批准量;
· ★ 扣减改为按批准单配对的 source_table + stock_id 定位库存行加锁,
不再信任前端传来的 stock_id —— 实测前端传伪造 stock_id=99999 时,
仍从批准单指定的库存行扣减,台账同样记录批准单的 stock_id;
· 同一 SKU 在批准单占多行时,按批准顺序依次分配扣减量。
实测 7 项校验用例 + 多行分配 / 批准行已删除 / 可用不足 均符合预期。
|
2026-09-10 10:21:50 +08:00 |
|
|
|
7719943779
|
feat(scrap): 报废执行改为按单扫码校验,废弃盲执行
execute() 原先只吃 request_id,按申请单快照全量扣减,用户反馈「扫码与报废脱节」。
现改为接收实扫明细 scanned_items:
· 强制按单:未提交实扫明细一律拒绝执行;
· 键为 (source_table, stock_id),与申请单 items_json 同口径,
同一物品多次扫码自动累加,兼容「逐件扫」与「输数量」两种操作;
· 校验实扫项必须落在批准明细内,且累计量不得超批准量,否则整单拒绝;
· 允许合法子集(少扫 = 本次不报废该行);
· 扣减以实扫量为准,同时扣 available_quantity 与 stock_quantity
(报废即实物销毁,上一版只扣可用库存会让总库存虚挂)。
接口 POST /scrap/request/<id>/execute 由无 body 改为接收 {items:[...]}。
|
2026-09-10 10:14:40 +08:00 |
|
|
|
8755837fe8
|
fix(timezone): 审批单据时间统一为 naive 北京时间,消除 8 小时偏差
成因:approved_at / executed_at 列是 timestamp without time zone,而赋值用了
带时区的 datetime.now(timezone(timedelta(hours=8)))。psycopg2 对 naive 列不会
剥掉 tzinfo,而是转成 naive UTC 再写入,结果比同为北京时间的 created_at 早 8 小时。
(代码里并无 datetime.utcnow(),真实成因是 aware 值被驱动的隐式 UTC 转换。)
改动:
· outbound_service / borrow_service 的审批分支
datetime.now(beijing_tz).replace(tzinfo=None) → beijing_time()
(免审批分支已在上一轮改为 beijing_time,此处补齐审批分支);
· purchase_service 审批/完结分支同源缺陷一并修复;
· scrap_approval / scrap_approval_service 的 _beijing()、_beijing_now() 由
tz-aware 改为 naive —— 配合上述迁移把列类型改为 naive,
若仍返回 aware 值,timestamptz→timestamp 后会反向早 8 小时。
实测四表(scrap/outbound/borrow/purchase)created_at 与 approved_at 差值
均在同一秒内(-1ms ~ -12ms)。
|
2026-09-10 10:14:31 +08:00 |
|
|
|
ffbb2199f0
|
feat(scrap): 报废申请审批流 + 按单报废(后端)
- ScrapApproval 模型 + ScrapApprovalService:提交/列表/审批/执行(锁库存扣 available_quantity 写 TransScrap)
- 新路由 POST /scrap/request、/request/check-approval、GET /request、PATCH /request/<id>/approve、POST /request/<id>/execute;权限码 scrap_apply/scrap_approval/scrap_execute(无角色硬编码)
- 旧 /scrap 直接报废入口保持不变
- /inbound/stock/list 每项返回 source_table,供按单流程精准选库存
|
2026-09-10 09:46:57 +08:00 |
|