|
@@ -5,6 +5,8 @@ import cn.hutool.core.collection.CollUtil;
|
|
|
import cn.hutool.core.util.ObjUtil;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
|
|
|
+import cn.iocoder.yudao.module.pms.controller.admin.iotlockstock.vo.IotLockStockPageReqVO;
|
|
|
+import cn.iocoder.yudao.module.pms.controller.admin.iotsappickinglist.vo.IotSapPickingListPageReqVO;
|
|
|
import cn.iocoder.yudao.module.pms.dal.dataobject.iotlockstock.IotLockStockDO;
|
|
|
import cn.iocoder.yudao.module.pms.dal.dataobject.iotmaterial.IotMaterialDO;
|
|
|
import cn.iocoder.yudao.module.pms.dal.dataobject.iotsappickinglist.IotSapPickingListDO;
|
|
@@ -259,11 +261,12 @@ public class IotSapServiceImpl implements IotSapService {
|
|
|
pickingListHeads.forEach(head -> {
|
|
|
pickingCodeCostCenterPair.put(head.getZLTNO(), head.getKOSTL());
|
|
|
});
|
|
|
- // 遍历子表 所有物料
|
|
|
- // 领料单表不合并物料数量、单价 审核入本地库时 合并相同成本中心下的物料数量 单价
|
|
|
+ // 领料单表不合并物料数量、单价 todo(审核入本地库时 合并相同成本中心下的物料数量 单价)
|
|
|
List<IotSapPickingListDO> pickingLists = new ArrayList<>();
|
|
|
// 本地库存初始化时合并相同成本中心的 物料数量 单价
|
|
|
- List<IotLockStockDO> lockStocks = new ArrayList<>();
|
|
|
+ List<IotLockStockDO> tobeAddedLockStocks = new ArrayList<>();
|
|
|
+ // 需要更新的本地库存集合
|
|
|
+ List<IotLockStockDO> tobeUpdatedLockStocks = new ArrayList<>();
|
|
|
// 本地库存初始化 成本中心+物料编码,确定唯一明细记录,合并数量、单价
|
|
|
// 合并的物料数量集合
|
|
|
Map<String, BigDecimal> mergeMaterialQuantities = new HashMap<>();
|
|
@@ -272,14 +275,41 @@ public class IotSapServiceImpl implements IotSapService {
|
|
|
// 合并的物料总价
|
|
|
Map<String, BigDecimal> mergeMaterialTotalPrices = new HashMap<>();
|
|
|
Map<String, IotSapPickingListItemVO> basicMaterials = new HashMap<>();
|
|
|
+ // 首先查询领料单表中已经存在的领料单号 集合 existPickingNumbers
|
|
|
+ // 筛选出 pickingListItems 中不在集合 existPickingNumbers 中的数据集合 A 新增到 领料单表
|
|
|
+ // 本地库存表也要基于集合A 与 本地已有的库存数据 合并总数量 与 平均价 既有新增的物料 也有需要更新的物料
|
|
|
+ IotSapPickingListPageReqVO reqVO = new IotSapPickingListPageReqVO();
|
|
|
+ List<IotSapPickingListDO> existPickingList = TenantUtils.execute(1L, () -> iotSapPickingListMapper.selectList(reqVO));
|
|
|
+ Set<String> distinctNumbers = new HashSet<>();
|
|
|
+ if (CollUtil.isNotEmpty(existPickingList)) {
|
|
|
+ distinctNumbers = existPickingList.stream()
|
|
|
+ .map(IotSapPickingListDO::getNumber) // 提取 number 属性
|
|
|
+ .filter(Objects::nonNull) // 过滤 null
|
|
|
+ .collect(Collectors.toSet());
|
|
|
+ }
|
|
|
+ Set<String> finalDistinctNumbers = distinctNumbers;
|
|
|
// 以 成本中心-物料编码 维度统计 物料总数量 物料总金额
|
|
|
- pickingListItems.forEach(item -> {
|
|
|
+
|
|
|
+ // 先处理新增的本地库存 筛选出不在本地领料单集合中的数据 B 与 在本地领料单集合中的数据 C
|
|
|
+ // 如果没有不在本地库存中的领料单 则不需要新增或更新本地库存
|
|
|
+ Set<Long> relativeCostCenterIds = new HashSet<>();
|
|
|
+ Set<String> relativeMaterialCodes = new HashSet<>();
|
|
|
+ // 新的领料单包含的 成本中心-物料 集合
|
|
|
+ Set<String> relativeUniqueKeys = new HashSet<>();
|
|
|
+ pickingListItems.stream()
|
|
|
+ .filter(item -> StrUtil.isNotBlank(item.getZLTNO()) && !finalDistinctNumbers.contains(item.getZLTNO()))
|
|
|
+ .forEach(item -> {
|
|
|
if (StrUtil.isNotBlank(item.getMATNR())
|
|
|
&& StrUtil.isNotBlank(item.getZLTNO()) && pickingCodeCostCenterPair.containsKey(item.getZLTNO())) {
|
|
|
-
|
|
|
// 领料单号<->成本中心编码
|
|
|
String costCenterCode = pickingCodeCostCenterPair.get(item.getZLTNO());
|
|
|
if (StrUtil.isNotBlank(costCenterCode)) {
|
|
|
+ if (costCenterIdPair.containsKey(costCenterCode)) {
|
|
|
+ relativeCostCenterIds.add(costCenterIdPair.get(costCenterCode));
|
|
|
+ relativeUniqueKeys.add(StrUtil.join("~~", costCenterIdPair.get(costCenterCode), item.getMATNR()));
|
|
|
+ System.out.println("costCenterId 唯一key:" + StrUtil.join("~~", costCenterIdPair.get(costCenterCode), item.getMATNR()));
|
|
|
+ }
|
|
|
+ relativeMaterialCodes.add(item.getMATNR());
|
|
|
String uniqueKey = StrUtil.join("~~", costCenterCode, item.getMATNR());
|
|
|
System.out.println("唯一key:" + uniqueKey);
|
|
|
// 当前明细行 物料数量
|
|
@@ -288,14 +318,14 @@ public class IotSapServiceImpl implements IotSapService {
|
|
|
BigDecimal currentUnitPrice = ObjUtil.isEmpty(item.getVERPR()) ? BigDecimal.ZERO : item.getVERPR();
|
|
|
// 当前明细行 物料总价
|
|
|
BigDecimal currentTotalPrice = currentQuantity.multiply(currentUnitPrice);
|
|
|
- // 物料总数量
|
|
|
+ // 相同物料总数量
|
|
|
if (mergeMaterialQuantities.containsKey(uniqueKey)) {
|
|
|
BigDecimal tempQuantity = mergeMaterialQuantities.get(uniqueKey);
|
|
|
mergeMaterialQuantities.put(uniqueKey, tempQuantity.add(currentQuantity));
|
|
|
} else {
|
|
|
mergeMaterialQuantities.put(uniqueKey, currentQuantity);
|
|
|
}
|
|
|
- // 物料总价 单价*数量
|
|
|
+ // 相同物料 单价总和
|
|
|
if (mergeMaterialTotalPrices.containsKey(uniqueKey)) {
|
|
|
BigDecimal tempTotalPrice = mergeMaterialTotalPrices.get(uniqueKey);
|
|
|
// 查询已经暂存的 物料总数量
|
|
@@ -311,6 +341,36 @@ public class IotSapServiceImpl implements IotSapService {
|
|
|
}
|
|
|
});
|
|
|
System.out.println(factoryCode + "基准物料集合容量:" + basicMaterials.size());
|
|
|
+ // 根据筛选出的不在本地领料单库的领料单 组装的 ‘成本中心-物料编码’ 集合 查询本地库存中已有的物料库存 以 成本中心-物料编码 为唯一键 统计物料总数量 物料总金额
|
|
|
+ Set<String> existUniqueKey = new HashSet<>();
|
|
|
+ // 新领料单物料在本地库存中不存在 成本中心-物料 集合 新增物料本地库存
|
|
|
+ Set<String> tobeAddedUniqueKeys = new HashSet<>();
|
|
|
+ if (CollUtil.isNotEmpty(relativeCostCenterIds) && CollUtil.isNotEmpty(relativeMaterialCodes)) {
|
|
|
+ IotLockStockPageReqVO lockStockReqVO = new IotLockStockPageReqVO();
|
|
|
+ lockStockReqVO.setCostCenterIds(relativeCostCenterIds);
|
|
|
+ lockStockReqVO.setMaterialCodes(relativeMaterialCodes);
|
|
|
+ List<IotLockStockDO> existLockStocks = TenantUtils.execute(1L, () -> iotLockStockMapper.selectList(lockStockReqVO));
|
|
|
+ System.out.println("本地库存已经存在的新领料单 成本中心-物料:" + existLockStocks.size());
|
|
|
+ // 新增的领料单包含的物料 如果在本地库存中已经存在,需要合并计算总数量 平均单价
|
|
|
+ // 如果新增的领料单包含的物料在本地库存中不存在,单向合并计算总数量 平均单价后 新增本地库存
|
|
|
+ if (CollUtil.isNotEmpty(existLockStocks)) {
|
|
|
+ existLockStocks.forEach(lockStock -> {
|
|
|
+ existUniqueKey.add(StrUtil.join("~~", lockStock.getCostCenterId(), lockStock.getMaterialCode()));
|
|
|
+ System.out.println("当前库中已经存在的成本中心-物料key:" + StrUtil.join("~~", lockStock.getCostCenterId(), lockStock.getMaterialCode()));
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 存在新增的领料单 找出新增领料单物料不在已有本地库存中的数据
|
|
|
+ if (CollUtil.isNotEmpty(relativeUniqueKeys)) {
|
|
|
+ relativeUniqueKeys.forEach(key -> {
|
|
|
+ if (!existUniqueKey.contains(key)) {
|
|
|
+ // 新增的领料单 成本中心-物料编码 在本地库存不存在
|
|
|
+ tobeAddedUniqueKeys.add(key);
|
|
|
+ System.out.println("新增的领料单 成本中心-物料编码:" + key);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
// 以 成本中心-物料编码 维度统计 物料平均单价=物料总金额/物料总数量
|
|
|
if (CollUtil.isNotEmpty(mergeMaterialTotalPrices)) {
|
|
|
mergeMaterialTotalPrices.forEach((k,v) -> {
|
|
@@ -332,42 +392,52 @@ public class IotSapServiceImpl implements IotSapService {
|
|
|
if (costCenterMaterialAttr.length > 1) {
|
|
|
// 领料单<->成本中心<->部门
|
|
|
String costCenterCode = costCenterMaterialAttr[0];
|
|
|
+ String materialCode = costCenterMaterialAttr[1];
|
|
|
if (costCenterCodeDeptIdPair.containsKey(costCenterCode)) {
|
|
|
- IotLockStockDO lockStock = new IotLockStockDO();
|
|
|
- if (costCenterCodeDeptIdPair.containsKey(costCenterCode)) {
|
|
|
- lockStock.setDeptId(costCenterCodeDeptIdPair.get(costCenterCode));
|
|
|
- }
|
|
|
- // sap成本中心 在pms系统中的id
|
|
|
if (costCenterIdPair.containsKey(costCenterCode)) {
|
|
|
- lockStock.setCostCenterId(costCenterIdPair.get(costCenterCode));
|
|
|
- }
|
|
|
- // sap工厂 在pms系统中的id
|
|
|
- if (costCenterFactoryCodePair.containsKey(costCenterCode)) {
|
|
|
- String tempFactoryCode = costCenterFactoryCodePair.get(costCenterCode);
|
|
|
- if (factoryIdPair.containsKey(tempFactoryCode)) {
|
|
|
- lockStock.setFactoryId(factoryIdPair.get(tempFactoryCode));
|
|
|
+ // 只有部门设置了对应的 成本中心 才会新增 本地库存数据
|
|
|
+ String uniqueKey = StrUtil.join("~~", costCenterIdPair.get(costCenterCode), materialCode);
|
|
|
+ if (tobeAddedUniqueKeys.contains(uniqueKey)) {
|
|
|
+ IotLockStockDO lockStock = new IotLockStockDO();
|
|
|
+ if (costCenterCodeDeptIdPair.containsKey(costCenterCode)) {
|
|
|
+ lockStock.setDeptId(costCenterCodeDeptIdPair.get(costCenterCode));
|
|
|
+ }
|
|
|
+ // sap成本中心 在pms系统中的id
|
|
|
+ if (costCenterIdPair.containsKey(costCenterCode)) {
|
|
|
+ lockStock.setCostCenterId(costCenterIdPair.get(costCenterCode));
|
|
|
+ }
|
|
|
+ // sap工厂 在pms系统中的id
|
|
|
+ if (costCenterFactoryCodePair.containsKey(costCenterCode)) {
|
|
|
+ String tempFactoryCode = costCenterFactoryCodePair.get(costCenterCode);
|
|
|
+ if (factoryIdPair.containsKey(tempFactoryCode)) {
|
|
|
+ lockStock.setFactoryId(factoryIdPair.get(tempFactoryCode));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 物料编码
|
|
|
+ lockStock.setMaterialCode(costCenterMaterialAttr[1]);
|
|
|
+ // 物料描述
|
|
|
+ lockStock.setMaterialName(v.getMAKTX());
|
|
|
+ // 单位
|
|
|
+ lockStock.setUnit(v.getMEINS());
|
|
|
+ // 物料数量
|
|
|
+ if (mergeMaterialQuantities.containsKey(k)) {
|
|
|
+ lockStock.setQuantity(mergeMaterialQuantities.get(k));
|
|
|
+ }
|
|
|
+ // 单价
|
|
|
+ if (mergeMaterialUnitPrices.containsKey(k)) {
|
|
|
+ lockStock.setUnitPrice(mergeMaterialUnitPrices.get(k));
|
|
|
+ }
|
|
|
+ tobeAddedLockStocks.add(lockStock);
|
|
|
}
|
|
|
}
|
|
|
- // 物料编码
|
|
|
- lockStock.setMaterialCode(costCenterMaterialAttr[1]);
|
|
|
- // 物料描述
|
|
|
- lockStock.setMaterialName(v.getMAKTX());
|
|
|
- // 单位
|
|
|
- lockStock.setUnit(v.getMEINS());
|
|
|
- // 物料数量
|
|
|
- if (mergeMaterialQuantities.containsKey(k)) {
|
|
|
- lockStock.setQuantity(mergeMaterialQuantities.get(k));
|
|
|
- }
|
|
|
- // 单价
|
|
|
- if (mergeMaterialUnitPrices.containsKey(k)) {
|
|
|
- lockStock.setUnitPrice(mergeMaterialUnitPrices.get(k));
|
|
|
- }
|
|
|
- lockStocks.add(lockStock);
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
- pickingListItems.forEach(item -> {
|
|
|
+ // 从SAP返回数据中 筛选出不在本地领料单集合中的数据 新增
|
|
|
+ pickingListItems.stream()
|
|
|
+ .filter(item -> StrUtil.isNotBlank(item.getZLTNO()) && !finalDistinctNumbers.contains(item.getZLTNO()))
|
|
|
+ .forEach(item -> {
|
|
|
IotSapPickingListDO picking = new IotSapPickingListDO();
|
|
|
// 领料单<->成本中心<->部门
|
|
|
if (pickingCodeCostCenterPair.containsKey(item.getZLTNO())) {
|
|
@@ -400,9 +470,9 @@ public class IotSapServiceImpl implements IotSapService {
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
- // 本地库存 初始化 批量插入本地库存 记录
|
|
|
- if (CollUtil.isNotEmpty(lockStocks)) {
|
|
|
- TenantUtils.execute(1L, () -> iotLockStockMapper.insertBatch(lockStocks));
|
|
|
+ // 本地库存 初始化 批量插入本地库存 记录 新增本地库存
|
|
|
+ if (CollUtil.isNotEmpty(tobeAddedLockStocks)) {
|
|
|
+ TenantUtils.execute(1L, () -> iotLockStockMapper.insertBatch(tobeAddedLockStocks));
|
|
|
}
|
|
|
// 新增领料单
|
|
|
if (CollUtil.isNotEmpty(pickingLists)) {
|