Merge remote-tracking branch 'origin/wms_dev' into wms_dev
This commit is contained in:
+275
-2
@@ -1,17 +1,31 @@
|
|||||||
package com.mhd.wms.application.service.inventoryAdjustmentRecord;
|
package com.mhd.wms.application.service.inventoryAdjustmentRecord;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.mhd.common.core.utils.StringUtils;
|
||||||
|
import com.mhd.common.core.web.domain.AjaxResult;
|
||||||
import com.mhd.common.security.utils.SecurityUtils;
|
import com.mhd.common.security.utils.SecurityUtils;
|
||||||
|
import com.mhd.system.api.SystemServiceFeign;
|
||||||
|
import com.mhd.system.api.domain.BatchDetailFeignPO;
|
||||||
import com.mhd.system.api.domain.cache.AssociationWarehouseCacheDO;
|
import com.mhd.system.api.domain.cache.AssociationWarehouseCacheDO;
|
||||||
import com.mhd.system.api.domain.cache.SystemServiceCacheUtil;
|
import com.mhd.system.api.domain.cache.SystemServiceCacheUtil;
|
||||||
import com.mhd.system.api.model.LoginUser;
|
import com.mhd.system.api.model.LoginUser;
|
||||||
import com.mhd.wms.domain.inventoryAdjustmentRecord.repository.po.InventoryAdjustmentRecordPO;
|
import com.mhd.wms.domain.inventoryAdjustmentRecord.repository.po.InventoryAdjustmentRecordPO;
|
||||||
import com.mhd.wms.domain.inventoryAdjustmentRecord.repository.todo.InventoryAdjustmentRecordDO;
|
import com.mhd.wms.domain.inventoryAdjustmentRecord.repository.todo.InventoryAdjustmentRecordDO;
|
||||||
import com.mhd.wms.domain.inventoryAdjustmentRecord.service.InventoryAdjustmentRecordDomainService;
|
import com.mhd.wms.domain.inventoryAdjustmentRecord.service.InventoryAdjustmentRecordDomainService;
|
||||||
|
import com.mhd.wms.domain.materialInventory.repository.mapper.MaterialInventoryMapper;
|
||||||
|
import com.mhd.wms.domain.materialInventory.repository.po.MaterialInventoryPO;
|
||||||
|
import com.mhd.wms.domain.materialMoreDetail.repository.po.MaterialMoreDetailPO;
|
||||||
|
import com.mhd.wms.domain.statementStatistics.po.ImmediateInventoryPO;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
import java.util.List;
|
import java.lang.reflect.Field;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 库存调整记录ApplicationService
|
* 库存调整记录ApplicationService
|
||||||
@@ -24,6 +38,10 @@ import java.util.List;
|
|||||||
public class InventoryAdjustmentRecordApplicationService {
|
public class InventoryAdjustmentRecordApplicationService {
|
||||||
@Autowired
|
@Autowired
|
||||||
private InventoryAdjustmentRecordDomainService inventoryAdjustmentRecordDomainService;
|
private InventoryAdjustmentRecordDomainService inventoryAdjustmentRecordDomainService;
|
||||||
|
@Autowired
|
||||||
|
private MaterialInventoryMapper materialInventoryMapper;
|
||||||
|
@Autowired
|
||||||
|
private SystemServiceFeign systemServiceFeign;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -40,7 +58,262 @@ public class InventoryAdjustmentRecordApplicationService {
|
|||||||
AssociationWarehouseCacheDO associationWarehouseCacheDO = SystemServiceCacheUtil.getAssociationWarehouseCache(loginUser.getUserid());
|
AssociationWarehouseCacheDO associationWarehouseCacheDO = SystemServiceCacheUtil.getAssociationWarehouseCache(loginUser.getUserid());
|
||||||
inventoryAdjustmentRecordDO.setWarehouseId(associationWarehouseCacheDO.getWarehouseId());
|
inventoryAdjustmentRecordDO.setWarehouseId(associationWarehouseCacheDO.getWarehouseId());
|
||||||
}
|
}
|
||||||
return inventoryAdjustmentRecordDomainService.queryList(inventoryAdjustmentRecordDO);
|
List<InventoryAdjustmentRecordPO> inventoryAdjustmentRecordPOS = inventoryAdjustmentRecordDomainService.queryList(inventoryAdjustmentRecordDO);
|
||||||
|
|
||||||
|
// 性能优化:批量获取批次属性,避免N+1查询问题
|
||||||
|
// 1. 收集所有唯一的materialBaseInfoId
|
||||||
|
Set<Long> materialBaseInfoIdSet = inventoryAdjustmentRecordPOS.stream()
|
||||||
|
.map(InventoryAdjustmentRecordPO::getMaterialBaseInfoId)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
// 2. 批量查询批次属性(使用Map缓存,避免重复查询相同的materialBaseInfoId)
|
||||||
|
Map<Long, List<BatchDetailFeignPO>> batchDetailMap = new HashMap<>();
|
||||||
|
for (Long materialBaseInfoId : materialBaseInfoIdSet) {
|
||||||
|
try {
|
||||||
|
AjaxResult ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(materialBaseInfoId);
|
||||||
|
if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) {
|
||||||
|
List<BatchDetailFeignPO> batchDetailFeignPOList = JSON.parseArray(
|
||||||
|
JSONObject.toJSONString(ajaxResult.get("data")), BatchDetailFeignPO.class);
|
||||||
|
if (!CollectionUtils.isEmpty(batchDetailFeignPOList)) {
|
||||||
|
// 过滤isDisplay=1的属性
|
||||||
|
List<BatchDetailFeignPO> filteredList = batchDetailFeignPOList.stream()
|
||||||
|
.filter(batchDetail -> batchDetail.getIsDisplay() != null && batchDetail.getIsDisplay() == 1)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
batchDetailMap.put(materialBaseInfoId, filteredList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("获取物料批次属性失败,物料基础信息ID:{},错误:{}", materialBaseInfoId, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 为每个物料明细设置更多属性(从库存表中获取值)
|
||||||
|
setMaterialMoreDetailListFromInventory(inventoryAdjustmentRecordPOS, batchDetailMap);
|
||||||
|
return inventoryAdjustmentRecordPOS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 为物料库存设置更多属性(从库存表中获取值)
|
||||||
|
* @param materialInventoryPOList 物料库存列表
|
||||||
|
* @param batchDetailMap 批次属性Map
|
||||||
|
*/
|
||||||
|
private void setMaterialMoreDetailListFromInventory(List<InventoryAdjustmentRecordPO> materialInventoryPOList,
|
||||||
|
Map<Long, List<BatchDetailFeignPO>> batchDetailMap) {
|
||||||
|
if (CollectionUtils.isEmpty(materialInventoryPOList)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
materialInventoryPOList.forEach(materialInventoryPO -> {
|
||||||
|
Long materialBaseInfoId = materialInventoryPO.getMaterialBaseInfoId();
|
||||||
|
Long materialInventoryId = materialInventoryPO.getMaterialInventoryId();
|
||||||
|
|
||||||
|
// 创建新的materialMoreDetailList,只包含isDisplay=1的属性
|
||||||
|
List<MaterialMoreDetailPO> materialMoreDetailList = new ArrayList<>();
|
||||||
|
|
||||||
|
// 从库存表获取数据(包含批次属性字段)
|
||||||
|
MaterialInventoryPO inventoryPO = null;
|
||||||
|
if (materialInventoryId != null) {
|
||||||
|
inventoryPO = materialInventoryMapper.selectByIdWithBatchAttributes(materialInventoryId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (materialBaseInfoId != null && batchDetailMap.containsKey(materialBaseInfoId)) {
|
||||||
|
List<BatchDetailFeignPO> batchDetailFeignPOList = batchDetailMap.get(materialBaseInfoId);
|
||||||
|
// 用于跟踪已添加到列表中的batchDetailId
|
||||||
|
Set<Long> addedBatchDetailIds = new HashSet<>();
|
||||||
|
|
||||||
|
for (BatchDetailFeignPO batchDetailFeignPO : batchDetailFeignPOList) {
|
||||||
|
MaterialMoreDetailPO materialMoreDetailPO = new MaterialMoreDetailPO();
|
||||||
|
materialMoreDetailPO.setBatchId(batchDetailFeignPO.getBatchId());
|
||||||
|
materialMoreDetailPO.setBatchDetailId(batchDetailFeignPO.getBatchDetailId());
|
||||||
|
materialMoreDetailPO.setBatchLabels(batchDetailFeignPO.getBatchLabels());
|
||||||
|
materialMoreDetailPO.setInputControl(batchDetailFeignPO.getInputControl());
|
||||||
|
materialMoreDetailPO.setAttributeFormat(batchDetailFeignPO.getAttributeFormat());
|
||||||
|
materialMoreDetailPO.setAttributeOption(batchDetailFeignPO.getAttributeOption());
|
||||||
|
materialMoreDetailPO.setRemark(batchDetailFeignPO.getRemark());
|
||||||
|
|
||||||
|
// 确保添加到列表中(使用batchDetailId来避免重复)
|
||||||
|
Long batchDetailId = batchDetailFeignPO.getBatchDetailId();
|
||||||
|
if (batchDetailId != null && !addedBatchDetailIds.contains(batchDetailId)) {
|
||||||
|
materialMoreDetailList.add(materialMoreDetailPO);
|
||||||
|
addedBatchDetailIds.add(batchDetailId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据fieldName或batchLabels从库存表中获取对应的字段值
|
||||||
|
if (inventoryPO != null) {
|
||||||
|
String fieldValue = null;
|
||||||
|
String usedFieldName = null;
|
||||||
|
// 优先使用fieldName(如果存在)
|
||||||
|
if (StringUtils.isNotBlank(batchDetailFeignPO.getFieldName())) {
|
||||||
|
usedFieldName = batchDetailFeignPO.getFieldName();
|
||||||
|
fieldValue = getFieldValueByFieldName(inventoryPO, usedFieldName);
|
||||||
|
log.info("批次属性 batchDetailId={}, fieldName={}, 从库存表获取到的值={}",
|
||||||
|
batchDetailFeignPO.getBatchDetailId(), usedFieldName, fieldValue);
|
||||||
|
}
|
||||||
|
// 如果fieldName为空,尝试根据batchLabels映射到字段名
|
||||||
|
else if (StringUtils.isNotBlank(batchDetailFeignPO.getBatchLabels())) {
|
||||||
|
String fieldNameByLabel = getFieldNameByBatchLabel(batchDetailFeignPO.getBatchLabels());
|
||||||
|
if (StringUtils.isNotBlank(fieldNameByLabel)) {
|
||||||
|
usedFieldName = fieldNameByLabel;
|
||||||
|
fieldValue = getFieldValueByFieldName(inventoryPO, usedFieldName);
|
||||||
|
log.info("批次属性 batchDetailId={}, batchLabels={}, 映射字段名={}, 从库存表获取到的值={}",
|
||||||
|
batchDetailFeignPO.getBatchDetailId(), batchDetailFeignPO.getBatchLabels(),
|
||||||
|
usedFieldName, fieldValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 只有当获取到值时才更新attributeValue
|
||||||
|
if (fieldValue != null) {
|
||||||
|
materialMoreDetailPO.setAttributeValue(fieldValue);
|
||||||
|
log.info("设置更多属性:batchDetailId={}, batchLabels={}, attributeValue={}",
|
||||||
|
materialMoreDetailPO.getBatchDetailId(), materialMoreDetailPO.getBatchLabels(),
|
||||||
|
materialMoreDetailPO.getAttributeValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
materialInventoryPO.setMaterialMoreDetailList(materialMoreDetailList);
|
||||||
|
log.info("物料库存 materialInventoryId={}, materialBaseInfoId={}, materialMoreDetailList大小={}",
|
||||||
|
materialInventoryPO.getMaterialInventoryId(), materialInventoryPO.getMaterialBaseInfoId(),
|
||||||
|
materialMoreDetailList != null ? materialMoreDetailList.size() : 0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据字段名从对象中获取字段值(使用反射)
|
||||||
|
* @param obj 对象
|
||||||
|
* @param fieldName 字段名
|
||||||
|
* @return 字段值(转换为字符串)
|
||||||
|
*/
|
||||||
|
private String getFieldValueByFieldName(Object obj, String fieldName) {
|
||||||
|
if (obj == null || StringUtils.isBlank(fieldName)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 兼容:如果传的是下划线命名(数据库列名风格),先转成驼峰字段名再取
|
||||||
|
String normalizedFieldName = fieldName;
|
||||||
|
if (normalizedFieldName.contains("_")) {
|
||||||
|
normalizedFieldName = snakeToCamel(normalizedFieldName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取对象的Class
|
||||||
|
Class<?> clazz = obj.getClass();
|
||||||
|
|
||||||
|
// 尝试获取字段(包括父类字段)
|
||||||
|
Field field = null;
|
||||||
|
Class<?> currentClass = clazz;
|
||||||
|
while (currentClass != null && field == null) {
|
||||||
|
try {
|
||||||
|
field = currentClass.getDeclaredField(normalizedFieldName);
|
||||||
|
} catch (NoSuchFieldException e) {
|
||||||
|
currentClass = currentClass.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (field == null) {
|
||||||
|
log.warn("字段不存在:{}(normalized:{}),对象类型:{}", fieldName, normalizedFieldName, clazz.getName());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置可访问
|
||||||
|
field.setAccessible(true);
|
||||||
|
|
||||||
|
// 获取字段值
|
||||||
|
Object value = field.get(obj);
|
||||||
|
|
||||||
|
// 转换为字符串
|
||||||
|
if (value == null) {
|
||||||
|
log.info("字段 {} 的值为 null,对象类型:{}", normalizedFieldName, clazz.getName());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String result;
|
||||||
|
// 处理日期类型字段
|
||||||
|
if (value instanceof Date) {
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
|
result = sdf.format((Date) value);
|
||||||
|
} else {
|
||||||
|
result = value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("通过反射获取字段值成功,字段名:{}(原始:{}),值:{},对象类型:{}",
|
||||||
|
normalizedFieldName, fieldName, result, clazz.getName());
|
||||||
|
return result;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("通过反射获取字段值失败,字段名:{},对象类型:{},错误:{}", fieldName, obj.getClass().getName(), e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String snakeToCamel(String snake) {
|
||||||
|
if (StringUtils.isBlank(snake)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String s = snake.trim().toLowerCase();
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
boolean upperNext = false;
|
||||||
|
for (int i = 0; i < s.length(); i++) {
|
||||||
|
char c = s.charAt(i);
|
||||||
|
if (c == '_') {
|
||||||
|
upperNext = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (upperNext) {
|
||||||
|
sb.append(Character.toUpperCase(c));
|
||||||
|
upperNext = false;
|
||||||
|
} else {
|
||||||
|
sb.append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据批次标签(batchLabels)映射到字段名
|
||||||
|
* @param batchLabel 批次标签
|
||||||
|
* @return 字段名,如果找不到映射则返回null
|
||||||
|
*/
|
||||||
|
private String getFieldNameByBatchLabel(String batchLabel) {
|
||||||
|
if (StringUtils.isBlank(batchLabel)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批次标签到字段名的映射关系
|
||||||
|
Map<String, String> labelToFieldNameMap = new HashMap<>();
|
||||||
|
labelToFieldNameMap.put("Invoice No.", "invoiceNo");
|
||||||
|
labelToFieldNameMap.put("Invoice No", "invoiceNo");
|
||||||
|
labelToFieldNameMap.put("发票号", "invoiceNo");
|
||||||
|
labelToFieldNameMap.put("Batch Ref NO's", "batchRefNo");
|
||||||
|
labelToFieldNameMap.put("Batch Ref NO", "batchRefNo");
|
||||||
|
labelToFieldNameMap.put("批次参考号", "batchRefNo");
|
||||||
|
labelToFieldNameMap.put("Sheet Ref NO's", "sheetRefNo");
|
||||||
|
labelToFieldNameMap.put("Sheet Ref NO", "sheetRefNo");
|
||||||
|
labelToFieldNameMap.put("单据参考号", "sheetRefNo");
|
||||||
|
labelToFieldNameMap.put("箱号/卡板号", "boxPalletNo");
|
||||||
|
labelToFieldNameMap.put("箱号", "boxPalletNo");
|
||||||
|
labelToFieldNameMap.put("卡板号", "boxPalletNo");
|
||||||
|
labelToFieldNameMap.put("生产日期", "productionDate");
|
||||||
|
labelToFieldNameMap.put("过期日期", "expiryDate");
|
||||||
|
labelToFieldNameMap.put("存货日期", "inventoryDate");
|
||||||
|
labelToFieldNameMap.put("扩展字段1", "extAttr1");
|
||||||
|
labelToFieldNameMap.put("扩展字段2", "extAttr2");
|
||||||
|
labelToFieldNameMap.put("扩展字段3", "extAttr3");
|
||||||
|
labelToFieldNameMap.put("扩展字段4", "extAttr4");
|
||||||
|
|
||||||
|
// 精确匹配
|
||||||
|
String fieldName = labelToFieldNameMap.get(batchLabel.trim());
|
||||||
|
if (StringUtils.isNotBlank(fieldName)) {
|
||||||
|
return fieldName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 模糊匹配(包含关系)
|
||||||
|
for (Map.Entry<String, String> entry : labelToFieldNameMap.entrySet()) {
|
||||||
|
if (batchLabel.contains(entry.getKey()) || entry.getKey().contains(batchLabel)) {
|
||||||
|
return entry.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
-1
@@ -11,7 +11,6 @@ import com.mhd.system.api.domain.cache.AssociationWarehouseCacheDO;
|
|||||||
import com.mhd.system.api.domain.cache.SystemServiceCacheUtil;
|
import com.mhd.system.api.domain.cache.SystemServiceCacheUtil;
|
||||||
import com.mhd.system.api.model.LoginUser;
|
import com.mhd.system.api.model.LoginUser;
|
||||||
import com.mhd.wms.domain.inventoryStandingDetail.service.InventoryStandingDetailDomainService;
|
import com.mhd.wms.domain.inventoryStandingDetail.service.InventoryStandingDetailDomainService;
|
||||||
import com.mhd.wms.domain.investigetionManageDetail.repository.po.InvestigetionManageDetailPO;
|
|
||||||
import com.mhd.wms.domain.materialInventory.repository.mapper.MaterialInventoryMapper;
|
import com.mhd.wms.domain.materialInventory.repository.mapper.MaterialInventoryMapper;
|
||||||
import com.mhd.wms.domain.materialInventory.repository.po.MaterialInventoryPO;
|
import com.mhd.wms.domain.materialInventory.repository.po.MaterialInventoryPO;
|
||||||
import com.mhd.wms.domain.materialInventory.service.MaterialInventoryDomainService;
|
import com.mhd.wms.domain.materialInventory.service.MaterialInventoryDomainService;
|
||||||
|
|||||||
+85
-129
@@ -1080,8 +1080,10 @@ public class StockInOrderApplicationService {
|
|||||||
// 货主信息:优先使用表头,如果表头为空则使用明细行
|
// 货主信息:优先使用表头,如果表头为空则使用明细行
|
||||||
String shipperName = StringUtils.isNotBlank(headerInfo.getShipperName()) ? headerInfo.getShipperName() : h.getShipperName();
|
String shipperName = StringUtils.isNotBlank(headerInfo.getShipperName()) ? headerInfo.getShipperName() : h.getShipperName();
|
||||||
String shipperCode = StringUtils.isNotBlank(headerInfo.getShipperCode()) ? headerInfo.getShipperCode() : h.getShipperCode();
|
String shipperCode = StringUtils.isNotBlank(headerInfo.getShipperCode()) ? headerInfo.getShipperCode() : h.getShipperCode();
|
||||||
// 货主ID先设置为null,后续在shipperParam方法中根据名称或编号查找
|
// 提前获取货主ID,用于查询物料基础信息时过滤
|
||||||
order.setShipperId(null);
|
Long shipperId = getShipperIdByNameOrCode(shipperName, shipperCode);
|
||||||
|
// 货主ID先设置为获取到的值,后续在shipperParam方法中会再次确认
|
||||||
|
order.setShipperId(shipperId);
|
||||||
if (StringUtils.isNotBlank(shipperName)) {
|
if (StringUtils.isNotBlank(shipperName)) {
|
||||||
order.setShipperName(shipperName);
|
order.setShipperName(shipperName);
|
||||||
}
|
}
|
||||||
@@ -1168,6 +1170,7 @@ public class StockInOrderApplicationService {
|
|||||||
r.getWarehouseQuantity(), r.getInboundQuantity());
|
r.getWarehouseQuantity(), r.getInboundQuantity());
|
||||||
|
|
||||||
// 根据明细表中的字段查询物料基础信息(优先:料号 > 商品SKU码 > 商品名称)
|
// 根据明细表中的字段查询物料基础信息(优先:料号 > 商品SKU码 > 商品名称)
|
||||||
|
// 注意:查询时必须加上货主ID条件,确保查询到的是该货主绑定的物料
|
||||||
Long materialBaseInfoId = null;
|
Long materialBaseInfoId = null;
|
||||||
LoginUser currentLoginUser = SecurityUtils.getLoginUser();
|
LoginUser currentLoginUser = SecurityUtils.getLoginUser();
|
||||||
Long topOrganizationId = currentLoginUser != null && currentLoginUser.getUserPo() != null
|
Long topOrganizationId = currentLoginUser != null && currentLoginUser.getUserPo() != null
|
||||||
@@ -1180,14 +1183,20 @@ public class StockInOrderApplicationService {
|
|||||||
if (topOrganizationId != null) {
|
if (topOrganizationId != null) {
|
||||||
queryDO.setTopOrganizationId(topOrganizationId);
|
queryDO.setTopOrganizationId(topOrganizationId);
|
||||||
}
|
}
|
||||||
log.info("尝试通过料号查询物料基础信息,料号: [{}], topOrganizationId: {}", r.getMaterialCode(), topOrganizationId);
|
// 加上货主ID条件,确保查询到的是该货主绑定的物料
|
||||||
|
if (shipperId != null) {
|
||||||
|
queryDO.setShipperId(shipperId);
|
||||||
|
}
|
||||||
|
log.info("尝试通过料号查询物料基础信息,料号: [{}], topOrganizationId: {}, shipperId: {}",
|
||||||
|
r.getMaterialCode(), topOrganizationId, shipperId);
|
||||||
List<MaterialBaseInfoPO> materialList = materialBaseInfoService.queryList(queryDO);
|
List<MaterialBaseInfoPO> materialList = materialBaseInfoService.queryList(queryDO);
|
||||||
log.info("料号查询结果,查询到 {} 条记录", materialList != null ? materialList.size() : 0);
|
log.info("料号查询结果,查询到 {} 条记录", materialList != null ? materialList.size() : 0);
|
||||||
if (materialList != null && !materialList.isEmpty()) {
|
if (materialList != null && !materialList.isEmpty()) {
|
||||||
materialBaseInfoId = materialList.get(0).getMaterialBaseInfoId();
|
materialBaseInfoId = materialList.get(0).getMaterialBaseInfoId();
|
||||||
log.info("通过料号查询到物料基础信息,料号: {}, 物料ID: {}", r.getMaterialCode(), materialBaseInfoId);
|
log.info("通过料号查询到物料基础信息,料号: {}, 物料ID: {}, 货主ID: {}",
|
||||||
|
r.getMaterialCode(), materialBaseInfoId, shipperId);
|
||||||
} else {
|
} else {
|
||||||
log.warn("通过料号未查询到物料基础信息,料号: [{}]", r.getMaterialCode());
|
log.warn("通过料号未查询到物料基础信息,料号: [{}], 货主ID: [{}]", r.getMaterialCode(), shipperId);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.warn("料号为空,跳过料号查询");
|
log.warn("料号为空,跳过料号查询");
|
||||||
@@ -1200,14 +1209,20 @@ public class StockInOrderApplicationService {
|
|||||||
if (topOrganizationId != null) {
|
if (topOrganizationId != null) {
|
||||||
queryDO.setTopOrganizationId(topOrganizationId);
|
queryDO.setTopOrganizationId(topOrganizationId);
|
||||||
}
|
}
|
||||||
log.info("尝试通过商品SKU码查询物料基础信息,SKU码: [{}], topOrganizationId: {}", r.getSkuCode(), topOrganizationId);
|
// 加上货主ID条件,确保查询到的是该货主绑定的物料
|
||||||
|
if (shipperId != null) {
|
||||||
|
queryDO.setShipperId(shipperId);
|
||||||
|
}
|
||||||
|
log.info("尝试通过商品SKU码查询物料基础信息,SKU码: [{}], topOrganizationId: {}, shipperId: {}",
|
||||||
|
r.getSkuCode(), topOrganizationId, shipperId);
|
||||||
List<MaterialBaseInfoPO> materialList = materialBaseInfoService.queryList(queryDO);
|
List<MaterialBaseInfoPO> materialList = materialBaseInfoService.queryList(queryDO);
|
||||||
log.info("SKU码查询结果,查询到 {} 条记录", materialList != null ? materialList.size() : 0);
|
log.info("SKU码查询结果,查询到 {} 条记录", materialList != null ? materialList.size() : 0);
|
||||||
if (materialList != null && !materialList.isEmpty()) {
|
if (materialList != null && !materialList.isEmpty()) {
|
||||||
materialBaseInfoId = materialList.get(0).getMaterialBaseInfoId();
|
materialBaseInfoId = materialList.get(0).getMaterialBaseInfoId();
|
||||||
log.info("通过商品SKU码查询到物料基础信息,SKU码: {}, 物料ID: {}", r.getSkuCode(), materialBaseInfoId);
|
log.info("通过商品SKU码查询到物料基础信息,SKU码: {}, 物料ID: {}, 货主ID: {}",
|
||||||
|
r.getSkuCode(), materialBaseInfoId, shipperId);
|
||||||
} else {
|
} else {
|
||||||
log.warn("通过SKU码未查询到物料基础信息,SKU码: [{}]", r.getSkuCode());
|
log.warn("通过SKU码未查询到物料基础信息,SKU码: [{}], 货主ID: [{}]", r.getSkuCode(), shipperId);
|
||||||
}
|
}
|
||||||
} else if (materialBaseInfoId == null) {
|
} else if (materialBaseInfoId == null) {
|
||||||
log.warn("SKU码为空,跳过SKU码查询");
|
log.warn("SKU码为空,跳过SKU码查询");
|
||||||
@@ -1220,14 +1235,20 @@ public class StockInOrderApplicationService {
|
|||||||
if (topOrganizationId != null) {
|
if (topOrganizationId != null) {
|
||||||
queryDO.setTopOrganizationId(topOrganizationId);
|
queryDO.setTopOrganizationId(topOrganizationId);
|
||||||
}
|
}
|
||||||
log.info("尝试通过商品名称查询物料基础信息,商品名称: [{}], topOrganizationId: {}", r.getMaterialName(), topOrganizationId);
|
// 加上货主ID条件,确保查询到的是该货主绑定的物料
|
||||||
|
if (shipperId != null) {
|
||||||
|
queryDO.setShipperId(shipperId);
|
||||||
|
}
|
||||||
|
log.info("尝试通过商品名称查询物料基础信息,商品名称: [{}], topOrganizationId: {}, shipperId: {}",
|
||||||
|
r.getMaterialName(), topOrganizationId, shipperId);
|
||||||
List<MaterialBaseInfoPO> materialList = materialBaseInfoService.queryList(queryDO);
|
List<MaterialBaseInfoPO> materialList = materialBaseInfoService.queryList(queryDO);
|
||||||
log.info("商品名称查询结果,查询到 {} 条记录", materialList != null ? materialList.size() : 0);
|
log.info("商品名称查询结果,查询到 {} 条记录", materialList != null ? materialList.size() : 0);
|
||||||
if (materialList != null && !materialList.isEmpty()) {
|
if (materialList != null && !materialList.isEmpty()) {
|
||||||
materialBaseInfoId = materialList.get(0).getMaterialBaseInfoId();
|
materialBaseInfoId = materialList.get(0).getMaterialBaseInfoId();
|
||||||
log.info("通过商品名称查询到物料基础信息,商品名称: {}, 物料ID: {}", r.getMaterialName(), materialBaseInfoId);
|
log.info("通过商品名称查询到物料基础信息,商品名称: {}, 物料ID: {}, 货主ID: {}",
|
||||||
|
r.getMaterialName(), materialBaseInfoId, shipperId);
|
||||||
} else {
|
} else {
|
||||||
log.warn("通过商品名称未查询到物料基础信息,商品名称: [{}]", r.getMaterialName());
|
log.warn("通过商品名称未查询到物料基础信息,商品名称: [{}], 货主ID: [{}]", r.getMaterialName(), shipperId);
|
||||||
}
|
}
|
||||||
} else if (materialBaseInfoId == null) {
|
} else if (materialBaseInfoId == null) {
|
||||||
log.warn("商品名称为空,跳过商品名称查询");
|
log.warn("商品名称为空,跳过商品名称查询");
|
||||||
@@ -1486,18 +1507,18 @@ public class StockInOrderApplicationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 封装货主信息(货主信息就是客户)
|
* @description 根据货主名称或编号获取货主ID(用于导入时提前获取货主ID)
|
||||||
* @author ZhouGY
|
* @param shipperName 货主名称
|
||||||
* @date 2024/5/9 20:43
|
* @param shipperCode 货主编号
|
||||||
* @param stockInOrderDO
|
* @return 货主ID,如果找不到则返回null
|
||||||
*/
|
*/
|
||||||
private void shipperParam(StockInOrderDO stockInOrderDO){
|
private Long getShipperIdByNameOrCode(String shipperName, String shipperCode) {
|
||||||
Long shipperId = stockInOrderDO.getShipperId();
|
if (StringUtils.isBlank(shipperName) && StringUtils.isBlank(shipperCode)) {
|
||||||
String shipperName = stockInOrderDO.getShipperName();
|
return null;
|
||||||
String shipperCode = stockInOrderDO.getShipperCode();
|
}
|
||||||
|
|
||||||
|
Long shipperId = null;
|
||||||
|
|
||||||
// 如果货主ID为空,尝试根据货主名称或编号查找
|
|
||||||
if (shipperId == null) {
|
|
||||||
// 优先尝试:如果名称是纯数字,可能是误传的ID,直接按ID查询
|
// 优先尝试:如果名称是纯数字,可能是误传的ID,直接按ID查询
|
||||||
if (StringUtils.isNotEmpty(shipperName) && shipperName.matches("\\d+")) {
|
if (StringUtils.isNotEmpty(shipperName) && shipperName.matches("\\d+")) {
|
||||||
try {
|
try {
|
||||||
@@ -1508,15 +1529,15 @@ public class StockInOrderApplicationService {
|
|||||||
if (userPo != null) {
|
if (userPo != null) {
|
||||||
shipperId = userPo.getUserId();
|
shipperId = userPo.getUserId();
|
||||||
log.info("根据货主名称(实际为ID)找到货主ID:{}", shipperId);
|
log.info("根据货主名称(实际为ID)找到货主ID:{}", shipperId);
|
||||||
|
return shipperId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("尝试将货主名称作为ID查询失败,货主名称:{},错误:{}", shipperName, e.getMessage());
|
log.debug("尝试将货主名称作为ID查询失败,货主名称:{},错误:{}", shipperName, e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果仍未找到,尝试根据名称查询(使用 getInfoByName 接口,更高效)
|
// 如果仍未找到,尝试根据名称查询
|
||||||
// 注意:如果接口返回404,说明接口可能未实现,继续尝试从列表中查找
|
|
||||||
if (shipperId == null && StringUtils.isNotEmpty(shipperName) && !shipperName.matches("\\d+")) {
|
if (shipperId == null && StringUtils.isNotEmpty(shipperName) && !shipperName.matches("\\d+")) {
|
||||||
try {
|
try {
|
||||||
AjaxResult ajaxResult = userServiceFeign.getInfoByName(shipperName);
|
AjaxResult ajaxResult = userServiceFeign.getInfoByName(shipperName);
|
||||||
@@ -1526,26 +1547,21 @@ public class StockInOrderApplicationService {
|
|||||||
if (userPo != null) {
|
if (userPo != null) {
|
||||||
shipperId = userPo.getUserId();
|
shipperId = userPo.getUserId();
|
||||||
log.info("根据货主名称找到货主ID,货主名称:{},货主ID:{}", shipperName, shipperId);
|
log.info("根据货主名称找到货主ID,货主名称:{},货主ID:{}", shipperName, shipperId);
|
||||||
|
return shipperId;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// 接口返回非200(可能是404),记录日志但继续尝试其他方式
|
|
||||||
log.debug("getInfoByName接口返回非200,货主名称:{},返回码:{},将继续尝试从列表中查找", shipperName, code);
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// 接口调用异常(包括404),记录日志但继续尝试其他方式
|
log.debug("根据货主名称查询失败,货主名称:{},错误:{}", shipperName, e.getMessage());
|
||||||
log.debug("根据货主名称查询失败(可能是接口未实现),货主名称:{},错误:{},将继续尝试从列表中查找", shipperName, e.getMessage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果仍未找到,尝试从货主列表中根据编号或名称查找(兜底方案)
|
// 如果仍未找到,尝试从货主列表中根据编号或名称查找
|
||||||
if (shipperId == null && (StringUtils.isNotEmpty(shipperName) || StringUtils.isNotEmpty(shipperCode))) {
|
if (shipperId == null && (StringUtils.isNotEmpty(shipperName) || StringUtils.isNotEmpty(shipperCode))) {
|
||||||
try {
|
try {
|
||||||
log.debug("开始从货主列表中查找,货主名称:{},货主编号:{}", shipperName, shipperCode);
|
|
||||||
AjaxResult shipperListResult = userServiceFeign.userShipperListAll();
|
AjaxResult shipperListResult = userServiceFeign.userShipperListAll();
|
||||||
if ("200".equals(String.valueOf(shipperListResult.get("code"))) && shipperListResult.get("data") != null) {
|
if ("200".equals(String.valueOf(shipperListResult.get("code"))) && shipperListResult.get("data") != null) {
|
||||||
Object data = shipperListResult.get("data");
|
Object data = shipperListResult.get("data");
|
||||||
List<Map<String, Object>> shipperList = null;
|
List<Map<String, Object>> shipperList = null;
|
||||||
// 尝试解析为列表
|
|
||||||
if (data instanceof List) {
|
if (data instanceof List) {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
List<Object> rawList = (List<Object>) data;
|
List<Object> rawList = (List<Object>) data;
|
||||||
@@ -1556,38 +1572,16 @@ public class StockInOrderApplicationService {
|
|||||||
Map<String, Object> mapItem = (Map<String, Object>) item;
|
Map<String, Object> mapItem = (Map<String, Object>) item;
|
||||||
shipperList.add(mapItem);
|
shipperList.add(mapItem);
|
||||||
} else {
|
} else {
|
||||||
// 如果不是Map,尝试转换为Map
|
|
||||||
Map<String, Object> mapItem = JSON.parseObject(JSONObject.toJSONString(item), Map.class);
|
Map<String, Object> mapItem = JSON.parseObject(JSONObject.toJSONString(item), Map.class);
|
||||||
shipperList.add(mapItem);
|
shipperList.add(mapItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 如果不是列表,尝试转换为列表
|
|
||||||
String jsonStr = JSONObject.toJSONString(data);
|
String jsonStr = JSONObject.toJSONString(data);
|
||||||
shipperList = JSON.parseObject(jsonStr, new com.alibaba.fastjson.TypeReference<List<Map<String, Object>>>(){});
|
shipperList = JSON.parseObject(jsonStr, new com.alibaba.fastjson.TypeReference<List<Map<String, Object>>>(){});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shipperList != null && !shipperList.isEmpty()) {
|
if (shipperList != null && !shipperList.isEmpty()) {
|
||||||
log.debug("货主列表大小:{},开始匹配查找,查找货主名称:{},货主编号:{}",
|
|
||||||
shipperList.size(), shipperName, shipperCode);
|
|
||||||
|
|
||||||
// 输出前3个货主的详细信息,用于调试
|
|
||||||
if (log.isDebugEnabled() && shipperList.size() > 0) {
|
|
||||||
int debugCount = Math.min(3, shipperList.size());
|
|
||||||
for (int i = 0; i < debugCount; i++) {
|
|
||||||
Map<String, Object> debugShipper = shipperList.get(i);
|
|
||||||
log.debug("货主列表示例[{}]:所有字段={}", i, debugShipper.keySet());
|
|
||||||
log.debug("货主列表示例[{}]:userId={}, userName={}, userCode={}, userMemberCode={}, name={}, shipperName={}",
|
|
||||||
i,
|
|
||||||
debugShipper.get("userId"),
|
|
||||||
debugShipper.get("userName"),
|
|
||||||
debugShipper.get("userCode"),
|
|
||||||
debugShipper.get("userMemberCode"),
|
|
||||||
debugShipper.get("name"),
|
|
||||||
debugShipper.get("shipperName"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 标准化输入的货主名称和编号(去除空格,用于匹配)
|
|
||||||
String normalizedShipperName = shipperName != null ? shipperName.trim() : "";
|
String normalizedShipperName = shipperName != null ? shipperName.trim() : "";
|
||||||
String normalizedShipperCode = shipperCode != null ? shipperCode.trim() : "";
|
String normalizedShipperCode = shipperCode != null ? shipperCode.trim() : "";
|
||||||
|
|
||||||
@@ -1597,120 +1591,82 @@ public class StockInOrderApplicationService {
|
|||||||
Object userCode = shipper.get("userCode");
|
Object userCode = shipper.get("userCode");
|
||||||
Object userMemberCode = shipper.get("userMemberCode");
|
Object userMemberCode = shipper.get("userMemberCode");
|
||||||
|
|
||||||
// 尝试多个可能的字段名(按优先级顺序)
|
|
||||||
if (userName == null) {
|
if (userName == null) {
|
||||||
userName = shipper.get("name");
|
userName = shipper.get("name");
|
||||||
}
|
}
|
||||||
if (userName == null) {
|
if (userName == null) {
|
||||||
userName = shipper.get("shipperName");
|
userName = shipper.get("shipperName");
|
||||||
}
|
}
|
||||||
if (userName == null) {
|
|
||||||
userName = shipper.get("userName");
|
|
||||||
}
|
|
||||||
// 尝试其他可能的字段名
|
|
||||||
if (userName == null) {
|
|
||||||
userName = shipper.get("customerName");
|
|
||||||
}
|
|
||||||
if (userName == null) {
|
|
||||||
userName = shipper.get("companyName");
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean matched = false;
|
boolean matched = false;
|
||||||
// 优先根据编号匹配(更准确)
|
// 优先根据编号匹配
|
||||||
if (StringUtils.isNotEmpty(normalizedShipperCode)) {
|
if (StringUtils.isNotEmpty(normalizedShipperCode)) {
|
||||||
String normalizedUserCode = userCode != null ? String.valueOf(userCode).trim() : "";
|
String normalizedUserCode = userCode != null ? String.valueOf(userCode).trim() : "";
|
||||||
String normalizedUserMemberCode = userMemberCode != null ? String.valueOf(userMemberCode).trim() : "";
|
String normalizedUserMemberCode = userMemberCode != null ? String.valueOf(userMemberCode).trim() : "";
|
||||||
if (normalizedShipperCode.equals(normalizedUserCode) ||
|
if (normalizedShipperCode.equals(normalizedUserCode) ||
|
||||||
normalizedShipperCode.equals(normalizedUserMemberCode)) {
|
normalizedShipperCode.equals(normalizedUserMemberCode)) {
|
||||||
matched = true;
|
matched = true;
|
||||||
log.debug("通过编号匹配成功,货主编号:{},货主ID:{}", normalizedShipperCode, userId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 如果编号不匹配,再根据名称匹配(支持去除空格后匹配)
|
// 如果编号不匹配,再根据名称匹配
|
||||||
if (!matched && StringUtils.isNotEmpty(normalizedShipperName) && userName != null) {
|
if (!matched && StringUtils.isNotEmpty(normalizedShipperName) && userName != null) {
|
||||||
String normalizedUserName = String.valueOf(userName).trim();
|
String normalizedUserName = String.valueOf(userName).trim();
|
||||||
// 精确匹配(优先)
|
if (normalizedShipperName.equals(normalizedUserName) ||
|
||||||
if (normalizedShipperName.equals(normalizedUserName)) {
|
normalizedUserName.contains(normalizedShipperName)) {
|
||||||
matched = true;
|
matched = true;
|
||||||
log.debug("通过名称精确匹配成功,货主名称:{},货主ID:{}", normalizedShipperName, userId);
|
|
||||||
}
|
}
|
||||||
// 如果精确匹配失败,尝试包含匹配(列表中的名称包含导入的名称,例如列表中是"珠海百思科鞋材有限公司",导入的是"百思科")
|
|
||||||
// 注意:这里不使用反向包含匹配(导入的名称包含列表中的名称),因为这样会误匹配(例如导入"珠海百思科鞋材有限公司"会匹配到"百思科")
|
|
||||||
if (!matched && normalizedUserName.contains(normalizedShipperName)) {
|
|
||||||
matched = true;
|
|
||||||
log.debug("通过名称包含匹配成功,货主名称:{},列表中的名称:{},货主ID:{}",
|
|
||||||
normalizedShipperName, normalizedUserName, userId);
|
|
||||||
}
|
|
||||||
// 不再使用反向包含匹配,避免误匹配
|
|
||||||
// 例如:导入"珠海百思科鞋材有限公司"不应该匹配到列表中的"百思科"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matched && userId != null) {
|
if (matched && userId != null) {
|
||||||
shipperId = Long.valueOf(String.valueOf(userId));
|
shipperId = Long.valueOf(String.valueOf(userId));
|
||||||
log.info("从货主列表中找到货主ID,货主名称:{},货主编号:{},货主ID:{}",
|
log.info("从货主列表中找到货主ID,货主名称:{},货主编号:{},货主ID:{}",
|
||||||
shipperName, shipperCode, shipperId);
|
shipperName, shipperCode, shipperId);
|
||||||
break;
|
return shipperId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shipperId == null) {
|
|
||||||
// 输出所有货主名称,帮助排查
|
|
||||||
List<String> allShipperNames = new ArrayList<>();
|
|
||||||
for (Map<String, Object> shipper : shipperList) {
|
|
||||||
Object name = shipper.get("userName");
|
|
||||||
if (name == null) {
|
|
||||||
name = shipper.get("name");
|
|
||||||
}
|
}
|
||||||
if (name == null) {
|
|
||||||
name = shipper.get("shipperName");
|
|
||||||
}
|
|
||||||
if (name != null) {
|
|
||||||
allShipperNames.add(String.valueOf(name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log.warn("从货主列表中未找到匹配的货主,货主名称:{},货主编号:{},列表大小:{},所有货主名称:{}",
|
|
||||||
shipperName, shipperCode, shipperList.size(), allShipperNames);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.warn("货主列表为空或解析失败");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.warn("获取货主列表失败,返回码:{}", shipperListResult.get("code"));
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("从货主列表中查找货主ID失败,货主名称:{},货主编号:{},错误:{}", shipperName, shipperCode, e.getMessage(), e);
|
log.debug("从货主列表中查找货主ID失败,货主名称:{},货主编号:{},错误:{}",
|
||||||
|
shipperName, shipperCode, e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果仍然找不到货主ID,抛出异常
|
|
||||||
if (shipperId == null) {
|
if (shipperId == null) {
|
||||||
String errorMsg = "货主ID不能为空(货主信息就是客户)";
|
log.warn("未找到货主ID,货主名称:{},货主编号:{}", shipperName, shipperCode);
|
||||||
if (StringUtils.isNotEmpty(shipperName)) {
|
|
||||||
errorMsg += "。已提供货主名称:" + shipperName + ",但未找到对应的货主ID,请确保货主名称正确或直接提供货主ID";
|
|
||||||
} else if (StringUtils.isNotEmpty(shipperCode)) {
|
|
||||||
errorMsg += "。已提供货主编号:" + shipperCode + ",但未找到对应的货主ID,请确保货主编号正确或直接提供货主ID";
|
|
||||||
} else {
|
|
||||||
errorMsg += "。请提供货主ID、货主名称或货主编号";
|
|
||||||
}
|
|
||||||
throw new ServiceException(errorMsg);
|
|
||||||
}
|
|
||||||
stockInOrderDO.setShipperId(shipperId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据货主ID获取详细信息
|
return shipperId;
|
||||||
AjaxResult ajaxResult = userServiceFeign.getInfo(shipperId);
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 封装货主信息(改为与出库单相同的简洁逻辑,使用入库单的字段shipperName)
|
||||||
|
* @author ZhouGY
|
||||||
|
* @date 2024/5/9 20:43
|
||||||
|
* @param stockInOrderDO
|
||||||
|
*/
|
||||||
|
private void shipperParam(StockInOrderDO stockInOrderDO){
|
||||||
|
String shipperName = stockInOrderDO.getShipperName();
|
||||||
|
if (StringUtils.isEmpty(shipperName)) return;
|
||||||
|
if (!shipperName.matches("\\d+")) {
|
||||||
|
// 按名称查询
|
||||||
|
AjaxResult ajaxResult = userServiceFeign.getInfoByName(shipperName);
|
||||||
if(!"200".equals(String.valueOf(ajaxResult.get("code")))){
|
if(!"200".equals(String.valueOf(ajaxResult.get("code")))){
|
||||||
String errorMsg = ajaxResult.get("msg") != null ? String.valueOf(ajaxResult.get("msg")) : "未知错误";
|
throw new ServiceException("获取货主信息失败");
|
||||||
throw new ServiceException("获取货主信息失败(货主ID: " + shipperId + "),错误信息: " + errorMsg);
|
|
||||||
}
|
|
||||||
UserPo userPo = JSON.parseObject(JSONObject.toJSONString(ajaxResult.get("data")), UserPo.class);
|
|
||||||
if (userPo == null) {
|
|
||||||
throw new ServiceException("获取货主信息失败:返回数据为空(货主ID: " + shipperId + ")");
|
|
||||||
}
|
}
|
||||||
|
UserPo userPo = JSON.parseObject(com.alibaba.fastjson2.JSONObject.toJSONString(ajaxResult.get("data")), UserPo.class);
|
||||||
|
stockInOrderDO.setShipperId(userPo.getUserId());
|
||||||
|
stockInOrderDO.setShipperCode(userPo.getUserMemberCode());
|
||||||
|
stockInOrderDO.setShipperName(userPo.getUserName());
|
||||||
|
} else {
|
||||||
|
// 按ID查询
|
||||||
|
AjaxResult ajaxResult = userServiceFeign.getInfo(Long.valueOf(shipperName));
|
||||||
|
if(!"200".equals(String.valueOf(ajaxResult.get("code")))){
|
||||||
|
throw new ServiceException("获取货主信息失败");
|
||||||
|
}
|
||||||
|
UserPo userPo = JSON.parseObject(com.alibaba.fastjson2.JSONObject.toJSONString(ajaxResult.get("data")), UserPo.class);
|
||||||
|
stockInOrderDO.setShipperId(userPo.getUserId());
|
||||||
stockInOrderDO.setShipperCode(userPo.getUserMemberCode());
|
stockInOrderDO.setShipperCode(userPo.getUserMemberCode());
|
||||||
// 如果原始shipperName不为空,保留原始值(导入时读取的客户名称应该保留)
|
|
||||||
// 只有在原始shipperName为空时,才使用查询到的userName
|
|
||||||
if (StringUtils.isBlank(stockInOrderDO.getShipperName())) {
|
|
||||||
stockInOrderDO.setShipperName(userPo.getUserName());
|
stockInOrderDO.setShipperName(userPo.getUserName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+57
@@ -1,12 +1,17 @@
|
|||||||
package com.mhd.wms.domain.inventoryAdjustmentRecord.repository.po;
|
package com.mhd.wms.domain.inventoryAdjustmentRecord.repository.po;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
import com.mhd.common.core.annotation.Excel;
|
import com.mhd.common.core.annotation.Excel;
|
||||||
import com.mhd.common.core.web.domain.BaseVOEntity;
|
import com.mhd.common.core.web.domain.BaseVOEntity;
|
||||||
|
import com.mhd.wms.domain.materialMoreDetail.repository.po.MaterialMoreDetailPO;
|
||||||
import io.swagger.annotations.ApiModel;
|
import io.swagger.annotations.ApiModel;
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -147,6 +152,58 @@ public class InventoryAdjustmentRecordPO extends BaseVOEntity {
|
|||||||
@Excel(name = "调整后冻结数量")
|
@Excel(name = "调整后冻结数量")
|
||||||
private BigDecimal freezeAfterQuantity;
|
private BigDecimal freezeAfterQuantity;
|
||||||
|
|
||||||
|
@ApiModelProperty("Batch Ref NO's")
|
||||||
|
@Excel(name = "Batch Ref NO's")
|
||||||
|
private String batchRefNo;
|
||||||
|
|
||||||
|
@ApiModelProperty("Sheet Ref NO's")
|
||||||
|
@Excel(name = "Sheet Ref NO's")
|
||||||
|
private String sheetRefNo;
|
||||||
|
|
||||||
|
@ApiModelProperty("箱号/卡板号")
|
||||||
|
@Excel(name = "箱号/卡板号")
|
||||||
|
private String boxPalletNo;
|
||||||
|
|
||||||
|
@ApiModelProperty("扩展字段1")
|
||||||
|
@Excel(name = "扩展字段1")
|
||||||
|
private String extAttr1;
|
||||||
|
|
||||||
|
@ApiModelProperty("扩展字段2")
|
||||||
|
@Excel(name = "扩展字段2")
|
||||||
|
private String extAttr2;
|
||||||
|
|
||||||
|
@ApiModelProperty("生产日期")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Excel(name = "生产日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date productionDate;
|
||||||
|
|
||||||
|
@ApiModelProperty("过期日期")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Excel(name = "过期日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date expiryDate;
|
||||||
|
|
||||||
|
@ApiModelProperty("存货日期")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Excel(name = "存货日期", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date inventoryDate;
|
||||||
|
|
||||||
|
@ApiModelProperty("ExtAttr3")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Excel(name = "ExtAttr3", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date extAttr3;
|
||||||
|
|
||||||
|
@ApiModelProperty("ExtAttr4")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
@Excel(name = "ExtAttr4", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date extAttr4;
|
||||||
|
|
||||||
|
@ApiModelProperty("物料更多属性列表(批次属性)")
|
||||||
|
private List<MaterialMoreDetailPO> materialMoreDetailList;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
+10
@@ -74,6 +74,16 @@ public interface IOutMaterialDetailService extends IService<OutMaterialDetail>
|
|||||||
*/
|
*/
|
||||||
public StockOutOrderPO batchCancelAssignUpdate(String outOrderNumber, List<OutMaterialDetailDO> outMaterialDetailDOList);
|
public StockOutOrderPO batchCancelAssignUpdate(String outOrderNumber, List<OutMaterialDetailDO> outMaterialDetailDOList);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 手动取消分配批量修改物流明细(弹窗方式,类似batchAssignUpdate)
|
||||||
|
* @author ZhouGY
|
||||||
|
* @date 2024/5/22 9:27
|
||||||
|
* @param outOrderNumber
|
||||||
|
* @param outMaterialDetailDOList
|
||||||
|
* @return StockOutOrderPO
|
||||||
|
*/
|
||||||
|
public StockOutOrderPO batchManualCancelAssignUpdate(String outOrderNumber, List<OutMaterialDetailDO> outMaterialDetailDOList);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description 拣货批量修改物流明细
|
* @description 拣货批量修改物流明细
|
||||||
* @author ZhouGY
|
* @author ZhouGY
|
||||||
|
|||||||
+55
-35
@@ -44,113 +44,133 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<result property="updateBy" column="update_by" />
|
<result property="updateBy" column="update_by" />
|
||||||
<result property="updateByName" column="update_by_name" />
|
<result property="updateByName" column="update_by_name" />
|
||||||
<result property="delFlag" column="del_flag" />
|
<result property="delFlag" column="del_flag" />
|
||||||
|
<result property="extAttr1" column="ext_attr_1" />
|
||||||
|
<result property="extAttr2" column="ext_attr_2" />
|
||||||
|
<result property="extAttr3" column="ext_attr_3" />
|
||||||
|
<result property="extAttr4" column="ext_attr_4" />
|
||||||
|
<result property="productionDate" column="production_date" />
|
||||||
|
<result property="expiryDate" column="expiry_date" />
|
||||||
|
<result property="inventoryDate" column="inventory_date" />
|
||||||
|
<result property="batchRefNo" column="batch_ref_no" />
|
||||||
|
<result property="sheetRefNo" column="sheet_ref_no" />
|
||||||
|
<result property="boxPalletNo" column="box_pallet_no" />
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
|
|
||||||
<sql id="selectInventoryAdjustmentRecordPo">
|
<sql id="selectInventoryAdjustmentRecordPo">
|
||||||
select inventory_adjustment_id, organization_id, organization_name, top_organization_id, material_inventory_id, material_base_info_id, material_code, material_name, bar_code, shipper_id, shipper_name, warehouse_id, warehouse_code, warehouse_name, storage_section_id, storage_code, storage_name, storage_location_id, storage_location_code, storage_location_name, adjust_type, adjust_direction, adjust_before_status_code, adjust_before_status_name, adjust_after_status_code, adjust_after_status_name, inventory_before_quantity, allocation_before_quantity, freeze_before_quantity, inventory_after_quantity, allocation_after_quantity, freeze_after_quantity, create_time, create_by, create_by_name, update_time, update_by, update_by_name, del_flag from inventory_adjustment_record
|
select a.inventory_adjustment_id, a.organization_id, a.organization_name, a.top_organization_id, a.material_inventory_id,
|
||||||
where del_flag = 1
|
a.material_base_info_id, a.material_code, a.material_name, a.bar_code, a.shipper_id, a.shipper_name, a.warehouse_id,
|
||||||
|
a.warehouse_code, a.warehouse_name, a.storage_section_id, a.storage_code, a.storage_name, a.storage_location_id,
|
||||||
|
a.storage_location_code, a.storage_location_name, a.adjust_type, a.adjust_direction, a.adjust_before_status_code,
|
||||||
|
a.adjust_before_status_name, a.adjust_after_status_code, a.adjust_after_status_name, a.inventory_before_quantity,
|
||||||
|
a.allocation_before_quantity, a.freeze_before_quantity, a.inventory_after_quantity, a.allocation_after_quantity,
|
||||||
|
a.freeze_after_quantity, a.create_time, a.create_by, a.create_by_name, a.update_time, a.update_by, a.update_by_name,
|
||||||
|
a.del_flag,b.ext_attr_1, b.ext_attr_2, b.ext_attr_3, b.ext_attr_4,
|
||||||
|
b.production_date, b.expiry_date, b.inventory_date,
|
||||||
|
b.batch_ref_no, b.sheet_ref_no, b.box_pallet_no
|
||||||
|
from inventory_adjustment_record a left join material_inventory b on a.material_inventory_id = b.material_inventory_id
|
||||||
|
where a.del_flag = 1
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
<sql id="selectInventoryAdjustmentRecordPo1">
|
<sql id="selectInventoryAdjustmentRecordPo1">
|
||||||
<if test="organizationId != null ">
|
<if test="organizationId != null ">
|
||||||
and organization_id = #{organizationId}
|
and a.organization_id = #{organizationId}
|
||||||
</if>
|
</if>
|
||||||
<if test="organizationName != null and organizationName != ''">
|
<if test="organizationName != null and organizationName != ''">
|
||||||
and organization_name like concat('%', #{organizationName}, '%')
|
and a.organization_name like concat('%', #{organizationName}, '%')
|
||||||
</if>
|
</if>
|
||||||
<if test="topOrganizationId != null ">
|
<if test="topOrganizationId != null ">
|
||||||
and top_organization_id = #{topOrganizationId}
|
and a.top_organization_id = #{topOrganizationId}
|
||||||
</if>
|
</if>
|
||||||
<if test="materialBaseInfoId != null ">
|
<if test="materialBaseInfoId != null ">
|
||||||
and material_base_info_id = #{materialBaseInfoId}
|
and a.material_base_info_id = #{materialBaseInfoId}
|
||||||
</if>
|
</if>
|
||||||
<if test="materialInventoryId != null ">
|
<if test="materialInventoryId != null ">
|
||||||
and material_inventory_id = #{materialInventoryId}
|
and a.material_inventory_id = #{materialInventoryId}
|
||||||
</if>
|
</if>
|
||||||
<if test="materialCode != null and materialCode != ''">
|
<if test="materialCode != null and materialCode != ''">
|
||||||
and material_code = #{materialCode}
|
and a.material_code = #{materialCode}
|
||||||
</if>
|
</if>
|
||||||
<if test="materialName != null and materialName != ''">
|
<if test="materialName != null and materialName != ''">
|
||||||
and material_name like concat('%', #{materialName}, '%')
|
and a.material_name like concat('%', #{materialName}, '%')
|
||||||
</if>
|
</if>
|
||||||
<if test="barCode != null and barCode != ''">
|
<if test="barCode != null and barCode != ''">
|
||||||
and bar_code = #{barCode}
|
and a.bar_code = #{barCode}
|
||||||
</if>
|
</if>
|
||||||
<if test="shipperId != null ">
|
<if test="shipperId != null ">
|
||||||
and shipper_id = #{shipperId}
|
and a.shipper_id = #{shipperId}
|
||||||
</if>
|
</if>
|
||||||
<if test="shipperName != null and shipperName != ''">
|
<if test="shipperName != null and shipperName != ''">
|
||||||
and shipper_name like concat('%', #{shipperName}, '%')
|
and a.shipper_name like concat('%', #{shipperName}, '%')
|
||||||
</if>
|
</if>
|
||||||
<if test="warehouseId != null ">
|
<if test="warehouseId != null ">
|
||||||
and warehouse_id = #{warehouseId}
|
and a.warehouse_id = #{warehouseId}
|
||||||
</if>
|
</if>
|
||||||
<if test="warehouseCode != null and warehouseCode != ''">
|
<if test="warehouseCode != null and warehouseCode != ''">
|
||||||
and warehouse_code = #{warehouseCode}
|
and a.warehouse_code = #{warehouseCode}
|
||||||
</if>
|
</if>
|
||||||
<if test="warehouseName != null and warehouseName != ''">
|
<if test="warehouseName != null and warehouseName != ''">
|
||||||
and warehouse_name like concat('%', #{warehouseName}, '%')
|
and a.warehouse_name like concat('%', #{warehouseName}, '%')
|
||||||
</if>
|
</if>
|
||||||
<if test="storageSectionId != null ">
|
<if test="storageSectionId != null ">
|
||||||
and storage_section_id = #{storageSectionId}
|
and a.storage_section_id = #{storageSectionId}
|
||||||
</if>
|
</if>
|
||||||
<if test="storageCode != null and storageCode != ''">
|
<if test="storageCode != null and storageCode != ''">
|
||||||
and storage_code = #{storageCode}
|
and a.storage_code = #{storageCode}
|
||||||
</if>
|
</if>
|
||||||
<if test="storageName != null and storageName != ''">
|
<if test="storageName != null and storageName != ''">
|
||||||
and storage_name like concat('%', #{storageName}, '%')
|
and a.storage_name like concat('%', #{storageName}, '%')
|
||||||
</if>
|
</if>
|
||||||
<if test="storageLocationId != null ">
|
<if test="storageLocationId != null ">
|
||||||
and storage_location_id = #{storageLocationId}
|
and a.storage_location_id = #{storageLocationId}
|
||||||
</if>
|
</if>
|
||||||
<if test="storageLocationCode != null and storageLocationCode != ''">
|
<if test="storageLocationCode != null and storageLocationCode != ''">
|
||||||
and storage_location_code = #{storageLocationCode}
|
and a.storage_location_code = #{storageLocationCode}
|
||||||
</if>
|
</if>
|
||||||
<if test="storageLocationName != null and storageLocationName != ''">
|
<if test="storageLocationName != null and storageLocationName != ''">
|
||||||
and storage_location_name like concat('%', #{storageLocationName}, '%')
|
and a.storage_location_name like concat('%', #{storageLocationName}, '%')
|
||||||
</if>
|
</if>
|
||||||
<if test="adjustType != null ">
|
<if test="adjustType != null ">
|
||||||
and adjust_type = #{adjustType}
|
and a.adjust_type = #{adjustType}
|
||||||
</if>
|
</if>
|
||||||
<if test="adjustDirection != null ">
|
<if test="adjustDirection != null ">
|
||||||
and adjust_direction = #{adjustDirection}
|
and a.adjust_direction = #{adjustDirection}
|
||||||
</if>
|
</if>
|
||||||
<if test="adjustBeforeStatusCode != null ">
|
<if test="adjustBeforeStatusCode != null ">
|
||||||
and adjust_before_status_code = #{adjustBeforeStatusCode}
|
and a.adjust_before_status_code = #{adjustBeforeStatusCode}
|
||||||
</if>
|
</if>
|
||||||
<if test="adjustBeforeStatusName != null ">
|
<if test="adjustBeforeStatusName != null ">
|
||||||
and adjust_before_status_name = #{adjustBeforeStatusName}
|
and a.adjust_before_status_name = #{adjustBeforeStatusName}
|
||||||
</if>
|
</if>
|
||||||
<if test="adjustAfterStatusCode != null ">
|
<if test="adjustAfterStatusCode != null ">
|
||||||
and adjust_after_status_code = #{adjustAfterStatusCode}
|
and a.adjust_after_status_code = #{adjustAfterStatusCode}
|
||||||
</if>
|
</if>
|
||||||
<if test="adjustAfterStatusName != null ">
|
<if test="adjustAfterStatusName != null ">
|
||||||
and adjust_after_status_name = #{adjustAfterStatusName}
|
and a.adjust_after_status_name = #{adjustAfterStatusName}
|
||||||
</if>
|
</if>
|
||||||
<if test="inventoryBeforeQuantity != null ">
|
<if test="inventoryBeforeQuantity != null ">
|
||||||
and inventory_before_quantity = #{inventoryBeforeQuantity}
|
and a.inventory_before_quantity = #{inventoryBeforeQuantity}
|
||||||
</if>
|
</if>
|
||||||
<if test="allocationBeforeQuantity != null ">
|
<if test="allocationBeforeQuantity != null ">
|
||||||
and allocation_before_quantity = #{allocationBeforeQuantity}
|
and a.allocation_before_quantity = #{allocationBeforeQuantity}
|
||||||
</if>
|
</if>
|
||||||
<if test="freezeBeforeQuantity != null ">
|
<if test="freezeBeforeQuantity != null ">
|
||||||
and freeze_before_quantity = #{freezeBeforeQuantity}
|
and a.freeze_before_quantity = #{freezeBeforeQuantity}
|
||||||
</if>
|
</if>
|
||||||
<if test="inventoryAfterQuantity != null ">
|
<if test="inventoryAfterQuantity != null ">
|
||||||
and inventory_after_quantity = #{inventoryAfterQuantity}
|
and a.inventory_after_quantity = #{inventoryAfterQuantity}
|
||||||
</if>
|
</if>
|
||||||
<if test="allocationAfterQuantity != null ">
|
<if test="allocationAfterQuantity != null ">
|
||||||
and allocation_after_quantity = #{allocationAfterQuantity}
|
and a.allocation_after_quantity = #{allocationAfterQuantity}
|
||||||
</if>
|
</if>
|
||||||
<if test="freezeAfterQuantity != null ">
|
<if test="freezeAfterQuantity != null ">
|
||||||
and freeze_after_quantity = #{freezeAfterQuantity}
|
and a.freeze_after_quantity = #{freezeAfterQuantity}
|
||||||
</if>
|
</if>
|
||||||
<if test="createByName != null and createByName != ''">
|
<if test="createByName != null and createByName != ''">
|
||||||
and create_by_name like concat('%', #{createByName}, '%')
|
and a.create_by_name like concat('%', #{createByName}, '%')
|
||||||
</if>
|
</if>
|
||||||
<if test="updateByName != null and updateByName != ''">
|
<if test="updateByName != null and updateByName != ''">
|
||||||
and update_by_name like concat('%', #{updateByName}, '%')
|
and a.update_by_name like concat('%', #{updateByName}, '%')
|
||||||
</if>
|
</if>
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user