Files
dealerhub/PROGRESS_PHASE3_FINANCE.md

159 lines
9.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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% 通过)
```bash
$ 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
===== 全部通过 =====
```