From 4123a6a59cbe97a910e88f0b121d99595acd354c Mon Sep 17 00:00:00 2001 From: yaosutu <770858045@qq.com> Date: Thu, 1 Oct 2026 17:42:29 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=B8=E9=94=80=E7=AE=A1=E7=90=86=E5=90=8E?= =?UTF-8?q?=E7=AB=AF=E8=90=BD=E5=9C=B0=EF=BC=9A=E5=9D=8F=E8=B4=A6=E6=A0=B8?= =?UTF-8?q?=E9=94=80/=E5=80=BA=E5=8A=A1=E8=B1=81=E5=85=8D=205=20=E7=AB=AF?= =?UTF-8?q?=E7=82=B9=EF=BC=88#8689=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...01_8689_核销管理5端点-新增接口-管理后台.md | 218 ++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 changelogs-v2/2026-10/01_8689_核销管理5端点-新增接口-管理后台.md diff --git a/changelogs-v2/2026-10/01_8689_核销管理5端点-新增接口-管理后台.md b/changelogs-v2/2026-10/01_8689_核销管理5端点-新增接口-管理后台.md new file mode 100644 index 00000000..74fcd714 --- /dev/null +++ b/changelogs-v2/2026-10/01_8689_核销管理5端点-新增接口-管理后台.md @@ -0,0 +1,218 @@ +--- +schema: "hl-changelog/v2" +ticket: "8689" +title: "核销管理后端落地:坏账核销/债务豁免 5 端点(#8689)" +consumer: "admin" +author: "yst(GIT)" +change_type: "新增接口" +backend_status: "merged" +gateway_status: "not_required" +frontend_status: "pending" +frontend_owner: "" +frontend_ref: "" +target_release: "v2.1" +verified_at: "2026-10-01" +status_note: "核销管理(API §6.5 设计稿)本期提前落地。核销=往来账面抹债不动资金(无资金流水、不改账户结存、不过出纳),与支付本质区别:支付是钱真动了,核销只是账认了这笔损失/对冲。本期落地 SUPPLIER 债务豁免(冲减应付)+ CUSTOMER 坏账核销(冲减应收)两类;STAFF 员工·司导往来不做。新增 /admin/finance/writeoffs 5 端点(两页签列表/发起核销/提交审批/批准/驳回)。审批本期本地手工批(企微审批流留 TODO),金额≥阈值(默认 5000)落待审批、<阈值建单即入账。坏账核销只落往来台账留痕、不回改订单侧应收金额。" +updated_at: "2026-10-01" +base: "dev-v3" +--- + +# finance:核销管理后端落地(坏账核销/债务豁免 5 端点)(管理后台) + +> **PR**: #8697 | **服务**: hl-order-service-v3(hl-finance 编译其中) | **更新时间**: 2026-10-01 + +## 1. 接口背景 + +财务往来账上会有「收不回的应收(坏账)」和「不用付的应付(债务豁免)」,需要从账面轧掉认损。这就是**核销**。 + +核销与支付的本质区别: +- **支付**:钱真的动了(产生资金流水、账户结存变动、过出纳) +- **核销**:只是账面抹债——**不动资金、无资金流水、不改账户结存、不过出纳**,只在该对象的往来台账上记一笔反向对冲行(净额减) + +本期落地两类核销: +| 核销类型 | 账套 | 作用 | +|---|---|---| +| 债务豁免 `DEBT_WAIVER` | 供应商 `SUPPLIER` | 冲减应付(不用付了的应付款轧掉) | +| 坏账核销 `BAD_DEBT` | 客户 `CUSTOMER` | 冲减应收(收不回的应收款认损失) | + +> **STAFF 员工·司导往来本期不做**(该账套属后续 Epic、净往来无来源)。报销冲抵不进本表(走费用域闭环)。 + +此前核销管理只有设计稿(API §6.5),本次后端正式落地 5 个端点。 + +## 2. 变更清单 + +| # | 接口 | 方法 | 路径 | 变更类型 | 说明 | +|---|------|------|------|----------|------| +| 1 | 核销分页(两页签) | GET | /admin/finance/writeoffs/page | 新增 | PENDING 待审批 / LOG 全量记录 | +| 2 | 发起核销 | POST | /admin/finance/writeoffs | 新增 | 建核销单,按金额阈值分流 | +| 3 | 提交审批 | POST | /admin/finance/writeoffs/{id}/submit | 新增 | 本期本地手工批,仅守卫 | +| 4 | 批准核销 | POST | /admin/finance/writeoffs/{id}/approve | 新增 | 入账:写台账对冲行 | +| 5 | 驳回核销 | POST | /admin/finance/writeoffs/{id}/reject | 新增 | 驳回不动账 | + +## 3. 接口详情 + +### 3.1 核销分页(两页签) + +- **使用场景**:核销管理页两页签——「待审批」列待批核销单,「核销记录」列全量(已入账+已驳回) +- **认证**:需登录,财务查看权限 +- **入参(Query)**: + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| tab | String | ✅ | 页签:`PENDING` 待审批 / `LOG` 核销记录(其他值报 596013) | +| ledgerType | String | ❌ | 账套过滤:`SUPPLIER` / `CUSTOMER` | +| status | String | ❌ | 状态过滤;**LOG 页签仅允许 `POSTED`/`REJECTED`**(传其他报 596013),PENDING 页签忽略 | +| keyword | String | ❌ | 核销单号 / 往来对象名 模糊 | +| pageNo / pageSize | int | ✅ | 分页 | + +- **出参**:`PageResult` + +### 3.2 发起核销 + +- **使用场景**:财务在某往来对象上发起一笔核销 +- **入参(Body,WriteoffCreateReqVO)**: + +| 字段 | 类型 | 必填 | 说明 | 校验 | +|------|------|------|------|------| +| ledgerType | String | ✅ | 账套:`SUPPLIER` / `CUSTOMER` | | +| writeoffType | String | ✅ | 核销类型:`DEBT_WAIVER`(SUPPLIER)/ `BAD_DEBT`(CUSTOMER) | 与账套不匹配报 596014 | +| refId | Long | 见说明 | 往来对象 ID(SUPPLIER 必填) | | +| refName | String | ✅ | 往来对象名(CUSTOMER 按客户名聚合) | | +| amount | BigDecimal | ✅ | 核销金额 | >0(596012)、@Digits(16,2)、≤ 该对象净往来(596001) | +| reason | String | ✅ | 核销原因 | | +| sourceType / sourceId / sourceNo | String/Long/String | ❌ | 来源单据(可选追溯) | | + +- **分流**:金额 < 阈值(默认 5000)→ 直接 `POSTED` 入账;≥ 阈值 → `PENDING_APPROVAL` 待审批 +- **出参**:`WriteoffCreateRespVO`(writeoffId / writeoffNo / status / needApproval) + +### 3.3 提交审批 + +- **使用场景**:≥阈值核销单提交走审批 +- **本期说明**:审批为**本地手工批**(对齐费用/支付),企微审批流留 TODO 不接;submit 仅做状态守卫、状态不变,返回空串实例 ID +- **入参**:路径 `id` +- **出参**:`WriteoffSubmitRespVO`(approvalInstanceId 本期恒空串) + +### 3.4 批准核销 + +- **使用场景**:批准一笔待审批核销 → 入账 +- **动作**:`PENDING_APPROVAL` → `POSTED`,写一行往来台账反向对冲行(净额减),回写核销单 statement_entry_id + posted_at + 审批人快照 +- **防超额**:批准时会**重算该对象当前净往来**,若 PENDING 期间净额已被其他入账冲减到不够核销,报 596001 不予入账 +- **入参**:路径 `id` + +### 3.5 驳回核销 + +- **使用场景**:驳回一笔待审批核销(不动账) +- **动作**:`PENDING_APPROVAL` → `REJECTED`,记驳回原因 + 审批人快照 +- **入参**:路径 `id` + Body `WriteoffRejectReqVO`: + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| reason | String | ✅ | 驳回原因 | + +## 5. 出参(核销行 WriteoffRowRespVO) + +| 字段 | 类型 | 说明 | +|------|------|------| +| id | Long | 核销单 ID(字符串化) | +| writeoffNo | String | 核销单号(HX- 开头) | +| ledgerType | String | 账套 SUPPLIER/CUSTOMER | +| ledgerTypeName | String | 账套中文名 | +| writeoffType | String | 核销类型 DEBT_WAIVER/BAD_DEBT | +| writeoffTypeName | String | 核销类型中文名 | +| refId | Long | 往来对象 ID | +| refName | String | 往来对象名 | +| amount | BigDecimal | 核销金额 | +| reason | String | 核销原因 | +| status | String | 状态 PENDING_APPROVAL/POSTED/REJECTED | +| statusName | String | 状态中文名 | +| needApproval | Integer | 是否需审批 0/1 | +| operatorName | String | 经办人 | +| approverName | String | 审批人(本期手工批回填) | +| rejectReason | String | 驳回原因 | +| postedAt | String | 入账时间 | +| createTime | String | 创建时间 | + +## 6. 枚举 / 数据字典 + +### 6.1 ledgerType(账套) +| 值 | 中文 | 说明 | +|----|------|------| +| SUPPLIER | 供应商 | 应付侧 | +| CUSTOMER | 客户 | 应收侧 | + +### 6.2 writeoffType(核销类型) +| 值 | 中文 | 适用账套 | +|----|------|----------| +| DEBT_WAIVER | 债务豁免 | SUPPLIER | +| BAD_DEBT | 坏账核销 | CUSTOMER | + +### 6.3 status(核销单状态) +| 值 | 中文 | 说明 | +|----|------|------| +| PENDING_APPROVAL | 待审批 | ≥阈值待批 | +| POSTED | 已入账 | 已写台账对冲行 | +| REJECTED | 已驳回 | 审批驳回 | + +### 6.4 tab(页签) +| 值 | 中文 | +|----|------| +| PENDING | 待审批 | +| LOG | 核销记录 | + +## 7. 错误码 + +| code | 含义 | 触发场景 | +|------|------|----------| +| 596001 | 核销金额超过该对象净往来 | 发起 / 批准时金额 > 净往来 | +| 596002 | 核销单状态不允许该操作 | 对非待审批单做 submit/approve/reject | +| 596004 | 往来对象不存在 | 供应商/客户查无(SUPPLIER 无任何期初与流水) | +| 596011 | 核销单不存在 | id 查无 | +| 596012 | 核销金额无效须>0 | amount ≤0 | +| 596013 | 核销页签非法 / LOG 页签 status 非法 | tab 非 PENDING/LOG;LOG 传非 POSTED/REJECTED | +| 596014 | 核销类型与账套不匹配 | SUPPLIER 传 BAD_DEBT / CUSTOMER 传 DEBT_WAIVER | +| 596015 | 核销单号取号撞号耗尽 | HX- 取号并发耗尽(极少) | + +## 8. 示例 + +### 8.1 典型成功(发起一笔供应商债务豁免,<阈值直接入账) + +**请求** POST /admin/finance/writeoffs +```json +{ "ledgerType": "SUPPLIER", "writeoffType": "DEBT_WAIVER", "refId": 101, "refName": "嘉世豪酒店", "amount": 800.00, "reason": "供应商同意减免尾款" } +``` +**响应** +```json +{ "code": 0, "data": { "writeoffId": "1234567890", "writeoffNo": "HX-202610010001", "status": "POSTED", "needApproval": 0 }, "msg": "" } +``` + +### 8.2 边界(金额 ≥ 阈值 → 落待审批) + +**请求** POST /admin/finance/writeoffs +```json +{ "ledgerType": "CUSTOMER", "writeoffType": "BAD_DEBT", "refName": "张三", "amount": 6000.00, "reason": "客户失联认损" } +``` +**响应** +```json +{ "code": 0, "data": { "writeoffId": "1234567891", "writeoffNo": "HX-202610010002", "status": "PENDING_APPROVAL", "needApproval": 1 }, "msg": "" } +``` + +### 8.3 业务失败(核销金额超净往来) + +**响应** +```json +{ "code": 596001, "msg": "核销金额超过该对象净往来", "data": null } +``` + +## 9. 业务边界 + +- ✅ 核销只动往来账面:在该对象台账记一行反向对冲(净额减) +- ❌ 核销**不产生资金流水、不改账户结存、不过出纳** +- ❌ 坏账核销**不回改订单侧应收金额**——核销是财务账面认损失,订单应收仍在;CUSTOMER 按客户名聚合校验+回扣已核销防重复 +- ⚠️ 同名客户本期算一起(应收台账行无 customerId),将来补 customerId 后升级按 ID + +## 13. 关联 / 联系人 + +- **Issue**: [#8689](https://git.1814.love/wx/HL/issues/8689) +- **PR**: [#8697](https://git.1814.love/wx/HL/pulls/8697) +- **Merge commit**: [04e7ff6025](https://git.1814.love/wx/HL/commit/04e7ff60250f9199684856801452bd1d0062e46a) +- **后端负责人**: @yaosutu