一笔租赁已经收取两百分钱,同时已经提供两小时设备使用服务。这两个事实有关联,但不能直接相加。四小时服务的承诺也不能因实际只提供两小时,就被改写成两小时。交换模型需要保存各自的资源、单位、参与方以及承诺与实际发生的联系。

REA 提供了一组观察经济交换的概念。本文依据原始研究辨认这些概念,再建立一个小型合成样本,检查部分履约、重复事件、超额履约和价格义务变化。脚本只是本篇受限解释的校验器,没有声明实现完整 REA 本体或会计系统。

原始概念与本篇的取舍

McCarthy 在一九八二年的论文中提出资源、经济事件、经济代理及其关系。作者网站提供原论文,并把后续扩展研究单独列出。Geerts 与 McCarthy 的扩展分析讨论了经济交换、对偶关系以及承诺等概念;承诺属于扩展部分,不能把所有后续机制都归到最初论文。作者资料与原始论文入口

资源关注具有经济价值的对象,事件描述经济变化,代理参与交换。对偶关系把一次交换中付出与获得的事件联系起来。扩展研究还区分已发生、已承诺与政策层面的可能或应当发生;这些区分有助于避免把愿望、义务和实际结果放进同一条记录。Geerts与McCarthy,扩展REA分析

教学样本把资源分为设备使用小时和现金分,代理只有租赁方与客户。这里建模的是使用服务的交付,没有表达相机所有权转让。实物相机的序列号、维修状态与仓库保管关系仍在其他模型中;不能根据服务减少两小时就从资产目录删除相机。

样本的双方都以稳定标识表示,不把姓名当作身份。代理在一侧提供服务,在另一侧接收付款,所以 provider 和 receiver 是事件中的角色。同一个租赁方可以出现在不同方向的记录里,不必为收款方和服务方复制两个组织对象。

flowchart LR
  R[租赁方] -->|提供| U[设备使用事件 两小时]
  U -->|接收| C[客户]
  C -->|提供| P[现金事件 两百分]
  P -->|接收| R
  U ---|本样本对偶联系| P
  U --> H[设备使用资源 单位小时]
  P --> M[现金资源 单位分]

图中一条对偶联系只表示这两个样本事件属于一次交换关系,没有暗含两小时与两百分在数学上相等。价目规则、税费和优惠可能改变对应金额。数量相等与价值关联必须分开,否则改价格就会迫使资源数量跟着改变。

承诺与兑现保持两层记录

models/E07/exchange.json 包含两项承诺:租赁方向客户提供四小时设备使用,客户向租赁方支付四百分。实际事件分别记录两小时与两百分,并通过 commitment 字段引用相应承诺。模型文件显式给出资源及代理引用,程序可以检查引用是否存在。

正常场景得到剩余服务两小时、剩余付款两百分。这个计算按每项承诺分别累加事件数量,再从承诺数量扣除;它不会把不同资源的数值放进同一个余额。两个剩余值必须连同单位展示,只有数字的仪表盘会掩盖业务含义。

完成场景复制相同数量的新事件,使用新的事件编号,并为新增服务与现金事件建立联系。重新计算后,两项剩余义务均为零。这证明在当前样本中多次实际发生可以共同兑现一项承诺;并不要求一次承诺只对应一条事件。

这也解释了为什么实际执行不能覆盖原承诺。覆盖之后,只能知道最终发生了多少,无法说明最初答应多少以及还差多少。原义务和实际历史分开保存,取消、折让和追加服务才有明确的参照对象。

flowchart TD
  S[服务承诺 四小时] --> A[实际使用 两小时]
  S --> B[后续使用 两小时]
  A --> X[按承诺累加 已兑现四小时]
  B --> X
  X --> Z[剩余零]
  P[付款承诺 四百分] --> C[已收现金 两百分]
  P --> D[后续现金 两百分]
  C --> Y[按承诺累加 已兑现四百分]
  D --> Y
  Y --> Q[剩余零]

本篇没有加入服务发生时间,因此这幅图也不证明两个服务事件对应不同的实际时间段。若两条记录描述了同一次交付,只给它们不同编号仍可能重复计量。实际系统需要业务幂等键和可追踪凭据;本次实验仅检查模型内编号重复,不能承担外部事实去重。

校验器检查什么

