forked from erp-dev/erp
feat: correct first
This commit is contained in:
@@ -6,13 +6,31 @@
|
||||
|
||||
## 1. 功能概览
|
||||
|
||||
- **客户对账单**:聚合指定客户的销售单、销售退货单、收款单,统一展示正负金额、当前余额以及累欠金额。
|
||||
- **客户对账单**:聚合指定客户的销售单、销售退货单、收款单,以及外部来源的 statement-only 业务依据,统一展示正负金额、当前余额以及累欠金额。
|
||||
- **供应商对账单**:聚合指定供应商的采购单、采购退货单、付款单,展示待付金额的增减与余额。
|
||||
- **排序规则**:固定按 `occurred_at -> recorded_at -> source_id` 倒序排列,不支持外部修改。
|
||||
- **金额方向**:
|
||||
- 客户:销售单记入 `positive_amount`(增加应收),销售退货/收款记入 `negative_amount`(减少应收)。
|
||||
- 供应商:采购单记入 `positive_amount`(增加待付),采购退货/付款记入 `negative_amount`(减少待付)。
|
||||
- **余额来源**:调用 `BalanceService`,每次请求仅查询一次,并冗余在每条记录中,便于前端表格或统计组件使用。
|
||||
- **余额来源**:供应商对账单直接使用余额表;客户对账单在存在外部 statement-only 业务依据时,会基于余额表做一次“仅用于 statement 展示”的临时口径修正。
|
||||
|
||||
### 1.1 外部 statement-only 业务依据
|
||||
|
||||
当客户的历史 `sale` / `sale_return` 来自外部系统、且不希望落入核心 `SalesOrder` / `SalesReturnOrder` 时,系统会把它们存入:
|
||||
|
||||
- `business.ExternalCustomerStatementOrder`
|
||||
|
||||
这些记录:
|
||||
|
||||
- 只参与客户对账单计算
|
||||
- 不参与库存流转
|
||||
- 不参与核心销售单审批链
|
||||
- 不修改持久化 `CustomerBalance`
|
||||
|
||||
在对账单响应中,它们会以以下 `source_type` 出现:
|
||||
|
||||
- `external_sales_order`
|
||||
- `external_sales_return_order`
|
||||
|
||||
---
|
||||
|
||||
@@ -41,8 +59,8 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"customer": 6,
|
||||
"customer_name": "杭州零售商",
|
||||
"counterparty": 6,
|
||||
"counterparty_name": "杭州零售商",
|
||||
"records": [
|
||||
{
|
||||
"source_type": "sales_order",
|
||||
@@ -104,18 +122,58 @@
|
||||
| `cumulative_amount` | 当前记录输出前累计的对账金额(正负抵消)。 |
|
||||
| `current_balance` | 余额表的最新应收/待付款快照;每条记录重复提供,便于表格展示。 |
|
||||
| `arrears_amount` | 累欠金额,等于 `current_balance - cumulative_amount`,表示该记录时刻的实时欠款/待付款。 |
|
||||
| `remarks` | 统一备注字段。所有 record 都会返回;无备注时为空字符串。 |
|
||||
| `extra` | 预留字段,后续可扩展批次、仓库等信息。 |
|
||||
| `summary` | 记录集中正负金额的求和,供前端快速展示。 |
|
||||
|
||||
对于外部 statement-only 业务依据,`extra` 当前会额外包含:
|
||||
|
||||
- `external_source_id`
|
||||
- `external_customer_id`
|
||||
- `settlement_method`
|
||||
|
||||
对客户对账单来说,当前还可能出现两种新的 `source_type`:
|
||||
|
||||
- `external_sales_order`
|
||||
- `external_sales_return_order`
|
||||
|
||||
`remarks` 的来源统一如下:
|
||||
|
||||
- 本地采购/销售/退货/收付款单:直接取对应单据的 `remarks`
|
||||
- 外部 statement-only 业务依据:取 `ExternalCustomerStatementOrder.remarks`,其中会包含同步时整理过的 `BeiZhu` / `BeiZhuC` / `BeiZhuD` / `MeoD` 文本
|
||||
|
||||
---
|
||||
|
||||
## 4. 业务规则
|
||||
|
||||
1. **审批依赖**:只有审批通过的单据才会出现在对账单中;审批完成后若需冲销则需走红冲流程。
|
||||
2. **数据一致性**:在审批事务内同步写入 `BalanceService` 及 `BalanceChangeRecord`,对账单直接基于这些模型计算,因此账面数据与业务状态保持一致。
|
||||
2. **数据一致性**:在纯本地业务场景下,对账单直接基于审批后的业务单据和余额表计算,因此账面数据与业务状态保持一致。
|
||||
3. **幂等保障**:`BalanceService` 在审批中使用行级锁和 `select_for_update`,避免重复写入;对账单查询为只读操作,不影响事务。
|
||||
4. **扩展字段**:如需在对账单中加入汇总、备注、仓库信息,可在视图构建 `extra` 字段或通过 serializer context 注入新的统计字段。
|
||||
|
||||
### 4.1 客户余额口径边界
|
||||
|
||||
这是本次修正最重要的边界说明。
|
||||
|
||||
当客户存在 `ExternalCustomerStatementOrder` 时:
|
||||
|
||||
- `GET /customers/<id>/balance/` 仍返回数据库中持久化的 `CustomerBalance.balance`
|
||||
- `GET /customers/<id>/statements/` 中每条记录的 `current_balance` / `arrears_amount`,会基于“本地余额 + 外部业务来源净额”做一次临时口径修正
|
||||
|
||||
因此,在存在外部 statement-only 业务依据的客户上:
|
||||
|
||||
- 余额接口和对账单接口的余额展示,可能暂时不完全一致
|
||||
|
||||
这是当前设计的有意结果,因为:
|
||||
|
||||
- 我们需要让对账单拥有完整的“应收业务依据”
|
||||
- 但又不希望把外部历史业务单写入核心销售链,进而污染库存与审批语义
|
||||
|
||||
换句话说:
|
||||
|
||||
- `CustomerBalance` 代表 ERP 内部正式余额账
|
||||
- 客户对账单在此场景下代表“兼容外部历史业务依据后的展示口径”
|
||||
|
||||
---
|
||||
|
||||
## 5. 场景示例
|
||||
|
||||
Reference in New Issue
Block a user