已修改9个文件
167 ■■■■ 文件已修改
src/main/java/com/ruoyi/production/controller/ProductBomController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/dto/ProductWorkOrderDto.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/dto/ProductionProductMainDto.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/ProductBomService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductBomServiceImpl.java 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductWorkOrderServiceImpl.java 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductionProductMainMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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