|
@@ -457,8 +457,106 @@ public class IotSapServiceImpl implements IotSapService {
|
|
|
});
|
|
|
}
|
|
|
});
|
|
|
+ // 查询所有SAP库存集合A,以 ‘库存地点+物料编码’ 为唯一key 如果 sapStocks 中有物料不在A中 新增物料
|
|
|
+ Set<String> existStockKeys = new HashSet<>();
|
|
|
+ List<IotSapStockDO> existStocks = TenantUtils.execute(1L, () -> iotSapStockMapper.selectList());
|
|
|
+ if (CollUtil.isNotEmpty(existStocks)) {
|
|
|
+ existStockKeys = existStocks.stream()
|
|
|
+ .filter(stk -> ObjUtil.isNotEmpty(stk) && StrUtil.isNotBlank(stk.getMaterialCode()) && ObjUtil.isNotEmpty(stk.getStorageLocationId())) // 过滤非空对象和非空code
|
|
|
+ .map(stk -> StrUtil.join("-", String.valueOf(stk.getStorageLocationId()), stk.getMaterialCode()))
|
|
|
+ .collect(Collectors.toSet());
|
|
|
+ }
|
|
|
+ // 将已经存在的库存数据 设置成 Map<String, IotSapStockDO> 的形式 便于后续更新
|
|
|
+ // key库存地点id-物料编码 value库存对象 从此集合中筛选将要被更新的库存对象
|
|
|
+ Map<String, IotSapStockDO> tobeUpdatedStockPair = new HashMap<>();
|
|
|
+ tobeUpdatedStockPair = existStocks.stream()
|
|
|
+ .filter(stk -> StrUtil.isNotBlank(stk.getMaterialCode()) && ObjUtil.isNotEmpty(stk.getStorageLocationId())
|
|
|
+ && stockLocationCodeIdPair.containsKey(stk.getStorageLocationId()))
|
|
|
+ .collect(Collectors.toMap(
|
|
|
+ stk -> StrUtil.join("-", stk.getStorageLocationId(), stk.getMaterialCode()),
|
|
|
+ stk -> stk, // 值为对象本身
|
|
|
+ (existing, replacement) -> existing // 处理键冲突: 保留先出现的元素
|
|
|
+ ));
|
|
|
+
|
|
|
+ System.out.println(factoryCode + "当前库中已有sap库存数量:" + existStockKeys.size());
|
|
|
+ // 找出需要新增的库存(SAP物料编码去掉前导零后,不在现有物料集合中的记录)
|
|
|
+ Set<String> finalExistStockKeys = existStockKeys;
|
|
|
+ List<IotSapStockVO> newStocks = sapStocks.stream()
|
|
|
+ .filter(stk -> StrUtil.isNotBlank(stk.getMATNR()) && StrUtil.isNotBlank(stk.getLGORT())
|
|
|
+ && storageLocationIdPair.containsKey(stk.getLGORT()))
|
|
|
+ .filter(stk -> {
|
|
|
+ // 处理前导零:移除MATNR前的 00000000
|
|
|
+ String processedCode = stk.getMATNR().replaceFirst("^0+", "");
|
|
|
+ // 本地已经配置过库存地点 包含SAP库存接口返回的库存地点
|
|
|
+ Long storageLocationId = storageLocationIdPair.get(stk.getLGORT());
|
|
|
+ return !finalExistStockKeys.contains(StrUtil.join("-", storageLocationId, processedCode));
|
|
|
+ })
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ System.out.println(factoryCode + "需要新增的sap库存数量:" + newStocks.size());
|
|
|
+ // 新增SAP库存数据
|
|
|
+ List<IotSapStockDO> tobeAddedStocks = new ArrayList<>();
|
|
|
+ if (CollUtil.isNotEmpty(newStocks)) {
|
|
|
+ newStocks.forEach(stock -> {
|
|
|
+ // 只保存pms维护过库存地点的数据
|
|
|
+ if (locationCodeDeptIdPair.containsKey(stock.getLGORT())) {
|
|
|
+ IotSapStockDO sapStock = new IotSapStockDO();
|
|
|
+ // 部门id
|
|
|
+ sapStock.setDeptId(locationCodeDeptIdPair.get(stock.getLGORT()));
|
|
|
+ // 工厂id
|
|
|
+ if (factoryIdPair.containsKey(stock.getWERKS())) {
|
|
|
+ sapStock.setFactoryId(factoryIdPair.get(stock.getWERKS()));
|
|
|
+ }
|
|
|
+ // 工厂名称
|
|
|
+ if (factoryNamePair.containsKey(stock.getWERKS())) {
|
|
|
+ sapStock.setFactory(factoryNamePair.get(stock.getWERKS()));
|
|
|
+ }
|
|
|
+ // 库存地点id
|
|
|
+ if (storageLocationIdPair.containsKey(stock.getLGORT())) {
|
|
|
+ sapStock.setStorageLocationId(storageLocationIdPair.get(stock.getLGORT()));
|
|
|
+ }
|
|
|
+ // 库存地点名称
|
|
|
+ if (stockLocationNamePair.containsKey(stock.getLGORT())) {
|
|
|
+ sapStock.setProjectDepartment(stockLocationNamePair.get(stock.getLGORT()));
|
|
|
+ }
|
|
|
+ // 物料编码 需要去掉前缀 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());
|
|
|
+ tobeAddedStocks.add(sapStock);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ // 使用返回的SAP库存数据更新已有的 库存数据
|
|
|
+ // pms中已有 SAP返回数据中也存在 则更新
|
|
|
+ List<IotSapStockDO> actualUpdatedStocks = new ArrayList<>();
|
|
|
+ // key库存id-物料编码 value库存对象
|
|
|
+ Map<String, IotSapStockVO> existStockPair = createExistStockMap(sapStocks, existStockKeys, storageLocationIdPair);
|
|
|
+ if (CollUtil.isNotEmpty(existStockPair)) {
|
|
|
+ Map<String, IotSapStockDO> finalTobeUpdatedStockPair = tobeUpdatedStockPair;
|
|
|
+ existStockPair.forEach((k, v) -> {
|
|
|
+ if (finalTobeUpdatedStockPair.containsKey(k)) {
|
|
|
+ IotSapStockDO sapStock = finalTobeUpdatedStockPair.get(k);
|
|
|
+ sapStock.setUnitPrice(v.getJIAGE()); // 更新库存价格
|
|
|
+ sapStock.setQuantity(v.getLABST()); // 更新库存数量
|
|
|
+ sapStock.setUnit(v.getMEINS()); // 更新基本单位
|
|
|
+ actualUpdatedStocks.add(sapStock);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ System.out.println(factoryCode + "需要更新的SAP库存数量:" + actualUpdatedStocks.size());
|
|
|
+ // pms中已有 但是 SAP返回数据不存在 如果设置了安全库存,则库存为0,若没有设置安全库存,则可以删除
|
|
|
+
|
|
|
+
|
|
|
// 遍历明细数据 新增 修改 SAP库存数据
|
|
|
- List<IotSapStockDO> tobeSapStocks = new ArrayList<>();
|
|
|
+ /* List<IotSapStockDO> tobeSapStocks = new ArrayList<>();
|
|
|
sapStocks.forEach(stock -> {
|
|
|
// 只保存pms维护过库存地点的数据
|
|
|
if (locationCodeDeptIdPair.containsKey(stock.getLGORT())) {
|
|
@@ -481,7 +579,7 @@ public class IotSapServiceImpl implements IotSapService {
|
|
|
if (stockLocationNamePair.containsKey(stock.getLGORT())) {
|
|
|
sapStock.setProjectDepartment(stockLocationNamePair.get(stock.getLGORT()));
|
|
|
}
|
|
|
- // 物料编码
|
|
|
+ // 物料编码 需要去掉前缀 00000000
|
|
|
sapStock.setMaterialCode(stock.getMATNR());
|
|
|
// 物料描述
|
|
|
sapStock.setMaterialName(stock.getMAKTX());
|
|
@@ -495,10 +593,14 @@ public class IotSapServiceImpl implements IotSapService {
|
|
|
sapStock.setSyncTime(LocalDateTime.now());
|
|
|
tobeSapStocks.add(sapStock);
|
|
|
}
|
|
|
- });
|
|
|
+ }); */
|
|
|
// 本地库存 初始化 批量插入本地库存 记录
|
|
|
- if (CollUtil.isNotEmpty(tobeSapStocks)) {
|
|
|
- TenantUtils.execute(1L, () -> iotSapStockMapper.insertBatch(tobeSapStocks));
|
|
|
+ if (CollUtil.isNotEmpty(tobeAddedStocks)) {
|
|
|
+ TenantUtils.execute(1L, () -> iotSapStockMapper.insertBatch(tobeAddedStocks));
|
|
|
+ }
|
|
|
+ // pms中存在而且SAP接口也返回的库存数据:更新
|
|
|
+ if (CollUtil.isNotEmpty(actualUpdatedStocks)) {
|
|
|
+ TenantUtils.execute(1L, () -> iotSapStockMapper.updateBatch(actualUpdatedStocks));
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -524,4 +626,31 @@ public class IotSapServiceImpl implements IotSapService {
|
|
|
(existing, replacement) -> existing // 如果有重复的key,保留第一个值
|
|
|
));
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * sap库存 更新 创建 唯一key(库存地点id-物料编码) 到 sap库存对象 的映射
|
|
|
+ * pms中已有的库存 SAP库存接口也返回了 需要更新
|
|
|
+ * @param sapStocks SAP库存列表
|
|
|
+ * @param existStockKeys 数据库中已存在的 sap库存 集合
|
|
|
+ * @param storageLocationIdPair key库存地点code value库存地点id
|
|
|
+ * @return 物料编码到描述的映射
|
|
|
+ */
|
|
|
+ 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()) && storageLocationIdPair.containsKey(sapStock.getLGORT()))
|
|
|
+ .map(sapStock -> {
|
|
|
+ // 处理前导零:移除MATNR前的 00000000
|
|
|
+ String processedCode = sapStock.getMATNR().replaceFirst("^0+", "");
|
|
|
+ // 本地已经配置过库存地点 包含SAP库存接口返回的库存地点
|
|
|
+ Long storageLocationId = storageLocationIdPair.get(sapStock.getLGORT());
|
|
|
+ return new AbstractMap.SimpleEntry<>(StrUtil.join("-", storageLocationId, processedCode), sapStock);
|
|
|
+ })
|
|
|
+ .filter(entry -> existStockKeys.contains(entry.getKey()))
|
|
|
+ .collect(Collectors.toMap(
|
|
|
+ Map.Entry::getKey,
|
|
|
+ Map.Entry::getValue,
|
|
|
+ (existing, replacement) -> existing // 如果有重复的key,保留第一个值
|
|
|
+ ));
|
|
|
+ }
|
|
|
}
|