程序先建立承诺和事件索引,再核对编号没有重复。事件引用的承诺必须存在;事件的资源、提供方和接收方必须与承诺一致。一个使用事件即使数量合法,也不能拿付款承诺作兑现目标,因为两者资源和方向不同。

每项数量必须是正整数。零数量不是有效发生记录,负数也不能在这里偷渡成撤销。若业务需要退款或冲销,应设计明确的事件类型和原事件引用,并重新讨论符号和汇总政策。本模型拒绝负数,换取当前累计逻辑的简单边界。

累计兑现超过承诺数量时,程序报告 over-fulfillment。把首笔服务改为五小时,四小时承诺便会失败。这是样本政策,不宣称所有企业都禁止超额履约;有些业务允许先交付再补合同,那就必须改变约束并留下对应验收场景。

对偶联系的两端必须引用存在的事件,双方方向也必须相反。引用不存在的现金事件会被拒绝。程序没有要求每个事件必须立即找到对偶事件,因为先交付后付款在数据录入时可能暂时只有一侧;但它也没有实现未结清交换的期限管理。

正常执行共检查十个场景。其中五个字段变异覆盖超量、零数量、未知代理、资源错配和未知承诺。另有重复事件、悬空对偶联系、部分兑现、完整兑现与价格义务变化。原始日志打印违反的规则名,便于把失败追到具体关系,而不是只看到一个总失败标记。

与教学账本逐项对照

账户分录与费用 使用账户和分录说明费用、付款以及记账。REA 样本保留服务和现金的经济事实,两边的对象分类并不相同。账户不是本篇资源字典中的一个同义词,借贷分录也没有直接变成提供方与接收方。

例如一笔现金事件可以作为记账输入的来源,但产生哪些账户分录仍需要明确的会计政策。税费、押金、预收款和收入确认在本实验中没有定义,因此不能从收款两百分直接声称已经确认相同金额的收入。这里对照的是模型语义,未执行法定会计或财务合规判断。

计划资源与承诺 还处理日历容量与具体设备分配。本篇四小时服务承诺没有起止时间,也没有指向某台相机,因此不能用它证明两个客户不会争用同一设备。容量模型需要时间窗口,交换模型需要服务与支付的关系,二者应通过明确标识关联。

如果后续建立映射,可以让一项交换承诺引用主线预留编号,同时让实际使用事件引用交付凭据。取消预留是否取消支付义务,则需要合同政策决定,不能按对象名称自动级联删除。已经发生的现金事件更不能随预留删除,否则经济历史与剩余义务都会失真。

这种对照保留了两个模型各自擅长回答的问题:账本按账户归集,交换模型解释资源与参与者之间发生什么。正文没有把两种模型强制融合为一个巨型对象,也没有声称存在可以直接生成全部分录的通用映射。

价格变化不能重写收款历史

变化卡将付款承诺从四百分改为五百分,已经登记的现金仍为两百分。程序观察到剩余付款从两百分变为三百分,服务剩余仍为两小时。新义务与旧发生之间的差额是本次变化的输出,不通过修改历史现金来取得表面平衡。

在脚本中,变化通过深复制输入后修改完成,原输入保持不变。这只是两份模型快照之间的实验,没有实现合同修订流程。真实变更还需要记录修订版本、生效时间与参与方同意,不能把编辑 JSON 本身当作完成合同变更。

本篇也没有要求服务价格固定为每小时一百分。首个样本恰好具有这个比例,变化卡故意打破按旧比例推断余款的习惯。若系统存在独立定价模型,应由定价结果生成承诺金额,并把采用的价格版本保留下来。

剩余为零只表示当前记录数量满足当前义务。它不证明支付已经通过银行清算、设备确已交付或所有法律义务已经终止。实验里的事件都是显式给出的合成输入,实际系统还要验证外部凭据的来源与状态。

复跑与观察

下载 实验包,保持目录结构,使用 Python 标准库入口执行。

1
bash examples/software-modeling/labs/E07/run.sh

正常入口打印十项 PASS 并返回零。末尾追加 over,会把实际服务改为五小时,打印超额兑现标签并返回一。源码、模型和两种运行结果在包内的 E07 对应目录中,PYTHON_BINARY 可以选择解释器。

读者可以将付款承诺改为五百分后再次运行相关计算,检查余款是否为三百分,并确认旧现金事件仍为两百分。若改成另一种资源或币种,现有字典和累计策略也需要一起审查;当前样本没有汇率换算和复合单位,跨单位直接相减不在其有效范围内。