Bläddra i källkod

pms 保养 带出所有保养项的物料

zhangcl 2 veckor sedan
förälder
incheckning
9123b22b8d

+ 6 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotdevicematerial/vo/IotDeviceMaterialRespVO.java

@@ -81,4 +81,10 @@ public class IotDeviceMaterialRespVO {
     @Schema(description = "成本中心名称", example = "新疆科瑞-制氮-华北-HY-E1")
     private String costCenter;
 
+    @Schema(description = "库存地点id", example = "27947")
+    private Long storageLocationId;
+
+    @Schema(description = "库存地点名称", example = "华中项目部库")
+    private String storageLocation;
+
 }

+ 5 - 154
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotmainworkorderbom/IotMainWorkOrderBomController.java

@@ -10,35 +10,21 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
-import cn.iocoder.yudao.module.pms.controller.admin.iotdevicematerial.vo.IotDeviceMaterialPageReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotdevicematerial.vo.IotDeviceMaterialRespVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotdevicerunlog.vo.IotDeviceRunLogRespVO;
-import cn.iocoder.yudao.module.pms.controller.admin.iotlockstock.vo.IotLockStockPageReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotmainworkorderbom.vo.IotMainWorkOrderBomPageReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotmainworkorderbom.vo.IotMainWorkOrderBomRespVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotmainworkorderbom.vo.IotMainWorkOrderBomSaveReqVO;
-import cn.iocoder.yudao.module.pms.controller.admin.iotmaterial.vo.IotMaterialPageReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.vo.IotDeviceRespVO;
-import cn.iocoder.yudao.module.pms.dal.dataobject.iotdevicematerial.IotDeviceMaterialDO;
-import cn.iocoder.yudao.module.pms.dal.dataobject.iotlockstock.IotLockStockDO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotmainworkorderbom.IotMainWorkOrderBomDO;
-import cn.iocoder.yudao.module.pms.dal.dataobject.iotmaterial.IotMaterialDO;
 import cn.iocoder.yudao.module.pms.service.IotDeviceService;
 import cn.iocoder.yudao.module.pms.service.iotdevicematerial.IotDeviceMaterialService;
 import cn.iocoder.yudao.module.pms.service.iotdevicerunlog.IotDeviceRunLogService;
-import cn.iocoder.yudao.module.pms.service.iotlockstock.IotLockStockService;
 import cn.iocoder.yudao.module.pms.service.iotmainworkorder.IotMainWorkOrderService;
 import cn.iocoder.yudao.module.pms.service.iotmainworkorderbom.IotMainWorkOrderBomService;
-import cn.iocoder.yudao.module.pms.service.iotmaterial.IotMaterialService;
-import cn.iocoder.yudao.module.system.api.dept.DeptSapOrgApi;
-import cn.iocoder.yudao.module.system.api.dept.dto.DeptSapOrgRespDTO;
-import cn.iocoder.yudao.module.system.api.saporg.SapOrgApi;
-import cn.iocoder.yudao.module.system.api.saporg.dto.SapOrgRespDTO;
-import cn.iocoder.yudao.module.system.service.dept.DeptService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.tags.Tag;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
@@ -72,16 +58,6 @@ public class IotMainWorkOrderBomController {
     private IotMainWorkOrderService iotMainWorkOrderService;
     @Resource
     private IotDeviceMaterialService iotDeviceMaterialService;
-    @Resource
-    private IotMaterialService iotMaterialService;
-    @Autowired
-    private DeptService deptService;
-    @Autowired
-    private DeptSapOrgApi deptSapOrgApi;
-    @Autowired
-    private IotLockStockService iotLockStockService;
-    @Autowired
-    private SapOrgApi sapOrgApi;
 
     @PostMapping("/create")
     @Operation(summary = "创建PMS 保养计划明细BOM")
@@ -164,6 +140,8 @@ public class IotMainWorkOrderBomController {
         Map<Long, Long> deviceCategoryPair = new HashMap<>();
         // 保养j明细 保养项BOM节点id集合
         Set<Long> bomNodeIds = new HashSet<>();
+        // 设备所属部门id集合
+        Set<Long> deptIds = new HashSet<>();
         BOMs.forEach(bom -> {
             if (ObjUtil.isNotEmpty(bom.getDeviceId())) {
                 deviceIds.add(bom.getDeviceId());
@@ -182,6 +160,7 @@ public class IotMainWorkOrderBomController {
                 deviceMap.forEach((k,v) -> {
                     deviceCategoryIds.add(v.getAssetClass());
                     deviceCategoryPair.put(k, v.getAssetClass());
+                    deptIds.add(v.getDeptId());
                 });
             }
         });
@@ -213,137 +192,9 @@ public class IotMainWorkOrderBomController {
                 });
             }
         }
