| | |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.basic.pojo.Product; |
| | |
| | | import com.ruoyi.production.dto.BomImportDto; |
| | | import com.ruoyi.production.dto.ProductBomDto; |
| | | import com.ruoyi.production.dto.ProductStructureDto; |
| | | import com.ruoyi.production.mapper.ProductBomMapper; |
| | | import com.ruoyi.production.pojo.ProductBom; |
| | | import com.ruoyi.production.pojo.ProductProcess; |
| | | import com.ruoyi.production.pojo.ProductStructure; |
| | | import com.ruoyi.production.mapper.*; |
| | | import com.ruoyi.production.pojo.*; |
| | | import com.ruoyi.production.service.ProductBomService; |
| | | import com.ruoyi.production.service.ProductProcessService; |
| | | import com.ruoyi.production.service.ProductStructureService; |
| | | import org.jetbrains.annotations.NotNull; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | |
| | | @Autowired |
| | | private ProductProcessService productProcessService; |
| | | |
| | | @Autowired |
| | | private ProductStructureMapper productStructureMapper; |
| | | |
| | | @Autowired |
| | | private ProductOrderMapper productOrderMapper; |
| | | |
| | | @Autowired |
| | | private ProductProcessRouteMapper productProcessRouteMapper; |
| | | |
| | | @Autowired |
| | | private ProcessRouteMapper processRouteMapper; |
| | | |
| | | @Override |
| | | public IPage<ProductBomDto> listPage(Page page, ProductBomDto productBomDto) { |
| | | return productBomMapper.listPage(page, productBomDto); |
| | |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public AjaxResult update(ProductBom productBom) { |
| | | // 查询出产品模型信息 |
| | | if (productBom.getProductModelId() == null) { |
| | | throw new ServiceException("请选择产品模型"); |
| | | } |
| | | |
| | | ProductBom oldBom = productBomMapper.selectById(productBom.getId()); |
| | | // 如果规格改变,关联的生产订单如果订单完成数量>0,则不许改bom;否则删除之前关联的产品结构, 修改关联订单的产品信息 |
| | | if (!oldBom.getProductModelId().equals(productBom.getProductModelId())) { |
| | | ProductModel productModel = productModelService.getById(productBom.getProductModelId()); |
| | | if (productModel == null) { |
| | | throw new ServiceException("选择的产品模型不存在"); |
| | | } |
| | | |
| | | // 关联的生产订单如果订单完成数量>0,则不许改bom |
| | | // 先查询与该BOM关联的工艺路线 |
| | | List<ProductProcessRoute> productProcessRoutes = productProcessRouteMapper.selectList(new LambdaQueryWrapper<ProductProcessRoute>() |
| | | .eq(ProductProcessRoute::getBomId, oldBom.getId())); |
| | | |
| | | // 检查是否有关联的工艺路线 |
| | | if (!productProcessRoutes.isEmpty()) { |
| | | // 提取工艺路线关联的生产订单ID |
| | | List<Long> orderIds = productProcessRoutes.stream() |
| | | .map(ProductProcessRoute::getProductOrderId) |
| | | .filter(Objects::nonNull) |
| | | .collect(Collectors.toList()); |
| | | |
| | | // 查询关联的生产订单 |
| | | if (!orderIds.isEmpty()) { |
| | | List<ProductOrder> productOrders = productOrderMapper.selectList(new LambdaQueryWrapper<ProductOrder>() |
| | | .in(ProductOrder::getId, orderIds)); |
| | | |
| | | // 检查订单完成数量 |
| | | for (ProductOrder order : productOrders) { |
| | | if (order.getCompleteQuantity() != null && order.getCompleteQuantity().compareTo(BigDecimal.ZERO) > 0) { |
| | | throw new ServiceException("该BOM已关联生产订单且有完成数量,无法修改"); |
| | | } else { |
| | | // 修改关联订单的产品信息 |
| | | order.setProductModelId(productBom.getProductModelId()); |
| | | productOrderMapper.updateById(order); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 修改关联产品工艺路线的产品信息 |
| | | for (ProductProcessRoute route : productProcessRoutes) { |
| | | route.setProductModelId(productBom.getProductModelId()); |
| | | productProcessRouteMapper.updateById(route); |
| | | } |
| | | |
| | | // 查询关联的工艺路线 |
| | | List<ProcessRoute> processRoutes = processRouteMapper.selectList(new LambdaQueryWrapper<ProcessRoute>() |
| | | .eq(ProcessRoute::getBomId, oldBom.getId())); |
| | | if (!processRoutes.isEmpty()) { |
| | | // 修改关联工艺路线的产品信息 |
| | | for (ProcessRoute route : processRoutes) { |
| | | route.setProductModelId(productBom.getProductModelId()); |
| | | processRouteMapper.updateById(route); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 删除之前关联的产品结构 |
| | | productStructureMapper.delete(new LambdaQueryWrapper<ProductStructure>().eq(ProductStructure::getBomId, productBom.getId())); |
| | | |
| | | // 关联新的产品结构 |
| | | ProductStructure productStructure = new ProductStructure(); |
| | | productStructure.setProductModelId(productBom.getProductModelId()); |
| | | productStructure.setUnit(productModel.getUnit()); |
| | | productStructure.setUnitQuantity(BigDecimal.valueOf(1)); |
| | | productStructure.setBomId(productBom.getId()); |
| | | productStructureService.save(productStructure); |
| | | } |
| | | productBomMapper.updateById(productBom); |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public AjaxResult copy(ProductBomDto productBom) { |
| | | Long copyId = productBom.getCopyId(); |
| | | if (copyId == null) { |
| | | throw new ServiceException("复制源BOM ID不能为空"); |
| | | } |
| | | ProductBom sourceBom = productBomMapper.selectById(copyId); |
| | | if (sourceBom == null) { |
| | | throw new ServiceException("复制源BOM不存在"); |
| | | } |
| | | |
| | | |
| | | ProductBom newBom = getProductBom(productBom, sourceBom); |
| | | productBomMapper.insert(newBom); |
| | | newBom.setBomNo("BM." + String.format("%05d", newBom.getId())); |
| | | productBomMapper.updateById(newBom); |
| | | |
| | | |
| | | |
| | | ProductModel productModel = productModelService.getById(newBom.getProductModelId()); |
| | | if (productModel == null) { |
| | | throw new ServiceException("选择的产品模型不存在"); |
| | | } |
| | | |
| | | ProductStructure newRoot = getProductStructure(newBom, productModel); |
| | | productStructureService.save(newRoot); |
| | | List<ProductStructure> sourceStructures = productStructureMapper.selectList( |
| | | Wrappers.<ProductStructure>lambdaQuery() |
| | | .eq(ProductStructure::getBomId, copyId.intValue())); |
| | | if (sourceStructures == null || sourceStructures.isEmpty()) { |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | ProductStructure oldRoot = sourceStructures.stream() |
| | | .filter(s -> s.getParentId() == null) |
| | | .findFirst().orElse(new ProductStructure()); |
| | | |
| | | List<ProductStructure> children = sourceStructures |
| | | .stream() |
| | | .filter(s -> !s.getId().equals(oldRoot.getId())) |
| | | .collect(Collectors.toList()); |
| | | |
| | | Map<Long, Long> oldNewIdMap = new HashMap<>(); |
| | | |
| | | oldNewIdMap.put(oldRoot.getId(), newRoot.getId()); |
| | | |
| | | List<ProductStructure> insertList = children |
| | | .stream() |
| | | .map(item -> getProductStructures(item, newBom)) |
| | | .collect(Collectors.toList()); |
| | | |
| | | productStructureService.saveBatch(insertList); |
| | | |
| | | for (int i = 0; i < children.size(); i++) { |
| | | oldNewIdMap.put( |
| | | children.get(i).getId(), |
| | | insertList.get(i).getId() |
| | | ); |
| | | } |
| | | |
| | | List<ProductStructure> updateList = new ArrayList<>(); |
| | | for (int i = 0; i < children.size(); i++) { |
| | | ProductStructure source = children.get(i); |
| | | ProductStructure inserted = insertList.get(i); |
| | | Long newParentId = oldNewIdMap.get(source.getParentId()); |
| | | if (newParentId != null) { |
| | | inserted.setParentId(newParentId); |
| | | updateList.add(inserted); |
| | | } |
| | | } |
| | | if (!updateList.isEmpty()) { |
| | | productStructureService.updateBatchById(updateList); |
| | | } |
| | | |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | @NotNull |
| | | private static ProductStructure getProductStructures(ProductStructure item, ProductBom newBom) { |
| | | ProductStructure copy = new ProductStructure(); |
| | | copy.setProductModelId(item.getProductModelId()); |
| | | copy.setProcessId(item.getProcessId()); |
| | | copy.setUnitQuantity(item.getUnitQuantity()); |
| | | copy.setDemandedQuantity(item.getDemandedQuantity()); |
| | | copy.setUnit(item.getUnit()); |
| | | copy.setBomId(newBom.getId()); |
| | | return copy; |
| | | } |
| | | |
| | | @NotNull |
| | | private static ProductStructure getProductStructure(ProductBom newBom, ProductModel productModel) { |
| | | ProductStructure newRoot = new ProductStructure(); |
| | | newRoot.setProductModelId(newBom.getProductModelId()); |
| | | newRoot.setUnitQuantity(BigDecimal.valueOf(1)); |
| | | newRoot.setUnit(productModel.getUnit()); |
| | | newRoot.setBomId(newBom.getId()); |
| | | return newRoot; |
| | | } |
| | | |
| | | @NotNull |
| | | private static ProductBom getProductBom(ProductBomDto productBom, ProductBom sourceBom) { |
| | | ProductBom newBom = new ProductBom(); |
| | | newBom.setProductModelId(productBom.getProductModelId() != null ? productBom.getProductModelId() : sourceBom.getProductModelId()); |
| | | newBom.setRemark(productBom.getRemark()); |
| | | newBom.setVersion(productBom.getVersion() != null ? productBom.getVersion() : sourceBom.getVersion()); |
| | | return newBom; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public AjaxResult uploadBom(MultipartFile file) { |
| | | ExcelUtil<BomImportDto> util = new ExcelUtil<>(BomImportDto.class); |
| | | List<BomImportDto> list; |