Skip to content

Accounting 期间与账务 ​

把「一笔结算」变成「一条可入账的分录」,并把时间锁进期间。


职责 ​

负责不负责
期间的开关与重开通用会计引擎(多准则、税务)
分录与四科目多币种换算与重估
期间门禁(关闭后拒写)报表与 BI
结算 → 分录派生真实资金转移

期间模型 ​

periodId = `${scope}:${refId}`
scope用途
order / task按单结:一单一个期间,结算即出分录,跨月不拆
calendar自然月汇总视图(只读,不参与门禁)

状态机:

open ──close──▶ closed ──reopen(需原因)──▶ open

reopen 会累加 reopenCount——审计要看到这个期间被动过几次。


门禁:在存储层,不在应用层 ​

情况结果
写 /periods/{id}/{child} 且期间已关闭409
已重开过的期间 + 业务发生时间不可信(inferred)400
写 /periods/{id} 根路径放行(否则 close 之后无法 reopen,自己锁死)

绕过记账服务直接写状态层,同样被拒。


四科目 ​

科目含义
escrow_held托管中、尚未归属的资金
payable_supplier应付供给方
payable_platform应付平台服务费
refundable_buyer应退买方

刻意不做收入/成本/费用/税/资产的完整科目体系。


接口 ​

MethodPath说明
GET/api/accounting/periods/:periodId期间详情
POST/api/accounting/periods/open开期间(幂等)
POST/api/accounting/periods/:periodId/close关账(幂等)
POST/api/accounting/periods/:periodId/reopen重开(必须给原因)
GET/api/accounting/periods/:periodId/entries期间分录
GET/api/accounting/periods/:periodId/balance科目余额与试算平衡表
POST/api/accounting/periods/:periodId/verify校验借贷平衡(不平 409)

写操作(open / close / reopen)是账务控制面,目前以 platform 身份执行; 生产前应限制为管理员。


分录怎么产生 ​

escrow.settle()  ← 唯一出口
  → 借 escrow_held        amount
    贷 payable_supplier    toAgent
    贷 refundable_buyer    toBuyer
    贷 payable_platform    toPlatform

零金额行不输出。金额守恒由托管层保证(toAgent + toBuyer + toPlatform === amount), 所以分录的借贷平衡是结构保证,不靠记账代码自觉。


七条不变量 ​

#不变量
I1每笔分录 Σdebit === Σcredit
I2期间内 Σdebit === Σcredit
I3Σ结算分录 === 托管金额
I4已关闭期间不接受新分录
I5跨期调整必须指向已关闭期间
I6分录不可修改,只能冲销
I7单笔分录币种一致

边界 ​

  • 跨币种只预留字段,结算必须拆成多笔分录
  • 不做通用会计引擎
  • 自然月汇总视图尚未实现为正式功能
  • inferred 只对「被重开过的期间」强制拒绝

源码 ​

libs/modules/src/accounting/
├── interfaces/period.interface.ts   期间
├── interfaces/journal.interface.ts  分录 + 科目
├── services/period.service.ts       开关重开
└── services/journal.service.ts      记账 + 不变量

libs/modules/src/state/services/period.guard.ts   门禁(存储层)
libs/modules/src/escrow/services/settlement-journal.ts  结算 → 分录

Released under the MIT License.