物资管理Phase 4

使用说明

这份说明同时是交付文档:页面里的内容来自 docs/使用说明.md, 可以 下载 Markdown 存档。

目录

物资管理 · 使用说明

适用版本:1.6.0(Phase 4 · 安全与交付) 这份文档同时是页面 /materials/system/help 的内容来源,可下载 Markdown 存档。


一、这是什么,管什么

一个只管非食材物资的库存台账:办公用品、清洁用品、纸品、电池、耗材……

它和另外两个子系统的边界是刻意的:

系统 管什么 与本系统的关系
物资管理(本系统) 非食材物资的入库、领用、盘点、成本 ——
diet(饮食) 食材、餐次、营养 不共表、不共库;食材不进这里
finance(财务) 真实支出流水 只对账,不自动记账;本系统不会往 finance 写一笔

一句话:这里记"东西怎么变少的",finance 记"钱怎么花出去的",两者每月对一次账。


二、五分钟上手

第一次用,按这个顺序走,不要跳步:

  1. 建分类 → 「物资档案」页 → 新建分类(如"办公耗材""生活日用品")。
  2. 建库位 → 同一页 → 新建库位(如"储物柜""阳台柜")。库位可以不只一层。
  3. 建物资 → 填名称 + 基本单位(个/张/包/瓶)+ 分类 + 最低库存。 基本单位一旦产生流水就锁定,改不了(改了历史全部作废)。
  4. 录入现有库存 → 「存量建账」页。 系统上线前就有的东西走这里,它不参与财务对账,见第五节。
  5. 以后每次买东西 → 「采购入库」建单、收货;每次拿东西 → 「快速消耗」。

底部导航一共 11 个入口,常用的就三个:快速消耗、采购入库、库存查询。


三、七个日常动作

3.1 新建物资档案

「物资档案」→ 新建。要点:

3.2 存量建账(上线前就有的东西)

「存量建账」→ 一屏 6 行,填「物资 / 数量 / 单位 / 总金额」即可。

3.3 采购入库

「采购入库」→ 新建:选物资、填数量、单位、单价,保存即生成采购单。

3.4 快速消耗

「快速消耗」→ 选物资(可搜)、填数量、选场景,提交。

3.5 盘点

「盘点调整」→ 新建盘点单 → 录入实盘数 → 完成。

3.6 查库存 / 查流水

3.7 改错

所有改错都遵循同一条规则:原行不动,加一笔红冲。

想改什么 怎么做 结果
某笔流水数量/金额错了 流水页 → 编辑(或删除) → 填原因 原行保留,新增一条冲销 + 一条新流水
采购单单价写错了(已入库) 采购单 → 修改这张采购单 红冲该行有效收货 + 按新价重开
整张采购单是误录 / 退货了 采购单 → 删除这张采购单 红冲全部有效收货,单据置「已取消」
盘点单错了 盘点详情 → 取消整单 红冲该单产生的全部调整流水

为什么不能直接改?

一旦允许原地改,"这笔数为什么和上个月对不上"就永远查不出来了。 冲销 + 重开让每一步都留下痕迹,且账本上任何一行都可以回溯到它为什么存在。

删除是软删除:单据留在库里(状态改为已取消),列表默认隐藏, 勾选「显示已删除」还能翻出来看原因。


四、口径(这部分决定数字对不对)

4.1 库存唯一真源

库里没有任何"当前库存"字段。当前库存永远等于:

库存 = SUM(quantity_delta) WHERE status = 'posted'

这样不存在"流水和库存对不上"的可能 —— 因为它们是同一个东西。 系统页的 C1–C6 自检就是拿来验证这一点的(见第八节)。

4.2 数量与金额都是整数

4.3 成本:移动加权平均

每次入库把新成本并进平均价,出库按当前平均价计价。 所以恒等式永远成立:

Σ入库金额 = Σ出库金额 + 期末存货价值

4.4 成本"未知"不等于 0

4.5 冲销怎么计数

冲销行会以原类型出现在统计里(冲一笔消耗就是 usage_out 的负数), 净额天然正确;页面显示"已冲销"由 reversal_of_id 推导,原行状态永远是 posted。

4.6 时间口径


五、对账:和 finance 怎么对

「对账」页只读,不改任何数据。核心是 A 式:

期末存货价值 + 本期消耗成本 + 报损
− 存量建账 − 退回入库 − 盘盈 + 盘亏
= finance 本期「物资」类支出

几个关键点:

差额不为 0 时先看两件事:采购单价是不是填错了(比如把"每包价"填成了"每张价"), 以及有没有支出被记到别的分类。


六、统计与补货

「统计」页(只读):

补货建议只读:它不会自动下单,也不会改账本。


