Files
docs/财务管理/README.md
T

387 lines
29 KiB
Markdown
Raw 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.
# 财务管理闭环盘点与范围建议
## 当前确认:一件代发客户资金账户(2026-09-05)
当前对话已将资金账户作为一件代发的前置节点重新纳入范围,并覆盖本文后续历史章节中“钱包不做”的旧结论。首批固定为 CNY。账户分别保存实际余额、冻结金额、授信额度、已用授信和冻结授信;`总可用余额 = 实际余额 + 授信额度 - 已用授信 - 冻结金额`,`可用授信 = 授信额度 - 已用授信 - 冻结授信`。扣款及业务冻结先使用未冻结的实际资金,再使用授信;充值先归还已用授信,剩余金额增加实际余额。
客户选择固定或自定义金额,查看后台配置的微信/支付宝静态收款码,付款后上传 JPG/PNG 截图形成待审核申请。平台在客户账户明细顶部审核或驳回,也可手工充值、扣款和设置客户授信额度;每次变动写不可变账户流水。新账户授信额度读取 `baiyue.finance.wallet.default-credit-limit`,默认 `0.00`,平台设置的客户额度随后独立持久化。Finance 还提供仅服务令牌可访问、按业务类型和业务单号幂等的冻结、结算和释放接口,供一件代发等模块接入。审核、账户更新、流水、冻结记录和幂等结果在 Finance 单事务内完成,文件内容仍归 File 服务。接口契约见 [客户资金账户 OpenAPI](openapi/finance-wallet-v1.yaml)。
> 盘点日期:2026-08-10
> 当前状态:F0/F1 已有 Finance 服务、数据库、权限、Admin/Client 页面和基础接口;订单与客户 11 个 P0 operation 的目标契约已冻结,本地实现验收按独立 G1-G4 证据矩阵均为 `PASS`;真实 MySQL、测试环境 HTTP 冒烟和领导页面验收仍需单独执行
> 盘点范围:入库计费现状、平台后台财务原型、Admin/Client/Firstleg 当前实现
> 结论口径:本文区分“代码已实现”“原型展示”和“建议范围”;原型功能不自动成为开发范围。
## 费用来源扩展确认(2026-09-02)
- Finance 继续保持独立服务和独立数据库;业务服务只生产费用事实,不能直接写财务单据或余额。
- Firstleg 入库费用继续按客户和入仓码进入 Finance;柜级公共费用必须先按柜内真实客户与业务订单原子分摊,再逐客户进入应收应付。入仓码是可选引用:存在时必须校验真实归属,不存在时保留订单/业务单号,禁止伪造入仓码。
- Lastleg 的海外入仓、海外采购、本土卡车、本土散板和海外仓服务费使用统一版本化来源。审核通过、调整和作废同事务写海外 Outbox,通过 Event Bridge 向国内 Finance 投递完整不可变快照;Finance 不跨海外数据库回查。
- Finance 以 `sourceSystem + sourceType + sourceFeeId + sourceVersion` 唯一入池;重复事件幂等,同版本不同哈希拒绝,已进入有效账单或结算单的来源禁止替换/作废。
- 海外仓服务费只强制客户、海外仓和业务编号;入仓记录/入仓码按真实业务选填,月租、仓租等无入仓码费用仍可入池。
当前本地实现包含柜级分摊 API/Admin 录入、海外费用来源 API、跨区事件、Finance 通用消费入口及数据库脚本。测试环境真实 HTTP、数据库迁移实跑和页面截图仍须部署后单独验收。
## 测试环境部署状态(2026-08-12)
Finance 全链路测试环境实跑报告为 `baiyue-firstleg/reports/finance-full-acceptance-20260812.json`:共 430 项,411 项通过,19 项失败。当前结论是 `DEPLOYMENT_BLOCKED`,不是脚本契约测试失败,也不是验收通过;19 个失败项继续以 deployment blocker 和 coverage gap 原样保留,禁止通过模拟数据或修改报告伪造通过。
当前主要部署阻断:
- Gateway 健康,但 `/finance-service/v3/api-docs` 返回 HTTP 503,测试环境 Finance 服务不可用。
- `baiyue_finance` 当前仅部署旧 F0 schema;`fin_bill`、`fin_fee_source` 等存量表无业务数据,G3/G4 新表未部署。因此对账、应收应付、凭证及结算写链无法完成真实 HTTP 验收。
- 本地脚本和模块契约测试通过只证明验收程序契约成立,不代表测试环境 Finance 服务或数据库迁移已经部署成功。
报告生成后,产品进一步确认现有 ACTIVE 往来单位均可作为应付结算候选,不要求 `SUPPLIER` 类型。曾为诊断临时新增的 `FIN-FULL-SUP-20260812` 及其类型映射已从测试库完整删除;全量脚本和 Admin 页面均已改为复用现有 ACTIVE 往来单位。原报告中的“未找到 ACTIVE SUPPLIER”仅反映当时脚本的旧过滤条件,不能倒推为测试环境已通过。当前仍需完成墨家测量实重同步修复、Finance 服务部署和 G3/G4 schema 迁移,再重跑同一三模块链路形成新报告。
产品/业务逐项确认请使用:[财务管理产品确认表](财务管理产品确认表.md)。
产品回传后的差异和剩余门禁见:[财务管理产品确认版差异与剩余待确认](财务管理产品确认版差异与剩余待确认.md)。
技术边界已确认:[财务服务边界设计](财务服务边界设计.md)。Finance 采用独立服务和独立数据库,Firstleg 仅提供业务费用来源。
开发前总控门禁与 F0/F1 任务清单:[财务开工门禁与F0-F1任务清单](财务开工门禁与F0-F1任务清单.md)。
订单与客户领导验收唯一范围入口:[财务核心五页产品与接口验收契约](财务核心五页产品与接口验收契约.md)。
订单与客户 11 个 P0 操作、状态机与验收用例:[财务核心 P0 操作契约与验收用例](财务核心P0操作契约与验收用例.md)。
订单与客户实现与 Admin 接入证据(不反向修改目标契约):[财务核心 P0 实现证据矩阵](财务核心P0实现证据矩阵.md)。
文档优先级:五页验收契约和本轮产品确认 > 五页目标 OpenAPI > 既有人工 F1 契约/门禁 > 领域模型、历史全量规划和迁移文档。旧文档用于追溯,不得据此把钱包、充值、发票、费用分析或利润表重新纳入订单与客户。
旧文档降级规则:
| 文档/章节 | 当前用途 | 订单与客户实施约束 |
|---|---|---|
| 本文第六节起的“历史全量规划” | 保存早期盘点和演进背景 | 与五页契约冲突时全部失效,不作为菜单、路由、字段或接口依据 |
| `财务领域模型与跨服务契约.md` | 历史合并稿 | 已被数据字典和跨服务契约替代 |
| `财务服务边界设计.md`、`财务领域模型与数据字典.md` | 服务边界和长期模型参考 | 其中钱包、充值、发票、费用分析、利润模型不属于订单与客户 |
| `财务历史迁移与上线验收方案.md`、`财务F0实施任务拆分.md` | 历史迁移、底座任务追溯 | 不得覆盖五页范围和当前实现状态 |
详细设计材料:
- [财务业务操作流程图](财务全链路流程图.md)
- [财务业务全流程总览图(PNG)](财务业务全流程总览图.png)
- [财务来源接入现状](财务来源接入现状.md)
- [财务领域模型与数据字典](财务领域模型与数据字典.md)
- [Firstleg-Finance跨服务契约](Firstleg-Finance跨服务契约.md)
- [F1 人工账单、收款、成本接口契约](F1人工账单收款成本接口契约.md)
- [F1 人工财务契约审查与门禁](F1人工财务契约审查与门禁.md)
- [财务核心五页产品与接口验收契约](财务核心五页产品与接口验收契约.md)
- [财务核心五页 OpenAPI](openapi/finance-core-five-pages-v1.yaml)
- [财务核心 P0 操作契约与验收用例](财务核心P0操作契约与验收用例.md)
- [财务核心 P0 实现证据矩阵](财务核心P0实现证据矩阵.md)
- [财务历史迁移与上线验收方案](财务历史迁移与上线验收方案.md)
- [财务F0实施任务拆分](财务F0实施任务拆分.md)
历史合并稿:[财务领域模型与跨服务契约](财务领域模型与跨服务契约.md) 已由“领域模型与数据字典”和“Firstleg-Finance 跨服务契约”两份文档替代,不作为后续实施依据。
## 一、结论
当前首期采用人工简化方案:平台财务登记收付款并上传凭证;客户可查询并确认本人已出账对账单。首期不做银行自动对账、自动核销任务、复杂审批、客户钱包、发票、供应商在线结算、汇率、月结或总账。
当前已经实现业务计费闭环,并已落地 Finance 独立服务/数据库、人工账单/收款/成本基础接口、平台与客户权限种子、Admin 财务页面和 Client 只读账单页面。当前不是“整体未开发”,而是已进入专项修复和契约收敛阶段。
已具备的基础链路:
```text
测量/称重
-> 测量审核
-> 计费规则匹配
-> 费用试算与快照
-> 发布对客费用
-> 客户查看并确认已出账对账单
-> 完成入库
```
当前 F1 已具备的实现链路:
```text
平台财务创建草稿账单
-> 出账冻结
-> 人工登记收款
-> 一笔收款分配多张账单
-> 部分收款/收清状态更新
-> 客户只读查询
```
此前基础链路已完成 Firstleg 真实柜次体积快照、客户归属、成本凭证校验、revision、双权限上传、费用来源事件/Relay/快照、Finance `fin_fee_source` 消费写入和完整幂等。在此基础上,固定五页所需的 11 个目标 operation、Admin 页面动作与 IAM 权限目录现已闭环,G1-G4 本地门禁均为 `PASS`;最终直接证据包括 Finance 聚合 82/82、G3 16/16、G4 18/18、收款及 AR 同步 12/12、IAM 168/168、Admin 财务专项 60/60、Admin 全量 654/654 及 Admin 构建通过。真实 MySQL 执行、测试环境 HTTP 冒烟和领导页面验收仍需单独完成,未经当前对话明确授权不触发 Jenkins。
订单与客户范围已重新冻结为原型 5 页:客户账户、客户应收应付、客户对账单、结算单应收、结算单应付。费用分析、利润表、发票和钱包不做,也不保留菜单、路由或假按钮。客户账户改为账单、收款和应收应付来源派生的财务往来总览,不做充值/预收。
## 二、事实来源与边界
本次按以下资料核对:
1. 入库测量与计费需求文档明确入库测量与计费只做头程计费,不自动形成应收、应付、对账单、收付款、核销、发票、利润或总账。
2. 平台后台原型提供财务管理全量参考,但其中数据和交互主要由单页 HTML 内的静态数据及前端脚本驱动。
3. 当前代码用于证明“已经实现什么”,不反向扩大产品范围。
主要依据:
- `docs/入库测量与计费/入库测量与计费计费财务需求确认表.md`
- `docs/入库测量与计费/入库测量与计费V2需求确认清单.md`
- `docs/入库测量与计费/入库测量与计费需求优化版-v2-测量计费入库主流程.md`
- `docs/悦/货代SAAS平台后台/货代SaaS平台原型.html`
- `apps/admin-web/src/modules/inbounds/`
- `apps/admin-web/src/modules/fee-items/`
- `apps/admin-web/src/prototype/modules/finance/`
- `apps/client-web/src/modules/first-leg/`
- `apps/client-web/src/modules/finance/`
- `baiyue-firstleg/firstleg/`
## 三、当前已经具备什么
### 3.1 可作为财务上游的业务数据
| 能力 | 当前状态 | 可复用价值 | 不能代表什么 |
|---|---|---|---|
| 实测重量、体积、计费量 | 已实现 | 作为费用计算依据和业务快照 | 不是财务凭证 |
| 客户计费规则、船司价格 | 已实现 | 产生确定的对客头程价格 | 船司价格不等于供应商应付 |
| 费用试算、确认、发布 | 已实现 | 形成版本化对客费用快照 | 不等于应收单或账单 |
| 费用调整 | 已实现 | 已发布费用调整生成新版本并留原因 | 尚未定义已出账或已核销后的调整方式 |
| 客户侧费用与账单查看 | 已实现 | 客户能看到入库及已发布费用结果,并在线确认本人已出账且待确认的对账单 | 客户不能修改金额、在线提出争议或登记收款/核销 |
| 费用项目主数据 | 已实现 | 支持费用编码、分类、国内/国际、提货/仓库应收应付属性 | 费用项目属性不自动生成财务记录 |
| 入库费用明细 | 后端已实现 | 支持人工新增、编辑、删除、审核、自动发布的入库运费明细 | 尚无跨入库单财务台账和结算生命周期 |
| 权限与审计基础 | 部分具备 | 费用明细查看、编辑、删除、审核已有权限和业务审计 | 财务制单、复核、收款、核销、反核销权限尚未定义 |
### 3.2 当前费用明细的真实边界
Firstleg 已有 `fl_inbound_fee_detail`,包含:
- 入库单、费用项目、方向、业务发生日、币种、单价、金额;
- 重量、体积、计费量等业务快照;
- 审核状态、审核人、驳回原因;
- 发布状态、发布时间;审核通过后自动发布并成为结算候选;
- 自动计费来源的费用单号和版本。
但当前仍存在以下断点:
- 自动发布链路只生成 `RECEIVABLE` 对客运费。
- 人工 `PAYABLE` 明细使用 Warehouse `supplierId/supplierName` 快照;费用项目 `supplierCategory` 可空,空表示任意启用供应商,非空严格匹配。
- 人工明细采用编辑、提交、审核、调整、作废闭环;审核通过后自动发布,不再存在“是否结算”开关。
- 已发布应收明细只能按单个入库单查询,未形成按客户、币种、账期聚合的财务台账。
- 没有冻结、出账、核销后的费用变更规则,无法保证历史账单金额稳定。
## 四、原型中有什么
平台后台原型的财务菜单包含以下能力:
| 原型模块 | 原型展示的主要能力 | 当前代码状态 | 是否能直接纳入首期 |
|---|---|---|---|
| 客户账户 | 原型为余额、冻结、可用余额和充值流水 | 未实现 | 订单与客户保留汇总/详情/流水结构,但改为未收、待出账、本期已收等派生指标;删除充值/钱包能力 |
| 客户应收应付 | 费用明细、编辑审核、按截止时间或勾选生成账单 | 已接入真实费用来源和编辑审核闭环 | 作为应收应付费用池 |
| 客户对账单 | 账期、汇率、应收、已收、结清、明细和支付历史 | 未实现 | 可作为应收闭环核心,但汇率和开票先暂缓 |
| 结算单应收 | 应收、已收、余额、到期日、审批、部分收款 | 未实现 | 可合并进账单/应收单,避免首期重复建模 |
| 结算单应付 | 供应商应付、已付、余额、审批、部分付款、利润 | 未实现;上游成本来源不完整 | 订单与客户纳入,但删除利润字段/按钮;必须先补真实供应商应付来源和付款凭证链路 |
| 费用分析 | 内外部费用对比、趋势和明细 | 未实现 | 订单与客户明确不做,不进菜单/路由 |
| 利润表 | 按客户、货柜、单票、月份统计收入、成本、利润率 | 未实现 | 订单与客户明确不做,不进菜单/路由 |
原型还出现了发票抬头、开票日期、汇率、支付方式、收付款凭证号等字段。它们只说明未来可能需要,不代表当前产品已经确认税务、外币折算、资金或发票边界。
当前 Admin 已有正式财务路由、账单详情/草稿修改/出账/调整/作废、人工收款和成本页面及真实凭证上传调用,Client 已有正式只读账单页面。后端已改为根据 `containerId` 调 Firstleg 体积快照并完成成本凭证校验,但 Admin 仍强制人工填写并提交柜内订单体积,且未接客户账期和 revision,因此前端创建闭环尚未与最终契约对齐。
## 五、当前修复中缺口
| 序号 | 断点 | 直接影响 |
|---|---|---|
| 1 | 五页读接口、平台/客户固定 DTO 和追踪响应已实现 | Finance 35/35 BUILD SUCCESS;本轮使用现有 Surefire 报告核对,不重新执行 Maven |
| 2 | 收款和成本均已校验凭证,但 `fileClient == null` 时仍 fail-open | File 客户端缺失时可能绕过凭证校验 |
| 3 | 后端已使用 Firstleg 真实体积快照,Admin 仍要求人工填写并提交体积 | 页面与最终请求契约不一致,产生无效输入和误导 |
| 4 | 幂等已有 SHA-256 与同参重放,但未覆盖完整规范化请求,缺 PROCESSING 恢复测试 | 仍可能误判同参或无法恢复中间态 |
| 5 | 客户账单已过滤可见状态,收款列表仍暴露平台字段且未按可见账单过滤 | 客户只读边界仍不完整 |
| 6 | Admin 已接账单动作,但未接客户账期、revision,整柜仍人工填体积 | 平台财务页面仍非完整闭环 |
| 7 | 业务错误码仍以通用错误和中文消息为主 | 前端无法稳定区分版本、幂等、凭证和归属错误 |
| 8 | revision 后端查询已落地,Admin 尚未接展示 | 调整历史仍不能在产品页面核对 |
## 六、全量财务规划与交付顺序
### 6.1 历史全量规划(不作为订单与客户范围)
以下内容只保留为历史分析。若与《财务核心五页产品与接口验收契约》冲突,以五页契约为准。
| 目标域 | 业务结果 | 主要来源 | 不能提前假定的口径 |
|---|---|---|---|
| 客户账户 | 客户财务往来派生汇总、详情和流水 | 账单、收款和应收应付来源 | 订单与客户不建设钱包、充值、预收或自动扣款 |
| 客户应收 | 客户欠款、到期、逾期、结清 | 已发布对客费用、补差/冲销 | 收入确认节点和账期规则 |
| 客户应付 | 客户代垫或返还类应付款(如确有业务) | 业务费用或人工单据 | 产品是否真的存在“平台向客户付款”的场景 |
| 客户对账单 | 期间内费用汇总、明细、平台出账和客户确认 | 应收/应付费用池 | 一张账单是否允许混合方向、混合币种 |
| 结算单应收 | 可审批、可收款、可核销的应收结算单 | 已确认客户账单 | 与客户对账单是一对一还是一对多 |
| 结算单应付 | 供应商成本、付款、余额和结清 | 供应商费用、运力/仓储/报关成本 | 成本确认、供应商账期、审批和付款方式 |
| 收付款与核销 | 到账/付款凭证,部分结算、反核销 | 银行流水或人工登记 | 是否首期接银行流水,是否允许一笔多单核销 |
| 发票 | 开票申请、开具、红冲、作废和关联 | 已确认应收/收款 | 税率、含税/未税、开票主体、外部平台 |
| 费用分析 | 历史规划,订单与客户不做 | 应收应付台账 | 不进入订单与客户菜单、路由和验收 |
| 利润 | 客户/单票/柜次/月度收入、成本、利润率 | 应收收入 + 应付成本 + 分摊 | 汇率、成本分摊、收入成本确认时间 |
### 6.2 分阶段交付顺序
全量目标建议拆成五个可验收阶段:
| 阶段 | 交付范围 | 关键闭环 | 前置依赖 |
|---|---|---|---|
| F0 财务底座 | 独立 Finance 服务/数据库、财务主体、客户/供应商往来单位、币种、费用科目、期间、权限、审计、幂等、金额精度 | 所有后续对象使用同一基础口径 | 服务边界已技术确认;产品确认主体、币种、权限和编码 |
| F1 应收与客户对账 | 应收费用池、平台出账、客户确认、结算单应收、收款登记、核销、反核销 | 费用 → 账单 → 客户确认 → 应收 → 收款 → 结清 | 当前已发布对客费用来源 |
| F2 应付与供应商结算 | 成本费用池、供应商账单、结算单应付、付款登记、付款核销、应付调整 | 成本 → 供应商账单 → 应付 → 付款 → 结清 | 供应商主数据和真实成本来源 |
| F3 客户账户与发票 | 订单与客户只做派生客户账户总览;发票暂缓 | 账户只读聚合,不维护资金余额 | 发票不属于订单与客户 |
| F4 分析与利润 | 订单与客户不做 | 不建设菜单、路由或假入口 | 后续重新立项 |
阶段之间可以并行做页面原型和契约设计,但生产数据链路必须按 F0 → F1/F2 → F3 → F4 验收。F4 不能用原型静态数字先行替代真实台账。
### 6.3 F1 最小财务闭环
F1 先处理当前已经有可靠来源的对客头程费用:
```text
已审核并发布的应收费用明细
-> 进入待对账费用池
-> 按客户 + 币种 + 账期生成对账单
-> 内部复核
-> 客户在线确认(异议仍线下反馈)
-> 平台财务出账后形成应收
-> 登记实际收款
-> 将收款核销到应收
-> 全额核销后结清
-> 错误时按权限反核销并留审计
```
F1 建议页面:
1. 应收费用池:查询、编辑、提交、审核、调整、作废;审核通过自动进入结算候选。
2. 客户对账单:生成、明细、内部复核、发送、关闭;平台财务可重开或调整。
3. 应收与收款:应收余额、到期日、收款登记、附件/凭证号、部分核销。
4. 核销记录:每笔收款对应哪些应收、核销金额、剩余余额、反核销历史。
5. 客户侧账单:查看明细、收款与未结余额,并在线确认本人已出账账单;不做在线争议。
以下历史排除清单已被 2026-08-11 的五页范围取代。结算单应付现在属于订单与客户;其余未确认能力继续排除:
- 供应商在线确认和自动付款(应付结算单与人工付款属于订单与客户);
- 客户预充值、余额冻结和自动扣款;
- 发票申请、开票和税务接口;
- 多币种折算与汇兑损益;
- 利润表、利润率和总账;
- 银行流水自动认领;
- 复杂费用分摊和会计凭证。
### 6.4 全量阶段的范围门禁
| 范围 | 开工门禁 |
|---|---|
| 客户账户 | 已确认只做派生财务往来总览;禁止充值、冻结/解冻、退款、自动扣款和可写余额 |
| 客户应收应付 | 明确客户作为付款方还是收款方;没有真实业务场景的方向不建菜单和数据 |
| 供应商应付 | 必须有供应商主数据、成本来源凭证、审批人、付款方式和付款责任主体 |
| 收付款核销 | 明确人工登记与银行流水的边界;收款、付款、核销、反核销分开授权 |
| 发票 | 明确开票主体、税率、含税/未税、红冲/作废和外部开票平台;未确认前只保留接口扩展位 |
| 费用分析/利润 | 先冻结汇率、收入成本确认日、成本分摊和跨币种折算;报表必须能钻取到原始费用和结算单 |
## 七、已确认的产品结论(历史问题关闭结果)
下表原为产品问题清单,现按本轮确认结果保留。不得再把这些条目解释为待产品确认;实现仍受真实费用来源链路和专项技术门禁约束。
| 编号 | 待确认问题 | 建议默认值 |
|---|---|---|
| F1 | 订单与客户领导验收范围 | 固定为客户账户、客户应收应付、客户对账单、结算单应收、结算单应付;费用分析和利润表不做 |
| F2 | 账单生成维度 | 客户 + 币种 + 账期;不同币种不合并 |
| F3 | 哪些费用可以进入账单 | `APPROVED + PUBLISHED + AVAILABLE + CNY + amount>0` 且未出账;无人工结算开关 |
| F4 | 当前已发布头程费用是否自动进入待对账池 | 是,但仍由财务选择并生成账单 |
| F5 | 账单生成后上游费用能否直接调整 | 不能;应走补差单/冲销单并保留原账单 |
| F6 | 客户是否需要在线确认和提出争议 | 客户在线确认本人已出账对账单;确认状态独立于主状态,在线争议暂不做 |
| F7 | 是否需要内部复核 | 建议制单与复核权限分离,首期允许同人需业务明确 |
| F8 | 收付款是人工登记还是接银行流水 | F1/F2 先人工登记,F3 再接银行流水;必须保存到账日/付款日、方式、凭证号和附件 |
| F9 | 一笔收款能否核销多张应收,一张应收能否被多次收款 | 两者都允许,禁止累计核销超过余额 |
| F10 | 反核销和作废权限 | 独立高风险权限,必须填写原因并完整审计 |
| F11 | 到期日如何计算 | 由客户结算条款或账单确认日 + 账期天数计算 |
| F12 | 历史已发布费用如何迁移 | 仅迁移满足入池条件且尚未形成线下已结算事实的费用 |
## 八、建议状态模型
状态应按对象拆分,避免把费用、账单和资金状态混为一个字段。
### 8.1 费用明细
```text
DRAFT -> PENDING -> APPROVED -> PUBLISHED -> BILLED
-> REJECTED
PUBLISHED/BILLED -> ADJUSTED(通过补差或冲销,不覆盖原记录)
```
### 8.2 对账单
```text
DRAFT -> REVIEWED -> SENT -> CONFIRMED -> CLOSED
-> DISPUTED -> DRAFT/VOIDED
```
### 8.3 应收与核销
```text
应收:OPEN -> PARTIALLY_SETTLED -> SETTLED
-> OVERDUE
收款:DRAFT -> CONFIRMED -> PARTIALLY_ALLOCATED -> FULLY_ALLOCATED
核销:ACTIVE -> REVERSED
```
“收款已登记”与“应收已核销”必须分开。只有核销完成后,对应应收余额才减少;反核销恢复余额,但不得删除原记录。
## 九、关键数据与约束建议
首期至少需要以下独立对象,不能只在现有费用明细表上继续追加字段:
| 对象 | 核心职责 |
|---|---|
| 财务费用来源 | 引用不可变的业务费用版本,保存来源服务、来源单据、来源版本和来源幂等键 |
| 对账单 | 客户、币种、账期、状态、版本、金额合计和确认信息 |
| 对账单明细 | 关联费用来源并保存出账时快照;一条有效费用只能进入一张有效账单 |
| 应收单 | 应收金额、已核销金额、余额、到期日和状态 |
| 收款单 | 到账金额、币种、日期、方式、凭证号、附件和登记/确认人 |
| 核销记录 | 收款单、应收单、核销金额、操作人、时间和幂等键 |
| 反核销记录 | 原核销记录、原因、审批/操作人和恢复金额 |
| 财务操作日志 | 对账、确认、争议、收款、核销、反核销和作废的完整历史 |
必须具备的约束:
- 金额统一使用定点小数,币种使用 ISO 三位码;不同币种首期禁止合并和直接核销。
- 长整型 ID 按字符串跨前端传输。
- 所有写操作带幂等键和乐观锁版本。
- 同一费用来源版本只能进入一个未作废的账单明细。
- 核销累计金额不得超过收款可用余额或应收未结余额。
- 出账、核销后禁止物理删除;调整、作废和反核销必须保留原记录。
- 客户隔离由服务端登录上下文保证;平台员工操作目标客户时必须显式选择客户并校验权限。
- 客户不可看到供应商成本、内部备注、审核意见和平台凭证附件。
## 十、原型需要修正或裁剪的地方
后续做正式页面时,不建议直接照搬原型:
1. “客户应收应付”把客户应收和供应商应付混在同一概念下,应按交易对手和职责拆分。
2. “客户对账单”和“结算单应收”字段大量重复,首期应定义清晰的一对一或一对多关系,避免两套金额状态并存。
3. 原型中的“支付历史”在应收场景应统一使用“收款/核销记录”,避免收付款术语混用。
4. 原型允许直接登记部分收付款,但没有展示确认、撤销、反核销、超额校验和并发冲突。
5. 客户账户充值与应收结算不是同一个闭环,不能用余额字段代替收款和核销台账。
6. 利润表直接展示结果,但没有收入确认、成本来源、外币折算和分摊规则,当前结果不可审计。
7. 所有正式业务表格的“操作”列应放在第一列;原型部分旧页面需要按仓库统一规则调整。
## 十一、完成标准
只有同时满足以下条件,才可以称为“客户应收财务闭环”:
- 每笔应收都能追溯到已审核、已发布且不可变的费用来源版本;
- 能生成、复核、发送并确认客户对账单;
- 能形成有到期日和余额的应收;
- 支持一次或多次收款及多对多核销;
- 支持部分核销、全额结清、反核销和作废;
- 所有金额变化均可审计,重复提交和并发操作不会多记账;
- Admin 与 Client 对同一账单、应收余额和状态的展示一致;
- 越权、跨客户、不同币种、超额核销、已出账费用调整等异常路径有服务端硬校验;
- 使用真实 API 完成至少一条“费用 -> 对账 -> 应收 -> 收款 -> 核销 -> 结清”回归,并验证反核销恢复余额。
## 十二、下一步文档工作
在写代码前建议依次完成:
1. 由产品/业务填写 F1-F12,冻结首期范围。
2. 形成《客户应收闭环需求确认表》,明确页面、角色、状态和异常处理。
3. 使用《财务管理产品确认表》完成 S1-S8、F0-F4 的产品确认。
4. 服务边界、领域模型、跨服务契约及 F0/F1 基础实现已经形成;当前按《F1人工财务契约审查与门禁》完成专项修复和测试放行,不再等待产品填写 XLSX 或重复讨论是否拆服务。
5. 形成《客户应收接口与权限契约》,包括错误码、幂等、数据范围和审计事件。
6. 形成《历史费用迁移与上线方案》,避免已有线下结算数据被重复出账。