# 10-A 采购退货累计量与冲销开发复验

采购退货改为按原入库明细计算可退量；冲销按原库存流水回补数量和实际成本，完整反向流水同时释放来源可退量。依据为详设 01 V1.0、06 V1.1 §4.6/§4.16/§7.5 与内部任务 10-A。全部为本地开发，未部署或写共享库。

## 实现与操作口径

- 新建退货每行必须填写 `ReceiptLineId`，且属于指定原入库单。物料、单位、批次须与来源行一致；组织、仓库、供应商须与原单一致。当前货位可以与原入库位置不同，但必须属于该仓库并处于启用、正常状态。
- 可退量 = 原 S-25 行数量 − 净已生效退量。同一退货单的重复来源行先合计；不同物料不能互占额度。待审单不预留额度，审核时重新核算，因此两张待审单不能依靠创建时的余量同时超退。
- 审核与冲销在同一事务内更新原入库单的过账版本，使用 ABP 原有并发字段争用同一来源。冲突向调用方返回失败，刷新后重试；不在应用内盲目重放库存或 NC 调用。
- 可用库存仍由 `StockBalanceUpdater` 及 S-13/S-14 的现有规则检查。新增货位复核覆盖新建、审核、实际冲销；不套用“批次未过期才允许采购入库”的规则阻止退回过期物料。
- 冲销复用 `ReverseTransactionAsync`：按原 S-21 数量、金额的反数生成新流水，保留原流水并建立双向关联。使用原实际出库成本，不能用退货单标价重算。
- 历史“状态已冲销但没有反向流水”的单据，重新执行冲销会补回库存。补账完成前仍占来源可退额度；完整补偿后再次执行不多补。缺少原流水、来源错配、部分补偿、状态与完整补偿冲突均明确失败，不能猜数补账。
- 新增采购退货动作权限：`SupplyCore.PurchaseReturn.Create`、`.Approve`（含驳回）、`.Void`、`.Reverse`。五个写接口与服务分别要求对应权限和事务工作单元；查询及组织数据范围继续使用 `SupplyCore.Inventory`。

权限定义、权限目录和测试管理员种子已补齐。当前设计矩阵未单列采购退货岗位授权表，因此普通岗位未被自动扩大授权。正式上线前由权限管理员按确认的岗位办理范围配置新增动作；不能把库存查询权限当作退货审批权。退货页面、换货处理及工作流回调的完整接通属于 10-B 等后续范围，当前 provider 仍保留原有通知记录行为。

## 开发样例与结果

环境为本机 .NET 10，使用仓储替身与实际领域库存更新器；没有连接业务数据库。以下均由 `PurchaseReturnAppService_Tests` 直接核对结存及生成流水。

| 用例 | 预期与已验证结果 |
| --- | --- |
| 原入 6，退 2、再退 4、再申请退 1 | 前两笔通过，结存 0；超退被拒，已记退货流水 2 条 |
| 冲销退 4 | 结存恢复 4；新增 +4 反向流水，与原流水双向关联 |
| 原实际单位成本 50、退货标价 100 | 冲销 4 回补金额 200，不按标价回补 400 |
| 重复冲销 | 流水仍为原退货 2 条加冲销 1 条，库存不再增长 |
| 冲销后重新退 4 | 来源额度已恢复，审核后结存回到 0 |
| 先建两张待审退 4 | 首张通过后余量 2，第二张审批拒绝，未多扣、未再推 NC |
| 重复审核 | 不多记库存流水、不重复调用 NC |
| 物料借额、同来源重复行合计超量 | 按原明细的剩余额度拒绝 |
| 缺来源、来源不属于原单、物料/单位/批次错配 | 新建拒绝，不保存退货 |
| 组织、仓库、供应商与原单不一致 | 新建拒绝 |
| 历史仅改已冲销状态 | 补账前不释放可退量；重办冲销补回一次 |
| 建单后货位冻结 | 审核、冲销均拒绝；既有库存和流水保持不变 |
| 审批/冲销跨组织或仓库 | 返回不可见，不改库存 |
| 来源并发版本写入冲突 | 在库存和 NC 之前失败，单据仍待审 |

- 解决方案构建通过。首次构建纠正了既有链路测试中误加到领料 DTO 的来源字段；此后全签名和调用点同批通过。
- Application 筛选采购退货、Sprint5a、InventoryReferences 与 Permissions：123 项通过。
- Domain 采购退货：21 项通过。
- EF 并发映射守护：4 项通过。该项只验证映射，不列作数据库并发实测。

新增错误提示说明原行缺失、来源不符、累计超退、历史来源待补以及补偿链异常。实体和数据库中既有可空来源列保留，避免通过迁移猜测历史关系；新建请求和领域验证要求明确来源。

## 测试站复验步骤

部署并配置正式岗位后，在 `https://test.fxkyjt.cn` 现有共享库完成以下复验。使用独立可识别的样本单据，记录每条原行、退货、库存和流水标识，不另建复验数据库。

1. 原入 6，退 2、退 4，超退 1 拒绝；保留变动前后 S-13、S-14（启用批次时）与 S-21 证据。
2. 冲销退 4，核对回补数量、实际金额、双向关联及可退量；再次冲销应无额外库存流水。
3. 两个会话并发审核同一来源超额退货，至多一个成功；刷新后余量准确。重复同单审批、冲销也不多记。
4. 通过受控故障使第二条库存行或单头保存失败，核对整个事务回滚：两条库存、流水、单头状态和来源版本均一致。
5. 分别用仅库存查询、创建、审批、冲销岗位直接调用对应端点，核对动作边界；再验证跨组织、跨仓库、被冻结货位。
6. 历史已冲销漏补账样本由业务确认后重办，原流水引用不完整或部分补偿的样本保留异常，不自动猜补。

数据库并发和中途失败回滚尚未实际执行，不能凭属性声明或替身测试标记完成。NC 继续沿用现有 BIZ-RED stub 和失败记录口径，正式财务联调、原入库冲销与已退货之间的跨单业务裁定另行承接；本项完成不能单独关闭 OPEN-044。