+        // key设备id-bom节点id      value设备物料集合
+        Map<String, List<IotDeviceMaterialRespVO>> deviceBomMaterialPair = iotDeviceMaterialService.bomMaterials(deptIds, deviceIds, bomNodeIds);
 
-        // 查询每个保养项上关联的物料列表
-        IotDeviceMaterialPageReqVO reqVO = new IotDeviceMaterialPageReqVO();
-        reqVO.setDeviceIds(new ArrayList<>(deviceIds));
-        reqVO.setBomNodeIds(new ArrayList<>(bomNodeIds));
-        List<IotDeviceMaterialDO> deviceBomMaterials = iotDeviceMaterialService.deviceBomMaterials(reqVO);
-        // 将 deviceBomMaterials 集合中的对象类型转换成 IotDeviceMaterialRespVO
-        // key设备id-bomid    value保养项关联的物料列表
-        Map<String, List<IotDeviceMaterialRespVO>> deviceBomMaterialPair = new HashMap<>();
-        Set<String> materialCodes = new HashSet<>();
-        if (CollUtil.isNotEmpty(deviceBomMaterials)) {
-            deviceBomMaterials.forEach(material -> {
-                // 设置物料编码组合
-                materialCodes.add(material.getCode());
-            });
-
-            // 查询每个保养项上 关联的物料数量 关联查询并直接绑定 设备所属部门的SAP组织成本中心的库存物料 与 保养项关联的物料 匹配
-            Set<Long> deptIds = new HashSet<>();
-            Set<Long> allDeptIds = new HashSet<>();
-            List<IotLockStockDO> lockStocks = new ArrayList<>();
-            Map<String, IotLockStockDO> lockStockPair = new HashMap<>();
-            Map<Long, String> factoryPair = new HashMap<>();
-            Map<Long, String> costCenterPair = new HashMap<>();
-            if (CollUtil.isNotEmpty(deviceMap)) {
-                deviceMap.forEach((k,v) -> {
-                    // k设备id   v设备对象
-                    deptIds.add(v.getDeptId());
-                });
-                // 查询每个部门下的所有子部门 将所有 部门id设置到 相同集合
-                if (CollUtil.isNotEmpty(deptIds)) {
-                    deptIds.forEach(deptId -> {
-                        Set<Long> tempDeptIds = new HashSet<>();
-                        tempDeptIds = deptService.getChildDeptIdListFromCache(deptId);
-                        tempDeptIds.add(deptId);
-                        allDeptIds.addAll(tempDeptIds);
-                    });
-                }
-                // 查询所有部门关联的SAP工厂 成本中心 列表
-                List<DeptSapOrgRespDTO> sapOrgS = deptSapOrgApi.getSapOrgListByDeptIds(allDeptIds);
-                Set<Long> factoryIds = new HashSet<>();
-                Set<Long> costCenterIds = new HashSet<>();
-                Set<Long> sapOrgIds = new HashSet<>();
-                if (CollUtil.isNotEmpty(sapOrgS)) {
-                    sapOrgS.forEach(org -> {
-                        if (ObjUtil.isNotEmpty(org.getFactoryId())) {
-                            factoryIds.add(org.getFactoryId());
-                        }
-                        if (ObjUtil.isNotEmpty(org.getCostCenterId())) {
-                            costCenterIds.add(org.getCostCenterId());
-                        }
-                    });
-                    if (CollUtil.isNotEmpty(factoryIds)) {
-                        sapOrgIds.addAll(factoryIds);
-                    }
-                    if (CollUtil.isNotEmpty(costCenterIds)) {
-                        sapOrgIds.addAll(costCenterIds);
-                    }
-                }
-                // 查询所有sap 工厂 成本中心下的指定物料的库存信息
-                if (CollUtil.isNotEmpty(factoryIds) && CollUtil.isNotEmpty(costCenterIds) && CollUtil.isNotEmpty(materialCodes)) {
-                    IotLockStockPageReqVO stockReqVO = new IotLockStockPageReqVO();
-                    stockReqVO.setFactoryIds(factoryIds);
-                    stockReqVO.setCostCenterIds(costCenterIds);
-                    stockReqVO.setMaterialCodes(materialCodes);
-                    lockStocks = iotLockStockService.getIotLockStocks(stockReqVO);
-                    // 查询各工厂 成本中心的名称
-                    List<SapOrgRespDTO> sapOrganizations = sapOrgApi.getSapOrgList(sapOrgIds);
-                    if (CollUtil.isNotEmpty(sapOrganizations)) {
-                        sapOrganizations.forEach(org -> {
-                            // 工厂 名称集合
-                            if (ObjUtil.isNotEmpty(org.getType()) && 1==org.getType()) {
-                                factoryPair.put(org.getId(), org.getFactoryName());
-                            }
-                            // 成本中心名称集合
-                            if (ObjUtil.isNotEmpty(org.getType()) && 2==org.getType()) {
-                                costCenterPair.put(org.getId(), org.getCostCenterName());
-                            }
-                        });
-                    }
-                    if (CollUtil.isNotEmpty(lockStocks)) {
-                        lockStocks.forEach(stock -> {
-                            lockStockPair.put(stock.getMaterialCode(), stock);
-                        });
-                    }
-                }
-            }
-
-            // 查询集合中所有物料的单位
-            IotMaterialPageReqVO materialReqVO = new IotMaterialPageReqVO();
-            materialReqVO.setCodes(new ArrayList<>(materialCodes));
-            List<IotMaterialDO> materials = iotMaterialService.getIotMaterials(materialReqVO);
-            Map<String, String> materialUnitPair = new HashMap<>();
-            if (CollUtil.isNotEmpty(materials)) {
-                materials.forEach(material -> {
-                    materialUnitPair.put(material.getCode(), material.getUnit());
-                });
-            }
-            // 设置保养项关联的物料列表
-            List<IotDeviceMaterialRespVO> deviceMaterials = BeanUtils.toBean(deviceBomMaterials, IotDeviceMaterialRespVO.class);
-            // 设置保养项关联的物料的本地库存
-            deviceMaterials.forEach(material -> {
-                if (lockStockPair.containsKey(material.getCode())) {
-                    IotLockStockDO tempLockStock = lockStockPair.get(material.getCode());
-                    material.setStockQuantity(tempLockStock.getQuantity());
-                    material.setUnitPrice(tempLockStock.getUnitPrice());
-                    material.setFactoryId(tempLockStock.getFactoryId());
-                    material.setCostCenterId(tempLockStock.getCostCenterId());
-                    if (factoryPair.containsKey(tempLockStock.getFactoryId())) {
-                        material.setFactory(factoryPair.get(tempLockStock.getFactoryId()));
-                    }
-                    if (costCenterPair.containsKey(tempLockStock.getCostCenterId())) {
-                        material.setCostCenter(costCenterPair.get(tempLockStock.getCostCenterId()));
-                    }
-                }
-            });
-            deviceMaterials.forEach(bomMaterial -> {
-                if (materialUnitPair.containsKey(bomMaterial.getCode())) {
-                    bomMaterial.setUnit(materialUnitPair.get(bomMaterial.getCode()));
-                }
-                String uniqueKey = StrUtil.join("-", bomMaterial.getDeviceId(), bomMaterial.getBomNodeId());
-                if (deviceBomMaterialPair.containsKey(uniqueKey)) {
-                    List<IotDeviceMaterialRespVO> tempBomMaterials = deviceBomMaterialPair.get(uniqueKey);
-                    tempBomMaterials.add(bomMaterial);
-                    deviceBomMaterialPair.put(uniqueKey, tempBomMaterials);
-                } else {
-                    List<IotDeviceMaterialRespVO> tempBomMaterials = new ArrayList<>();
-                    tempBomMaterials.add(bomMaterial);
-                    deviceBomMaterialPair.put(uniqueKey, tempBomMaterials);
-                }
-            });
-        }
         return BeanUtils.toBean(BOMs, IotMainWorkOrderBomRespVO.class, bomVO -> {
             // 设置设备相关信息
             MapUtils.findAndThen(deviceMap, bomVO.getDeviceId(),

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

@@ -9,6 +9,7 @@ import org.springframework.format.annotation.DateTimeFormat;
 
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
+import java.util.Set;
 
 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
 
@@ -103,4 +104,14 @@ public class IotSapStockPageReqVO extends PageParam {
      */
     @Schema(description = "是否设置了安全库存 Y已设置 N未设置")
     private String configFlag;
+
+    @Schema(description = "工厂id集合")
+    private Set<Long> factoryIds;
+
+    @Schema(description = "库存地点id集合")
+    private Set<Long> storageLocationIds;
+
+    @Schema(description = "物料编码集合")
+    private Set<String> materialCodes;
+
 }

+ 4 - 0
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/vo/IotDeviceRespVO.java

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.module.pms.controller.admin.vo;
 
+import cn.iocoder.yudao.module.pms.controller.admin.iotdevicematerial.vo.IotDeviceMaterialRespVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotdevicerunlog.vo.IotDeviceRunLogRespVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotmaintenancebom.vo.IotMaintenanceBomRespVO;
 import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
@@ -228,4 +229,7 @@ public class IotDeviceRespVO {
     private String vehicleName;
     private String assetOwnership;
     private String useProject;
+
+    @Schema(description = "保养/维修项关联的设备bom物料列表")
+    private List<IotDeviceMaterialRespVO> deviceBomMaterials;
 }

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

@@ -57,8 +57,10 @@ public interface IotSapStockMapper extends BaseMapperX<IotSapStockDO> {
         MPJLambdaWrapperX<IotSapStockDO> query = new MPJLambdaWrapperX<IotSapStockDO>();
         query.eqIfPresent(IotSapStockDO::getDeptId, reqVO.getDeptId())
                 .eqIfPresent(IotSapStockDO::getFactoryId, reqVO.getFactoryId())
+                .inIfPresent(IotSapStockDO::getFactoryId, reqVO.getFactoryIds())
                 .eqIfPresent(IotSapStockDO::getFactory, reqVO.getFactory())
                 .eqIfPresent(IotSapStockDO::getStorageLocationId, reqVO.getStorageLocationId())
+                .inIfPresent(IotSapStockDO::getStorageLocationId, reqVO.getStorageLocationIds())
                 .eqIfPresent(IotSapStockDO::getProjectDepartment, reqVO.getProjectDepartment())
                 .likeIfPresent(IotSapStockDO::getMaterialCode, reqVO.getMaterialCode())
                 .likeIfPresent(IotSapStockDO::getMaterialName, reqVO.getMaterialName())

+ 15 - 1
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/IotDeviceServiceImpl.java

@@ -13,6 +13,7 @@ import cn.iocoder.yudao.framework.datapermission.core.util.DataPermissionUtils;
 import cn.iocoder.yudao.module.pms.ThingsModelDTO;
 import cn.iocoder.yudao.module.pms.controller.admin.TableDataInfo;
 import cn.iocoder.yudao.module.pms.controller.admin.iotdevicecategorytemplateattrs.vo.IotDeviceProperty;
+import cn.iocoder.yudao.module.pms.controller.admin.iotdevicematerial.vo.IotDeviceMaterialRespVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotdeviceperson.vo.IotDevicePersonPageReqVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotdevicerunlog.vo.IotDeviceRunLogRespVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotmodeltemplateattrs.vo.IotModelTemplateAttrsPageReqVO;
@@ -36,6 +37,7 @@ import cn.iocoder.yudao.module.pms.dal.mysql.iotmodel.IotModelMapper;
 import cn.iocoder.yudao.module.pms.dal.mysql.iotopeationfill.IotOpeationFillMapper;
 import cn.iocoder.yudao.module.pms.service.iotbom.IotBomService;
 import cn.iocoder.yudao.module.pms.service.iotdevicebom.IotDeviceBomService;
+import cn.iocoder.yudao.module.pms.service.iotdevicematerial.IotDeviceMaterialService;
 import cn.iocoder.yudao.module.pms.service.iotdeviceperson.IotDevicePersonService;
 import cn.iocoder.yudao.module.pms.service.iotdevicerunlog.IotDeviceRunLogService;
 import cn.iocoder.yudao.module.pms.service.iotmodeltemplateattrs.IotModelTemplateAttrsService;
@@ -52,7 +54,6 @@ import cn.iocoder.yudao.module.system.service.user.AdminUserService;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.core.toolkit.Assert;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
@@ -122,6 +123,8 @@ public class IotDeviceServiceImpl implements IotDeviceService {
     @Autowired
     private IotDevicePersonService iotDevicePersonService;
     @Autowired
+    private IotDeviceMaterialService iotDeviceMaterialService;
+    @Autowired
     private IotOpeationFillMapper zhbdmapper;
     private final static String parameter = "lng~~经度,lat~~纬度,today_distance~~当日里程,distance~~总里程,todayoil~~当日油量,totaloil~~总油量,online~~是否在线,oil1~~1路油量,oil2~~2路油量,oil3~~3路油量,oil4~~4路油量,vehicle_name~~车牌号码";
 
@@ -579,6 +582,8 @@ public class IotDeviceServiceImpl implements IotDeviceService {
         List<Long> bomNodeIds = new ArrayList<>();
         // key设备id  value设备对应的运行记录模板中涉及多个累计时长累计公里数的属性集合
         Map<Long, List<IotDeviceRunLogRespVO>> deviceRunLogPair = new HashMap<>();
+        // 设备所属部门id集合
+        Set<Long> deptIds = new HashSet<>();
         if (CollUtil.isNotEmpty(devices)) {
             // 设备运行模板中正常的 累计时长 累计里程 集合
             Map<Long, IotDeviceRunLogRespVO> deviceRunLogMap = new HashMap<>();
@@ -587,8 +592,12 @@ public class IotDeviceServiceImpl implements IotDeviceService {
                 bomNodeIds.add(Long.valueOf(device.getBomNodeId()));
                 deviceCategoryIds.add(device.getAssetClass());
                 deviceCategoryPair.put(device.getId(), device.getAssetClass());
+                deptIds.add(device.getDeptId());
             });
 
+            // key设备id-bom节点id      value设备物料集合
+            Map<String, List<IotDeviceMaterialRespVO>> bomMaterialsPair = iotDeviceMaterialService.bomMaterials(deptIds, deviceIds, new HashSet<>(bomNodeIds));
+
             if (CollUtil.isNotEmpty(deviceCategoryIds)) {
                 // 查询设备分类id集合对应的运行记录模板中涉及 累计运行时长、累计运行公里数 的属性
                 IotModelTemplateAttrsPageReqVO reqVO = new IotModelTemplateAttrsPageReqVO();
@@ -652,6 +661,11 @@ public class IotDeviceServiceImpl implements IotDeviceService {
             Map<Long, String> bomFullPaths = iotDeviceBomService.buildBomFullPaths(bomNodeIds);
             Map<Long, IotDeviceRunLogRespVO> finalDeviceRunLogMap = deviceRunLogMap;
             devices.forEach(device -> {
+                String uniqueKey = StrUtil.join("-", device.getId(), device.getBomNodeId());
+                if (bomMaterialsPair.containsKey(uniqueKey)) {
+                    device.setDeviceBomMaterials(bomMaterialsPair.get(uniqueKey));
+                }
+                // 保养项全路径名
                 if (bomFullPaths.containsKey(Long.valueOf(device.getBomNodeId()))) {
                     if (StrUtil.isNotBlank(bomFullPaths.get(Long.valueOf(device.getBomNodeId())))) {
                         device.setName(bomFullPaths.get(Long.valueOf(device.getBomNodeId())));

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

@@ -2,11 +2,14 @@ package cn.iocoder.yudao.module.pms.service.iotdevicematerial;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.pms.controller.admin.iotdevicematerial.vo.IotDeviceMaterialPageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotdevicematerial.vo.IotDeviceMaterialRespVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotdevicematerial.vo.IotDeviceMaterialSaveReqVO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotdevicematerial.IotDeviceMaterialDO;
 
 import javax.validation.Valid;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * PMS 设备BOM物料关联 Service 接口
@@ -94,4 +97,9 @@ public interface IotDeviceMaterialService {
      *
      */
     Long addMaterials(List<IotDeviceMaterialSaveReqVO> materials);
+
+    /**
+     * 查询每个 维修/保养项 已经绑定的物料列表
+     */
+    Map<String, List<IotDeviceMaterialRespVO>> bomMaterials(Set<Long> deptIds, Set<Long> deviceIds, Set<Long> bomNodeIds);
 }

+ 232 - 4
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/service/iotdevicematerial/IotDeviceMaterialServiceImpl.java

@@ -6,20 +6,34 @@ import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.pms.controller.admin.iotdevicematerial.vo.IotDeviceMaterialPageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotdevicematerial.vo.IotDeviceMaterialRespVO;
 import cn.iocoder.yudao.module.pms.controller.admin.iotdevicematerial.vo.IotDeviceMaterialSaveReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotlockstock.vo.IotLockStockPageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotmaterial.vo.IotMaterialPageReqVO;
+import cn.iocoder.yudao.module.pms.controller.admin.iotsapstock.vo.IotSapStockPageReqVO;
 import cn.iocoder.yudao.module.pms.dal.dataobject.iotdevicematerial.IotDeviceMaterialDO;
+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.iotsapstock.IotSapStockDO;
 import cn.iocoder.yudao.module.pms.dal.mysql.IotDeviceMapper;
 import cn.iocoder.yudao.module.pms.dal.mysql.iotdevicematerial.IotDeviceMaterialMapper;
+import cn.iocoder.yudao.module.pms.dal.mysql.iotlockstock.IotLockStockMapper;
+import cn.iocoder.yudao.module.pms.dal.mysql.iotmaterial.IotMaterialMapper;
+import cn.iocoder.yudao.module.pms.dal.mysql.iotsapstock.IotSapStockMapper;
 import cn.iocoder.yudao.module.pms.service.iotbom.IotBomService;
+import cn.iocoder.yudao.module.system.api.dept.DeptSapOrgApi;
+import cn.iocoder.yudao.module.system.api.dept.dto.DeptSapOrgRespDTO;
+import cn.iocoder.yudao.module.system.api.saporg.SapOrgApi;
+import cn.iocoder.yudao.module.system.api.saporg.dto.SapOrgRespDTO;
+import cn.iocoder.yudao.module.system.service.dept.DeptService;
 import com.google.common.collect.ImmutableMap;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
+import java.math.BigDecimal;
+import java.util.*;
 import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -41,6 +55,18 @@ public class IotDeviceMaterialServiceImpl implements IotDeviceMaterialService {
     private IotDeviceMapper iotDeviceMapper;
     @Resource
     private IotBomService iotBomService;
+    @Autowired
+    private DeptService deptService;
+    @Autowired
+    private DeptSapOrgApi deptSapOrgApi;
+    @Autowired
+    private SapOrgApi sapOrgApi;
+    @Autowired
+    private IotLockStockMapper iotLockStockMapper;
+    @Autowired
+    private IotSapStockMapper iotSapStockMapper;
+    @Autowired
+    private IotMaterialMapper iotMaterialMapper;
 
     @Override
     public Long createIotDeviceMaterial(IotDeviceMaterialSaveReqVO createReqVO) {
@@ -169,4 +195,206 @@ public class IotDeviceMaterialServiceImpl implements IotDeviceMaterialService {
         return resultCount;
     }
 
+    @Override
+    public Map<String, List<IotDeviceMaterialRespVO>> bomMaterials(Set<Long> deptIds, Set<Long> deviceIds, Set<Long> bomNodeIds) {
+        // key设备id-bomid    value保养项关联的物料列表
+        Map<String, List<IotDeviceMaterialRespVO>> deviceBomMaterialPair = new HashMap<>();
+        // 查询每个 维修/保养 项绑定的物料
+        IotDeviceMaterialPageReqVO reqVO = new IotDeviceMaterialPageReqVO();
+        reqVO.setDeviceIds(new ArrayList<>(deviceIds));
+        reqVO.setBomNodeIds(new ArrayList<>(bomNodeIds));
+        List<IotDeviceMaterialDO> deviceBomMaterials = iotDeviceMaterialMapper.selectList(reqVO);
+        Set<String> materialCodes = new HashSet<>();
+        if (CollUtil.isNotEmpty(deviceBomMaterials)) {
+            deviceBomMaterials.forEach(material -> {
+                // 设置物料编码组合
+                materialCodes.add(material.getCode());
+            });
+            // 查询每个保养项上 关联的物料数量 关联查询并直接绑定 设备所属部门的SAP组织成本中心的库存物料 与 保养项关联的物料 匹配
+            // 物料按照优化级绑定 本地库存 > sap库存 > sap主数据
+            /// Set<Long> deptIds = new HashSet<>();
+            Set<Long> allDeptIds = new HashSet<>();
+            List<IotLockStockDO> lockStocks = new ArrayList<>();
+            List<IotSapStockDO> sapStocks = new ArrayList<>();
+            // key物料编码  value:本地库存对象
+            Map<String, IotLockStockDO> lockStockPair = new HashMap<>();
+            // key物料编码  value:sap库存对象
+            Map<String, IotSapStockDO> sapStockPair = new HashMap<>();
+            // key物料编码  value:sap主数据对象
+            Map<String, IotMaterialDO> sapMasterDataPair = new HashMap<>();
+
+            Map<Long, String> factoryPair = new HashMap<>();
+            // key成本中心id    value成本中心名称
+            Map<Long, String> costCenterPair = new HashMap<>();
+            // key库存地点id    value库存地点名称
+            Map<Long, String> storageLocationPair = new HashMap<>();
+            if (CollUtil.isNotEmpty(deptIds)) {
+                // 查询每个部门下的所有子部门 将所有 部门id设置到 相同集合
+                if (CollUtil.isNotEmpty(deptIds)) {
+                    deptIds.forEach(deptId -> {
+                        Set<Long> tempDeptIds = new HashSet<>();
+                        tempDeptIds = deptService.getChildDeptIdListFromCache(deptId);
+                        tempDeptIds.add(deptId);
+                        allDeptIds.addAll(tempDeptIds);
+                    });
+                }
+                // 查询所有部门关联的SAP工厂 成本中心 库存地点 列表
+                List<DeptSapOrgRespDTO> sapOrgS = deptSapOrgApi.getSapOrgListByDeptIds(allDeptIds);
+                Set<Long> factoryIds = new HashSet<>();         // 工厂 id 集合
+                Set<Long> costCenterIds = new HashSet<>();      // 成本中心id集合
+                Set<Long> storageLocationIds = new HashSet<>(); // 库存地点id集合
+                Set<Long> sapOrgIds = new HashSet<>();          // 查询本地库存 工厂id-成本中心id
+                Set<Long> factoryStorageIds = new HashSet<>();          // 查询sap库存 工厂id-库存地点id
+                if (CollUtil.isNotEmpty(sapOrgS)) {
+                    sapOrgS.forEach(org -> {
+                        if (ObjUtil.isNotEmpty(org.getFactoryId())) {
+                            factoryIds.add(org.getFactoryId());
+                        }
+                        if (ObjUtil.isNotEmpty(org.getCostCenterId())) {
+                            costCenterIds.add(org.getCostCenterId());
+                        }
+                        if (ObjUtil.isNotEmpty(org.getStockLocationId())) {
+                            storageLocationIds.add(org.getStockLocationId());
+                        }
+                    });
+                    if (CollUtil.isNotEmpty(factoryIds)) {
+                        sapOrgIds.addAll(factoryIds);
+                        factoryStorageIds.addAll(factoryIds);
+                    }
+                    if (CollUtil.isNotEmpty(costCenterIds)) {
+                        sapOrgIds.addAll(costCenterIds);
+                    }
+                    if (CollUtil.isNotEmpty(storageLocationIds)) {
+                        factoryStorageIds.addAll(storageLocationIds);
+                    }
+                }
+                // 查询所有sap 工厂 成本中心下的指定物料的库存信息
+                if (CollUtil.isNotEmpty(factoryIds) && CollUtil.isNotEmpty(costCenterIds) && CollUtil.isNotEmpty(materialCodes)) {
+                    IotLockStockPageReqVO stockReqVO = new IotLockStockPageReqVO();
+                    stockReqVO.setFactoryIds(factoryIds);
+                    stockReqVO.setCostCenterIds(costCenterIds);
+                    stockReqVO.setMaterialCodes(materialCodes);
+                    lockStocks = iotLockStockMapper.selectList(stockReqVO);
+                    // 查询各工厂 成本中心的名称
+                    List<SapOrgRespDTO> sapOrganizations = sapOrgApi.getSapOrgList(sapOrgIds);
+                    if (CollUtil.isNotEmpty(sapOrganizations)) {
+                        sapOrganizations.forEach(org -> {
+                            // 工厂 名称集合
+                            if (ObjUtil.isNotEmpty(org.getType()) && 1==org.getType()) {
+                                factoryPair.put(org.getId(), org.getFactoryName());
+                            }
+                            // 成本中心名称集合
+                            if (ObjUtil.isNotEmpty(org.getType()) && 2==org.getType()) {
+                                costCenterPair.put(org.getId(), org.getCostCenterName());
+                            }
+                        });
+                    }
+                    if (CollUtil.isNotEmpty(lockStocks)) {
+                        lockStocks.forEach(stock -> {
+                            lockStockPair.put(stock.getMaterialCode(), stock);
+                        });
+                    }
+                }
+                // 查询SAP库存
+                if (CollUtil.isNotEmpty(factoryIds) && CollUtil.isNotEmpty(storageLocationIds) && CollUtil.isNotEmpty(materialCodes)) {
+                    IotSapStockPageReqVO sapStockReqVO = new IotSapStockPageReqVO();
+                    sapStockReqVO.setFactoryIds(factoryIds);
+                    sapStockReqVO.setStorageLocationIds(storageLocationIds);
+                    sapStockReqVO.setMaterialCodes(materialCodes);
+                    sapStocks = iotSapStockMapper.selectList(sapStockReqVO);
+                    // 查询各工厂 库存地点的名称
+                    List<SapOrgRespDTO> sapOrganizations = sapOrgApi.getSapOrgList(factoryStorageIds);
+                    if (CollUtil.isNotEmpty(sapOrganizations)) {
+                        sapOrganizations.forEach(org -> {
+                            // 工厂 名称集合
+                            if (ObjUtil.isNotEmpty(org.getType()) && 1==org.getType()) {
+                                factoryPair.put(org.getId(), org.getFactoryName());
+                            }
+                            // 库存地点名称集合
+                            if (ObjUtil.isNotEmpty(org.getType()) && 3==org.getType()) {
+                                storageLocationPair.put(org.getId(), org.getStorageLocationName());
+                            }
+                        });
+                    }
+                    if (CollUtil.isNotEmpty(sapStocks)) {
+                        sapStocks.forEach(stock -> {
+                            sapStockPair.put(stock.getMaterialCode(), stock);
+                        });
+                    }
+                }
+                // 查询SAP主数据
+                if (CollUtil.isNotEmpty(materialCodes)) {
+                    IotMaterialPageReqVO materialReqVO = new IotMaterialPageReqVO();
+                    materialReqVO.setCodes(new ArrayList<>(materialCodes));
+                    List<IotMaterialDO> materials = iotMaterialMapper.selectList(materialReqVO, null);
+                    if (CollUtil.isNotEmpty(materials)) {
+                        materials.forEach(material -> {
+                            sapMasterDataPair.put(material.getCode(), material);
+                        });
+                    }
+                }
+
+                // 设置保养项关联的物料列表
+                List<IotDeviceMaterialRespVO> deviceMaterials = BeanUtils.toBean(deviceBomMaterials, IotDeviceMaterialRespVO.class);
+                // 绑定保养项关联的物料 优先级 本地库存 > sap库存 > sap主数据
+                deviceMaterials.forEach(material -> {
+                    if (lockStockPair.containsKey(material.getCode())) {
+                        // 本地库存物料
+                        IotLockStockDO tempLockStock = lockStockPair.get(material.getCode());
+                        material.setStockQuantity(tempLockStock.getQuantity());
+                        material.setUnit(tempLockStock.getUnit());
+                        material.setUnitPrice(tempLockStock.getUnitPrice());
+                        material.setFactoryId(tempLockStock.getFactoryId());
+                        material.setCostCenterId(tempLockStock.getCostCenterId());
+                        if (factoryPair.containsKey(tempLockStock.getFactoryId())) {
+                            material.setFactory(factoryPair.get(tempLockStock.getFactoryId()));
+                        }
+                        if (costCenterPair.containsKey(tempLockStock.getCostCenterId())) {
+                            material.setCostCenter(costCenterPair.get(tempLockStock.getCostCenterId()));
+                        }
+                    } else if (sapStockPair.containsKey(material.getCode())) {
+                        // sap库存物料
+                        IotSapStockDO tempSapStock = sapStockPair.get(material.getCode());
+                        material.setStockQuantity(tempSapStock.getQuantity());
+                        material.setUnit(tempSapStock.getUnit());
+                        material.setUnitPrice(tempSapStock.getUnitPrice());
+                        material.setFactoryId(tempSapStock.getFactoryId());
+                        material.setStorageLocationId(tempSapStock.getStorageLocationId());
+                        if (factoryPair.containsKey(tempSapStock.getFactoryId())) {
+                            material.setFactory(factoryPair.get(tempSapStock.getFactoryId()));
+                        }
+                        if (storageLocationPair.containsKey(tempSapStock.getStorageLocationId())) {
+                            material.setStorageLocation(storageLocationPair.get(tempSapStock.getStorageLocationId()));
+                        }
+                    } else if (sapMasterDataPair.containsKey(material.getCode())) {
+                        // sap主数据
+                        IotMaterialDO tempMaterial = sapMasterDataPair.get(material.getCode());
+                        material.setStockQuantity(BigDecimal.ZERO);
+                        material.setUnit(tempMaterial.getUnit());
+                        material.setUnitPrice(BigDecimal.ZERO);
+                        material.setFactoryId(null);
+                        material.setStorageLocationId(null);
+                        material.setCostCenterId(null);
+                        material.setFactory(StrUtil.EMPTY);
+                        material.setStorageLocation(StrUtil.EMPTY);
+                        material.setCostCenter(StrUtil.EMPTY);
+                    }
+                });
+                deviceMaterials.forEach(bomMaterial -> {
+                    String uniqueKey = StrUtil.join("-", bomMaterial.getDeviceId(), bomMaterial.getBomNodeId());
+                    if (deviceBomMaterialPair.containsKey(uniqueKey)) {
+                        List<IotDeviceMaterialRespVO> tempBomMaterials = deviceBomMaterialPair.get(uniqueKey);
+                        tempBomMaterials.add(bomMaterial);
+                        deviceBomMaterialPair.put(uniqueKey, tempBomMaterials);
+                    } else {
+                        List<IotDeviceMaterialRespVO> tempBomMaterials = new ArrayList<>();
+                        tempBomMaterials.add(bomMaterial);
+                        deviceBomMaterialPair.put(uniqueKey, tempBomMaterials);
+                    }
+                });
+            }
+        }
+        return deviceBomMaterialPair;
+    }
+
 }