Selaa lähdekoodia

pms 同步SAP领料单功能优化

zhangcl 2 kuukautta sitten
vanhempi
commit
cf60449c96

+ 29 - 1
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotsapstock/IotSapStockController.java

@@ -1,6 +1,7 @@
 package cn.iocoder.yudao.module.pms.controller.admin.iotsapstock;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjUtil;
 import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
@@ -23,7 +24,9 @@ import javax.annotation.Resource;
 import javax.servlet.http.HttpServletResponse;
 import javax.validation.Valid;
 import java.io.IOException;
+import java.math.BigDecimal;
 import java.util.List;
+import java.util.Objects;
 
 import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -87,7 +90,32 @@ public class IotSapStockController {
     @PreAuthorize("@ss.hasPermission('pms:iot-sap-stock:query')")
     public CommonResult<PageResult<IotSapStockRespVO>> getIotSapStockPage(@Valid IotSapStockPageReqVO pageReqVO) {
         PageResult<IotSapStockDO> pageResult = iotSapStockService.getIotSapStockPage(pageReqVO);
-        return success(BeanUtils.toBean(pageResult, IotSapStockRespVO.class));
+        List<IotSapStockDO> sapStockList = iotSapStockService.getIotSapStockList(pageReqVO);
+        // 计算符合查询条件的 库存总数量 库存总金额
+        BigDecimal totalQuantity;
+        BigDecimal totalAmount;
+        if (CollUtil.isNotEmpty(sapStockList)) {
+            totalQuantity = sapStockList.stream()
+                    .map(IotSapStockDO::getQuantity)
+                    .filter(Objects::nonNull)
+                    .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+            totalAmount = sapStockList.stream()
+                    .filter(stock -> ObjUtil.isNotEmpty(stock.getQuantity()) && ObjUtil.isNotEmpty(stock.getUnitPrice()))
+                    .map(stock -> stock.getQuantity().multiply(stock.getUnitPrice()))
+                    .reduce(BigDecimal.ZERO, BigDecimal::add);
+        } else {
+            totalQuantity = BigDecimal.ZERO;
+            totalAmount = BigDecimal.ZERO;
+        }
+        PageResult<IotSapStockRespVO> respPage = BeanUtils.toBean(pageResult, IotSapStockRespVO.class);
+        if (CollUtil.isNotEmpty(respPage.getList())) {
+            respPage.getList().forEach(record -> {
+                record.setTotalAmount(totalAmount);
+                record.setTotalQuantity(totalQuantity);
+            });
+        }
+        return success(respPage);
     }
 
     @GetMapping("/export-excel")

+ 9 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotsapstock/vo/IotSapStockRespVO.java

@@ -117,4 +117,13 @@ public class IotSapStockRespVO {
     @ExcelProperty("创建时间")
     private LocalDateTime createTime;
 
+    /**
+     * 扩展字段
+     */
+    @Schema(description = "库存总数量", example = "243.65")
+    private BigDecimal totalQuantity;
+
+    @Schema(description = "库存总金额", example = "243.65")
+    private BigDecimal totalAmount;
+
 }

+ 1 - 1
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/iotlockstock/IotLockStockMapper.java

@@ -44,7 +44,7 @@ public interface IotLockStockMapper extends BaseMapperX<IotLockStockDO> {
                 .eqIfPresent(IotLockStockDO::getAuditStatus, reqVO.getAuditStatus())
                 .eqIfPresent(IotLockStockDO::getRemark, reqVO.getRemark())
                 .betweenIfPresent(IotLockStockDO::getCreateTime, reqVO.getCreateTime())
-                .orderByDesc(IotLockStockDO::getId));
+                .orderByAsc(IotLockStockDO::getFactoryId).orderByAsc(IotLockStockDO::getCostCenterId));
     }
 
     default List<IotLockStockDO> selectList(IotLockStockPageReqVO reqVO) {

+ 28 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/iotsappickinglist/IotSapPickingListMapper.java

@@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.pms.controller.admin.iotsappickinglist.vo.IotSapP
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotsappickinglist.IotSapPickingListDO;
 import org.apache.ibatis.annotations.Mapper;
 
+import java.util.List;
+
 /**
  * PMS SAP 领料单 Mapper
  *
@@ -42,4 +44,30 @@ public interface IotSapPickingListMapper extends BaseMapperX<IotSapPickingListDO
                 .orderByDesc(IotSapPickingListDO::getId));
     }
 
+    default List<IotSapPickingListDO> selectList(IotSapPickingListPageReqVO reqVO) {
+        return selectList(new LambdaQueryWrapperX<IotSapPickingListDO>()
+                .eqIfPresent(IotSapPickingListDO::getDeptId, reqVO.getDeptId())
+                .eqIfPresent(IotSapPickingListDO::getFactoryId, reqVO.getFactoryId())
+                .eqIfPresent(IotSapPickingListDO::getFactory, reqVO.getFactory())
+                .eqIfPresent(IotSapPickingListDO::getCostCenterId, reqVO.getCostCenterId())
+                .eqIfPresent(IotSapPickingListDO::getCostCenter, reqVO.getCostCenter())
+                .eqIfPresent(IotSapPickingListDO::getStorageLocationId, reqVO.getStorageLocationId())
+                .eqIfPresent(IotSapPickingListDO::getStorageLocation, reqVO.getStorageLocation())
+                .eqIfPresent(IotSapPickingListDO::getNumber, reqVO.getNumber())
+                .eqIfPresent(IotSapPickingListDO::getMaterialCode, reqVO.getMaterialCode())
+                .likeIfPresent(IotSapPickingListDO::getMaterialName, reqVO.getMaterialName())
+                .likeIfPresent(IotSapPickingListDO::getMaterialGroupName, reqVO.getMaterialGroupName())
+                .eqIfPresent(IotSapPickingListDO::getMaterialGroupId, reqVO.getMaterialGroupId())
+                .eqIfPresent(IotSapPickingListDO::getQuantity, reqVO.getQuantity())
+                .eqIfPresent(IotSapPickingListDO::getUnitPrice, reqVO.getUnitPrice())
+                .eqIfPresent(IotSapPickingListDO::getUnit, reqVO.getUnit())
+                .eqIfPresent(IotSapPickingListDO::getSyncStatus, reqVO.getSyncStatus())
+                .betweenIfPresent(IotSapPickingListDO::getSyncTime, reqVO.getSyncTime())
+                .eqIfPresent(IotSapPickingListDO::getSyncError, reqVO.getSyncError())
+                .eqIfPresent(IotSapPickingListDO::getSort, reqVO.getSort())
+                .eqIfPresent(IotSapPickingListDO::getStatus, reqVO.getStatus())
+                .eqIfPresent(IotSapPickingListDO::getRemark, reqVO.getRemark())
+                .betweenIfPresent(IotSapPickingListDO::getCreateTime, reqVO.getCreateTime()));
+    }
+
 }

+ 36 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/dal/mysql/iotsapstock/IotSapStockMapper.java

@@ -52,6 +52,42 @@ public interface IotSapStockMapper extends BaseMapperX<IotSapStockDO> {
         }
         return selectJoinPage(reqVO, IotSapStockDO.class, query);
     }
+
+    default List<IotSapStockDO> selectList(IotSapStockPageReqVO reqVO) {
+        MPJLambdaWrapperX<IotSapStockDO> query = new MPJLambdaWrapperX<IotSapStockDO>();
+        query.eqIfPresent(IotSapStockDO::getDeptId, reqVO.getDeptId())
+                .eqIfPresent(IotSapStockDO::getFactoryId, reqVO.getFactoryId())
+                .eqIfPresent(IotSapStockDO::getFactory, reqVO.getFactory())
+                .eqIfPresent(IotSapStockDO::getStorageLocationId, reqVO.getStorageLocationId())
+                .eqIfPresent(IotSapStockDO::getProjectDepartment, reqVO.getProjectDepartment())
+                .likeIfPresent(IotSapStockDO::getMaterialCode, reqVO.getMaterialCode())
+                .likeIfPresent(IotSapStockDO::getMaterialName, reqVO.getMaterialName())
+                .likeIfPresent(IotSapStockDO::getMaterialGroupName, reqVO.getMaterialGroupName())
+                .eqIfPresent(IotSapStockDO::getMaterialGroupId, reqVO.getMaterialGroupId())
+                .eqIfPresent(IotSapStockDO::getQuantity, reqVO.getQuantity())
+                .eqIfPresent(IotSapStockDO::getUnitPrice, reqVO.getUnitPrice())
+                .eqIfPresent(IotSapStockDO::getUnit, reqVO.getUnit())
+                .eqIfPresent(IotSapStockDO::getSafetyStock, reqVO.getSafetyStock())
+                .eqIfPresent(IotSapStockDO::getStorageAreaId, reqVO.getStorageAreaId())
+                .eqIfPresent(IotSapStockDO::getShelvesId, reqVO.getShelvesId())
+                .eqIfPresent(IotSapStockDO::getCargoLocationId, reqVO.getCargoLocationId())
+                .eqIfPresent(IotSapStockDO::getType, reqVO.getType())
+                .eqIfPresent(IotSapStockDO::getSyncStatus, reqVO.getSyncStatus())
+                .betweenIfPresent(IotSapStockDO::getSyncTime, reqVO.getSyncTime())
+                .eqIfPresent(IotSapStockDO::getSyncError, reqVO.getSyncError())
+                .eqIfPresent(IotSapStockDO::getSort, reqVO.getSort())
+                .eqIfPresent(IotSapStockDO::getStatus, reqVO.getStatus())
+                .eqIfPresent(IotSapStockDO::getRemark, reqVO.getRemark())
+                .betweenIfPresent(IotSapStockDO::getCreateTime, reqVO.getCreateTime())
+                .orderByAsc(IotSapStockDO::getFactoryId).orderByAsc(IotSapStockDO::getStorageLocationId);
+        if ("Y".equals(reqVO.getConfigFlag())) {
+            query.gt(IotSapStockDO::getSafetyStock, 0);
+        } else if ("N".equals(reqVO.getConfigFlag())) {
+            query.eq(IotSapStockDO::getSafetyStock, 0);
+        }
+        return selectJoinList(IotSapStockDO.class, query);
+    }
+
     default List<IotSapStockDO> getSafeList() {
         return selectList(new LambdaUpdateWrapper<IotSapStockDO>()
                 .gt(IotSapStockDO::getSafetyStock, 0));

+ 6 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/job/sap/SyncSapPickingListJob.java

@@ -24,11 +24,15 @@ import org.springframework.stereotype.Component;
 import javax.annotation.Resource;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 import java.util.concurrent.CountDownLatch;
 import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.module.pms.framework.config.MultiThreadConfiguration.PMS_THREAD_POOL_TASK_EXECUTOR;
 
+/**
+ * 同步 SAP 领料单 定时任务
+ */
 @Component
 @Slf4j
 public class SyncSapPickingListJob implements JobHandler {
@@ -156,7 +160,9 @@ public class SyncSapPickingListJob implements JobHandler {
             return CollectionUtil.newArrayList();
         }
         List<String> factoryCodes = sapOrgs.stream()
+                .filter(org -> ObjUtil.isNotEmpty(org.getStatus()) && org.getStatus() == 0)
                 .map(SapOrgRespDTO::getFactoryCode)
+                .filter(Objects::nonNull)
                 .collect(Collectors.toList());
         return CollUtil.isEmpty(factoryCodes) ? CollUtil.empty(String.class) : factoryCodes;
     }

+ 108 - 38
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/sap/service/IotSapServiceImpl.java

@@ -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)) {

+ 8 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotsapstock/IotSapStockService.java

@@ -53,6 +53,14 @@ public interface IotSapStockService {
      */
     PageResult<IotSapStockDO> getIotSapStockPage(IotSapStockPageReqVO pageReqVO);
 
+    /**
+     * 获得PMS SAP 库存(通用库存/项目部库存)分页
+     *
+     * @param pageReqVO 分页查询
+     * @return PMS SAP 库存(通用库存/项目部库存)分页
+     */
+    List<IotSapStockDO> getIotSapStockList(IotSapStockPageReqVO pageReqVO);
+
     /**
      * 批量设置安全库存
      *

+ 5 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotsapstock/IotSapStockServiceImpl.java

@@ -70,6 +70,11 @@ public class IotSapStockServiceImpl implements IotSapStockService {
         return iotSapStockMapper.selectPage(pageReqVO);
     }
 
+    @Override
+    public List<IotSapStockDO> getIotSapStockList(IotSapStockPageReqVO pageReqVO) {
+        return iotSapStockMapper.selectList(pageReqVO);
+    }
+
     @Override
     public Long batchSetSafetyStock(List<IotSapStockSaveReqVO> sapStocks) {
         List<IotSapStockDO> sapStockDOs = new ArrayList<>();

+ 1 - 1
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/saporg/dto/SapOrgRespDTO.java

@@ -63,7 +63,7 @@ public class SapOrgRespDTO {
     private Integer sort;
 
     /**
-     * 部门编号
+     * 状态(0正常同步sap领料单   1停用同步sap领料单)
      */
     private Integer status;