From b7cacaeb8dc2411efdec404634267ba0412e6146 Mon Sep 17 00:00:00 2001 From: rcx <3084692334@qq.com> Date: Wed, 9 Sep 2026 15:38:21 +0800 Subject: [PATCH] =?UTF-8?q?feat(oms,wms):=20=E5=85=A5=E5=BA=93=E4=B8=9A?= =?UTF-8?q?=E5=8A=A1=E5=8D=95=E5=8F=8D=E5=AE=A1=E2=80=94=E2=80=94=E4=B8=9A?= =?UTF-8?q?=E5=8A=A1=E5=8D=95=E6=94=B9=E5=B7=B2=E9=A9=B3=E5=9B=9E+?= =?UTF-8?q?=E5=B7=B2=E5=8F=8D=E5=AE=A1tab=EF=BC=8C=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=E5=8D=95/W=E5=85=A5=E5=BA=93/=E6=94=B6=E8=B4=A7/=E4=B8=8A?= =?UTF-8?q?=E6=9E=B6=E8=BD=AF=E5=88=A0=E6=89=93=E6=A0=87=E5=BD=92=E6=A1=A3?= =?UTF-8?q?=EF=BC=8C=E5=BA=93=E5=AD=98=E8=BF=98=E5=8E=9F=E6=89=A3=E5=87=8F?= =?UTF-8?q?=EF=BC=8CW=E5=85=A5=E5=BA=93=E5=BC=82=E5=B8=B8=E5=8F=8D?= =?UTF-8?q?=E5=AE=A1=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 【需求】已入库/已出库的单子客户通知需要回退的场景,单子回退到最原始状态。反审入口在 OMS-入库业务单页面【反審單據】按钮,一次操作全链路回退。 【反审规则】 1. 按页面状态 issueStatus 判断:进行中(1)/已审核(2)/已入库(4)/部分完成(5) 可反审;已创建(0)无需反审、已驳回(3)可直接编辑;已取消/已关闭(status 6/7)兜底拦截 2. 已推送关务/NC(pushStatus=3)直接拦截,避免关务与仓内数据不一致 3. W入库单有出库记录就不能反审:按入库单号+动作(分配库存/出库)查询库存调整记录>0 即拦截,另校验库存冻结量>0 4. WMS无该单数据时幂等成功(未下发单反审),反审失败可安全重试 【反审动作】 1. 入库业务单:状态改为已驳回(issueStatus=3,与审核不通过同语义,可编辑→重新审核→重新下发),打已反审标记落入【已反审】tab;清空入库数量/入库时间/执行单号,明细 INBOUND_ITEMS/TOTAL_NET_WEIGHT 归零 2. 入库执行单+物料明细:软删(del_flag=2)+打已反审标记,【已反审】tab 按「已软删+已反审」查询归档数据,避免归档单被误审核/下发 3. WMS侧(逐执行单Feign omsReverseInOrder):库存还原扣减(校验库存行合计=已完成上架量后整行对称扣回,GREATEST(x-n,0)兜底)→ W入库单/W收货单/W上架单及明细、收货/上架作业单/任务/质检单整链软删+打已反审标记 → 写1条入库异常【反审记录】(type=3/abnormalType=6,FSYC单号)用于记录跟踪 【接口】 - POST /reservationStockInOrderApi/reverseAudit 反审(inOrderIds + reverseAuditRemark,支持批量) - 已反审tab:/reservationStockInOrderApi/list?reverseAuditStatus=1(执行单/W入库单/W收货单/W上架单同参数,后端固定限定 del_flag=2+标记=1 归档数据) - 归档详情:/executionStockInOrderApi、/stockInOrderApi、/stockReceiptOrderApi、/stockShelfOrderApi 各增 getReverseAuditInfo/{id}(原 getInfo 行为不变) - 反审记录筛选:/inOrderAbnormalApi/list?abnormalType=6 【DDL】sql/20260908_oms_inbound_reverse_audit.sql:RESERVATION_STOCK_IN_ORDER / EXECUTION_STOCK_IN_ORDER / STOCK_IN_ORDER / STOCK_RECEIPT_ORDER / STOCK_SHELF_ORDER 各新增 REVERSE_AUDIT_STATUS/REMARK/BY/BY_NAME/TIME 五列,发服务前先执行 【其他】 - 库存扣减走 batchSubtractInventoryQuantity 并显式传更新人,规避 Feign 链路无登录态时 SecurityUtils 抛异常 - omsReverseInOrder 的 Feign 方法与降级已随出库反审提交(715883f1)入库,本次不再重复提交 - 归档行只读,详情走 getReverseAuditInfo;正常数据与归档数据互不干扰 --- .../entity/ExecutionStockInOrder.java | 17 + .../po/ExecutionStockInOrderPO.java | 17 + .../todo/ExecutionStockInOrderDO.java | 17 + .../todo/ExecutionStockInOrderDTO.java | 17 + ...ecutionStockInOrderApplicationService.java | 19 +- .../ExecutionStockInOrderDomainService.java | 17 + .../entity/ReservationStockInOrder.java | 17 + .../po/ReservationStockInOrderPO.java | 17 + .../todo/ReservationStockInOrderDO.java | 17 + .../todo/ReservationStockInOrderDTO.java | 17 + ...rvationStockInOrderApplicationService.java | 12 +- .../ReservationStockInOrderDomainService.java | 162 ++++++++ .../ExecutionStockInOrderApi.java | 10 + .../ReservationStockInOrderApi.java | 13 + .../ExecutionStockInOrderMapper.xml | 23 +- .../ReservationStockInOrderMapper.xml | 16 +- .../StockInOrderApplicationService.java | 27 +- .../entity/InOrderAbnormal.java | 8 +- .../facade/IInOrderAbnormalService.java | 7 + .../persistence/InOrderAbnormalImpl.java | 19 + .../stockInOrder/entity/StockInOrder.java | 17 + .../repository/po/StockInOrderPO.java | 17 + .../repository/todo/StockInOrderDO.java | 17 + .../service/StockInOrderDomainService.java | 346 +++++++++++++++++- .../entity/StockReceiptOrder.java | 17 + .../repository/po/StockReceiptOrderPO.java | 17 + .../repository/todo/StockReceiptOrderDO.java | 17 + .../entity/StockShelfOrder.java | 17 + .../repository/po/StockShelfOrderPO.java | 17 + .../repository/todo/StockShelfOrderDO.java | 17 + .../dto/stockInOrder/StockInOrderDTO.java | 3 + .../StockReceiptOrderDTO.java | 3 + .../stockShelfOrder/StockShelfOrderDTO.java | 3 + .../stockInOrder/StockInOrderApi.java | 21 ++ .../stockInOrder/StockInOrderMapper.xml | 23 +- .../StockReceiptOrderMapper.xml | 21 +- .../stockShelfOrder/StockShelfOrderMapper.xml | 19 +- sql/20260908_oms_inbound_reverse_audit.sql | 93 +++++ 38 files changed, 1127 insertions(+), 27 deletions(-) create mode 100644 sql/20260908_oms_inbound_reverse_audit.sql diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockInOrder/entity/ExecutionStockInOrder.java b/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockInOrder/entity/ExecutionStockInOrder.java index a632a9046..87e18b112 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockInOrder/entity/ExecutionStockInOrder.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockInOrder/entity/ExecutionStockInOrder.java @@ -459,4 +459,21 @@ public class ExecutionStockInOrder extends BaseVOEntity { @ApiModelProperty("通知单备注") private String noticeRemark; + + @ApiModelProperty("反审状态: 0-无 1-已反审") + private Integer reverseAuditStatus; + + @ApiModelProperty("反审原因") + private String reverseAuditRemark; + + @ApiModelProperty("反审人id") + private Long reverseAuditBy; + + @ApiModelProperty("反审人姓名") + private String reverseAuditByName; + + @ApiModelProperty("反审时间") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date reverseAuditTime; } \ No newline at end of file diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockInOrder/repository/po/ExecutionStockInOrderPO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockInOrder/repository/po/ExecutionStockInOrderPO.java index 304015586..f1c276df9 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockInOrder/repository/po/ExecutionStockInOrderPO.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockInOrder/repository/po/ExecutionStockInOrderPO.java @@ -482,4 +482,21 @@ public class ExecutionStockInOrderPO extends BaseVOEntity { private String khdm; @ApiModelProperty("通知单备注") private String noticeRemark; + + @ApiModelProperty("反审状态: 0-无 1-已反审") + private Integer reverseAuditStatus; + + @ApiModelProperty("反审原因") + private String reverseAuditRemark; + + @ApiModelProperty("反审人id") + private Long reverseAuditBy; + + @ApiModelProperty("反审人姓名") + private String reverseAuditByName; + + @ApiModelProperty("反审时间") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date reverseAuditTime; } \ No newline at end of file diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockInOrder/repository/todo/ExecutionStockInOrderDO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockInOrder/repository/todo/ExecutionStockInOrderDO.java index 9da4e4dd7..4f0851406 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockInOrder/repository/todo/ExecutionStockInOrderDO.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockInOrder/repository/todo/ExecutionStockInOrderDO.java @@ -513,4 +513,21 @@ public class ExecutionStockInOrderDO extends BaseVOEntity { private String businessPriceWay; @ApiModelProperty("通知单备注") private String noticeRemark; + + @ApiModelProperty("反审状态: 0-无 1-已反审") + private Integer reverseAuditStatus; + + @ApiModelProperty("反审原因") + private String reverseAuditRemark; + + @ApiModelProperty("反审人id") + private Long reverseAuditBy; + + @ApiModelProperty("反审人姓名") + private String reverseAuditByName; + + @ApiModelProperty("反审时间") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date reverseAuditTime; } \ No newline at end of file diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockInOrder/repository/todo/ExecutionStockInOrderDTO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockInOrder/repository/todo/ExecutionStockInOrderDTO.java index 2957ed604..ca947d339 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockInOrder/repository/todo/ExecutionStockInOrderDTO.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockInOrder/repository/todo/ExecutionStockInOrderDTO.java @@ -510,4 +510,21 @@ public class ExecutionStockInOrderDTO extends ExecutionStockInOrderBaseDTO { private String businessPriceWay; @ApiModelProperty("通知单备注") private String noticeRemark; + + @ApiModelProperty("反审状态: 0-无 1-已反审") + private Integer reverseAuditStatus; + + @ApiModelProperty("反审原因") + private String reverseAuditRemark; + + @ApiModelProperty("反审人id") + private Long reverseAuditBy; + + @ApiModelProperty("反审人姓名") + private String reverseAuditByName; + + @ApiModelProperty("反审时间") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date reverseAuditTime; } \ No newline at end of file diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockInOrder/service/ExecutionStockInOrderApplicationService.java b/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockInOrder/service/ExecutionStockInOrderApplicationService.java index 46a751e43..0491c2d66 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockInOrder/service/ExecutionStockInOrderApplicationService.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockInOrder/service/ExecutionStockInOrderApplicationService.java @@ -263,7 +263,16 @@ public class ExecutionStockInOrderApplicationService { */ public ExecutionStockInOrderPO getInfo(Long inOrderId) { - ExecutionStockInOrderPO info = stockInOrderDomainService.getInfo(inOrderId); + return getInfo(inOrderId, false); + } + + /** + * 获取入库执行单详情(getReverseAuditInfo 归档详情复用) + * @param archive true-查询【已反审】tab 归档数据 + */ + public ExecutionStockInOrderPO getInfo(Long inOrderId, boolean archive) + { + ExecutionStockInOrderPO info = stockInOrderDomainService.getInfo(inOrderId, archive); String userNcCode = reservationStockInOrderMapper.getUserNcCode(info.getShipperId()); info.setKhdm(userNcCode); List materialDetailList = info.getMaterialDetailList(); @@ -276,6 +285,14 @@ public class ExecutionStockInOrderApplicationService { return info; } + /** + * 查询入库执行单【已反审】tab 归档详情(已软删+已反审标记的数据,含软删明细) + */ + public ExecutionStockInOrderPO getReverseAuditInfo(Long inOrderId) + { + return getInfo(inOrderId, true); + } + /** diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockInOrder/service/ExecutionStockInOrderDomainService.java b/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockInOrder/service/ExecutionStockInOrderDomainService.java index b6a8e0209..3758a733e 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockInOrder/service/ExecutionStockInOrderDomainService.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockInOrder/service/ExecutionStockInOrderDomainService.java @@ -314,14 +314,31 @@ public class ExecutionStockInOrderDomainService { * 获取入库单详细信息 */ public ExecutionStockInOrderPO getInfo(Long inOrderId) + { + return getInfo(inOrderId, false); + } + + /** + * 获取入库执行单详情 + * @param archive true-查询【已反审】tab 归档数据(主单须为已软删+已反审标记,明细放行软删行) + */ + public ExecutionStockInOrderPO getInfo(Long inOrderId, boolean archive) { ExecutionStockInOrderPO stockInOrderPO = stockInOrderService.getInfo(inOrderId); + if (archive && (stockInOrderPO.getDelFlag() == null || stockInOrderPO.getDelFlag() != 2 + || !Integer.valueOf(1).equals(stockInOrderPO.getReverseAuditStatus()))) { + throw new ServiceException("入库执行单非已反审归档数据,无法查看归档详情"); + } ExecutionInMaterialDetailDO inMaterialDetailDO = new ExecutionInMaterialDetailDO(); String inOrderNumber = stockInOrderPO.getInOrderNumber(); List businessDocumentOrders = businessDocumentOrderMapper.selectList(new LambdaQueryWrapper().eq(BusinessDocumentOrder::getInOrderNumber, inOrderNumber).notIn(BusinessDocumentOrder::getOrderStatus,4,5)); stockInOrderPO.setBusinessDocumentOrderDOList(businessDocumentOrders); inMaterialDetailDO.setInOrderNumber(inOrderNumber); inMaterialDetailDO.setLevel(1); + if (archive) { + //归档明细已随主单软删(del_flag=2),放行软删明细行 + inMaterialDetailDO.setDelFlag(2); + } List inMaterialDetailPOList = materialDetailService.queryList(inMaterialDetailDO); // 先通过入库单号查询收货单列表 diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/entity/ReservationStockInOrder.java b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/entity/ReservationStockInOrder.java index f61291f28..eede5606f 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/entity/ReservationStockInOrder.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/entity/ReservationStockInOrder.java @@ -456,4 +456,21 @@ public class ReservationStockInOrder extends BaseVOEntity { @ApiModelProperty("业务计价方式") private String businessPriceWay; + + @ApiModelProperty("反审状态: 0-无 1-已反审") + private Integer reverseAuditStatus; + + @ApiModelProperty("反审原因") + private String reverseAuditRemark; + + @ApiModelProperty("反审人id") + private Long reverseAuditBy; + + @ApiModelProperty("反审人姓名") + private String reverseAuditByName; + + @ApiModelProperty("反审时间") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date reverseAuditTime; } \ No newline at end of file diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/po/ReservationStockInOrderPO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/po/ReservationStockInOrderPO.java index 932142c33..782df5252 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/po/ReservationStockInOrderPO.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/po/ReservationStockInOrderPO.java @@ -502,4 +502,21 @@ public class ReservationStockInOrderPO extends BaseVOEntity { @ApiModelProperty("业务计价方式") private String businessPriceWay; private String khdm; + + @ApiModelProperty("反审状态: 0-无 1-已反审") + private Integer reverseAuditStatus; + + @ApiModelProperty("反审原因") + private String reverseAuditRemark; + + @ApiModelProperty("反审人id") + private Long reverseAuditBy; + + @ApiModelProperty("反审人姓名") + private String reverseAuditByName; + + @ApiModelProperty("反审时间") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date reverseAuditTime; } \ No newline at end of file diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/todo/ReservationStockInOrderDO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/todo/ReservationStockInOrderDO.java index fe2eb7cc2..e5e31f27b 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/todo/ReservationStockInOrderDO.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/todo/ReservationStockInOrderDO.java @@ -513,4 +513,21 @@ public class ReservationStockInOrderDO extends BaseVOEntity { @ApiModelProperty("业务计价方式") private String businessPriceWay; + + @ApiModelProperty("反审状态: 0-无 1-已反审") + private Integer reverseAuditStatus; + + @ApiModelProperty("反审原因") + private String reverseAuditRemark; + + @ApiModelProperty("反审人id") + private Long reverseAuditBy; + + @ApiModelProperty("反审人姓名") + private String reverseAuditByName; + + @ApiModelProperty("反审时间") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date reverseAuditTime; } \ No newline at end of file diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/todo/ReservationStockInOrderDTO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/todo/ReservationStockInOrderDTO.java index fb0ff4f6f..bf269c011 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/todo/ReservationStockInOrderDTO.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/todo/ReservationStockInOrderDTO.java @@ -507,4 +507,21 @@ public class ReservationStockInOrderDTO extends ReservationStockInOrderBaseDTO { @ApiModelProperty("业务计价方式") private String businessPriceWay; + + @ApiModelProperty("反审状态: 0-无 1-已反审") + private Integer reverseAuditStatus; + + @ApiModelProperty("反审原因") + private String reverseAuditRemark; + + @ApiModelProperty("反审人id") + private Long reverseAuditBy; + + @ApiModelProperty("反审人姓名") + private String reverseAuditByName; + + @ApiModelProperty("反审时间") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date reverseAuditTime; } \ No newline at end of file diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/service/ReservationStockInOrderApplicationService.java b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/service/ReservationStockInOrderApplicationService.java index 9e5049c8f..19c8cdfba 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/service/ReservationStockInOrderApplicationService.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/service/ReservationStockInOrderApplicationService.java @@ -282,8 +282,7 @@ public class ReservationStockInOrderApplicationService { * @return Boolean */ public Boolean auditState(ReservationStockInOrderDO stockInOrderDO){ - Boolean b = stockInOrderDomainService.auditState(stockInOrderDO); -// List inOrderIds = stockInOrderDO.getInOrderIds(); + Boolean b = stockInOrderDomainService.auditState(stockInOrderDO);// List inOrderIds = stockInOrderDO.getInOrderIds(); // if (inOrderIds != null && !inOrderIds.isEmpty()) { // ReservationStockInOrder stockInOrder = reservationStockInOrderMapper.selectById(inOrderIds.get(0)); // Integer needCustomsDeclaration = stockInOrder.getNeedCustomsDeclaration(); @@ -302,6 +301,15 @@ public class ReservationStockInOrderApplicationService { return b; } + /** + * 反审入库业务单:业务单状态改为已驳回(issueStatus=3)并打已反审标记落入【已反审】tab, + * 入库执行单+明细逻辑删除,WMS侧整链回退(库存扣减+单据清理+反审异常记录), + * W入库单有出库记录时WMS侧拦截,已推送关务直接拦截 + */ + public Boolean reverseAudit(ReservationStockInOrderDO stockInOrderDO){ + return stockInOrderDomainService.reverseAudit(stockInOrderDO); + } + /** * @description 下发入库单 * @author ZhouGY diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/service/ReservationStockInOrderDomainService.java b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/service/ReservationStockInOrderDomainService.java index f327fda66..396935fef 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/service/ReservationStockInOrderDomainService.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/service/ReservationStockInOrderDomainService.java @@ -13,6 +13,9 @@ import com.mhd.common.core.web.domain.AjaxResult; import com.mhd.common.security.utils.SecurityUtils; import com.mhd.oms.domain.businessDocumentOrder.entity.BusinessDocumentOrder; import com.mhd.oms.domain.businessDocumentOrder.repository.mapper.BusinessDocumentOrderMapper; +import com.mhd.oms.domain.electronicSignature.entity.ElectronicSignature; +import com.mhd.oms.domain.electronicSignature.repository.facade.IElectronicSignatureMaterialDetailService; +import com.mhd.oms.domain.electronicSignature.repository.facade.IElectronicSignatureService; import com.mhd.oms.domain.executionInMaterialDetail.entity.ExecutionInMaterialDetail; import com.mhd.oms.domain.executionInMaterialDetail.repository.facade.IExecutionInMaterialDetailService; import com.mhd.oms.domain.executionStockInOrder.entity.ExecutionStockInOrder; @@ -91,6 +94,10 @@ public class ReservationStockInOrderDomainService { private ExecutionStockInOrderMapper executionStockInOrderMapper; @Autowired private ReserveStockInOrderMapper reserveStockInOrderMapper; + @Autowired + private IElectronicSignatureService electronicSignatureService; + @Autowired + private IElectronicSignatureMaterialDetailService electronicSignatureMaterialDetailService; /** * 分页查询入库单列表 @@ -767,6 +774,161 @@ public class ReservationStockInOrderDomainService { } } + /** + * 反审入库业务单(需求:已入库/已出库的单子客户通知需要回退的场景,单子回退到最原始状态): + * 页面状态列按 issueStatus(0-已创建 1-进行中 2-已审核 3-已驳回 4-已入库 5-部分完成)展示, + * 反审条件按 issueStatus 判断——进行中(1)/已审核(2)/已入库(4)/部分完成(5)可反审, + * 已创建(0)无需反审、已驳回(3)可直接编辑;已取消/已关闭(status 6/7)兜底拦截。 + * 反审动作("审核不通过"同语义 + 全链路回退,补齐 auditState 审核不通过缺失的下游联动): + *
    + *
  • 业务单状态改为"已驳回"(issueStatus=3),打已反审标记(REVERSE_AUDIT_STATUS=1)落入【已反审】tab, + * 之后可「编辑」→重新「审核」→重新「下发」生成全新执行单
  • + *
  • 入库执行单+物料明细软删(del_flag=2)并打已反审标记——执行单【已反审】tab按 + * "已软删+已反审"查询归档数据;软删后不出现在正常tab,避免归档单被误「审核/下发」
  • + *
  • 清空WMS完成上架跨库回写的完成数据(业务单 IN_QUANTITY/STORAGE_TIME、明细 INBOUND_ITEMS/TOTAL_NET_WEIGHT)
  • + *
  • WMS侧逐执行单回退(omsReverseInOrder):W入库单有出库记录则拦截(按入库单号+动作"分配库存/出库" + * 查库存调整记录>0)→ 库存还原扣减 → W入库单/W收货单/W上架单整链软删并打已反审标记 + * (数据划归W入库单/W收货单/W上架单【已反审】tab归档)→ + * 写1条W入库异常【反审记录】用于记录跟踪
  • + *
+ * 已推送关务(pushStatus=3)直接拦截。WMS回退幂等,反审失败可安全重试。 + */ + @Transactional(rollbackFor = Exception.class) + public Boolean reverseAudit(ReservationStockInOrderDO stockInOrderDO) { + LoginUser loginUser = SecurityUtils.getLoginUser(); + // 获取用户姓名(优先从UserPo获取,如果为空则使用realname,最后使用username作为兜底) + String userRealName = loginUser.getUserPo() != null && loginUser.getUserPo().getUserName() != null + ? loginUser.getUserPo().getUserName() + : (loginUser.getRealname() != null ? loginUser.getRealname() : loginUser.getUsername()); + + List inOrderIds = stockInOrderDO.getInOrderIds(); + if (inOrderIds == null || inOrderIds.isEmpty()) { + throw new ServiceException("未选择反审的入库业务单"); + } + Date now = new Date(); + for (Long inOrderId : inOrderIds) { + ReservationStockInOrder businessOrder = stockInOrderService.getById(inOrderId); + if (businessOrder == null + || (businessOrder.getDelFlag() != null && businessOrder.getDelFlag() != 1)) { + throw new ServiceException("入库业务单不存在或已被删除,无法反审"); + } + String businessNumber = businessOrder.getInOrderNumber(); + Integer issueStatus = businessOrder.getIssueStatus(); + if (issueStatus == null || issueStatus == 0) { + throw new ServiceException("入库业务单[" + businessNumber + "]为已创建状态,无需反审"); + } + if (issueStatus == 3) { + throw new ServiceException("入库业务单[" + businessNumber + "]已驳回,无需反审,可直接编辑后重新提交审核"); + } + if (issueStatus != 1 && issueStatus != 2 && issueStatus != 4 && issueStatus != 5) { + throw new ServiceException("入库业务单[" + businessNumber + "]仅进行中/已审核/已入库状态可反审,当前状态值:" + issueStatus); + } + if (businessOrder.getStatus() != null && (businessOrder.getStatus() == 6 || businessOrder.getStatus() == 7)) { + throw new ServiceException("入库业务单[" + businessNumber + "]已取消/已关闭,无法反审"); + } + if (businessOrder.getPushStatus() != null && businessOrder.getPushStatus() == 3) { + throw new ServiceException("入库业务单[" + businessNumber + "]已推送关务/NC,无法反审,请先在关务侧处理"); + } + + //该业务单下全部有效执行单:逐张调WMS回退后软删并打已反审标记 + List executionOrders = executionStockInOrderService.list( + new LambdaQueryWrapper() + .eq(ExecutionStockInOrder::getBusinessInOrderNumber, businessNumber) + .eq(ExecutionStockInOrder::getDelFlag, 1)); + for (ExecutionStockInOrder executionOrder : executionOrders) { + String executionNumber = executionOrder.getInOrderNumber(); + if (executionOrder.getPushStatus() != null && executionOrder.getPushStatus() == 3) { + throw new ServiceException("执行入库单[" + executionNumber + "]已推送关务/NC,无法反审,请先在关务侧处理"); + } + //WMS侧回退(对称收货/上架完成链路,见 WMS StockInOrderDomainService.reverseExecutionOrder): + //有出库/库存已被分配时WMS报错,此处抛错整体回滚;WMS无数据时幂等成功(未下发执行单反审) + StockInOrder reverseParam = new StockInOrder(); + reverseParam.setInOrderNumber(executionNumber); + reverseParam.setRemark("业务单号:" + businessNumber + + (StringUtils.isNotEmpty(stockInOrderDO.getReverseAuditRemark()) + ? ",反审原因:" + stockInOrderDO.getReverseAuditRemark() : "")); + reverseParam.setUpdateBy(loginUser.getUserid()); + reverseParam.setUpdateByName(userRealName); + AjaxResult reverseResult = wmsServiceFeign.omsReverseInOrder(reverseParam); + if (reverseResult == null || !"200".equals(String.valueOf(reverseResult.get("code")))) { + throw new ServiceException("反审失败:执行入库单[" + executionNumber + "]WMS回退失败:" + + (reverseResult == null ? "WMS服务不可用或已降级" : reverseResult.get("msg"))); + } + //清理下发自动审核生成的待签名电子签名记录(signatureStatus=1,已签名记录保留作凭证) + cancelPendingSignature(executionNumber); + //执行单+物料明细软删(del_flag=2)并打已反审标记: + //执行单【已反审】tab按"已软删+已反审"(del_flag=2 and REVERSE_AUDIT_STATUS=1)查询归档数据; + //软删后不出现在正常tab,避免归档单被误「审核/下发」;业务单重新下发时生成全新执行单 + executionInMaterialDetailService.update(new UpdateWrapper().lambda() + .set(ExecutionInMaterialDetail::getDelFlag, 2) + .set(ExecutionInMaterialDetail::getUpdateBy, loginUser.getUserid()) + .set(ExecutionInMaterialDetail::getUpdateByName, userRealName) + .set(ExecutionInMaterialDetail::getUpdateTime, now) + .eq(ExecutionInMaterialDetail::getInOrderNumber, executionNumber) + .eq(ExecutionInMaterialDetail::getDelFlag, 1)); + executionStockInOrderService.update(new UpdateWrapper().lambda() + .set(ExecutionStockInOrder::getDelFlag, 2) + .set(ExecutionStockInOrder::getReverseAuditStatus, 1) + .set(ExecutionStockInOrder::getReverseAuditRemark, stockInOrderDO.getReverseAuditRemark()) + .set(ExecutionStockInOrder::getReverseAuditBy, loginUser.getUserid()) + .set(ExecutionStockInOrder::getReverseAuditByName, userRealName) + .set(ExecutionStockInOrder::getReverseAuditTime, now) + .set(ExecutionStockInOrder::getUpdateBy, loginUser.getUserid()) + .set(ExecutionStockInOrder::getUpdateByName, userRealName) + .set(ExecutionStockInOrder::getUpdateTime, now) + .eq(ExecutionStockInOrder::getInOrderId, executionOrder.getInOrderId()) + .eq(ExecutionStockInOrder::getDelFlag, 1)); + } + + //清空WMS完成上架跨库回写的业务单明细入库数量(INBOUND_ITEMS/TOTAL_NET_WEIGHT 上架时按上架量覆写过) + materialDetailService.update(new UpdateWrapper().lambda() + .set(ReservationInMaterialDetail::getInboundQuantity, BigDecimal.ZERO) + .set(ReservationInMaterialDetail::getTotalNetWeight, BigDecimal.ZERO) + .eq(ReservationInMaterialDetail::getInOrderNumber, businessNumber) + .eq(ReservationInMaterialDetail::getDelFlag, 1)); + } + + //业务单状态改为"已驳回"(与审核不通过同语义)+ 已反审标记落入【已反审】tab + 清空完成回写数据 + return stockInOrderService.update(null, new UpdateWrapper().lambda() + .set(ReservationStockInOrder::getIssueStatus, 3) + .set(ReservationStockInOrder::getInQuantity, BigDecimal.ZERO) + .set(ReservationStockInOrder::getStorageTime, null) + .set(ReservationStockInOrder::getExecutionInOrderNumber, null) + //反审标记与反审痕迹(【已反审】tab 按 reverseAuditStatus=1 过滤;业务单本身不软删,保持可编辑重新下发) + .set(ReservationStockInOrder::getReverseAuditStatus, 1) + .set(ReservationStockInOrder::getReverseAuditRemark, stockInOrderDO.getReverseAuditRemark()) + .set(ReservationStockInOrder::getReverseAuditBy, loginUser.getUserid()) + .set(ReservationStockInOrder::getReverseAuditByName, userRealName) + .set(ReservationStockInOrder::getReverseAuditTime, now) + .set(ReservationStockInOrder::getUpdateBy, loginUser.getUserid()) + .set(ReservationStockInOrder::getUpdateByName, userRealName) + .set(ReservationStockInOrder::getUpdateTime, now) + .in(ReservationStockInOrder::getInOrderId, inOrderIds)); + } + + /** + * 反审时清理下发自动审核生成的待签名电子签名记录(signatureStatus=1)及其明细, + * 已签名记录保留作凭证;清理失败仅记日志不阻断反审主流程(同取消下发) + */ + private void cancelPendingSignature(String inOrderNumber) { + try { + List signatures = electronicSignatureService.list( + new LambdaQueryWrapper() + .eq(ElectronicSignature::getOrderNumber, inOrderNumber) + .eq(ElectronicSignature::getOrderType, "IN") + .eq(ElectronicSignature::getSignatureStatus, 1) + .eq(ElectronicSignature::getDelFlag, 1)); + for (ElectronicSignature signature : signatures) { + electronicSignatureMaterialDetailService.deleteBySignatureId(signature.getSignatureId()); + electronicSignatureService.update(new UpdateWrapper().lambda() + .set(ElectronicSignature::getDelFlag, 2) + .eq(ElectronicSignature::getSignatureId, signature.getSignatureId())); + } + } catch (Exception e) { + log.error("反审清理电子签名记录失败,入库单号:{}", inOrderNumber, e); + } + } + @Transactional(rollbackFor = Exception.class) public Boolean executeAndIssue(ReservationStockInOrderDO stockInOrderDO) { // 防重复执行校验(与 issueOrder 的防重逻辑对齐):issueTime 有值表示已下发/执行过。 diff --git a/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/executionStockInOrder/ExecutionStockInOrderApi.java b/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/executionStockInOrder/ExecutionStockInOrderApi.java index 6406a2472..68469eecf 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/executionStockInOrder/ExecutionStockInOrderApi.java +++ b/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/executionStockInOrder/ExecutionStockInOrderApi.java @@ -93,6 +93,16 @@ public class ExecutionStockInOrderApi extends BaseController { return AjaxResult.success(stockInOrderApplicationService.getInfo(inOrderId)); } + /** + * 查询入库执行单【已反审】tab 归档详情(已软删+已反审标记的数据,含软删明细) + */ + @ApiOperation("查询入库执行单已反审归档详情") + @GetMapping(value = "/getReverseAuditInfo/{inOrderId}") + public AjaxResult getReverseAuditInfo(@PathVariable("inOrderId") Long inOrderId) + { + return AjaxResult.success(stockInOrderApplicationService.getReverseAuditInfo(inOrderId)); + } + /** * 导入入库单 */ diff --git a/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/reservationStockInOrder/ReservationStockInOrderApi.java b/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/reservationStockInOrder/ReservationStockInOrderApi.java index 5e497d56c..cd6a3701e 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/reservationStockInOrder/ReservationStockInOrderApi.java +++ b/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/reservationStockInOrder/ReservationStockInOrderApi.java @@ -122,6 +122,19 @@ public class ReservationStockInOrderApi extends BaseController { return AjaxResult.success(stockInOrderApplicationService.auditState(stockInOrderDO)); } + /** + * 反审入库业务单:已入库/已出库的单子客户通知需要回退的场景,单子回退到最原始状态—— + * 业务单状态改为"已驳回"(issueStatus=3,与审核不通过同语义,可编辑→重新审核→重新下发) + * 并打已反审标记落入【已反审】tab;入库执行单+明细软删并打已反审标记; + * W入库单有出库记录时WMS侧拦截不允许反审;已推送关务(pushStatus=3)直接拦截 + */ + @ApiOperation("反审入库业务单") + @PostMapping(value = "/reverseAudit") + public AjaxResult reverseAudit(@RequestBody ReservationStockInOrderDTO stockInOrderDTO) { + ReservationStockInOrderDO stockInOrderDO = stockInOrderAssembler.toDO(stockInOrderDTO); + return AjaxResult.success(stockInOrderApplicationService.reverseAudit(stockInOrderDO)); + } + /** * 下发入库单 */ diff --git a/mhd_oms/src/main/resources/mapper/executionStockInOrder/ExecutionStockInOrderMapper.xml b/mhd_oms/src/main/resources/mapper/executionStockInOrder/ExecutionStockInOrderMapper.xml index e241f6801..e321f8670 100644 --- a/mhd_oms/src/main/resources/mapper/executionStockInOrder/ExecutionStockInOrderMapper.xml +++ b/mhd_oms/src/main/resources/mapper/executionStockInOrder/ExecutionStockInOrderMapper.xml @@ -108,6 +108,11 @@ + + + + + @@ -145,7 +150,8 @@ a.WAREHOUSE_DATE, a.COMPLETION_TIME, a.ORDER_DATE,a.reservation_audit_time,a.reservation_audit_name ,a.reservation_audit_id,a.issue_name,a.issue_id,a.issue_time,a.issue_status,a.RESERVATION_ORDER_SOURCE,a.tms_order_number ,a.DIRECTOR_NAME ,a.DIRECTOR_PHONE,a.DIRECTOR_ID,a.STORAGE_TIME,a.in_quantity, - a.PUSH_TIME,a.PUSH_STATUS,a.PUSH_BY,a.PUSH_BY_NAME + a.PUSH_TIME,a.PUSH_STATUS,a.PUSH_BY,a.PUSH_BY_NAME, + a.REVERSE_AUDIT_STATUS,a.REVERSE_AUDIT_REMARK,a.REVERSE_AUDIT_BY,a.REVERSE_AUDIT_BY_NAME,a.REVERSE_AUDIT_TIME @@ -288,7 +294,7 @@ and a.order_type_code = #{orderTypeCode} - and (a.BUSINESS_TYPE like concat('%', #{orderTypeName}, '%') or a.ORDER_TYPE_CODE like concat('%', #{orderTypeName}, '%')) + and (a.ORDER_TYPE_NAME like concat('%', #{orderTypeName}, '%') or a.BUSINESS_TYPE like concat('%', #{orderTypeName}, '%') or a.ORDER_TYPE_CODE like concat('%', #{orderTypeName}, '%')) and a.supplier_id = #{supplierId} @@ -501,9 +507,18 @@ ) + - and a.del_flag = #{delFlag} - and a.del_flag = 1 + + and a.REVERSE_AUDIT_STATUS = #{reverseAuditStatus} + and a.del_flag = 2 + + + + and a.del_flag = #{delFlag} + and a.del_flag = 1 + + diff --git a/mhd_oms/src/main/resources/mapper/reservationStockInOrder/ReservationStockInOrderMapper.xml b/mhd_oms/src/main/resources/mapper/reservationStockInOrder/ReservationStockInOrderMapper.xml index 7d5ab84a6..505b00c03 100644 --- a/mhd_oms/src/main/resources/mapper/reservationStockInOrder/ReservationStockInOrderMapper.xml +++ b/mhd_oms/src/main/resources/mapper/reservationStockInOrder/ReservationStockInOrderMapper.xml @@ -109,6 +109,11 @@ + + + + + @@ -155,7 +160,8 @@ a.WAREHOUSE_DATE, a.COMPLETION_TIME, a.ORDER_DATE,a.reservation_audit_time,a.reservation_audit_name ,a.reservation_audit_id,a.issue_name,a.issue_id,a.issue_time,a.issue_status,a.RESERVATION_ORDER_SOURCE,a.tms_order_number ,a.DIRECTOR_NAME ,a.DIRECTOR_PHONE,a.DIRECTOR_ID,a.STORAGE_TIME,a.in_quantity, - a.PUSH_TIME,a.PUSH_STATUS,a.PUSH_BY,a.PUSH_BY_NAME,a.execution_in_order_number + a.PUSH_TIME,a.PUSH_STATUS,a.PUSH_BY,a.PUSH_BY_NAME,a.execution_in_order_number, + a.REVERSE_AUDIT_STATUS,a.REVERSE_AUDIT_REMARK,a.REVERSE_AUDIT_BY,a.REVERSE_AUDIT_BY_NAME,a.REVERSE_AUDIT_TIME @@ -239,7 +245,7 @@ and a.notice_number = #{noticeNumber} - and a.in_order_number = #{inOrderNumber} + and a.in_order_number like concat('%', #{inOrderNumber}, '%') and a.status = #{status} @@ -274,6 +280,10 @@ and a.issue_status = #{issueStatus} + + + and a.REVERSE_AUDIT_STATUS = #{reverseAuditStatus} + and a.warehouse_id = #{warehouseId} @@ -293,7 +303,7 @@ and a.order_type_code = #{orderTypeCode} - and (a.BUSINESS_TYPE like concat('%', #{orderTypeName}, '%') or a.ORDER_TYPE_CODE like concat('%', #{orderTypeName}, '%')) + and (a.ORDER_TYPE_NAME like concat('%', #{orderTypeName}, '%') or a.BUSINESS_TYPE like concat('%', #{orderTypeName}, '%') or a.ORDER_TYPE_CODE like concat('%', #{orderTypeName}, '%')) and a.supplier_id = #{supplierId} diff --git a/mhd_wms/src/main/java/com/mhd/wms/application/service/stockInOrder/StockInOrderApplicationService.java b/mhd_wms/src/main/java/com/mhd/wms/application/service/stockInOrder/StockInOrderApplicationService.java index 03d02de33..042799783 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/application/service/stockInOrder/StockInOrderApplicationService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/application/service/stockInOrder/StockInOrderApplicationService.java @@ -667,7 +667,16 @@ public class StockInOrderApplicationService { */ public StockInOrderPO getInfo(Long inOrderId) { - StockInOrderPO info = stockInOrderDomainService.getInfo(inOrderId); + return getInfo(inOrderId, false); + } + + /** + * 获取入库单详情 + * @param archive true-查询【已反审】tab 归档数据(已软删+已反审标记,明细放行软删行) + */ + public StockInOrderPO getInfo(Long inOrderId, boolean archive) + { + StockInOrderPO info = stockInOrderDomainService.getInfo(inOrderId, archive); String userNcCode = stockOutOrderMapper.getUserNcCode(info.getShipperId()); info.setKhdm(userNcCode); List materialDetailList = info.getMaterialDetailList(); @@ -762,6 +771,14 @@ public class StockInOrderApplicationService { return info; } + /** + * 查询入库单【已反审】tab 归档详情(已软删+已反审标记的数据,含软删明细/收货单/上架单) + */ + public StockInOrderPO getReverseAuditInfo(Long inOrderId) + { + return getInfo(inOrderId, true); + } + /** @@ -955,6 +972,14 @@ public class StockInOrderApplicationService { stockInOrderDomainService.cancelExecutionOrder(stockInOrder); } + /** + * OMS入库业务单反审:WMS侧回退已完成单据(出库拦截 -> 回退库存 -> + * 逻辑删除收货/上架链路 -> 写入库异常【反审记录】),已产生出库则报错拦截 + */ + public void omsReverseInOrder(StockInOrder stockInOrder){ + stockInOrderDomainService.reverseExecutionOrder(stockInOrder); + } + /** * @description 取消入库单 * @author ZhouGY diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/inOrderAbnormal/entity/InOrderAbnormal.java b/mhd_wms/src/main/java/com/mhd/wms/domain/inOrderAbnormal/entity/InOrderAbnormal.java index abc6692c8..8316f0ebd 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/inOrderAbnormal/entity/InOrderAbnormal.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/inOrderAbnormal/entity/InOrderAbnormal.java @@ -53,8 +53,8 @@ public class InOrderAbnormal extends BaseVOEntity { @Excel(name = "上架单号") private String shelfOrderNumber; - @ApiModelProperty("类型:1-收货 2-上架") - @Excel(name = "类型:1-收货 2-上架") + @ApiModelProperty("类型:1-收货 2-上架 3-反审") + @Excel(name = "类型:1-收货 2-上架 3-反审") private Integer type; @ApiModelProperty("计划数量") @@ -73,8 +73,8 @@ public class InOrderAbnormal extends BaseVOEntity { @Excel(name = "异常数量") private BigDecimal abnormalActualQuantity; - @ApiModelProperty("异常类型: 1-上架异常 2-收货异常 3-收货异常(允许超收没超出超收比例) 4-收货异常(不允许超收)5-收货异常(允许超收但超出超收比例)") - @Excel(name = "异常类型: 1-上架异常 2-收货异常 3-收货异常", readConverterExp = "允=许超收但不允许超出超收比例") + @ApiModelProperty("异常类型: 1-上架异常 2-收货异常 3-收货异常(允许超收没超出超收比例) 4-收货异常(不允许超收)5-收货异常(允许超收但超出超收比例) 6-反审记录") + @Excel(name = "异常类型: 1-上架异常 2-收货异常 6-反审记录", readConverterExp = "允=许超收但不允许超出超收比例") private Integer abnormalType; @ApiModelProperty("异常原因") diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/inOrderAbnormal/repository/facade/IInOrderAbnormalService.java b/mhd_wms/src/main/java/com/mhd/wms/domain/inOrderAbnormal/repository/facade/IInOrderAbnormalService.java index ea1f1768c..c4381ded8 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/inOrderAbnormal/repository/facade/IInOrderAbnormalService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/inOrderAbnormal/repository/facade/IInOrderAbnormalService.java @@ -51,4 +51,11 @@ public interface IInOrderAbnormalService extends IService * @return Boolean */ Boolean genInOrderAbnormal(InOrderAbnormalBaseDO inOrderAbnormalBaseDO, Integer type); + + /** + * 生成入库异常【反审记录】(入库业务单反审时调用,用于记录跟踪) + * 单号自动生成(FSYC 前缀,与出库反审记录一致),固定 type=3(反审)、abnormalType=6(反审记录), + * 其余字段(inOrderNumber/abnormalReason/quantity/remark/createBy 等)由调用方填充 + */ + Boolean genReverseAuditAbnormal(InOrderAbnormal inOrderAbnormal); } diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/inOrderAbnormal/repository/persistence/InOrderAbnormalImpl.java b/mhd_wms/src/main/java/com/mhd/wms/domain/inOrderAbnormal/repository/persistence/InOrderAbnormalImpl.java index b0cda6088..e6d13bec3 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/inOrderAbnormal/repository/persistence/InOrderAbnormalImpl.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/inOrderAbnormal/repository/persistence/InOrderAbnormalImpl.java @@ -174,6 +174,25 @@ public class InOrderAbnormalImpl extends ServiceImpl inMaterialDetailPOList = materialDetailService.queryList(inMaterialDetailDO); - + // 先通过入库单号查询收货单列表 StockReceiptOrderDO stockReceiptOrderDO = new StockReceiptOrderDO(); stockReceiptOrderDO.setInOrderNumber(stockInOrderPO.getInOrderNumber()); + if (archive) { + stockReceiptOrderDO.setDelFlag(2); + } List stockReceiptOrderPOList = stockReceiptOrderDomainService.queryList(stockReceiptOrderDO); - + // 先通过入库单号查询上架单列表 StockShelfOrderDO stockShelfOrderDO = new StockShelfOrderDO(); stockShelfOrderDO.setInOrderNumber(stockInOrderPO.getInOrderNumber()); + if (archive) { + stockShelfOrderDO.setDelFlag(2); + } List stockShelfOrderPOList = stockShelfOrderDomainService.queryList(stockShelfOrderDO); - + // 查询收货单明细,用于填充收货数量和更新毛重、净重、面积、体积 List receiptMaterialDetailPOList = new ArrayList<>(); if (!CollectionUtils.isEmpty(stockReceiptOrderPOList)) { @@ -548,10 +595,13 @@ public class StockInOrderDomainService { if (!CollectionUtils.isEmpty(receiptOrderNumberList)) { ReceiptMaterialDetailDO receiptMaterialDetailDO = new ReceiptMaterialDetailDO(); receiptMaterialDetailDO.setReceiptOrderNumberList(receiptOrderNumberList); + if (archive) { + receiptMaterialDetailDO.setDelFlag(2); + } receiptMaterialDetailPOList = receiptMaterialDetailService.queryList(receiptMaterialDetailDO); } } - + // 查询上架单明细,用于填充上架数量 List shelfMaterialDetailPOList = new ArrayList<>(); if (!CollectionUtils.isEmpty(stockShelfOrderPOList)) { @@ -559,6 +609,9 @@ public class StockInOrderDomainService { if (StringUtils.isNotBlank(stockShelfOrderPO.getShelfOrderNumber())) { ShelfMaterialDetailDO shelfMaterialDetailDO = new ShelfMaterialDetailDO(); shelfMaterialDetailDO.setShelfOrderNumber(stockShelfOrderPO.getShelfOrderNumber()); + if (archive) { + shelfMaterialDetailDO.setDelFlag(2); + } List shelfDetails = shelfMaterialDetailService.queryList(shelfMaterialDetailDO); if (!CollectionUtils.isEmpty(shelfDetails)) { shelfMaterialDetailPOList.addAll(shelfDetails); @@ -844,6 +897,291 @@ public class StockInOrderDomainService { .eq(StockInOrder::getDelFlag, 1)); } + /** + * OMS入库业务单反审:WMS侧一个事务内把已完成单据回退到最原始状态(供 Feign /stockInOrderApi/omsReverseInOrder 调用)。 + * + *

与 {@link #cancelExecutionOrder(StockInOrder)}(取消下发,仅限未开始收货)不同,本方法处理 + * 已开始收货/上架/已入库(status>=3)的单据,回退动作与"完成收货/完成上架"链路对称:

+ *
    + *
  • 出库拦截:按"入库单号+动作(分配库存/出库)"查库存调整记录>0 即有出库记录;另校验库存冻结量 + * (入库单有出库就不能反审)
  • + *
  • 回退库存:按本单库存行整行扣回(上架时 inventory_quantity 与 allocation_quantity 同量增加、 + * 重量体积一并累加,此处对称扣回,复用统一扣减服务 GREATEST(x-n,0) 兜底); + * 扣减前校验"库存行合计=已上架完成量",不一致说明发生过库存合并/人工调整,拦截人工核实
  • + *
  • W入库单/W收货单/W上架单整链软删(del_flag=2)并打已反审标记(REVERSE_AUDIT_STATUS=1), + * 各页面【已反审】tab按"已软删+已反审"(del_flag=2 and reverse_audit_status=1)查询归档数据; + * 物料明细/作业单/任务/质检单一并软删留痕,台账节点物理删除保持与回退后库存一致
  • + *
  • 写1条入库异常【反审记录】(in_order_abnormal type=3/abnormalType=6) 用于记录跟踪
  • + *
+ *

WMS无该单数据时幂等返回成功(OMS未下发单反审不产生WMS数据);任何校验失败抛错经 + * Feign 返回,OMS侧整体回滚。反审可重试,本方法幂等。

+ */ + @Transactional(rollbackFor = Exception.class) + public void reverseExecutionOrder(StockInOrder stockInOrder) { + String inOrderNumber = stockInOrder.getInOrderNumber(); + if (StringUtils.isEmpty(inOrderNumber)) { + throw new ServiceException("反审失败:入库单号为空"); + } + //反审原因/反审人由OMS经Feign传入(不依赖Feign链路的登录上下文) + String reverseReason = stockInOrder.getRemark(); + String reverseByName = stockInOrder.getUpdateByName(); + + List stockInOrders = stockInOrderService.list(new LambdaQueryWrapper() + .eq(StockInOrder::getInOrderNumber, inOrderNumber) + .eq(StockInOrder::getDelFlag, 1)); + if (CollectionUtils.isEmpty(stockInOrders)) { + //幂等:WMS无该单数据(未下发单反审或已反审过),直接成功,保证OMS反审可重试 + return; + } + StockInOrder wmsOrder = stockInOrders.get(0); + + // ========== 1. 出库拦截:入库单有出库就不能反审 ========== + //按"入库单号+动作(分配库存/出库)"查询库存调整记录:出库分配/交接出库时都会写入调整记录, + //>0 即证明该入库单的库存已发生出库流转;取消分配时调整记录随之软删,不会误拦 + List outboundRecords = inventoryAdjustmentRecordService.list( + new LambdaQueryWrapper() + .eq(InventoryAdjustmentRecord::getInOrderNumber, inOrderNumber) + .in(InventoryAdjustmentRecord::getAdjustAction, "分配库存", "出库") + .eq(InventoryAdjustmentRecord::getDelFlag, 1)); + if (!CollectionUtils.isEmpty(outboundRecords)) { + throw new ServiceException("入库单[" + inOrderNumber + "]已产生出库记录,无法反审"); + } + //本单库存行(反审要扣回的库存) + List inventoryRows = materialInventoryService.list(new LambdaQueryWrapper() + .eq(MaterialInventory::getInOrderNumber, inOrderNumber)); + for (MaterialInventory row : inventoryRows) { + if (row.getFreezeQuantity() != null && row.getFreezeQuantity().compareTo(BigDecimal.ZERO) > 0) { + throw new ServiceException("入库单[" + inOrderNumber + "]库存已被出库分配,无法反审"); + } + } + + // ========== 2. 回退库存(对称"完成上架"写入) ========== + List shelfOrders = stockShelfOrderService.list(new LambdaQueryWrapper() + .eq(StockShelfOrder::getInOrderNumber, inOrderNumber) + .eq(StockShelfOrder::getDelFlag, 1)); + List shelfOrderNumbers = shelfOrders.stream() + .map(StockShelfOrder::getShelfOrderNumber) + .filter(StringUtils::isNotEmpty) + .distinct() + .collect(Collectors.toList()); + BigDecimal inventoryTotal = inventoryRows.stream() + .map(row -> row.getInventoryQuantity() == null ? BigDecimal.ZERO : row.getInventoryQuantity()) + .reduce(BigDecimal.ZERO, BigDecimal::add); + if (inventoryTotal.compareTo(BigDecimal.ZERO) > 0) { + //扣减前校验:库存行合计必须等于"已完成上架单"的上架量,否则整行扣回会误伤合并进来的其他来源库存。 + //只统计已完成(status=3)的上架单——库存只在完成上架时写入,上架中未完成的单不产生库存 + BigDecimal shelfDoneTotal = BigDecimal.ZERO; + List doneShelfOrderNumbers = shelfOrders.stream() + .filter(shelfOrder -> shelfOrder.getStatus() != null && shelfOrder.getStatus() == 3) + .map(StockShelfOrder::getShelfOrderNumber) + .filter(StringUtils::isNotEmpty) + .distinct() + .collect(Collectors.toList()); + if (!doneShelfOrderNumbers.isEmpty()) { + List shelfDetails = shelfMaterialDetailService.list(new LambdaQueryWrapper() + .in(ShelfMaterialDetail::getShelfOrderNumber, doneShelfOrderNumbers) + .eq(ShelfMaterialDetail::getDelFlag, 1)); + for (ShelfMaterialDetail shelfDetail : shelfDetails) { + BigDecimal shelved = shelfDetail.getAlreadyShelvesQuantity() != null + ? shelfDetail.getAlreadyShelvesQuantity() + : (shelfDetail.getShelvesQuantity() != null ? shelfDetail.getShelvesQuantity() : BigDecimal.ZERO); + shelfDoneTotal = shelfDoneTotal.add(shelved); + } + } + if (shelfDoneTotal.compareTo(BigDecimal.ZERO) <= 0 || inventoryTotal.compareTo(shelfDoneTotal) != 0) { + throw new ServiceException("入库单[" + inOrderNumber + "]库存(" + inventoryTotal.stripTrailingZeros().toPlainString() + + ")与上架完成量(" + shelfDoneTotal.stripTrailingZeros().toPlainString() + + ")不一致,可能已发生出库或库存合并,请人工核实后再反审"); + } + List subtractList = new ArrayList<>(); + for (MaterialInventory row : inventoryRows) { + if (row.getInventoryQuantity() == null || row.getInventoryQuantity().compareTo(BigDecimal.ZERO) <= 0) { + continue; + } + MaterialInventoryDO subtractDO = new MaterialInventoryDO(); + subtractDO.setMaterialInventoryId(row.getMaterialInventoryId()); + subtractDO.setInventoryQuantity(row.getInventoryQuantity()); + //SQL按 GREATEST(x-#{item.n},0) 扣减,DM/Oracle下 GREATEST 遇 null 返回 null,数值字段一律兜底0 + subtractDO.setNetWeight(row.getNetWeight() == null ? BigDecimal.ZERO : row.getNetWeight()); + subtractDO.setGrossWeight(row.getGrossWeight() == null ? BigDecimal.ZERO : row.getGrossWeight()); + subtractDO.setVolume(row.getVolume() == null ? BigDecimal.ZERO : row.getVolume()); + subtractDO.setArea(row.getArea() == null ? BigDecimal.ZERO : row.getArea()); + subtractList.add(subtractDO); + } + if (!CollectionUtils.isEmpty(subtractList)) { + //直接走统一批量扣减(GREATEST(x-n,0)兜底)并显式传更新人:不经 updateMaterialInventoryInfo, + //其内部 subtractMaterialInventory 取 SecurityUtils 登录上下文,OMS经Feign调用时可能无登录态(会抛异常) + MaterialInventoryParentDO subtractParent = new MaterialInventoryParentDO(); + subtractParent.setMaterialInventoryDOList(subtractList); + subtractParent.setUpdateBy(stockInOrder.getUpdateBy() == null ? 0L : stockInOrder.getUpdateBy()); + subtractParent.setUpdateByName(StringUtils.isEmpty(reverseByName) ? "system" : reverseByName); + subtractParent.setUpdateTime(new Date()); + materialInventoryService.batchSubtractInventoryQuantity(subtractParent); + } + } + + // ========== 3. 软删下游全链 + W入库单/W收货单/W上架单打"已反审"标记 ========== + //三单软删(del_flag=2)并打已反审标记(REVERSE_AUDIT_STATUS=1),各页面【已反审】tab按 + //"已软删+已反审"(del_flag=2 and reverse_audit_status=1)查询归档数据; + //物料明细/收货上架作业单/任务/质检单/台账一并软删留痕,重新下发时生成全新数据 + String reverseRemarkForWms = StringUtils.isEmpty(reverseReason) ? "入库单反审" : "入库单反审:" + reverseReason; + Long reverseAuditUserId = stockInOrder.getUpdateBy() == null ? 0L : stockInOrder.getUpdateBy(); + String reverseAuditUserName = StringUtils.isEmpty(reverseByName) ? "system" : reverseByName; + Date reverseAuditDate = new Date(); + //收货单(含历史重复下发产生的多张同号收货单,全部查出统一清理,避免按单号取一条漏删/报错) + List receiptOrders = stockReceiptOrderService.list(new LambdaQueryWrapper() + .eq(StockReceiptOrder::getInOrderNumber, inOrderNumber) + .eq(StockReceiptOrder::getDelFlag, 1)); + List receiptOrderNumbers = receiptOrders.stream() + .map(StockReceiptOrder::getReceiptOrderNumber) + .filter(StringUtils::isNotEmpty) + .distinct() + .collect(Collectors.toList()); + //收货/上架作业单(type=1收货 type=2上架;上架作业单兜底按上架单号再查一道防 in_order_number 为空) + //上架单复用第2节已查出的 shelfOrders/shelfOrderNumbers + List taskOrders = stockInTaskOrderService.list(new LambdaQueryWrapper() + .eq(StockInTaskOrder::getInOrderNumber, inOrderNumber) + .eq(StockInTaskOrder::getDelFlag, 1)); + if (!shelfOrderNumbers.isEmpty()) { + Set existTaskNumbers = taskOrders.stream() + .map(StockInTaskOrder::getTaskNumber) + .collect(Collectors.toSet()); + List shelfTaskOrders = stockInTaskOrderService.list(new LambdaQueryWrapper() + .in(StockInTaskOrder::getShelfOrderNumber, shelfOrderNumbers) + .eq(StockInTaskOrder::getDelFlag, 1)); + for (StockInTaskOrder shelfTaskOrder : shelfTaskOrders) { + if (shelfTaskOrder.getTaskNumber() != null && !existTaskNumbers.contains(shelfTaskOrder.getTaskNumber())) { + taskOrders.add(shelfTaskOrder); + } + } + } + List taskNumbers = taskOrders.stream() + .map(StockInTaskOrder::getTaskNumber) + .filter(StringUtils::isNotEmpty) + .distinct() + .collect(Collectors.toList()); + //1.收货/上架作业单明细 + if (!taskNumbers.isEmpty()) { + taskReceiptMaterialDetailService.update(new UpdateWrapper().lambda() + .set(TaskReceiptMaterialDetail::getDelFlag, 2) + .in(TaskReceiptMaterialDetail::getTaskNumber, taskNumbers) + .eq(TaskReceiptMaterialDetail::getDelFlag, 1)); + taskShelfMaterialDetailService.update(new UpdateWrapper().lambda() + .set(TaskShelfMaterialDetail::getDelFlag, 2) + .in(TaskShelfMaterialDetail::getTaskNumber, taskNumbers) + .eq(TaskShelfMaterialDetail::getDelFlag, 1)); + } + //2.收货/上架作业单 + if (!taskNumbers.isEmpty()) { + stockInTaskOrderService.update(new UpdateWrapper().lambda() + .set(StockInTaskOrder::getDelFlag, 2) + .eq(StockInTaskOrder::getInOrderNumber, inOrderNumber) + .eq(StockInTaskOrder::getDelFlag, 1)); + if (!shelfOrderNumbers.isEmpty()) { + stockInTaskOrderService.update(new UpdateWrapper().lambda() + .set(StockInTaskOrder::getDelFlag, 2) + .in(StockInTaskOrder::getShelfOrderNumber, shelfOrderNumbers) + .eq(StockInTaskOrder::getDelFlag, 1)); + } + } + //3.收货/上架任务(tracking_number=收货/上架单号;补"RV-"+入库单号兜底历史同号收货单) + if (!receiptOrderNumbers.isEmpty() || !shelfOrderNumbers.isEmpty()) { + Set trackingNumbers = new HashSet<>(receiptOrderNumbers); + trackingNumbers.addAll(shelfOrderNumbers); + trackingNumbers.add("RV-" + inOrderNumber); + deliveTaskService.update(new UpdateWrapper().lambda() + .set(DeliveTask::getDelFlag, 2) + .in(DeliveTask::getTrackingNumber, trackingNumbers) + .in(DeliveTask::getTaskType, 1, 2) + .eq(DeliveTask::getDelFlag, 1)); + } + //4.质检单 + qualityInspectionService.update(new UpdateWrapper().lambda() + .set(com.mhd.wms.domain.qualityInspection.entity.QualityInspection::getDelFlag, 2) + .eq(com.mhd.wms.domain.qualityInspection.entity.QualityInspection::getInOrderNumber, inOrderNumber) + .eq(com.mhd.wms.domain.qualityInspection.entity.QualityInspection::getDelFlag, 1)); + //5.收货单明细 + if (!receiptOrderNumbers.isEmpty()) { + receiptMaterialDetailService.update(new UpdateWrapper().lambda() + .set(ReceiptMaterialDetail::getDelFlag, 2) + .in(ReceiptMaterialDetail::getReceiptOrderNumber, receiptOrderNumbers) + .eq(ReceiptMaterialDetail::getDelFlag, 1)); + } + //6.收货单(软删+打已反审标记,收货单【已反审】tab 可查归档数据) + stockReceiptOrderService.update(new UpdateWrapper().lambda() + .set(StockReceiptOrder::getDelFlag, 2) + .set(StockReceiptOrder::getReverseAuditStatus, 1) + .set(StockReceiptOrder::getReverseAuditRemark, reverseRemarkForWms) + .set(StockReceiptOrder::getReverseAuditBy, reverseAuditUserId) + .set(StockReceiptOrder::getReverseAuditByName, reverseAuditUserName) + .set(StockReceiptOrder::getReverseAuditTime, reverseAuditDate) + .set(StockReceiptOrder::getUpdateBy, reverseAuditUserId) + .set(StockReceiptOrder::getUpdateByName, reverseAuditUserName) + .set(StockReceiptOrder::getUpdateTime, reverseAuditDate) + .eq(StockReceiptOrder::getInOrderNumber, inOrderNumber) + .eq(StockReceiptOrder::getDelFlag, 1)); + //7.上架单明细 + if (!shelfOrderNumbers.isEmpty()) { + shelfMaterialDetailService.update(new UpdateWrapper().lambda() + .set(ShelfMaterialDetail::getDelFlag, 2) + .in(ShelfMaterialDetail::getShelfOrderNumber, shelfOrderNumbers) + .eq(ShelfMaterialDetail::getDelFlag, 1)); + } + //8.上架单(软删+打已反审标记,上架单【已反审】tab 可查归档数据) + stockShelfOrderService.update(new UpdateWrapper().lambda() + .set(StockShelfOrder::getDelFlag, 2) + .set(StockShelfOrder::getReverseAuditStatus, 1) + .set(StockShelfOrder::getReverseAuditRemark, reverseRemarkForWms) + .set(StockShelfOrder::getReverseAuditBy, reverseAuditUserId) + .set(StockShelfOrder::getReverseAuditByName, reverseAuditUserName) + .set(StockShelfOrder::getReverseAuditTime, reverseAuditDate) + .set(StockShelfOrder::getUpdateBy, reverseAuditUserId) + .set(StockShelfOrder::getUpdateByName, reverseAuditUserName) + .set(StockShelfOrder::getUpdateTime, reverseAuditDate) + .eq(StockShelfOrder::getInOrderNumber, inOrderNumber) + .eq(StockShelfOrder::getDelFlag, 1)); + //9.收货/上架节点库存台账(trackingNumber=收货/上架单号;台账无逻辑删除标志,物理删除保持台账与回退后库存一致) + Set standingTrackingNumbers = new HashSet<>(receiptOrderNumbers); + standingTrackingNumbers.addAll(shelfOrderNumbers); + if (!standingTrackingNumbers.isEmpty()) { + inventoryStandingDetailService.remove(new LambdaQueryWrapper() + .in(InventoryStandingDetail::getTrackingNumber, standingTrackingNumbers) + .in(InventoryStandingDetail::getNodeStatus, 1, 2)); + } + //10.入库单明细 + materialDetailService.update(new UpdateWrapper().lambda() + .set(InMaterialDetail::getDelFlag, 2) + .eq(InMaterialDetail::getInOrderNumber, inOrderNumber) + .eq(InMaterialDetail::getDelFlag, 1)); + //11.入库单(软删+打已反审标记,入库单【已反审】tab 可查归档数据) + stockInOrderService.update(new UpdateWrapper().lambda() + .set(StockInOrder::getDelFlag, 2) + .set(StockInOrder::getReverseAuditStatus, 1) + .set(StockInOrder::getReverseAuditRemark, reverseRemarkForWms) + .set(StockInOrder::getReverseAuditBy, reverseAuditUserId) + .set(StockInOrder::getReverseAuditByName, reverseAuditUserName) + .set(StockInOrder::getReverseAuditTime, reverseAuditDate) + .set(StockInOrder::getUpdateBy, reverseAuditUserId) + .set(StockInOrder::getUpdateByName, reverseAuditUserName) + .set(StockInOrder::getUpdateTime, reverseAuditDate) + .eq(StockInOrder::getInOrderNumber, inOrderNumber) + .eq(StockInOrder::getDelFlag, 1)); + + // ========== 4. 写1条入库异常【反审记录】用于记录跟踪 ========== + InOrderAbnormal reverseAbnormal = new InOrderAbnormal(); + reverseAbnormal.setOrganizationId(wmsOrder.getOrganizationId()); + reverseAbnormal.setOrganizationName(wmsOrder.getOrganizationName()); + reverseAbnormal.setTopOrganizationId(wmsOrder.getTopOrganizationId()); + reverseAbnormal.setInOrderNumber(inOrderNumber); + reverseAbnormal.setAbnormalReason(StringUtils.isEmpty(reverseReason) ? "入库业务单反审" : "入库业务单反审:" + reverseReason); + reverseAbnormal.setQuantity(inventoryTotal); + reverseAbnormal.setRemark("入库业务单反审:回退库存" + inventoryTotal.stripTrailingZeros().toPlainString() + + ",清理收货/上架链路数据"); + reverseAbnormal.setCreateBy(stockInOrder.getUpdateBy() == null ? 0L : stockInOrder.getUpdateBy()); + reverseAbnormal.setCreateByName(StringUtils.isEmpty(reverseByName) ? "system" : reverseByName); + inOrderAbnormalService.genReverseAuditAbnormal(reverseAbnormal); + } + /** * OMS下发入库单明细保存后自动审核通过(生成收货单并更新审核状态) */ diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/entity/StockReceiptOrder.java b/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/entity/StockReceiptOrder.java index 9450425eb..256aadd92 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/entity/StockReceiptOrder.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/entity/StockReceiptOrder.java @@ -164,5 +164,22 @@ public class StockReceiptOrder extends BaseVOEntity { @Excel(name = "业务单号") private String batchNo; + @ApiModelProperty("反审状态: 0-无 1-已反审(已反审tab过滤)") + private Integer reverseAuditStatus; + + @ApiModelProperty("反审原因") + private String reverseAuditRemark; + + @ApiModelProperty("反审人id") + private Long reverseAuditBy; + + @ApiModelProperty("反审人姓名") + private String reverseAuditByName; + + @ApiModelProperty("反审时间") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date reverseAuditTime; + } \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/repository/po/StockReceiptOrderPO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/repository/po/StockReceiptOrderPO.java index c3a4730b7..c17b0b614 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/repository/po/StockReceiptOrderPO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/repository/po/StockReceiptOrderPO.java @@ -194,4 +194,21 @@ public class StockReceiptOrderPO extends StockInOrderBasePO { @ApiModelProperty("批次号") @Excel(name = "批次号") private String batchNo; + + @ApiModelProperty("反审状态: 0-无 1-已反审(已反审tab过滤)") + private Integer reverseAuditStatus; + + @ApiModelProperty("反审原因") + private String reverseAuditRemark; + + @ApiModelProperty("反审人id") + private Long reverseAuditBy; + + @ApiModelProperty("反审人姓名") + private String reverseAuditByName; + + @ApiModelProperty("反审时间") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date reverseAuditTime; } \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/repository/todo/StockReceiptOrderDO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/repository/todo/StockReceiptOrderDO.java index ed83f5dcf..ba1773edd 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/repository/todo/StockReceiptOrderDO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/repository/todo/StockReceiptOrderDO.java @@ -203,4 +203,21 @@ public class StockReceiptOrderDO extends StockInOrderBaseDO { @ApiModelProperty("是否需要报关") @Excel(name = "是否需要报关") private Integer needCustomsDeclaration; + + @ApiModelProperty("反审状态: 0-无 1-已反审(已反审tab过滤)") + private Integer reverseAuditStatus; + + @ApiModelProperty("反审原因") + private String reverseAuditRemark; + + @ApiModelProperty("反审人id") + private Long reverseAuditBy; + + @ApiModelProperty("反审人姓名") + private String reverseAuditByName; + + @ApiModelProperty("反审时间") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date reverseAuditTime; } \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/stockShelfOrder/entity/StockShelfOrder.java b/mhd_wms/src/main/java/com/mhd/wms/domain/stockShelfOrder/entity/StockShelfOrder.java index db1fd2b5f..439af484c 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/stockShelfOrder/entity/StockShelfOrder.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/stockShelfOrder/entity/StockShelfOrder.java @@ -118,4 +118,21 @@ public class StockShelfOrder extends BaseVOEntity { @Excel(name = "批次号") private String batchNo; + @ApiModelProperty("反审状态: 0-无 1-已反审(已反审tab过滤)") + private Integer reverseAuditStatus; + + @ApiModelProperty("反审原因") + private String reverseAuditRemark; + + @ApiModelProperty("反审人id") + private Long reverseAuditBy; + + @ApiModelProperty("反审人姓名") + private String reverseAuditByName; + + @ApiModelProperty("反审时间") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date reverseAuditTime; + } \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/stockShelfOrder/repository/po/StockShelfOrderPO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/stockShelfOrder/repository/po/StockShelfOrderPO.java index 4598df5fc..008a1d073 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/stockShelfOrder/repository/po/StockShelfOrderPO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/stockShelfOrder/repository/po/StockShelfOrderPO.java @@ -153,4 +153,21 @@ public class StockShelfOrderPO extends StockInOrderBasePO { @DateTimeFormat(pattern = "yyyy-MM-dd") @Excel(name = "完成时间", width = 30, dateFormat = "yyyy-MM-dd") private Date completionTime; + + @ApiModelProperty("反审状态: 0-无 1-已反审(已反审tab过滤)") + private Integer reverseAuditStatus; + + @ApiModelProperty("反审原因") + private String reverseAuditRemark; + + @ApiModelProperty("反审人id") + private Long reverseAuditBy; + + @ApiModelProperty("反审人姓名") + private String reverseAuditByName; + + @ApiModelProperty("反审时间") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date reverseAuditTime; } \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/stockShelfOrder/repository/todo/StockShelfOrderDO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/stockShelfOrder/repository/todo/StockShelfOrderDO.java index b4a947b3e..23c283f17 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/stockShelfOrder/repository/todo/StockShelfOrderDO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/stockShelfOrder/repository/todo/StockShelfOrderDO.java @@ -173,4 +173,21 @@ public class StockShelfOrderDO extends StockInOrderBaseDO { @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date createTimeTo; + + @ApiModelProperty("反审状态: 0-无 1-已反审(已反审tab过滤)") + private Integer reverseAuditStatus; + + @ApiModelProperty("反审原因") + private String reverseAuditRemark; + + @ApiModelProperty("反审人id") + private Long reverseAuditBy; + + @ApiModelProperty("反审人姓名") + private String reverseAuditByName; + + @ApiModelProperty("反审时间") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date reverseAuditTime; } \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockInOrder/StockInOrderDTO.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockInOrder/StockInOrderDTO.java index c1588f31d..cfd15b170 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockInOrder/StockInOrderDTO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockInOrder/StockInOrderDTO.java @@ -468,4 +468,7 @@ public class StockInOrderDTO extends StockInOrderBaseDTO { */ @ApiModelProperty("作业任务人员(模糊查询)") private String workUserNameLike; + + @ApiModelProperty("反审状态: 0-无 1-已反审(已反审tab过滤)") + private Integer reverseAuditStatus; } \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockReceiptOrder/StockReceiptOrderDTO.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockReceiptOrder/StockReceiptOrderDTO.java index 03e53fd5d..c2861c763 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockReceiptOrder/StockReceiptOrderDTO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockReceiptOrder/StockReceiptOrderDTO.java @@ -171,4 +171,7 @@ public class StockReceiptOrderDTO extends StockInOrderBaseDTO { @ApiModelProperty("业务单号") @Excel(name = "业务单号") private String batchNo; + + @ApiModelProperty("反审状态: 0-无 1-已反审(已反审tab过滤)") + private Integer reverseAuditStatus; } \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockShelfOrder/StockShelfOrderDTO.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockShelfOrder/StockShelfOrderDTO.java index 9f2cc0c2d..8e4009454 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockShelfOrder/StockShelfOrderDTO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockShelfOrder/StockShelfOrderDTO.java @@ -162,4 +162,7 @@ public class StockShelfOrderDTO extends StockInOrderBaseDTO { @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private Date createTimeTo; + + @ApiModelProperty("反审状态: 0-无 1-已反审(已反审tab过滤)") + private Integer reverseAuditStatus; } \ No newline at end of file diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/stockInOrder/StockInOrderApi.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/stockInOrder/StockInOrderApi.java index 860c279dd..7ff3edcb7 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/stockInOrder/StockInOrderApi.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/stockInOrder/StockInOrderApi.java @@ -147,6 +147,16 @@ public class StockInOrderApi extends BaseController { return AjaxResult.success(stockInOrderApplicationService.getInfo(inOrderId)); } + /** + * 查询入库单【已反审】tab 归档详情(已软删+已反审标记的数据,含软删明细/收货单/上架单) + */ + @ApiOperation("查询入库单已反审归档详情") + @GetMapping(value = "/getReverseAuditInfo/{inOrderId}") + public AjaxResult getReverseAuditInfo(@PathVariable("inOrderId") Long inOrderId) + { + return AjaxResult.success(stockInOrderApplicationService.getReverseAuditInfo(inOrderId)); + } + /** * 导入入库单 */ @@ -329,6 +339,17 @@ public class StockInOrderApi extends BaseController { return AjaxResult.success(); } + /** + * oms入库业务单反审:WMS侧回退已完成单据(出库拦截 -> 回退库存 -> + * 逻辑删除收货/上架链路 -> 写入库异常【反审记录】),已产生出库则报错拦截 + */ + @ApiOperation("oms入库单反审WMS回退") + @PostMapping(value = "/omsReverseInOrder") + public AjaxResult omsReverseInOrder(@RequestBody StockInOrder stockInOrder) { + stockInOrderApplicationService.omsReverseInOrder(stockInOrder); + return AjaxResult.success(); + } + @ApiOperation("查询入库信息(通过入库单号)") @PostMapping("/queryInStockInfo") public AjaxResult queryInStockInfo(@RequestBody StockInOrderDTO stockInOrderDTO) { diff --git a/mhd_wms/src/main/resources/mapper/stockInOrder/StockInOrderMapper.xml b/mhd_wms/src/main/resources/mapper/stockInOrder/StockInOrderMapper.xml index 5ff496b02..888ac6bb3 100644 --- a/mhd_wms/src/main/resources/mapper/stockInOrder/StockInOrderMapper.xml +++ b/mhd_wms/src/main/resources/mapper/stockInOrder/StockInOrderMapper.xml @@ -110,6 +110,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + + + + @@ -144,7 +149,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" a.CUSTOMS_BROKER_INFO, a.DELIVERY_ADDRESS, a.ENTRY_EXIT_CUSTOMS, a.ORIGIN_DESTINATION_COUNTRY, a.CARRIER, a.CONTAINER_NO, a.TRANSPORT_METHOD, a.SUPERVISION_METHOD, a.CUSTOMS_INSPECTION, a.NEED_CUSTOMS_DECLARATION, a.NEED_TRANSPORT, a.WAREHOUSE_DATE, a.COMPLETION_TIME, a.ORDER_DATE,a.stock_in_order,a.business_order_no,a.WORK_USER_ID,a.WORK_TASK_RECEIVE_STATUS,a.TASK_ISSUE_USER_ID,a.WORK_USER_NAME, - a.SIGNATURE_STATUS, a.SIGNATURE_TIME, a.SIGNATURE_PIC, a.EVIDENCE_PICS, a.SIGNATURE_REMARK + a.SIGNATURE_STATUS, a.SIGNATURE_TIME, a.SIGNATURE_PIC, a.EVIDENCE_PICS, a.SIGNATURE_REMARK, + a.REVERSE_AUDIT_STATUS, a.REVERSE_AUDIT_REMARK, a.REVERSE_AUDIT_BY, a.REVERSE_AUDIT_BY_NAME, a.REVERSE_AUDIT_TIME @@ -483,9 +489,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
) + + + and a.REVERSE_AUDIT_STATUS = #{reverseAuditStatus} + - and a.del_flag = #{delFlag} - and a.del_flag = 1 + + and a.del_flag = 2 + + + + and a.del_flag = #{delFlag} + and a.del_flag = 1 + +
diff --git a/mhd_wms/src/main/resources/mapper/stockReceiptOrder/StockReceiptOrderMapper.xml b/mhd_wms/src/main/resources/mapper/stockReceiptOrder/StockReceiptOrderMapper.xml index 9509d5da5..3987b65d0 100644 --- a/mhd_wms/src/main/resources/mapper/stockReceiptOrder/StockReceiptOrderMapper.xml +++ b/mhd_wms/src/main/resources/mapper/stockReceiptOrder/StockReceiptOrderMapper.xml @@ -45,6 +45,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + + + + @@ -54,7 +59,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" a.status, a.platform_id, a.platform_code, a.platform_name, a.platform_use_time_id, a.platform_use_start_time, a.platform_use_end_time, a.platform_use_status, a.quantity, a.receipt_quantity, a.receipt_material_quantity, a.material_quantity, a.abnormal, a.task_distribution, a.task_distribution_time, a.operators_by, a.operators_name, a.remark, a.create_time, a.create_by, a.create_by_name, - a.update_time, a.update_by, a.update_by_name, a.del_flag, a.billing_json,a.business_order_no,a.batch_no + a.update_time, a.update_by, a.update_by_name, a.del_flag, a.billing_json,a.business_order_no,a.batch_no, + a.REVERSE_AUDIT_STATUS, a.REVERSE_AUDIT_REMARK, a.REVERSE_AUDIT_BY, a.REVERSE_AUDIT_BY_NAME, a.REVERSE_AUDIT_TIME @@ -140,9 +146,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and date_format(a.create_time,'%Y-%m-%d') <= #{createTimeEnd} + - and a.del_flag = #{delFlag} - and a.del_flag = 1 + + and a.REVERSE_AUDIT_STATUS = #{reverseAuditStatus} + and a.del_flag = 2 + + + + and a.del_flag = #{delFlag} + and a.del_flag = 1 + + diff --git a/mhd_wms/src/main/resources/mapper/stockShelfOrder/StockShelfOrderMapper.xml b/mhd_wms/src/main/resources/mapper/stockShelfOrder/StockShelfOrderMapper.xml index c28664856..00f904ba3 100644 --- a/mhd_wms/src/main/resources/mapper/stockShelfOrder/StockShelfOrderMapper.xml +++ b/mhd_wms/src/main/resources/mapper/stockShelfOrder/StockShelfOrderMapper.xml @@ -31,6 +31,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + + + + @@ -40,6 +45,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" a.shelves_material_quantity, a.abnormal,a.task_distribution, a.task_distribution_time, a.operators_by, a.remark, a.create_time, a.create_by, a.create_by_name, a.update_time, a.update_by, a.update_by_name, a.del_flag ,a.push_status,a.push_time,a.push_by,a.push_by_name, + a.REVERSE_AUDIT_STATUS, a.REVERSE_AUDIT_REMARK, a.REVERSE_AUDIT_BY, a.REVERSE_AUDIT_BY_NAME, a.REVERSE_AUDIT_TIME, (SELECT m.goods_type FROM shelf_material_detail d JOIN material_base_info m ON d.material_base_info_id = m.material_base_info_id WHERE d.shelf_order_number = a.shelf_order_number AND d.level = 1 @@ -125,9 +131,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and a.PUSH_STATUS = #{pushStatus} + - and a.del_flag = #{delFlag} - and a.del_flag = 1 + + and a.REVERSE_AUDIT_STATUS = #{reverseAuditStatus} + and a.del_flag = 2 + + + + and a.del_flag = #{delFlag} + and a.del_flag = 1 + + diff --git a/sql/20260908_oms_inbound_reverse_audit.sql b/sql/20260908_oms_inbound_reverse_audit.sql new file mode 100644 index 000000000..27d04a73e --- /dev/null +++ b/sql/20260908_oms_inbound_reverse_audit.sql @@ -0,0 +1,93 @@ +-- ============================================================================= +-- OMS 入库业务单「反审」功能 —— 反审标记字段(业务单/执行单/WMS三单) +-- 日期: 2026-09-08 版本: v3 +-- 数据库: 达梦(DM8), 兼容 Oracle 语法, 表名/字段名统一大写 +-- 模式: NGWL_TEST_OMS (mhd_oms) / NGWL_TEST_WMS (mhd_wms) +-- 需求: +-- 入库单「反审」: 已入库/已出库的单子客户通知需要回退的场景, 单子回退到最原始状态。 +-- 反审入口在 OMS-入库业务单页面, 点击【反審單據】后: +-- 1. 入库业务单状态改为"已驳回"(issueStatus=3) + 已反审标记, 落【已反审】tab, +-- 可编辑→重新审核→重新下发 +-- 2. 入库执行单 改为"已反审"(状态回退已创建+已反审标记), 物料明细保留 +-- 3. W入库单/W收货单/W上架单 状态回退到"已创建"+已反审标记, +-- 数据划归到各自页面【已反审】tab页签, 可继续点击「编辑」or「审核」or「撤销」 +-- 4. W库存还原扣减(按入库单号定位库存行整行扣回) +-- 5. 生成1条W入库异常【反审记录】(in_order_abnormal type=3)用于记录跟踪 +-- 拦截: W入库单有出库记录就不能反审——按入库单号+动作("分配库存"/"出库") +-- 查询库存调整记录(inventory_adjustment_record)>0 即有出库; +-- 已推送关务(pushStatus=3)拦截。 +-- ============================================================================= + +-- 执行前检查(确认列不存在, 避免重复执行报错; DM 数据字典标识符按大写存储) +-- SELECT OWNER, TABLE_NAME, COLUMN_NAME FROM ALL_TAB_COLUMNS +-- WHERE COLUMN_NAME = 'REVERSE_AUDIT_STATUS' +-- AND TABLE_NAME IN ('RESERVATION_STOCK_IN_ORDER','EXECUTION_STOCK_IN_ORDER', +-- 'STOCK_IN_ORDER','STOCK_RECEIPT_ORDER','STOCK_SHELF_ORDER'); + +-- ============ 一、OMS 业务单 RESERVATION_STOCK_IN_ORDER ============ +ALTER TABLE "NGWL_TEST_OMS"."RESERVATION_STOCK_IN_ORDER" ADD COLUMN REVERSE_AUDIT_STATUS NUMBER(1) DEFAULT 0; +COMMENT ON COLUMN "NGWL_TEST_OMS"."RESERVATION_STOCK_IN_ORDER".REVERSE_AUDIT_STATUS IS '反审状态: 0-无 1-已反审'; +ALTER TABLE "NGWL_TEST_OMS"."RESERVATION_STOCK_IN_ORDER" ADD COLUMN REVERSE_AUDIT_REMARK VARCHAR2(500); +COMMENT ON COLUMN "NGWL_TEST_OMS"."RESERVATION_STOCK_IN_ORDER".REVERSE_AUDIT_REMARK IS '反审原因'; +ALTER TABLE "NGWL_TEST_OMS"."RESERVATION_STOCK_IN_ORDER" ADD COLUMN REVERSE_AUDIT_BY NUMBER(20); +COMMENT ON COLUMN "NGWL_TEST_OMS"."RESERVATION_STOCK_IN_ORDER".REVERSE_AUDIT_BY IS '反审人id'; +ALTER TABLE "NGWL_TEST_OMS"."RESERVATION_STOCK_IN_ORDER" ADD COLUMN REVERSE_AUDIT_BY_NAME VARCHAR2(64); +COMMENT ON COLUMN "NGWL_TEST_OMS"."RESERVATION_STOCK_IN_ORDER".REVERSE_AUDIT_BY_NAME IS '反审人姓名'; +ALTER TABLE "NGWL_TEST_OMS"."RESERVATION_STOCK_IN_ORDER" ADD COLUMN REVERSE_AUDIT_TIME DATE; +COMMENT ON COLUMN "NGWL_TEST_OMS"."RESERVATION_STOCK_IN_ORDER".REVERSE_AUDIT_TIME IS '反审时间'; + +-- ============ 二、OMS 执行单 EXECUTION_STOCK_IN_ORDER ============ +ALTER TABLE "NGWL_TEST_OMS"."EXECUTION_STOCK_IN_ORDER" ADD COLUMN REVERSE_AUDIT_STATUS NUMBER(1) DEFAULT 0; +COMMENT ON COLUMN "NGWL_TEST_OMS"."EXECUTION_STOCK_IN_ORDER".REVERSE_AUDIT_STATUS IS '反审状态: 0-无 1-已反审'; +ALTER TABLE "NGWL_TEST_OMS"."EXECUTION_STOCK_IN_ORDER" ADD COLUMN REVERSE_AUDIT_REMARK VARCHAR2(500); +COMMENT ON COLUMN "NGWL_TEST_OMS"."EXECUTION_STOCK_IN_ORDER".REVERSE_AUDIT_REMARK IS '反审原因'; +ALTER TABLE "NGWL_TEST_OMS"."EXECUTION_STOCK_IN_ORDER" ADD COLUMN REVERSE_AUDIT_BY NUMBER(20); +COMMENT ON COLUMN "NGWL_TEST_OMS"."EXECUTION_STOCK_IN_ORDER".REVERSE_AUDIT_BY IS '反审人id'; +ALTER TABLE "NGWL_TEST_OMS"."EXECUTION_STOCK_IN_ORDER" ADD COLUMN REVERSE_AUDIT_BY_NAME VARCHAR2(64); +COMMENT ON COLUMN "NGWL_TEST_OMS"."EXECUTION_STOCK_IN_ORDER".REVERSE_AUDIT_BY_NAME IS '反审人姓名'; +ALTER TABLE "NGWL_TEST_OMS"."EXECUTION_STOCK_IN_ORDER" ADD COLUMN REVERSE_AUDIT_TIME DATE; +COMMENT ON COLUMN "NGWL_TEST_OMS"."EXECUTION_STOCK_IN_ORDER".REVERSE_AUDIT_TIME IS '反审时间'; + +-- ============ 三、WMS 入库单 STOCK_IN_ORDER ============ +ALTER TABLE "NGWL_TEST_WMS"."STOCK_IN_ORDER" ADD COLUMN REVERSE_AUDIT_STATUS NUMBER(1) DEFAULT 0; +COMMENT ON COLUMN "NGWL_TEST_WMS"."STOCK_IN_ORDER".REVERSE_AUDIT_STATUS IS '反审状态: 0-无 1-已反审(已反审tab过滤)'; +ALTER TABLE "NGWL_TEST_WMS"."STOCK_IN_ORDER" ADD COLUMN REVERSE_AUDIT_REMARK VARCHAR2(500); +COMMENT ON COLUMN "NGWL_TEST_WMS"."STOCK_IN_ORDER".REVERSE_AUDIT_REMARK IS '反审原因'; +ALTER TABLE "NGWL_TEST_WMS"."STOCK_IN_ORDER" ADD COLUMN REVERSE_AUDIT_BY NUMBER(20); +COMMENT ON COLUMN "NGWL_TEST_WMS"."STOCK_IN_ORDER".REVERSE_AUDIT_BY IS '反审人id'; +ALTER TABLE "NGWL_TEST_WMS"."STOCK_IN_ORDER" ADD COLUMN REVERSE_AUDIT_BY_NAME VARCHAR2(64); +COMMENT ON COLUMN "NGWL_TEST_WMS"."STOCK_IN_ORDER".REVERSE_AUDIT_BY_NAME IS '反审人姓名'; +ALTER TABLE "NGWL_TEST_WMS"."STOCK_IN_ORDER" ADD COLUMN REVERSE_AUDIT_TIME DATE; +COMMENT ON COLUMN "NGWL_TEST_WMS"."STOCK_IN_ORDER".REVERSE_AUDIT_TIME IS '反审时间'; + +-- ============ 四、WMS 收货单 STOCK_RECEIPT_ORDER ============ +ALTER TABLE "NGWL_TEST_WMS"."STOCK_RECEIPT_ORDER" ADD COLUMN REVERSE_AUDIT_STATUS NUMBER(1) DEFAULT 0; +COMMENT ON COLUMN "NGWL_TEST_WMS"."STOCK_RECEIPT_ORDER".REVERSE_AUDIT_STATUS IS '反审状态: 0-无 1-已反审(已反审tab过滤)'; +ALTER TABLE "NGWL_TEST_WMS"."STOCK_RECEIPT_ORDER" ADD COLUMN REVERSE_AUDIT_REMARK VARCHAR2(500); +COMMENT ON COLUMN "NGWL_TEST_WMS"."STOCK_RECEIPT_ORDER".REVERSE_AUDIT_REMARK IS '反审原因'; +ALTER TABLE "NGWL_TEST_WMS"."STOCK_RECEIPT_ORDER" ADD COLUMN REVERSE_AUDIT_BY NUMBER(20); +COMMENT ON COLUMN "NGWL_TEST_WMS"."STOCK_RECEIPT_ORDER".REVERSE_AUDIT_BY IS '反审人id'; +ALTER TABLE "NGWL_TEST_WMS"."STOCK_RECEIPT_ORDER" ADD COLUMN REVERSE_AUDIT_BY_NAME VARCHAR2(64); +COMMENT ON COLUMN "NGWL_TEST_WMS"."STOCK_RECEIPT_ORDER".REVERSE_AUDIT_BY_NAME IS '反审人姓名'; +ALTER TABLE "NGWL_TEST_WMS"."STOCK_RECEIPT_ORDER" ADD COLUMN REVERSE_AUDIT_TIME DATE; +COMMENT ON COLUMN "NGWL_TEST_WMS"."STOCK_RECEIPT_ORDER".REVERSE_AUDIT_TIME IS '反审时间'; + +-- ============ 五、WMS 上架单 STOCK_SHELF_ORDER ============ +ALTER TABLE "NGWL_TEST_WMS"."STOCK_SHELF_ORDER" ADD COLUMN REVERSE_AUDIT_STATUS NUMBER(1) DEFAULT 0; +COMMENT ON COLUMN "NGWL_TEST_WMS"."STOCK_SHELF_ORDER".REVERSE_AUDIT_STATUS IS '反审状态: 0-无 1-已反审(已反审tab过滤)'; +ALTER TABLE "NGWL_TEST_WMS"."STOCK_SHELF_ORDER" ADD COLUMN REVERSE_AUDIT_REMARK VARCHAR2(500); +COMMENT ON COLUMN "NGWL_TEST_WMS"."STOCK_SHELF_ORDER".REVERSE_AUDIT_REMARK IS '反审原因'; +ALTER TABLE "NGWL_TEST_WMS"."STOCK_SHELF_ORDER" ADD COLUMN REVERSE_AUDIT_BY NUMBER(20); +COMMENT ON COLUMN "NGWL_TEST_WMS"."STOCK_SHELF_ORDER".REVERSE_AUDIT_BY IS '反审人id'; +ALTER TABLE "NGWL_TEST_WMS"."STOCK_SHELF_ORDER" ADD COLUMN REVERSE_AUDIT_BY_NAME VARCHAR2(64); +COMMENT ON COLUMN "NGWL_TEST_WMS"."STOCK_SHELF_ORDER".REVERSE_AUDIT_BY_NAME IS '反审人姓名'; +ALTER TABLE "NGWL_TEST_WMS"."STOCK_SHELF_ORDER" ADD COLUMN REVERSE_AUDIT_TIME DATE; +COMMENT ON COLUMN "NGWL_TEST_WMS"."STOCK_SHELF_ORDER".REVERSE_AUDIT_TIME IS '反审时间'; + +-- 存量数据无需回填: 历史单据 REVERSE_AUDIT_STATUS 默认 0(无), 只影响新反审操作。 + +-- ============================================================================= +-- 回滚(发布前执行了需回退时, 按表名对应 DROP 上述列即可) +-- 发布顺序: 先执行本 DDL 再发布服务(实体带新字段而表无列, MyBatis-Plus 查询/更新会报错); +-- mhd_wms 与 mhd_oms 同时发布。 +-- =============================================================================