diff --git a/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/WlhyServiceFeign.java b/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/WlhyServiceFeign.java index 60d6085d6..da908ddf6 100644 --- a/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/WlhyServiceFeign.java +++ b/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/WlhyServiceFeign.java @@ -540,6 +540,13 @@ public interface WlhyServiceFeign { @GetMapping("/feign/order/cancelIssueDocuments") public AjaxResult cancelIssueDocuments(@RequestParam(name="executeOrderId") String executeOrderId); + /** + * OMS出库业务单反审联动: 按执行单货源编号软删TMS整条链路(货源单->运单->运输作业单, is_delete=1), 幂等, + * 与 cancelIssueDocuments(仅关闭货源单且有有效运单即拒绝)不同, 反审口径不留TMS数据 + */ + @PostMapping("/feign/order/deleteChainByExecuteOrderNumber") + public AjaxResult deleteChainByExecuteOrderNumber(@RequestParam(name="executeOrderNumber") String executeOrderNumber); + @GetMapping(value = "/ntocc/tmsSettlementExchangeRate/queryList") public AjaxResult queryList(@RequestParam(name="pageNo", defaultValue="1") Integer pageNo, @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, diff --git a/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/WmsServiceFeign.java b/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/WmsServiceFeign.java index ced3b78d7..04540b78f 100644 --- a/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/WmsServiceFeign.java +++ b/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/WmsServiceFeign.java @@ -75,21 +75,21 @@ public interface WmsServiceFeign { */ @ApiOperation("oms下发单保存") @PostMapping(value = "/stockOutOrderApi/omsOutOrderAdd") - public void omsOutOrderAdd(@RequestBody StockOutOrder stockOutOrder); + public AjaxResult omsOutOrderAdd(@RequestBody StockOutOrder stockOutOrder); /** * oms下发单明细保存 */ @ApiOperation("oms下发单明细保存") @PostMapping(value = "/stockOutOrderApi/omsOutOrderAddDetail") - public void omsOutOrderAddDetail(@RequestBody List outMaterialDetails); + public AjaxResult omsOutOrderAddDetail(@RequestBody List outMaterialDetails); /** * oms下发单明细保存 */ @ApiOperation("oms下发单明细保存") @PostMapping(value = "/stockOutOrderApi/omsOutOrderAddDeliveryDetailsLink") - public void omsOutOrderAddDeliveryDetailsLink(@RequestBody List deliveryDetailsLinks); + public AjaxResult omsOutOrderAddDeliveryDetailsLink(@RequestBody List deliveryDetailsLinks); /** @@ -134,6 +134,27 @@ public interface WmsServiceFeign { @PostMapping(value = "/stockInOrderApi/omsCancelInOrder") public AjaxResult omsCancelInOrder(@RequestBody StockInOrder stockInOrder); + /** + * oms出库执行单反审(已出库/已复核单据客户通知回退场景):WMS侧还原实物库存并推送OMS库存、 + * 逻辑删除出库链路单据、生成1条出库异常【反审记录】;反审原因经 remark 透传。 + * 已产生下游不可逆数据时返回错误,OMS据此整体回滚。 + */ + @ApiOperation("oms出库执行单反审WMS回退") + @PostMapping(value = "/stockOutOrderApi/omsReverseExecutionOrder") + public AjaxResult omsReverseExecutionOrder(@RequestBody StockOutOrder stockOutOrder); + + /** + * oms入库业务单反审:WMS侧一个事务内回退已入库/收货中/上架中单据—— + * 校验未产生出库(按入库单号+动作"分配库存/出库"查库存调整记录>0即有出库) -> + * 按库存行整行回退库存扣减 -> 软删W入库单/W收货单/W上架单全链并打已反审标记 + * (各页面【已反审】tab按"已软删+已反审"查询归档数据)-> 写1条入库异常【反审记录】(type=3)。 + * 入参: inOrderNumber=执行入库单号, remark=业务单号+反审原因, updateBy/updateByName=反审人; + * WMS无该单数据时幂等返回成功(未下发单反审不产生WMS数据)。 + */ + @ApiOperation("oms入库单反审WMS回退") + @PostMapping(value = "/stockInOrderApi/omsReverseInOrder") + public AjaxResult omsReverseInOrder(@RequestBody StockInOrder stockInOrder); + @ApiOperation("oms查询物料列表") @GetMapping("/materialBaseInfoApi/queryList") public TableDataInfo getMaterialBaseInfoList(MaterialInfoDTO materialInfoDTO); diff --git a/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/factory/RemoteWlhyFallbackFactory.java b/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/factory/RemoteWlhyFallbackFactory.java index 489e8e221..7b401a6ad 100644 --- a/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/factory/RemoteWlhyFallbackFactory.java +++ b/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/factory/RemoteWlhyFallbackFactory.java @@ -551,6 +551,12 @@ public class RemoteWlhyFallbackFactory implements FallbackFactory queryList(Integer pageNo, Integer pageSize, String pushStatus, String organizationId) { return AjaxResult.error(cause.getMessage()); diff --git a/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/factory/RemoteWmsFallbackFactory.java b/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/factory/RemoteWmsFallbackFactory.java index daddb00ab..f5ea93014 100644 --- a/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/factory/RemoteWmsFallbackFactory.java +++ b/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/factory/RemoteWmsFallbackFactory.java @@ -57,16 +57,19 @@ public class RemoteWmsFallbackFactory implements FallbackFactory outMaterialDetails) { + public AjaxResult omsOutOrderAddDetail(List outMaterialDetails) { + return AjaxResult.error("WMS下发单明细保存失败(服务降级):" + cause.getMessage()); } @Override - public void omsOutOrderAddDeliveryDetailsLink(List deliveryDetailsLinks) { - + public AjaxResult omsOutOrderAddDeliveryDetailsLink(List deliveryDetailsLinks) { + return AjaxResult.error("WMS下发单配送明细保存失败(服务降级):" + cause.getMessage()); } @Override @@ -82,6 +85,12 @@ public class RemoteWmsFallbackFactory implements FallbackFactory selectGoodsNumbersByPrefix(@Param("prefix") String prefix); } diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/businessDocumentOrder/repository/persistence/BusinessDocumentOrderImpl.java b/mhd_oms/src/main/java/com/mhd/oms/domain/businessDocumentOrder/repository/persistence/BusinessDocumentOrderImpl.java index 4b5f43efa..1ab5894ba 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/businessDocumentOrder/repository/persistence/BusinessDocumentOrderImpl.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/businessDocumentOrder/repository/persistence/BusinessDocumentOrderImpl.java @@ -237,11 +237,8 @@ public class BusinessDocumentOrderImpl extends ServiceImpl() - .eq(ReservationStockOutOrder::getOutOrderNumber, tmsOrder.getInOrderNumber()) - .eq(ReservationStockOutOrder::getDelFlag, 1)); - if (reservationStockOutOrder != null){ - reservationStockOutOrder.setBusinessNumber(tmsOrder.getGoodsNumber()); - reservationStockOutOrderMapper.updateById(reservationStockOutOrder); - } - ReservationStockInOrder reservationStockInOrder = reservationStockInOrderMapper.selectOne(new LambdaQueryWrapper() - .eq(ReservationStockInOrder::getInOrderNumber, tmsOrder.getInOrderNumber()) - .eq(ReservationStockInOrder::getDelFlag, 1)); - if (reservationStockInOrder != null){ - reservationStockInOrder.setBusinessNumber(tmsOrder.getGoodsNumber()); - reservationStockInOrderMapper.updateById(reservationStockInOrder); - } + //生成货源单号并落库见下方 insertWithUniqueGoodsNumber: + //取号与插单合并为原子重试(撞goods_number唯一索引自动重新取号), + //出库/入库业务单的单号回填也移至插单成功之后,避免插单失败留下脏回填 List loadingAddressList = businessDocumentOrderDO.getLoadingAddressList();//装货地信息集合 List unloadAddressList = businessDocumentOrderDO.getUnloadAddressList();//卸货地信息集合 @@ -426,7 +411,24 @@ public class BusinessDocumentOrderDomainService { //一天后 tmsOrder.setDocumentDate(businessDocumentOrderDO.getDocumentDate()); - boolean istrue = businessDocumentOrderMapper.insert(tmsOrder) > 0; + //生成货源单号(yyMMdd + 当日顺序号,每日重置)并落库, 撞唯一索引自动重新取号重试 + boolean istrue = goodsNumberGenerator.insertWithUniqueGoodsNumber(tmsOrder); + + //落库成功后将运输业务单号回填至关联的出库/入库业务单 + ReservationStockOutOrder reservationStockOutOrder = reservationStockOutOrderMapper.selectOne(new LambdaQueryWrapper() + .eq(ReservationStockOutOrder::getOutOrderNumber, tmsOrder.getInOrderNumber()) + .eq(ReservationStockOutOrder::getDelFlag, 1)); + if (reservationStockOutOrder != null){ + reservationStockOutOrder.setBusinessNumber(tmsOrder.getGoodsNumber()); + reservationStockOutOrderMapper.updateById(reservationStockOutOrder); + } + ReservationStockInOrder reservationStockInOrder = reservationStockInOrderMapper.selectOne(new LambdaQueryWrapper() + .eq(ReservationStockInOrder::getInOrderNumber, tmsOrder.getInOrderNumber()) + .eq(ReservationStockInOrder::getDelFlag, 1)); + if (reservationStockInOrder != null){ + reservationStockInOrder.setBusinessNumber(tmsOrder.getGoodsNumber()); + reservationStockInOrderMapper.updateById(reservationStockInOrder); + } if (hasDetails) { for (BusinessDeliveryDetailsLinkDTO businessDeliveryDetailsLinkDTO : businessDeliveryDetailsLinkDTOList) { diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/businessDocumentOrder/service/GoodsNumberGenerator.java b/mhd_oms/src/main/java/com/mhd/oms/domain/businessDocumentOrder/service/GoodsNumberGenerator.java index 285c8a89f..c78b58bbd 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/businessDocumentOrder/service/GoodsNumberGenerator.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/businessDocumentOrder/service/GoodsNumberGenerator.java @@ -5,23 +5,44 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.mhd.common.core.exception.ServiceException; import com.mhd.oms.domain.businessDocumentOrder.entity.BusinessDocumentOrder; import com.mhd.oms.domain.businessDocumentOrder.repository.mapper.BusinessDocumentOrderMapper; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DuplicateKeyException; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import java.util.Date; import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; /** * 业务单据订单(goodsNumber)单号生成器 * 规则: yyMMdd(取自单据日期) + 当日顺序号(每日重置, 3位起步, 超999自动扩位) * 示例: 260804001、260804999、2608041000 + * + * 唯一性保障(不依赖唯一索引, 三层防线): + * 1) 取号: 当日已生成单号 MAX+1 作为基线 + 候选号存在性校验后移收敛 + * (对齐入库单号修复先例 ReservationStockInOrderDomainService#generateReserveOrderNumber) + * 2) 落库: 按日期前缀分段的JVM锁串行化"取号+插单", 消除本实例内并发审核/ + * 批量取号的check-then-act竞态(多实例部署时本层只覆盖各自实例) + * 3) 自检自愈: 插单后立即校验同号数量, >1 说明与并发插入撞号, 给本单重新 + * 取号改号, 兜住跨实例残余竞态 + * 若日后补建goods_number唯一索引(见 sql/20260906_oms_business_goods_number_unique.sql), + * 撞号将抛DuplicateKeyException由重试逻辑接住, 与上述防线叠加互不冲突 */ +@Slf4j @Component public class GoodsNumberGenerator { private static final int MAX_RETRY = 100; + /** + * 取号+插单分段锁: 按单号日期前缀(yyMMdd)分段, 同日串行、跨日并行, + * 锁对象常驻(每日新增1个, 增量可忽略) + */ + private static final Map LOCK_STRIPES = new ConcurrentHashMap<>(); + @Autowired private BusinessDocumentOrderMapper businessDocumentOrderMapper; @@ -33,8 +54,21 @@ public class GoodsNumberGenerator { Date date = (documentDate == null) ? new Date() : documentDate; String datePart = DateUtil.format(date, "yyMMdd"); - // count 只查一次作为序号基线 - long seq = (long) businessDocumentOrderMapper.countByGoodsNumberPrefix(datePart) + 1; + // 当日已生成单号的最大序号作为基线(MAX+1而非COUNT+1, 防脏数据/序号错位导致回退复用) + List existNumbers = businessDocumentOrderMapper.selectGoodsNumbersByPrefix(datePart); + long seq = 0; + for (String existNumber : existNumbers) { + if (existNumber == null || existNumber.length() <= datePart.length()) { + continue; + } + String numStr = existNumber.substring(datePart.length()); + if (!numStr.matches("\\d+")) { + continue; // 防脏数据(非纯数字后缀)导致解析失败 + } + seq = Math.max(seq, Long.parseLong(numStr)); + } + seq = seq + 1; + int retryCount = 0; while (retryCount < MAX_RETRY) { String orderCode = datePart + String.format("%03d", seq); @@ -46,8 +80,60 @@ public class GoodsNumberGenerator { if (CollectionUtils.isEmpty(exist)) { return orderCode; } - seq++; // ← 关键:查重失败,序号往后递增找空位,而不是重新count + seq++; // ← 关键:查重失败,序号往后递增找空位,而不是重新取基线 } throw new ServiceException("生成唯一业务单号失败,已达到最大重试次数:" + MAX_RETRY); } -} \ No newline at end of file + + /** + * 生成唯一业务单号并落库: JVM分段锁内完成"取号+插单", + * 插入撞goods_number唯一索引时自动重新取号重试(索引为可选兜底), + * 插单成功后自检同号并自愈改号。 + * 供业务单创建入口(手动/审核新增、审核拆单、预约确认)统一使用。 + * @return 是否插入成功(mapper.insert结果) + */ + public boolean insertWithUniqueGoodsNumber(BusinessDocumentOrder order) { + Date date = (order.getDocumentDate() == null) ? new Date() : order.getDocumentDate(); + String lockKey = DateUtil.format(date, "yyMMdd"); + synchronized (LOCK_STRIPES.computeIfAbsent(lockKey, k -> new Object())) { + int retryCount = 0; + while (retryCount < MAX_RETRY) { + retryCount++; + order.setGoodsNumber(generateUniqueGoodsNumber(order.getDocumentDate())); + try { + boolean inserted = businessDocumentOrderMapper.insert(order) > 0; + // 插单后自检自愈: 无唯一索引时跨实例并发窗口内的撞号双方都能落库, + // 同号数量>1说明本单撞号, 给本单重新取号改号, 防止单号重复扩散 + healIfDuplicated(order); + return inserted; + } catch (DuplicateKeyException e) { + // 已建唯一索引时的兜底: 仅业务单号撞唯一索引时重试, 其他唯一约束冲突原样抛出 + String message = e.getMessage(); + if (message == null || !message.toLowerCase().contains("goods_number")) { + throw e; + } + log.warn("业务单号[{}]撞号, 自动重新取号重试(第{}次): {}", order.getGoodsNumber(), retryCount, message); + } + } + throw new ServiceException("生成唯一业务单号失败,已达到最大重试次数:" + MAX_RETRY); + } + } + + /** + * 插单后自检自愈: 查同号数量, >1 说明有并发插入撞号(本单为后插入方), + * 保持先落库单据单号不变, 重新取号给本单改号 + */ + private void healIfDuplicated(BusinessDocumentOrder order) { + List sameNumber = businessDocumentOrderMapper.selectList( + new QueryWrapper().eq("goods_number", order.getGoodsNumber()) + ); + if (sameNumber != null && sameNumber.size() > 1) { + String oldNumber = order.getGoodsNumber(); + String newNumber = generateUniqueGoodsNumber(order.getDocumentDate()); + order.setGoodsNumber(newNumber); + businessDocumentOrderMapper.updateById(order); + log.warn("业务单号[{}]与并发插入撞号(无唯一索引兜底), 已自愈改号为[{}], orderId={}", + oldNumber, newNumber, order.getId()); + } + } +} diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/executionInMaterialDetail/repository/po/ExecutionInMaterialDetailPO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/executionInMaterialDetail/repository/po/ExecutionInMaterialDetailPO.java index 86be848a0..25f6bb9bb 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/executionInMaterialDetail/repository/po/ExecutionInMaterialDetailPO.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/executionInMaterialDetail/repository/po/ExecutionInMaterialDetailPO.java @@ -501,6 +501,6 @@ public class ExecutionInMaterialDetailPO extends ExecutionStockInOrderBasePO { private BigDecimal insureAmount; @ApiModelProperty("货物类型:0-物料 1-半成品 2-成品") - @Excel(name = "货物类型") + @Excel(name = "货物类型", readConverterExp = "0=物料,1=半成品,2=成品") private Integer goodsType; } \ No newline at end of file diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/executionInMaterialDetail/repository/po/ExecutionInMaterialDetailWithOrderPO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/executionInMaterialDetail/repository/po/ExecutionInMaterialDetailWithOrderPO.java index 3bb849e16..6bdc2549f 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/executionInMaterialDetail/repository/po/ExecutionInMaterialDetailWithOrderPO.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/executionInMaterialDetail/repository/po/ExecutionInMaterialDetailWithOrderPO.java @@ -1,5 +1,7 @@ package com.mhd.oms.domain.executionInMaterialDetail.repository.po; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.mhd.common.core.annotation.Excel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -15,21 +17,34 @@ import java.util.Date; public class ExecutionInMaterialDetailWithOrderPO extends ExecutionInMaterialDetailPO { private static final long serialVersionUID = 1L; - @ApiModelProperty("入库单状态: 1-已创建 2-已审核 3-收货中 4-上架中 5-已入库 6-已取消 7-已关闭") + @ApiModelProperty("入库单流转状态(参考): 1-已创建 2-已审核 3-收货中 4-上架中 5-已入库 6-已取消 7-已关闭") private Integer inOrderStatus; + @ApiModelProperty("入库单展示状态: 0-已创建 2-已审核 3-已驳回 4-已入库(WMS回写status=5时同步/推送创建时置4,前端状态列绑定此字段)") + @Excel(name = "单据状态", readConverterExp = "0=已创建,2=已审核,3=已驳回,4=已入库") + private Integer issueStatus; + + @ApiModelProperty("货物种类(物料分类名称,多个逗号分隔)") + @Excel(name = "货物种类") + private String materialClassifyName; + @ApiModelProperty("入库单审核状态: 1-未审核 2-审核不通过 3-审核通过") + @Excel(name = "入库单审核状态: 1-未审核 2-审核不通过 3-审核通过") private Integer inOrderAuditStatus; @ApiModelProperty("货主ID") private Long orderShipperId; @ApiModelProperty("货主编码") + @Excel(name = "货主编码") private String orderShipperCode; @ApiModelProperty("货主名称") + @Excel(name = "货主名称") private String orderShipperName; @ApiModelProperty("入库日期") + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @Excel(name = "入仓日期", width = 30, dateFormat = "yyyy-MM-dd") private Date warehouseDate; } diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/executionInMaterialDetail/repository/todo/ExecutionInMaterialDetailQueryDTO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/executionInMaterialDetail/repository/todo/ExecutionInMaterialDetailQueryDTO.java index b48723a4f..91e42b873 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/executionInMaterialDetail/repository/todo/ExecutionInMaterialDetailQueryDTO.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/executionInMaterialDetail/repository/todo/ExecutionInMaterialDetailQueryDTO.java @@ -45,6 +45,12 @@ public class ExecutionInMaterialDetailQueryDTO extends BaseVOEntity { @ApiModelProperty("入库单类型编码") private String inOrderTypeCode; + @ApiModelProperty("入库单类型编码(与inOrderTypeCode同义)") + private String orderTypeCode; + + @ApiModelProperty("入库单类型名称(模糊查询)") + private String orderTypeName; + @ApiModelProperty("入库状态: 1-已创建 2-已审核 3-收货中 4-上架中 5-已入库 6-已取消 7-已关闭") private Integer inStatus; @@ -66,4 +72,10 @@ public class ExecutionInMaterialDetailQueryDTO extends BaseVOEntity { @ApiModelProperty("物料名称") private String materialName; + + @ApiModelProperty("实际入仓日期 开始(yyyy-MM-dd,为空按建档时间兜底)") + private String warehouseDateStart; + + @ApiModelProperty("实际入仓日期 结束(yyyy-MM-dd,为空按建档时间兜底)") + private String warehouseDateEnd; } diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/executionInMaterialDetail/repository/todo/QueryOrderOverStockDO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/executionInMaterialDetail/repository/todo/QueryOrderOverStockDO.java index df2f48055..662cf7333 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/executionInMaterialDetail/repository/todo/QueryOrderOverStockDO.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/executionInMaterialDetail/repository/todo/QueryOrderOverStockDO.java @@ -78,6 +78,12 @@ public class QueryOrderOverStockDO extends BaseVOEntity { @Excel(name = "入库单类型编码") private String inOrderTypeCode; + @ApiModelProperty("入库单类型编码(与inOrderTypeCode同义)") + private String orderTypeCode; + + @ApiModelProperty("入库单类型名称") + private String orderTypeName; + @ApiModelProperty("入库单类型名称") @Excel(name = "入库单类型名称") private String inOrderTypeName; @@ -137,4 +143,10 @@ public class QueryOrderOverStockDO extends BaseVOEntity { @ApiModelProperty("越库单状态 0:无状态 1:处理中 2:越库完成") @Excel(name = "越库单状态 0:无状态 1:处理中 2:越库完成") private Integer overStockStatus; + + @ApiModelProperty("实际入仓日期 开始(yyyy-MM-dd,为空按建档时间兜底)") + private String warehouseDateStart; + + @ApiModelProperty("实际入仓日期 结束(yyyy-MM-dd,为空按建档时间兜底)") + private String warehouseDateEnd; } \ No newline at end of file diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/executionInMaterialDetail/service/ExecutionInMaterialDetailApplicationService.java b/mhd_oms/src/main/java/com/mhd/oms/domain/executionInMaterialDetail/service/ExecutionInMaterialDetailApplicationService.java index 5e03ad47a..35cb5afe5 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/executionInMaterialDetail/service/ExecutionInMaterialDetailApplicationService.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/executionInMaterialDetail/service/ExecutionInMaterialDetailApplicationService.java @@ -85,4 +85,21 @@ public class ExecutionInMaterialDetailApplicationService { return inMaterialDetailDomainService.queryInOrderDetailList(queryOrderOverStockDO); } + /** + * 入库明细导出(全字段,口径同 queryInOrderDetailList,不分页) + */ + public List exportInOrderDetailList(QueryOrderOverStockDO queryOrderOverStockDO) { + List list = queryInOrderDetailList(queryOrderOverStockDO); + // 货物种类=挂载分类的父级分类名称:material_classify_name为分类路径(如"食品,饮料"),取倒数第二段; + // 仅一级分类(无父级)时取自身名称 + for (ExecutionInMaterialDetailWithOrderPO po : list) { + String names = po.getMaterialClassifyName(); + if (names != null && names.contains(",")) { + String[] parts = names.split(","); + po.setMaterialClassifyName(parts[parts.length - 2].trim()); + } + } + return list; + } + } \ No newline at end of file diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/executionOutMaterialDetail/entity/ExecutionOutMaterialDetail.java b/mhd_oms/src/main/java/com/mhd/oms/domain/executionOutMaterialDetail/entity/ExecutionOutMaterialDetail.java index f5de4d62e..69d4e5474 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/executionOutMaterialDetail/entity/ExecutionOutMaterialDetail.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/executionOutMaterialDetail/entity/ExecutionOutMaterialDetail.java @@ -518,4 +518,7 @@ public class ExecutionOutMaterialDetail extends BaseVOEntity { private String inLineNumGw; private String opWhLocGw; private String warehouseGw; -} \ No newline at end of file + + @ApiModelProperty("反审标记: 0-无 1-已反审(业务单反审时软删del_flag=2并打标记)") + private Integer reverseFlag; +} diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/executionOutMaterialDetail/repository/po/ExecutionOutMaterialDetailWithOrderPO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/executionOutMaterialDetail/repository/po/ExecutionOutMaterialDetailWithOrderPO.java index 8534f26b5..6f40eb45c 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/executionOutMaterialDetail/repository/po/ExecutionOutMaterialDetailWithOrderPO.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/executionOutMaterialDetail/repository/po/ExecutionOutMaterialDetailWithOrderPO.java @@ -1,6 +1,7 @@ package com.mhd.oms.domain.executionOutMaterialDetail.repository.po; import com.fasterxml.jackson.annotation.JsonFormat; +import com.mhd.common.core.annotation.Excel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; @@ -18,34 +19,49 @@ import java.util.Date; public class ExecutionOutMaterialDetailWithOrderPO extends ExecutionOutMaterialDetailPO { private static final long serialVersionUID = 1L; - @ApiModelProperty("出库单状态: 1-已创建 2-已审核 3-部分分配 4-已分配 5-拣货中 6-波次中 7-拣货完成 8-复核中 9-已出库 10-已取消 11-已关闭") + @ApiModelProperty("出库单流转状态(参考): 1-已创建 2-已审核 3-部分分配 4-已分配 5-拣货中 6-波次中 7-拣货完成 8-复核中 9-已出库 10-已取消 11-已关闭 12-已复核 13-已交接;WMS出库完成不回写此字段") private Integer outOrderStatus; + @ApiModelProperty("出库单展示状态: 0-已创建 2-已审核 3-已驳回 4-已出库(WMS出库完成/推送创建时回写,前端状态列绑定此字段)") + @Excel(name = "单据状态", readConverterExp = "0=已创建,2=已审核,3=已驳回,4=已出库") + private Integer issueStatus; + @ApiModelProperty("出库单审核状态: 1-未审核 2-审核不通过 3-审核通过") + @Excel(name = "出库单审核状态: 1-未审核 2-审核不通过 3-审核通过") private Integer outOrderAuditStatus; @ApiModelProperty("货主ID") private Long orderShipperId; @ApiModelProperty("货主编码") + @Excel(name = "货主编码") private String orderShipperCode; @ApiModelProperty("货主名称") + @Excel(name = "货主名称") private String orderShipperName; @ApiModelProperty("出仓日期") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "出仓日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") private Date orderOutboundDate; @ApiModelProperty("出库时间") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Excel(name = "出库时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") private Date orderOutboundTime; @ApiModelProperty("保额") + @Excel(name = "保额") private BigDecimal insureAmount; @ApiModelProperty("货物类型:0-物料 1-半成品 2-成品") + @Excel(name = "货物类型", readConverterExp = "0=物料,1=半成品,2=成品") private Integer goodsType; + + @ApiModelProperty("货物种类(物料分类名称,多个逗号分隔)") + @Excel(name = "货物种类") + private String materialClassifyName; } diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/executionOutMaterialDetail/repository/todo/ExecutionOutMaterialDetailQueryDTO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/executionOutMaterialDetail/repository/todo/ExecutionOutMaterialDetailQueryDTO.java index e21050c93..1611fc6be 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/executionOutMaterialDetail/repository/todo/ExecutionOutMaterialDetailQueryDTO.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/executionOutMaterialDetail/repository/todo/ExecutionOutMaterialDetailQueryDTO.java @@ -45,6 +45,12 @@ public class ExecutionOutMaterialDetailQueryDTO extends BaseVOEntity { @ApiModelProperty("出库单类型编码") private String outOrderTypeCode; + @ApiModelProperty("出库单类型编码(与outOrderTypeCode同义)") + private String orderTypeCode; + + @ApiModelProperty("出库单类型名称(模糊查询)") + private String orderTypeName; + @ApiModelProperty("出库状态: 1-已创建 2-已审核 3-部分分配 4-已分配 5-拣货中 6-波次中 7-拣货完成 8-复核中 9-已出库 10-已取消 11-已关闭") private Integer outStatus; @@ -66,4 +72,10 @@ public class ExecutionOutMaterialDetailQueryDTO extends BaseVOEntity { @ApiModelProperty("物料名称") private String materialName; + + @ApiModelProperty("实际出仓日期 开始(yyyy-MM-dd,为空按建档时间兜底)") + private String outboundDateStart; + + @ApiModelProperty("实际出仓日期 结束(yyyy-MM-dd,为空按建档时间兜底)") + private String outboundDateEnd; } 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/executionStockOutOrder/entity/ExecutionStockOutOrder.java b/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockOutOrder/entity/ExecutionStockOutOrder.java index 67029be76..3ebde6d29 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockOutOrder/entity/ExecutionStockOutOrder.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockOutOrder/entity/ExecutionStockOutOrder.java @@ -516,4 +516,7 @@ public class ExecutionStockOutOrder extends BaseVOEntity { @ApiModelProperty("折扣") private BigDecimal discount; -} \ No newline at end of file + + @ApiModelProperty("反审标记: 0-无 1-已反审(业务单反审时软删del_flag=2并打标记)") + private Integer reverseFlag; +} diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockOutOrder/repository/po/ExecutionStockOutOrderPO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockOutOrder/repository/po/ExecutionStockOutOrderPO.java index 58f120900..1801bf6eb 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockOutOrder/repository/po/ExecutionStockOutOrderPO.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockOutOrder/repository/po/ExecutionStockOutOrderPO.java @@ -29,6 +29,8 @@ public class ExecutionStockOutOrderPO extends BaseVOEntity { @ApiModelProperty("出库单id") private Long outOrderId; + @ApiModelProperty("反审标记: 1-已反审(反审软删归档, 【已反审】tab按 delFlag=2+reverseFlag=1 查询)") + private Integer reverseFlag; @ApiModelProperty("总价") @Excel(name = "总价") private BigDecimal amount; diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockOutOrder/repository/todo/ExecutionStockOutOrderDO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockOutOrder/repository/todo/ExecutionStockOutOrderDO.java index b8317cf1c..8dbda715e 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockOutOrder/repository/todo/ExecutionStockOutOrderDO.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockOutOrder/repository/todo/ExecutionStockOutOrderDO.java @@ -29,6 +29,9 @@ public class ExecutionStockOutOrderDO extends BaseVOEntity { @ApiModelProperty("出库单id") private Long outOrderId; + @ApiModelProperty("反审标记查询: 1-已反审(与delFlag=2成对传, 查【已反审】tab归档数据)") + private Integer reverseFlag; + @ApiModelProperty("组织表ID") @Excel(name = "组织表ID") private Long organizationId; diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockOutOrder/repository/todo/ExecutionStockOutOrderDTO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockOutOrder/repository/todo/ExecutionStockOutOrderDTO.java index 0b2033f43..a140f238b 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockOutOrder/repository/todo/ExecutionStockOutOrderDTO.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockOutOrder/repository/todo/ExecutionStockOutOrderDTO.java @@ -27,6 +27,9 @@ public class ExecutionStockOutOrderDTO extends ExecutionStockOutOrderBaseDTO { @ApiModelProperty("出库单id") private Long outOrderId; + @ApiModelProperty("反审标记查询: 1-已反审(与delFlag=2成对传, 查【已反审】tab归档数据)") + private Integer reverseFlag; + @ApiModelProperty("组织表ID") @Excel(name = "组织表ID") private Long organizationId; diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockOutOrder/service/ExecutionStockOutOrderApplicationService.java b/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockOutOrder/service/ExecutionStockOutOrderApplicationService.java index f28d93192..320fa25fa 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockOutOrder/service/ExecutionStockOutOrderApplicationService.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockOutOrder/service/ExecutionStockOutOrderApplicationService.java @@ -66,6 +66,8 @@ import java.util.stream.Collectors; public class ExecutionStockOutOrderApplicationService { @Autowired private ExecutionStockOutOrderDomainService stockOutOrderDomainService; + @Autowired + private com.mhd.oms.application.service.WarehouseInfoApplicationService warehouseInfoApplicationService; // @Autowired // private ExecutionOutMaterialDetailDomainService outMaterialDetailDomainService; // @Autowired @@ -862,11 +864,8 @@ public class ExecutionStockOutOrderApplicationService { if (stockOutOrderDO.getWarehouseId() == null) { throw new ServiceException("仓库ID不能为空"); } - AjaxResult ajaxResult = systemServiceFeign.getWarehouseInfoByWarehouseId(stockOutOrderDO.getWarehouseId()); - if(!"200".equals(String.valueOf(ajaxResult.get("code")))){ - throw new ServiceException("获取仓库信息失败"); - } - WarehouseFeignPO warehouseFeignPO = JSON.parseObject(JSONObject.toJSONString(ajaxResult.get("data")), WarehouseFeignPO.class); + // Feign失败走本地跨库兜底, 避免保存被"获取仓库信息失败"阻断 + WarehouseFeignPO warehouseFeignPO = warehouseInfoApplicationService.getWarehouseInfo(stockOutOrderDO.getWarehouseId()); stockOutOrderDO.setWarehouseCode(warehouseFeignPO.getWarehouseCode()); stockOutOrderDO.setWarehouseName(warehouseFeignPO.getWarehouseName()); } diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockOutOrder/service/ExecutionStockOutOrderDomainService.java b/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockOutOrder/service/ExecutionStockOutOrderDomainService.java index 5d57783ba..6a1617cb8 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockOutOrder/service/ExecutionStockOutOrderDomainService.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/executionStockOutOrder/service/ExecutionStockOutOrderDomainService.java @@ -71,6 +71,8 @@ public class ExecutionStockOutOrderDomainService { @Autowired private IExecutionStockOutOrderService stockOutOrderService; @Autowired + private com.mhd.oms.application.service.WarehouseInfoApplicationService warehouseInfoApplicationService; + @Autowired private IExecutionOutMaterialDetailService outMaterialDetailService; @Autowired private IReservationDeliveryDetailsLinkService deliveryDetailsLinkService; @@ -148,14 +150,9 @@ public class ExecutionStockOutOrderDomainService { public Boolean insert(ExecutionStockOutOrderDO stockOutOrderDO) { //建单校验:明细数量必须大于0(0数量单下发WMS后自动分配必失败,出库单会卡死在已审核状态) validateMaterialDetailQuantity(stockOutOrderDO.getMaterialDetailList()); - //设置单号 + //设置单号(仓库信息: Feign优先, system服务失败/降级时本地跨库兜底) Long warehouseId = stockOutOrderDO.getWarehouseId(); - AjaxResult ajaxResult = systemServiceFeign.getWarehouseInfoByWarehouseId(warehouseId); - if (!"200".equals(String.valueOf(ajaxResult.get("code")))) { - throw new ServiceException("获取仓库信息失败"); - } - //仓库信息 - WarehouseFeignPO warehouseFeignPO = com.alibaba.fastjson.JSON.parseObject(com.alibaba.fastjson2.JSONObject.toJSONString(ajaxResult.get("data")), WarehouseFeignPO.class); + WarehouseFeignPO warehouseFeignPO = warehouseInfoApplicationService.getWarehouseInfo(warehouseId); String orderNoGenerateRule = warehouseFeignPO.getOrderNoGenerateRule(); String prefix = warehouseFeignPO.getOutOrderNoPrefix(); if ("yang_pin_chu_ku".equals(stockOutOrderDO.getBusinessType())) { @@ -218,14 +215,9 @@ public class ExecutionStockOutOrderDomainService { @Transactional(rollbackFor = Exception.class) public Boolean batchInsert(List stockOutOrderDOList) { for (ExecutionStockOutOrderDO stockOutOrderDO : stockOutOrderDOList){ - //设置单号 + //设置单号(仓库信息: Feign优先, system服务失败/降级时本地跨库兜底) Long warehouseId = stockOutOrderDO.getWarehouseId(); - AjaxResult ajaxResult = systemServiceFeign.getWarehouseInfoByWarehouseId(warehouseId); - if (!"200".equals(String.valueOf(ajaxResult.get("code")))) { - throw new ServiceException("获取仓库信息失败"); - } - //仓库信息 - WarehouseFeignPO warehouseFeignPO = com.alibaba.fastjson.JSON.parseObject(com.alibaba.fastjson2.JSONObject.toJSONString(ajaxResult.get("data")), WarehouseFeignPO.class); + WarehouseFeignPO warehouseFeignPO = warehouseInfoApplicationService.getWarehouseInfo(warehouseId); String orderNoGenerateRule = warehouseFeignPO.getOrderNoGenerateRule(); String prefix = warehouseFeignPO.getOutOrderNoPrefix(); if ("yang_pin_chu_ku".equals(stockOutOrderDO.getBusinessType())) { @@ -542,7 +534,12 @@ public class ExecutionStockOutOrderDomainService { stockOutOrder.setOrganizationId(orgId); stockOutOrder.setOrganizationName(orgName); stockOutOrder.setTopOrganizationId(topOrgId); - wmsServiceFeign.omsOutOrderAdd(stockOutOrder); + //单头/配送明细推送同样校验返回值: 降级吞掉会残留"有单无明细"等半截单 + AjaxResult orderAddResult = wmsServiceFeign.omsOutOrderAdd(stockOutOrder); + if (orderAddResult == null || !"200".equals(String.valueOf(orderAddResult.get("code")))) { + throw new ServiceException("出库单[" + currentOrderNumber + "]WMS出库单推送失败:" + + (orderAddResult == null ? "WMS服务不可用或已降级" : orderAddResult.get("msg"))); + } List list = deliveryDetailsLinkService.list(new QueryWrapper().lambda().eq(ReservationDeliveryDetailsLink::getOrderNumber, byId.getOutOrderNumber())); List deliveryDetailsLinkList = new ArrayList<>(); @@ -552,7 +549,11 @@ public class ExecutionStockOutOrderDomainService { deliveryDetailsLink.setOmsId(reservationDeliveryDetailsLink.getId()); deliveryDetailsLinkList.add(deliveryDetailsLink); } - wmsServiceFeign.omsOutOrderAddDeliveryDetailsLink(deliveryDetailsLinkList); + AjaxResult linkAddResult = wmsServiceFeign.omsOutOrderAddDeliveryDetailsLink(deliveryDetailsLinkList); + if (linkAddResult == null || !"200".equals(String.valueOf(linkAddResult.get("code")))) { + throw new ServiceException("出库单[" + currentOrderNumber + "]WMS配送明细推送失败:" + + (linkAddResult == null ? "WMS服务不可用或已降级" : linkAddResult.get("msg"))); + } String inOrderNumber = stockOutOrder.getOutOrderNumber(); @@ -566,7 +567,12 @@ public class ExecutionStockOutOrderDomainService { outMaterialDetail.setTopOrganizationId(topOrgId); outMaterialDetailList.add(outMaterialDetail); } - wmsServiceFeign.omsOutOrderAddDetail(outMaterialDetailList); + //明细推送必须校验返回值: 失败被降级吞掉时WMS会残留"有单无明细"的出库单, 自动分配报"可用库存为0"难定位 + AjaxResult detailAddResult = wmsServiceFeign.omsOutOrderAddDetail(outMaterialDetailList); + if (detailAddResult == null || !"200".equals(String.valueOf(detailAddResult.get("code")))) { + throw new ServiceException("出库单[" + currentOrderNumber + "]WMS出库明细推送失败:" + + (detailAddResult == null ? "WMS服务不可用或已降级" : detailAddResult.get("msg"))); + } String outOrderNumber = byId.getOutOrderNumber(); com.mhd.system.api.domain.StockOutOrderDTO stockOutOrderDTO = new com.mhd.system.api.domain.StockOutOrderDTO(); diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationInMaterialDetail/repository/todo/QueryOrderOverStockDO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationInMaterialDetail/repository/todo/QueryOrderOverStockDO.java index 3310cedd1..bb55c5bae 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationInMaterialDetail/repository/todo/QueryOrderOverStockDO.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationInMaterialDetail/repository/todo/QueryOrderOverStockDO.java @@ -102,6 +102,12 @@ public class QueryOrderOverStockDO extends BaseVOEntity { @Excel(name = "出库单类型编码") private String outOrderTypeCode; + @ApiModelProperty("出库单类型编码(与outOrderTypeCode同义)") + private String orderTypeCode; + + @ApiModelProperty("出库单类型名称") + private String orderTypeName; + @ApiModelProperty("出库单类型名称") @Excel(name = "出库单类型名称") private String outOrderTypeName; @@ -137,4 +143,10 @@ public class QueryOrderOverStockDO extends BaseVOEntity { @ApiModelProperty("越库单状态 0:无状态 1:处理中 2:越库完成") @Excel(name = "越库单状态 0:无状态 1:处理中 2:越库完成") private Integer overStockStatus; + + @ApiModelProperty("实际出仓日期 开始(yyyy-MM-dd,为空按建档时间兜底)") + private String outboundDateStart; + + @ApiModelProperty("实际出仓日期 结束(yyyy-MM-dd,为空按建档时间兜底)") + private String outboundDateEnd; } \ No newline at end of file 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/mapper/ReservationStockInOrderMapper.java b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/mapper/ReservationStockInOrderMapper.java index 16e7e43d2..9f47433f4 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/mapper/ReservationStockInOrderMapper.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockInOrder/repository/mapper/ReservationStockInOrderMapper.java @@ -54,6 +54,13 @@ public interface ReservationStockInOrderMapper extends BaseMapper queryNoticePrint(ReservationStockInOrderDO stockInOrderDO); List queryNoticePrintDetail(ReservationStockInOrderDO stockInOrderDO); public void updateByTransportationNumber(@Param("transportationNumber") String transportationNumber); 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..26595005f 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; /** * 分页查询入库单列表 @@ -169,6 +176,10 @@ public class ReservationStockInOrderDomainService { // //统计总体积 // BigDecimal volumeLimit = stockInOrderDO.getMaterialDetailList().stream().map(ReservationInMaterialDetailDO::getVolumeLimit).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add); // stockInOrderDO.setVolumeLimit(volumeLimit); + // 订单来源为空时兜底为手动创建(导入/预约下发等路径已显式设置,不受影响),下发执行单时随业务单继承 + if (stockInOrderDO.getReservationOrderSource() == null || stockInOrderDO.getReservationOrderSource().isEmpty()) { + stockInOrderDO.setReservationOrderSource("手动创建"); + } stockInOrderService.insert(stockInOrderDO); return materialDetailService.batchInsert(stockInOrderDO.getInOrderNumber(), stockInOrderDO.getMaterialDetailList()); } @@ -607,7 +618,6 @@ public class ReservationStockInOrderDomainService { reservationStockInOrder.setOrderTypeName("普通入库"); reservationStockInOrder.setBusinessType("pu_tong_ru_ku"); } - reservationStockInOrder.setReservationOrderSource("客户预约"); reservationStockInOrder.setWarehouseId(warehouseId); if (warehouseId == null || warehouseId == 0L){ reservationStockInOrder.setWarehouseId(byId.getWarehouseId()); @@ -767,6 +777,171 @@ 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() : "")); + //组织三字段:WMS幂等跳过分支(未下发单反审)写反审记录时取不到W入库单,需经Feign透传 + reverseParam.setOrganizationId(executionOrder.getOrganizationId()); + reverseParam.setOrganizationName(executionOrder.getOrganizationName()); + reverseParam.setTopOrganizationId(executionOrder.getTopOrganizationId()); + 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) + //清空下发/执行时间(前端"是否执行"列按执行时间判断,不清会仍显示已执行,与取消下发 cancelIssueOrder 同口径) + .set(ReservationStockInOrder::getIssueTime, null) + //入库进度状态(1-已创建 2-已审核 3-收货中 4-上架中 5-已入库):首轮"完成上架"会经WMS回传写成5, + //不重置的话重新下发时copy给执行单→W入库单→收货单,收货单带着"已完成"状态导致前端不给收货按钮; + //重置为1(已创建),与手工新单首次下发链路一致(W入库单/收货单起点=1-待收货) + .set(ReservationStockInOrder::getStatus, 1) + .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 有值表示已下发/执行过。 @@ -870,7 +1045,6 @@ public class ReservationStockInOrderDomainService { reservationStockInOrder.setOrderTypeName("普通入库"); reservationStockInOrder.setBusinessType("pu_tong_ru_ku"); } - reservationStockInOrder.setReservationOrderSource("客户预约"); reservationStockInOrder.setWarehouseId(warehouseId); // reservationStockInOrder.setOrganizationId(orgId); // reservationStockInOrder.setOrganizationName(orgName); diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockOutOrder/entity/ReservationStockOutOrder.java b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockOutOrder/entity/ReservationStockOutOrder.java index 1a8a18599..500b1ba00 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockOutOrder/entity/ReservationStockOutOrder.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockOutOrder/entity/ReservationStockOutOrder.java @@ -515,4 +515,21 @@ public class ReservationStockOutOrder extends BaseVOEntity { @ApiModelProperty("折扣") private BigDecimal discount; + @ApiModelProperty("反审状态: 0-无 1-已反审(反审后status回退为1-已创建,重新审核通过自动复位0)") + private Integer reverseStatus; + + @ApiModelProperty("反审人id") + private Long reverseBy; + + @ApiModelProperty("反审人姓名") + private String reverseByName; + + @ApiModelProperty("反审时间") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date reverseTime; + + @ApiModelProperty("反审原因") + private String reverseRemark; + } \ No newline at end of file diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockOutOrder/repository/po/ReservationStockOutOrderPO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockOutOrder/repository/po/ReservationStockOutOrderPO.java index 7f93ccfa5..fa2236371 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockOutOrder/repository/po/ReservationStockOutOrderPO.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockOutOrder/repository/po/ReservationStockOutOrderPO.java @@ -538,4 +538,21 @@ public class ReservationStockOutOrderPO extends BaseVOEntity { @ApiModelProperty("折扣") private BigDecimal discount; + @ApiModelProperty("反审状态: 0-无 1-已反审(反审后status回退为1-已创建,重新审核通过自动复位0)") + private Integer reverseStatus; + + @ApiModelProperty("反审人id") + private Long reverseBy; + + @ApiModelProperty("反审人姓名") + private String reverseByName; + + @ApiModelProperty("反审时间") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date reverseTime; + + @ApiModelProperty("反审原因") + private String reverseRemark; + } \ No newline at end of file diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockOutOrder/repository/todo/ReservationStockOutOrderDO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockOutOrder/repository/todo/ReservationStockOutOrderDO.java index 066e84512..860fe227b 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockOutOrder/repository/todo/ReservationStockOutOrderDO.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockOutOrder/repository/todo/ReservationStockOutOrderDO.java @@ -591,4 +591,19 @@ public class ReservationStockOutOrderDO extends BaseVOEntity { @ApiModelProperty("折扣") private BigDecimal discount; + @ApiModelProperty("反审状态: 0-无 1-已反审(反审后status回退为1-已创建,重新审核通过自动复位0)") + private Integer reverseStatus; + + @ApiModelProperty("反审人id") + private Long reverseBy; + + @ApiModelProperty("反审人姓名") + private String reverseByName; + + @ApiModelProperty("反审时间") + private Date reverseTime; + + @ApiModelProperty("反审原因") + private String reverseRemark; + } \ No newline at end of file diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockOutOrder/repository/todo/ReservationStockOutOrderDTO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockOutOrder/repository/todo/ReservationStockOutOrderDTO.java index f6611d76e..0880dc84d 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockOutOrder/repository/todo/ReservationStockOutOrderDTO.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockOutOrder/repository/todo/ReservationStockOutOrderDTO.java @@ -580,4 +580,21 @@ public class ReservationStockOutOrderDTO extends ReservationStockOutOrderBaseDTO @ApiModelProperty("折扣") private BigDecimal discount; + @ApiModelProperty("反审状态: 0-无 1-已反审(反审后status回退为1-已创建,重新审核通过自动复位0)") + private Integer reverseStatus; + + @ApiModelProperty("反审人id") + private Long reverseBy; + + @ApiModelProperty("反审人姓名") + private String reverseByName; + + @ApiModelProperty("反审时间") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date reverseTime; + + @ApiModelProperty("反审原因") + private String reverseRemark; + } \ No newline at end of file diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockOutOrder/service/ReservationStockOutOrderApplicationService.java b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockOutOrder/service/ReservationStockOutOrderApplicationService.java index 1e4f07f3c..e10484acd 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockOutOrder/service/ReservationStockOutOrderApplicationService.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockOutOrder/service/ReservationStockOutOrderApplicationService.java @@ -85,6 +85,8 @@ import java.util.stream.Collectors; public class ReservationStockOutOrderApplicationService { @Autowired private ReservationStockOutOrderDomainService stockOutOrderDomainService; + @Autowired + private com.mhd.oms.application.service.WarehouseInfoApplicationService warehouseInfoApplicationService; // @Autowired // private ReservationOutMaterialDetailDomainService outMaterialDetailDomainService; // @Autowired @@ -881,6 +883,14 @@ public class ReservationStockOutOrderApplicationService { return stockOutOrderDomainService.cancelIssueOrder(stockOutOrderDO); } + /** + * @description 反审出库业务单(已出库/已复核单据回退到已创建, WMS库存还原并生成反审异常记录) + * @date 2026/9/8 + */ + public Boolean reverseAudit(ReservationStockOutOrderDO stockOutOrderDO){ + return stockOutOrderDomainService.reverseAudit(stockOutOrderDO); + } + public Boolean executeAndIssue(ReservationStockOutOrderDO stockOutOrderDO){ return stockOutOrderDomainService.executeAndIssue(stockOutOrderDO); } @@ -905,11 +915,8 @@ public class ReservationStockOutOrderApplicationService { if (stockOutOrderDO.getWarehouseId() == null) { throw new ServiceException("仓库ID不能为空"); } - AjaxResult ajaxResult = systemServiceFeign.getWarehouseInfoByWarehouseId(stockOutOrderDO.getWarehouseId()); - if(!"200".equals(String.valueOf(ajaxResult.get("code")))){ - throw new ServiceException("获取仓库信息失败"); - } - WarehouseFeignPO warehouseFeignPO = JSON.parseObject(JSONObject.toJSONString(ajaxResult.get("data")), WarehouseFeignPO.class); + // Feign失败走本地跨库兜底, 避免新增/编辑保存被"获取仓库信息失败"阻断 + WarehouseFeignPO warehouseFeignPO = warehouseInfoApplicationService.getWarehouseInfo(stockOutOrderDO.getWarehouseId()); stockOutOrderDO.setWarehouseCode(warehouseFeignPO.getWarehouseCode()); stockOutOrderDO.setWarehouseName(warehouseFeignPO.getWarehouseName()); } diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockOutOrder/service/ReservationStockOutOrderDomainService.java b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockOutOrder/service/ReservationStockOutOrderDomainService.java index 8dcf82a96..12d1a1ce1 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockOutOrder/service/ReservationStockOutOrderDomainService.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/reservationStockOutOrder/service/ReservationStockOutOrderDomainService.java @@ -18,6 +18,10 @@ import com.mhd.oms.domain.businessDeliveryDetailsLink.repository.facade.IBusines import com.mhd.oms.domain.businessDeliveryDetailsLink.repository.mapper.BusinessDeliveryDetailsLinkMapper; import com.mhd.oms.domain.businessDocumentOrder.entity.BusinessDocumentOrder; import com.mhd.oms.domain.businessDocumentOrder.repository.mapper.BusinessDocumentOrderMapper; +import com.mhd.oms.domain.businessDocumentCargoMulti.entity.BusinessDocumentCargoMulti; +import com.mhd.oms.domain.businessDocumentCargoMulti.repository.mapper.BusinessDocumentCargoMultiMapper; +import com.mhd.oms.domain.businessDocumentAddressMulti.entity.BusinessDocumentAddressMulti; +import com.mhd.oms.domain.businessDocumentAddressMulti.repository.mapper.BusinessDocumentAddressMultiMapper; import com.mhd.oms.domain.executeOrder.entity.ExecuteOrder; import com.mhd.oms.domain.executeOrder.repository.mapper.ExecuteOrderMapper; import com.mhd.oms.domain.executionInMaterialDetail.entity.ExecutionInMaterialDetail; @@ -48,6 +52,8 @@ import com.mhd.oms.domain.reservationStockInOrder.repository.mapper.ReservationS import com.mhd.oms.domain.reservationStockInOrder.repository.po.MaterialBaseInfoPO; import com.mhd.oms.domain.reservationStockInOrder.repository.todo.ReservationStockInOrderDO; import com.mhd.oms.domain.reservationStockOutOrder.entity.ReservationStockOutOrder; +import com.mhd.oms.domain.reservationInventoryAdjustmentRecord.entity.ReservationInventoryAdjustmentRecord; +import com.mhd.oms.domain.reservationInventoryAdjustmentRecord.repository.mapper.ReservationInventoryAdjustmentRecordMapper; import com.mhd.oms.domain.reservationStockOutOrder.repository.facade.IReservationStockOutOrderService; import com.mhd.oms.domain.reservationStockOutOrder.repository.mapper.ReservationStockOutOrderMapper; import com.mhd.oms.domain.reservationStockOutOrder.repository.po.ReservationStockOutOrderPO; @@ -55,6 +61,7 @@ import com.mhd.oms.domain.reservationStockOutOrder.repository.todo.ReservationSt import com.mhd.oms.domain.reserveStockOutOrder.repository.mapper.ReserveStockOutOrderMapper; import com.mhd.system.api.SystemServiceFeign; import com.mhd.system.api.WmsServiceFeign; +import com.mhd.system.api.WlhyServiceFeign; import com.mhd.system.api.domain.*; import com.mhd.system.api.model.LoginUser; import lombok.extern.slf4j.Slf4j; @@ -118,6 +125,16 @@ public class ReservationStockOutOrderDomainService { private ReserveStockOutOrderMapper reserveStockOutOrderMapper; @Autowired private MaterialBaseInfoResolveService materialBaseInfoResolveService; + @Resource + private ReservationInventoryAdjustmentRecordMapper inventoryAdjustmentRecordMapper; + @Resource + private WlhyServiceFeign wlhyServiceFeign; + @Autowired + private BusinessDocumentCargoMultiMapper businessDocumentCargoMultiMapper; + @Autowired + private BusinessDocumentAddressMultiMapper businessDocumentAddressMultiMapper; + @Autowired + private com.mhd.oms.application.service.WarehouseInfoApplicationService warehouseInfoApplicationService; /** * 分页查询出库单列表 @@ -215,6 +232,10 @@ public class ReservationStockOutOrderDomainService { if (stockOutOrderDO.getCheckTaskDistribution() == null) { stockOutOrderDO.setCheckTaskDistribution(2); } + // 订单来源为空时兜底为手动创建(导入/预约下发等路径已显式设置,不受影响),下发执行单时随业务单继承 + if (stockOutOrderDO.getReservationOrderSource() == null || stockOutOrderDO.getReservationOrderSource().isEmpty()) { + stockOutOrderDO.setReservationOrderSource("手动创建"); + } stockOutOrderService.insert(stockOutOrderDO); List reservationDeliveryDetailsLinkList = stockOutOrderDO.getReservationDeliveryDetailsLinkList(); if (reservationDeliveryDetailsLinkList != null && !reservationDeliveryDetailsLinkList.isEmpty()){ @@ -409,7 +430,8 @@ public class ReservationStockOutOrderDomainService { String userRealName = loginUser.getUserPo() != null && loginUser.getUserPo().getUserName() != null ? loginUser.getUserPo().getUserName() : (loginUser.getRealname() != null ? loginUser.getRealname() : loginUser.getUsername()); - boolean updateResult = stockOutOrderService.update(null, new UpdateWrapper().lambda() + boolean updateResult; + LambdaUpdateWrapper auditUpdateWrapper = new UpdateWrapper().lambda() .set(ReservationStockOutOrder::getReservationAuditId, loginUser.getUserid()) .set(ReservationStockOutOrder::getReservationAuditName, userRealName) .set(ReservationStockOutOrder::getReservationAuditTime, new Date()) @@ -417,7 +439,12 @@ public class ReservationStockOutOrderDomainService { .set(ReservationStockOutOrder::getUpdateByName, userRealName) .set(ReservationStockOutOrder::getUpdateTime, new Date()) .set(ReservationStockOutOrder::getIssueStatus, issueStatus) - .in(ReservationStockOutOrder::getOutOrderId, stockOutOrderDO.getOutOrderIds())); + .in(ReservationStockOutOrder::getOutOrderId, stockOutOrderDO.getOutOrderIds()); + // 重新审核通过时复位反审标记: 单据离开【已反审】页签回到正常流转 + if (issueStatus == 2) { + auditUpdateWrapper.set(ReservationStockOutOrder::getReverseStatus, 0); + } + updateResult = stockOutOrderService.update(null, auditUpdateWrapper); //审核通过时同步线路/车次到关联的运输业务单 if (issueStatus == 2) { @@ -481,6 +508,125 @@ public class ReservationStockOutOrderDomainService { } } + /** + * 重新下发前自愈清理: 历史版本反审/取消下发软删的执行明细(del_flag=2)仍占用unique_id + * (EXECUTION_OUT_MATERIAL_DETAIL 唯一约束不含del_flag), 重新下发从预留明细复制同一unique_id会撞键; + * 归档行的unique_id无功能用途(仅活动明细展示反查批号用到), 统一置空释放键位, 幂等可重复执行 + */ + private void releaseArchivedDetailUniqueId(String businessOutOrderNumber) { + List executionOrderNumbers = executionStockOutOrderService.list(new QueryWrapper().lambda() + .eq(ExecutionStockOutOrder::getBusinessOutOrderNumber, businessOutOrderNumber)) + .stream() + .map(ExecutionStockOutOrder::getOutOrderNumber) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + if (executionOrderNumbers.isEmpty()) { + return; + } + executionOutMaterialDetailService.update(null, new UpdateWrapper().lambda() + .set(ExecutionOutMaterialDetail::getUniqueId, null) + .eq(ExecutionOutMaterialDetail::getDelFlag, 2) + .in(ExecutionOutMaterialDetail::getOutOrderNumber, executionOrderNumbers)); + } + + /** + * 反审联动软删运输链路(编辑"是否运输"=是 且审核通过后生成的链), 真实层级: + * 运输业务单-主单(splicingOrderType=4, business_document_order) + * -> 审核运输业务单按配送明细生成子单(splicingOrderType=3, mainOrderId=主单id, 每明细一单) + * -> 下发每个子单各生成一个运输执行单(execute_order.businessDocumentId=【子单id】, goodsNumber=子单货源号, 主单下无直接执行单) + * -> 每个执行单各推一单TMS(tms_order.execute_order_number=执行单货源号) -> TMS运单/运输作业单(wlhy外部服务)。 + * 定位运输业务单: ①出库单.businessNumber(创建运输业务单时回填的货源单号) ②inOrderNumber=出库单号兜底 + * (businessNumber缺失/已清空场景); 均不滤del_flag——此前被旧版反审漏删或手工删过的主单, + * 其子单/执行单/TMS链可能仍存活, 同样要清理(幂等)。配送明细链的invoiceNumber存的是送货单号而非出库单号, 不能作为定位条件。 + * 执行单逐个调 TMS deleteChainByExecuteOrderNumber 软删TMS侧整链(未下发过则TMS无数据, 幂等空操作), 失败抛异常整批回滚; + * 本地软删执行单/主单及子单及其货品/地址明细/配送明细链; 无关联运输单时直接跳过。 + */ + private void reverseTransportChain(ReservationStockOutOrder byId) { + String outOrderNumber = byId.getOutOrderNumber(); + Set transportOrderIds = new HashSet<>(); + if (StringUtils.isNotBlank(byId.getBusinessNumber())) { + businessDocumentOrderMapper.selectList(new LambdaQueryWrapper() + .eq(BusinessDocumentOrder::getGoodsNumber, byId.getBusinessNumber())) + .forEach(order -> transportOrderIds.add(order.getId())); + } + businessDocumentOrderMapper.selectList(new LambdaQueryWrapper() + .eq(BusinessDocumentOrder::getInOrderNumber, outOrderNumber)) + .forEach(order -> transportOrderIds.add(order.getId())); + if (transportOrderIds.isEmpty()) { + return; + } + for (Long transportOrderId : transportOrderIds) { + BusinessDocumentOrder transportOrder = businessDocumentOrderMapper.selectById(transportOrderId); + if (transportOrder == null) { + continue; + } + // 0. 拆单主单自身无执行单: 收集主单+全部子单id, 执行单/货品/地址明细按全量id清理 + List subOrders = businessDocumentOrderMapper.selectList(new LambdaQueryWrapper() + .eq(BusinessDocumentOrder::getMainOrderId, String.valueOf(transportOrderId)) + .eq(BusinessDocumentOrder::getDelFlag, 1)); + Set chainDocIds = new HashSet<>(); + chainDocIds.add(transportOrderId); + subOrders.forEach(subOrder -> chainDocIds.add(subOrder.getId())); + // 1. 执行单: 不滤del_flag——历史周期已归档执行单的TMS链也幂等补清(防"执行单已删TMS残留"), + // 先逐个软删TMS侧整链(货源单->运单->作业单), 再软删本地执行单(已归档的跳过更新) + List executeOrders = executeOrderMapper.selectList(new LambdaQueryWrapper() + .in(ExecuteOrder::getBusinessDocumentId, chainDocIds)); + for (ExecuteOrder executeOrder : executeOrders) { + if (StringUtils.isNotBlank(executeOrder.getGoodsNumber())) { + AjaxResult tmsResult = wlhyServiceFeign.deleteChainByExecuteOrderNumber(executeOrder.getGoodsNumber()); + if (tmsResult == null || !"200".equals(String.valueOf(tmsResult.get("code")))) { + throw new ServiceException("出库单[" + outOrderNumber + "]反审失败: 运输执行单货源单号[" + + executeOrder.getGoodsNumber() + "]TMS链路软删失败: " + + (tmsResult == null ? "TMS服务不可用" : tmsResult.get("msg"))); + } + } + if (!Integer.valueOf(2).equals(executeOrder.getDelFlag())) { + executeOrder.setDelFlag(2); + executeOrderMapper.updateById(executeOrder); + } + } + // 2. 软删运输业务单(主单+子单)及其货品/地址明细(主单已软删的只补清理子单/明细, 不重复更新主单) + if (!Integer.valueOf(2).equals(transportOrder.getDelFlag())) { + transportOrder.setDelFlag(2); + businessDocumentOrderMapper.updateById(transportOrder); + } + for (BusinessDocumentOrder subOrder : subOrders) { + subOrder.setDelFlag(2); + businessDocumentOrderMapper.updateById(subOrder); + } + List chainDocIdStrings = chainDocIds.stream().map(String::valueOf).collect(Collectors.toList()); + businessDocumentCargoMultiMapper.update(null, new LambdaUpdateWrapper() + .set(BusinessDocumentCargoMulti::getDelFlag, 2) + .in(BusinessDocumentCargoMulti::getOrderId, chainDocIdStrings) + .eq(BusinessDocumentCargoMulti::getDelFlag, 1)); + businessDocumentAddressMultiMapper.update(null, new LambdaUpdateWrapper() + .set(BusinessDocumentAddressMulti::getDelFlag, 2) + .in(BusinessDocumentAddressMulti::getOrderId, chainDocIdStrings) + .eq(BusinessDocumentAddressMulti::getDelFlag, 1)); + } + // 3. 配送明细链软删: 链的orderId固定指向运输业务单-主单, 按本次命中的主单id清理(含历史周期残留链) + businessDeliveryDetailsLinkService.update(null, new LambdaUpdateWrapper() + .set(BusinessDeliveryDetailsLink::getDelFlag, 2) + .in(BusinessDeliveryDetailsLink::getOrderId, transportOrderIds) + .eq(BusinessDeliveryDetailsLink::getDelFlag, 1)); + } + + /** + * 获取仓库信息(Feign优先, system服务失败/降级时本地跨库兜底), 统一委托共享组件 + */ + private WarehouseFeignPO getWarehouseInfoWithFallback(Long warehouseId) { + return warehouseInfoApplicationService.getWarehouseInfo(warehouseId); + } + + /** + * 获取仓库单号生成规则(下发生成执行单号用): 优先 Feign 调 system 服务; + * Feign 异常/降级/返回非200时回退本地跨库直查 NGWL_TEST_SYSTEM.WAREHOUSE(同库同表, 与 getWarehouseCode 等查询同数据源), + * 避免 system 服务抖动阻断下发; 两侧都取不到才报错并带出 Feign 真实返回原因。 + */ + private WarehouseFeignPO getWarehouseOrderNoRule(Long warehouseId) { + return getWarehouseInfoWithFallback(warehouseId); + } + /** * @description 审核出库单 * @author ZhouGY @@ -521,8 +667,14 @@ public class ReservationStockOutOrderDomainService { if (activeExecutionCount > 0) { throw new ServiceException("出库单[" + inOrderNumber + "]已下发,请勿重复下发;如需重新下发请先取消下发"); } + // 自愈: 历史版本反审/取消下发的归档明细可能仍占用unique_id, 先置空释放键位再重新下发 + releaseArchivedDetailUniqueId(inOrderNumber); List executionInOrderNumbers = new ArrayList<>(); - List materialDetailList = outMaterialDetailService.list(new QueryWrapper().lambda().eq(ReservationOutMaterialDetail::getOutOrderNumber, inOrderNumber)); + // 下发明细必须过滤软删行(del_flag=1):编辑对账软删的旧行仍留表内, + // 不滤会参与按仓库分组/数量汇总,多生成执行单且数量叠加(入库侧同查询已过滤) + List materialDetailList = outMaterialDetailService.list(new QueryWrapper().lambda() + .eq(ReservationOutMaterialDetail::getOutOrderNumber, inOrderNumber) + .eq(ReservationOutMaterialDetail::getDelFlag, 1)); // 按照 warehouseId 分组 Map> materialDetailGroupByWarehouse = materialDetailList.stream() @@ -540,7 +692,6 @@ public class ReservationStockOutOrderDomainService { reservationStockInOrder.setOrderTypeCode("pu_tong_chu_ku"); reservationStockInOrder.setOrderTypeName("普通出库"); reservationStockInOrder.setBusinessType("pu_tong_chu_ku"); - reservationStockInOrder.setReservationOrderSource("客户预约"); reservationStockInOrder.setWarehouseId(warehouseId); reservationStockInOrder.setWarehouseCode(warehouseCode); reservationStockInOrder.setWarehouseName(warehouseName); @@ -556,14 +707,8 @@ public class ReservationStockOutOrderDomainService { reservationStockInOrder.setBusinessOutOrderNumber(inOrderNumber); // reservationStockInOrder.setOutOrderNumber(generateExecutionOrderNumber(warehouseCode)); - //设置单号 - Long warehouseId1 = reservationStockInOrder.getWarehouseId(); - AjaxResult ajaxResult = systemServiceFeign.getWarehouseInfoByWarehouseId(warehouseId1); - if (!"200".equals(String.valueOf(ajaxResult.get("code")))) { - throw new ServiceException("获取仓库信息失败"); - } - //仓库信息 - WarehouseFeignPO warehouseFeignPO = com.alibaba.fastjson.JSON.parseObject(com.alibaba.fastjson2.JSONObject.toJSONString(ajaxResult.get("data")), WarehouseFeignPO.class); + //设置单号(仓库单号规则: Feign优先, system服务失败/降级时本地跨库兜底) + WarehouseFeignPO warehouseFeignPO = getWarehouseOrderNoRule(reservationStockInOrder.getWarehouseId()); String orderNoGenerateRule = warehouseFeignPO.getOrderNoGenerateRule(); String prefix = warehouseFeignPO.getOutOrderNoPrefix(); if ("yang_pin_chu_ku".equals(stockOutOrderDO.getBusinessType())) { @@ -652,6 +797,8 @@ public class ReservationStockOutOrderDomainService { materialDetails.forEach(executionOutMaterialDetail -> { executionOutMaterialDetailService.update(null, new UpdateWrapper().lambda() .set(ExecutionOutMaterialDetail::getDelFlag, 2) + // 归档行置空uniqueId: 明细表唯一约束不含del_flag, 保留原值会与重新下发时从预留明细复制的同一uniqueId撞键 + .set(ExecutionOutMaterialDetail::getUniqueId, null) .eq(ExecutionOutMaterialDetail::getMaterialDetailId, executionOutMaterialDetail.getMaterialDetailId())); }); executionStockOutOrderService.update(null, new UpdateWrapper().lambda() @@ -662,6 +809,129 @@ public class ReservationStockOutOrderDomainService { return update; } + /** + * @description 反审出库业务单(按前端展示字段 issueStatus 判断可反审范围: 2-已审核(未出库) / 4-已出库 均可反审; + * 0-已创建无需反审、3-已驳回可直接编辑; status 字段在出库完成后不一定同步为9, 故不作为判断依据, + * 仅兜底排除 10-已取消/11-已关闭)。 + * 反审将单据回退到已创建(status=1)且审核状态置为已驳回(issueStatus=3, 与入库侧反审同口径, 可编辑→重新审核→重新下发) + * 并打上反审标记: + * WMS 侧按出库单实际状态分支还原库存(已出库: 实物库存还原+推OMS; 未出库: 仅还原分配/冻结占用)、 + * 清理执行单据(出库单/明细/拣货/复核/交接/配送, 软删+reverseFlag=1 划归【已反审】tab)、 + * 每个执行出库单生成1条出库异常记录【反审记录】(out_order_abnormal, abnormalType=3); + * OMS 侧软删执行出库单及明细、软删预约库存调整记录。 + * 反审后单据进入【已反审】页签(status=1 且 reverse_status=1), 可继续编辑/审核/撤销; + * 重新审核通过时 reverse_status 自动复位 0(见 auditState)。 + * @date 2026/9/8 + */ + @Transactional(rollbackFor = Exception.class) + public Boolean reverseAudit(ReservationStockOutOrderDO stockOutOrderDO) { + 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 outOrderIds = stockOutOrderDO.getOutOrderIds(); + if (outOrderIds == null || outOrderIds.isEmpty()) { + throw new ServiceException("请选择需要反审的出库单"); + } + String reverseRemark = stockOutOrderDO.getReverseRemark(); + + for (Long outOrderId : outOrderIds) { + ReservationStockOutOrder byId = stockOutOrderService.getById(outOrderId); + if (byId == null) { + throw new ServiceException("出库单不存在, outOrderId=" + outOrderId); + } + Integer status = byId.getStatus(); + if (status != null && (status == 10 || status == 11)) { + throw new ServiceException("出库单[" + byId.getOutOrderNumber() + "]已取消/已关闭, 不能反审"); + } + // 反审条件按前端展示字段 issueStatus 判断: 2-已审核(未出库) / 4-已出库 均可反审 + Integer issueStatus = byId.getIssueStatus(); + if (!Integer.valueOf(2).equals(issueStatus) && !Integer.valueOf(4).equals(issueStatus)) { + throw new ServiceException("出库单[" + byId.getOutOrderNumber() + "]当前状态(issueStatus=" + issueStatus + + ")不支持反审, 仅已审核/已出库状态可反审"); + } + // 逐个执行出库单调 WMS 反审: 还原实物库存+推送OMS库存、清理WMS单据、生成反审异常记录; + // 任一失败抛异常整体回滚, 避免单边反审 + List executionOrders = executionStockOutOrderService.list(new QueryWrapper().lambda() + .eq(ExecutionStockOutOrder::getBusinessOutOrderNumber, byId.getOutOrderNumber()) + .eq(ExecutionStockOutOrder::getDelFlag, 1)); + for (ExecutionStockOutOrder executionStockOutOrder : executionOrders) { + String executionOutOrderNumber = executionStockOutOrder.getOutOrderNumber(); + StockOutOrder wmsOutOrder = new StockOutOrder(); + wmsOutOrder.setOutOrderNumber(executionOutOrderNumber); + // 反审原因经 remark 透传 WMS, 记入反审异常记录备注 + wmsOutOrder.setRemark("业务单号:" + byId.getOutOrderNumber() + + (reverseRemark != null && !reverseRemark.isEmpty() ? ",反审原因:" + reverseRemark : "")); + AjaxResult wmsResult = wmsServiceFeign.omsReverseExecutionOrder(wmsOutOrder); + if (wmsResult == null || !"200".equals(String.valueOf(wmsResult.get("code")))) { + throw new ServiceException("执行出库单[" + executionOutOrderNumber + "]WMS反审失败:" + + (wmsResult == null ? "WMS服务不可用" : wmsResult.get("msg"))); + } + // 软删执行出库单明细 + 执行出库单(与取消下发 cancelIssueOrder 一致) + List materialDetails = executionOutMaterialDetailService.list(new QueryWrapper().lambda() + .eq(ExecutionOutMaterialDetail::getOutOrderNumber, executionOutOrderNumber) + .eq(ExecutionOutMaterialDetail::getDelFlag, 1)); + materialDetails.forEach(executionOutMaterialDetail -> { + executionOutMaterialDetailService.update(null, new UpdateWrapper().lambda() + .set(ExecutionOutMaterialDetail::getDelFlag, 2) + .set(ExecutionOutMaterialDetail::getReverseFlag, 1) + // 归档行置空uniqueId: 明细表唯一约束不含del_flag, 保留原值会与重新下发时从预留明细复制的同一uniqueId撞键 + .set(ExecutionOutMaterialDetail::getUniqueId, null) + .eq(ExecutionOutMaterialDetail::getMaterialDetailId, executionOutMaterialDetail.getMaterialDetailId())); + }); + executionStockOutOrderService.update(null, new UpdateWrapper().lambda() + .set(ExecutionStockOutOrder::getDelFlag, 2) + .set(ExecutionStockOutOrder::getReverseFlag, 1) + .eq(ExecutionStockOutOrder::getOutOrderNumber, executionOutOrderNumber)); + // 软删预约库存调整记录(下发分配时生成): 仅软删留痕, 库存数量由 WMS omsEdit 推送还原 + inventoryAdjustmentRecordMapper.update(null, new UpdateWrapper().lambda() + .set(ReservationInventoryAdjustmentRecord::getDelFlag, 2) + .eq(ReservationInventoryAdjustmentRecord::getExecutionOrderNumber, executionOutOrderNumber) + .eq(ReservationInventoryAdjustmentRecord::getDelFlag, 1)); + } + // 反审联动: 软删关联运输链路(运输业务单/运输执行单/TMS货源单-运单-作业单), 无关联运输单时跳过 + reverseTransportChain(byId); + } + + // 主单回退到已创建并打反审标记; 更新条件带 issueStatus in (2,4) + 排除已取消/已关闭 兜底防并发重复反审 + // issueStatus 回退到 3-已驳回(前端展示映射: 0-已创建 2-已审核 3-已驳回 4-已出库; 与入库侧反审同口径, + // 已驳回态可编辑→重新审核→重新下发, 重新审核通过时 reverse_status 自动复位 0 离开已反审tab); + // 清空执行出库单号——执行单已随反审软删, 前端"是否执行"列由该字段有无值推导, 不清空会仍显示已执行 + return stockOutOrderService.update(null, new UpdateWrapper().lambda() + .set(ReservationStockOutOrder::getStatus, 1) + .set(ReservationStockOutOrder::getIssueStatus, 3) + .set(ReservationStockOutOrder::getExecutionOutOrderNumber, null) + // 运输业务单已随反审软删, 货源单号一并清空, 重新审核后重建运输链路时自动回填 + .set(ReservationStockOutOrder::getBusinessNumber, null) + .set(ReservationStockOutOrder::getIssueId, null) + .set(ReservationStockOutOrder::getIssueName, null) + .set(ReservationStockOutOrder::getIssueTime, null) + .set(ReservationStockOutOrder::getReservationAuditId, null) + .set(ReservationStockOutOrder::getReservationAuditName, null) + .set(ReservationStockOutOrder::getReservationAuditTime, null) + .set(ReservationStockOutOrder::getAllocationQuantity, BigDecimal.ZERO) + .set(ReservationStockOutOrder::getAlreadyAllocationQuantity, BigDecimal.ZERO) + .set(ReservationStockOutOrder::getPickingQuantity, BigDecimal.ZERO) + .set(ReservationStockOutOrder::getCheckQuantity, BigDecimal.ZERO) + .set(ReservationStockOutOrder::getCheckStatus, 1) + .set(ReservationStockOutOrder::getCheckTaskDistribution, 2) + .set(ReservationStockOutOrder::getCheckTaskDistributionTime, null) + .set(ReservationStockOutOrder::getCompleteTime, null) + .set(ReservationStockOutOrder::getOutboundTime, null) + .set(ReservationStockOutOrder::getReverseStatus, 1) + .set(ReservationStockOutOrder::getReverseBy, loginUser.getUserid()) + .set(ReservationStockOutOrder::getReverseByName, userRealName) + .set(ReservationStockOutOrder::getReverseTime, new Date()) + .set(ReservationStockOutOrder::getReverseRemark, reverseRemark) + .set(ReservationStockOutOrder::getUpdateBy, loginUser.getUserid()) + .set(ReservationStockOutOrder::getUpdateByName, userRealName) + .set(ReservationStockOutOrder::getUpdateTime, new Date()) + .in(ReservationStockOutOrder::getOutOrderId, outOrderIds) + .in(ReservationStockOutOrder::getIssueStatus, 2, 4) + .notIn(ReservationStockOutOrder::getStatus, 10, 11)); + } + @Transactional(rollbackFor = Exception.class) public Boolean executeAndIssue(ReservationStockOutOrderDO stockOutOrderDO) { LoginUser loginUser = SecurityUtils.getLoginUser(); @@ -691,7 +961,13 @@ public class ReservationStockOutOrderDomainService { String warehouseCode1 = byId.getWarehouseCode(); String warehouseName1 = byId.getWarehouseName(); String inOrderNumber = byId.getOutOrderNumber(); - List materialDetailList = outMaterialDetailService.list(new QueryWrapper().lambda().eq(ReservationOutMaterialDetail::getOutOrderNumber, inOrderNumber)); + // 自愈: 历史版本反审/取消下发的归档明细可能仍占用unique_id, 先置空释放键位再重新下发 + releaseArchivedDetailUniqueId(inOrderNumber); + // 下发明细必须过滤软删行(del_flag=1):编辑对账软删的旧行仍留表内, + // 不滤会参与按仓库分组/数量汇总,多生成执行单且数量叠加(入库侧同查询已过滤) + List materialDetailList = outMaterialDetailService.list(new QueryWrapper().lambda() + .eq(ReservationOutMaterialDetail::getOutOrderNumber, inOrderNumber) + .eq(ReservationOutMaterialDetail::getDelFlag, 1)); // 按照 warehouseId 分组 Map> materialDetailGroupByWarehouse = materialDetailList.stream() @@ -755,7 +1031,6 @@ public class ReservationStockOutOrderDomainService { reservationStockInOrder.setOrderTypeCode("pu_tong_chu_ku"); reservationStockInOrder.setOrderTypeName("普通出库"); reservationStockInOrder.setBusinessType("pu_tong_chu_ku"); - reservationStockInOrder.setReservationOrderSource("客户预约"); reservationStockInOrder.setWarehouseId(warehouseId); reservationStockInOrder.setOrganizationId(orgId); reservationStockInOrder.setOrganizationName(orgName); @@ -765,14 +1040,8 @@ public class ReservationStockOutOrderDomainService { reservationStockInOrder.setBusinessOutOrderNumber(inOrderNumber); - //设置单号 -// Long warehouseId1 = reservationStockInOrder.getWarehouseId(); - AjaxResult ajaxResult = systemServiceFeign.getWarehouseInfoByWarehouseId(warehouseId); - if (!"200".equals(String.valueOf(ajaxResult.get("code")))) { - throw new ServiceException("获取仓库信息失败"); - } - //仓库信息 - WarehouseFeignPO warehouseFeignPO = com.alibaba.fastjson.JSON.parseObject(com.alibaba.fastjson2.JSONObject.toJSONString(ajaxResult.get("data")), WarehouseFeignPO.class); + //设置单号(仓库单号规则: Feign优先, system服务失败/降级时本地跨库兜底) + WarehouseFeignPO warehouseFeignPO = getWarehouseOrderNoRule(warehouseId); String orderNoGenerateRule = warehouseFeignPO.getOrderNoGenerateRule(); String prefix = warehouseFeignPO.getOutOrderNoPrefix(); if ("yang_pin_chu_ku".equals(stockOutOrderDO.getBusinessType())) { diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/reserveStockOutOrder/service/ReserveStockOutOrderApplicationService.java b/mhd_oms/src/main/java/com/mhd/oms/domain/reserveStockOutOrder/service/ReserveStockOutOrderApplicationService.java index 210afd106..720c3a76c 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/domain/reserveStockOutOrder/service/ReserveStockOutOrderApplicationService.java +++ b/mhd_oms/src/main/java/com/mhd/oms/domain/reserveStockOutOrder/service/ReserveStockOutOrderApplicationService.java @@ -68,6 +68,8 @@ import java.util.concurrent.ThreadLocalRandom; public class ReserveStockOutOrderApplicationService { @Autowired private ReserveStockOutOrderDomainService stockOutOrderDomainService; + @Autowired + private com.mhd.oms.application.service.WarehouseInfoApplicationService warehouseInfoApplicationService; // @Autowired // private ReserveOutMaterialDetailDomainService outMaterialDetailDomainService; // @Autowired @@ -895,11 +897,8 @@ public class ReserveStockOutOrderApplicationService { if (stockOutOrderDO.getWarehouseId() == null) { throw new ServiceException("仓库ID不能为空"); } - AjaxResult ajaxResult = systemServiceFeign.getWarehouseInfoByWarehouseId(stockOutOrderDO.getWarehouseId()); - if(!"200".equals(String.valueOf(ajaxResult.get("code")))){ - throw new ServiceException("获取仓库信息失败"); - } - WarehouseFeignPO warehouseFeignPO = JSON.parseObject(JSONObject.toJSONString(ajaxResult.get("data")), WarehouseFeignPO.class); + // Feign失败走本地跨库兜底, 避免保存被"获取仓库信息失败"阻断 + WarehouseFeignPO warehouseFeignPO = warehouseInfoApplicationService.getWarehouseInfo(stockOutOrderDO.getWarehouseId()); stockOutOrderDO.setWarehouseCode(warehouseFeignPO.getWarehouseCode()); stockOutOrderDO.setWarehouseName(warehouseFeignPO.getWarehouseName()); } diff --git a/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/ReservationStockOutOrder/ReservationStockOutOrderApi.java b/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/ReservationStockOutOrder/ReservationStockOutOrderApi.java index 28114c62b..ee912d037 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/ReservationStockOutOrder/ReservationStockOutOrderApi.java +++ b/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/ReservationStockOutOrder/ReservationStockOutOrderApi.java @@ -159,6 +159,17 @@ public class ReservationStockOutOrderApi extends BaseController { return AjaxResult.success(stockOutOrderApplicationService.cancelIssueOrder(stockOutOrderDO)); } + /** + * 反审出库单: 已出库/已复核(issueStatus=2已审核)的单据回退到已创建并打反审标记, + * WMS还原实物库存并生成出库异常记录【反审记录】, 单据划归【已反审】页签 + */ + @ApiOperation("反审出库单") + @PostMapping(value = "/reverseAudit") + public AjaxResult reverseAudit(@RequestBody ReservationStockOutOrderDTO stockOutOrderDTO) { + ReservationStockOutOrderDO stockOutOrderDO = stockOutOrderAssembler.toDO(stockOutOrderDTO); + return AjaxResult.success(stockOutOrderApplicationService.reverseAudit(stockOutOrderDO)); + } + @ApiOperation("下发出库单") @PostMapping(value = "/executeAndIssue") public AjaxResult executeAndIssue(@RequestBody ReservationStockOutOrderDTO stockOutOrderDTO) { diff --git a/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/executionInMaterialDetail/ExecutionInMaterialDetailApi.java b/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/executionInMaterialDetail/ExecutionInMaterialDetailApi.java index 56546052e..31cf13e33 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/executionInMaterialDetail/ExecutionInMaterialDetailApi.java +++ b/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/executionInMaterialDetail/ExecutionInMaterialDetailApi.java @@ -3,6 +3,7 @@ package com.mhd.oms.interfaces.facade.executionInMaterialDetail; import com.mhd.common.core.web.controller.BaseController; import com.mhd.common.core.web.domain.AjaxResult; import com.mhd.common.core.web.page.TableDataInfo; +import com.mhd.common.core.utils.poi.ExcelUtil; import com.mhd.oms.domain.executionInMaterialDetail.repository.po.ExecutionInMaterialDetailPO; import com.mhd.oms.domain.executionInMaterialDetail.repository.po.ExecutionInMaterialDetailWithOrderPO; import com.mhd.oms.domain.executionInMaterialDetail.repository.todo.ExecutionInMaterialDetailDO; @@ -16,6 +17,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.net.URLEncoder; import java.util.List; /** @@ -96,4 +99,24 @@ public class ExecutionInMaterialDetailApi extends BaseController { return getDataTable(list); } + /** + * 导出入库明细查询Excel(关联入库执行单,全量不分页; + * SQL固定只统计已入库(5)单据,可按单据类型(如退货入库tui_huo_ru_ku)与实际入仓日期区间过滤) + */ + @ApiOperation("导出入库明细查询Excel") + @GetMapping("/exportWithOrder") + public void exportWithOrder(HttpServletResponse response, ExecutionInMaterialDetailQueryDTO queryDTO) throws Exception + { + //转换实体(不分页,导出全量) + QueryOrderOverStockDO queryDO = inMaterialDetailAssembler.toQueryDO(queryDTO); + List list = inMaterialDetailApplicationService.exportInOrderDetailList(queryDO); + + String fileName = URLEncoder.encode("入库明细查询", "UTF-8").replaceAll("\\+", "%20"); + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); + ExcelUtil util = new ExcelUtil<>(ExecutionInMaterialDetailWithOrderPO.class); + util.exportExcel(response, list, "入库明细查询"); + } + } \ No newline at end of file diff --git a/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/executionOutMaterialDetail/ExecutionOutMaterialDetailApi.java b/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/executionOutMaterialDetail/ExecutionOutMaterialDetailApi.java index dc8e1a808..7ffdd719f 100644 --- a/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/executionOutMaterialDetail/ExecutionOutMaterialDetailApi.java +++ b/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/executionOutMaterialDetail/ExecutionOutMaterialDetailApi.java @@ -2,6 +2,7 @@ package com.mhd.oms.interfaces.facade.executionOutMaterialDetail; import com.mhd.common.core.web.controller.BaseController; import com.mhd.common.core.web.page.TableDataInfo; +import com.mhd.common.core.utils.poi.ExcelUtil; import com.mhd.oms.domain.executionOutMaterialDetail.repository.po.ExecutionOutMaterialDetailWithOrderPO; import com.mhd.oms.domain.executionOutMaterialDetail.repository.todo.ExecutionOutMaterialDetailQueryDTO; import com.mhd.oms.domain.executionOutMaterialDetail.service.ExecutionOutMaterialDetailApplicationService; @@ -14,6 +15,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.net.URLEncoder; import java.util.List; /** @@ -41,4 +44,23 @@ public class ExecutionOutMaterialDetailApi extends BaseController { List list = outMaterialDetailApplicationService.queryOutOrderDetailList(queryDO); return getDataTable(list); } + + /** + * 导出出库明细查询Excel(关联出库执行单,全量不分页; + * SQL固定只统计已出库(9/12/13)单据,可按单据类型与实际出仓日期区间过滤) + */ + @ApiOperation("导出出库明细查询Excel") + @GetMapping("/exportWithOrder") + public void exportWithOrder(HttpServletResponse response, ExecutionOutMaterialDetailQueryDTO queryDTO) throws Exception { + //转换实体(不分页,导出全量) + QueryOrderOverStockDO queryDO = outMaterialDetailAssembler.toQueryDO(queryDTO); + List list = outMaterialDetailApplicationService.queryOutOrderDetailList(queryDO); + + String fileName = URLEncoder.encode("出库明细查询", "UTF-8").replaceAll("\\+", "%20"); + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setCharacterEncoding("utf-8"); + response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); + ExcelUtil util = new ExcelUtil<>(ExecutionOutMaterialDetailWithOrderPO.class); + util.exportExcel(response, list, "出库明细查询"); + } } 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/bootstrap.yml b/mhd_oms/src/main/resources/bootstrap.yml index 542b6bce7..8751e75da 100644 --- a/mhd_oms/src/main/resources/bootstrap.yml +++ b/mhd_oms/src/main/resources/bootstrap.yml @@ -18,15 +18,15 @@ spring: discovery: # server-addr: 127.0.0.1:8848 # 线上测试环境配置 容器名+端口号 -# server-addr: 10.33.0.129:6010 - server-addr: 10.102.192.31:6848 + server-addr: 10.33.0.129:6010 +# server-addr: 10.102.192.31:6848 username: nacos password: manhuoda@2023 config: # server-addr: 127.0.0.1:8848 # 线上测试环境配置 容器名+端口号 -# server-addr: 10.33.0.129:6010 - server-addr: 10.102.192.31:6848 + server-addr: 10.33.0.129:6010 +# server-addr: 10.102.192.31:6848 username: nacos password: manhuoda@2023 #线上正式环境 diff --git a/mhd_oms/src/main/resources/mapper/businessDocumentOrder/BusinessDocumentOrderMapper.xml b/mhd_oms/src/main/resources/mapper/businessDocumentOrder/BusinessDocumentOrderMapper.xml index 7c9037567..e098fac0b 100644 --- a/mhd_oms/src/main/resources/mapper/businessDocumentOrder/BusinessDocumentOrderMapper.xml +++ b/mhd_oms/src/main/resources/mapper/businessDocumentOrder/BusinessDocumentOrderMapper.xml @@ -1278,8 +1278,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" select PUSH_VERIFY from NGWL_TEST_PRODUCT.SYS_ORGANIZATION where ORGANIZATION_ID = #{organizationId} - + SELECT goods_number FROM business_document_order WHERE goods_number LIKE concat(#{prefix}, '%') AND LENGTH(goods_number) <= 12 diff --git a/mhd_oms/src/main/resources/mapper/executeOrder/ExecuteOrderMapper.xml b/mhd_oms/src/main/resources/mapper/executeOrder/ExecuteOrderMapper.xml index f1a46305c..7fef8e674 100644 --- a/mhd_oms/src/main/resources/mapper/executeOrder/ExecuteOrderMapper.xml +++ b/mhd_oms/src/main/resources/mapper/executeOrder/ExecuteOrderMapper.xml @@ -42,6 +42,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + + and eo.DEL_FLAG = #{delFlag} + and eo.DEL_FLAG = 1 + and eo.CREATE_TIME >= #{createStartTime} diff --git a/mhd_oms/src/main/resources/mapper/executionInMaterialDetail/executionInMaterialDetailMapper.xml b/mhd_oms/src/main/resources/mapper/executionInMaterialDetail/executionInMaterialDetailMapper.xml index 66dc5a801..bec732497 100644 --- a/mhd_oms/src/main/resources/mapper/executionInMaterialDetail/executionInMaterialDetailMapper.xml +++ b/mhd_oms/src/main/resources/mapper/executionInMaterialDetail/executionInMaterialDetailMapper.xml @@ -365,6 +365,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + + + @@ -403,12 +407,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" a.single_volume, a.single_gross_weight, a.lot_no, a.drink_date, a.fire_insure_fee, a.unit_price, a.line_num_gw, a.spec_gw, a.unit_gw, a.qty_gw, a.erp_curr_gw, a.erp_price_gw, a.amount_gw, - c.insure_amount, c.goods_type, + c.insure_amount, c.goods_type, c.material_classify_name, b.shipper_id as order_shipper_id, b.shipper_code as order_shipper_code, b.shipper_name as order_shipper_name, + b.order_type_code, + b.order_type_name, b.status as in_order_status, b.audit_status as in_order_audit_status, + b.issue_status as issue_status, b.warehouse_date from execution_in_material_detail a left join execution_stock_in_order b on a.in_order_number = b.in_order_number @@ -450,15 +457,28 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and b.order_type_code = #{inOrderTypeCode} - - and b.status = #{inStatus} + + and b.order_type_code = #{orderTypeCode} + + and b.order_type_name like concat('%', #{orderTypeName}, '%') + + + and b.issue_status = 4 and b.expect_time >= #{inOrderExpectStartTime} and b.expect_time <= #{inOrderExpectEndTime} + + + and date_format(IFNULL(b.warehouse_date, b.create_time), '%Y-%m-%d') >= #{warehouseDateStart} + + + and date_format(IFNULL(b.warehouse_date, b.create_time), '%Y-%m-%d') <= #{warehouseDateEnd} + and a.del_flag = 1 and b.del_flag = 1 diff --git a/mhd_oms/src/main/resources/mapper/executionOutMaterialDetail/ExecutionOutMaterialDetailMapper.xml b/mhd_oms/src/main/resources/mapper/executionOutMaterialDetail/ExecutionOutMaterialDetailMapper.xml index 6f7068f7a..d1ef3d9f6 100644 --- a/mhd_oms/src/main/resources/mapper/executionOutMaterialDetail/ExecutionOutMaterialDetailMapper.xml +++ b/mhd_oms/src/main/resources/mapper/executionOutMaterialDetail/ExecutionOutMaterialDetailMapper.xml @@ -454,6 +454,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" id="OutMaterialDetailWithOrderResult" extends="MaterialDetailResult"> + + + + @@ -495,14 +499,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" a.stock_unit, a.stock_quantity, a.inventory_quantity, a.line_num_gw, a.spec_gw, a.unit_gw, a.qty_gw, a.erp_curr_gw, a.erp_price_gw, a.amount_gw, a.in_order_number_gw, a.in_line_num_gw, - c.insure_amount, c.goods_type, + c.insure_amount, c.goods_type, c.material_classify_name, b.shipper_id as order_shipper_id, b.shipper_code as order_shipper_code, b.shipper_name as order_shipper_name, + b.order_type_code, + b.order_type_name, b.OUTBOUND_DATE as order_outbound_date, b.OUTBOUND_TIME as order_outbound_time, b.status as out_order_status, - b.audit_status as out_order_audit_status + b.audit_status as out_order_audit_status, + b.issue_status as issue_status from execution_out_material_detail a left join execution_stock_out_order b on a.out_order_number = b.out_order_number left join NGWL_TEST_WMS.material_base_info c on a.material_base_info_id = c.material_base_info_id @@ -543,15 +550,28 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and b.order_type_code = #{outOrderTypeCode} - - and b.status = #{outStatus} + + and b.order_type_code = #{orderTypeCode} + + and b.order_type_name like concat('%', #{orderTypeName}, '%') + + + and b.issue_status = 4 and b.expect_time >= #{outOrderExpectStartTime} and b.expect_time <= #{outOrderExpectEndTime} + + + and date_format(b.OUTBOUND_DATE, '%Y-%m-%d') >= #{outboundDateStart} + + + and date_format(b.OUTBOUND_DATE, '%Y-%m-%d') <= #{outboundDateEnd} + and a.del_flag = 1 and b.del_flag = 1 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/executionStockOutOrder/ExecutionStockOutOrderMapper.xml b/mhd_oms/src/main/resources/mapper/executionStockOutOrder/ExecutionStockOutOrderMapper.xml index 631d9f187..ced13d638 100644 --- a/mhd_oms/src/main/resources/mapper/executionStockOutOrder/ExecutionStockOutOrderMapper.xml +++ b/mhd_oms/src/main/resources/mapper/executionStockOutOrder/ExecutionStockOutOrderMapper.xml @@ -52,6 +52,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + @@ -127,7 +128,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" a.cancel_time, a.close_order, a.close_remark, a.close_by, a.close_by_name, a.close_time, a.check_status,a.BUSINESS_ORDER_NO, a.check_task_distribution, a.check_task_distribution_time, a.check_operators_by, a.check_operators_name, a.mobilize_code, a.remark, a.create_time, a.create_by, a.create_by_name,a.business_number,a.train_no,a.amount,a.business_out_order_number, - a.update_time, a.update_by, a.update_by_name, a.del_flag, a.over_stock_id, a.over_stock_status, a.over_stock_type,a."TO", + a.update_time, a.update_by, a.update_by_name, a.del_flag, a.reverse_flag, a.over_stock_id, a.over_stock_status, a.over_stock_type,a."TO", a.CONTACT_PERSON,a.VEHICLE_MODEL_PLATE,a.ENTRUST_NO,a.TEL,a.DRIVER_SIGN,a.FAX,a.DECLARE_CUSTOMS,a.MANUFACTURER, a.CUSTOMS_DECLARER_INFO,a.DELIVERY_ADDR,a.ENTRY_EXIT_CUSTOMS,a.DEPARTURE_ARRIVAL_COUNTRY,a.CARRIER,a.CONTAINER_NO,a.CONTAINER_NO_NAME,a.OUTBOUND_DATE, a.COMPLETE_TIME,a.ORDER_DATE,a.TRANSPORT_MODE_CODE,a.TRANSPORT_MODE_NAME,a.SUPERVISION_MODE_CODE,a.SUPERVISION_MODE_NAME, @@ -401,6 +402,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and a.del_flag = #{delFlag} and a.del_flag = 1 + + and a.reverse_flag = #{reverseFlag} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + UPDATE out_material_detail diff --git a/mhd_wms/src/main/resources/mapper/handoverTaskOrder/HandoverTaskOrderMapper.xml b/mhd_wms/src/main/resources/mapper/handoverTaskOrder/HandoverTaskOrderMapper.xml index 197871c3d..e01a2e528 100644 --- a/mhd_wms/src/main/resources/mapper/handoverTaskOrder/HandoverTaskOrderMapper.xml +++ b/mhd_wms/src/main/resources/mapper/handoverTaskOrder/HandoverTaskOrderMapper.xml @@ -39,6 +39,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + @@ -49,7 +50,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 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.order_type_code, a.order_type_name, a.expect_time, a.warehouse_id, a.warehouse_code, a.warehouse_name, a.shipper_id, a.shipper_name, a.order_number, a.picking_order_number, a.remark, a.task_distribution, a.task_distribution_time, a.create_time, a.create_by, a.create_by_name, a.update_time, - a.update_by, a.update_by_name, a.del_flag, a.picture_app,a.billing_json + a.update_by, a.update_by_name, a.del_flag, a.reverse_flag, a.picture_app,a.billing_json @@ -138,6 +139,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and a.del_flag = #{delFlag} and a.del_flag = 1 + + and a.reverse_flag = #{reverseFlag} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -112,7 +111,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" from out_order_abnormal a - left join stock_out_order b on a.out_order_number = b.out_order_number and b.del_flag = 1 + + left join stock_out_order b on a.out_order_number = b.out_order_number diff --git a/mhd_wms/src/main/resources/mapper/pickingMaterialDetail/PickingMaterialDetailMapper.xml b/mhd_wms/src/main/resources/mapper/pickingMaterialDetail/PickingMaterialDetailMapper.xml index 4aa6ac0a8..7e1aae9ee 100644 --- a/mhd_wms/src/main/resources/mapper/pickingMaterialDetail/PickingMaterialDetailMapper.xml +++ b/mhd_wms/src/main/resources/mapper/pickingMaterialDetail/PickingMaterialDetailMapper.xml @@ -248,6 +248,21 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" AND b.DEL_FLAG = 1 + + + + + + + + + + + + + + + + + + + @@ -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 + + @@ -152,7 +167,22 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" from stock_receipt_order a - LEFT JOIN stock_in_order b ON a.in_order_number = b.in_order_number and a.DEL_FLAG = 1 and b.DEL_FLAG = 1 + + LEFT JOIN stock_in_order b ON a.in_order_number = b.in_order_number + + + and a.DEL_FLAG = 2 and b.DEL_FLAG = 2 + + and b.IN_ORDER_ID = (select max(c.IN_ORDER_ID) from stock_in_order c + where c.IN_ORDER_NUMBER = a.in_order_number and c.DEL_FLAG = 2) + + + and a.DEL_FLAG = 1 and b.DEL_FLAG = 1 + and b.IN_ORDER_ID = (select max(c.IN_ORDER_ID) from stock_in_order c + where c.IN_ORDER_NUMBER = a.in_order_number and c.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..3b468716c 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 + + @@ -143,7 +158,22 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" from stock_shelf_order a - LEFT JOIN stock_in_order b ON a.in_order_number = b.in_order_number and a.DEL_FLAG = 1 and b.DEL_FLAG = 1 + + LEFT JOIN stock_in_order b ON a.in_order_number = b.in_order_number + + + and a.DEL_FLAG = 2 and b.DEL_FLAG = 2 + + and b.IN_ORDER_ID = (select max(c.IN_ORDER_ID) from stock_in_order c + where c.IN_ORDER_NUMBER = a.in_order_number and c.DEL_FLAG = 2) + + + and a.DEL_FLAG = 1 and b.DEL_FLAG = 1 + and b.IN_ORDER_ID = (select max(c.IN_ORDER_ID) from stock_in_order c + where c.IN_ORDER_NUMBER = a.in_order_number and c.DEL_FLAG = 1) + + diff --git a/sql/20260908_alter_table_szwl_oms_reservation_stock_out_order_reverse.sql b/sql/20260908_alter_table_szwl_oms_reservation_stock_out_order_reverse.sql new file mode 100644 index 000000000..848ef6b67 --- /dev/null +++ b/sql/20260908_alter_table_szwl_oms_reservation_stock_out_order_reverse.sql @@ -0,0 +1,28 @@ +-- ===================================================================== +-- 出库业务单反审功能 —— OMS 出库业务单加反审字段 +-- 日期: 2026-09-08 +-- 数据库: 达梦(DM), 兼容 Oracle 语法 +-- 背景: +-- 已出库/已复核的出库业务单客户通知需要回退时, 点击【反审单据】回退到已创建, +-- 数据划归到出库单【已反审】tab; WMS 还原实物库存并生成出库异常记录【反审记录】。 +-- 设计说明: +-- REVERSE_STATUS 反审状态: 0-无(默认) 1-已反审。 +-- 反审后主单 status 回退为 1(已创建) 且 REVERSE_STATUS=1, +-- 【已反审】页签查询: 前端传 status=-2 (后端解析为 status=1 and reverse_status=1); +-- 【已创建】页签排除 REVERSE_STATUS=1, 保证页签互斥; +-- 重新审核通过时后端自动将 REVERSE_STATUS 复位为 0, 单据回到正常流转。 +-- 反审校验: status in (9,12) 且 issueStatus in (2-已审核,4-已出库)。 +-- 关联脚本: 20260908_reverse_flag_out_order_reverse_audit.sql(执行单/WMS单据反审标记) +-- ===================================================================== + +-- ============ 一、OMS 业务单 RESERVATION_STOCK_OUT_ORDER ============ +ALTER TABLE "NGWL_TEST_OMS"."RESERVATION_STOCK_OUT_ORDER" ADD COLUMN REVERSE_STATUS NUMBER(1) DEFAULT 0; +COMMENT ON COLUMN "NGWL_TEST_OMS"."RESERVATION_STOCK_OUT_ORDER".REVERSE_STATUS IS '反审状态: 0-无 1-已反审(已反审tab过滤,重新审核通过自动复位0)'; +ALTER TABLE "NGWL_TEST_OMS"."RESERVATION_STOCK_OUT_ORDER" ADD COLUMN REVERSE_REMARK VARCHAR2(500); +COMMENT ON COLUMN "NGWL_TEST_OMS"."RESERVATION_STOCK_OUT_ORDER".REVERSE_REMARK IS '反审原因'; +ALTER TABLE "NGWL_TEST_OMS"."RESERVATION_STOCK_OUT_ORDER" ADD COLUMN REVERSE_BY NUMBER(20); +COMMENT ON COLUMN "NGWL_TEST_OMS"."RESERVATION_STOCK_OUT_ORDER".REVERSE_BY IS '反审人id'; +ALTER TABLE "NGWL_TEST_OMS"."RESERVATION_STOCK_OUT_ORDER" ADD COLUMN REVERSE_BY_NAME VARCHAR2(64); +COMMENT ON COLUMN "NGWL_TEST_OMS"."RESERVATION_STOCK_OUT_ORDER".REVERSE_BY_NAME IS '反审人姓名'; +ALTER TABLE "NGWL_TEST_OMS"."RESERVATION_STOCK_OUT_ORDER" ADD COLUMN REVERSE_TIME DATE; +COMMENT ON COLUMN "NGWL_TEST_OMS"."RESERVATION_STOCK_OUT_ORDER".REVERSE_TIME IS '反审时间'; 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 同时发布。 +-- ============================================================================= diff --git a/sql/20260908_reverse_flag_out_order_reverse_audit.sql b/sql/20260908_reverse_flag_out_order_reverse_audit.sql new file mode 100644 index 000000000..1f6929ac2 --- /dev/null +++ b/sql/20260908_reverse_flag_out_order_reverse_audit.sql @@ -0,0 +1,55 @@ +-- ===================================================================== +-- 出库业务单反审功能 —— 下游单据反审标记(软删留痕, 已反审tab过滤) +-- 日期: 2026-09-08 +-- 数据库: 达梦(DM), 兼容 Oracle 语法 +-- 背景: +-- 出库业务单反审时, 下游单据(OMS执行出库单/明细、WMS出库单/明细、WMS拣货单/明细、 +-- WMS复核单/明细、WMS出库交接单)"软删+打已反审标记", +-- 数据划归到 W出库单/W拣货单/W复核单/W出库交接单 各列表【已反审】tab +-- (查询条件 delFlag=2 and reverseFlag=1)作记录跟踪; +-- 业务单重新下发时生成全新的执行单+WMS单(旧单保留在已反审tab)。 +-- 设计说明: +-- REVERSE_FLAG 反审标记: 0-无(默认) 1-已反审。 +-- 反审即软删(del_flag=2), 各列表常规查询 del_flag=1 天然排除已反审单据; +-- 【已反审】tab 显式传 delFlag=2 + reverseFlag=1, 与真删数据互斥。 +-- 反审同时生成 WMS 出库异常记录【反审记录】(out_order_abnormal.ABNORMAL_TYPE=3)。 +-- 关联脚本: 20260908_alter_table_szwl_oms_reservation_stock_out_order_reverse.sql(业务单反审字段) +-- 注意: 列名与入库侧 REVERSE_AUDIT_* 不同(出库后端代码已按 REVERSE_FLAG 落地), +-- 如需统一命名需联动改出库后端约30个文件。 +-- ===================================================================== + +-- ============ 一、OMS 执行出库单 EXECUTION_STOCK_OUT_ORDER ============ +ALTER TABLE "NGWL_TEST_OMS"."EXECUTION_STOCK_OUT_ORDER" ADD COLUMN REVERSE_FLAG NUMBER(1) DEFAULT 0; +COMMENT ON COLUMN "NGWL_TEST_OMS"."EXECUTION_STOCK_OUT_ORDER".REVERSE_FLAG IS '反审标记: 0-无 1-已反审(业务单反审时软删del_flag=2并打标记)'; + +-- ============ 二、OMS 执行出库明细 EXECUTION_OUT_MATERIAL_DETAIL ============ +ALTER TABLE "NGWL_TEST_OMS"."EXECUTION_OUT_MATERIAL_DETAIL" ADD COLUMN REVERSE_FLAG NUMBER(1) DEFAULT 0; +COMMENT ON COLUMN "NGWL_TEST_OMS"."EXECUTION_OUT_MATERIAL_DETAIL".REVERSE_FLAG IS '反审标记: 0-无 1-已反审(随执行单反审软删时打标记)'; + +-- ============ 三、WMS 出库单 STOCK_OUT_ORDER ============ +ALTER TABLE "NGWL_TEST_WMS"."STOCK_OUT_ORDER" ADD COLUMN REVERSE_FLAG NUMBER(1) DEFAULT 0; +COMMENT ON COLUMN "NGWL_TEST_WMS"."STOCK_OUT_ORDER".REVERSE_FLAG IS '反审标记: 0-无 1-已反审(已反审tab过滤: del_flag=2 and reverse_flag=1)'; + +-- ============ 四、WMS 出库明细 OUT_MATERIAL_DETAIL ============ +ALTER TABLE "NGWL_TEST_WMS"."OUT_MATERIAL_DETAIL" ADD COLUMN REVERSE_FLAG NUMBER(1) DEFAULT 0; +COMMENT ON COLUMN "NGWL_TEST_WMS"."OUT_MATERIAL_DETAIL".REVERSE_FLAG IS '反审标记: 0-无 1-已反审(随出库单反审软删时打标记)'; + +-- ============ 五、WMS 拣货单 PICKING_ORDER ============ +ALTER TABLE "NGWL_TEST_WMS"."PICKING_ORDER" ADD COLUMN REVERSE_FLAG NUMBER(1) DEFAULT 0; +COMMENT ON COLUMN "NGWL_TEST_WMS"."PICKING_ORDER".REVERSE_FLAG IS '反审标记: 0-无 1-已反审(已反审tab过滤: del_flag=2 and reverse_flag=1)'; + +-- ============ 六、WMS 拣货明细 PICKING_MATERIAL_DETAIL ============ +ALTER TABLE "NGWL_TEST_WMS"."PICKING_MATERIAL_DETAIL" ADD COLUMN REVERSE_FLAG NUMBER(1) DEFAULT 0; +COMMENT ON COLUMN "NGWL_TEST_WMS"."PICKING_MATERIAL_DETAIL".REVERSE_FLAG IS '反审标记: 0-无 1-已反审(随拣货单反审软删时打标记)'; + +-- ============ 七、WMS 复核单 REVIEW_ORDER ============ +ALTER TABLE "NGWL_TEST_WMS"."REVIEW_ORDER" ADD COLUMN REVERSE_FLAG NUMBER(1) DEFAULT 0; +COMMENT ON COLUMN "NGWL_TEST_WMS"."REVIEW_ORDER".REVERSE_FLAG IS '反审标记: 0-无 1-已反审(已反审tab过滤: del_flag=2 and reverse_flag=1)'; + +-- ============ 八、WMS 复核明细 REVIEW_MATERIAL_DETAIL ============ +ALTER TABLE "NGWL_TEST_WMS"."REVIEW_MATERIAL_DETAIL" ADD COLUMN REVERSE_FLAG NUMBER(1) DEFAULT 0; +COMMENT ON COLUMN "NGWL_TEST_WMS"."REVIEW_MATERIAL_DETAIL".REVERSE_FLAG IS '反审标记: 0-无 1-已反审(随复核单反审软删时打标记)'; + +-- ============ 九、WMS 出库交接单 HANDOVER_TASK_ORDER ============ +ALTER TABLE "NGWL_TEST_WMS"."HANDOVER_TASK_ORDER" ADD COLUMN REVERSE_FLAG NUMBER(1) DEFAULT 0; +COMMENT ON COLUMN "NGWL_TEST_WMS"."HANDOVER_TASK_ORDER".REVERSE_FLAG IS '反审标记: 0-无 1-已反审(已反审tab过滤: del_flag=2 and reverse_flag=1)';