feat(oms):出库导入校验送貨線號/車次并回填线路名称
1. 出库导入(预约/执行两侧)增加validateLineAndShuttle校验: 送貨線號/車次缺失直接报错;线路须在WMS线路管理存在(route_code精确匹配); 车次须在该线路车次清单(shuttle_json)内;校验通过回填lineName, 线路/车次一并落lineCode/lineName/shuttleNo。 2. WmsServiceFeign新增listLineManagement(复用WMS /lineManagementApi/listByApp) 供OMS跨库查线路,附降级实现;顺带移除FeignClient写死的本机url,恢复Nacos服务发现。 3. 执行侧DynamicDeliveryExcelListener(关键字版)补送貨線號/車次独立成行的解析, 原实现仅支持与送貨日期同行取值,该模板为分行布局导致解析不到。
This commit is contained in:
@@ -151,4 +151,12 @@ public interface WmsServiceFeign {
|
||||
@ApiOperation("OMS批量签名-同步WMS入/出库单签名字段")
|
||||
@PostMapping("/stockSignatureApi/batchSign")
|
||||
public AjaxResult batchSignWms(@RequestBody SignatureBatchFeignDTO dto);
|
||||
|
||||
/**
|
||||
* OMS查询WMS线路管理列表(按线路编码模糊查,OMS侧自行精确匹配),
|
||||
* 出库导入时校验送貨線號/車次并回填线路名称
|
||||
*/
|
||||
@ApiOperation("OMS查询WMS线路管理列表")
|
||||
@GetMapping("/lineManagementApi/listByApp")
|
||||
public AjaxResult listLineManagement(@RequestParam("routeCode") String routeCode);
|
||||
}
|
||||
+6
@@ -125,6 +125,12 @@ public class RemoteWmsFallbackFactory implements FallbackFactory<WmsServiceFeign
|
||||
log.error("WMS批量签名调用失败");
|
||||
return AjaxResult.error("WMS批量签名调用失败:" + cause.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public AjaxResult listLineManagement(String routeCode) {
|
||||
log.error("OMS查询WMS线路管理失败, routeCode:{}", routeCode);
|
||||
return AjaxResult.error("WMS线路管理查询失败:" + cause.getMessage());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+16
@@ -34,6 +34,8 @@ public class DynamicDeliveryExcelListener extends AnalysisEventListener<Map<Stri
|
||||
private static final Pattern DECIMAL_PATTERN = Pattern.compile("-?\\d+(\\.\\d+)?");
|
||||
// 关键字定义(Excel标签匹配)
|
||||
private static final String KEYWORD_DELIVERY_DATE = "送貨日期";
|
||||
private static final String KEYWORD_DELIVERY_LINE_NO = "送貨線號";
|
||||
private static final String KEYWORD_TRAIN_NUMBER = "車次";
|
||||
private static final String KEYWORD_PRODUCT_DETAIL = "货品明细";
|
||||
private static final String KEYWORD_TOTAL_RECORD = "紀錄合共";
|
||||
private static final String KEYWORD_CUSTOMER_DETAIL = "客户配送明细";
|
||||
@@ -89,6 +91,20 @@ public class DynamicDeliveryExcelListener extends AnalysisEventListener<Map<Stri
|
||||
// 空闲状态:解析表头信息(送货日期行,多单元格数据)
|
||||
if (firstCellValue.contains(KEYWORD_DELIVERY_DATE)) {
|
||||
parseHeaderInfo(data, rowNum);
|
||||
} else if (firstCellValue.contains(KEYWORD_DELIVERY_LINE_NO)) {
|
||||
// 送货线号独立成行(A列=标签,B列=值),覆盖parseHeaderInfo按同行取值的兜底逻辑
|
||||
String deliveryLineNo = getValueSafely(data, 1, String.class);
|
||||
if (deliveryLineNo != null && !deliveryLineNo.trim().isEmpty()) {
|
||||
deliveryHeader.setDeliveryLineNo(deliveryLineNo.trim());
|
||||
}
|
||||
LOGGER.debug("第{}行:解析送货线号={}", rowNum, deliveryLineNo);
|
||||
} else if (firstCellValue.contains(KEYWORD_TRAIN_NUMBER)) {
|
||||
// 车次独立成行(A列=标签,B列=值)
|
||||
Integer trainNumber = getValueSafely(data, 1, Integer.class);
|
||||
if (trainNumber != null) {
|
||||
deliveryHeader.setTrainNumber(trainNumber);
|
||||
}
|
||||
LOGGER.debug("第{}行:解析车次={}", rowNum, trainNumber);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
+67
@@ -1,6 +1,7 @@
|
||||
package com.mhd.oms.domain.executionStockInOrder.repository.persistence;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.json.JSONArray;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
@@ -36,6 +37,7 @@ import com.mhd.oms.domain.reservationDeliveryDetailsLink.entity.ReservationDeliv
|
||||
import com.mhd.oms.domain.reservationDeliveryDetailsLink.repository.facade.IReservationDeliveryDetailsLinkService;
|
||||
import com.mhd.system.api.SystemServiceFeign;
|
||||
import com.mhd.system.api.UserServiceFeign;
|
||||
import com.mhd.system.api.WmsServiceFeign;
|
||||
import com.mhd.system.api.domain.SysDictData;
|
||||
import com.mhd.system.api.domain.WarehouseFeignPO;
|
||||
import com.mhd.system.api.domain.cache.AssociationWarehouseCacheDO;
|
||||
@@ -67,6 +69,8 @@ public class ExecutionStockInOrderImpl extends ServiceImpl<ExecutionStockInOrder
|
||||
@Autowired
|
||||
private ExecutionStockOutOrderMapper stockOutOrderMapper;
|
||||
@Autowired
|
||||
private WmsServiceFeign wmsServiceFeign;
|
||||
@Autowired
|
||||
private IReservationDeliveryDetailsLinkService reservationDeliveryDetailsLinkService;
|
||||
@Autowired
|
||||
private ExecutionStockOutOrderApplicationService reservationStockOutOrderApplicationService;
|
||||
@@ -144,6 +148,64 @@ public class ExecutionStockInOrderImpl extends ServiceImpl<ExecutionStockInOrder
|
||||
return stockInOrderMapper.queryNoticePrintDetail(stockInOrderDO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 出库导入-送貨線號(线路)/車次校验
|
||||
* 1.送貨線號/車次缺失直接报错
|
||||
* 2.线路须存在于WMS线路管理(line_management,按route_code精确匹配)
|
||||
* 3.车次须在该线路维护的车次清单(shuttle_json)内
|
||||
* 校验通过返回线路名称,用于回填lineName
|
||||
*/
|
||||
private String validateLineAndShuttle(DeliveryHeader deliveryHeader) throws Exception {
|
||||
String lineCode = deliveryHeader.getDeliveryLineNo();
|
||||
Integer trainNumber = deliveryHeader.getTrainNumber();
|
||||
if (StringUtils.isBlank(lineCode)) {
|
||||
throw new Exception("Excel未识别到【送貨線號】(线路),请检查模板第2行后重新导入");
|
||||
}
|
||||
if (trainNumber == null || trainNumber <= 0) {
|
||||
throw new Exception("Excel未识别到【車次】,请检查模板第3行后重新导入");
|
||||
}
|
||||
AjaxResult lineResult = wmsServiceFeign.listLineManagement(lineCode);
|
||||
if (lineResult == null || lineResult.get(AjaxResult.DATA_TAG) == null) {
|
||||
throw new Exception("查询WMS线路管理失败,请稍后重试");
|
||||
}
|
||||
String lineName = null;
|
||||
String shuttleJson = null;
|
||||
boolean lineFound = false;
|
||||
List<Map<String, Object>> lineList = (List<Map<String, Object>>) lineResult.get(AjaxResult.DATA_TAG);
|
||||
for (Map<String, Object> line : lineList) {
|
||||
//listByApp按routeCode模糊查,此处做精确匹配
|
||||
if (lineCode.equals(String.valueOf(line.get("routeCode")))) {
|
||||
lineFound = true;
|
||||
Object routeName = line.get("routeName");
|
||||
lineName = routeName == null ? null : String.valueOf(routeName);
|
||||
Object shuttleObj = line.get("shuttleJson");
|
||||
shuttleJson = shuttleObj == null ? null : String.valueOf(shuttleObj);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!lineFound) {
|
||||
throw new Exception("线路【" + lineCode + "】在WMS线路管理中不存在,请先在基础数据-线路管理中维护");
|
||||
}
|
||||
boolean shuttleMatched = false;
|
||||
if (StringUtils.isNotBlank(shuttleJson)) {
|
||||
try {
|
||||
JSONArray shuttleArray = JSONUtil.parseArray(shuttleJson);
|
||||
for (Object shuttle : shuttleArray) {
|
||||
if (String.valueOf(trainNumber).equals(String.valueOf(shuttle))) {
|
||||
shuttleMatched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
shuttleMatched = false;
|
||||
}
|
||||
}
|
||||
if (!shuttleMatched) {
|
||||
throw new Exception("线路【" + lineCode + "】维护的车次清单(" + shuttleJson + ")中不存在车次【" + trainNumber + "】,请先在WMS线路管理中维护该车次");
|
||||
}
|
||||
return StringUtils.isNotBlank(lineName) ? lineName : lineCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeliveryDataDTO parseExcelFile(MultipartFile file, String sheetName) throws Exception {
|
||||
LoginUser loginUser = SecurityUtils.getLoginUser();
|
||||
@@ -223,6 +285,11 @@ public class ExecutionStockInOrderImpl extends ServiceImpl<ExecutionStockInOrder
|
||||
reservationStockOutOrderDO.setReservationOrderSource("数据导入");
|
||||
reservationStockOutOrderDO.setOutboundDate(deliveryHeader.getDeliveryDate());
|
||||
reservationStockOutOrderDO.setTrainNo(deliveryHeader.getTrainNumber());
|
||||
//送貨線號(线路)/車次校验:必填、线路须在WMS线路管理存在、车次须在线路车次清单内;通过后回填线路名称
|
||||
String lineName = validateLineAndShuttle(deliveryHeader);
|
||||
reservationStockOutOrderDO.setLineCode(deliveryHeader.getDeliveryLineNo());
|
||||
reservationStockOutOrderDO.setLineName(lineName);
|
||||
reservationStockOutOrderDO.setShuttleNo(String.valueOf(deliveryHeader.getTrainNumber()));
|
||||
int index = 1;
|
||||
List<ExecutionOutMaterialDetailDO> reservationOutMaterialDetailDOList = new ArrayList<>();
|
||||
for (ProductDetail productDetail : productDetailList) {
|
||||
|
||||
+67
@@ -1,6 +1,7 @@
|
||||
package com.mhd.oms.domain.reservationStockInOrder.repository.persistence;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.json.JSONArray;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
@@ -42,6 +43,7 @@ import com.mhd.oms.domain.reservationStockOutOrder.service.ReservationStockOutOr
|
||||
import com.mhd.oms.domain.reserveStockInOrder.repository.mapper.ReserveStockInOrderMapper;
|
||||
import com.mhd.system.api.SystemServiceFeign;
|
||||
import com.mhd.system.api.UserServiceFeign;
|
||||
import com.mhd.system.api.WmsServiceFeign;
|
||||
import com.mhd.system.api.domain.SysDictData;
|
||||
import com.mhd.system.api.domain.WarehouseFeignPO;
|
||||
import com.mhd.system.api.domain.cache.AssociationWarehouseCacheDO;
|
||||
@@ -73,6 +75,8 @@ public class ReservationStockInOrderImpl extends ServiceImpl<ReservationStockInO
|
||||
@Autowired
|
||||
private ReservationStockOutOrderMapper stockOutOrderMapper;
|
||||
@Autowired
|
||||
private WmsServiceFeign wmsServiceFeign;
|
||||
@Autowired
|
||||
private IReservationDeliveryDetailsLinkService reservationDeliveryDetailsLinkService;
|
||||
@Autowired
|
||||
private IReservationStockOutOrderService reservationStockOutOrderService;
|
||||
@@ -157,6 +161,64 @@ public class ReservationStockInOrderImpl extends ServiceImpl<ReservationStockInO
|
||||
return stockInOrderMapper.queryNoticePrintDetail(stockInOrderDO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 出库导入-送貨線號(线路)/車次校验
|
||||
* 1.送貨線號/車次缺失直接报错
|
||||
* 2.线路须存在于WMS线路管理(line_management,按route_code精确匹配)
|
||||
* 3.车次须在该线路维护的车次清单(shuttle_json)内
|
||||
* 校验通过返回线路名称,用于回填lineName
|
||||
*/
|
||||
private String validateLineAndShuttle(DeliveryHeader deliveryHeader) throws Exception {
|
||||
String lineCode = deliveryHeader.getDeliveryLineNo();
|
||||
Integer trainNumber = deliveryHeader.getTrainNumber();
|
||||
if (StringUtils.isBlank(lineCode)) {
|
||||
throw new Exception("Excel未识别到【送貨線號】(线路),请检查模板第2行后重新导入");
|
||||
}
|
||||
if (trainNumber == null || trainNumber <= 0) {
|
||||
throw new Exception("Excel未识别到【車次】,请检查模板第3行后重新导入");
|
||||
}
|
||||
AjaxResult lineResult = wmsServiceFeign.listLineManagement(lineCode);
|
||||
if (lineResult == null || lineResult.get(AjaxResult.DATA_TAG) == null) {
|
||||
throw new Exception("查询WMS线路管理失败,请稍后重试");
|
||||
}
|
||||
String lineName = null;
|
||||
String shuttleJson = null;
|
||||
boolean lineFound = false;
|
||||
List<Map<String, Object>> lineList = (List<Map<String, Object>>) lineResult.get(AjaxResult.DATA_TAG);
|
||||
for (Map<String, Object> line : lineList) {
|
||||
//listByApp按routeCode模糊查,此处做精确匹配
|
||||
if (lineCode.equals(String.valueOf(line.get("routeCode")))) {
|
||||
lineFound = true;
|
||||
Object routeName = line.get("routeName");
|
||||
lineName = routeName == null ? null : String.valueOf(routeName);
|
||||
Object shuttleObj = line.get("shuttleJson");
|
||||
shuttleJson = shuttleObj == null ? null : String.valueOf(shuttleObj);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!lineFound) {
|
||||
throw new Exception("线路【" + lineCode + "】在WMS线路管理中不存在,请先在基础数据-线路管理中维护");
|
||||
}
|
||||
boolean shuttleMatched = false;
|
||||
if (StringUtils.isNotBlank(shuttleJson)) {
|
||||
try {
|
||||
JSONArray shuttleArray = JSONUtil.parseArray(shuttleJson);
|
||||
for (Object shuttle : shuttleArray) {
|
||||
if (String.valueOf(trainNumber).equals(String.valueOf(shuttle))) {
|
||||
shuttleMatched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
shuttleMatched = false;
|
||||
}
|
||||
}
|
||||
if (!shuttleMatched) {
|
||||
throw new Exception("线路【" + lineCode + "】维护的车次清单(" + shuttleJson + ")中不存在车次【" + trainNumber + "】,请先在WMS线路管理中维护该车次");
|
||||
}
|
||||
return StringUtils.isNotBlank(lineName) ? lineName : lineCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeliveryDataDTO parseExcelFile(MultipartFile file, String sheetName) throws Exception {
|
||||
LoginUser loginUser = SecurityUtils.getLoginUser();
|
||||
@@ -258,6 +320,11 @@ public class ReservationStockInOrderImpl extends ServiceImpl<ReservationStockInO
|
||||
reservationStockOutOrderDO.setReservationOrderSource("数据导入");
|
||||
reservationStockOutOrderDO.setOutboundDate(deliveryHeader.getDeliveryDate());
|
||||
reservationStockOutOrderDO.setTrainNo(deliveryHeader.getTrainNumber());
|
||||
//送貨線號(线路)/車次校验:必填、线路须在WMS线路管理存在、车次须在线路车次清单内;通过后回填线路名称
|
||||
String lineName = validateLineAndShuttle(deliveryHeader);
|
||||
reservationStockOutOrderDO.setLineCode(deliveryHeader.getDeliveryLineNo());
|
||||
reservationStockOutOrderDO.setLineName(lineName);
|
||||
reservationStockOutOrderDO.setShuttleNo(String.valueOf(deliveryHeader.getTrainNumber()));
|
||||
int index = 1;
|
||||
List<ReservationOutMaterialDetailDO> reservationOutMaterialDetailDOList = new ArrayList<>();
|
||||
for (ProductDetail productDetail : productDetailList) {
|
||||
|
||||
Reference in New Issue
Block a user