Files
dealerhub/PROGRESS_PHASE3_FINANCE.md

9.8 KiB
Raw Permalink Blame History

dealerhub · 阶段 3 完整财务(总账系统 + 业财一体化)实施与验收报告

目标:实现对标管家婆“财贸双全”的核心总账与业务一体化财务系统,涵盖会计科目、会计期间、记账凭证、借贷校验、往来核销、自动记账、期末结转损益与结账、财务三大主表(科目余额表、资产负债表、利润表)及明细分类账。


一、架构设计与核心模型

本模块由两大部分深度融合构成:

  1. 往来管理(AR / AP):支持销售应收、采购应付、收款单、付款单、跨单及部分核销明细。
  2. 总账核算(General Ledger):支持会计准则科目树、月度会计期间、借贷平衡复式记账凭证、凭证过账/作废状态机、期末损益结转、反结账以及实时报表生成。

1. 数据模型(apps/finance/models.py)

模型 表名 说明
Account finance_account 会计科目(资产/负债/所有者权益/收入/费用 5 大类,借/贷正常余额方向,客户/供应商辅助核算,系统预置保护)
Period finance_period 会计期间(YYYY-MM,起止日期,未结 open / 已结账 closed 状态流转)
Voucher finance_voucher 记账凭证(编号 V{YYYYMM}{seq:04d},期间关联,业务来源追溯,借贷合计校验,草稿 draft / 已过账 posted / 已作废 cancelled)
VoucherEntry finance_voucher_entry 凭证分录(科目外键、借方/贷方金额、摘要、客户/供应商辅助核算外键)
Receivable finance_receivable 应收单(客户关联、单号 RC...、总额、已收、剩余未收 balance)
Payable finance_payable 应付单(供应商关联、单号 PY...、总额、已付、剩余未付 balance)
Receipt finance_receipt 收款单(客户关联、收款方式、过账状态)
Payment finance_payment 付款单(供应商关联、付款方式、过账状态)
Allocation finance_allocation 核销明细(收款冲应收、付款冲应付的多对多核销关系)

二、业财一体化(业务单据自动过账生成凭证)

当租户初始化会计科目后,业务流程中的确认动作会自动生成并过账记账凭证,实现业务数据与财务总账的实时同步:

  1. 销售单确认(apps/sales/services.py:confirm_sales_bill):
    • 扣减库存,生成应收单
    • 自动生成销售收入凭证:
      • 借:1122 应收账款(辅助核算:对应客户)
      • 贷:6001 主营业务收入
    • 自动根据出库加权平均成本结转销售成本凭证:
      • 借:6401 主营业务成本
      • 贷:1403 库存商品
  2. 进货单确认(apps/purchase/services.py:confirm_purchase_bill):
    • 增加库存,生成应付单
    • 自动生成采购入库凭证:
      • 借:1403 库存商品
      • 贷:2202 应付账款(辅助核算:对应供应商)
  3. 收款单核销(apps/finance/services.py:allocate_receipt):
    • 校验核销金额一致性与应收单余额
    • 自动生成收款凭证:
      • 借:1002 银行存款(或 1001 现金)
      • 贷:1122 应收账款(按核销单据逐笔挂客户)
  4. 付款单核销(apps/finance/services.py:allocate_payment):
    • 校验核销金额一致性与应付单余额
    • 自动生成付款凭证:
      • 借:2202 应付账款(按核销单据逐笔挂供应商)
      • 贷:1002 银行存款(或 1001 现金)

三、期末处理与财务报表

1. 期末损益结转与结账(close_period)

  • 自动汇总当期所有已过账业务凭证中的收入科目与费用科目。
  • 将收入科目贷方发生额借记转出,费用科目借方发生额贷记转出。
  • 差额结算本期净利润(盈利贷记 4103 本年利润,亏损借记 4103 本年利润)。
  • 生成并在当期自动过账 period_close 凭证,使损益科目期末余额归零。
  • 将期间置为 closed。已结账期间严格禁止新增、修改或过账凭证。

2. 反结账(reopen_period)

  • 必须按倒序反结账(不存在更晚已结期间)。
  • 自动作废当期期末结转损益凭证,恢复期间为 open 状态。

3. 财务三大报表与明细账

  • 科目余额表(试算平衡表 trial_balance):
    • 输出期初借/贷、本期发生借/贷、期末借/贷。
    • 自动校验试算平衡:期初借==贷,本期发生借==贷,期末借==贷。
  • 资产负债表(balance_sheet):
    • 累计统计至指定期间期末的资产、负债和所有者权益。
    • 动态计算未结转损益(unclosed_profit = 累计收入 - 累计费用),保证在期末结账前后始终严格满足会计恒等式: \text{资产总计} = \text{负债总计} + \text{所有者权益} + \text{未结转本期损益}
  • 利润表(income_statement):
    • 统计期间营业收入、主营业务成本(COGS)、毛利润、期间费用、净利润。
  • 明细分类账(account_ledger):
    • 查询指定科目(如 1002 银行存款、1122 应收账款)的期初余额、每笔凭证发生额、辅助核算对象和连续滚动余额。

