From f5a0c81286a28233340e9061f72dec35452ad44c Mon Sep 17 00:00:00 2001 From: ouyangxq <775153912@qq.com> Date: Tue, 11 Aug 2026 09:25:45 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 财务管理/F1人工账单收款成本接口契约.md | 115 ++++++++++ 财务管理/README.md | 23 +- 财务管理/openapi/finance-f1-manual-v1.yaml | 203 ++++++++++++++++++ 财务管理/财务历史迁移与上线验收方案.md | 14 +- 财务管理/财务开工门禁与F0-F1任务清单.md | 20 +- 财务管理/财务服务边界设计.md | 2 +- .../财务管理产品确认版差异与剩余待确认.md | 62 ++++++ 财务管理/财务管理产品确认表.md | 78 ++++--- 财务管理/财务领域模型与数据字典.md | 31 +-- 9 files changed, 482 insertions(+), 66 deletions(-) create mode 100644 财务管理/F1人工账单收款成本接口契约.md create mode 100644 财务管理/openapi/finance-f1-manual-v1.yaml create mode 100644 财务管理/财务管理产品确认版差异与剩余待确认.md diff --git a/财务管理/F1人工账单收款成本接口契约.md b/财务管理/F1人工账单收款成本接口契约.md new file mode 100644 index 0000000..ef5e051 --- /dev/null +++ b/财务管理/F1人工账单收款成本接口契约.md @@ -0,0 +1,115 @@ +# F1 人工账单、收款、成本接口契约 + +> 版本:V1.0 +> 日期:2026-08-11 +> 状态:可进入 Finance 后端实现 +> OpenAPI:`openapi/finance-f1-manual-v1.yaml` + +## 1. 首期边界 + +- 只支持 RMB/CNY,不做汇率、月结、钱包、发票、银行流水和自动认款。 +- 平台财务人工填写账单、收款、成本表单并上传凭证。 +- 客户只读查看本客户账单、收款记录和未收余额。 +- 出账前账单可改;出账后冻结,只能由平台财务调整或作废重开。 +- 客户账期按客户配置,默认 30 个自然日;到期日为出账日加账期天数。 +- 一笔收款可分配到多张账单;财务逐张填写分配金额。首期不处理预收、多收、手续费、退款。 +- 单票成本归属单票;整柜清关、拖车等公共成本按柜内有效票体积分摊。 + +## 2. 统一接口约定 + +- 路径分为平台财务 `/api/platform/finance/v1` 和客户只读 `/api/client/finance/v1`。 +- 普通业务返回 HTTP 200,业务结果在 `code` 字段;成功 `code="200"`。认证/网关拒绝可返回 401/403。 +- 所有 ID 以字符串传输;金额为十进制定点数,首期 `currency=CNY`。 +- 写请求必须带 `Idempotency-Key`;更新/动作请求必须带 `expectedVersion`。 +- 客户范围从登录授权上下文取得,服务端忽略请求体中的客户切换字段。 +- 文件先由 File 服务上传,Finance 接收 `fileId` 引用,不直接接收二进制。 + +## 3. 对象与状态 + +### 3.1 账单 + +字段:`billId`、`billNo`、`customerId`、`billDate`、`dueDate`、`currency`、`lines[]`、`totalAmount`、`receivedAmount`、`outstandingAmount`、`status`、`version`。 + +账单明细至少保存 `sourceFeeId`、`sourceFeeVersion`、`orderId`/`inboundId`、费用项目快照、数量、单价和金额。多笔订单分别出账;同一账单可包含多个费用项。 + +状态:`DRAFT → ISSUED → PARTIALLY_PAID → PAID`;`ISSUED/PARTIALLY_PAID/PAID → VOIDED`。`DRAFT` 可编辑,其他状态金额不可覆盖。 + +### 3.2 收款 + +字段:`receiptId`、`receiptNo`、`customerId`、`receivedDate`、`amount`、`currency`、`paymentMethod`、`voucherFileIds[]`、`remark`、`allocations[]`、`operatorSnapshot`。 + +`allocations[]` 每项为 `billId + allocatedAmount`。首期要求分配金额之和等于收款金额;每项不得超过对应账单未收余额。收款凭证可被同一笔收款的多张账单共享。 + +### 3.3 成本 + +字段:`costEntryId`、`costNo`、`costType`(`SINGLE_ORDER`/`CONTAINER_SHARED`)、`orderId`/`containerId`、费用项目、供应商/成本对象快照、金额、币种、凭证文件、备注、操作人。 + +单票成本直接归属单票;整柜公共成本按 `票体积 / 柜内有效票总体积` 分摊。体积为零或总量为零时拒绝自动分摊,改为人工指定;舍入尾差归最后一票并记录调整原因。 + +## 4. 接口清单 + +### 平台财务 + +| 方法 | 路径 | 用途 | +|---|---|---| +| GET | `/api/platform/finance/v1/bills` | 查询账单 | +| POST | `/api/platform/finance/v1/bills` | 保存账单草稿 | +| GET | `/api/platform/finance/v1/bills/{billId}` | 查询平台账单详情 | +| PUT | `/api/platform/finance/v1/bills/{billId}` | 更新账单草稿 | +| POST | `/api/platform/finance/v1/bills/{billId}/issue` | 出账并冻结 | +| POST | `/api/platform/finance/v1/bills/{billId}/adjust` | 出账后调整/生成新版本 | +| POST | `/api/platform/finance/v1/bills/{billId}/void` | 作废账单 | +| POST | `/api/platform/finance/v1/receipts` | 人工登记收款并分配账单 | +| GET | `/api/platform/finance/v1/receipts` | 查询收款记录 | +| POST | `/api/platform/finance/v1/cost-entries` | 人工登记单票/整柜成本 | +| GET | `/api/platform/finance/v1/cost-entries` | 查询成本记录 | + +### 客户只读 + +| 方法 | 路径 | 用途 | +|---|---|---| +| GET | `/api/client/finance/v1/bills` | 查询本客户账单 | +| GET | `/api/client/finance/v1/bills/{billId}` | 查看账单详情 | +| GET | `/api/client/finance/v1/receipts` | 查看本客户收款记录 | + +客户端禁止 POST、PUT、PATCH、DELETE 财务写操作。 + +## 5. 最小错误码 + +| 错误码 | 场景 | +|---|---| +| `FIN-AR-001` | 账单不存在或不属于当前客户 | +| `FIN-AR-002` | 账单状态不允许当前操作 | +| `FIN-AR-003` | 出账后尝试直接修改金额 | +| `FIN-AR-004` | 账期配置无效 | +| `FIN-AR-005` | 首期仅允许 CNY | +| `FIN-AR-006` | 收款分配金额合计不等于收款金额 | +| `FIN-AR-007` | 分配金额超过账单未收余额 | +| `FIN-AR-008` | 凭证文件不存在、无权引用或类型不允许 | +| `FIN-AR-009` | 版本冲突,请刷新后重试 | +| `FIN-AR-010` | 幂等键重复但请求内容不同 | +| `FIN-COST-001` | 成本归属对象缺失 | +| `FIN-COST-002` | 体积为零,无法按体积分摊 | +| `FIN-AUTH-001` | 当前角色无平台财务写权限 | + +## 6. 验收用例 + +1. 平台财务创建 CNY 草稿账单,保存后可继续编辑。 +2. 账单出账生成账单号和到期日(出账日+客户账期,默认 30 天)。 +3. 出账后修改金额被拒绝;通过调整或作废重开保留原版本。 +4. 登记 300 元收款,上传一张凭证并分配到 3 张 100 元账单,三张账单均更新余额。 +5. 一张账单分两次收款后显示 `PARTIALLY_PAID`,余额归零后显示 `PAID`。 +6. 收款分配超过任一账单未收余额或合计不等于收款金额时拒绝且不落部分数据。 +7. 客户只读可见本客户账单和收款记录,不可写入、不跨客户查询。 +8. 客户子用户停用后不能访问财务页面,但历史操作人和客户财务归属不变。 +9. 登记单票成本成功;整柜公共成本按体积分摊,零体积场景要求人工指定。 +10. 重复 `Idempotency-Key` 返回原结果;同键不同请求返回 `FIN-AR-010`。 + +## 7. 实现依赖 + +- F0:Finance 服务、客户范围、权限码、编号器、审计、文件引用和幂等表。 +- Firstleg:已发布费用来源快照和来源版本查询;Finance 不跨库读取。 +- Admin:平台财务路由和三个写表单。 +- Client:账单/收款只读查询。 + +本契约不要求修改 Firstleg 或 Finance Java;后端实现时以此文档和 OpenAPI 为准。 diff --git a/财务管理/README.md b/财务管理/README.md index bd2e750..5e53bee 100644 --- a/财务管理/README.md +++ b/财务管理/README.md @@ -7,6 +7,8 @@ 产品/业务逐项确认请使用:[财务管理产品确认表](财务管理产品确认表.md)。 +产品回传后的差异和剩余门禁见:[财务管理产品确认版差异与剩余待确认](财务管理产品确认版差异与剩余待确认.md)。 + 技术边界已确认:[财务服务边界设计](财务服务边界设计.md)。Finance 采用独立服务和独立数据库,Firstleg 仅提供业务费用来源。 开发前总控门禁与 F0/F1 任务清单:[财务开工门禁与F0-F1任务清单](财务开工门禁与F0-F1任务清单.md)。 @@ -16,6 +18,7 @@ - [财务来源接入现状](财务来源接入现状.md) - [财务领域模型与数据字典](财务领域模型与数据字典.md) - [Firstleg-Finance跨服务契约](Firstleg-Finance跨服务契约.md) +- [F1 人工账单、收款、成本接口契约](F1人工账单收款成本接口契约.md) - [财务历史迁移与上线验收方案](财务历史迁移与上线验收方案.md) - [财务F0实施任务拆分](财务F0实施任务拆分.md) @@ -23,6 +26,8 @@ ## 一、结论 +当前首期已确定采用人工简化方案:平台财务人工填写账单、收款和成本表单并上传凭证,客户只读;首期不做银行自动对账、自动核销任务、复杂审批、客户钱包、发票、供应商在线结算、汇率、月结或总账。完整原型能力仅作为后续扩展参考,不作为本期开工范围。 + 当前已经实现了从入库测量数据到对客头程费用发布的**业务计费闭环**: ```text @@ -129,7 +134,7 @@ Firstleg 已有 `fl_inbound_fee_detail`,包含: | 1 | 没有财务费用池的跨订单查询和筛选 | 财务无法集中选择待出账费用 | | 2 | 没有费用冻结/锁定规则 | 账单生成后上游调整可能改变应收依据 | | 3 | 没有对账单及唯一编号、账期、版本 | 无法向客户确认一个确定期间的应收集合 | -| 4 | 没有客户确认、争议、重开机制 | 对账无法形成双方认可的结论 | +| 4 | 没有平台财务调整、作废重开和线下异议记录机制 | 客户反馈金额有误时无法在保留历史的前提下纠错 | | 5 | 没有应收单及到期规则 | 无法管理待收、部分收款、逾期和结清 | | 6 | 没有收款记录和凭证 | 无法证明资金已到账 | | 7 | 没有核销与反核销 | 收款不能对应到具体账单或费用,也无法纠错 | @@ -144,9 +149,9 @@ Firstleg 已有 `fl_inbound_fee_detail`,包含: | 目标域 | 业务结果 | 主要来源 | 不能提前假定的口径 | |---|---|---|---| | 客户账户 | 预存、冻结、扣款、退款、账户流水 | 客户充值、业务扣款 | 是否采用钱包作为应收结算方式、资金归属和退款规则 | -| 客户应收 | 客户欠款、到期、逾期、结清 | 已发布对客费用、补差/冲销 | 收入确认节点、账期和客户确认规则 | +| 客户应收 | 客户欠款、到期、逾期、结清 | 已发布对客费用、补差/冲销 | 收入确认节点和账期规则 | | 客户应付 | 客户代垫或返还类应付款(如确有业务) | 业务费用或人工单据 | 产品是否真的存在“平台向客户付款”的场景 | -| 客户对账单 | 期间内费用汇总、明细、争议和确认 | 应收/应付费用池 | 一张账单是否允许混合方向、混合币种 | +| 客户对账单 | 期间内费用汇总、明细、平台出账和客户只读查看 | 应收/应付费用池 | 一张账单是否允许混合方向、混合币种 | | 结算单应收 | 可审批、可收款、可核销的应收结算单 | 已确认客户账单 | 与客户对账单是一对一还是一对多 | | 结算单应付 | 供应商成本、付款、余额和结清 | 供应商费用、运力/仓储/报关成本 | 成本确认、供应商账期、审批和付款方式 | | 收付款与核销 | 到账/付款凭证,部分结算、反核销 | 银行流水或人工登记 | 是否首期接银行流水,是否允许一笔多单核销 | @@ -161,7 +166,7 @@ Firstleg 已有 `fl_inbound_fee_detail`,包含: | 阶段 | 交付范围 | 关键闭环 | 前置依赖 | |---|---|---|---| | F0 财务底座 | 独立 Finance 服务/数据库、财务主体、客户/供应商往来单位、币种、费用科目、期间、权限、审计、幂等、金额精度 | 所有后续对象使用同一基础口径 | 服务边界已技术确认;产品确认主体、币种、权限和编码 | -| F1 应收与客户对账 | 应收费用池、客户账单、账单确认/争议、结算单应收、收款登记、核销、反核销 | 费用 → 账单 → 应收 → 收款 → 结清 | 当前已发布对客费用来源 | +| F1 应收与客户对账 | 应收费用池、平台出账、客户只读查看、结算单应收、收款登记、核销、反核销 | 费用 → 账单 → 应收 → 收款 → 结清 | 当前已发布对客费用来源 | | F2 应付与供应商结算 | 成本费用池、供应商账单、结算单应付、付款登记、付款核销、应付调整 | 成本 → 供应商账单 → 应付 → 付款 → 结清 | 供应商主数据和真实成本来源 | | F3 客户账户与发票 | 充值、冻结、扣款、退款、账户流水;开票申请、开票登记、红冲/作废 | 账户余额与应收核销可选联动;应收与发票可追溯 | 资金/税务主体、开票平台和合规口径 | | F4 分析与利润 | 费用分析、收入成本汇总、客户/单票/柜次/月度利润、利润率、导出 | 应收与应付同源统计,结果可追溯 | F1/F2 结算数据、汇率和分摊规则 | @@ -177,8 +182,8 @@ F1 先处理当前已经有可靠来源的对客头程费用: -> 进入待对账费用池 -> 按客户 + 币种 + 账期生成对账单 -> 内部复核 - -> 客户确认或提出争议 - -> 确认后形成应收 + -> 客户只读查看(异议线下反馈) + -> 平台财务出账后形成应收 -> 登记实际收款 -> 将收款核销到应收 -> 全额核销后结清 @@ -188,10 +193,10 @@ F1 先处理当前已经有可靠来源的对客头程费用: F1 建议页面: 1. 应收费用池:查询、审核状态、是否参与结算、争议/排除原因。 -2. 客户对账单:生成、明细、内部复核、发送、客户确认、驳回/重开。 +2. 客户对账单:生成、明细、内部复核、发送、关闭;平台财务可重开或调整。 3. 应收与收款:应收余额、到期日、收款登记、附件/凭证号、部分核销。 4. 核销记录:每笔收款对应哪些应收、核销金额、剩余余额、反核销历史。 -5. 客户侧账单:只读明细、确认或提出争议、查看收款与未结余额。 +5. 客户侧账单:只读明细、查看收款与未结余额;异议通过线下渠道反馈。 F1 暂不包含(在 F2-F4 交付): @@ -225,7 +230,7 @@ F1 暂不包含(在 F2-F4 交付): | F3 | 哪些费用可以进入账单 | `APPROVED + PUBLISHED + settlementIncluded=true` 且未作废、未出账 | | F4 | 当前已发布头程费用是否自动进入待对账池 | 是,但仍由财务选择并生成账单 | | F5 | 账单生成后上游费用能否直接调整 | 不能;应走补差单/冲销单并保留原账单 | -| F6 | 客户是否需要在线确认和提出争议 | 建议需要;超期自动确认是否启用另行决定 | +| F6 | 客户是否需要在线确认和提出争议 | 首期不需要;客户只读查看,异议线下反馈,由平台财务手动处理 | | F7 | 是否需要内部复核 | 建议制单与复核权限分离,首期允许同人需业务明确 | | F8 | 收付款是人工登记还是接银行流水 | F1/F2 先人工登记,F3 再接银行流水;必须保存到账日/付款日、方式、凭证号和附件 | | F9 | 一笔收款能否核销多张应收,一张应收能否被多次收款 | 两者都允许,禁止累计核销超过余额 | diff --git a/财务管理/openapi/finance-f1-manual-v1.yaml b/财务管理/openapi/finance-f1-manual-v1.yaml new file mode 100644 index 0000000..5ee9203 --- /dev/null +++ b/财务管理/openapi/finance-f1-manual-v1.yaml @@ -0,0 +1,203 @@ +openapi: 3.0.3 +info: + title: Finance F1 Manual AR API + version: 1.0.0 + description: 首期人工账单、收款和成本接口;仅 CNY,平台财务可写,客户只读。 +servers: + - url: /api +paths: + /platform/finance/v1/bills: + get: + summary: 查询平台账单 + security: [{platformFinance: []}] + parameters: + - {$ref: '#/components/parameters/CustomerId'} + - {name: status, in: query, schema: {$ref: '#/components/schemas/BillStatus'}} + - {name: page, in: query, schema: {type: integer, minimum: 1, default: 1}} + - {name: pageSize, in: query, schema: {type: integer, minimum: 1, maximum: 100, default: 20}} + responses: {'200': {$ref: '#/components/responses/SuccessPage'}} + post: + summary: 创建账单草稿 + security: [{platformFinance: []}] + parameters: [{$ref: '#/components/parameters/IdempotencyKey'}] + requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/CreateBillRequest'}}}} + responses: {'200': {$ref: '#/components/responses/SuccessBill'}, '403': {$ref: '#/components/responses/BusinessError'}} + /platform/finance/v1/bills/{billId}: + get: + summary: 查询平台账单详情 + security: [{platformFinance: []}] + parameters: [{$ref: '#/components/parameters/BillId'}] + responses: {'200': {$ref: '#/components/responses/SuccessBill'}} + put: + summary: 更新账单草稿 + security: [{platformFinance: []}] + parameters: [{$ref: '#/components/parameters/BillId'}, {$ref: '#/components/parameters/IdempotencyKey'}] + requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/UpdateBillRequest'}}}} + responses: {'200': {$ref: '#/components/responses/SuccessBill'}} + /platform/finance/v1/bills/{billId}/issue: + post: + summary: 出账并冻结账单 + security: [{platformFinance: []}] + parameters: [{$ref: '#/components/parameters/BillId'}, {$ref: '#/components/parameters/IdempotencyKey'}] + requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/VersionRequest'}}}} + responses: {'200': {$ref: '#/components/responses/SuccessBill'}} + /platform/finance/v1/bills/{billId}/adjust: + post: + summary: 出账后调整并生成新版本 + security: [{platformFinance: []}] + parameters: [{$ref: '#/components/parameters/BillId'}, {$ref: '#/components/parameters/IdempotencyKey'}] + requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/AdjustBillRequest'}}}} + responses: {'200': {$ref: '#/components/responses/SuccessBill'}} + /platform/finance/v1/bills/{billId}/void: + post: + summary: 作废账单 + security: [{platformFinance: []}] + parameters: [{$ref: '#/components/parameters/BillId'}, {$ref: '#/components/parameters/IdempotencyKey'}] + requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/ReasonRequest'}}}} + responses: {'200': {$ref: '#/components/responses/SuccessBill'}} + /platform/finance/v1/receipts: + post: + summary: 人工登记收款并分配账单 + security: [{platformFinance: []}] + parameters: [{$ref: '#/components/parameters/IdempotencyKey'}] + requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/CreateReceiptRequest'}}}} + responses: {'200': {$ref: '#/components/responses/SuccessReceipt'}} + get: + summary: 查询收款记录 + security: [{platformFinance: []}] + responses: {'200': {$ref: '#/components/responses/SuccessPage'}} + /platform/finance/v1/cost-entries: + post: + summary: 人工登记单票或整柜成本 + security: [{platformFinance: []}] + parameters: [{$ref: '#/components/parameters/IdempotencyKey'}] + requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/CreateCostRequest'}}}} + responses: {'200': {$ref: '#/components/responses/SuccessCost'}} + get: + summary: 查询成本记录 + security: [{platformFinance: []}] + responses: {'200': {$ref: '#/components/responses/SuccessPage'}} + /client/finance/v1/bills: + get: + summary: 客户只读查询账单 + security: [{customerFinanceRead: []}] + responses: {'200': {$ref: '#/components/responses/SuccessPage'}, '403': {$ref: '#/components/responses/BusinessError'}} + /client/finance/v1/bills/{billId}: + get: + summary: 客户只读查看账单详情 + security: [{customerFinanceRead: []}] + parameters: [{$ref: '#/components/parameters/BillId'}] + responses: {'200': {$ref: '#/components/responses/SuccessBill'}, '403': {$ref: '#/components/responses/BusinessError'}} + /client/finance/v1/receipts: + get: + summary: 客户只读查询收款记录 + security: [{customerFinanceRead: []}] + responses: {'200': {$ref: '#/components/responses/SuccessPage'}, '403': {$ref: '#/components/responses/BusinessError'}} +components: + securitySchemes: + platformFinance: {type: http, scheme: bearer} + customerFinanceRead: {type: http, scheme: bearer} + parameters: + BillId: {name: billId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}} + CustomerId: {name: customerId, in: query, required: false, schema: {type: string, pattern: '^[1-9][0-9]*$'}} + IdempotencyKey: {name: Idempotency-Key, in: header, required: true, schema: {type: string, maxLength: 128}} + schemas: + CreateBillRequest: + type: object + required: [customerId, billDate, lines] + properties: + customerId: {type: string} + billDate: {type: string, format: date} + lines: {type: array, minItems: 1, items: {$ref: '#/components/schemas/BillLineInput'}} + UpdateBillRequest: + allOf: + - {$ref: '#/components/schemas/CreateBillRequest'} + - type: object + required: [expectedVersion] + properties: {expectedVersion: {type: integer, minimum: 0}} + BillLineInput: + type: object + required: [sourceFeeId, sourceFeeVersion, amount] + properties: + sourceFeeId: {type: string} + sourceFeeVersion: {type: integer, minimum: 1} + orderId: {type: string} + inboundId: {type: string} + feeItemName: {type: string} + amount: {type: number, format: double, minimum: 0} + VersionRequest: + type: object + required: [expectedVersion] + properties: {expectedVersion: {type: integer, minimum: 0}} + ReasonRequest: + type: object + required: [expectedVersion, reason] + properties: + expectedVersion: {type: integer, minimum: 0} + reason: {type: string, minLength: 1, maxLength: 500} + AdjustBillRequest: + allOf: + - {$ref: '#/components/schemas/ReasonRequest'} + - type: object + required: [lines] + properties: {lines: {type: array, minItems: 1, items: {$ref: '#/components/schemas/BillLineInput'}}} + CreateReceiptRequest: + type: object + required: [customerId, receivedDate, amount, paymentMethod, voucherFileIds, allocations] + properties: + customerId: {type: string} + receivedDate: {type: string, format: date} + amount: {type: number, format: double, minimum: 0, exclusiveMinimum: true} + currency: {type: string, enum: [CNY], default: CNY} + paymentMethod: {type: string, enum: [BANK_TRANSFER, CASH, OTHER]} + voucherFileIds: {type: array, minItems: 1, items: {type: string}} + remark: {type: string, maxLength: 500} + allocations: {type: array, minItems: 1, items: {$ref: '#/components/schemas/ReceiptAllocationInput'}} + example: + customerId: '10001' + receivedDate: '2026-08-11' + amount: 300 + currency: CNY + paymentMethod: BANK_TRANSFER + voucherFileIds: ['90001'] + allocations: + - {billId: '81001', amount: 100} + - {billId: '81002', amount: 100} + - {billId: '81003', amount: 100} + ReceiptAllocationInput: + type: object + required: [billId, amount] + properties: + billId: {type: string} + amount: {type: number, format: double, minimum: 0, exclusiveMinimum: true} + CreateCostRequest: + type: object + required: [costType, amount, expenseName, voucherFileIds] + properties: + costType: {type: string, enum: [SINGLE_ORDER, CONTAINER_SHARED]} + orderId: {type: string} + containerId: {type: string} + expenseName: {type: string, minLength: 1, maxLength: 100} + amount: {type: number, format: double, minimum: 0, exclusiveMinimum: true} + currency: {type: string, enum: [CNY], default: CNY} + voucherFileIds: {type: array, minItems: 1, items: {type: string}} + remark: {type: string, maxLength: 500} + BillStatus: {type: string, enum: [DRAFT, ISSUED, PARTIALLY_PAID, PAID, VOIDED]} + ApiEnvelope: + type: object + required: [code, message, data] + properties: + code: {type: string, example: '200'} + message: {type: string} + data: {type: object, additionalProperties: true} + requestId: {type: string} + ErrorEnvelope: + type: object + required: [code, message] + properties: {code: {type: string}, message: {type: string}, requestId: {type: string}} + responses: + SuccessBill: {description: Bill result, content: {application/json: {schema: {$ref: '#/components/schemas/ApiEnvelope'}}}} + SuccessReceipt: {description: Receipt result, content: {application/json: {schema: {$ref: '#/components/schemas/ApiEnvelope'}}}} + SuccessCost: {description: Cost result, content: {application/json: {schema: {$ref: '#/components/schemas/ApiEnvelope'}}}} + SuccessPage: {description: Paged result, content: {application/json: {schema: {$ref: '#/components/schemas/ApiEnvelope'}}}} + BusinessError: {description: Business error, content: {application/json: {schema: {$ref: '#/components/schemas/ErrorEnvelope'}}}} diff --git a/财务管理/财务历史迁移与上线验收方案.md b/财务管理/财务历史迁移与上线验收方案.md index ea75023..3b31f1e 100644 --- a/财务管理/财务历史迁移与上线验收方案.md +++ b/财务管理/财务历史迁移与上线验收方案.md @@ -2,12 +2,14 @@ > 版本:V1.0 > 编制日期:2026-08-10 -> 状态:开发前设计;技术方案已定,业务数据口径待产品确认 +> 状态:首发已确认不迁移历史;本文仅保留为未来补迁/导入参考,不纳入首发门禁 > 适用范围:Finance F0 财务底座、F1 客户应收与对账首发上线 > 关联文档:[财务管理闭环盘点与范围建议](README.md)、[财务服务边界设计](财务服务边界设计.md)、[财务管理产品确认表](财务管理产品确认表.md) ## 一、目标与基本结论 +**首发产品结论:没有需要迁移的历史财务数据,Finance 只接收正式启用后的新费用来源。** 因此首发不得执行历史批量导入,也不要求准备线下已结算排除台账。本文后续迁移步骤仅在未来明确提出历史补迁时重新启用并复核。 + 本方案用于把 Finance 上线前已经存在于 Firstleg 的历史对客费用,安全地接入独立 `finance-service` 和 `baiyue_finance`,并定义 F0/F1 从测试、灰度到正式启用的验收门禁。 本方案不把“费用已发送/已发布”推断为“客户尚欠款”,也不把二期计费状态推断为财务结算状态。历史迁移分成三个明确步骤: @@ -357,7 +359,7 @@ Finance 待复核来源金额 = 本批纳入原币金额 | G0 测试环境 | 测试数据与脱敏历史样本 | F0/F1 自动化及业务回归通过 | | G1 生产影子 | 全量或限定来源只入 Inbox/待复核池;用户不可见、不可制单 | 连续观察期无漏单、重复或冲突;观察时长待上线评审确定 | | G2 内部灰度 | 白名单客户;仅平台财务可见和制单 | 财务逐日对账通过,无 P0/P1 缺陷 | -| G3 客户灰度 | 白名单客户可查看、确认/争议 | 客户侧金额和状态一致,通知无重复 | +| G3 客户灰度 | 白名单客户只读查看 | 客户侧金额和状态一致,通知无重复 | | G4 全量 | 全部已确认客户 | 灰度总结批准,监控、值守和补偿预案就绪 | ### 9.2 灰度维度 @@ -367,7 +369,7 @@ Finance 待复核来源金额 = 本批纳入原币金额 - 环境; - 财务主体; - 客户白名单; -- 功能(来源接入、制单、发送、客户确认、收款、核销、反核销); +- 功能(来源接入、制单、发送、客户只读查看、收款、核销、反核销); - 历史批次号与实时事件起始水位。 开关由服务端执行,前端隐藏按钮不能代替权限或灰度校验。 @@ -435,8 +437,8 @@ Finance 待复核来源金额 = 本批纳入原币金额 | 编号 | 场景 | 预期结果 | |---|---|---| | F1-N01 | 财务从激活来源池按客户+币种+账期生成账单 | 来源只进入一张有效账单,金额合计正确 | -| F1-N02 | 账单内部复核、发送、客户确认 | 状态按确认模型流转,平台与客户显示一致 | -| F1-N03 | 客户提出明细争议 | 记录原因和争议明细,原快照不被覆盖,可重开再发送 | +| F1-N02 | 账单内部复核、发送、客户只读查看 | 状态按平台出账模型流转,平台与客户显示一致 | +| F1-N03 | 平台录入线下异议 | 记录原因和争议明细,原快照不被覆盖,由平台财务调整/作废重开 | | F1-N04 | 确认账单形成应收 | 应收金额、余额、到期日和来源关系正确 | | F1-N05 | 登记一笔收款核销多张应收 | 每条分配关系可追溯,收款和应收余额正确 | | F1-N06 | 一张应收被多笔收款部分核销 | 状态依次为 OPEN/PARTIALLY_SETTLED/SETTLED,累计不超额 | @@ -496,7 +498,7 @@ Finance 待复核来源金额 = 本批纳入原币金额 - 影子接入和内部灰度观察完成; - 对应客户历史来源及实时来源逐币种对账通过; - 该客户线下已结算排除清单已确认; -- 客户侧权限、脱敏、空态、错误态和争议入口验收通过; +- 客户侧只读权限、脱敏、空态和错误态验收通过;平台线下异议录入验收通过; - 不发送历史自动账单;首张账单由财务人工复核后发送; - 客服/运营已获得争议、误账和通知失败处理说明。 diff --git a/财务管理/财务开工门禁与F0-F1任务清单.md b/财务管理/财务开工门禁与F0-F1任务清单.md index 960f361..7bc6d32 100644 --- a/财务管理/财务开工门禁与F0-F1任务清单.md +++ b/财务管理/财务开工门禁与F0-F1任务清单.md @@ -7,19 +7,19 @@ ## 一、总控结论 -Finance 的服务拆分、独立数据库、服务内部模块边界和 Firstleg 协作方式已经技术确认,可以继续做详细设计和契约测试准备。 +Finance 的服务拆分、独立数据库、服务内部模块边界和 Firstleg 协作方式已经技术确认,可以继续做详细设计和契约测试准备。 -当前不能直接进入全量业务开发的原因,是产品确认表仍有业务决策待填写,尤其是财务主体/账套、期间、来源入池、账单确认、收款核销、历史迁移和 F1 收入口径。未确认部分只能使用可逆的草案模型,不能生成生产数据或把建议默认值当成正式口径。 +F0 的平台主体、首期仅 RMB/CNY、自定义账期、编号、费用冻结、无历史迁移、客户角色和首期简化审批已经确认。当前采用人工简化方案:账单、收款、成本均由平台财务填写表单并上传凭证;客户账户、发票、供应商在线应付、银行接口、复杂审批和月结首期不做。原表状态已归一为 25 项已确认、7 项暂缓。详见[产品确认版差异与剩余待确认](财务管理产品确认版差异与剩余待确认.md)。 ## 二、文档交付状态 | 材料 | 状态 | 作用 | |---|---|---| | 财务服务边界设计 | 已完成 | 确认 `finance-service`、`baiyue_finance`、9203 预留和部署改造清单 | -| 财务管理产品确认表/XLSX | 待产品填写 | 仅保留需要业务确认的 26 项;技术结论单独列示 | +| 财务管理产品确认表/XLSX | 部分已确认 | 会议继续填写剩余业务项;技术结论单独列示 | | 财务领域模型与数据字典 | 草案完成 | F0/F1 模型、表和约束;未确认口径显式标记 | | Firstleg-Finance 跨服务契约 | 草案完成 | 事件、快照查询、幂等、重试、权限和契约测试 | -| 财务历史迁移与上线验收方案 | 草案完成 | 历史费用迁移、防重复、灰度和 F0/F1 验收 | +| 财务历史迁移与上线验收方案 | 首发不启用历史迁移 | 保留未来补迁参考;首发使用其中 F0/F1 灰度和验收部分 | ## 三、分阶段开工门禁 @@ -48,9 +48,9 @@ G0 允许:完善 API/OpenAPI、数据库迁移草案、契约测试样例、 进入 F1 前必须满足: -- 账单聚合维度和账期计算规则冻结; -- 账单确认、争议、重开和关闭状态冻结; -- 应收生成节点、到期日、收款登记和多对多核销规则冻结; +- 账单聚合维度(首期固定 RMB/CNY)和账期计算规则冻结; +- 平台出账、关闭、重开和线下异议录入状态冻结;客户首期只读; +- 应收生成节点、人工收款表单字段、凭证关联和到期日冻结;首期不实现复杂多对多核销模型; - 预收、多收、手续费、退款、反核销的处理方式冻结; - 至少准备一组真实或脱敏费用来源样本,能够完成费用→账单→应收→收款→核销回归。 @@ -68,10 +68,10 @@ G0 允许:完善 API/OpenAPI、数据库迁移草案、契约测试样例、 | F0-T04 | 来源池与事件消费 | Inbox、来源池、快照、事件结果查询 | 契约冻结 | 重复/乱序/重试/冲突均有可验收结果 | | F0-T05 | 财务权限与审计 | 权限码、客户范围、操作审计和高风险操作保护 | G1-3 | 越权和反核销等操作被服务端拒绝并留痕 | | F1-T01 | 应收费用池 | 跨入库单筛选、排除原因、来源版本锁定 | F0-T04 | 一条有效来源只能进入一张有效账单 | -| F1-T02 | 客户对账单 | 生成、复核、发送、确认、争议、重开、关闭 | 产品 F1 | 状态迁移和版本并发校验完整 | +| F1-T02 | 客户对账单 | 生成、复核、发送、关闭、平台重开/调整、线下异议录入 | 产品 F1 | 状态迁移和版本并发校验完整 | | F1-T03 | 应收单 | 应收金额、已核销额、余额、到期/逾期 | F1-T02 | 账单与应收金额可追溯且不可覆盖历史 | | F1-T04 | 收款与核销 | 收款登记、多对多核销、反核销 | 产品 F1 | 禁止跨币种、超额和重复核销 | -| F1-T05 | 客户侧账单 | 客户查看、确认/争议、余额和收款记录 | F1-T02/F1-T04 | 客户不可见内部备注、供应商成本和内部附件 | +| F1-T05 | 客户侧账单 | 客户只读查看、余额和收款记录 | F1-T02/F1-T04 | 客户不可见内部备注、供应商成本和内部附件 | | F1-T06 | F1 回归验收 | 正常、重复、并发、越权、冲销、迁移案例 | 以上任务 | 通过迁移与上线验收方案中的 F0/F1 用例 | ## 五、当前可立即执行与必须等待 @@ -80,7 +80,7 @@ G0 允许:完善 API/OpenAPI、数据库迁移草案、契约测试样例、 - 把草案契约转换为 OpenAPI/事件契约测试样例; - 完善 F0/F1 数据字典、状态转移表和权限矩阵; -- 设计 Finance Admin/Client 页面和空态、错误态、争议态; +- 设计 Finance Admin/Client 页面和空态、错误态、线下异议录入态; - 准备脱敏历史费用样本与迁移校验脚本设计; - 按 F0-T01~F0-T05 拆解开发任务,但暂不合入业务代码。 diff --git a/财务管理/财务服务边界设计.md b/财务管理/财务服务边界设计.md index c4885de..290be1e 100644 --- a/财务管理/财务服务边界设计.md +++ b/财务管理/财务服务边界设计.md @@ -15,7 +15,7 @@ Finance 中必须分开建模: - **客户企业/客户范围**:业务数据归属和客户侧结算对象,服务端从登录授权上下文确定,不能由前端任意切换; - **平台财务主体/账套**:平台收款、付款、开票和核算的法律/账务主体;即使当前只有一个,也保留独立对象; -- **客户用户/成员**:制单、复核、确认、收款登记等操作人,保存 `userId/memberId` 和当时的姓名快照; +- **客户用户/成员**:仅作为客户范围内的操作人,保存 `userId/memberId` 和当时的姓名快照;账单、应收、余额和核销归属客户企业,不归属成员。成员停用只撤销访问和权限,不触发财务单据转交。 - **角色与权限**:平台角色由平台维护,客户角色由客户在允许的权限目录内维护,任何角色都不能越过客户范围。 已确认首期采用“一客户企业=一个对客结算对象”。这里的客户是业务数据归属和应收结算对象,不等同于平台收付款、开票和核算的法律主体;平台财务主体/账套仍单独建模。首期不支持一个客户配置多个对客结算对象或独立账套。 diff --git a/财务管理/财务管理产品确认版差异与剩余待确认.md b/财务管理/财务管理产品确认版差异与剩余待确认.md new file mode 100644 index 0000000..b929054 --- /dev/null +++ b/财务管理/财务管理产品确认版差异与剩余待确认.md @@ -0,0 +1,62 @@ +# 财务管理产品确认版:回填结果与剩余确认项 + +> 来源:产品回传《财务管理产品确认表(确认版).xlsx》 +> 复核日期:2026-08-10 +> 用途:把产品回填内容转成可开发口径;不替代产品原始回传表。 + +## 一、回传表复核结论 + +回传表共 32 个事项。当前状态列实际为:16 项“已确认”、2 项“待确认”、14 项状态为空但填写了最终结论。因此,表内“填写说明”显示的 16 已确认 / 16 待确认不能直接作为放行依据;状态为空的 14 项需要产品补填“已确认”或“暂缓”。 + +其中,以下内容可直接纳入正式文档: + +- 客户应付、客户账户、发票和外部接口在头程首期不做,线下处理;不得因此创建半成品财务流程。 +- 供应商付款为线下付款并上传凭证;单票成本直接归属单票,整柜清关、拖车等公共成本按柜内体积分摊。 +- 首期账单只支持 RMB/CNY;每个客户维护自己的账期配置,默认 30 天。 +- 收款全部由财务人工填写表单并上传收款图片;一笔 300 元可由财务分别填入 3 张 100 元账单,关联同一张凭证。 +- 首期只统计 CNY 账单,不做汇率、不做月结,只按账单统计。 +- 客户财务权限按菜单分权限;与“客户子用户只读、平台财务执行写操作”的既有结论一致。 + +## 二、已确认但需要写入契约的细节 + +| 编号 | 当前回填 | 为什么还不能直接开发 | 建议产品最小结论 | +|---|---|---|---| +| F1-01 | “当前只支持 RMB,支持多种费用项,多笔订单分开出” | 已明确首期币种和多订单分别出账 | 首期只支持 RMB/CNY;多种费用项可在账单明细中展示;多笔订单分别出账 | +| F1-03 | “客户有一个设置的账期,默认 30 天” | 产品口径已足够;自然日和出账日作为成熟软件默认实现 | 每个客户配置账期天数,默认 30 个自然日;到期日=账单出账日+客户账期 | +| F1-04 | “人工填写表单,上传收款图” | 已足够支撑首期人工收款;仍需把表单字段写入接口契约 | 收款金额、到账日、方式、凭证号、凭证图片、登记人由平台财务人工填写 | +| F1-05 | “客户给 300,3 个账单都是 100,直接 3 个单” | 已明确首期按账单逐笔分配;不再扩展预收、多收、手续费、退款 | 财务分别在 3 张账单填写 100 元,并关联同一张 300 元收款凭证 | +| F2-02/F4-01 | “单票成本;整柜清关、拖车按体积分摊” | 已明确业务归属;只需在接口中固定人工录入和凭证字段 | 单票成本归属单票;整柜公共成本按柜内体积分摊;平台财务人工登记并上传凭证;收入按 CNY 账单统计 | +| F4-03 | “不做汇率和月结,只做账单,只统计 CNY” | 已解决首期范围;仅需在权限和报表验收中冻结为 CNY | 首期利润/分析只统计 CNY 账单,不做汇率、汇兑损益和月结快照 | + +## 三、可以按“首期不做/暂缓”处理的事项 + +以下回填可以作为暂缓结论,但必须在原 XLSX 的“状态”列补成“暂缓”,不能留空: + +| 事项 | 暂缓口径 | +|---|---| +| F2-01、F2-03、F2-04 | 当前不存在客户应付或供应商应付在线闭环,线下处理;不开放对应菜单和状态流转 | +| F3-01 至 F3-04 | 头程首期没有客户账户/钱包,线下处理;不建设余额、冻结、扣款、退款对象 | +| F3-05 至 F3-07 | 发票和外部开票/银行接口首期线下处理;只保留未来扩展位 | +| F4-04 | 按菜单分权限;平台财务可见完整利润和成本,客户侧不开放供应商成本和内部利润 | + +## 四、当前放行判断 + +- F0 技术方案和客户主体/成员边界已经冻结,可以继续做 Finance 服务骨架、数据库迁移草案、事件契约和权限矩阵设计。 +- F1 客户应收的核心产品口径已补齐;账期日期算法、账单单据粒度和收款字段可按本文默认值直接写入契约。 +- F2/F4 的产品口径已补齐;开发前只需把人工成本/收款表单字段、凭证关联和体积分摊公式写入接口与验收契约。 +- F3 可整体标记暂缓,不阻断 F0/F1。 + +因此,本轮已没有新的核心产品问题;剩余工作是把确认版 XLSX 的状态归一化,并在接口/验收契约中补充账期日期算法、收款表单字段、收款凭证与账单分配关系、成本来源字段和体积分摊公式。 + +## 五、首期人工简化方案(本轮最终确定) + +首期财务按“人工台账”建设,不追求自动化财务软件的完整复杂度: + +1. **账单**:平台财务从已发布费用中人工选择/填写账单,保存客户、账单日期、账期、CNY 金额和明细;出账后冻结。 +2. **收款**:平台财务人工填写收款表单并上传凭证图片;表单可选择多张账单,逐张填写本次收款金额。系统只校验金额不超过账单未收余额,不建设预收、多收、手续费和退款模型。 +3. **成本**:平台财务人工填写成本表单并上传凭证;选择“单票成本”或“整柜公共成本”。单票成本直接归属单票,整柜公共成本按体积分摊。 +4. **状态**:只保留必要状态:草稿、已出账、部分收款、已收清、作废。首期不做复杂审批流、供应商在线确认、银行自动对账、自动核销任务和月结。 +5. **客户侧**:客户只读查看账单、收款记录和余额;金额有误时线下反馈,由平台财务修改或作废重开。 +6. **凭证与审计**:所有人工表单保留填写人、填写时间、修改原因、凭证图片和原始版本;已出账记录不覆盖,修改使用调整或作废重开。 + +按此方案,开发重点是三个简单表单(账单、收款、成本)和三类查询(客户账单、收款记录、成本/利润统计),不是建设完整总账、钱包或自动结算系统。 diff --git a/财务管理/财务管理产品确认表.md b/财务管理/财务管理产品确认表.md index 6f9d1b9..2cd6f86 100644 --- a/财务管理/财务管理产品确认表.md +++ b/财务管理/财务管理产品确认表.md @@ -9,6 +9,8 @@ 正式技术决策见:[财务服务边界设计](财务服务边界设计.md)。 +产品回传版 XLSX 的逐项复核和剩余确认门禁见:[财务管理产品确认版差异与剩余待确认](财务管理产品确认版差异与剩余待确认.md)。 + ## 一、确认说明 本表用于把财务原型中的全量能力转换为可开发的产品结论。原型只作为页面和字段参考,不能代替状态、权限、金额口径和数据来源确认。 @@ -18,6 +20,29 @@ - 暂时无法确认的事项改为“暂缓”,同时填写本阶段临时处理方式。 - F0 是全量财务共同底座;F1/F2 可在 F0 契约冻结后并行;F3/F4 依赖前序台账。 +### 1.1 2026-08-10 本轮已确认结论 + +| 决策 | 已确认结论 | +|---|---| +| 平台财务主体 | “我的资料”作为平台主体信息维护入口;Finance 内部保存独立主体记录和历史快照,不绑定某个员工账号 | +| 币种与汇率 | 首期只支持 RMB/CNY;不做 USD、汇率折算或汇兑损益 | +| 首期账单币种 | 首期只支持 RMB/CNY;不做外币账单、汇率折算或汇兑损益 | +| 客户账期 | 每个客户维护自己的账期配置;默认账期 30 天 | +| 财务期间 | 使用自定义账期;关账后允许平台财务重开,必须记录原因和审计,不覆盖关账历史 | +| 单据编号 | 按成熟财务软件规则由服务端分类发号,采用单据类型+年月+流水号,重试不换号、作废不回收 | +| 费用冻结 | 未出账费用允许按权限修改;进入有效账单后冻结,不允许覆盖原金额 | +| 历史迁移 | 首发不迁移历史费用,只处理 Finance 正式启用后的来源 | +| 客户财务角色 | 客户管理员自行创建角色并决定哪些客户用户进入财务模块;获权用户共享本客户财务数据范围 | +| 客户端动作 | 客户端只读查看,不在线确认、争议、登记收款、核销、反核销、关账或修改金额;异议线下反馈 | +| 平台财务调整 | 只有平台财务可人工调整;已出账时通过调整/作废重开保留原金额、原因和版本,不直接覆盖历史 | +| 收款登记 | 全部由平台财务人工填写收款表单并上传收款凭证图片;首期不接银行流水 | +| 收款分配 | 客户一次付款可对应多张账单;财务在每张账单上填写对应收款金额,并关联同一张收款凭证;首期不做预收、多收、手续费和退款规则 | +| 成本归属 | 单票成本直接归属单票;整柜公共成本(如清关、拖车)按柜内体积进行分摊 | +| 利润统计范围 | 首期只统计 CNY 账单;不做汇率、不做月结,只按账单统计 | +| 实施复杂度 | 首期全部由平台财务人工填写账单、收款和成本表单并上传凭证;不建设自动银行对账、自动核销、复杂审批、钱包、发票或总账 | +| 审批复杂度 | 首期不做强制双人复核和金额分级审批;保留独立权限、操作原因和完整审计 | +| 成员停用 | 客户子用户停用只撤销访问权限;客户账单、应收、余额等仍归客户企业,不触发财务单据转交;历史保留操作人快照 | + ## 二、全量范围确认 | 编号 | 范围 | 建议结论 | 最终结论 | 状态 | @@ -25,7 +50,7 @@ | S1 | 客户账户 | 做预充值、冻结、解冻、扣款、退款和账户流水;账户余额与应收核销分开,任何抵扣都产生核销记录 | 待填写 | 待确认 | | S2 | 客户应收 | 做客户费用池、对账单、应收单、到期/逾期、收款、部分核销、结清、反核销 | 待填写 | 待确认 | | S3 | 客户应付 | 仅在确有平台向客户付款的业务场景时启用;否则不开放菜单和数据方向 | 待填写 | 待确认 | -| S4 | 客户对账单 | 按客户 + 币种 + 账期生成,支持内部复核、发送、客户确认、争议、重开和关闭 | 待填写 | 待确认 | +| S4 | 客户对账单 | 按客户 + 币种 + 账期生成,支持平台内部复核、发送、关闭和财务重开;客户只读查看 | 平台财务出账,客户只读,异议线下反馈 | 已确认 | | S5 | 供应商应付 | 做供应商成本池、供应商对账、应付单、付款、付款核销和反核销 | 待填写 | 待确认 | | S6 | 发票 | 做发票申请、开票登记、票号/文件关联、红冲和作废;不直接假定外部开票平台 | 待填写 | 待确认 | | S7 | 费用分析 | 按费用项目、客户、供应商、期间统计发生额、已结算额和余额,支持钻取来源单据 | 待填写 | 待确认 | @@ -37,43 +62,43 @@ 以下事实已由当前对话确认:产品层只有平台、客户两种身份;平台管理平台角色/用户,客户管理本客户角色/用户。子用户属于客户成员,是操作人,不自动成为财务主体。 -客户企业与对客结算对象的一对一关系已确认;仍需产品确认的是客户子用户可以看到和执行哪些财务动作,以及平台高风险操作的职责分离。对应条目已补充至 XLSX 的“待确认事项”页。 +客户企业与对客结算对象的一对一关系已确认;客户子用户只是本客户的操作人,停用只影响登录和权限,不影响客户主体的账单、应收和余额。对应条目已补充至 XLSX 的“待确认事项”页。 | 编号 | 需要确认的事项 | 建议结论 | 最终结论 | 状态 | |---|---|---|---|---| | F0-11 | 客户与财务主体关系 | 客户企业作为客户数据归属和对客结算对象;首期一客户一结算对象;平台财务主体/账套单独建模,客户子用户不成为新主体 | 一客户企业对应一个对客结算对象;客户子用户共享本客户财务范围;平台收付款/开票主体独立 | 已确认 | -| F0-12 | 客户子用户数据范围 | 具有财务权限的客户子用户默认查看本客户全部账单,不按“本人创建”切分;部门范围另行定义 | 待填写 | 待确认 | -| F0-13 | 客户财务权限分配 | 平台定义权限目录和越界规则;客户管理员仅能在本客户内创建角色并分配允许的客户侧权限 | 待填写 | 待确认 | -| F0-14 | 平台与客户财务动作边界 | 客户侧查看、确认/争议和发票申请;收付款登记、核销/反核销、关账、应付、成本和利润属于平台财务权限 | 待填写 | 待确认 | -| F0-15 | 职责分离与高风险操作 | 制单、复核、高风险执行使用独立权限;付款/退款、反核销、关账必须原因+审计;双人/金额分级审批待确认 | 待填写 | 待确认 | -| F0-16 | 成员停用与历史追溯 | 停用立即撤销访问;历史保留 userId/memberId、操作时姓名快照;未完成待办显式转交 | 待填写 | 待确认 | +| F0-12 | 客户子用户数据范围 | 具有财务权限的客户子用户查看本客户全部财务数据,不按“本人创建”或部门切分 | 客户管理员决定角色和成员;获权成员共享本客户财务范围 | 已确认 | +| F0-13 | 客户财务权限分配 | 平台定义权限目录和越界规则;客户管理员仅能在本客户内创建角色并分配允许的客户侧权限 | 客户自行创建客户角色并决定哪些成员进入财务模块 | 已确认 | +| F0-14 | 平台与客户财务动作边界 | 客户侧只读;收付款、核销/反核销、关账、调整、应付、成本和利润属于平台财务权限 | 客户不能执行财务写操作,异议线下反馈,由平台财务处理 | 已确认 | +| F0-15 | 职责分离与高风险操作 | 首期不强制双人或金额分级;仍使用独立权限、操作原因和审计 | 财务先按最简单方式处理,不需要强制双人/金额分级审批 | 已确认 | +| F0-16 | 成员停用与历史追溯 | 停用立即撤销访问;历史保留 userId/memberId、操作时姓名快照;不改变客户财务归属,不触发财务单据转交 | 客户子用户停用只撤销访问权限,不影响客户账单、应收和余额;不触发财务单据转交;历史操作人快照继续保留 | 已确认 | | 编号 | 需要确认的事项 | 建议结论 | 最终结论 | 状态 | |---|---|---|---|---| | F0-01 | 财务服务边界 | 新增独立 Finance 服务和财务数据库;Firstleg 只提供不可变业务费用来源,不承载应收应付余额 | 按当前架构采用独立 Finance 服务/财务库 | 技术已确认 | -| F0-02 | 财务主体/账套 | 至少支持平台收款主体、付款主体;主体、账套和客户隔离键分开建模 | 待填写 | 待确认 | +| F0-02 | 财务主体/账套 | “我的资料”提供主体信息入口;Finance 保存独立平台主体记录和历史快照,主体与员工账号、客户隔离键分开 | 首期一个平台主体,在“我的资料”维护 | 已确认 | | F0-03 | 往来单位 | Finance 引用客户/供应商主数据并保存名称快照;不复制业务实体,不跨库 Join | 待填写 | 待确认 | -| F0-04 | 币种与精度 | 使用 ISO 4217 三位码;原币金额不可覆盖;不同币种不直接合并或核销 | 待填写 | 待确认 | -| F0-05 | 汇率 | F0 预留汇率来源、生效时间、版本和快照;未确认前不做自动折算 | 待填写 | 待确认 | -| F0-06 | 财务期间 | 支持 OPEN、CLOSING、CLOSED;关闭期间禁止直接改账,错误走调整/冲销单 | 待填写 | 待确认 | -| F0-07 | 编号 | AR/AP/对账单/收款/付款/核销/发票/钱包分别由服务端发号,重试返回原单号 | 待填写 | 待确认 | -| F0-08 | 来源费用入池 | 仅接收 APPROVED、PUBLISHED、settlementIncluded=true 且未作废/未被有效账单使用的来源版本 | 待填写 | 待确认 | +| F0-04 | 币种与精度 | 支持 CNY/USD;原币金额不可覆盖;不同币种不合并、不核销 | 首期只支持 RMB/CNY;金额定点存储 | 已确认 | +| F0-05 | 汇率 | 保留汇率扩展字段,首期不自动折算、不计算汇兑损益 | 首期不做汇率能力、不做汇兑损益 | 已确认 | +| F0-06 | 财务期间 | 自定义账期;支持 OPEN/CLOSED 和重开;重开必须记录原因、操作人和前后版本 | 自定义账期,关账后允许重开 | 已确认 | +| F0-07 | 编号 | 服务端按单据类型+年月+流水号发号;重试返回原号,作废号不回收 | 按成熟软件规则实现 | 已确认 | +| F0-08 | 来源费用入池 | APPROVED、PUBLISHED、settlementIncluded=true 的有效来源可入池;未出账允许调整,进入有效账单后冻结 | 出账冻结,未出账允许修改 | 已确认 | | F0-09 | 事件可靠性 | Firstleg Outbox 发布费用事件,Finance 消费幂等并保存来源快照;失败可重试、可查结果 | 按现有 Outbox 与幂等模式实现 | 技术已确认 | -| F0-10 | 审计与权限 | 制单、复核、确认、收付款、核销、反核销、关账、开票、钱包操作使用独立权限和审计事件 | 待填写 | 待确认 | +| F0-10 | 审计与权限 | 首期不强制双人复核/金额分级;财务写操作仍使用独立权限、原因和审计事件 | 平台财务按最简单方式处理,不增加强制审批 | 已确认 | ## 四、F1 客户应收与对账确认 | 编号 | 需要确认的事项 | 建议结论 | 最终结论 | 状态 | |---|---|---|---|---| -| F1-01 | 账单聚合维度 | 客户 + 币种 + 账期;不同币种不合并 | 待填写 | 待确认 | +| F1-01 | 账单聚合维度 | 客户 + 币种 + 账期;不同币种不合并 | 首期只支持 RMB/CNY;支持多种费用项;多笔订单分别出账 | 已确认 | | F1-02 | 生成方式 | 支持按筛选结果人工生成;后续可增加定时生成,但不得重复出账 | 待填写 | 待确认 | -| F1-03 | 账单状态 | DRAFT → INTERNAL_REVIEW → SENT → CUSTOMER_CONFIRMED → CLOSED;SENT 可 DISPUTED 后重开 | 待填写 | 待确认 | -| F1-04 | 应收状态 | OPEN → PARTIALLY_SETTLED → SETTLED;到期后增加 OVERDUE 标记,不改变余额 | 待填写 | 待确认 | -| F1-05 | 客户确认 | 客户可确认或提出争议;争议必须填写原因和明细,处理后重新发送 | 待填写 | 待确认 | -| F1-06 | 收款登记 | 首版人工登记到账日、金额、币种、方式、凭证号、附件和登记人 | 待填写 | 待确认 | -| F1-07 | 核销关系 | 支持一笔收款核销多张应收、一张应收被多笔收款核销;禁止跨币种和超额 | 待填写 | 待确认 | +| F1-03 | 账单状态 | DRAFT → ISSUED → CLOSED;客户只读,异议线下反馈后由平台财务调整或作废重开 | 客户不在线确认/争议,平台财务手工处理 | 已确认 | +| F1-04 | 应收状态 | OPEN → PARTIALLY_SETTLED → SETTLED;到期后增加 OVERDUE 标记,不改变余额 | 客户账期由客户配置,默认 30 天;到期日按账单日期+客户账期计算 | 已确认 | +| F1-05 | 客户确认 | 首期不做客户在线确认/争议;客户只读查看,异议线下反馈 | 客户不能操作,由平台财务处理 | 已确认 | +| F1-06 | 收款登记 | 首版人工登记到账日、金额、币种、方式、凭证号、附件和登记人 | 平台财务人工填写收款表单并上传收款凭证图片 | 已确认 | +| F1-07 | 核销关系 | 支持一笔收款核销多张应收、一张应收被多笔收款核销;禁止跨币种和超额 | 一笔客户付款可分配到多张账单;财务分别填写各账单对应金额并关联同一收款凭证;首期不处理预收、多收、手续费、退款 | 已确认 | | F1-08 | 反核销/作废 | 独立高风险权限,填写原因并保留原记录;不物理删除 | 待填写 | 待确认 | -| F1-09 | 出账后调整 | 不直接覆盖原费用;通过补差、冲销或调整单形成新来源 | 待填写 | 待确认 | +| F1-09 | 出账后调整 | 已出账冻结;平台财务通过调整/作废重开形成新版本,保留原金额和原因 | 仅平台财务手工调整,不允许客户修改 | 已确认 | | F1-10 | 预收/多收/手续费/退款 | 单独建模为预收、其他应付款或退款,不直接冲减应收金额 | 待填写 | 待确认 | ## 五、F2 供应商应付与结算确认 @@ -105,11 +130,11 @@ | 编号 | 需要确认的事项 | 建议结论 | 最终结论 | 状态 | |---|---|---|---|---| -| F4-01 | 收入口径 | 按已确认/已发布应收还是已收款确认收入,二者报表分开显示 | 待填写 | 待确认 | -| F4-02 | 成本口径 | 按已确认应付还是已付款确认成本,二者报表分开显示 | 待填写 | 待确认 | -| F4-03 | 分摊维度 | 支持客户、订单、单票、柜次、费用项目;明确公共成本分摊算法 | 待填写 | 待确认 | +| F4-01 | 收入口径 | 按已确认/已发布应收还是已收款确认收入,二者报表分开显示 | 首期只统计 CNY 账单,不做汇率和月结,只按账单统计 | 已确认 | +| F4-02 | 成本口径 | 按已确认应付还是已付款确认成本,二者报表分开显示 | 单票成本直接归属单票;整柜公共成本进入柜次池 | 已确认 | +| F4-03 | 分摊维度 | 支持客户、订单、单票、柜次、费用项目;明确公共成本分摊算法 | 单票按单票真实成本;整柜清关、拖车等公共成本按体积分摊 | 已确认 | | F4-04 | 汇率 | 明确交易日、账单日或月末汇率,以及本位币和汇兑损益 | 待填写 | 待确认 | -| F4-05 | 期间锁定 | 月结后报表冻结;调整通过新期间补差/冲销反映 | 待填写 | 待确认 | +| F4-05 | 期间锁定 | 月结后报表冻结;调整通过新期间补差/冲销反映 | 首期不做月结;只按账单统计,暂不生成月结快照 | 已确认 | | F4-06 | 利润维度 | 客户、货柜、单票、月份均支持;每个结果可钻取到收入、成本、分摊和原始单据 | 待填写 | 待确认 | | F4-07 | 导出与权限 | 导出按财务数据权限控制,客户不可见供应商成本和内部利润 | 待填写 | 待确认 | @@ -121,7 +146,8 @@ Firstleg 已发布费用 → Finance 来源池 → 客户对账单 - → 内部复核/客户确认 + → 平台财务出账 + → 客户只读查看(异议线下反馈) → 应收单 → 部分收款 → 多对多核销 diff --git a/财务管理/财务领域模型与数据字典.md b/财务管理/财务领域模型与数据字典.md index b73c5a8..a60a0c8 100644 --- a/财务管理/财务领域模型与数据字典.md +++ b/财务管理/财务领域模型与数据字典.md @@ -34,13 +34,16 @@ - **当前对话已确认**:产品只有平台、客户两种身份;平台维护平台角色/用户,客户维护本客户角色/用户。 - **技术已确认**:客户用户的财务操作上下文必须来自服务端当前客户成员关系和权限快照;不能信任前端传入的 `customerId/tenantId`,也不能让客户用户切换到其他客户范围。 - **技术已确认**:财务单据保存操作人的 `userId/memberId`、角色/权限快照标识和操作时姓名快照;成员停用只撤销后续访问,不改历史单据。 +- **当前对话已确认**:账单、应收、余额、收款和核销等财务聚合均归属客户企业/对客结算对象,不归属某个客户子用户。子用户停用只撤销登录和权限,不改变客户财务归属,也不触发财务单据转交。 - **当前对话已确认**:首期一个客户企业唯一对应一个对客结算对象;不支持一个客户多个对客结算对象或独立账套。客户用户默认仍共享本客户财务数据边界,具体动作由角色权限控制。 -- **产品待确认**:客户用户是否继续按部门/业务线细分数据范围;客户管理员可分配哪些客户侧财务权限;付款、退款、反核销和关账是否强制职责分离。 +- **当前对话已确认**:客户管理员决定财务角色和成员;获权成员共享本客户财务数据范围,不按本人/部门切分。客户端首期只读,异议线下反馈;财务写操作全部由平台财务完成。 +- **当前对话已确认**:首期不做强制双人复核和金额分级审批,但权限、原因、版本和审计仍是技术硬约束。 - **术语约束**:客户企业是客户数据归属/结算对象;平台收付款、开票和核算的法律主体仍以 Finance 的 `FinancialEntity`/账套表达。客户子用户永远不是新的财务主体。 ### 2.4 金额、币种和精度 - **技术已确认**:币种保存 ISO 4217 三位码;原币金额不可覆盖;不同币种不能直接合并或核销。 +- **当前对话已确认**:首期只支持 RMB/CNY;金额使用定点小数保存,首期不做 USD、汇率折算或汇兑损益。 - **建议默认值**:金额 `DECIMAL(20,6)` 保存原始计算值,展示/结算精度和舍入模式另设字段;数量/重量/体积 `DECIMAL(20,6)`。具体精度需与产品确认的计费规则复核。 - 所有金额字段成对保存 `*_amount` 与 `currency_code`(或由单据头统一币种且明细校验一致),不得用浮点数。 @@ -65,19 +68,19 @@ ARAllocation --(反核销)--> ARAllocationReversal 以下为建议物理表名;字段类型是实现建议,不代表已经执行建表。 -### 4.1 `fin_subject`:财务主体(产品待确认) +### 4.1 `fin_subject`:财务主体(首期已确认一个平台主体) | 字段 | 类型/约束 | 说明 | 状态 | |---|---|---|---| | `id` | BIGINT PK | 主体 ID | 技术已确认(ID 规则) | -| `subject_code` | VARCHAR(64) UNIQUE | 收款/付款法律或业务主体编码 | 产品待确认:主体数量和编码 | -| `subject_name` | VARCHAR(200) | 主体名称快照 | 产品待确认 | -| `subject_type` | VARCHAR(32) | `RECEIVING`/`PAYING`/`BOTH` 建议 | 建议默认值 | +| `subject_code` | VARCHAR(64) UNIQUE | 收款/付款法律或业务主体编码 | 技术已确认:服务端生成/维护 | +| `subject_name` | VARCHAR(200) | 主体名称快照;入口为平台“我的资料” | 当前对话已确认 | +| `subject_type` | VARCHAR(32) | 首期 `BOTH`;后续可扩展 `RECEIVING`/`PAYING` | 当前对话已确认 | | `status` | VARCHAR(20) | `ACTIVE`/`INACTIVE` | 建议默认值 | ### 4.2 `fin_ledger`:账套与期间归属(账套待确认) -`ledger` 关联 `subject_id`,不把客户 ID 当作账套。建议字段:`ledger_code`(唯一)、`ledger_name`、`subject_id`、`base_currency_code`、`status`、审计字段。期间表 `fin_period` 使用 `period_code`(如 `2026-08`)和 `status=OPEN|CLOSING|CLOSED`;关闭期间禁止原地改账。主体、账套数量、本位币和是否月结均为**产品待确认**。 +`ledger` 关联 `subject_id`,不把客户 ID 当作账套。首期一个平台主体对应一个默认账套;客户企业是对客结算对象,不创建客户账套。期间表使用自定义 `period_code` 和 `status=OPEN|CLOSING|CLOSED`;关账后允许平台财务重开,但必须记录原因和审计。 ### 4.3 `fin_counterparty_ref`:往来单位引用快照 @@ -95,11 +98,11 @@ ARAllocation --(反核销)--> ARAllocationReversal ### 4.4 `fin_currency` / `fin_exchange_rate`(F0 预留) `fin_currency`:`currency_code CHAR(3) PK`、名称、精度、启用状态。 -`fin_exchange_rate`:`id`、`from_currency`、`to_currency`、`rate DECIMAL(20,10)`、`rate_source`、`effective_at`、`version_no`、`snapshot_hash`、审计字段;唯一建议为 `(from_currency,to_currency,effective_at,version_no)`。汇率来源、交易日/账单日/月末取值和本位币折算为**产品待确认**,F0 仅建扩展位,未确认前不自动折算。 +`fin_exchange_rate`:首期不建业务流程;如保留扩展表,仅作为未来能力预留,不参与 CNY 账单和利润计算。 ### 4.5 `fin_number_sequence`:单据编号 -按 `sequence_type`(`AR`、`AP`、`STATEMENT`、`RECEIPT`、`PAYMENT`、`ALLOCATION`、`INVOICE`、`ACCOUNT`)和日期/主体分段发号。建议唯一 `(tenant_id, sequence_type, period_key)`,数据库锁或原子更新保证并发安全;重试使用幂等键返回原单号。编号格式和是否按主体分段为**产品待确认**。 +按 `sequence_type`(`AR`、`AP`、`STATEMENT`、`RECEIPT`、`PAYMENT`、`ALLOCATION`、`INVOICE`、`ACCOUNT`)和年月/主体分段发号。采用成熟软件常见的“类型+年月+流水号”格式;数据库锁或原子更新保证并发安全,重试使用幂等键返回原单号,作废号不回收。 ### 4.6 `fin_fee_source`:财务费用来源池 @@ -121,7 +124,7 @@ ARAllocation --(反核销)--> ARAllocationReversal | `event_id` | VARCHAR(100) | Outbox 事件 ID | | 唯一约束 | `(source_type, source_id, source_version)`;`(event_id)` | 防重复入池 | -**建议默认值**:仅 `APPROVED + PUBLISHED + settlementIncluded=true`、未作废版本进入 `ELIGIBLE`。该门槛、是否自动入池及历史迁移是**产品待确认(F0-08/F1 相关)**。 +**当前对话已确认**:仅 `APPROVED + PUBLISHED + settlementIncluded=true`、未作废版本进入 `ELIGIBLE`;未出账允许按权限修改,进入有效账单后冻结。首发不迁移历史费用。 ### 4.7 `fin_inbox_event` / `fin_audit_log` @@ -133,9 +136,9 @@ ARAllocation --(反核销)--> ARAllocationReversal ### 5.1 `ar_statement`:客户对账单聚合根 核心字段:`id`、`tenant_id`、`statement_no`、`ledger_id`、`subject_id`、`counterparty_ref_id`、`currency_code`、`period_start/end`、`due_date`、`status`、`subtotal_amount`、`tax_amount`、`total_amount`、`confirmed_at/by`、`dispute_reason`、`version`。 -建议唯一 `(tenant_id, statement_no)`;防重复出账的业务唯一键建议 `(tenant_id,counterparty_ref_id,currency_code,period_start,period_end,generation_key)`。账期边界、到期日和是否允许同一期间多张账单为**产品待确认**。 +建议唯一 `(tenant_id, statement_no)`;首期账单币种固定 CNY,防重复出账的业务唯一键建议 `(tenant_id,counterparty_ref_id,currency_code,period_start,period_end,generation_key)`。每个客户维护账期天数,默认 30 天;账期日期基准(出账日/账单日、自然日/工作日)需在接口契约中明确。 -状态建议:`DRAFT → INTERNAL_REVIEW → SENT → CUSTOMER_CONFIRMED → CLOSED`;`SENT → DISPUTED → DRAFT`(重开)或 `VOIDED`。状态值来自产品确认表建议,最终流转和客户确认是否必需仍待确认。 +状态建议:`DRAFT → INTERNAL_REVIEW → ISSUED → CLOSED`;平台财务可 `ISSUED → ADJUSTED/VOIDED → ISSUED`,原账单不覆盖。客户首期只读查看,异议线下反馈,不开放 `CUSTOMER_CONFIRMED/DISPUTED` 客户操作状态。 ### 5.2 `ar_statement_line`:对账单明细快照 @@ -161,7 +164,7 @@ ARAllocation --(反核销)--> ARAllocationReversal ### 5.6 `ar_dispute`(建议预留) -保存 `statement_id`、提出方、争议明细/原因、状态 `OPEN|PROCESSING|RESOLVED|REJECTED`、处理结论和审计字段。客户是否在线提出争议、是否超期自动确认是**产品待确认**;若 F1 暂不做,可先在对账单保留原因字段而不开放独立菜单。 +保存 `statement_id`、提出方、争议明细/原因、状态 `OPEN|PROCESSING|RESOLVED|REJECTED`、处理结论和审计字段。首期争议来源为线下反馈,由平台财务录入和处理,不开放客户独立争议动作。 ## 6. F2-F4 预留模型(不代表本期开发) @@ -170,7 +173,7 @@ ARAllocation --(反核销)--> ARAllocationReversal | F2 应付 | `ap_statement`、`ap_statement_line`、`ap_payable`、`ap_payment`、`ap_allocation`、`ap_allocation_reversal` | 成本来源池 → 供应商账单 → 应付 → 付款核销 | 供应商主数据、成本确认节点、付款主体、审批分级 | | F3 账户 | `fin_customer_account`、`fin_account_entry`、`fin_account_hold`、`fin_account_refund` | 充值/冻结/扣款/退款与应收核销分开,任何抵扣关联 `ar_allocation` | 账户是预付款还是授信、冻结/退款规则 | | F3 发票 | `fin_invoice_application`、`fin_invoice`、`fin_invoice_action` | 应收可选关联发票;红冲/作废新增动作,不覆盖原票 | 开票主体、税率、含税口径、外部平台 | -| F4 分析 | `fin_cost_entry`、`fin_allocation_rule`、`fin_profit_snapshot`、`fin_report_snapshot` | 收入/成本来源、分摊、汇率快照 → 可钻取利润 | 收入成本确认日、汇率日、分摊维度、本位币和月结 | +| F4 分析 | `fin_cost_entry`、`fin_allocation_rule`、`fin_profit_snapshot`、`fin_report_snapshot` | CNY 账单收入、单票成本、整柜公共成本分摊 → 可钻取利润 | 成本来源字段和报表触发点仍需写入契约;不做汇率和月结 | F2 的来源必须具备供应商、付款主体、成本凭证、币种金额和成本归属;当前人工 `PAYABLE` 明细不自动视为应付闭环。 @@ -191,7 +194,7 @@ Firstleg Outbox 事件建议包含:`eventId`、`eventType`、`occurredAt`、`c ## 9. 产品待确认清单(本稿不替代确认表) 1. F0:财务主体与账套数量、往来单位/供应商归属、账期与关账、单据编号格式、来源入池和历史迁移。 -2. F1:账单生成维度和周期、客户确认/争议、应收生成节点、收款登记/复核、到期日、预收/多收/手续费/退款处理。 +2. F1:账单生成维度和周期、应收生成节点、收款登记/复核、到期日、预收/多收/手续费/退款处理。 3. F2:供应商成本确认节点、付款主体、应付审批和付款方式。 4. F3:账户资金性质、冻结/解冻/退款、发票税务主体和外部平台。 5. F4:收入/成本确认日、汇率来源和日期、公共成本分摊、期间快照及报表权限。