|
@@ -513,13 +513,13 @@ public class IotSapServiceImpl implements IotSapService {
|
|
|
Map<String, Long> factoryIdPair = new HashMap<>();
|
|
|
// key工厂code value工厂名称
|
|
|
Map<String, String> factoryNamePair = new HashMap<>();
|
|
|
- // key库存地点code value库存地点id
|
|
|
+ // key工厂code-库存地点code value库存地点id
|
|
|
Map<String, Long> storageLocationIdPair = new HashMap<>();
|
|
|
- // key库存地点id value库存地点code
|
|
|
+ // key库存地点id value工厂code-库存地点code
|
|
|
Map<Long, String> stockLocationCodeIdPair = new HashMap<>();
|
|
|
// key库存地点code value部门id
|
|
|
Map<String, Long> locationCodeDeptIdPair = new HashMap<>();
|
|
|
- // key库存地点code value库存地点名称描述
|
|
|
+ // key工厂code-库存地点code value库存地点名称描述
|
|
|
Map<String, String> stockLocationNamePair = new HashMap<>();
|
|
|
// 工厂集合
|
|
|
factories.forEach(factory -> {
|
|
@@ -530,15 +530,13 @@ public class IotSapServiceImpl implements IotSapService {
|
|
|
storageLocations.forEach(location -> {
|
|
|
System.out.println("当前库存地点信息:" + location.getFactoryCode() + " - " + location.getStorageLocationCode());
|
|
|
String uniqueKey = StrUtil.join("-", location.getFactoryCode(), location.getStorageLocationCode());
|
|
|
- // stockLocationCodeIdPair.put(location.getId(), location.getStorageLocationCode());
|
|
|
stockLocationCodeIdPair.put(location.getId(), uniqueKey);
|
|
|
- // storageLocationIdPair.put(location.getStorageLocationCode(), location.getId());
|
|
|
storageLocationIdPair.put(uniqueKey, location.getId());
|
|
|
- // stockLocationNamePair.put(location.getStorageLocationCode(), location.getStorageLocationName());
|
|
|
stockLocationNamePair.put(uniqueKey, location.getStorageLocationName());
|
|
|
});
|
|
|
// 筛选出pms系统中未维护的 库存地点 信息(工厂-库存地点编码)
|
|
|
Set<String> notExistStorageLocations = new HashSet<>();
|
|
|
+ // 系统中未维护的 工厂 库存地点 也需要存储到数据库 但是 不设置 deptId
|
|
|
sapStocks.forEach(stock -> {
|
|
|
String uniqueKey = StrUtil.join("-", stock.getWERKS(), stock.getLGORT());
|
|
|
if (!storageLocationIdPair.containsKey(uniqueKey)) {
|
|
@@ -566,7 +564,7 @@ public class IotSapServiceImpl implements IotSapService {
|
|
|
});
|
|
|
}
|
|
|
});
|
|
|
- // 查询所有SAP库存集合A,以 ‘库存地点+物料编码’ 为唯一key 如果 sapStocks 中有物料不在A中 新增物料
|
|
|
+ // 查询所有SAP库存集合A,以 ‘库存地点id+物料编码’ 为唯一key 如果 sapStocks 中有物料不在A中 新增物料
|
|
|
Set<String> existStockKeys = new HashSet<>();
|
|
|
List<IotSapStockDO> existStocks = TenantUtils.execute(1L, () -> iotSapStockMapper.selectList());
|
|
|
if (CollUtil.isNotEmpty(existStocks)) {
|
|
@@ -576,6 +574,19 @@ public class IotSapServiceImpl implements IotSapService {
|
|
|
.map(stk -> StrUtil.join("-", String.valueOf(stk.getStorageLocationId()), stk.getMaterialCode()))
|
|
|
.collect(Collectors.toSet());
|
|
|
}
|
|
|
+ System.out.println(factoryCode + "当前库中已有sap库存数量:" + existStockKeys.size());
|
|
|
+
|
|
|
+ // todo 没有维护SAP工厂 库存地点的组织 已经存在的库存数据
|
|
|
+ Set<String> noFactoryExistStockKeys = new HashSet<>();
|
|
|
+ if (CollUtil.isNotEmpty(existStocks)) {
|
|
|
+ noFactoryExistStockKeys = existStocks.stream()
|
|
|
+ // 过滤非空对象和非空code
|
|
|
+ .filter(stk -> ObjUtil.isNotEmpty(stk) && StrUtil.isNotBlank(stk.getMaterialCode())
|
|
|
+ && StrUtil.isNotBlank(stk.getFactoryCode()) && StrUtil.isNotBlank(stk.getStorageLocationCode()))
|
|
|
+ .map(stk -> StrUtil.join("-", stk.getFactoryCode(), stk.getStorageLocationCode(), stk.getMaterialCode()))
|
|
|
+ .collect(Collectors.toSet());
|
|
|
+ }
|
|
|
+
|
|
|
// 将已经存在的库存数据 设置成 Map<String, IotSapStockDO> 的形式 便于后续更新
|
|
|
// key库存地点id-物料编码 value库存对象 从此集合中筛选将要被更新的库存对象
|
|
|
Map<String, IotSapStockDO> tobeUpdatedStockPair = new HashMap<>();
|
|
@@ -588,7 +599,19 @@ public class IotSapServiceImpl implements IotSapService {
|
|
|
(existing, replacement) -> existing // 处理键冲突: 保留先出现的元素
|
|
|
));
|
|
|
|
|
|
- System.out.println(factoryCode + "当前库中已有sap库存数量:" + existStockKeys.size());
|
|
|
+ // todo 没有配置SAP 工厂 库存地点 的组织库存更新
|
|
|
+ // 将已经存在的库存数据 设置成 Map<String, IotSapStockDO> 的形式 便于后续更新
|
|
|
+ // key工厂code-库存地点code-物料编码 value库存对象 从此集合中筛选将要被更新的库存对象
|
|
|
+ Map<String, IotSapStockDO> noFactoryTobeUpdatedStockPair = new HashMap<>();
|
|
|
+ noFactoryTobeUpdatedStockPair = existStocks.stream()
|
|
|
+ .filter(stk -> StrUtil.isNotBlank(stk.getMaterialCode()) && StrUtil.isNotBlank(stk.getFactoryCode())
|
|
|
+ && StrUtil.isNotBlank(stk.getStorageLocationCode()))
|
|
|
+ .collect(Collectors.toMap(
|
|
|
+ stk -> StrUtil.join("-", stk.getFactoryCode(), stk.getStorageLocationCode(), stk.getMaterialCode()),
|
|
|
+ stk -> stk, // 值为对象本身
|
|
|
+ (existing, replacement) -> existing // 处理键冲突: 保留先出现的元素
|
|
|
+ ));
|
|
|
+
|
|
|
// 找出需要新增的库存(SAP物料编码去掉前导零后,不在现有物料集合中的记录)
|
|
|
Set<String> finalExistStockKeys = existStockKeys;
|
|
|
List<IotSapStockVO> newStocks = sapStocks.stream()
|
|
@@ -602,7 +625,22 @@ public class IotSapServiceImpl implements IotSapService {
|
|
|
return !finalExistStockKeys.contains(StrUtil.join("-", storageLocationId, processedCode));
|
|
|
})
|
|
|
.collect(Collectors.toList());
|
|
|
+
|
|
|
System.out.println(factoryCode + "需要新增的sap库存数量:" + newStocks.size());
|
|
|
+
|
|
|
+ // todo 没有维护SAP工厂 库存地点的组织 新增的库存数据
|
|
|
+ // 找出需要新增的库存(SAP物料编码去掉前导零后,不在现有物料集合中的记录)
|
|
|
+ Set<String> noFactoryFinalExistStockKeys = noFactoryExistStockKeys;
|
|
|
+ List<IotSapStockVO> noFactoryNewStocks = sapStocks.stream()
|
|
|
+ .filter(stk -> StrUtil.isNotBlank(stk.getMATNR()) && StrUtil.isNotBlank(stk.getLGORT()) && StrUtil.isNotBlank(stk.getWERKS()))
|
|
|
+ .filter(stk -> {
|
|
|
+ // 处理前导零:移除MATNR前的 00000000
|
|
|
+ String processedCode = stk.getMATNR().replaceFirst("^0+", "");
|
|
|
+ // 本地已经配置过库存地点 包含SAP库存接口返回的库存地点
|
|
|
+ return !noFactoryFinalExistStockKeys.contains(StrUtil.join("-", stk.getWERKS(), stk.getLGORT(), processedCode));
|
|
|
+ })
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
// 新增SAP库存数据
|
|
|
List<IotSapStockDO> tobeAddedStocks = new ArrayList<>();
|
|
|
if (CollUtil.isNotEmpty(newStocks)) {
|
|
@@ -645,6 +683,51 @@ public class IotSapServiceImpl implements IotSapService {
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
+
|
|
|
+ // todo 新增 没有配置组织部门的 SAP库存数据
|
|
|
+ List<IotSapStockDO> noFactoryTobeAddedStocks = new ArrayList<>();
|
|
|
+ if (CollUtil.isNotEmpty(noFactoryNewStocks)) {
|
|
|
+ noFactoryNewStocks.forEach(stock -> {
|
|
|
+ // 只保存pms维护过库存地点的数据
|
|
|
+ String uniqueKey = StrUtil.join("-", stock.getWERKS(), stock.getLGORT());
|
|
|
+ IotSapStockDO sapStock = new IotSapStockDO();
|
|
|
+ // 部门统一设置为 科瑞石油技术
|
|
|
+ sapStock.setDeptId(156l);
|
|
|
+ // 工厂id
|
|
|
+ /* if (factoryIdPair.containsKey(stock.getWERKS())) {
|
|
|
+ sapStock.setFactoryId(factoryIdPair.get(stock.getWERKS()));
|
|
|
+ } */
|
|
|
+ sapStock.setFactoryCode(stock.getWERKS());
|
|
|
+ // 工厂名称
|
|
|
+ if (factoryNamePair.containsKey(stock.getWERKS())) {
|
|
|
+ sapStock.setFactory(factoryNamePair.get(stock.getWERKS()));
|
|
|
+ }
|
|
|
+ // 库存地点 code
|
|
|
+ sapStock.setStorageLocationCode(stock.getLGORT());
|
|
|
+ // 库存地点id
|
|
|
+ /* if (storageLocationIdPair.containsKey(uniqueKey)) {
|
|
|
+ sapStock.setStorageLocationId(storageLocationIdPair.get(uniqueKey));
|
|
|
+ } */
|
|
|
+ // 库存地点名称
|
|
|
+ if (stockLocationNamePair.containsKey(uniqueKey)) {
|
|
|
+ sapStock.setProjectDepartment(stockLocationNamePair.get(uniqueKey));
|
|
|
+ }
|
|
|
+ // 物料编码 需要去掉前缀 00000000
|
|
|
+ sapStock.setMaterialCode(stock.getMATNR().replaceFirst("^0+", ""));
|
|
|
+ // 物料描述
|
|
|
+ sapStock.setMaterialName(stock.getMAKTX());
|
|
|
+ // 库存数量
|
|
|
+ sapStock.setQuantity(stock.getLABST());
|
|
|
+ // 单价
|
|
|
+ sapStock.setUnitPrice(stock.getJIAGE());
|
|
|
+ // 基本单位
|
|
|
+ sapStock.setUnit(stock.getMEINS());
|
|
|
+ // 同步时间
|
|
|
+ sapStock.setSyncTime(LocalDateTime.now());
|
|
|
+ noFactoryTobeAddedStocks.add(sapStock);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
// 使用返回的SAP库存数据更新已有的 库存数据
|
|
|
// pms中已有 SAP返回数据中也存在 则更新
|
|
|
List<IotSapStockDO> actualUpdatedStocks = new ArrayList<>();
|
|
@@ -663,8 +746,27 @@ public class IotSapServiceImpl implements IotSapService {
|
|
|
});
|
|
|
}
|
|
|
System.out.println(factoryCode + "需要更新的SAP库存数量:" + actualUpdatedStocks.size());
|
|
|
- // pms中已有 但是 SAP返回数据不存在 如果设置了安全库存,则库存为0,若没有设置安全库存,则可以删除
|
|
|
|
|
|
+ // todo sap 工厂 库存地点 未关联组织部门
|
|
|
+ // 使用返回的SAP库存数据更新已有的 库存数据 pms中已有 SAP返回数据中也存在 则更新
|
|
|
+ List<IotSapStockDO> noFactoryActualUpdatedStocks = new ArrayList<>();
|
|
|
+ // key工厂code-库存地点code-物料编码 value库存对象
|
|
|
+ Map<String, IotSapStockVO> noFactoryExistStockPair = createNoFactoryExistStockMap(sapStocks, noFactoryExistStockKeys, storageLocationIdPair);
|
|
|
+ if (CollUtil.isNotEmpty(noFactoryExistStockPair)) {
|
|
|
+ Map<String, IotSapStockDO> finalTobeUpdatedStockPair = noFactoryTobeUpdatedStockPair;
|
|
|
+ noFactoryExistStockPair.forEach((k, v) -> {
|
|
|
+ if (finalTobeUpdatedStockPair.containsKey(k)) {
|
|
|
+ IotSapStockDO sapStock = finalTobeUpdatedStockPair.get(k);
|
|
|
+ sapStock.setUnitPrice(v.getJIAGE()); // 更新库存价格
|
|
|
+ sapStock.setQuantity(v.getLABST()); // 更新库存数量
|
|
|
+ sapStock.setUnit(v.getMEINS()); // 更新基本单位
|
|
|
+ noFactoryActualUpdatedStocks.add(sapStock);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ System.out.println(factoryCode + "SAP工厂库存地点未关联组织部门-需要更新的SAP库存数量:" + noFactoryActualUpdatedStocks.size());
|
|
|
+
|
|
|
+ // pms中已有 但是 SAP返回数据不存在 如果设置了安全库存,则库存为0,若没有设置安全库存,则可以删除
|
|
|
|
|
|
// 遍历明细数据 新增 修改 SAP库存数据
|
|
|
/* List<IotSapStockDO> tobeSapStocks = new ArrayList<>();
|
|
@@ -705,14 +807,22 @@ public class IotSapServiceImpl implements IotSapService {
|
|
|
tobeSapStocks.add(sapStock);
|
|
|
}
|
|
|
}); */
|
|
|
- // 本地库存 初始化 批量插入本地库存 记录
|
|
|
+ // 本地库存 初始化 批量插入SAP 库存 工厂 库存地点 已经关联了组织架构部门
|
|
|
if (CollUtil.isNotEmpty(tobeAddedStocks)) {
|
|
|
TenantUtils.execute(1L, () -> iotSapStockMapper.insertBatch(tobeAddedStocks));
|
|
|
}
|
|
|
+ // 本地库存 初始化 批量插入本地库存 记录 工厂 库存地点 未关联了组织架构部门
|
|
|
+ if (CollUtil.isNotEmpty(noFactoryTobeAddedStocks)) {
|
|
|
+ TenantUtils.execute(1L, () -> iotSapStockMapper.insertBatch(noFactoryTobeAddedStocks));
|
|
|
+ }
|
|
|
// pms中存在而且SAP接口也返回的库存数据:更新
|
|
|
if (CollUtil.isNotEmpty(actualUpdatedStocks)) {
|
|
|
TenantUtils.execute(1L, () -> iotSapStockMapper.updateBatch(actualUpdatedStocks));
|
|
|
}
|
|
|
+ // pms中存在而且SAP接口也返回的库存数据:更新 工厂 库存地点 未关联了组织架构部门
|
|
|
+ if (CollUtil.isNotEmpty(noFactoryActualUpdatedStocks)) {
|
|
|
+ TenantUtils.execute(1L, () -> iotSapStockMapper.updateBatch(noFactoryActualUpdatedStocks));
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -772,7 +882,7 @@ public class IotSapServiceImpl implements IotSapService {
|
|
|
private Map<String, IotSapStockVO> createExistStockMap(List<IotSapStockVO> sapStocks, Set<String> existStockKeys, Map<String, Long> storageLocationIdPair) {
|
|
|
return sapStocks.stream()
|
|
|
.filter(sapStock -> StrUtil.isNotBlank(sapStock.getMATNR()) &&
|
|
|
- ObjUtil.isNotEmpty(sapStock.getLGORT()) &&
|
|
|
+ StrUtil.isNotBlank(sapStock.getLGORT()) &&
|
|
|
storageLocationIdPair.containsKey(StrUtil.join("-", sapStock.getWERKS(), sapStock.getLGORT())))
|
|
|
.map(sapStock -> {
|
|
|
// 处理前导零:移除MATNR前的 00000000
|
|
@@ -788,4 +898,31 @@ public class IotSapServiceImpl implements IotSapService {
|
|
|
(existing, replacement) -> existing // 如果有重复的key,保留第一个值
|
|
|
));
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理本地未维护的工厂 库存地点 同步过来的物料
|
|
|
+ * sap库存 更新 创建 唯一key(工厂code+库存地点code-物料编码) 到 sap库存对象 的映射
|
|
|
+ * pms中已有的库存 SAP库存接口也返回了 需要更新
|
|
|
+ * @param sapStocks SAP库存列表
|
|
|
+ * @param existStockKeys 数据库中已存在的 sap库存 集合
|
|
|
+ * @param storageLocationIdPair key库存地点code value库存地点id
|
|
|
+ * @return 物料编码到描述的映射
|
|
|
+ */
|
|
|
+ private Map<String, IotSapStockVO> createNoFactoryExistStockMap(List<IotSapStockVO> sapStocks,
|
|
|
+ Set<String> existStockKeys, Map<String, Long> storageLocationIdPair) {
|
|
|
+ return sapStocks.stream()
|
|
|
+ .filter(sapStock -> StrUtil.isNotBlank(sapStock.getMATNR()) && StrUtil.isNotBlank(sapStock.getLGORT()))
|
|
|
+ .map(sapStock -> {
|
|
|
+ // 处理前导零:移除MATNR前的 00000000
|
|
|
+ String processedCode = sapStock.getMATNR().replaceFirst("^0+", "");
|
|
|
+ // 本地已经配置过库存地点 包含SAP库存接口返回的库存地点
|
|
|
+ return new AbstractMap.SimpleEntry<>(StrUtil.join("-", sapStock.getWERKS(), sapStock.getLGORT(), processedCode), sapStock);
|
|
|
+ })
|
|
|
+ .filter(entry -> existStockKeys.contains(entry.getKey()))
|
|
|
+ .collect(Collectors.toMap(
|
|
|
+ Map.Entry::getKey,
|
|
|
+ Map.Entry::getValue,
|
|
|
+ (existing, replacement) -> existing // 如果有重复的key,保留第一个值
|
|
|
+ ));
|
|
|
+ }
|
|
|
}
|