feat(oms,wms): 入库业务单反审——业务单改已驳回+已反审tab,执行单/W入库/收货/上架软删打标归档,库存还原扣减,W入库异常反审记录
【需求】已入库/已出库的单子客户通知需要回退的场景,单子回退到最原始状态。反审入口在 OMS-入库业务单页面【反審單據】按钮,一次操作全链路回退。
【反审规则】
1. 按页面状态 issueStatus 判断:进行中(1)/已审核(2)/已入库(4)/部分完成(5) 可反审;已创建(0)无需反审、已驳回(3)可直接编辑;已取消/已关闭(status 6/7)兜底拦截
2. 已推送关务/NC(pushStatus=3)直接拦截,避免关务与仓内数据不一致
3. W入库单有出库记录就不能反审:按入库单号+动作(分配库存/出库)查询库存调整记录>0 即拦截,另校验库存冻结量>0
4. WMS无该单数据时幂等成功(未下发单反审),反审失败可安全重试
【反审动作】
1. 入库业务单:状态改为已驳回(issueStatus=3,与审核不通过同语义,可编辑→重新审核→重新下发),打已反审标记落入【已反审】tab;清空入库数量/入库时间/执行单号,明细 INBOUND_ITEMS/TOTAL_NET_WEIGHT 归零
2. 入库执行单+物料明细:软删(del_flag=2)+打已反审标记,【已反审】tab 按「已软删+已反审」查询归档数据,避免归档单被误审核/下发
3. WMS侧(逐执行单Feign omsReverseInOrder):库存还原扣减(校验库存行合计=已完成上架量后整行对称扣回,GREATEST(x-n,0)兜底)→ W入库单/W收货单/W上架单及明细、收货/上架作业单/任务/质检单整链软删+打已反审标记 → 写1条入库异常【反审记录】(type=3/abnormalType=6,FSYC单号)用于记录跟踪
【接口】
- POST /reservationStockInOrderApi/reverseAudit 反审(inOrderIds + reverseAuditRemark,支持批量)
- 已反审tab:/reservationStockInOrderApi/list?reverseAuditStatus=1(执行单/W入库单/W收货单/W上架单同参数,后端固定限定 del_flag=2+标记=1 归档数据)
- 归档详情:/executionStockInOrderApi、/stockInOrderApi、/stockReceiptOrderApi、/stockShelfOrderApi 各增 getReverseAuditInfo/{id}(原 getInfo 行为不变)
- 反审记录筛选:/inOrderAbnormalApi/list?abnormalType=6
【DDL】sql/20260908_oms_inbound_reverse_audit.sql:RESERVATION_STOCK_IN_ORDER / EXECUTION_STOCK_IN_ORDER / STOCK_IN_ORDER / STOCK_RECEIPT_ORDER / STOCK_SHELF_ORDER 各新增 REVERSE_AUDIT_STATUS/REMARK/BY/BY_NAME/TIME 五列,发服务前先执行
【其他】
- 库存扣减走 batchSubtractInventoryQuantity 并显式传更新人,规避 Feign 链路无登录态时 SecurityUtils 抛异常
- omsReverseInOrder 的 Feign 方法与降级已随出库反审提交(715883f1)入库,本次不再重复提交
- 归档行只读,详情走 getReverseAuditInfo;正常数据与归档数据互不干扰
This commit is contained in:
+17
@@ -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;
|
||||
}
|
||||
+17
@@ -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;
|
||||
}
|
||||
+17
@@ -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;
|
||||
}
|
||||
+17
@@ -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;
|
||||
}
|
||||
+18
-1
@@ -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<ExecutionInMaterialDetailPO> materialDetailList = info.getMaterialDetailList();
|
||||
@@ -276,6 +285,14 @@ public class ExecutionStockInOrderApplicationService {
|
||||
return info;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询入库执行单【已反审】tab 归档详情(已软删+已反审标记的数据,含软删明细)
|
||||
*/
|
||||
public ExecutionStockInOrderPO getReverseAuditInfo(Long inOrderId)
|
||||
{
|
||||
return getInfo(inOrderId, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
+17
@@ -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<BusinessDocumentOrder> businessDocumentOrders = businessDocumentOrderMapper.selectList(new LambdaQueryWrapper<BusinessDocumentOrder>().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<ExecutionInMaterialDetailPO> inMaterialDetailPOList = materialDetailService.queryList(inMaterialDetailDO);
|
||||
|
||||
// 先通过入库单号查询收货单列表
|
||||
|
||||
+17
@@ -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;
|
||||
}
|
||||
+17
@@ -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;
|
||||
}
|
||||
+17
@@ -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;
|
||||
}
|
||||
+17
@@ -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;
|
||||
}
|
||||
+10
-2
@@ -282,8 +282,7 @@ public class ReservationStockInOrderApplicationService {
|
||||
* @return Boolean
|
||||
*/
|
||||
public Boolean auditState(ReservationStockInOrderDO stockInOrderDO){
|
||||
Boolean b = stockInOrderDomainService.auditState(stockInOrderDO);
|
||||
// List<Long> inOrderIds = stockInOrderDO.getInOrderIds();
|
||||
Boolean b = stockInOrderDomainService.auditState(stockInOrderDO);// List<Long> 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
|
||||
|
||||
+162
@@ -13,6 +13,9 @@ import com.mhd.common.core.web.domain.AjaxResult;
|
||||
import com.mhd.common.security.utils.SecurityUtils;
|
||||
import com.mhd.oms.domain.businessDocumentOrder.entity.BusinessDocumentOrder;
|
||||
import com.mhd.oms.domain.businessDocumentOrder.repository.mapper.BusinessDocumentOrderMapper;
|
||||
import com.mhd.oms.domain.electronicSignature.entity.ElectronicSignature;
|
||||
import com.mhd.oms.domain.electronicSignature.repository.facade.IElectronicSignatureMaterialDetailService;
|
||||
import com.mhd.oms.domain.electronicSignature.repository.facade.IElectronicSignatureService;
|
||||
import com.mhd.oms.domain.executionInMaterialDetail.entity.ExecutionInMaterialDetail;
|
||||
import com.mhd.oms.domain.executionInMaterialDetail.repository.facade.IExecutionInMaterialDetailService;
|
||||
import com.mhd.oms.domain.executionStockInOrder.entity.ExecutionStockInOrder;
|
||||
@@ -91,6 +94,10 @@ public class ReservationStockInOrderDomainService {
|
||||
private ExecutionStockInOrderMapper executionStockInOrderMapper;
|
||||
@Autowired
|
||||
private ReserveStockInOrderMapper reserveStockInOrderMapper;
|
||||
@Autowired
|
||||
private IElectronicSignatureService electronicSignatureService;
|
||||
@Autowired
|
||||
private IElectronicSignatureMaterialDetailService electronicSignatureMaterialDetailService;
|
||||
|
||||
/**
|
||||
* 分页查询入库单列表
|
||||
@@ -767,6 +774,161 @@ public class ReservationStockInOrderDomainService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 反审入库业务单(需求:已入库/已出库的单子客户通知需要回退的场景,单子回退到最原始状态):
|
||||
* 页面状态列按 issueStatus(0-已创建 1-进行中 2-已审核 3-已驳回 4-已入库 5-部分完成)展示,
|
||||
* 反审条件按 issueStatus 判断——进行中(1)/已审核(2)/已入库(4)/部分完成(5)可反审,
|
||||
* 已创建(0)无需反审、已驳回(3)可直接编辑;已取消/已关闭(status 6/7)兜底拦截。
|
||||
* 反审动作("审核不通过"同语义 + 全链路回退,补齐 auditState 审核不通过缺失的下游联动):
|
||||
* <ul>
|
||||
* <li>业务单状态改为"已驳回"(issueStatus=3),打已反审标记(REVERSE_AUDIT_STATUS=1)落入【已反审】tab,
|
||||
* 之后可「编辑」→重新「审核」→重新「下发」生成全新执行单</li>
|
||||
* <li>入库执行单+物料明细软删(del_flag=2)并打已反审标记——执行单【已反审】tab按
|
||||
* "已软删+已反审"查询归档数据;软删后不出现在正常tab,避免归档单被误「审核/下发」</li>
|
||||
* <li>清空WMS完成上架跨库回写的完成数据(业务单 IN_QUANTITY/STORAGE_TIME、明细 INBOUND_ITEMS/TOTAL_NET_WEIGHT)</li>
|
||||
* <li>WMS侧逐执行单回退(omsReverseInOrder):W入库单有出库记录则拦截(按入库单号+动作"分配库存/出库"
|
||||
* 查库存调整记录>0)→ 库存还原扣减 → W入库单/W收货单/W上架单整链软删并打已反审标记
|
||||
* (数据划归W入库单/W收货单/W上架单【已反审】tab归档)→
|
||||
* 写1条W入库异常【反审记录】用于记录跟踪</li>
|
||||
* </ul>
|
||||
* 已推送关务(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<Long> 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<ExecutionStockInOrder> executionOrders = executionStockInOrderService.list(
|
||||
new LambdaQueryWrapper<ExecutionStockInOrder>()
|
||||
.eq(ExecutionStockInOrder::getBusinessInOrderNumber, businessNumber)
|
||||
.eq(ExecutionStockInOrder::getDelFlag, 1));
|
||||
for (ExecutionStockInOrder executionOrder : executionOrders) {
|
||||
String executionNumber = executionOrder.getInOrderNumber();
|
||||
if (executionOrder.getPushStatus() != null && executionOrder.getPushStatus() == 3) {
|
||||
throw new ServiceException("执行入库单[" + executionNumber + "]已推送关务/NC,无法反审,请先在关务侧处理");
|
||||
}
|
||||
//WMS侧回退(对称收货/上架完成链路,见 WMS StockInOrderDomainService.reverseExecutionOrder):
|
||||
//有出库/库存已被分配时WMS报错,此处抛错整体回滚;WMS无数据时幂等成功(未下发执行单反审)
|
||||
StockInOrder reverseParam = new StockInOrder();
|
||||
reverseParam.setInOrderNumber(executionNumber);
|
||||
reverseParam.setRemark("业务单号:" + businessNumber
|
||||
+ (StringUtils.isNotEmpty(stockInOrderDO.getReverseAuditRemark())
|
||||
? ",反审原因:" + stockInOrderDO.getReverseAuditRemark() : ""));
|
||||
reverseParam.setUpdateBy(loginUser.getUserid());
|
||||
reverseParam.setUpdateByName(userRealName);
|
||||
AjaxResult reverseResult = wmsServiceFeign.omsReverseInOrder(reverseParam);
|
||||
if (reverseResult == null || !"200".equals(String.valueOf(reverseResult.get("code")))) {
|
||||
throw new ServiceException("反审失败:执行入库单[" + executionNumber + "]WMS回退失败:"
|
||||
+ (reverseResult == null ? "WMS服务不可用或已降级" : reverseResult.get("msg")));
|
||||
}
|
||||
//清理下发自动审核生成的待签名电子签名记录(signatureStatus=1,已签名记录保留作凭证)
|
||||
cancelPendingSignature(executionNumber);
|
||||
//执行单+物料明细软删(del_flag=2)并打已反审标记:
|
||||
//执行单【已反审】tab按"已软删+已反审"(del_flag=2 and REVERSE_AUDIT_STATUS=1)查询归档数据;
|
||||
//软删后不出现在正常tab,避免归档单被误「审核/下发」;业务单重新下发时生成全新执行单
|
||||
executionInMaterialDetailService.update(new UpdateWrapper<ExecutionInMaterialDetail>().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<ExecutionStockInOrder>().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<ReservationInMaterialDetail>().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<ReservationStockInOrder>().lambda()
|
||||
.set(ReservationStockInOrder::getIssueStatus, 3)
|
||||
.set(ReservationStockInOrder::getInQuantity, BigDecimal.ZERO)
|
||||
.set(ReservationStockInOrder::getStorageTime, null)
|
||||
.set(ReservationStockInOrder::getExecutionInOrderNumber, null)
|
||||
//反审标记与反审痕迹(【已反审】tab 按 reverseAuditStatus=1 过滤;业务单本身不软删,保持可编辑重新下发)
|
||||
.set(ReservationStockInOrder::getReverseAuditStatus, 1)
|
||||
.set(ReservationStockInOrder::getReverseAuditRemark, stockInOrderDO.getReverseAuditRemark())
|
||||
.set(ReservationStockInOrder::getReverseAuditBy, loginUser.getUserid())
|
||||
.set(ReservationStockInOrder::getReverseAuditByName, userRealName)
|
||||
.set(ReservationStockInOrder::getReverseAuditTime, now)
|
||||
.set(ReservationStockInOrder::getUpdateBy, loginUser.getUserid())
|
||||
.set(ReservationStockInOrder::getUpdateByName, userRealName)
|
||||
.set(ReservationStockInOrder::getUpdateTime, now)
|
||||
.in(ReservationStockInOrder::getInOrderId, inOrderIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 反审时清理下发自动审核生成的待签名电子签名记录(signatureStatus=1)及其明细,
|
||||
* 已签名记录保留作凭证;清理失败仅记日志不阻断反审主流程(同取消下发)
|
||||
*/
|
||||
private void cancelPendingSignature(String inOrderNumber) {
|
||||
try {
|
||||
List<ElectronicSignature> signatures = electronicSignatureService.list(
|
||||
new LambdaQueryWrapper<ElectronicSignature>()
|
||||
.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<ElectronicSignature>().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 有值表示已下发/执行过。
|
||||
|
||||
+10
@@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
* 导入入库单
|
||||
*/
|
||||
|
||||
+13
@@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
* 下发入库单
|
||||
*/
|
||||
|
||||
+19
-4
@@ -108,6 +108,11 @@
|
||||
<result property="discount" column="DISCOUNT" />
|
||||
<result property="isFreeManpowerFee" column="IS_FREE_MANPOWER_FEE" />
|
||||
<result property="businessInOrderNumber" column="BUSINESS_IN_ORDER_NUMBER" />
|
||||
<result property="reverseAuditStatus" column="REVERSE_AUDIT_STATUS" />
|
||||
<result property="reverseAuditRemark" column="REVERSE_AUDIT_REMARK" />
|
||||
<result property="reverseAuditBy" column="REVERSE_AUDIT_BY" />
|
||||
<result property="reverseAuditByName" column="REVERSE_AUDIT_BY_NAME" />
|
||||
<result property="reverseAuditTime" column="REVERSE_AUDIT_TIME" />
|
||||
</resultMap>
|
||||
|
||||
|
||||
@@ -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
|
||||
</sql>
|
||||
|
||||
<sql id="joinStockInOrderPo">
|
||||
@@ -288,7 +294,7 @@
|
||||
and a.order_type_code = #{orderTypeCode}
|
||||
</if>
|
||||
<if test="orderTypeName != null and orderTypeName != ''">
|
||||
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}, '%'))
|
||||
</if>
|
||||
<if test="supplierId != null ">
|
||||
and a.supplier_id = #{supplierId}
|
||||
@@ -501,9 +507,18 @@
|
||||
</if>
|
||||
)
|
||||
</if>
|
||||
<!-- 反审状态过滤:入库执行单【已反审】tab 传 reverseAuditStatus=1,查询已软删且打反审标记的归档数据 -->
|
||||
<choose>
|
||||
<when test="delFlag != null"> and a.del_flag = #{delFlag} </when>
|
||||
<otherwise> and a.del_flag = 1 </otherwise>
|
||||
<when test="reverseAuditStatus != null">
|
||||
and a.REVERSE_AUDIT_STATUS = #{reverseAuditStatus}
|
||||
and a.del_flag = 2
|
||||
</when>
|
||||
<otherwise>
|
||||
<choose>
|
||||
<when test="delFlag != null"> and a.del_flag = #{delFlag} </when>
|
||||
<otherwise> and a.del_flag = 1 </otherwise>
|
||||
</choose>
|
||||
</otherwise>
|
||||
</choose>
|
||||
</sql>
|
||||
|
||||
|
||||
+13
-3
@@ -109,6 +109,11 @@
|
||||
<result property="discount" column="DISCOUNT" />
|
||||
<result property="isFreeManpowerFee" column="IS_FREE_MANPOWER_FEE" />
|
||||
<result property="executionInOrderNumber" column="EXECUTION_IN_ORDER_NUMBER" />
|
||||
<result property="reverseAuditStatus" column="REVERSE_AUDIT_STATUS" />
|
||||
<result property="reverseAuditRemark" column="REVERSE_AUDIT_REMARK" />
|
||||
<result property="reverseAuditBy" column="REVERSE_AUDIT_BY" />
|
||||
<result property="reverseAuditByName" column="REVERSE_AUDIT_BY_NAME" />
|
||||
<result property="reverseAuditTime" column="REVERSE_AUDIT_TIME" />
|
||||
<!-- 饮用有效日期:queryList联查明细表聚合带出,其他查询无此列时不填充 -->
|
||||
<result property="drinkDate" column="drink_date" />
|
||||
</resultMap>
|
||||
@@ -155,7 +160,8 @@
|
||||
a.WAREHOUSE_DATE, a.COMPLETION_TIME, a.ORDER_DATE,a.reservation_audit_time,a.reservation_audit_name
|
||||
,a.reservation_audit_id,a.issue_name,a.issue_id,a.issue_time,a.issue_status,a.RESERVATION_ORDER_SOURCE,a.tms_order_number
|
||||
,a.DIRECTOR_NAME ,a.DIRECTOR_PHONE,a.DIRECTOR_ID,a.STORAGE_TIME,a.in_quantity,
|
||||
a.PUSH_TIME,a.PUSH_STATUS,a.PUSH_BY,a.PUSH_BY_NAME,a.execution_in_order_number
|
||||
a.PUSH_TIME,a.PUSH_STATUS,a.PUSH_BY,a.PUSH_BY_NAME,a.execution_in_order_number,
|
||||
a.REVERSE_AUDIT_STATUS,a.REVERSE_AUDIT_REMARK,a.REVERSE_AUDIT_BY,a.REVERSE_AUDIT_BY_NAME,a.REVERSE_AUDIT_TIME
|
||||
</sql>
|
||||
|
||||
<sql id="joinStockInOrderPo">
|
||||
@@ -239,7 +245,7 @@
|
||||
and a.notice_number = #{noticeNumber}
|
||||
</if>
|
||||
<if test="inOrderNumber != null and inOrderNumber != ''">
|
||||
and a.in_order_number = #{inOrderNumber}
|
||||
and a.in_order_number like concat('%', #{inOrderNumber}, '%')
|
||||
</if>
|
||||
<if test="status != null ">
|
||||
and a.status = #{status}
|
||||
@@ -274,6 +280,10 @@
|
||||
<if test="issueStatus != null">
|
||||
and a.issue_status = #{issueStatus}
|
||||
</if>
|
||||
<!-- 反审状态过滤:入库业务单【已反审】tab 传 reverseAuditStatus=1 -->
|
||||
<if test="reverseAuditStatus != null">
|
||||
and a.REVERSE_AUDIT_STATUS = #{reverseAuditStatus}
|
||||
</if>
|
||||
<if test="warehouseId != null ">
|
||||
and a.warehouse_id = #{warehouseId}
|
||||
</if>
|
||||
@@ -293,7 +303,7 @@
|
||||
and a.order_type_code = #{orderTypeCode}
|
||||
</if>
|
||||
<if test="orderTypeName != null and orderTypeName != ''">
|
||||
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}, '%'))
|
||||
</if>
|
||||
<if test="supplierId != null ">
|
||||
and a.supplier_id = #{supplierId}
|
||||
|
||||
+26
-1
@@ -667,7 +667,16 @@ public class StockInOrderApplicationService {
|
||||
*/
|
||||
public StockInOrderPO getInfo(Long inOrderId)
|
||||
{
|
||||
StockInOrderPO info = stockInOrderDomainService.getInfo(inOrderId);
|
||||
return getInfo(inOrderId, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取入库单详情
|
||||
* @param archive true-查询【已反审】tab 归档数据(已软删+已反审标记,明细放行软删行)
|
||||
*/
|
||||
public StockInOrderPO getInfo(Long inOrderId, boolean archive)
|
||||
{
|
||||
StockInOrderPO info = stockInOrderDomainService.getInfo(inOrderId, archive);
|
||||
String userNcCode = stockOutOrderMapper.getUserNcCode(info.getShipperId());
|
||||
info.setKhdm(userNcCode);
|
||||
List<InMaterialDetailPO> materialDetailList = info.getMaterialDetailList();
|
||||
@@ -762,6 +771,14 @@ public class StockInOrderApplicationService {
|
||||
return info;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询入库单【已反审】tab 归档详情(已软删+已反审标记的数据,含软删明细/收货单/上架单)
|
||||
*/
|
||||
public StockInOrderPO getReverseAuditInfo(Long inOrderId)
|
||||
{
|
||||
return getInfo(inOrderId, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@@ -955,6 +972,14 @@ public class StockInOrderApplicationService {
|
||||
stockInOrderDomainService.cancelExecutionOrder(stockInOrder);
|
||||
}
|
||||
|
||||
/**
|
||||
* OMS入库业务单反审:WMS侧回退已完成单据(出库拦截 -> 回退库存 ->
|
||||
* 逻辑删除收货/上架链路 -> 写入库异常【反审记录】),已产生出库则报错拦截
|
||||
*/
|
||||
public void omsReverseInOrder(StockInOrder stockInOrder){
|
||||
stockInOrderDomainService.reverseExecutionOrder(stockInOrder);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 取消入库单
|
||||
* @author ZhouGY
|
||||
|
||||
+4
-4
@@ -53,8 +53,8 @@ public class InOrderAbnormal extends BaseVOEntity {
|
||||
@Excel(name = "上架单号")
|
||||
private String shelfOrderNumber;
|
||||
|
||||
@ApiModelProperty("类型:1-收货 2-上架")
|
||||
@Excel(name = "类型:1-收货 2-上架")
|
||||
@ApiModelProperty("类型:1-收货 2-上架 3-反审")
|
||||
@Excel(name = "类型:1-收货 2-上架 3-反审")
|
||||
private Integer type;
|
||||
|
||||
@ApiModelProperty("计划数量")
|
||||
@@ -73,8 +73,8 @@ public class InOrderAbnormal extends BaseVOEntity {
|
||||
@Excel(name = "异常数量")
|
||||
private BigDecimal abnormalActualQuantity;
|
||||
|
||||
@ApiModelProperty("异常类型: 1-上架异常 2-收货异常 3-收货异常(允许超收没超出超收比例) 4-收货异常(不允许超收)5-收货异常(允许超收但超出超收比例)")
|
||||
@Excel(name = "异常类型: 1-上架异常 2-收货异常 3-收货异常", readConverterExp = "允=许超收但不允许超出超收比例")
|
||||
@ApiModelProperty("异常类型: 1-上架异常 2-收货异常 3-收货异常(允许超收没超出超收比例) 4-收货异常(不允许超收)5-收货异常(允许超收但超出超收比例) 6-反审记录")
|
||||
@Excel(name = "异常类型: 1-上架异常 2-收货异常 6-反审记录", readConverterExp = "允=许超收但不允许超出超收比例")
|
||||
private Integer abnormalType;
|
||||
|
||||
@ApiModelProperty("异常原因")
|
||||
|
||||
+7
@@ -51,4 +51,11 @@ public interface IInOrderAbnormalService extends IService<InOrderAbnormal>
|
||||
* @return Boolean
|
||||
*/
|
||||
Boolean genInOrderAbnormal(InOrderAbnormalBaseDO inOrderAbnormalBaseDO, Integer type);
|
||||
|
||||
/**
|
||||
* 生成入库异常【反审记录】(入库业务单反审时调用,用于记录跟踪)
|
||||
* 单号自动生成(FSYC 前缀,与出库反审记录一致),固定 type=3(反审)、abnormalType=6(反审记录),
|
||||
* 其余字段(inOrderNumber/abnormalReason/quantity/remark/createBy 等)由调用方填充
|
||||
*/
|
||||
Boolean genReverseAuditAbnormal(InOrderAbnormal inOrderAbnormal);
|
||||
}
|
||||
|
||||
+19
@@ -174,6 +174,25 @@ public class InOrderAbnormalImpl extends ServiceImpl<InOrderAbnormalMapper, InOr
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成入库异常【反审记录】(入库业务单反审时调用,用于记录跟踪)
|
||||
* 与出库反审记录共用 FSYC 单号前缀;type=3(反审)、abnormalType=6(反审记录)
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean genReverseAuditAbnormal(InOrderAbnormal inOrderAbnormal) {
|
||||
if (inOrderAbnormal == null || !StringUtils.hasText(inOrderAbnormal.getInOrderNumber())) {
|
||||
throw new ServiceException("生成反审记录失败:入库单号为空");
|
||||
}
|
||||
inOrderAbnormal.setAbnormalNumber(OrderSequence.getOrderCode("FSYC"));
|
||||
inOrderAbnormal.setType(3);
|
||||
inOrderAbnormal.setAbnormalType(6);
|
||||
if (inOrderAbnormal.getCreateTime() == null) {
|
||||
inOrderAbnormal.setCreateTime(new Date());
|
||||
}
|
||||
return this.save(inOrderAbnormal);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 收货数量与计划数量不符,完成收货会生成收货异常记录
|
||||
* @author ZhouGY
|
||||
|
||||
@@ -410,4 +410,21 @@ public class StockInOrder extends BaseVOEntity {
|
||||
|
||||
@ApiModelProperty("签名备注")
|
||||
private String signatureRemark;
|
||||
|
||||
@ApiModelProperty("反审状态: 0-无 1-已反审(已反审tab过滤)")
|
||||
private Integer reverseAuditStatus;
|
||||
|
||||
@ApiModelProperty("反审原因")
|
||||
private String reverseAuditRemark;
|
||||
|
||||
@ApiModelProperty("反审人id")
|
||||
private Long reverseAuditBy;
|
||||
|
||||
@ApiModelProperty("反审人姓名")
|
||||
private String reverseAuditByName;
|
||||
|
||||
@ApiModelProperty("反审时间")
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date reverseAuditTime;
|
||||
}
|
||||
+17
@@ -477,4 +477,21 @@ public class StockInOrderPO extends BaseVOEntity {
|
||||
|
||||
@ApiModelProperty("签名备注")
|
||||
private String signatureRemark;
|
||||
|
||||
@ApiModelProperty("反审状态: 0-无 1-已反审(已反审tab过滤)")
|
||||
private Integer reverseAuditStatus;
|
||||
|
||||
@ApiModelProperty("反审原因")
|
||||
private String reverseAuditRemark;
|
||||
|
||||
@ApiModelProperty("反审人id")
|
||||
private Long reverseAuditBy;
|
||||
|
||||
@ApiModelProperty("反审人姓名")
|
||||
private String reverseAuditByName;
|
||||
|
||||
@ApiModelProperty("反审时间")
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date reverseAuditTime;
|
||||
}
|
||||
+17
@@ -470,6 +470,23 @@ public class StockInOrderDO extends BaseVOEntity {
|
||||
@ApiModelProperty("签名备注")
|
||||
private String signatureRemark;
|
||||
|
||||
@ApiModelProperty("反审状态: 0-无 1-已反审(已反审tab过滤)")
|
||||
private Integer reverseAuditStatus;
|
||||
|
||||
@ApiModelProperty("反审原因")
|
||||
private String reverseAuditRemark;
|
||||
|
||||
@ApiModelProperty("反审人id")
|
||||
private Long reverseAuditBy;
|
||||
|
||||
@ApiModelProperty("反审人姓名")
|
||||
private String reverseAuditByName;
|
||||
|
||||
@ApiModelProperty("反审时间")
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date reverseAuditTime;
|
||||
|
||||
/**
|
||||
* PDA入库签名列表专用:作业任务人员模糊查询字段(与 workUserName LIKE 同义,
|
||||
* 单独提供是为了避免和现有 workUserName(精确/等值)逻辑冲突)。
|
||||
|
||||
+342
-4
@@ -30,10 +30,20 @@ import com.mhd.wms.domain.inMaterialDetail.repository.facade.IInMaterialDetailSe
|
||||
import com.mhd.wms.domain.inMaterialDetail.repository.po.InMaterialDetailPO;
|
||||
import com.mhd.wms.domain.inMaterialDetail.repository.todo.InMaterialDetailBaseDO;
|
||||
import com.mhd.wms.domain.inMaterialDetail.repository.todo.InMaterialDetailDO;
|
||||
import com.mhd.wms.domain.inOrderAbnormal.entity.InOrderAbnormal;
|
||||
import com.mhd.wms.domain.inOrderAbnormal.repository.facade.IInOrderAbnormalService;
|
||||
import com.mhd.wms.domain.inventoryAdjustmentRecord.entity.InventoryAdjustmentRecord;
|
||||
import com.mhd.wms.domain.inventoryAdjustmentRecord.repository.facade.IInventoryAdjustmentRecordService;
|
||||
import com.mhd.wms.domain.inventoryStandingDetail.entity.InventoryStandingDetail;
|
||||
import com.mhd.wms.domain.inventoryStandingDetail.repository.facade.IInventoryStandingDetailService;
|
||||
import com.mhd.wms.domain.materialBaseInfo.repository.facade.IMaterialBaseInfoService;
|
||||
import com.mhd.wms.domain.materialBaseInfo.repository.po.MaterialBaseInfoPO;
|
||||
import com.mhd.wms.domain.materialGoodsRule.repository.facade.IMaterialGoodsRuleService;
|
||||
import com.mhd.wms.domain.materialGoodsRule.repository.po.MaterialGoodsRulePO;
|
||||
import com.mhd.wms.domain.materialInventory.entity.MaterialInventory;
|
||||
import com.mhd.wms.domain.materialInventory.repository.facade.IMaterialInventoryService;
|
||||
import com.mhd.wms.domain.materialInventory.repository.todo.MaterialInventoryDO;
|
||||
import com.mhd.wms.domain.materialInventory.repository.todo.MaterialInventoryParentDO;
|
||||
import com.mhd.wms.domain.materialWarehouseControl.repository.facade.IMaterialWarehouseControlService;
|
||||
import com.mhd.wms.domain.materialWarehouseControl.repository.po.MaterialWarehouseControlPO;
|
||||
import com.mhd.wms.domain.qualityInspection.repository.facade.IQualityInspectionService;
|
||||
@@ -53,6 +63,10 @@ import com.mhd.wms.domain.stockInOrder.repository.po.StockInOrderPO;
|
||||
import com.mhd.wms.domain.stockInOrder.repository.todo.StockInOrderDO;
|
||||
import com.mhd.wms.domain.stockInTaskOrder.entity.StockInTaskOrder;
|
||||
import com.mhd.wms.domain.stockInTaskOrder.repository.facade.IStockInTaskOrderService;
|
||||
import com.mhd.wms.domain.taskShelfMaterialDetail.entity.TaskShelfMaterialDetail;
|
||||
import com.mhd.wms.domain.taskShelfMaterialDetail.repository.facade.ITaskShelfMaterialDetailService;
|
||||
import com.mhd.wms.domain.taskShelfMaterialDetail.entity.TaskShelfMaterialDetail;
|
||||
import com.mhd.wms.domain.taskShelfMaterialDetail.repository.facade.ITaskShelfMaterialDetailService;
|
||||
import com.mhd.wms.domain.stockReceiptOrder.entity.StockReceiptOrder;
|
||||
import com.mhd.wms.domain.stockReceiptOrder.repository.facade.IStockReceiptOrderService;
|
||||
import com.mhd.wms.domain.stockReceiptOrder.repository.po.StockReceiptOrderPO;
|
||||
@@ -127,6 +141,16 @@ public class StockInOrderDomainService {
|
||||
@Autowired
|
||||
private ITaskReceiptMaterialDetailService taskReceiptMaterialDetailService;
|
||||
@Autowired
|
||||
private ITaskShelfMaterialDetailService taskShelfMaterialDetailService;
|
||||
@Autowired
|
||||
private IInventoryAdjustmentRecordService inventoryAdjustmentRecordService;
|
||||
@Autowired
|
||||
private IInventoryStandingDetailService inventoryStandingDetailService;
|
||||
@Autowired
|
||||
private IMaterialInventoryService materialInventoryService;
|
||||
@Autowired
|
||||
private IInOrderAbnormalService inOrderAbnormalService;
|
||||
@Autowired
|
||||
private IdGenerator idGenerator;
|
||||
|
||||
/**
|
||||
@@ -521,23 +545,46 @@ public class StockInOrderDomainService {
|
||||
* 获取入库单详细信息
|
||||
*/
|
||||
public StockInOrderPO getInfo(Long inOrderId)
|
||||
{
|
||||
return getInfo(inOrderId, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取入库单详情
|
||||
* @param archive true-查询【已反审】tab 归档数据(主单须为已软删+已反审标记,收货/上架单及明细放行软删行)
|
||||
*/
|
||||
public StockInOrderPO getInfo(Long inOrderId, boolean archive)
|
||||
{
|
||||
StockInOrderPO stockInOrderPO = stockInOrderService.getInfo(inOrderId);
|
||||
if (archive && (stockInOrderPO.getDelFlag() == null || stockInOrderPO.getDelFlag() != 2
|
||||
|| !Integer.valueOf(1).equals(stockInOrderPO.getReverseAuditStatus()))) {
|
||||
throw new ServiceException("入库单非已反审归档数据,无法查看归档详情");
|
||||
}
|
||||
InMaterialDetailDO inMaterialDetailDO = new InMaterialDetailDO();
|
||||
inMaterialDetailDO.setInOrderNumber(stockInOrderPO.getInOrderNumber());
|
||||
inMaterialDetailDO.setLevel(1);
|
||||
if (archive) {
|
||||
//归档明细已随主单软删,放行软删行
|
||||
inMaterialDetailDO.setDelFlag(2);
|
||||
}
|
||||
List<InMaterialDetailPO> inMaterialDetailPOList = materialDetailService.queryList(inMaterialDetailDO);
|
||||
|
||||
|
||||
// 先通过入库单号查询收货单列表
|
||||
StockReceiptOrderDO stockReceiptOrderDO = new StockReceiptOrderDO();
|
||||
stockReceiptOrderDO.setInOrderNumber(stockInOrderPO.getInOrderNumber());
|
||||
if (archive) {
|
||||
stockReceiptOrderDO.setDelFlag(2);
|
||||
}
|
||||
List<StockReceiptOrderPO> stockReceiptOrderPOList = stockReceiptOrderDomainService.queryList(stockReceiptOrderDO);
|
||||
|
||||
|
||||
// 先通过入库单号查询上架单列表
|
||||
StockShelfOrderDO stockShelfOrderDO = new StockShelfOrderDO();
|
||||
stockShelfOrderDO.setInOrderNumber(stockInOrderPO.getInOrderNumber());
|
||||
if (archive) {
|
||||
stockShelfOrderDO.setDelFlag(2);
|
||||
}
|
||||
List<StockShelfOrderPO> stockShelfOrderPOList = stockShelfOrderDomainService.queryList(stockShelfOrderDO);
|
||||
|
||||
|
||||
// 查询收货单明细,用于填充收货数量和更新毛重、净重、面积、体积
|
||||
List<ReceiptMaterialDetailPO> receiptMaterialDetailPOList = new ArrayList<>();
|
||||
if (!CollectionUtils.isEmpty(stockReceiptOrderPOList)) {
|
||||
@@ -548,10 +595,13 @@ public class StockInOrderDomainService {
|
||||
if (!CollectionUtils.isEmpty(receiptOrderNumberList)) {
|
||||
ReceiptMaterialDetailDO receiptMaterialDetailDO = new ReceiptMaterialDetailDO();
|
||||
receiptMaterialDetailDO.setReceiptOrderNumberList(receiptOrderNumberList);
|
||||
if (archive) {
|
||||
receiptMaterialDetailDO.setDelFlag(2);
|
||||
}
|
||||
receiptMaterialDetailPOList = receiptMaterialDetailService.queryList(receiptMaterialDetailDO);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 查询上架单明细,用于填充上架数量
|
||||
List<ShelfMaterialDetailPO> shelfMaterialDetailPOList = new ArrayList<>();
|
||||
if (!CollectionUtils.isEmpty(stockShelfOrderPOList)) {
|
||||
@@ -559,6 +609,9 @@ public class StockInOrderDomainService {
|
||||
if (StringUtils.isNotBlank(stockShelfOrderPO.getShelfOrderNumber())) {
|
||||
ShelfMaterialDetailDO shelfMaterialDetailDO = new ShelfMaterialDetailDO();
|
||||
shelfMaterialDetailDO.setShelfOrderNumber(stockShelfOrderPO.getShelfOrderNumber());
|
||||
if (archive) {
|
||||
shelfMaterialDetailDO.setDelFlag(2);
|
||||
}
|
||||
List<ShelfMaterialDetailPO> shelfDetails = shelfMaterialDetailService.queryList(shelfMaterialDetailDO);
|
||||
if (!CollectionUtils.isEmpty(shelfDetails)) {
|
||||
shelfMaterialDetailPOList.addAll(shelfDetails);
|
||||
@@ -844,6 +897,291 @@ public class StockInOrderDomainService {
|
||||
.eq(StockInOrder::getDelFlag, 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* OMS入库业务单反审:WMS侧一个事务内把已完成单据回退到最原始状态(供 Feign /stockInOrderApi/omsReverseInOrder 调用)。
|
||||
*
|
||||
* <p>与 {@link #cancelExecutionOrder(StockInOrder)}(取消下发,仅限未开始收货)不同,本方法处理
|
||||
* 已开始收货/上架/已入库(status>=3)的单据,回退动作与"完成收货/完成上架"链路对称:</p>
|
||||
* <ul>
|
||||
* <li>出库拦截:按"入库单号+动作(分配库存/出库)"查库存调整记录>0 即有出库记录;另校验库存冻结量
|
||||
* (入库单有出库就不能反审)</li>
|
||||
* <li>回退库存:按本单库存行整行扣回(上架时 inventory_quantity 与 allocation_quantity 同量增加、
|
||||
* 重量体积一并累加,此处对称扣回,复用统一扣减服务 GREATEST(x-n,0) 兜底);
|
||||
* 扣减前校验"库存行合计=已上架完成量",不一致说明发生过库存合并/人工调整,拦截人工核实</li>
|
||||
* <li>W入库单/W收货单/W上架单整链软删(del_flag=2)并打已反审标记(REVERSE_AUDIT_STATUS=1),
|
||||
* 各页面【已反审】tab按"已软删+已反审"(del_flag=2 and reverse_audit_status=1)查询归档数据;
|
||||
* 物料明细/作业单/任务/质检单一并软删留痕,台账节点物理删除保持与回退后库存一致</li>
|
||||
* <li>写1条入库异常【反审记录】(in_order_abnormal type=3/abnormalType=6) 用于记录跟踪</li>
|
||||
* </ul>
|
||||
* <p>WMS无该单数据时幂等返回成功(OMS未下发单反审不产生WMS数据);任何校验失败抛错经
|
||||
* Feign 返回,OMS侧整体回滚。反审可重试,本方法幂等。</p>
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void reverseExecutionOrder(StockInOrder stockInOrder) {
|
||||
String inOrderNumber = stockInOrder.getInOrderNumber();
|
||||
if (StringUtils.isEmpty(inOrderNumber)) {
|
||||
throw new ServiceException("反审失败:入库单号为空");
|
||||
}
|
||||
//反审原因/反审人由OMS经Feign传入(不依赖Feign链路的登录上下文)
|
||||
String reverseReason = stockInOrder.getRemark();
|
||||
String reverseByName = stockInOrder.getUpdateByName();
|
||||
|
||||
List<StockInOrder> stockInOrders = stockInOrderService.list(new LambdaQueryWrapper<StockInOrder>()
|
||||
.eq(StockInOrder::getInOrderNumber, inOrderNumber)
|
||||
.eq(StockInOrder::getDelFlag, 1));
|
||||
if (CollectionUtils.isEmpty(stockInOrders)) {
|
||||
//幂等:WMS无该单数据(未下发单反审或已反审过),直接成功,保证OMS反审可重试
|
||||
return;
|
||||
}
|
||||
StockInOrder wmsOrder = stockInOrders.get(0);
|
||||
|
||||
// ========== 1. 出库拦截:入库单有出库就不能反审 ==========
|
||||
//按"入库单号+动作(分配库存/出库)"查询库存调整记录:出库分配/交接出库时都会写入调整记录,
|
||||
//>0 即证明该入库单的库存已发生出库流转;取消分配时调整记录随之软删,不会误拦
|
||||
List<InventoryAdjustmentRecord> outboundRecords = inventoryAdjustmentRecordService.list(
|
||||
new LambdaQueryWrapper<InventoryAdjustmentRecord>()
|
||||
.eq(InventoryAdjustmentRecord::getInOrderNumber, inOrderNumber)
|
||||
.in(InventoryAdjustmentRecord::getAdjustAction, "分配库存", "出库")
|
||||
.eq(InventoryAdjustmentRecord::getDelFlag, 1));
|
||||
if (!CollectionUtils.isEmpty(outboundRecords)) {
|
||||
throw new ServiceException("入库单[" + inOrderNumber + "]已产生出库记录,无法反审");
|
||||
}
|
||||
//本单库存行(反审要扣回的库存)
|
||||
List<MaterialInventory> inventoryRows = materialInventoryService.list(new LambdaQueryWrapper<MaterialInventory>()
|
||||
.eq(MaterialInventory::getInOrderNumber, inOrderNumber));
|
||||
for (MaterialInventory row : inventoryRows) {
|
||||
if (row.getFreezeQuantity() != null && row.getFreezeQuantity().compareTo(BigDecimal.ZERO) > 0) {
|
||||
throw new ServiceException("入库单[" + inOrderNumber + "]库存已被出库分配,无法反审");
|
||||
}
|
||||
}
|
||||
|
||||
// ========== 2. 回退库存(对称"完成上架"写入) ==========
|
||||
List<StockShelfOrder> shelfOrders = stockShelfOrderService.list(new LambdaQueryWrapper<StockShelfOrder>()
|
||||
.eq(StockShelfOrder::getInOrderNumber, inOrderNumber)
|
||||
.eq(StockShelfOrder::getDelFlag, 1));
|
||||
List<String> shelfOrderNumbers = shelfOrders.stream()
|
||||
.map(StockShelfOrder::getShelfOrderNumber)
|
||||
.filter(StringUtils::isNotEmpty)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
BigDecimal inventoryTotal = inventoryRows.stream()
|
||||
.map(row -> row.getInventoryQuantity() == null ? BigDecimal.ZERO : row.getInventoryQuantity())
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
if (inventoryTotal.compareTo(BigDecimal.ZERO) > 0) {
|
||||
//扣减前校验:库存行合计必须等于"已完成上架单"的上架量,否则整行扣回会误伤合并进来的其他来源库存。
|
||||
//只统计已完成(status=3)的上架单——库存只在完成上架时写入,上架中未完成的单不产生库存
|
||||
BigDecimal shelfDoneTotal = BigDecimal.ZERO;
|
||||
List<String> doneShelfOrderNumbers = shelfOrders.stream()
|
||||
.filter(shelfOrder -> shelfOrder.getStatus() != null && shelfOrder.getStatus() == 3)
|
||||
.map(StockShelfOrder::getShelfOrderNumber)
|
||||
.filter(StringUtils::isNotEmpty)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
if (!doneShelfOrderNumbers.isEmpty()) {
|
||||
List<ShelfMaterialDetail> shelfDetails = shelfMaterialDetailService.list(new LambdaQueryWrapper<ShelfMaterialDetail>()
|
||||
.in(ShelfMaterialDetail::getShelfOrderNumber, doneShelfOrderNumbers)
|
||||
.eq(ShelfMaterialDetail::getDelFlag, 1));
|
||||
for (ShelfMaterialDetail shelfDetail : shelfDetails) {
|
||||
BigDecimal shelved = shelfDetail.getAlreadyShelvesQuantity() != null
|
||||
? shelfDetail.getAlreadyShelvesQuantity()
|
||||
: (shelfDetail.getShelvesQuantity() != null ? shelfDetail.getShelvesQuantity() : BigDecimal.ZERO);
|
||||
shelfDoneTotal = shelfDoneTotal.add(shelved);
|
||||
}
|
||||
}
|
||||
if (shelfDoneTotal.compareTo(BigDecimal.ZERO) <= 0 || inventoryTotal.compareTo(shelfDoneTotal) != 0) {
|
||||
throw new ServiceException("入库单[" + inOrderNumber + "]库存(" + inventoryTotal.stripTrailingZeros().toPlainString()
|
||||
+ ")与上架完成量(" + shelfDoneTotal.stripTrailingZeros().toPlainString()
|
||||
+ ")不一致,可能已发生出库或库存合并,请人工核实后再反审");
|
||||
}
|
||||
List<MaterialInventoryDO> subtractList = new ArrayList<>();
|
||||
for (MaterialInventory row : inventoryRows) {
|
||||
if (row.getInventoryQuantity() == null || row.getInventoryQuantity().compareTo(BigDecimal.ZERO) <= 0) {
|
||||
continue;
|
||||
}
|
||||
MaterialInventoryDO subtractDO = new MaterialInventoryDO();
|
||||
subtractDO.setMaterialInventoryId(row.getMaterialInventoryId());
|
||||
subtractDO.setInventoryQuantity(row.getInventoryQuantity());
|
||||
//SQL按 GREATEST(x-#{item.n},0) 扣减,DM/Oracle下 GREATEST 遇 null 返回 null,数值字段一律兜底0
|
||||
subtractDO.setNetWeight(row.getNetWeight() == null ? BigDecimal.ZERO : row.getNetWeight());
|
||||
subtractDO.setGrossWeight(row.getGrossWeight() == null ? BigDecimal.ZERO : row.getGrossWeight());
|
||||
subtractDO.setVolume(row.getVolume() == null ? BigDecimal.ZERO : row.getVolume());
|
||||
subtractDO.setArea(row.getArea() == null ? BigDecimal.ZERO : row.getArea());
|
||||
subtractList.add(subtractDO);
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(subtractList)) {
|
||||
//直接走统一批量扣减(GREATEST(x-n,0)兜底)并显式传更新人:不经 updateMaterialInventoryInfo,
|
||||
//其内部 subtractMaterialInventory 取 SecurityUtils 登录上下文,OMS经Feign调用时可能无登录态(会抛异常)
|
||||
MaterialInventoryParentDO subtractParent = new MaterialInventoryParentDO();
|
||||
subtractParent.setMaterialInventoryDOList(subtractList);
|
||||
subtractParent.setUpdateBy(stockInOrder.getUpdateBy() == null ? 0L : stockInOrder.getUpdateBy());
|
||||
subtractParent.setUpdateByName(StringUtils.isEmpty(reverseByName) ? "system" : reverseByName);
|
||||
subtractParent.setUpdateTime(new Date());
|
||||
materialInventoryService.batchSubtractInventoryQuantity(subtractParent);
|
||||
}
|
||||
}
|
||||
|
||||
// ========== 3. 软删下游全链 + W入库单/W收货单/W上架单打"已反审"标记 ==========
|
||||
//三单软删(del_flag=2)并打已反审标记(REVERSE_AUDIT_STATUS=1),各页面【已反审】tab按
|
||||
//"已软删+已反审"(del_flag=2 and reverse_audit_status=1)查询归档数据;
|
||||
//物料明细/收货上架作业单/任务/质检单/台账一并软删留痕,重新下发时生成全新数据
|
||||
String reverseRemarkForWms = StringUtils.isEmpty(reverseReason) ? "入库单反审" : "入库单反审:" + reverseReason;
|
||||
Long reverseAuditUserId = stockInOrder.getUpdateBy() == null ? 0L : stockInOrder.getUpdateBy();
|
||||
String reverseAuditUserName = StringUtils.isEmpty(reverseByName) ? "system" : reverseByName;
|
||||
Date reverseAuditDate = new Date();
|
||||
//收货单(含历史重复下发产生的多张同号收货单,全部查出统一清理,避免按单号取一条漏删/报错)
|
||||
List<StockReceiptOrder> receiptOrders = stockReceiptOrderService.list(new LambdaQueryWrapper<StockReceiptOrder>()
|
||||
.eq(StockReceiptOrder::getInOrderNumber, inOrderNumber)
|
||||
.eq(StockReceiptOrder::getDelFlag, 1));
|
||||
List<String> receiptOrderNumbers = receiptOrders.stream()
|
||||
.map(StockReceiptOrder::getReceiptOrderNumber)
|
||||
.filter(StringUtils::isNotEmpty)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
//收货/上架作业单(type=1收货 type=2上架;上架作业单兜底按上架单号再查一道防 in_order_number 为空)
|
||||
//上架单复用第2节已查出的 shelfOrders/shelfOrderNumbers
|
||||
List<StockInTaskOrder> taskOrders = stockInTaskOrderService.list(new LambdaQueryWrapper<StockInTaskOrder>()
|
||||
.eq(StockInTaskOrder::getInOrderNumber, inOrderNumber)
|
||||
.eq(StockInTaskOrder::getDelFlag, 1));
|
||||
if (!shelfOrderNumbers.isEmpty()) {
|
||||
Set<String> existTaskNumbers = taskOrders.stream()
|
||||
.map(StockInTaskOrder::getTaskNumber)
|
||||
.collect(Collectors.toSet());
|
||||
List<StockInTaskOrder> shelfTaskOrders = stockInTaskOrderService.list(new LambdaQueryWrapper<StockInTaskOrder>()
|
||||
.in(StockInTaskOrder::getShelfOrderNumber, shelfOrderNumbers)
|
||||
.eq(StockInTaskOrder::getDelFlag, 1));
|
||||
for (StockInTaskOrder shelfTaskOrder : shelfTaskOrders) {
|
||||
if (shelfTaskOrder.getTaskNumber() != null && !existTaskNumbers.contains(shelfTaskOrder.getTaskNumber())) {
|
||||
taskOrders.add(shelfTaskOrder);
|
||||
}
|
||||
}
|
||||
}
|
||||
List<String> taskNumbers = taskOrders.stream()
|
||||
.map(StockInTaskOrder::getTaskNumber)
|
||||
.filter(StringUtils::isNotEmpty)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
//1.收货/上架作业单明细
|
||||
if (!taskNumbers.isEmpty()) {
|
||||
taskReceiptMaterialDetailService.update(new UpdateWrapper<TaskReceiptMaterialDetail>().lambda()
|
||||
.set(TaskReceiptMaterialDetail::getDelFlag, 2)
|
||||
.in(TaskReceiptMaterialDetail::getTaskNumber, taskNumbers)
|
||||
.eq(TaskReceiptMaterialDetail::getDelFlag, 1));
|
||||
taskShelfMaterialDetailService.update(new UpdateWrapper<TaskShelfMaterialDetail>().lambda()
|
||||
.set(TaskShelfMaterialDetail::getDelFlag, 2)
|
||||
.in(TaskShelfMaterialDetail::getTaskNumber, taskNumbers)
|
||||
.eq(TaskShelfMaterialDetail::getDelFlag, 1));
|
||||
}
|
||||
//2.收货/上架作业单
|
||||
if (!taskNumbers.isEmpty()) {
|
||||
stockInTaskOrderService.update(new UpdateWrapper<StockInTaskOrder>().lambda()
|
||||
.set(StockInTaskOrder::getDelFlag, 2)
|
||||
.eq(StockInTaskOrder::getInOrderNumber, inOrderNumber)
|
||||
.eq(StockInTaskOrder::getDelFlag, 1));
|
||||
if (!shelfOrderNumbers.isEmpty()) {
|
||||
stockInTaskOrderService.update(new UpdateWrapper<StockInTaskOrder>().lambda()
|
||||
.set(StockInTaskOrder::getDelFlag, 2)
|
||||
.in(StockInTaskOrder::getShelfOrderNumber, shelfOrderNumbers)
|
||||
.eq(StockInTaskOrder::getDelFlag, 1));
|
||||
}
|
||||
}
|
||||
//3.收货/上架任务(tracking_number=收货/上架单号;补"RV-"+入库单号兜底历史同号收货单)
|
||||
if (!receiptOrderNumbers.isEmpty() || !shelfOrderNumbers.isEmpty()) {
|
||||
Set<String> trackingNumbers = new HashSet<>(receiptOrderNumbers);
|
||||
trackingNumbers.addAll(shelfOrderNumbers);
|
||||
trackingNumbers.add("RV-" + inOrderNumber);
|
||||
deliveTaskService.update(new UpdateWrapper<DeliveTask>().lambda()
|
||||
.set(DeliveTask::getDelFlag, 2)
|
||||
.in(DeliveTask::getTrackingNumber, trackingNumbers)
|
||||
.in(DeliveTask::getTaskType, 1, 2)
|
||||
.eq(DeliveTask::getDelFlag, 1));
|
||||
}
|
||||
//4.质检单
|
||||
qualityInspectionService.update(new UpdateWrapper<com.mhd.wms.domain.qualityInspection.entity.QualityInspection>().lambda()
|
||||
.set(com.mhd.wms.domain.qualityInspection.entity.QualityInspection::getDelFlag, 2)
|
||||
.eq(com.mhd.wms.domain.qualityInspection.entity.QualityInspection::getInOrderNumber, inOrderNumber)
|
||||
.eq(com.mhd.wms.domain.qualityInspection.entity.QualityInspection::getDelFlag, 1));
|
||||
//5.收货单明细
|
||||
if (!receiptOrderNumbers.isEmpty()) {
|
||||
receiptMaterialDetailService.update(new UpdateWrapper<ReceiptMaterialDetail>().lambda()
|
||||
.set(ReceiptMaterialDetail::getDelFlag, 2)
|
||||
.in(ReceiptMaterialDetail::getReceiptOrderNumber, receiptOrderNumbers)
|
||||
.eq(ReceiptMaterialDetail::getDelFlag, 1));
|
||||
}
|
||||
//6.收货单(软删+打已反审标记,收货单【已反审】tab 可查归档数据)
|
||||
stockReceiptOrderService.update(new UpdateWrapper<StockReceiptOrder>().lambda()
|
||||
.set(StockReceiptOrder::getDelFlag, 2)
|
||||
.set(StockReceiptOrder::getReverseAuditStatus, 1)
|
||||
.set(StockReceiptOrder::getReverseAuditRemark, reverseRemarkForWms)
|
||||
.set(StockReceiptOrder::getReverseAuditBy, reverseAuditUserId)
|
||||
.set(StockReceiptOrder::getReverseAuditByName, reverseAuditUserName)
|
||||
.set(StockReceiptOrder::getReverseAuditTime, reverseAuditDate)
|
||||
.set(StockReceiptOrder::getUpdateBy, reverseAuditUserId)
|
||||
.set(StockReceiptOrder::getUpdateByName, reverseAuditUserName)
|
||||
.set(StockReceiptOrder::getUpdateTime, reverseAuditDate)
|
||||
.eq(StockReceiptOrder::getInOrderNumber, inOrderNumber)
|
||||
.eq(StockReceiptOrder::getDelFlag, 1));
|
||||
//7.上架单明细
|
||||
if (!shelfOrderNumbers.isEmpty()) {
|
||||
shelfMaterialDetailService.update(new UpdateWrapper<ShelfMaterialDetail>().lambda()
|
||||
.set(ShelfMaterialDetail::getDelFlag, 2)
|
||||
.in(ShelfMaterialDetail::getShelfOrderNumber, shelfOrderNumbers)
|
||||
.eq(ShelfMaterialDetail::getDelFlag, 1));
|
||||
}
|
||||
//8.上架单(软删+打已反审标记,上架单【已反审】tab 可查归档数据)
|
||||
stockShelfOrderService.update(new UpdateWrapper<StockShelfOrder>().lambda()
|
||||
.set(StockShelfOrder::getDelFlag, 2)
|
||||
.set(StockShelfOrder::getReverseAuditStatus, 1)
|
||||
.set(StockShelfOrder::getReverseAuditRemark, reverseRemarkForWms)
|
||||
.set(StockShelfOrder::getReverseAuditBy, reverseAuditUserId)
|
||||
.set(StockShelfOrder::getReverseAuditByName, reverseAuditUserName)
|
||||
.set(StockShelfOrder::getReverseAuditTime, reverseAuditDate)
|
||||
.set(StockShelfOrder::getUpdateBy, reverseAuditUserId)
|
||||
.set(StockShelfOrder::getUpdateByName, reverseAuditUserName)
|
||||
.set(StockShelfOrder::getUpdateTime, reverseAuditDate)
|
||||
.eq(StockShelfOrder::getInOrderNumber, inOrderNumber)
|
||||
.eq(StockShelfOrder::getDelFlag, 1));
|
||||
//9.收货/上架节点库存台账(trackingNumber=收货/上架单号;台账无逻辑删除标志,物理删除保持台账与回退后库存一致)
|
||||
Set<String> standingTrackingNumbers = new HashSet<>(receiptOrderNumbers);
|
||||
standingTrackingNumbers.addAll(shelfOrderNumbers);
|
||||
if (!standingTrackingNumbers.isEmpty()) {
|
||||
inventoryStandingDetailService.remove(new LambdaQueryWrapper<InventoryStandingDetail>()
|
||||
.in(InventoryStandingDetail::getTrackingNumber, standingTrackingNumbers)
|
||||
.in(InventoryStandingDetail::getNodeStatus, 1, 2));
|
||||
}
|
||||
//10.入库单明细
|
||||
materialDetailService.update(new UpdateWrapper<InMaterialDetail>().lambda()
|
||||
.set(InMaterialDetail::getDelFlag, 2)
|
||||
.eq(InMaterialDetail::getInOrderNumber, inOrderNumber)
|
||||
.eq(InMaterialDetail::getDelFlag, 1));
|
||||
//11.入库单(软删+打已反审标记,入库单【已反审】tab 可查归档数据)
|
||||
stockInOrderService.update(new UpdateWrapper<StockInOrder>().lambda()
|
||||
.set(StockInOrder::getDelFlag, 2)
|
||||
.set(StockInOrder::getReverseAuditStatus, 1)
|
||||
.set(StockInOrder::getReverseAuditRemark, reverseRemarkForWms)
|
||||
.set(StockInOrder::getReverseAuditBy, reverseAuditUserId)
|
||||
.set(StockInOrder::getReverseAuditByName, reverseAuditUserName)
|
||||
.set(StockInOrder::getReverseAuditTime, reverseAuditDate)
|
||||
.set(StockInOrder::getUpdateBy, reverseAuditUserId)
|
||||
.set(StockInOrder::getUpdateByName, reverseAuditUserName)
|
||||
.set(StockInOrder::getUpdateTime, reverseAuditDate)
|
||||
.eq(StockInOrder::getInOrderNumber, inOrderNumber)
|
||||
.eq(StockInOrder::getDelFlag, 1));
|
||||
|
||||
// ========== 4. 写1条入库异常【反审记录】用于记录跟踪 ==========
|
||||
InOrderAbnormal reverseAbnormal = new InOrderAbnormal();
|
||||
reverseAbnormal.setOrganizationId(wmsOrder.getOrganizationId());
|
||||
reverseAbnormal.setOrganizationName(wmsOrder.getOrganizationName());
|
||||
reverseAbnormal.setTopOrganizationId(wmsOrder.getTopOrganizationId());
|
||||
reverseAbnormal.setInOrderNumber(inOrderNumber);
|
||||
reverseAbnormal.setAbnormalReason(StringUtils.isEmpty(reverseReason) ? "入库业务单反审" : "入库业务单反审:" + reverseReason);
|
||||
reverseAbnormal.setQuantity(inventoryTotal);
|
||||
reverseAbnormal.setRemark("入库业务单反审:回退库存" + inventoryTotal.stripTrailingZeros().toPlainString()
|
||||
+ ",清理收货/上架链路数据");
|
||||
reverseAbnormal.setCreateBy(stockInOrder.getUpdateBy() == null ? 0L : stockInOrder.getUpdateBy());
|
||||
reverseAbnormal.setCreateByName(StringUtils.isEmpty(reverseByName) ? "system" : reverseByName);
|
||||
inOrderAbnormalService.genReverseAuditAbnormal(reverseAbnormal);
|
||||
}
|
||||
|
||||
/**
|
||||
* OMS下发入库单明细保存后自动审核通过(生成收货单并更新审核状态)
|
||||
*/
|
||||
|
||||
+17
@@ -164,5 +164,22 @@ public class StockReceiptOrder extends BaseVOEntity {
|
||||
@Excel(name = "业务单号")
|
||||
private String batchNo;
|
||||
|
||||
@ApiModelProperty("反审状态: 0-无 1-已反审(已反审tab过滤)")
|
||||
private Integer reverseAuditStatus;
|
||||
|
||||
@ApiModelProperty("反审原因")
|
||||
private String reverseAuditRemark;
|
||||
|
||||
@ApiModelProperty("反审人id")
|
||||
private Long reverseAuditBy;
|
||||
|
||||
@ApiModelProperty("反审人姓名")
|
||||
private String reverseAuditByName;
|
||||
|
||||
@ApiModelProperty("反审时间")
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date reverseAuditTime;
|
||||
|
||||
|
||||
}
|
||||
+17
@@ -194,4 +194,21 @@ public class StockReceiptOrderPO extends StockInOrderBasePO {
|
||||
@ApiModelProperty("批次号")
|
||||
@Excel(name = "批次号")
|
||||
private String batchNo;
|
||||
|
||||
@ApiModelProperty("反审状态: 0-无 1-已反审(已反审tab过滤)")
|
||||
private Integer reverseAuditStatus;
|
||||
|
||||
@ApiModelProperty("反审原因")
|
||||
private String reverseAuditRemark;
|
||||
|
||||
@ApiModelProperty("反审人id")
|
||||
private Long reverseAuditBy;
|
||||
|
||||
@ApiModelProperty("反审人姓名")
|
||||
private String reverseAuditByName;
|
||||
|
||||
@ApiModelProperty("反审时间")
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date reverseAuditTime;
|
||||
}
|
||||
+17
@@ -203,4 +203,21 @@ public class StockReceiptOrderDO extends StockInOrderBaseDO {
|
||||
@ApiModelProperty("是否需要报关")
|
||||
@Excel(name = "是否需要报关")
|
||||
private Integer needCustomsDeclaration;
|
||||
|
||||
@ApiModelProperty("反审状态: 0-无 1-已反审(已反审tab过滤)")
|
||||
private Integer reverseAuditStatus;
|
||||
|
||||
@ApiModelProperty("反审原因")
|
||||
private String reverseAuditRemark;
|
||||
|
||||
@ApiModelProperty("反审人id")
|
||||
private Long reverseAuditBy;
|
||||
|
||||
@ApiModelProperty("反审人姓名")
|
||||
private String reverseAuditByName;
|
||||
|
||||
@ApiModelProperty("反审时间")
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date reverseAuditTime;
|
||||
}
|
||||
@@ -118,4 +118,21 @@ public class StockShelfOrder extends BaseVOEntity {
|
||||
@Excel(name = "批次号")
|
||||
private String batchNo;
|
||||
|
||||
@ApiModelProperty("反审状态: 0-无 1-已反审(已反审tab过滤)")
|
||||
private Integer reverseAuditStatus;
|
||||
|
||||
@ApiModelProperty("反审原因")
|
||||
private String reverseAuditRemark;
|
||||
|
||||
@ApiModelProperty("反审人id")
|
||||
private Long reverseAuditBy;
|
||||
|
||||
@ApiModelProperty("反审人姓名")
|
||||
private String reverseAuditByName;
|
||||
|
||||
@ApiModelProperty("反审时间")
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date reverseAuditTime;
|
||||
|
||||
}
|
||||
+17
@@ -153,4 +153,21 @@ public class StockShelfOrderPO extends StockInOrderBasePO {
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
@Excel(name = "完成时间", width = 30, dateFormat = "yyyy-MM-dd")
|
||||
private Date completionTime;
|
||||
|
||||
@ApiModelProperty("反审状态: 0-无 1-已反审(已反审tab过滤)")
|
||||
private Integer reverseAuditStatus;
|
||||
|
||||
@ApiModelProperty("反审原因")
|
||||
private String reverseAuditRemark;
|
||||
|
||||
@ApiModelProperty("反审人id")
|
||||
private Long reverseAuditBy;
|
||||
|
||||
@ApiModelProperty("反审人姓名")
|
||||
private String reverseAuditByName;
|
||||
|
||||
@ApiModelProperty("反审时间")
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date reverseAuditTime;
|
||||
}
|
||||
+17
@@ -173,4 +173,21 @@ public class StockShelfOrderDO extends StockInOrderBaseDO {
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTimeTo;
|
||||
|
||||
@ApiModelProperty("反审状态: 0-无 1-已反审(已反审tab过滤)")
|
||||
private Integer reverseAuditStatus;
|
||||
|
||||
@ApiModelProperty("反审原因")
|
||||
private String reverseAuditRemark;
|
||||
|
||||
@ApiModelProperty("反审人id")
|
||||
private Long reverseAuditBy;
|
||||
|
||||
@ApiModelProperty("反审人姓名")
|
||||
private String reverseAuditByName;
|
||||
|
||||
@ApiModelProperty("反审时间")
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date reverseAuditTime;
|
||||
}
|
||||
@@ -468,4 +468,7 @@ public class StockInOrderDTO extends StockInOrderBaseDTO {
|
||||
*/
|
||||
@ApiModelProperty("作业任务人员(模糊查询)")
|
||||
private String workUserNameLike;
|
||||
|
||||
@ApiModelProperty("反审状态: 0-无 1-已反审(已反审tab过滤)")
|
||||
private Integer reverseAuditStatus;
|
||||
}
|
||||
+3
@@ -171,4 +171,7 @@ public class StockReceiptOrderDTO extends StockInOrderBaseDTO {
|
||||
@ApiModelProperty("业务单号")
|
||||
@Excel(name = "业务单号")
|
||||
private String batchNo;
|
||||
|
||||
@ApiModelProperty("反审状态: 0-无 1-已反审(已反审tab过滤)")
|
||||
private Integer reverseAuditStatus;
|
||||
}
|
||||
+3
@@ -162,4 +162,7 @@ public class StockShelfOrderDTO extends StockInOrderBaseDTO {
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTimeTo;
|
||||
|
||||
@ApiModelProperty("反审状态: 0-无 1-已反审(已反审tab过滤)")
|
||||
private Integer reverseAuditStatus;
|
||||
}
|
||||
+21
@@ -147,6 +147,16 @@ public class StockInOrderApi extends BaseController {
|
||||
return AjaxResult.success(stockInOrderApplicationService.getInfo(inOrderId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询入库单【已反审】tab 归档详情(已软删+已反审标记的数据,含软删明细/收货单/上架单)
|
||||
*/
|
||||
@ApiOperation("查询入库单已反审归档详情")
|
||||
@GetMapping(value = "/getReverseAuditInfo/{inOrderId}")
|
||||
public AjaxResult getReverseAuditInfo(@PathVariable("inOrderId") Long inOrderId)
|
||||
{
|
||||
return AjaxResult.success(stockInOrderApplicationService.getReverseAuditInfo(inOrderId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 导入入库单
|
||||
*/
|
||||
@@ -329,6 +339,17 @@ public class StockInOrderApi extends BaseController {
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* oms入库业务单反审:WMS侧回退已完成单据(出库拦截 -> 回退库存 ->
|
||||
* 逻辑删除收货/上架链路 -> 写入库异常【反审记录】),已产生出库则报错拦截
|
||||
*/
|
||||
@ApiOperation("oms入库单反审WMS回退")
|
||||
@PostMapping(value = "/omsReverseInOrder")
|
||||
public AjaxResult omsReverseInOrder(@RequestBody StockInOrder stockInOrder) {
|
||||
stockInOrderApplicationService.omsReverseInOrder(stockInOrder);
|
||||
return AjaxResult.success();
|
||||
}
|
||||
|
||||
@ApiOperation("查询入库信息(通过入库单号)")
|
||||
@PostMapping("/queryInStockInfo")
|
||||
public AjaxResult queryInStockInfo(@RequestBody StockInOrderDTO stockInOrderDTO) {
|
||||
|
||||
@@ -110,6 +110,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<result property="signaturePic" column="SIGNATURE_PIC" />
|
||||
<result property="evidencePics" column="EVIDENCE_PICS" />
|
||||
<result property="signatureRemark" column="SIGNATURE_REMARK" />
|
||||
<result property="reverseAuditStatus" column="REVERSE_AUDIT_STATUS" />
|
||||
<result property="reverseAuditRemark" column="REVERSE_AUDIT_REMARK" />
|
||||
<result property="reverseAuditBy" column="REVERSE_AUDIT_BY" />
|
||||
<result property="reverseAuditByName" column="REVERSE_AUDIT_BY_NAME" />
|
||||
<result property="reverseAuditTime" column="REVERSE_AUDIT_TIME" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectStockInOrderPo">
|
||||
@@ -144,7 +149,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
a.CUSTOMS_BROKER_INFO, a.DELIVERY_ADDRESS, a.ENTRY_EXIT_CUSTOMS, a.ORIGIN_DESTINATION_COUNTRY, a.CARRIER, a.CONTAINER_NO,
|
||||
a.TRANSPORT_METHOD, a.SUPERVISION_METHOD, a.CUSTOMS_INSPECTION, a.NEED_CUSTOMS_DECLARATION, a.NEED_TRANSPORT,
|
||||
a.WAREHOUSE_DATE, a.COMPLETION_TIME, a.ORDER_DATE,a.stock_in_order,a.business_order_no,a.WORK_USER_ID,a.WORK_TASK_RECEIVE_STATUS,a.TASK_ISSUE_USER_ID,a.WORK_USER_NAME,
|
||||
a.SIGNATURE_STATUS, a.SIGNATURE_TIME, a.SIGNATURE_PIC, a.EVIDENCE_PICS, a.SIGNATURE_REMARK
|
||||
a.SIGNATURE_STATUS, a.SIGNATURE_TIME, a.SIGNATURE_PIC, a.EVIDENCE_PICS, a.SIGNATURE_REMARK,
|
||||
a.REVERSE_AUDIT_STATUS, a.REVERSE_AUDIT_REMARK, a.REVERSE_AUDIT_BY, a.REVERSE_AUDIT_BY_NAME, a.REVERSE_AUDIT_TIME
|
||||
</sql>
|
||||
|
||||
<sql id="joinStockInOrderPo">
|
||||
@@ -483,9 +489,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</if>
|
||||
)
|
||||
</if>
|
||||
<!-- 反审状态过滤:入库单【已反审】tab 传 reverseAuditStatus=1,查询已软删且打反审标记的归档数据 -->
|
||||
<if test="reverseAuditStatus != null">
|
||||
and a.REVERSE_AUDIT_STATUS = #{reverseAuditStatus}
|
||||
</if>
|
||||
<choose>
|
||||
<when test="delFlag != null"> and a.del_flag = #{delFlag} </when>
|
||||
<otherwise> and a.del_flag = 1 </otherwise>
|
||||
<when test="reverseAuditStatus != null">
|
||||
and a.del_flag = 2
|
||||
</when>
|
||||
<otherwise>
|
||||
<choose>
|
||||
<when test="delFlag != null"> and a.del_flag = #{delFlag} </when>
|
||||
<otherwise> and a.del_flag = 1 </otherwise>
|
||||
</choose>
|
||||
</otherwise>
|
||||
</choose>
|
||||
</sql>
|
||||
|
||||
|
||||
@@ -45,6 +45,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<result property="billingJson" column="billing_json" />
|
||||
<result property="businessOrderNo" column="business_order_no" />
|
||||
<result property="batchNo" column="batch_no" />
|
||||
<result property="reverseAuditStatus" column="REVERSE_AUDIT_STATUS" />
|
||||
<result property="reverseAuditRemark" column="REVERSE_AUDIT_REMARK" />
|
||||
<result property="reverseAuditBy" column="REVERSE_AUDIT_BY" />
|
||||
<result property="reverseAuditByName" column="REVERSE_AUDIT_BY_NAME" />
|
||||
<result property="reverseAuditTime" column="REVERSE_AUDIT_TIME" />
|
||||
|
||||
</resultMap>
|
||||
|
||||
@@ -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
|
||||
</sql>
|
||||
|
||||
<sql id="selectStockReceiptOrderPo1">
|
||||
@@ -140,9 +146,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="createTimeEnd != null and createTimeEnd != ''">
|
||||
and date_format(a.create_time,'%Y-%m-%d') <= #{createTimeEnd}
|
||||
</if>
|
||||
<!-- 反审状态过滤:收货单【已反审】tab 传 reverseAuditStatus=1,查询已软删且打反审标记的归档数据 -->
|
||||
<choose>
|
||||
<when test="delFlag != null"> and a.del_flag = #{delFlag} </when>
|
||||
<otherwise> and a.del_flag = 1 </otherwise>
|
||||
<when test="reverseAuditStatus != null">
|
||||
and a.REVERSE_AUDIT_STATUS = #{reverseAuditStatus}
|
||||
and a.del_flag = 2
|
||||
</when>
|
||||
<otherwise>
|
||||
<choose>
|
||||
<when test="delFlag != null"> and a.del_flag = #{delFlag} </when>
|
||||
<otherwise> and a.del_flag = 1 </otherwise>
|
||||
</choose>
|
||||
</otherwise>
|
||||
</choose>
|
||||
|
||||
</sql>
|
||||
|
||||
@@ -31,6 +31,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<result property="pushBy" column="push_by" />
|
||||
<result property="pushByName" column="push_by_name" />
|
||||
<result property="goodsType" column="goods_type" />
|
||||
<result property="reverseAuditStatus" column="REVERSE_AUDIT_STATUS" />
|
||||
<result property="reverseAuditRemark" column="REVERSE_AUDIT_REMARK" />
|
||||
<result property="reverseAuditBy" column="REVERSE_AUDIT_BY" />
|
||||
<result property="reverseAuditByName" column="REVERSE_AUDIT_BY_NAME" />
|
||||
<result property="reverseAuditTime" column="REVERSE_AUDIT_TIME" />
|
||||
</resultMap>
|
||||
|
||||
|
||||
@@ -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"
|
||||
<if test="pushStatus != null">
|
||||
and a.PUSH_STATUS = #{pushStatus}
|
||||
</if>
|
||||
<!-- 反审状态过滤:上架单【已反审】tab 传 reverseAuditStatus=1,查询已软删且打反审标记的归档数据 -->
|
||||
<choose>
|
||||
<when test="delFlag != null"> and a.del_flag = #{delFlag} </when>
|
||||
<otherwise> and a.del_flag = 1 </otherwise>
|
||||
<when test="reverseAuditStatus != null">
|
||||
and a.REVERSE_AUDIT_STATUS = #{reverseAuditStatus}
|
||||
and a.del_flag = 2
|
||||
</when>
|
||||
<otherwise>
|
||||
<choose>
|
||||
<when test="delFlag != null"> and a.del_flag = #{delFlag} </when>
|
||||
<otherwise> and a.del_flag = 1 </otherwise>
|
||||
</choose>
|
||||
</otherwise>
|
||||
</choose>
|
||||
|
||||
</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 同时发布。
|
||||
-- =============================================================================
|
||||
Reference in New Issue
Block a user