|
|
bfd0db791c
|
feat(scrap): 报废原因分类 + 角色级审批
报废要回答「这笔损失出在哪个环节」,并让主管审批不再依赖逐个指定人。
- 新增「报废原因分类」字段(scrap_approval + trans_scrap 各一列),
只有两个互斥口径:生产报废(走 Track 的)/ 库存报废(MOM 自身流程的)。
不传即库存报废 —— 这条二分法在写入那一刻就成立,不依赖任何推导。
⚠️ 不能从 source_table 推导:Track 的生产报废与手工的不良品退回共用
同一张 trans_defective_goods 表,推导会把生产损失算成库存损失。
- scrap_approval 加 company_name / source_ref:前者是公司隔离快照,
后者是外部单据的幂等锚点(Redis 未部署,prevent_double_submit 全程
fail-open,唯一索引是唯一防线)。
- 审批从「只认 type=user」放宽到「user 或 role」——主管角色都能审,
谁审就记谁。★ 空名单依然拒绝所有人(Fail-Closed),这是历史
「名单为空则人人可审」漏洞的修复点,不得改回 fail-open。
- 角色级放行必须配公司隔离:6 个主管里 IRIS 5 个、LICA 1 个,
不隔离就是跨公司审批通道。
- trans_return 加 source_ref(幂等锚点)。
迁移:db_migrations/phase12(建列)+ phase13(存量空分类回填为库存报废)。
|
2026-09-23 15:17:44 +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 |
|