Merge branch 'dev-ty1.2' into dev
This commit is contained in:
+75
-13
@@ -19,6 +19,9 @@ import com.mhd.oms.domain.executionInMaterialDetail.repository.po.ExecutionInMat
|
||||
import com.mhd.oms.domain.executionInMaterialDetail.repository.todo.ExecutionInMaterialDetailBaseDO;
|
||||
import com.mhd.oms.domain.executionInMaterialDetail.repository.todo.ExecutionInMaterialDetailDO;
|
||||
import com.mhd.oms.domain.executionInMaterialDetail.repository.todo.InventoryAdjustmentRecordPO;
|
||||
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.executionStockInOrder.entity.ExecutionStockInOrder;
|
||||
import com.mhd.oms.domain.executionStockInOrder.repository.facade.IExecutionStockInOrderService;
|
||||
import com.mhd.oms.domain.executionStockInOrder.repository.mapper.ExecutionStockInOrderMapper;
|
||||
@@ -94,6 +97,10 @@ public class ExecutionStockInOrderDomainService {
|
||||
private ReservationStockInOrderMapper stockInOrderMapper;
|
||||
@Autowired
|
||||
private ReserveStockInOrderMapper reserveStockInOrderMapper;
|
||||
@Autowired
|
||||
private IElectronicSignatureService electronicSignatureService;
|
||||
@Autowired
|
||||
private IElectronicSignatureMaterialDetailService electronicSignatureMaterialDetailService;
|
||||
/**
|
||||
* 分页查询入库单列表
|
||||
*/
|
||||
@@ -523,25 +530,34 @@ public class ExecutionStockInOrderDomainService {
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean cancelAuditState(ExecutionStockInOrderDO stockInOrderDO) {
|
||||
LoginUser loginUser = SecurityUtils.getLoginUser();
|
||||
Integer issueStatus = stockInOrderDO.getIssueStatus();
|
||||
// 获取用户姓名(优先从UserPo获取,如果为空则使用realname,最后使用username作为兜底)
|
||||
String userRealName = loginUser.getUserPo() != null && loginUser.getUserPo().getUserName() != null
|
||||
? loginUser.getUserPo().getUserName()
|
||||
: (loginUser.getRealname() != null ? loginUser.getRealname() : loginUser.getUsername());
|
||||
|
||||
//逻辑删除w入库单信息
|
||||
//回退下发在WMS产生的数据:调用WMS清理接口,与下发链路(omsInOrderAdd→omsInOrderAddDetail→自动审核
|
||||
//生成收货单/收货任务/收货作业单/质检单/电子签名)对称,WMS侧一个事务内逻辑删除全部数据。
|
||||
//此前OMS直接跨库UPDATE仅清理入库单/明细/收货单/收货明细4张表,收货任务、收货作业单、质检单、
|
||||
//电子签名记录残留;且按入库单号取收货单号(getWShOrder返回String)在重复下发产生多张同号收货单时
|
||||
//抛TooManyResultsException,取消下发整体回滚失败——正是"下发产生2条数据后取消下发阻断"的直接原因。
|
||||
//清理失败时抛错整体回滚(OMS保持已下发状态),WMS清理幂等,取消下发可安全重试
|
||||
List<Long> inOrderIds = stockInOrderDO.getInOrderIds();
|
||||
if (inOrderIds != null && !inOrderIds.isEmpty()) {
|
||||
for (Long inOrderId : inOrderIds) {
|
||||
ExecutionStockInOrder executionStockInOrder = reservationStockInOrderMapper.selectById(inOrderId);
|
||||
if (executionStockInOrder != null) {
|
||||
String inOrderNumber = executionStockInOrder.getInOrderNumber();
|
||||
reservationStockInOrderMapper.delWOrder(inOrderNumber);
|
||||
reservationStockInOrderMapper.delWOrderDetail(inOrderNumber);
|
||||
String wShOrder = reservationStockInOrderMapper.getWShOrder(inOrderNumber);
|
||||
reservationStockInOrderMapper.delWShOrder(inOrderNumber);
|
||||
reservationStockInOrderMapper.delWShOrderDetail(wShOrder);
|
||||
if (executionStockInOrder == null) {
|
||||
continue;
|
||||
}
|
||||
String inOrderNumber = executionStockInOrder.getInOrderNumber();
|
||||
StockInOrder cancelParam = new StockInOrder();
|
||||
cancelParam.setInOrderNumber(inOrderNumber);
|
||||
AjaxResult cancelResult = wmsServiceFeign.omsCancelInOrder(cancelParam);
|
||||
if (cancelResult == null || !"200".equals(String.valueOf(cancelResult.get("code")))) {
|
||||
throw new ServiceException("取消下发失败:入库单[" + inOrderNumber + "]WMS数据清理失败:"
|
||||
+ (cancelResult == null ? "WMS服务不可用或已降级" : cancelResult.get("msg")));
|
||||
}
|
||||
//清理下发自动审核时生成的待签名电子签名记录(已签名记录保留作凭证,不阻断主流程)
|
||||
cancelPendingSignature(inOrderNumber);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -556,6 +572,29 @@ public class ExecutionStockInOrderDomainService {
|
||||
.in(ExecutionStockInOrder::getInOrderId, stockInOrderDO.getInOrderIds()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消下发时清理下发自动审核生成的待签名电子签名记录(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) {
|
||||
//WMS数据已清理成功,签名属附属记录,清理失败仅记日志,不回滚取消下发主流程
|
||||
log.error("取消下发清理电子签名记录失败,入库单号:{}", inOrderNumber, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 审核入库单
|
||||
* @author ZhouGY
|
||||
@@ -574,9 +613,15 @@ public class ExecutionStockInOrderDomainService {
|
||||
}
|
||||
// 入参去重:同一请求内重复ID会导致同一执行单被多次推送WMS
|
||||
List<Long> distinctInOrderIds = inOrderIds.stream().distinct().collect(Collectors.toList());
|
||||
// 只校验有效单据:已删除(软删)执行单混入ID(过期页面提交)时在此拦截,
|
||||
// 此前list/getById均不过滤del_flag,软删单照样被推到WMS形成"幽灵单"
|
||||
List<ExecutionStockInOrder> checkOrders = stockInOrderService.list(
|
||||
new QueryWrapper<ExecutionStockInOrder>().lambda()
|
||||
.in(ExecutionStockInOrder::getInOrderId, distinctInOrderIds));
|
||||
.in(ExecutionStockInOrder::getInOrderId, distinctInOrderIds)
|
||||
.eq(ExecutionStockInOrder::getDelFlag, 1));
|
||||
if (checkOrders.size() != distinctInOrderIds.size()) {
|
||||
throw new ServiceException("下发失败:存在已删除的单据,请刷新后重新选择");
|
||||
}
|
||||
for (ExecutionStockInOrder order : checkOrders) {
|
||||
if (order.getIssueTime() != null) {
|
||||
throw new ServiceException("下发失败:单据[" + order.getInOrderNumber() + "]已下发,不可重复下发;如需重新下发请先取消下发");
|
||||
@@ -589,6 +634,9 @@ public class ExecutionStockInOrderDomainService {
|
||||
String userRealName = loginUser.getUserPo() != null && loginUser.getUserPo().getUserName() != null
|
||||
? loginUser.getUserPo().getUserName()
|
||||
: (loginUser.getRealname() != null ? loginUser.getRealname() : loginUser.getUsername());
|
||||
//下发标记改为条件更新(issue_time IS NULL):前置list校验与update之间存在并发窗口,
|
||||
//双击/并发请求会同时通过校验各自推一遍WMS(WMS侧同号入库单/明细翻倍的根源之一);
|
||||
//加上条件后,后到的事务影响行数为0,在此拦截,保证同一执行单只会推送WMS一次
|
||||
boolean update = stockInOrderService.update(null, new UpdateWrapper<ExecutionStockInOrder>().lambda()
|
||||
.set(ExecutionStockInOrder::getIssueId, loginUser.getUserid())
|
||||
.set(ExecutionStockInOrder::getIssueName, userRealName)
|
||||
@@ -597,7 +645,11 @@ public class ExecutionStockInOrderDomainService {
|
||||
.set(ExecutionStockInOrder::getUpdateBy, loginUser.getUserid())
|
||||
.set(ExecutionStockInOrder::getUpdateByName, userRealName)
|
||||
.set(ExecutionStockInOrder::getUpdateTime, new Date())
|
||||
.in(ExecutionStockInOrder::getInOrderId, distinctInOrderIds));
|
||||
.in(ExecutionStockInOrder::getInOrderId, distinctInOrderIds)
|
||||
.isNull(ExecutionStockInOrder::getIssueTime));
|
||||
if (!update) {
|
||||
throw new ServiceException("下发失败:单据已被并发下发,请刷新后查看");
|
||||
}
|
||||
|
||||
//todo下发推送到wms
|
||||
for (Long inOrderId : distinctInOrderIds) {
|
||||
@@ -612,7 +664,13 @@ public class ExecutionStockInOrderDomainService {
|
||||
stockInOrder.setOrganizationId(orgId);
|
||||
stockInOrder.setOrganizationName(orgName);
|
||||
stockInOrder.setTopOrganizationId(topOrgId);
|
||||
wmsServiceFeign.omsInOrderAdd(stockInOrder);
|
||||
//WMS保存结果必须校验:此前接口返回void、Feign降级被静默吞掉,OMS标记已下发但WMS无数据/缺明细,
|
||||
//收货流程无从进行(流程阻断);失败抛错回滚下发标记,WMS侧幂等(主单/明细判重),重下发安全
|
||||
AjaxResult addResult = wmsServiceFeign.omsInOrderAdd(stockInOrder);
|
||||
if (addResult == null || !"200".equals(String.valueOf(addResult.get("code")))) {
|
||||
throw new ServiceException("下发失败:入库单[" + stockInOrder.getInOrderNumber() + "]推送WMS保存主单失败:"
|
||||
+ (addResult == null ? "WMS服务不可用或已降级" : addResult.get("msg")));
|
||||
}
|
||||
String inOrderNumber = stockInOrder.getInOrderNumber();
|
||||
// 只推有效明细(del_flag=1),软删旧行不推WMS,防止WMS侧计划数量虚高
|
||||
List<ExecutionInMaterialDetail> materialDetailList = materialDetailService.list(new QueryWrapper<ExecutionInMaterialDetail>().lambda()
|
||||
@@ -633,7 +691,11 @@ public class ExecutionStockInOrderDomainService {
|
||||
}
|
||||
inMaterialDetailList.add(inMaterialDetail);
|
||||
}
|
||||
wmsServiceFeign.omsInOrderAddDetail(inMaterialDetailList);
|
||||
AjaxResult detailResult = wmsServiceFeign.omsInOrderAddDetail(inMaterialDetailList);
|
||||
if (detailResult == null || !"200".equals(String.valueOf(detailResult.get("code")))) {
|
||||
throw new ServiceException("下发失败:入库单[" + inOrderNumber + "]推送WMS保存明细失败:"
|
||||
+ (detailResult == null ? "WMS服务不可用或已降级" : detailResult.get("msg")));
|
||||
}
|
||||
}
|
||||
return update;
|
||||
}
|
||||
|
||||
+12
@@ -504,4 +504,16 @@ public class ExecutionStockOutOrder extends BaseVOEntity {
|
||||
@Excel(name = "车次")
|
||||
private String shuttleNo;
|
||||
|
||||
@ApiModelProperty("总仓租")
|
||||
private BigDecimal totalWarehouseRent;
|
||||
|
||||
@ApiModelProperty("业务计价类型")
|
||||
private String businessChargeType;
|
||||
|
||||
@ApiModelProperty("业务计价方式")
|
||||
private String businessPriceWay;
|
||||
|
||||
@ApiModelProperty("折扣")
|
||||
private BigDecimal discount;
|
||||
|
||||
}
|
||||
+12
@@ -516,4 +516,16 @@ public class ExecutionStockOutOrderPO extends BaseVOEntity {
|
||||
@ApiModelProperty("车次")
|
||||
@Excel(name = "车次")
|
||||
private String shuttleNo;
|
||||
|
||||
@ApiModelProperty("总仓租")
|
||||
private BigDecimal totalWarehouseRent;
|
||||
|
||||
@ApiModelProperty("业务计价类型")
|
||||
private String businessChargeType;
|
||||
|
||||
@ApiModelProperty("业务计价方式")
|
||||
private String businessPriceWay;
|
||||
|
||||
@ApiModelProperty("折扣")
|
||||
private BigDecimal discount;
|
||||
}
|
||||
+12
@@ -576,4 +576,16 @@ public class ExecutionStockOutOrderDO extends BaseVOEntity {
|
||||
|
||||
@ApiModelProperty("车次")
|
||||
private String shuttleNo;
|
||||
|
||||
@ApiModelProperty("总仓租")
|
||||
private BigDecimal totalWarehouseRent;
|
||||
|
||||
@ApiModelProperty("业务计价类型")
|
||||
private String businessChargeType;
|
||||
|
||||
@ApiModelProperty("业务计价方式")
|
||||
private String businessPriceWay;
|
||||
|
||||
@ApiModelProperty("折扣")
|
||||
private BigDecimal discount;
|
||||
}
|
||||
+12
@@ -564,4 +564,16 @@ public class ExecutionStockOutOrderDTO extends ExecutionStockOutOrderBaseDTO {
|
||||
|
||||
@ApiModelProperty("车次")
|
||||
private String shuttleNo;
|
||||
|
||||
@ApiModelProperty("总仓租")
|
||||
private BigDecimal totalWarehouseRent;
|
||||
|
||||
@ApiModelProperty("业务计价类型")
|
||||
private String businessChargeType;
|
||||
|
||||
@ApiModelProperty("业务计价方式")
|
||||
private String businessPriceWay;
|
||||
|
||||
@ApiModelProperty("折扣")
|
||||
private BigDecimal discount;
|
||||
}
|
||||
+4
@@ -381,6 +381,10 @@ public class ReservationInMaterialDetail extends BaseVOEntity {
|
||||
private Date drinkDate;
|
||||
@ApiModelProperty("火险保费")
|
||||
private BigDecimal fireInsureFee;
|
||||
@ApiModelProperty("夫力费")
|
||||
private BigDecimal manpowerFee;
|
||||
@ApiModelProperty("仓租费")
|
||||
private BigDecimal totalWarehouseRent;
|
||||
|
||||
|
||||
//订单行号
|
||||
|
||||
+4
@@ -483,6 +483,10 @@ public class ReservationInMaterialDetailPO extends ReservationStockInOrderBasePO
|
||||
private String lotNumber;
|
||||
@ApiModelProperty("火险保费")
|
||||
private BigDecimal fireInsureFee;
|
||||
@ApiModelProperty("夫力费")
|
||||
private BigDecimal manpowerFee;
|
||||
@ApiModelProperty("仓租费")
|
||||
private BigDecimal totalWarehouseRent;
|
||||
|
||||
//订单行号
|
||||
private String lineNumGw;
|
||||
|
||||
+4
@@ -448,6 +448,10 @@ public class ReservationInMaterialDetailDO extends ReservationStockInOrderBaseDO
|
||||
private BigDecimal unitPrice;
|
||||
@ApiModelProperty("火险保费")
|
||||
private BigDecimal fireInsureFee;
|
||||
@ApiModelProperty("夫力费")
|
||||
private BigDecimal manpowerFee;
|
||||
@ApiModelProperty("仓租费")
|
||||
private BigDecimal totalWarehouseRent;
|
||||
|
||||
//订单行号
|
||||
private String lineNumGw;
|
||||
|
||||
+4
@@ -455,6 +455,10 @@ public class ReservationInMaterialDetailDTO extends BaseVOEntity {
|
||||
private String productionDate;
|
||||
@ApiModelProperty("火险保费")
|
||||
private BigDecimal fireInsureFee;
|
||||
@ApiModelProperty("夫力费")
|
||||
private BigDecimal manpowerFee;
|
||||
@ApiModelProperty("仓租费")
|
||||
private BigDecimal totalWarehouseRent;
|
||||
|
||||
//订单行号
|
||||
private String lineNumGw;
|
||||
|
||||
+3
@@ -501,6 +501,9 @@ public class ReservationOutMaterialDetail extends BaseVOEntity {
|
||||
@Excel(name = "库存数量")
|
||||
private BigDecimal stockQuantity;
|
||||
|
||||
@ApiModelProperty("总仓租")
|
||||
private BigDecimal totalWarehouseRent;
|
||||
|
||||
|
||||
//订单行号
|
||||
private String lineNumGw;
|
||||
|
||||
+3
@@ -519,6 +519,9 @@ public class ReservationOutMaterialDetailPO extends ReservationStockOutOrderBase
|
||||
@Excel(name = "库存数量")
|
||||
private BigDecimal stockQuantity;
|
||||
|
||||
@ApiModelProperty("总仓租")
|
||||
private BigDecimal totalWarehouseRent;
|
||||
|
||||
@ApiModelProperty("出库异常明细:计划数量(复核异常场景=拣货数量)")
|
||||
@TableField(exist = false)
|
||||
private BigDecimal abnormalPlanQuantity;
|
||||
|
||||
+2
@@ -477,6 +477,8 @@ public class ReservationOutMaterialDetailDO extends BaseVOEntity {
|
||||
@Excel(name = "库存数量")
|
||||
private BigDecimal stockQuantity;
|
||||
|
||||
@ApiModelProperty("总仓租")
|
||||
private BigDecimal totalWarehouseRent;
|
||||
|
||||
@ApiModelProperty("调整前库存数量")
|
||||
@Excel(name = "调整前库存数量")
|
||||
|
||||
+2
@@ -469,6 +469,8 @@ public class ReservationOutMaterialDetailDTO extends BaseVOEntity {
|
||||
@Excel(name = "库存数量")
|
||||
private BigDecimal stockQuantity;
|
||||
|
||||
@ApiModelProperty("总仓租")
|
||||
private BigDecimal totalWarehouseRent;
|
||||
|
||||
@ApiModelProperty("调整前库存数量")
|
||||
@Excel(name = "调整前库存数量")
|
||||
|
||||
+3
@@ -70,4 +70,7 @@ public interface IReservationStockInOrderService extends IService<ReservationSto
|
||||
* @throws Exception 解析异常
|
||||
*/
|
||||
List<SheetImportResultDTO> parseStockInExcel(MultipartFile file, String sheetName) throws Exception;
|
||||
//StockInDataDTO parseStockInExcel(MultipartFile file, String sheetName) throws Exception;
|
||||
|
||||
public List<ReservationStockInOrderPO> queryPushBmsList();
|
||||
}
|
||||
+2
@@ -79,4 +79,6 @@ public interface ReservationStockInOrderMapper extends BaseMapper<ReservationSto
|
||||
int existsByOrderNumber(@Param("inOrderNumber") String inOrderNumber);
|
||||
|
||||
int existsByBusinessOrderNo(@Param("businessOrderNo") String businessOrderNo);
|
||||
|
||||
public List<ReservationStockInOrderPO> queryPushBmsList();
|
||||
}
|
||||
+22
@@ -336,6 +336,12 @@ public class ReservationStockInOrderImpl extends ServiceImpl<ReservationStockInO
|
||||
if (productDetailList.isEmpty()) {
|
||||
throw new Exception("未解析到产品明细数据,请检查模板中是否填写了產品編號");
|
||||
}
|
||||
// 行级必填校验:支数缺失的行直接给出明确提示,避免后续 new BigDecimal(null) 抛无信息的NPE
|
||||
for (ProductDetail productDetail : productDetailList) {
|
||||
if (productDetail.getPieceCount() == null) {
|
||||
throw new Exception("产品[" + productDetail.getProductCode() + "]的【支/件数】未填写,请补全后重新导入");
|
||||
}
|
||||
}
|
||||
|
||||
LOGGER.info("页签[{}]解析完成,货品明细{}条,客户配送明细{}条",
|
||||
sheetName, productDetailList.size(), customerDeliveryDetailList.size());
|
||||
@@ -658,6 +664,9 @@ public class ReservationStockInOrderImpl extends ServiceImpl<ReservationStockInO
|
||||
preparedOrders.add(prepared); // null=空页签,跳过
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 完整堆栈进服务端日志,便于定位页签内解析异常的具体行号
|
||||
LOGGER.error("页签[{}]入库导入解析失败", name, e);
|
||||
// 非模板页签的解析异常(如NPE)message 可能为空,兜底用异常类名,避免报错显示"页签[x]:null"
|
||||
sheetProblems.add("页签[" + name + "]:" + (e.getMessage() == null ? e.toString() : e.getMessage()));
|
||||
}
|
||||
}
|
||||
@@ -710,6 +719,15 @@ public class ReservationStockInOrderImpl extends ServiceImpl<ReservationStockInO
|
||||
if (productDetailList == null || productDetailList.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
// 行级必填校验:编号/支数缺失的行直接给出明确提示,避免后续 new BigDecimal(null) 抛无信息的NPE
|
||||
for (StockInProductDetail productDetail : productDetailList) {
|
||||
if (productDetail.getProductCode() == null || productDetail.getProductCode().trim().isEmpty()) {
|
||||
throw new ServiceException("存在未填写【產品編號】的明细行,请补全后重新导入");
|
||||
}
|
||||
if (productDetail.getPieceCount() == null) {
|
||||
throw new ServiceException("产品[" + productDetail.getProductCode() + "]的【支/件数】未填写,请补全后重新导入");
|
||||
}
|
||||
}
|
||||
StockInHeader stockInHeader = resultDTO.getStockInHeader();
|
||||
// ====== 第一步:物料编号存在性校验(模板只填物料编号即可,名称按编号自动匹配) ======
|
||||
// 查询结果为空说明库中没有该物料,先收集全部缺失编号,不立即报错
|
||||
@@ -1091,5 +1109,9 @@ public class ReservationStockInOrderImpl extends ServiceImpl<ReservationStockInO
|
||||
}
|
||||
}
|
||||
|
||||
public List<ReservationStockInOrderPO> queryPushBmsList() {
|
||||
return stockInOrderMapper.queryPushBmsList();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+23
@@ -18,6 +18,8 @@ import com.mhd.oms.domain.gwLog.repository.mapper.GwLogMapper;
|
||||
import com.mhd.oms.domain.reservationInMaterialDetail.entity.ReservationInMaterialDetail;
|
||||
import com.mhd.oms.domain.reservationInMaterialDetail.repository.mapper.ReservationInMaterialDetailMapper;
|
||||
import com.mhd.oms.domain.reservationInMaterialDetail.repository.po.ReservationInMaterialDetailPO;
|
||||
import com.mhd.oms.domain.reservationMaterialInventory.repository.facade.IReservationMaterialInventoryService;
|
||||
import com.mhd.oms.domain.reservationMaterialInventory.repository.mapper.ReservationMaterialInventoryMapper;
|
||||
import com.mhd.oms.domain.reservationStockInOrder.entity.ReservationStockInOrder;
|
||||
import com.mhd.oms.domain.reservationStockInOrder.repository.mapper.ReservationStockInOrderMapper;
|
||||
import com.mhd.oms.domain.reservationStockInOrder.repository.po.MaterialBaseInfoPO;
|
||||
@@ -76,6 +78,8 @@ public class ReservationStockInOrderApplicationService {
|
||||
private ReservationStockInOrderMapper reservationStockInOrderMapper;
|
||||
@Autowired
|
||||
private ReservationInMaterialDetailMapper reservationInMaterialDetailMapper;
|
||||
@Autowired
|
||||
private IReservationMaterialInventoryService reservationMaterialInventoryService;
|
||||
// @Autowired
|
||||
// private IMaterialBaseInfoService materialBaseInfoService;
|
||||
private static final String PUSH_API_URL = "http://10.102.192.15/nagu-erp-api/transfer/pushData";
|
||||
@@ -2285,4 +2289,23 @@ public class ReservationStockInOrderApplicationService {
|
||||
public String generateReserveOrderNumber1() {
|
||||
return stockInOrderDomainService.generateReserveOrderNumber1();
|
||||
}
|
||||
|
||||
public List<ReservationStockInOrderPO> queryPushBmsList() {
|
||||
return stockInOrderDomainService.queryPushBmsList();
|
||||
}
|
||||
|
||||
public void pushBillingRecord() {
|
||||
|
||||
//reservationMaterialInventoryService
|
||||
// 当天应该推送的数据
|
||||
List<ReservationStockInOrderPO> reservationStockInOrderPOS = stockInOrderDomainService.queryPushBmsList();
|
||||
if (reservationStockInOrderPOS!=null&&reservationStockInOrderPOS.size()>0){
|
||||
for (ReservationStockInOrderPO reservationStockInOrderPO : reservationStockInOrderPOS) {
|
||||
String inOrderNumber = reservationStockInOrderPO.getInOrderNumber();
|
||||
ReservationInMaterialDetail reservationInMaterialDetail = reservationInMaterialDetailMapper.selectOne(new LambdaQueryWrapper<ReservationInMaterialDetail>()
|
||||
.eq(ReservationInMaterialDetail::getInOrderNumber, inOrderNumber)
|
||||
.eq(ReservationInMaterialDetail::getDelFlag, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+41
-35
@@ -525,9 +525,14 @@ public class ReservationStockInOrderDomainService {
|
||||
if (inOrderIds == null || inOrderIds.isEmpty()) {
|
||||
throw new ServiceException("下发失败:未选择单据");
|
||||
}
|
||||
// 只校验有效单据:软删单混入ID(过期页面提交)时在此拦截
|
||||
List<ReservationStockInOrder> checkOrders = stockInOrderService.list(
|
||||
new QueryWrapper<ReservationStockInOrder>().lambda()
|
||||
.in(ReservationStockInOrder::getInOrderId, inOrderIds));
|
||||
.in(ReservationStockInOrder::getInOrderId, inOrderIds)
|
||||
.eq(ReservationStockInOrder::getDelFlag, 1));
|
||||
if (checkOrders.size() != inOrderIds.stream().distinct().count()) {
|
||||
throw new ServiceException("下发失败:存在已删除的单据,请刷新后重新选择");
|
||||
}
|
||||
for (ReservationStockInOrder order : checkOrders) {
|
||||
// 校验1:必须已审核(issueStatus==2 表示审核成功)
|
||||
if (order.getIssueStatus() == null || order.getIssueStatus() != 2) {
|
||||
@@ -560,40 +565,12 @@ public class ReservationStockInOrderDomainService {
|
||||
.set(ReservationStockInOrder::getUpdateTime, new Date())
|
||||
.in(ReservationStockInOrder::getInOrderId, stockInOrderDO.getInOrderIds()));
|
||||
|
||||
//todo下发推送到wms
|
||||
for (Long inOrderId : inOrderIds) {
|
||||
ReservationStockInOrder byId = stockInOrderService.getById(inOrderId);
|
||||
StockInOrder stockInOrder = new StockInOrder();
|
||||
BeanUtils.copyProperties(byId, stockInOrder, "inOrderId");
|
||||
stockInOrder.setOmsStockInOrderId(String.valueOf(byId.getInOrderId()));
|
||||
// 业务链路(2026-09与业务确认,生产验证):预约单下发→生成执行单→执行单下发时才推送WMS。
|
||||
// 预约单下发此前会先把预约单自身推到WMS(omsInOrderAdd/omsInOrderAddDetail),执行单下发又推一次,
|
||||
// 导致WMS入库管理出现预约单号(R260907001)+执行单号(RK260907001)两张单、仓库收两道货。
|
||||
// 已移除预约单的WMS推送,WMS推送唯一入口收敛到 ExecutionStockInOrderDomainService.issueOrder。
|
||||
// 历史已推送的预约单数据由"取消下发"(cancelIssueOrder→omsCancelInOrder,幂等)负责清理。
|
||||
|
||||
try {
|
||||
wmsServiceFeign.omsInOrderAdd(stockInOrder); // 推主单
|
||||
|
||||
String inOrderNumber = stockInOrder.getInOrderNumber();
|
||||
List<ReservationInMaterialDetail> materialDetailList = materialDetailService.list(
|
||||
new QueryWrapper<ReservationInMaterialDetail>().lambda()
|
||||
.eq(ReservationInMaterialDetail::getInOrderNumber, inOrderNumber)
|
||||
.eq(ReservationInMaterialDetail::getDelFlag, 1));
|
||||
List<InMaterialDetail> inMaterialDetailList = new ArrayList<>();
|
||||
for (ReservationInMaterialDetail reservationInMaterialDetail : materialDetailList) {
|
||||
InMaterialDetail inMaterialDetail = new InMaterialDetail();
|
||||
BeanUtils.copyProperties(reservationInMaterialDetail, inMaterialDetail, "materialDetailId");
|
||||
inMaterialDetail.setOmsInMaterialDetail(String.valueOf(reservationInMaterialDetail.getMaterialDetailId()));
|
||||
// 过期日期为空且饮用日期有值时,用饮用日期补齐过期日期(食品业务饮用日期即效期),
|
||||
// 确保下发WMS后入库/收货/库存链路的过期日期能正常回显
|
||||
if (inMaterialDetail.getExpiryDate() == null && inMaterialDetail.getDrinkDate() != null) {
|
||||
inMaterialDetail.setExpiryDate(inMaterialDetail.getDrinkDate());
|
||||
}
|
||||
inMaterialDetailList.add(inMaterialDetail);
|
||||
}
|
||||
wmsServiceFeign.omsInOrderAddDetail(inMaterialDetailList); // 推明细(会触发WMS自动审核)
|
||||
log.info("下发到WMS成功,单据号:{}", byId.getInOrderNumber());
|
||||
} catch (Exception e) {
|
||||
log.error("下发到WMS失败,单据号:{}", byId.getInOrderNumber(), e);
|
||||
throw new ServiceException("下发到WMS失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
//todo下发推送到入库业务单
|
||||
for (Long inOrderId : inOrderIds) {
|
||||
// Long inOrderId = stockInOrderDO.getInOrderId();
|
||||
@@ -748,11 +725,17 @@ public class ReservationStockInOrderDomainService {
|
||||
for (Long inOrderId : inOrderIds) {
|
||||
ReservationStockInOrder byId = stockInOrderService.getById(inOrderId);
|
||||
String inOrderNumber = byId.getInOrderNumber();
|
||||
//清理预约单自身下发到WMS的数据(下发时omsInOrderAdd推过主单/明细并自动审核生成收货链路)
|
||||
cancelWmsInOrder(inOrderNumber);
|
||||
List<ExecutionStockInOrder> list = executionStockInOrderService.list(new QueryWrapper<ExecutionStockInOrder>().lambda()
|
||||
.eq(ExecutionStockInOrder::getBusinessInOrderNumber, inOrderNumber)
|
||||
.eq(ExecutionStockInOrder::getDelFlag, 1));
|
||||
for (ExecutionStockInOrder executionStockInOrder : list) {
|
||||
String inOrderNumber1 = executionStockInOrder.getInOrderNumber();
|
||||
//已下发的执行单同步清理WMS侧数据(与执行单取消下发同一清理接口,未下发则WMS无数据幂等跳过)
|
||||
if (executionStockInOrder.getIssueTime() != null) {
|
||||
cancelWmsInOrder(inOrderNumber1);
|
||||
}
|
||||
List<ExecutionInMaterialDetail> materialDetails = executionInMaterialDetailService.list(new QueryWrapper<ExecutionInMaterialDetail>().lambda()
|
||||
.eq(ExecutionInMaterialDetail::getInOrderNumber, inOrderNumber1)
|
||||
.eq(ExecutionInMaterialDetail::getDelFlag, 1));
|
||||
@@ -770,6 +753,20 @@ public class ReservationStockInOrderDomainService {
|
||||
return update;
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用WMS清理接口回退下发产生的数据(入库单/明细、收货单/明细、收货任务、收货作业单/明细、质检单),
|
||||
* WMS侧已开始收货会返回错误在此抛出,保证不会误删真实收货数据
|
||||
*/
|
||||
private void cancelWmsInOrder(String inOrderNumber) {
|
||||
StockInOrder cancelParam = new StockInOrder();
|
||||
cancelParam.setInOrderNumber(inOrderNumber);
|
||||
AjaxResult cancelResult = wmsServiceFeign.omsCancelInOrder(cancelParam);
|
||||
if (cancelResult == null || !"200".equals(String.valueOf(cancelResult.get("code")))) {
|
||||
throw new ServiceException("取消下发失败:入库单[" + inOrderNumber + "]WMS数据清理失败:"
|
||||
+ (cancelResult == null ? "WMS服务不可用或已降级" : cancelResult.get("msg")));
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean executeAndIssue(ReservationStockInOrderDO stockInOrderDO) {
|
||||
// 防重复执行校验(与 issueOrder 的防重逻辑对齐):issueTime 有值表示已下发/执行过。
|
||||
@@ -778,9 +775,14 @@ public class ReservationStockInOrderDomainService {
|
||||
if (inOrderIds == null || inOrderIds.isEmpty()) {
|
||||
throw new ServiceException("执行失败:未选择单据");
|
||||
}
|
||||
// 只校验有效单据:软删单混入ID(过期页面提交)时在此拦截(与 issueOrder 校验口径一致)
|
||||
List<ReservationStockInOrder> checkOrders = stockInOrderService.list(
|
||||
new QueryWrapper<ReservationStockInOrder>().lambda()
|
||||
.in(ReservationStockInOrder::getInOrderId, inOrderIds));
|
||||
.in(ReservationStockInOrder::getInOrderId, inOrderIds)
|
||||
.eq(ReservationStockInOrder::getDelFlag, 1));
|
||||
if (checkOrders.size() != inOrderIds.stream().distinct().count()) {
|
||||
throw new ServiceException("执行失败:存在已删除的单据,请刷新后重新选择");
|
||||
}
|
||||
for (ReservationStockInOrder order : checkOrders) {
|
||||
if (order.getIssueTime() != null) {
|
||||
throw new ServiceException("执行失败:单据[" + order.getInOrderNumber() + "]已下发,不可重复执行;如需重新下发请先取消下发");
|
||||
@@ -1493,4 +1495,8 @@ public class ReservationStockInOrderDomainService {
|
||||
// 与 generateReserveOrderNumber 收敛为同一套跨表取号逻辑,避免两份实现日后分叉
|
||||
return generateReserveOrderNumber();
|
||||
}
|
||||
|
||||
public List<ReservationStockInOrderPO> queryPushBmsList() {
|
||||
return stockInOrderService.queryPushBmsList();
|
||||
}
|
||||
}
|
||||
+12
@@ -503,4 +503,16 @@ public class ReservationStockOutOrder extends BaseVOEntity {
|
||||
@Excel(name = "车次")
|
||||
private String shuttleNo;
|
||||
|
||||
@ApiModelProperty("总仓租")
|
||||
private BigDecimal totalWarehouseRent;
|
||||
|
||||
@ApiModelProperty("业务计价类型")
|
||||
private String businessChargeType;
|
||||
|
||||
@ApiModelProperty("业务计价方式")
|
||||
private String businessPriceWay;
|
||||
|
||||
@ApiModelProperty("折扣")
|
||||
private BigDecimal discount;
|
||||
|
||||
}
|
||||
+12
@@ -526,4 +526,16 @@ public class ReservationStockOutOrderPO extends BaseVOEntity {
|
||||
@Excel(name = "车次")
|
||||
private String shuttleNo;
|
||||
|
||||
@ApiModelProperty("总仓租")
|
||||
private BigDecimal totalWarehouseRent;
|
||||
|
||||
@ApiModelProperty("业务计价类型")
|
||||
private String businessChargeType;
|
||||
|
||||
@ApiModelProperty("业务计价方式")
|
||||
private String businessPriceWay;
|
||||
|
||||
@ApiModelProperty("折扣")
|
||||
private BigDecimal discount;
|
||||
|
||||
}
|
||||
+12
@@ -579,4 +579,16 @@ public class ReservationStockOutOrderDO extends BaseVOEntity {
|
||||
@ApiModelProperty("车次")
|
||||
private String shuttleNo;
|
||||
|
||||
@ApiModelProperty("总仓租")
|
||||
private BigDecimal totalWarehouseRent;
|
||||
|
||||
@ApiModelProperty("业务计价类型")
|
||||
private String businessChargeType;
|
||||
|
||||
@ApiModelProperty("业务计价方式")
|
||||
private String businessPriceWay;
|
||||
|
||||
@ApiModelProperty("折扣")
|
||||
private BigDecimal discount;
|
||||
|
||||
}
|
||||
+12
@@ -568,4 +568,16 @@ public class ReservationStockOutOrderDTO extends ReservationStockOutOrderBaseDTO
|
||||
@ApiModelProperty("车次")
|
||||
private String shuttleNo;
|
||||
|
||||
@ApiModelProperty("总仓租")
|
||||
private BigDecimal totalWarehouseRent;
|
||||
|
||||
@ApiModelProperty("业务计价类型")
|
||||
private String businessChargeType;
|
||||
|
||||
@ApiModelProperty("业务计价方式")
|
||||
private String businessPriceWay;
|
||||
|
||||
@ApiModelProperty("折扣")
|
||||
private BigDecimal discount;
|
||||
|
||||
}
|
||||
@@ -22,7 +22,7 @@ import java.util.Map;
|
||||
/**
|
||||
* 三方服务 Feign
|
||||
*/
|
||||
@FeignClient(contextId = "thirdPartyServiceFeign",url = "http://10.102.192.30:8012", value = ServiceNameConstants.THIRDPARTY_CENTER, configuration = FeignAutoConfiguration.class)
|
||||
@FeignClient(contextId = "thirdPartyServiceFeign",url = "http://10.33.0.129:8012", value = ServiceNameConstants.THIRDPARTY_CENTER, configuration = FeignAutoConfiguration.class)
|
||||
public interface ThirdPartyServiceFeign {
|
||||
|
||||
//查询当前组织所有三方接口信息
|
||||
|
||||
+22
@@ -17,6 +17,8 @@ import com.mhd.system.api.domain.InMaterialDetail;
|
||||
import com.mhd.system.api.domain.InMaterialDetailTZPD;
|
||||
import com.mhd.system.api.domain.StockInOrder;
|
||||
import com.mhd.system.api.domain.StockInOrderTZPD;
|
||||
import com.xxl.job.core.context.XxlJobHelper;
|
||||
import com.xxl.job.core.handler.annotation.XxlJob;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
@@ -313,4 +315,24 @@ public class ReservationStockInOrderApi extends BaseController {
|
||||
return AjaxResult.success(stockInOrderApplicationService.generateReserveOrderNumber1());
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. 简单任务示例(Bean模式)
|
||||
* 这里的 demoJobHandler 必须和调度中心配置一致
|
||||
*/
|
||||
// @XxlJob("pushBillingRecord")
|
||||
public void pushBillingRecord() {
|
||||
// 获取任务参数
|
||||
String param = XxlJobHelper.getJobParam();
|
||||
logger.info("XXL-JOB 开始入库业务单推送bms计费流水,参数:{}", param);
|
||||
|
||||
try {
|
||||
stockInOrderApplicationService.pushBillingRecord();
|
||||
// 设置任务执行结果
|
||||
XxlJobHelper.handleSuccess("入库业务单推送bms计费流水执行成功");
|
||||
} catch (Exception e) {
|
||||
logger.error("XXL-JOB 执行失败", e);
|
||||
XxlJobHelper.handleFail("入库业务单推送bms计费流水执行失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user