| | |
| | | package com.ruoyi.production.service.impl; |
| | | |
| | | import com.alibaba.fastjson2.JSON; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; |
| | | import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | |
| | | import com.ruoyi.basic.pojo.Product; |
| | | import com.ruoyi.basic.pojo.ProductModel; |
| | | import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum; |
| | | import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum; |
| | | import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum; |
| | | import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum; |
| | | import com.ruoyi.common.exception.ServiceException; |
| | | import com.ruoyi.common.utils.bean.BeanUtils; |
| | | import com.ruoyi.procurementrecord.utils.StockUtils; |
| | | import com.ruoyi.production.dto.ProductStructureDto; |
| | | import com.ruoyi.production.dto.DrawMaterialDto; |
| | | import com.ruoyi.production.dto.ProductionProductMainDto; |
| | | import com.ruoyi.production.mapper.*; |
| | | import com.ruoyi.production.pojo.*; |
| | |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import com.ruoyi.production.mapper.ProductionProductMainMapper; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDate; |
| | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.function.Function; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @Service |
| | |
| | | productionProductMain.setProductProcessRouteItemId(dto.getProductProcessRouteItemId()); |
| | | productionProductMain.setWorkOrderId(dto.getWorkOrderId()); |
| | | productionProductMain.setStatus(0); |
| | | productionProductMain.setDeviceId(dto.getDeviceId()); |
| | | productionProductMainMapper.insert(productionProductMain); |
| | | /*新增报工投入表*/ |
| | | List<ProductStructureDto> productStructureDtos = productStructureMapper.listBybomAndProcess(productProcessRoute.getBomId(), productProcess.getId()); |
| | | if (productStructureDtos.isEmpty()) { |
| | | //如果该工序没有产品结构的投入品,那这个投入品和产出品是同一个 |
| | | ProductStructureDto productStructureDto = new ProductStructureDto(); |
| | | productStructureDto.setProductModelId(productProcessRouteItem.getProductModelId()); |
| | | productStructureDto.setUnitQuantity(BigDecimal.ONE); |
| | | productStructureDtos.add(productStructureDto); |
| | | } |
| | | for (ProductStructureDto productStructureDto : productStructureDtos) { |
| | | /* 新增报工投入表 */ |
| | | List<DrawMaterialDto> drawMaterialList = dto.getDrawMaterialList(); |
| | | if (!CollectionUtils.isEmpty(drawMaterialList)) { |
| | | // 1. 批量查询数据 |
| | | ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectById(dto.getWorkOrderId()); |
| | | if (productWorkOrder == null) { |
| | | throw new RuntimeException("工单不存在"); |
| | | } |
| | | |
| | | ProductionProductInput productionProductInput = new ProductionProductInput(); |
| | | productionProductInput.setProductModelId(productStructureDto.getProductModelId()); |
| | | productionProductInput.setQuantity(productStructureDto.getUnitQuantity().multiply(dto.getQuantity())); |
| | | productionProductInput.setProductMainId(productionProductMain.getId()); |
| | | productionProductInputMapper.insert(productionProductInput); |
| | | ProductOrder productOrder = productOrderMapper.selectById(productWorkOrder.getProductOrderId()); |
| | | if (productOrder == null) { |
| | | throw new RuntimeException("产品订单不存在"); |
| | | } |
| | | |
| | | // 2. 解析并构建物料Map |
| | | List<DrawMaterialDto> existingMaterialList = JSON.parseArray(productOrder.getDrawMaterials(), DrawMaterialDto.class); |
| | | if (CollectionUtils.isEmpty(existingMaterialList)) { |
| | | throw new RuntimeException("可领用物料列表为空"); |
| | | } |
| | | |
| | | Map<Long, DrawMaterialDto> materialMap = existingMaterialList.stream() |
| | | .collect(Collectors.toMap(DrawMaterialDto::getProductModelId, |
| | | Function.identity())); |
| | | |
| | | // 处理报工物料 |
| | | List<ProductionProductInput> inputList = new ArrayList<>(); |
| | | |
| | | for (DrawMaterialDto drawMaterial : drawMaterialList) { |
| | | Long modelId = drawMaterial.getProductModelId(); |
| | | BigDecimal reportQty = drawMaterial.getReportQty(); |
| | | |
| | | DrawMaterialDto material = materialMap.get(modelId); |
| | | if (material == null) { |
| | | throw new RuntimeException("物料不存在: " + modelId); |
| | | } |
| | | |
| | | // 验证库存 |
| | | BigDecimal availableQty = material.getRequisitionQty().subtract(reportQty); |
| | | if (availableQty.compareTo(BigDecimal.valueOf(0)) < 0) { |
| | | throw new RuntimeException(String.format("物料%s库存不足,可用:%s,需领:%s", |
| | | modelId, availableQty, reportQty)); |
| | | } |
| | | |
| | | // 更新可领用 |
| | | material.setRequisitionQty(availableQty); |
| | | |
| | | // 构建投入记录 |
| | | ProductionProductInput input = new ProductionProductInput(); |
| | | input.setProductModelId(modelId); |
| | | input.setQuantity(reportQty); |
| | | input.setProductMainId(productionProductMain.getId()); |
| | | input.setRemark(drawMaterial.getRemark()); |
| | | inputList.add(input); |
| | | } |
| | | |
| | | if (!inputList.isEmpty()) { |
| | | for (ProductionProductInput productionProductInput : inputList) { |
| | | productionProductInputMapper.insert(productionProductInput); |
| | | } |
| | | productOrder.setDrawMaterials(JSON.toJSONString(existingMaterialList)); |
| | | productOrderMapper.updateById(productOrder); |
| | | } |
| | | } |
| | | /*新增报工产出表*/ |
| | | ProductionProductOutput productionProductOutput = new ProductionProductOutput(); |
| | |
| | | productionProductOutput.setProductModelId(productProcessRouteItem.getProductModelId()); |
| | | productionProductOutput.setQuantity(dto.getQuantity() != null ? dto.getQuantity() : BigDecimal.ZERO); |
| | | productionProductOutput.setScrapQty(dto.getScrapQty() != null ? dto.getScrapQty() : BigDecimal.ZERO); |
| | | productionProductOutput.setOtherData(dto.getOtherData() != null ? dto.getOtherData() : ""); |
| | | productionProductOutputMapper.insert(productionProductOutput); |
| | | //合格数量=报工数量 |
| | | BigDecimal productQty = productionProductOutput.getQuantity(); |
| | |
| | | inspectType = 2; |
| | | process = null; |
| | | } |
| | | ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectById(productionProductMain.getWorkOrderId()); |
| | | ProductOrder productOrder = productOrderMapper.selectById(productWorkOrder.getProductOrderId()); |
| | | if (productOrder == null) { |
| | | throw new RuntimeException("生产订单不存在"); |
| | | } |
| | | |
| | | |
| | | Product product = productMapper.selectById(productModel.getProductId()); |
| | | QualityInspect qualityInspect = new QualityInspect(); |
| | | qualityInspect.setProductId(product.getId()); |
| | | qualityInspect.setProductName(product.getProductName()); |
| | | qualityInspect.setModel(productModel.getModel()); |
| | | qualityInspect.setUnit(productModel.getUnit()); |
| | | qualityInspect.setQuantity(productQty); |
| | | qualityInspect.setQuantity(productionProductOutput.getQuantity().subtract(productionProductOutput.getScrapQty())); |
| | | qualityInspect.setProcess(process); |
| | | qualityInspect.setInspectState(0); |
| | | qualityInspect.setInspectType(inspectType); |
| | | qualityInspect.setProductMainId(productionProductMain.getId()); |
| | | qualityInspect.setProductModelId(productModel.getId()); |
| | | qualityInspect.setBatchNo(productOrder.getBatchNo()); |
| | | qualityInspect.setManufacturingTeam(productOrder.getManufacturingTeam()); |
| | | qualityInspectMapper.insert(qualityInspect); |
| | | List<QualityTestStandard> qualityTestStandard = qualityTestStandardMapper.getQualityTestStandardByProductId(product.getId(), inspectType, process); |
| | | if (qualityTestStandard.size() > 0) { |
| | |
| | | qualityInspectParamMapper.insert(param); |
| | | }); |
| | | } |
| | | }else { |
| | | } else { |
| | | //直接入库 |
| | | stockUtils.addStock(productProcessRouteItem.getProductModelId(), productQty, StockInQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_IN.getCode(), productionProductMain.getId()); |
| | | stockUtils.addStock(productProcessRouteItem.getProductModelId(), productionProductOutput.getQuantity().subtract(productionProductOutput.getScrapQty()), StockInQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_IN.getCode(), productionProductMain.getId()); |
| | | } |
| | | /*更新工单和生产订单*/ |
| | | ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectById(dto.getWorkOrderId()); |
| | |
| | | public Boolean removeProductMain(Long id) { |
| | | //判断该条报工是否不合格处理,如果不合格处理了,则不允许删除 |
| | | List<QualityInspect> qualityInspects = qualityInspectMapper.selectList(Wrappers.<QualityInspect>lambdaQuery().eq(QualityInspect::getProductMainId, id)); |
| | | if (qualityInspects.size() > 0){ |
| | | if (qualityInspects.size() > 0) { |
| | | List<QualityUnqualified> qualityUnqualifieds = qualityUnqualifiedMapper.selectList(Wrappers.<QualityUnqualified>lambdaQuery() |
| | | .in(QualityUnqualified::getInspectId, qualityInspects.stream().map(QualityInspect::getId).collect(Collectors.toList()))); |
| | | if (qualityUnqualifieds.size() > 0 && qualityUnqualifieds.get(0).getInspectState()==1) { |
| | | if (qualityUnqualifieds.size() > 0 && qualityUnqualifieds.get(0).getInspectState() == 1) { |
| | | throw new ServiceException("该条报工已经不合格处理了,不允许删除"); |
| | | } |
| | | } |
| | |
| | | new LambdaQueryWrapper<QualityInspectParam>() |
| | | .eq(QualityInspectParam::getInspectId, q.getId())); |
| | | qualityInspectMapper.deleteById(q.getId()); |
| | | stockUtils.deleteStockInRecord(q.getId(), StockInQualifiedRecordTypeEnum.QUALITYINSPECT_STOCK_IN.getCode()); |
| | | stockUtils.deleteStockInRecord(q.getId(), StockInQualifiedRecordTypeEnum.QUALITYINSPECT_STOCK_IN.getCode()); |
| | | }); |
| | | |
| | | ProductOrder productOrder = productOrderMapper.selectById(productWorkOrder.getProductOrderId()); |
| | | |
| | | List<DrawMaterialDto> materialDtoList = JSON.parseArray(productOrder.getDrawMaterials(), DrawMaterialDto.class); |
| | | |
| | | // 批量查询并构建Map |
| | | Map<Long, BigDecimal> usedQuantityMap = productionProductInputMapper.selectList( |
| | | new LambdaQueryWrapper<ProductionProductInput>() |
| | | .eq(ProductionProductInput::getProductMainId, productionProductMain.getId()) |
| | | .in(ProductionProductInput::getProductModelId, |
| | | materialDtoList.stream() |
| | | .map(DrawMaterialDto::getProductModelId) |
| | | .collect(Collectors.toList())) |
| | | ).stream() |
| | | .collect(Collectors.groupingBy( |
| | | ProductionProductInput::getProductModelId, |
| | | Collectors.reducing(BigDecimal.ZERO, ProductionProductInput::getQuantity, BigDecimal::add) |
| | | )); |
| | | |
| | | // 更新所有物料 |
| | | materialDtoList.forEach(dto -> { |
| | | BigDecimal usedQty = usedQuantityMap.getOrDefault(dto.getProductModelId(), BigDecimal.ZERO); |
| | | dto.setRequisitionQty(dto.getRequisitionQty().add(usedQty)); |
| | | }); |
| | | |
| | | // 更新订单 |
| | | productOrder.setDrawMaterials(JSON.toJSONString(materialDtoList)); |
| | | productOrderMapper.updateById(productOrder); |
| | | |
| | | // 删除产出记录 |
| | | productionProductOutputMapper.delete(new LambdaQueryWrapper<ProductionProductOutput>() |
| | | .eq(ProductionProductOutput::getProductMainId, productionProductMain.getId())); |