七、导入与导出

7.1 导出(「系统」→ 导出)

文件 内容
库存.csv 每个物资的数量、价值、成本状态、库位分布
库存流水.csv 全量流水(上限 5 万行),含冲销关系
采购单.csv 采购明细,整单金额重复在每行(便于透视)
操作审计.csv 最近 2000 条审计
全量导出.zip 以上四份 + README

编码是 UTF-8 带 BOM,Excel 双击即开;用脚本读请用 utf-8-sig。 导出是只读快照,不保证能直接回灌。

7.2 导入(「系统」→ 导入)

只支持两类,且都是只增不改:

类型 必填列 行为
物资档案 名称、基本单位 同名物资一律跳过,绝不覆盖
存量建账 物资(编号或名称)、数量 逐行独立成败,单位/金额/日期可选

流程是两段式:

  1. 预览:逐行校验,显示"可导入几行 / 跳过几行 / 哪几行错、错在哪";
  2. 确认:服务端重新校验一遍再落库,写库前自动做 pre-import 备份。

为什么没有"流水导入":账本是逐笔生成的,批量灌 Excel 会绕过红冲、幂等、 库存非负三条防线。要批量补历史,走「存量建账」——它本来就不参与对账。


八、数据自检、备份、恢复

8.1 系统页(/materials/system/)

一屏看完:库文件大小、append-only 触发器是否齐全、C1–C6 自检结果、 最近备份、审计摘要、版本信息。

C1–C6 的含义:

项 检查
C1 全局库存 = 各库位库存之和
C2 没有负库存
C3 没有非 posted 状态的流水混入
C4 冲销都指向真实流水,且同一笔不会被冲两次
C5 消耗记录与流水一一对应
C6 成本金额与成本状态不矛盾

任何一项红了,先别导入、别恢复,先去流水页核对。

8.2 备份

8.3 恢复

「备份列表」→ 某一份 → 恢复,需要输入确认词 恢复。

执行顺序(任何一步失败,线上库一行没动):

  1. 校验备份(完整性 / 关键表 / 版本);
  2. 给当前库自动做一份 pre-restore 备份;
  3. 复制到临时文件 → 再校验一次 → os.replace 原子替换;
  4. 需要时补跑迁移;
  5. 写审计 system.restore,并跑一次一致性自检。

⚠️ 恢复是覆盖,不是合并。备份之后产生的数据会消失。 唯一例外是恢复动作本身会留下 pre-restore 备份。

8.4 保留策略

本版不做自动清理 —— 删备份是破坏性操作,交给人在文件管理器里做更安全。 建议:月底归档留 12 个月;pre-import / pre-restore 这类临时备份确认无用后可删。


九、权限

页面 游客 普通账户 拥有者
概览 / 档案 / 流水 / 库存 / 对账 / 统计 读 读 读写
使用说明(/system/help) 读 读 读
系统页 / 备份恢复 / 导入 / 审计 ✗ ✗ ✓

十、常见问题

Q:为什么改了单价,库存金额变化很大? A:多半是把"每包价"当成了"每张价"。先到档案页登记换算(1 包 = 500 张), 再改采购单;系统会按新单位重算整行金额。

Q:库存不够,但确实要领用,怎么办? A:先补入库(采购或盘盈),再领用。不要为了领用去改历史流水 —— 那会让成本链断掉。真需要调账,用盘点做盘亏,原因写清楚。

Q:删除采购单后还能找回吗? A:单据还在(状态「已取消」),列表勾选「显示已删除」可见; 它红冲掉的入库流水也都还在账本上,带 reversal_of_id 指回原行。

Q:对账差额一直不为 0? A:按顺序查:① 采购单价是否填错;② 有没有支出记到了别的分类; ③ finance 那边有没有一笔"物资"支出漏记;④ 存量建账是否被重复计入。

Q:能不能把食材也放进来? A:不建议。食材保质期与餐次关联在 diet 里,放进本系统会两边都不准。

Q:能不能直接改数据库? A:触发器会拒绝 UPDATE / DELETE(流水与审计表)。要修复数据, 走应用层的冲销 / 恢复;直接改文件只应作为最后手段,且必须先备份。


十一、已知限制与后续

项 现状
成本重估流水 未做。数量不变、只调金额的场景(如运费补记)暂无入口
采购单 ↔ finance 支出字段级关联 未做。目前靠金额 + 月份对账,不做逐单勾稽
FIFO / 批次成本 不支持,固定移动加权平均
多用户并发编辑同一单据 无锁;后提交者覆盖(审计能查到)
定时自动备份 未内置。建议用系统计划任务调用备份脚本
备份自动清理 刻意不做

十二、数据边界(给维护者看)

门户首页