src/main/java/com/ruoyi/production/controller/ProductBomController.java
@@ -73,7 +73,7 @@ @Log(title = "修改", businessType = BusinessType.UPDATE) @PutMapping("/update") public AjaxResult update(@RequestBody ProductBom productBom) { return AjaxResult.success(productBomService.updateById(productBom)); return AjaxResult.success(productBomService.update(productBom)); } @ApiOperation("删除BOM") src/main/java/com/ruoyi/production/dto/ProductWorkOrderDto.java
@@ -43,8 +43,16 @@ @ApiModelProperty(value = "完成进度") private BigDecimal completionStatus; // 总产出数量 @ApiModelProperty(value = "总产出数量(包含报废数量)") private BigDecimal totalQty; @ApiModelProperty(value = "报废数量") private BigDecimal scrapQty; // 不良数量 @ApiModelProperty(value = "不良数量") private BigDecimal defectiveQuantity; @ApiModelProperty(value = "工单类型 正常 /返工返修") private String workOrderType; @@ -63,7 +71,7 @@ private BigDecimal completeQty; @ApiModelProperty(value = "不良率") private BigDecimal scrapRate; private BigDecimal defectiveRate; @ApiModelProperty(value = "状态文本") private String statusText; src/main/java/com/ruoyi/production/dto/ProductionProductMainDto.java
@@ -33,6 +33,12 @@ @Excel(name = "报废数量") private BigDecimal scrapQty = BigDecimal.ZERO; // 不良数量 @ApiModelProperty(value = "不良数量") @Excel(name = "不良数量") private BigDecimal defectiveQuantity = BigDecimal.ZERO; // 合格数量 @ApiModelProperty(value = "合格数量") @Excel(name = "合格数量") private BigDecimal qualifiedQty = BigDecimal.ZERO; src/main/java/com/ruoyi/production/service/ProductBomService.java
@@ -27,4 +27,6 @@ AjaxResult uploadBom(MultipartFile file); void exportBom(HttpServletResponse response, Integer bomId); AjaxResult update(ProductBom productBom); } src/main/java/com/ruoyi/production/service/impl/ProductBomServiceImpl.java
@@ -15,10 +15,8 @@ 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; @@ -59,6 +57,18 @@ @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); @@ -99,6 +109,85 @@ @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 uploadBom(MultipartFile file) { ExcelUtil<BomImportDto> util = new ExcelUtil<>(BomImportDto.class); List<BomImportDto> list; src/main/java/com/ruoyi/production/service/impl/ProductWorkOrderServiceImpl.java
@@ -50,6 +50,8 @@ private ProductionProductOutputMapper productionProductOutputMapper; @Autowired private QualityUnqualifiedMapper qualityUnqualifiedMapper; @Autowired private QualityInspectMapper qualityInspectMapper; @Value("${file.temp-dir}") private String tempDir; @@ -189,20 +191,32 @@ productWorkOrderDtos.forEach(productWorkOrderDto -> { // 查询关联产出表数据 List<ProductionProductMain> productionProductMains = productionProductMainMapper.selectList(Wrappers.<ProductionProductMain>lambdaQuery().eq(ProductionProductMain::getWorkOrderId, productWorkOrderDto.getId())); // 查询报废数量 BigDecimal scrapQty = BigDecimal.ZERO; // 查询不良数量 BigDecimal defectiveQuantity = BigDecimal.ZERO; if (CollectionUtils.isNotEmpty(productionProductMains)) { // 计算报废数量 List<Long> mainIds = productionProductMains.stream().map(ProductionProductMain::getId).collect(Collectors.toList()); List<ProductionProductOutput> productionProductOutputs = productionProductOutputMapper.selectList(Wrappers.<ProductionProductOutput>lambdaQuery().in(ProductionProductOutput::getProductMainId, mainIds)); scrapQty = productionProductOutputs.stream().map(ProductionProductOutput::getScrapQty).reduce(BigDecimal.ZERO, BigDecimal::add); List<QualityInspect> qualityInspects = qualityInspectMapper.selectList(Wrappers.<QualityInspect>lambdaQuery().in(QualityInspect::getProductMainId, mainIds)); if (CollectionUtils.isNotEmpty(productionProductOutputs)) { scrapQty = productionProductOutputs.stream().map(ProductionProductOutput::getScrapQty).reduce(BigDecimal.ZERO, BigDecimal::add); } if (CollectionUtils.isNotEmpty(qualityInspects)) { defectiveQuantity = qualityInspects.stream().map(QualityInspect::getDefectiveQuantity).reduce(BigDecimal.ZERO, BigDecimal::add); } } if (productWorkOrderDto.getCompleteQuantity().compareTo(BigDecimal.ZERO) > 0) { productWorkOrderDto.setScrapRate(scrapQty.divide(productWorkOrderDto.getCompleteQuantity(), 4, RoundingMode.HALF_UP)); BigDecimal totalQuantity = productWorkOrderDto.getCompleteQuantity().add(scrapQty); if (totalQuantity.compareTo(BigDecimal.ZERO) > 0) { productWorkOrderDto.setDefectiveRate(defectiveQuantity.divide(productWorkOrderDto.getCompleteQuantity(), 4, RoundingMode.HALF_UP)); } else { productWorkOrderDto.setScrapRate(scrapQty.multiply(BigDecimal.valueOf(100))); productWorkOrderDto.setDefectiveRate(defectiveQuantity.multiply(BigDecimal.valueOf(100))); } productWorkOrderDto.setScrapQty(scrapQty); productWorkOrderDto.setCompleteQty(productWorkOrderDto.getCompleteQuantity().subtract(scrapQty)); productWorkOrderDto.setTotalQty(totalQuantity); productWorkOrderDto.setDefectiveQuantity(defectiveQuantity); productWorkOrderDto.setCompleteQty(productWorkOrderDto.getCompleteQuantity().subtract(defectiveQuantity)); }); } return productWorkOrderDtos; src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
@@ -436,6 +436,10 @@ productionProductMainDtos.forEach(p -> { QualityInspect qualityInspect = productMainIdToInspectMap.get(p.getId()); if (qualityInspect != null) { // 不良数量 p.setDefectiveQuantity( qualityInspect.getDefectiveQuantity()); // 合格数量 = 报工数量-报废数量-不良数量 p.setQualifiedQty(p.getQuantity().subtract(p.getScrapQty()).subtract(p.getDefectiveQuantity())); QualityUnqualified qualityUnqualified = inspectIdToUnqualifiedMap.get(qualityInspect.getId()); if (qualityUnqualified != null) { p.setDealResult(qualityUnqualified.getDealResult() == null ? "" : qualityUnqualified.getDealResult()); src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java
@@ -124,15 +124,20 @@ if (productQtyRate.compareTo(productProcess.getQualifiedRate()) < 0) { // 查询生产订单 ProductionProductMain productionProductMain = productionProductMainMapper.selectById(qualityInspect.getProductMainId()); ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectById(productionProductMain.getWorkOrderId()); ProductOrder productOrder = productOrderMapper.selectOne(new LambdaQueryWrapper<ProductOrder>().eq(ProductOrder::getId, productWorkOrder.getProductOrderId())); if (!ObjectUtils.isNull(productOrder)) { // 发送通知给管理员 sysNoticeService.simpleNoticeByUser("质检提示", String.format("%s生产订单,%s工序合格率%.2f%%低于标准%.2f%%", productOrder.getNpsNo(), productProcess.getName(), productQtyRate, productProcess.getQualifiedRate()), Arrays.asList(Long.valueOf(1L)), qualityInspect.getInspectType() == 2 ? "/qualityManagement/finalInspection" : "/qualityManagement/processInspection"); if (!ObjectUtils.isNull(productionProductMain)) { ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectById(productionProductMain.getWorkOrderId()); if (!ObjectUtils.isNull(productWorkOrder)) { ProductOrder productOrder = productOrderMapper.selectOne(new LambdaQueryWrapper<ProductOrder>().eq(ProductOrder::getId, productWorkOrder.getProductOrderId())); if (!ObjectUtils.isNull(productOrder)) { // 发送通知给管理员 sysNoticeService.simpleNoticeByUser("质检提示", String.format("%s生产订单,%s工序合格率%.2f%%低于标准%.2f%%", productOrder.getNpsNo(), productProcess.getName(), productQtyRate, productProcess.getQualifiedRate()), Arrays.asList(Long.valueOf(1L)), qualityInspect.getInspectType() == 2 ? "/qualityManagement/finalInspection" : "/qualityManagement/processInspection"); } } } } } src/main/resources/mapper/production/ProductionProductMainMapper.xml
@@ -67,7 +67,6 @@ ppo.quantity, ppo.scrap_qty, ppo.other_data, (ppo.quantity - ppo.scrap_qty) as qualifiedQty, pm.unit from production_product_main ppm