资金流水与更正
资金流水只追加,更正靠冲回,模型起草的付款也只能批准后追加
SZV 的资金流水只追加:更正一笔账,写一条金额相反、引用原单号的冲回行,旧行一个字不改。模型起草的付款也只能批准后追加流水,没有为模型另开的写入通道。这套机制不含银行流水接入,企业要把账与银行流水逐笔核对,另需接入与匹配。
冲回更正
流水表只追加,库里拒绝对它的改与删。动钱的流水表由一张定义表统一上锁:一行对应一张表,列白名单为空,就是只追加;白名单非空,只许改白名单里的列;要锁一张新表,加一行即可。写入锁由触发器实现,对超级用户的写入同样触发;声明 ENABLE ALWAYS 的表,连复制角色也绕不过,但表属主与超级用户可以停用触发器。
要更正已记的账,写冲回行,不改旧行。撤销一笔收款,系统按原收款的每一条腿逆向写一笔,并引用原单号。旧行和冲回行并存,审计看到的是完整的来龙去脉。
这与财务上的红字冲销是同一类做法:保留原凭证,另记一笔相反的。审计时不必怀疑某一行被改过:要找的更正,都是后面多出来的行。
流水核对比什么
先分清容易混的核对。
| 核对 | 比什么 | 何时发生 | 在这套机制里吗 |
|---|---|---|---|
| 三单匹配 | 订单、收货、发票 | 付款之前 | 不在 |
| 银行对账 | 账上的流水与银行流水 | 付款之后 | 不在,没有银行流水接入 |
| 流水核对 | 同一个指标的现算值与物化值 | 逐日 | 在 |
物化列是把计算结果预先存成一列,读起来快。现算值是读的时候按流水现场算出来的。物化换来速度,也多出一份存值;每多一份存值,就多一份与流水漂开的可能。流水核对就是为此设的检查:它比的是系统自己的两份数。
统一的口径
口径指一个数怎么算、从哪里取。每个指标的口径写在口径定义表里,报表、物化、导出、汇总与总览取同一份,所以同一个数只有一份算法。改口径,是新增一个版本、把旧版本置为退役,历史数据按书面执行令重算。字段与一个具体口径的例子见客户资料与统计口径。
重算会碰到一个边界:已经发出去的报表,原来的值与重算后的值要分开保存。
对账自检
对账自检表一行一对:现算列与物化列。一支纯函数按日比对每一对,输出差异行。
| 差异行字段 | 含义 |
|---|---|
| 检查码 | 哪一对列、哪一项检查 |
| 分支 | 哪个分支的数据 |
| 日期 | 哪一天 |
| 项目 | 哪个指标或项目 |
| 物化值 | 存下来的值 |
| 期望值 | 现算出来的值 |
| 差值 | 两者之差 |
纯函数指同样的输入得到同样的输出,不读外部状态。
自检还有一道覆盖检查:新增一个物化列,必须登记对账,或者写明它为什么不属于口径,否则自检直接点名。对账行指向一个没有登记的来源,也报红,不静默跳过。
余额是期初快照加上流水累计,另有抽样重放,用流水从头再算一遍,与存下来的余额核对。
差异行直接指出哪一天、哪个指标、差多少,财务负责人不必从头翻账。

图里每一项都是同一个指标的两份数相比,不是与外部来源相比;差异非零时,这里出的是差异行,不会自动改平。
差异的处理
自检只出差异行,不自动平账。处理顺序是:先取数,查明原因,定性;再裁定怎么修:冲回更正,或者修口径。口径修好之后,物化值按书面执行令重新物化。不生成自动的调节分录。
有的对账做法把「差异非零」当作拦截入账的条件。银行流水在付款之后才产生,不能做入账的前提;实务里的差异常是在途与时间差,硬阻断会堵住正常业务。SZV 的自检没有这一步,只出差异行。
另外的核对
| 核对 | 比什么 | 怎样把关 |
|---|---|---|
| 确认恒等式 | 已确认的收款加未确认的收款,等于实收 | 哪些来源的收款需要财务确认,写在确认通道定义表里,是版本化数据;恒等式由读取入口的用例核对 |
| 导入核对 | 导入时,来源端的聚合数与目标库逐项比对 | 只读,不写库,输出只含聚合数;全部相平才算通过 |
两者各自管一件事,与逐日的流水核对互不替代。
限制与不适用
- 流水只增不减,更正会让流水变长。
- 差异靠人定性,系统只出差异行。
- 不含银行流水接入。需要与银行流水逐笔自动对平时,这套机制不够。
其他做法
| 做法 | 它解决什么 | 为什么不用 |
|---|---|---|
| 原地更正旧行 | 流水短,看起来干净 | 改过之后,原值与更正时间只能靠另一份记录补,两份记录对不上时没人说得清哪个对 |
| 系统自动生成调节分录把差异平掉 | 差异自动消失 | 差异的原因没人定性,错账被盖过去;SZV 的自检只出差异行,不自动生成调节分录 |
与常见做法对照
TigerBeetle 是一个专做账务的开源数据库。它的文档写明:转账一旦记录就不能擦除,改错用另一笔转账冲回;借贷等额相反。
| 性质 | SZV 的资金流水 | TigerBeetle |
|---|---|---|
| 不可改写 | 触发器拒绝改删;动钱表由定义表统一上锁 | 记录之后不可擦除 |
| 更正 | 冲回行,引用原单号 | 另一笔转账 |
| 余额 | 期初快照加流水累计,抽样重放 | — |
「不可改写」与「更正」两行,做法同类。
验收时可以问的问题
- 请现场查一条冲回行,对照原单号,看它是否按原收款的每一条腿逆向记了一笔。
- 请演示口径变更之后重算历史:已经发出的报表,原来的值与重算后的值分别存在哪里。
- 请演示一次抽样重放:用流水从头再算一遍,与存下来的余额核对。
- 需要接入银行流水做逐笔对账时,由谁接入,与流水核对怎样分工,按什么约定。