四、REST API 接口清单

所有接口位于 /api/v1/finance/ 命名空间下,天然支持 JWT 鉴权与 X-Tenant-Id 多租户隔离:

接口 方法 说明
/api/v1/finance/accounts/ GET / POST 会计科目列表与维护
/api/v1/finance/accounts/init-chart/ POST 一键初始化 22 个国家标准会计科目
/api/v1/finance/periods/ GET 会计期间列表
/api/v1/finance/periods/{id}/close/ POST 会计期间期末结转与结账
/api/v1/finance/periods/{id}/reopen/ POST 会计期间反结账
/api/v1/finance/vouchers/ GET / POST 凭证列表,POST 支持提交 entries 嵌套分录及自动借贷校验
/api/v1/finance/vouchers/{id}/post/ POST 凭证过账
/api/v1/finance/vouchers/{id}/cancel/ POST 凭证作废
/api/v1/finance/voucher-entries/ GET 凭证分录查询(只读)
/api/v1/finance/receivables/ GET 应收单列表(含 customer_code、balance 等字段)
/api/v1/finance/payables/ GET 应付单列表(含 supplier_code、balance 等字段)
/api/v1/finance/receipts/ GET / POST 收款单列表及录入
/api/v1/finance/payments/ GET / POST 付款单列表及录入
/api/v1/finance/allocations/ GET 核销流水明细
/api/v1/finance/reports/trial-balance/ GET 科目余额表(参数:period=YYYY-MM)
/api/v1/finance/reports/balance-sheet/ GET 资产负债表(参数:period=YYYY-MM)
/api/v1/finance/reports/income-statement/ GET 利润表(参数:period=YYYY-MM)
/api/v1/finance/reports/ledger/ GET 明细分类账(参数:account=1002&period=YYYY-MM)

五、验证与验收证据

1. 单元与集成测试套件(75 个测试 100% 通过)

$ python -m pytest tests apps/core/tests/ -p no:cacheprovider
======================= 75 passed, 100 warnings in 1.32s =======================
  • tests/test_full_finance.py:覆盖科目初始化、期间计算、凭证借贷平衡拒绝、辅助核算强制校验、凭证过账作废状态机、销售与成本自动凭证、采购与付款自动凭证、收款核销自动凭证、期末损益结转与反结账、试算平衡、资产负债表等式、利润表计算、明细账、所有 8 个 REST API 接口(10/10 通过)。
  • tests/test_finance.py:覆盖既有应收应付创建、部分付款核销、超额核销拒绝、金额不匹配拒绝(8/8 通过)。
  • tests/test_e2e.py:端到端全业务链(采购→付款→销售→收款→对账结清)(3/3 通过)。
  • tests/test_catalog.py, test_partner.py, test_inventory.py, test_purchase.py, test_sales.py:全量业务模块(54/54 通过)。
  • apps/core/tests/test_workflow.py:状态机服务(14/14 通过)。

2. 内网服务器(lan-19216857)容器化部署与全量冒烟

  • 服务器:192.168.5.7:18050
  • 运行环境:PostgreSQL 16 (pg-main 共享实例) + Granian 2.8.2 ASGI 服务器 (4 Workers)
  • 迁移状态:finance.0002_account_period_voucher_voucherentry_and_more... OK
  • 镜像状态:Docker 镜像 dealerhub-backend:latest 已在服务器本地完成构建并更新。
  • 冒烟脚本输出(bash /home/chunyu/dealerhub/smoke_full.sh):
===== dealerhub 完整业务链冒烟 =====
[1] 创建测试实体
  product id=6, warehouse id=8, supplier id=6, customer id=6
[2] 在容器内创建进货单并过账(写库存 + 生成应付)
  purchase_bill: PB202609070003 state=confirmed total=160
[3] 检查库存 + 应付
  stocks: P094333/W094333 on_hand=20.0000 avg_cost=8.0000
  payables: PY202609070003 S094333 total=160.0000 status=open
[4] 在容器内创建销售单并过账(扣库存 + 生成应收)
  sales_bill: XS202609070003 state=confirmed total=84
[5] 检查应收(应该 7*12=84)
  receivables: RC202609070003 C094333 total=84.0000 balance=84.0000 status=open
[6] 检查财务凭证(业财一体化自动生成凭证)
  vouchers count = 6
    V2026090006 source=sale_cost 借/贷=56.0000/56.0000 [posted] 销售单 XS202609070003 结转成本
    V2026090005 source=sale      借/贷=84.0000/84.0000 [posted] 销售单 XS202609070003 确认
    V2026090004 source=purchase  借/贷=160.0000/160.0000 [posted] 采购单 PB202609070003 确认
[7] 检查科目余额表(试算平衡)
  trial_balance is_balanced = True  rows = 5
  期末借方合计 = 488.0  期末贷方合计 = 488.0
[8] 检查资产负债表与利润表
  balance_sheet balanced = True  资产总计 = 376.0  负债及权益 = 376.0
  income_statement 收入 = 168.0  成本 = 112.0  毛利 = 56.0  净利润 = 56.0
===== 全部通过 =====