1
0
forked from erp-dev/erp
Files
erpnew/business/ARCHITECTURE.md
2025-12-01 15:22:59 +08:00

4.4 KiB
Raw Blame History

business 模块结构与设计说明

本文档记录业务模块当前的结构、关键约定以及未来演进需要遵循的决策背景,防止在迭代中遗失设计意图。

1. 模块职责

business 负责“业务单据”领域目前包含采购单PurchaseOrder与销售单SalesOrder同时保留可扩展至退货单等更多对象的通用框架。核心职责

  • 聚合与校验业务明细数据
  • 通过服务层触发库存stock、财务等下游模块
  • 统一处理审批、作废等状态流转

2. 模型抽象

2.1 OrderItemsAggregationMixin

封装订单明细聚合逻辑,默认访问 items 关联,可通过 order_items_accessor 指定其他关联名。提供:

  • get_total_amount()
  • get_total_quantity()
  • get_total_diff_quantity()

这些方法仅关心明细结构,不关心订单方向。

2.2 OrderDirectionMixin

用于获取带方向的金额,约定:

  • get_direction() 返回 1(正向/入库)或 -1(负向/出库)
  • get_signed_total_amount() 在内部调用 get_total_amount() 并乘以方向

任何需要“正负金额”的业务(财务统计、库存红冲)都应依赖此能力,而不是重复编写正负逻辑。

2.3 OrderCounterpartyMixin

对外暴露统一的 get_counterparty() 接口,通过 get_counterparty_field_name()(或 counterparty_field_name 属性)确定具体业务主体字段。这样采购单/销售单分别返回 SupplierCustomer,但调用方只需面对一个接口。

2.4 订单类型

当前业务对象覆盖:

  • PurchaseOrder(采购单):direction=1counterparty=supplier,含库存明细。
  • SalesOrder(销售单):direction=-1counterparty=customer,含库存明细;严进严出模式需记录 consume_detail_ids
  • PaymentOrder(付款单):direction=-1counterparty=supplier,仅金额字段,不触发库存。
  • ReceiptOrder(收款单):direction=-1counterparty=customer,仅金额字段,不触发库存。
  • SupplierBalance / CustomerBalance:实时维护供应商应付、客户应收余额,所有审批通过的带金额单据都会写入,供查询接口和报表使用。
  • BalanceChangeRecord(余额变动记录):仿照 stock.StockSnapshot 的“流水 + 快照”模式,记录每一次余额写入的来源、方向、前后余额与可能的冲抵关系,为财务审计与未来的红冲能力提供依据。

通过 mixin所有单据都具备

  • 统一的金额聚合与方向计算(资金/库存可共用 get_signed_total_amount()
  • 一致的业务主体接口(供应商/客户)
  • 可扩展的服务与序列化模式(有无库存由具体模型决定)

3. 服务层约定

  • business.services 负责 orchestration与 API 解耦。审批、作废、触发库存等流程必须先在服务层实现,再暴露给 API。
  • 任何涉及库存的逻辑都必须通过 stock.services.StockFlowService,不得直接操作库存模型,保持模块边界清晰。
  • 红冲/对冲等高级动作应由业务模块提供入口(例如 PurchaseOrder 红冲),但最终仍调用库存服务完成实际库存变动。

4. 未来演进建议

  1. 新增单据:若未来出现调拨单、退货单或更多资金类单据,优先复用 OrderDirectionMixin + OrderCounterpartyMixin(如有明细再叠加 OrderItemsAggregationMixin),仅通过 get_direction() / get_counterparty_field_name() 区别方向与主体,减少重复实现。
  2. 审批/状态机:采购与销售如需共享状态流转,可提炼状态机或 service 层 mixin而无需在模型层合并。
  3. 统计与报表:财务/库存统计应依赖 get_signed_total_amount() / get_direction(),确保采购/销售、退货/正向都能通过统一接口处理。
  4. 余额审计:任何会写入 Supplier/CustomerBalance 的流程必须通过 BalanceService,以便自动生成 BalanceChangeRecord。审批通过后禁止作废,若未来需要冲销,必须新建红冲记录并维护 offset_to/offset_id 链路。
  5. 文档同步:新增单据或服务时必须更新本文件,描述新增模型如何复用 mixin、如何影响下游模块保持设计透明。

以上约定的目标是:保持各类业务单据的独立性,同时通过 mixin/服务层抽象复用绝大多数公共逻辑。如需变更此架构,请在评估后更新本文件,说明原因与迁移方案。