| | |
| | | import com.ruoyi.production.pojo.ProductMaterialSku; |
| | | import com.ruoyi.production.dto.ProductMaterialSkuImportDto; |
| | | import com.ruoyi.production.service.ProductMaterialSkuService; |
| | | import com.ruoyi.production.mapper.ProductOrderMapper; |
| | | import com.ruoyi.production.mapper.ProductStructureMapper; |
| | | import com.ruoyi.production.mapper.ProductionOrderRouteItemMapper; |
| | | import com.ruoyi.production.mapper.ProductionOrderRouteMapper; |
| | | import com.ruoyi.production.mapper.ProductionOrderStructureMapper; |
| | | import com.ruoyi.production.mapper.ProductionProductInputMapper; |
| | | import com.ruoyi.production.mapper.ProductionProductOutputMapper; |
| | | import com.ruoyi.production.pojo.ProductOrder; |
| | | import com.ruoyi.production.pojo.ProductStructure; |
| | | import com.ruoyi.production.pojo.ProductionOrderRoute; |
| | | import com.ruoyi.production.pojo.ProductionOrderRouteItem; |
| | | import com.ruoyi.production.pojo.ProductionOrderStructure; |
| | | import com.ruoyi.production.pojo.ProductionProductInput; |
| | | import com.ruoyi.production.pojo.ProductionProductOutput; |
| | | import com.ruoyi.productionPlan.mapper.ProductionPlanMapper; |
| | | import com.ruoyi.productionPlan.pojo.ProductionPlan; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.util.ArrayList; |
| | | import java.util.LinkedHashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | |
| | | |
| | | @Autowired |
| | | private ProductMaterialMapper productMaterialMapper; |
| | | |
| | | @Autowired |
| | | private ProductionPlanMapper productionPlanMapper; |
| | | |
| | | @Autowired |
| | | private ProductOrderMapper productOrderMapper; |
| | | |
| | | @Autowired |
| | | private ProductStructureMapper productStructureMapper; |
| | | |
| | | @Autowired |
| | | private ProductionOrderRouteItemMapper productionOrderRouteItemMapper; |
| | | |
| | | @Autowired |
| | | private ProductionOrderRouteMapper productionOrderRouteMapper; |
| | | |
| | | @Autowired |
| | | private ProductionOrderStructureMapper productionOrderStructureMapper; |
| | | |
| | | @Autowired |
| | | private ProductionProductOutputMapper productionProductOutputMapper; |
| | | |
| | | @Autowired |
| | | private ProductionProductInputMapper productionProductInputMapper; |
| | | |
| | | /** |
| | | * 查询物料规格列表 |
| | |
| | | if (ids == null || ids.isEmpty()) { |
| | | throw new ServiceException("请选择至少一条数据"); |
| | | } |
| | | |
| | | if (productionPlanMapper.selectCount(new LambdaQueryWrapper<ProductionPlan>().in(ProductionPlan::getProductMaterialSkuId, ids)) > 0) { |
| | | throw new ServiceException("该物料已被销售生产计划引用,无法删除"); |
| | | } |
| | | if (productOrderMapper.selectCount(new LambdaQueryWrapper<ProductOrder>().in(ProductOrder::getProductMaterialSkuId, ids)) > 0) { |
| | | throw new ServiceException("该物料已被生产订单引用,无法删除"); |
| | | } |
| | | if (productStructureMapper.selectCount(new LambdaQueryWrapper<ProductStructure>().in(ProductStructure::getProductModelId, ids)) > 0) { |
| | | throw new ServiceException("该物料已被BOM子表引用,无法删除"); |
| | | } |
| | | if (productionOrderRouteItemMapper.selectCount(new LambdaQueryWrapper<ProductionOrderRouteItem>().in(ProductionOrderRouteItem::getProductModelId, ids)) > 0) { |
| | | throw new ServiceException("该物料已被生产订单绑定的工艺路线--工序表引用,无法删除"); |
| | | } |
| | | if (productionOrderRouteMapper.selectCount(new LambdaQueryWrapper<ProductionOrderRoute>().in(ProductionOrderRoute::getProductModelId, ids)) > 0) { |
| | | throw new ServiceException("该物料已被生产订单绑定的工艺路线表引用,无法删除"); |
| | | } |
| | | if (productionOrderStructureMapper.selectCount(new LambdaQueryWrapper<ProductionOrderStructure>().in(ProductionOrderStructure::getProductModelId, ids)) > 0) { |
| | | throw new ServiceException("该物料已被生产订单绑定的BOM子表引用,无法删除"); |
| | | } |
| | | if (productionProductOutputMapper.selectCount(new LambdaQueryWrapper<ProductionProductOutput>().in(ProductionProductOutput::getProductModelId, ids)) > 0) { |
| | | throw new ServiceException("该物料已被生产报工产出明细表引用,无法删除"); |
| | | } |
| | | if (productionProductInputMapper.selectCount(new LambdaQueryWrapper<ProductionProductInput>().in(ProductionProductInput::getProductId, ids)) > 0) { |
| | | throw new ServiceException("该物料已被生产报工物料投入表引用,无法删除"); |
| | | } |
| | | |
| | | if (!this.removeByIds(ids)) { |
| | | throw new ServiceException("删除物料规格失败"); |
| | | } |
| | |
| | | |
| | | ProductMaterial material = productMaterialMapper.selectById(materialId); |
| | | if (material == null) { |
| | | throw new ServiceException("物料不存在"); |
| | | throw new ServiceException("主物料信息不存在"); |
| | | } |
| | | |
| | | ExcelUtil<ProductMaterialSkuImportDto> excelUtil = new ExcelUtil<>(ProductMaterialSkuImportDto.class); |
| | |
| | | log.error("导入物料规格Excel解析失败", e); |
| | | throw new ServiceException("Excel解析失败"); |
| | | } |
| | | |
| | | if (importList == null || importList.isEmpty()) { |
| | | throw new ServiceException("Excel没有数据"); |
| | | throw new ServiceException("Excel中未检测到有效数据"); |
| | | } |
| | | List<Integer> emptyCodeRows = new ArrayList<>(); |
| | | int currentRow = 1; |
| | | |
| | | Map<String, ProductMaterialSkuImportDto> specMap = new LinkedHashMap<>(); |
| | | for (ProductMaterialSkuImportDto dto : importList) { |
| | | if (dto == null || StringUtils.isEmpty(dto.getModel())) { |
| | | currentRow++; |
| | | if (dto == null) continue; |
| | | // 物料编码不能为空 |
| | | if (StringUtils.isEmpty(dto.getMaterialCode())) { |
| | | emptyCodeRows.add(currentRow); |
| | | continue; |
| | | } |
| | | String specification = dto.getModel().trim(); |
| | | if (specification.isEmpty()) { |
| | | continue; |
| | | // 产品规格不能为空 |
| | | if (StringUtils.isEmpty(dto.getModel())) { |
| | | throw new ServiceException("导入失败,产品规格不能为空"); |
| | | } |
| | | specMap.putIfAbsent(specification, dto); |
| | | if (StringUtils.isEmpty(dto.getSupplyType())) { |
| | | throw new ServiceException("导入失败,供应方式不能为空"); |
| | | } |
| | | |
| | | String modelKey = dto.getModel().trim(); |
| | | specMap.putIfAbsent(modelKey, dto); |
| | | } |
| | | |
| | | if (!emptyCodeRows.isEmpty()) { |
| | | throw new ServiceException("导入失败,以下行号的【物料编码】为空:" + emptyCodeRows.toString()); |
| | | } |
| | | if (specMap.isEmpty()) { |
| | | throw new ServiceException("Excel没有有效的规格数据"); |
| | | throw new ServiceException("Excel没有有效的规格型号数据"); |
| | | } |
| | | |
| | | Set<String> specifications = specMap.keySet(); |
| | | |
| | | Set<String> modelSet = specMap.keySet(); |
| | | List<ProductMaterialSku> existList = this.list(new LambdaQueryWrapper<ProductMaterialSku>() |
| | | .eq(ProductMaterialSku::getProductId, materialId) |
| | | .in(ProductMaterialSku::getModel, specifications)); |
| | | Map<String, ProductMaterialSku> existMap = existList.stream() |
| | | .collect(Collectors.toMap(ProductMaterialSku::getModel, sku -> sku, (a, b) -> a)); |
| | | .in(ProductMaterialSku::getModel, modelSet)); |
| | | |
| | | Map<String, ProductMaterialSku> existMap = existList.stream().collect(Collectors.toMap(ProductMaterialSku::getModel, sku -> sku, (a, b) -> a)); |
| | | LocalDateTime now = LocalDateTime.now(); |
| | | List<ProductMaterialSku> saveList = new ArrayList<>(); |
| | | List<ProductMaterialSku> updateList = new ArrayList<>(); |
| | | |
| | | for (Map.Entry<String, ProductMaterialSkuImportDto> entry : specMap.entrySet()) { |
| | | String specification = entry.getKey(); |
| | | String model = entry.getKey(); |
| | | ProductMaterialSkuImportDto dto = entry.getValue(); |
| | | String supplyType = StringUtils.isNotEmpty(dto.getSupplyType()) ? dto.getSupplyType().trim() : null; |
| | | |
| | | ProductMaterialSku exist = existMap.get(specification); |
| | | if (exist == null) { |
| | | ProductMaterialSku sku = new ProductMaterialSku(); |
| | | sku.setProductId(materialId); |
| | | sku.setModel(specification); |
| | | sku.setSupplyType(supplyType); |
| | | sku.setCreateTime(now); |
| | | sku.setUpdateTime(now); |
| | | saveList.add(sku); |
| | | String excelMaterialCode = dto.getMaterialCode().trim(); |
| | | String excelSupplyType = StringUtils.isNotEmpty(dto.getSupplyType()) ? dto.getSupplyType().trim() : null; |
| | | ProductMaterialSku existSku = existMap.get(model); |
| | | if (existSku == null) { |
| | | ProductMaterialSku newSku = new ProductMaterialSku(); |
| | | newSku.setProductId(materialId); |
| | | newSku.setModel(model); |
| | | newSku.setMaterialCode(excelMaterialCode); |
| | | newSku.setSupplyType(excelSupplyType); |
| | | newSku.setCreateTime(now); |
| | | newSku.setUpdateTime(now); |
| | | saveList.add(newSku); |
| | | } else { |
| | | boolean needUpdate = false; |
| | | if (supplyType != null && !supplyType.equals(exist.getSupplyType())) { |
| | | exist.setSupplyType(supplyType); |
| | | if (!Objects.equals(excelMaterialCode, existSku.getMaterialCode())) { |
| | | existSku.setMaterialCode(excelMaterialCode); |
| | | needUpdate = true; |
| | | } |
| | | if (!Objects.equals(excelSupplyType, existSku.getSupplyType())) { |
| | | existSku.setSupplyType(excelSupplyType); |
| | | needUpdate = true; |
| | | } |
| | | if (needUpdate) { |
| | | exist.setUpdateTime(now); |
| | | updateList.add(exist); |
| | | existSku.setUpdateTime(now); |
| | | updateList.add(existSku); |
| | | } |
| | | } |
| | | } |
| | | |
| | | if (saveList.isEmpty() && updateList.isEmpty()) { |
| | | throw new ServiceException("Excel与现有数据一致,无需导入"); |
| | | throw new ServiceException("Excel内容与现有数据完全一致"); |
| | | } |
| | | |
| | | if (!saveList.isEmpty()) { |
| | | this.saveBatch(saveList); |
| | | } |
| | |
| | | this.updateBatchById(updateList); |
| | | } |
| | | |
| | | log.info("物料规格导入完成 materialId={}, 新增{}条,更新{}条", materialId, saveList.size(), updateList.size()); |
| | | log.info("物料规格导入完成! materialId={}, 新增{}条,更新{}条", materialId, saveList.size(), updateList.size()); |
| | | } |
| | | } |