diff --git a/财务管理/Firstleg-Finance跨服务契约.md b/财务管理/Firstleg-Finance跨服务契约.md index fd6b682..d7a7938 100644 --- a/财务管理/Firstleg-Finance跨服务契约.md +++ b/财务管理/Firstleg-Finance跨服务契约.md @@ -127,6 +127,8 @@ Firstleg Outbox 发布采用至少一次投递:指数退避(建议 10s、30s 技术已确认:独立服务/数据库、DTO/事件通信、Outbox 至少一次、Finance Inbox 幂等、不可变来源快照、无跨库 Join、服务令牌、错误隔离和审计要求。 -产品口径已冻结:只有 `APPROVED + PUBLISHED + AVAILABLE + CNY + amount>0` 来源可入池;审核通过后自动成为结算候选。PAYABLE 的 supplierId 必须是 Warehouse `ACTIVE` 供应商,supplierCategory 为空时允许任意启用供应商,非空时严格匹配且 Finance 不从费用名称猜测类别。出账后冻结,调整/作废重开保留版本和原因;不做汇率、月结、钱包抵扣、费用分析和利润表。 +产品口径已冻结:只有 `APPROVED + PUBLISHED + AVAILABLE + CNY + amount>0` 来源可入池;审核通过后自动成为结算候选。PAYABLE 的 supplierId 必须是 Warehouse `ACTIVE` 供应商,supplierCategory 为空时允许任意启用供应商,非空时严格匹配且 Finance 不从费用名称猜测类别。PAYABLE 还必须携带 `settlementMode=ON_ACCOUNT|DIRECT_PAID`:ON_ACCOUNT 可进入 AP,且已付字段必须为空;DIRECT_PAID 必填 `paidAt`、`paymentMethod`,`paymentReferenceNo` 与付款凭证至少一项,只计成本、不得进入 AP 或待付金额。付款方式只允许 `ONLINE/BANK_TRANSFER/CASH/OTHER`。这些字段必须进入不可变来源快照和 `sourceHash`,RECEIVABLE 必须为空。出账后冻结,调整/作废重开保留版本和原因;不做汇率、月结、钱包抵扣、费用分析和利润表。 + +成本与资金动作分离:同一来源版本按 `sourceSystem + sourceType + sourceFeeId + sourceVersion` 只识别一次成本。DIRECT_PAID 来源唯一物化为 `fin_cost` 已付成本事实;ON_ACCOUNT 成本仍由来源事实识别,正式 AP 仅承载负债、到期日和付款,不重复确认成本。总成本等于有效 ON_ACCOUNT 来源成本加有效 DIRECT_PAID 成本事实;待付金额只来自非作废正式 AP 的 `outstanding_amount`;已付金额等于 AP `paid_amount` 加 DIRECT_PAID 金额。旧来源版本被替代或作废时,对应 DIRECT_PAID 成本事实同步失效。 主要剩余风险:测试环境尚未完成 Firstleg Relay → Finance Inbox → `fin_fee_source` 的真实 HTTP 冒烟。产品已确认无历史财务数据,不需要历史事件回放方案。 diff --git a/财务管理/openapi/finance-phase1-five-pages-v1.yaml b/财务管理/openapi/finance-phase1-five-pages-v1.yaml index e88facc..cdcdf6d 100644 --- a/财务管理/openapi/finance-phase1-five-pages-v1.yaml +++ b/财务管理/openapi/finance-phase1-five-pages-v1.yaml @@ -27,6 +27,13 @@ x-product-scope: x-source-gate: eligible: APPROVED + PUBLISHED + AVAILABLE + CNY + amount>0 currentStatus: 审核通过后自动发布并进入结算候选;Finance 不再维护人工“是否结算”开关,并继续校验客户、版本、方向和来源归属。 +x-payable-cost-contract: + settlementModes: [ON_ACCOUNT, DIRECT_PAID] + paymentMethods: [ONLINE, BANK_TRANSFER, CASH, OTHER] + onAccount: 可进入正式 PAYABLE settlement;paidAt/paymentMethod/paymentReferenceNo/paymentVoucherFileIds 必须为空 + directPaid: 必填 paidAt/paymentMethod,paymentReferenceNo 与 paymentVoucherFileIds 至少一项;只计成本,禁止进入 AP 和 outstandingPayable + totals: 总成本=有效ON_ACCOUNT来源+有效DIRECT_PAID成本事实;待付=正式AP outstanding;已付=AP paid+DIRECT_PAID + uniqueness: DIRECT_PAID 按 sourceSystem+sourceType+sourceFeeId+sourceVersion 唯一物化到 fin_cost,禁止与来源重复累计 x-phase1-p0-contract: status: FROZEN rule: 所有已列 operation 均为当前目标契约;实现状态不得写入本文件。 @@ -835,6 +842,13 @@ components: FeeDirection: type: string enum: [RECEIVABLE, PAYABLE] + SettlementMode: + type: string + enum: [ON_ACCOUNT, DIRECT_PAID] + description: 仅 PAYABLE 必填;RECEIVABLE 必须为空 + CostPaymentMethod: + type: string + enum: [ONLINE, BANK_TRANSFER, CASH, OTHER] FeeSourceType: type: string minLength: 1 @@ -870,7 +884,7 @@ components: total: {type: integer, format: int64, minimum: 0} AccountSummary: type: object - required: [customerId, customerCode, customerName, outstandingReceivable, pendingBilling, receivedInPeriod, outstandingPayable, status, lastChangedAt] + required: [customerId, customerCode, customerName, outstandingReceivable, pendingBilling, receivedInPeriod, totalCost, paidCost, outstandingPayable, status, lastChangedAt] properties: customerId: {$ref: '#/components/schemas/Id'} customerCode: {type: string} @@ -880,6 +894,8 @@ components: outstandingReceivable: {$ref: '#/components/schemas/Money'} pendingBilling: {$ref: '#/components/schemas/Money'} receivedInPeriod: {$ref: '#/components/schemas/Money'} + totalCost: {$ref: '#/components/schemas/Money'} + paidCost: {$ref: '#/components/schemas/Money'} outstandingPayable: {$ref: '#/components/schemas/Money'} status: {type: string, enum: [ACTIVE, DISABLED]} lastChangedAt: {type: string, format: date-time} @@ -905,7 +921,7 @@ components: items: {$ref: '#/components/schemas/AccountEntryRead'} CustomerAccountSummary: type: object - required: [customerId, currency, totalReceivable, receivedAmount, outstandingReceivable, pendingBilling, outstandingPayable, asOf, lastChangedAt] + required: [customerId, currency, totalReceivable, receivedAmount, outstandingReceivable, pendingBilling, totalCost, paidCost, outstandingPayable, asOf, lastChangedAt] properties: customerId: {$ref: '#/components/schemas/Id'} currency: {type: string, enum: [CNY]} @@ -913,6 +929,8 @@ components: receivedAmount: {$ref: '#/components/schemas/Money'} outstandingReceivable: {$ref: '#/components/schemas/Money'} pendingBilling: {$ref: '#/components/schemas/Money'} + totalCost: {$ref: '#/components/schemas/Money'} + paidCost: {$ref: '#/components/schemas/Money'} outstandingPayable: {$ref: '#/components/schemas/Money'} asOf: {type: string, format: date-time} lastChangedAt: {type: string, format: date-time} @@ -954,6 +972,13 @@ components: sourceFeeId: {$ref: '#/components/schemas/Id'} sourceVersion: {type: integer, minimum: 1} direction: {$ref: '#/components/schemas/FeeDirection'} + settlementMode: {$ref: '#/components/schemas/SettlementMode'} + paidAt: {type: string, format: date-time} + paymentMethod: {$ref: '#/components/schemas/CostPaymentMethod'} + paymentReferenceNo: {type: string, maxLength: 128} + paymentVoucherFileIds: + type: array + items: {type: string, minLength: 1} customerId: {$ref: '#/components/schemas/Id'} customerName: {type: string} supplierId: {$ref: '#/components/schemas/Id'} diff --git a/财务管理/财务一期五页产品与接口验收契约.md b/财务管理/财务一期五页产品与接口验收契约.md index 7349fe1..cbbdcb4 100644 --- a/财务管理/财务一期五页产品与接口验收契约.md +++ b/财务管理/财务一期五页产品与接口验收契约.md @@ -47,11 +47,11 @@ | 页面 | 原型结构和筛选 | 一期字段 | 一期操作 | 状态与验收 | |---|---|---|---|---| -| 客户账户 | 汇总卡、客户列表、账户详情、流水详情;客户名称/编号、账户状态、余额条件、流水类型和日期 | 客户基本信息、客户编号、联系人、电话、未收余额、待出账金额、本期已收金额、应付余额、账户状态、最后变动时间;流水号、时间、业务类型、关联单据、应收/应付变动、变动后未收余额、操作人、备注 | 详情、查询、重置、导出;**无充值、扣款或余额调整** | 客户主体正常/停用只影响访问和新业务;所有金额可由来源、单据和收付款逐笔追溯,禁止直接写余额 | -| 客户应收应付 | 工具栏、组合查询、选中汇总、费用列表、费用详情、审核进度、关联业务、操作记录 | 客户、费用单号、是否已生成对账单、审核状态、应收/应付、入仓码/柜次号、业务状态、费用类型、金额、业务发生日、来源类型、来源版本 | 详情、提交审核、审核通过/拒绝、作废、按截止时间或勾选生成;Firstleg 来源的金额编辑/调整回到入库或柜次业务明细完成;不提供“是否结算”开关 | `DRAFT/REJECTED -> PENDING -> APPROVED`;`APPROVED + PUBLISHED + AVAILABLE + CNY` 自动成为结算候选;作废由 Firstleg 落业务事实并发事件,Finance 消费后同步;同一来源版本不能重复进入有效单据 | +| 客户账户 | 汇总卡、客户列表、账户详情、流水详情;客户名称/编号、账户状态、余额条件、流水类型和日期 | 客户基本信息、客户编号、联系人、电话、未收余额、待出账金额、本期已收金额、总成本、已付成本、待付金额、账户状态、最后变动时间;流水号、时间、业务类型、关联单据、应收/应付变动、变动后未收余额、操作人、备注 | 详情、查询、重置、导出;**无充值、扣款或余额调整** | 待付只取正式 AP outstanding;已付=AP paid+DIRECT_PAID;总成本=ON_ACCOUNT来源成本+DIRECT_PAID成本事实,不得重复累计 | +| 客户应收应付 | 工具栏、组合查询、选中汇总、费用列表、费用详情、审核进度、关联业务、操作记录 | 客户、费用单号、是否已生成对账单、审核状态、应收/应付、结算方式、已付时间/方式/凭证、入仓码/柜次号、业务状态、费用类型、金额、业务发生日、来源类型、来源版本 | 详情、编辑草稿/驳回项、提交审核、审核通过/拒绝、调整、作废、按截止时间或勾选生成;不提供“是否结算”开关 | PAYABLE 必须区分 ON_ACCOUNT/DIRECT_PAID;前者可进入 AP,后者只计成本且排除 AP;同一来源版本只能识别一次成本 | | 客户对账单 | 查询区、主表、账单明细、支付历史;审核状态、账单编号、客户、柜次、结算起止日、是否结清、创建日期、最后收款时间 | 对账单号、客户、期间、账期、CNY、总应收、已收、未收、客户确认状态/确认人/确认时间、最后收款时间、是否结清、备注、创建/更新人时间 | 生成草稿、详情、导出、审核、出账、调整、作废;客户在 Client 确认本人已出账账单 | 主状态与客户确认状态独立;出账后 `PENDING_CONFIRMATION`,客户确认后 `CONFIRMED`,调整后重置待确认并保留历史审计 | | 结算单应收 | 汇总卡、筛选、列表、详情、费用明细、收款记录;收款状态、客户、结算单号 | 结算单号、客户、CNY、应收、已收、余额、关联对账单、业务期间、生成日、到期日、收款状态、制单人、状态 | 从已出账对账单生成、详情、部分收款、导出、作废/重开;不保留高级查询假入口 | 生成后直接 `ISSUED -> PARTIALLY_PAID -> PAID`;来源已在对账单阶段审核,结算单不重复增加假审批;未收款可作废,调整保留 revision | -| 结算单应付 | 汇总卡、供应商筛选、列表、详情、费用明细、付款记录 | 结算单号、供应商、费用类型、CNY、应付、已付、余额、来源期间、生成日、到期日、付款状态、制单人、状态 | 从审核通过且自动发布的应付来源生成、详情、部分付款、导出、作废/重开;删除利润分析和利润审批按钮 | 生成后直接 `ISSUED -> PARTIALLY_PAID -> PAID`;不重复增加结算单审批;作废/重开保留 revision,付款为后台人工登记和凭证图片 | +| 结算单应付 | 汇总卡、供应商筛选、列表、详情、费用明细、付款记录 | 结算单号、供应商、费用类型、CNY、应付、已付、余额、来源期间、生成日、到期日、付款状态、制单人、状态 | 仅从审核发布且 `settlementMode=ON_ACCOUNT` 的应付来源生成、详情、部分付款、导出、作废/重开;DIRECT_PAID 永不进入 | 生成后直接 `ISSUED -> PARTIALLY_PAID -> PAID`;AP只承载负债和付款,不再次确认成本;作废/重开保留 revision | 表格“操作”列必须位于第一列。原型中未形成真实闭环的“新增、生成账单、高级查询、快捷导出”等按钮,只有在对应接口和权限完成后才显示。 diff --git a/财务管理/财务管理产品确认表.md b/财务管理/财务管理产品确认表.md index 3c0804b..b6e4f9f 100644 --- a/财务管理/财务管理产品确认表.md +++ b/财务管理/财务管理产品确认表.md @@ -119,6 +119,10 @@ | F2-06 | 审批 | 应付确认和付款前复核使用独立权限;是否需要金额分级审批待确认 | 使用独立审核权限;一期不做金额分级或强制双人 | 已确认 | | F2-07 | 预付/押金/代付/退款 | 不混入普通应付余额,单独建模并保留关联单据 | 一期不做 | 已确认 | | F2-08 | 当前人工 PAYABLE 明细 | 仅作为待补充来源,不得直接视为供应商应付闭环 | 没有供应商、审核和发布事实的明细不得进入结算单应付 | 已确认 | +| F2-09 | 账期应付与已付成本 | 费用方向只表示收付对象,支付时点另建字段 | `direction` 保持 `RECEIVABLE/PAYABLE`;PAYABLE 必填 `settlementMode=ON_ACCOUNT/DIRECT_PAID`。ON_ACCOUNT 进入 AP,DIRECT_PAID 只计成本且永不进入 AP 或待付金额 | 已确认 | +| F2-10 | 已付成本凭证 | 已付事实必须具备时间、方式和可追溯证据 | DIRECT_PAID 必填 `paidAt`、`paymentMethod`;方式限 `ONLINE/BANK_TRANSFER/CASH/OTHER`,`paymentReferenceNo` 与付款凭证至少一项 | 已确认 | +| F2-11 | 成本、已付和待付口径 | 成本事实与付款资金动作分离,禁止同源重复累计 | 总成本=ON_ACCOUNT来源成本+DIRECT_PAID成本事实;待付只取正式AP outstanding;已付=AP paid+DIRECT_PAID;AP付款不再次确认成本 | 已确认 | +| F2-12 | 同一来源无重复 | 来源版本只允许确认一次成本,不允许 PAYABLE 来源与人工成本重复 | DIRECT_PAID 来源按 `sourceSystem+sourceType+sourceFeeId+sourceVersion` 唯一物化到 `fin_cost`;旧版本作废/替代时同步失效;ON_ACCOUNT 不物化重复成本记录 | 已确认 | ## 六、F3 客户账户与发票确认