package com.ruoyi.production.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; 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.mapper.ProductMapper; import com.ruoyi.basic.mapper.ProductModelMapper; import com.ruoyi.basic.pojo.Product; import com.ruoyi.basic.pojo.ProductModel; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.bean.BeanUtils; import com.ruoyi.procurementrecord.mapper.ProcurementRecordOutMapper; import com.ruoyi.procurementrecord.pojo.ProcurementRecordOut; import com.ruoyi.procurementrecord.utils.StockUtils; import com.ruoyi.production.controller.ProductWorkOrderController; import com.ruoyi.production.dto.ProductStructureDto; import com.ruoyi.production.dto.ProductionProductMainDto; import com.ruoyi.production.mapper.*; import com.ruoyi.production.pojo.*; import com.ruoyi.production.service.ProductionProductMainService; import com.ruoyi.project.system.domain.SysUser; import com.ruoyi.project.system.mapper.SysUserMapper; import com.ruoyi.quality.mapper.QualityInspectMapper; import com.ruoyi.quality.mapper.QualityInspectParamMapper; import com.ruoyi.quality.mapper.QualityTestStandardMapper; import com.ruoyi.quality.pojo.QualityInspect; import com.ruoyi.quality.pojo.QualityInspectParam; import com.ruoyi.quality.pojo.QualityTestStandard; import io.swagger.models.auth.In; import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.ruoyi.production.mapper.ProductionProductMainMapper; import oshi.driver.mac.net.NetStat; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.util.HashMap; import java.util.List; import java.util.Map; @Service @AllArgsConstructor @Transactional(rollbackFor = Exception.class) public class ProductionProductMainServiceImpl extends ServiceImpl implements ProductionProductMainService { private final ProcurementRecordOutMapper procurementRecordOutMapper; private ProductionProductMainMapper productionProductMainMapper; private ProductWorkOrderController productWorkOrderController; private ProductWorkOrderMapper productWorkOrderMapper; private ProductProcessRouteItemMapper productProcessRouteItemMapper; private SysUserMapper userMapper; private ProductionProductOutputMapper productionProductOutputMapper; private ProcessRouteItemMapper processRouteItemMapper; private ProductModelMapper productModelMapper; private QualityInspectMapper qualityInspectMapper; private ProductProcessMapper productProcessMapper; private ProductProcessRouteMapper productProcessRouteMapper; private ProductMapper productMapper; private QualityTestStandardMapper qualityTestStandardMapper; private QualityInspectParamMapper qualityInspectParamMapper; private ProductStructureMapper productStructureMapper; private ProductionProductInputMapper productionProductInputMapper; private ProductOrderMapper productOrderMapper; private SalesLedgerProductionAccountingMapper salesLedgerProductionAccountingMapper; private StockUtils stockUtils; @Override public IPage listPageProductionProductMainDto(Page page, ProductionProductMainDto productionProductMainDto) { return productionProductMainMapper.listPageProductionProductMainDto(page, productionProductMainDto); } @Override public Boolean addProductMain(ProductionProductMainDto dto) { SysUser user = userMapper.selectUserById(dto.getUserId()); ProductionProductMain productionProductMain = new ProductionProductMain(); //当前工艺路线对应的工序详情 ProductProcessRouteItem productProcessRouteItem = productProcessRouteItemMapper.selectById(dto.getProductProcessRouteItemId()); if (productProcessRouteItem == null) { throw new RuntimeException("工艺路线项不存在"); } //当前具体工序 ProductProcess productProcess = productProcessMapper.selectById(productProcessRouteItem.getProcessId()); //工艺路线中当前工序对应的产出规格型号 ProductModel productModel = productModelMapper.selectById(productProcessRouteItem.getProductModelId()); //查询该生产订单对应的bom ProductProcessRoute productProcessRoute = productProcessRouteMapper.selectById(productProcessRouteItem.getProductRouteId()); /*新增报工主表*/ //查询最大报工编号 String datePrefix = "BG" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyMMdd")); QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.select("MAX(product_no) as maxNo") .likeRight("product_no", datePrefix); List> resultList = productionProductMainMapper.selectMaps(queryWrapper); int sequenceNumber = 1; if (resultList != null && !resultList.isEmpty()) { Map result = resultList.get(0); if (result != null) { Object maxNoObj = result.get("maxNo"); if (maxNoObj != null) { String lastNo = maxNoObj.toString(); System.out.println("lastNo: " + lastNo); if (lastNo.startsWith(datePrefix)) { try { String seqStr = lastNo.substring(datePrefix.length()); sequenceNumber = Integer.parseInt(seqStr) + 1; } catch (NumberFormatException e) { sequenceNumber = 1; } } } } } String productNo = String.format("%s%03d", datePrefix, sequenceNumber); productionProductMain.setProductNo(productNo); productionProductMain.setUserId(dto.getUserId()); productionProductMain.setUserName(dto.getUserName()); productionProductMain.setProductProcessRouteItemId(dto.getProductProcessRouteItemId()); productionProductMain.setWorkOrderId(dto.getWorkOrderId()); productionProductMain.setStatus(0); productionProductMainMapper.insert(productionProductMain); /*新增报工投入表*/ List productStructureDtos = productStructureMapper.listBybomAndProcess(productProcessRoute.getBomId(), productProcess.getId()); if (productStructureDtos.size() == 0) { //如果该工序没有产品结构的投入品,那这个投入品和产出品是同一个 ProductStructureDto productStructureDto = new ProductStructureDto(); productStructureDto.setProductModelId(productProcessRouteItem.getProductModelId()); productStructureDto.setUnitQuantity(BigDecimal.ONE); productStructureDtos.add(productStructureDto); } for (ProductStructureDto productStructureDto : productStructureDtos) { ProductModel productModel1 = productModelMapper.selectById(productStructureDto.getProductModelId()); Product product = productMapper.selectById(productModel1.getProductId()); BigDecimal stockQuantity = stockUtils.getStockQuantity(productModel1.getId()).get("stockQuantity"); if (!(stockQuantity.compareTo(BigDecimal.ZERO) > 0)) { throw new RuntimeException(product.getProductName() + "库存为0"); } if (stockQuantity.compareTo(productStructureDto.getUnitQuantity().multiply(dto.getQuantity())) < 0) { throw new RuntimeException(product.getProductName() + "库存不足"); } ProductionProductInput productionProductInput = new ProductionProductInput(); productionProductInput.setProductModelId(productStructureDto.getProductModelId()); productionProductInput.setQuantity(productStructureDto.getUnitQuantity().multiply(dto.getQuantity())); productionProductInput.setProductMainId(productionProductMain.getId()); productionProductInputMapper.insert(productionProductInput); //对应的库存出库 DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyyMMdd"); LocalDate now = LocalDate.now(); ProcurementRecordOut procurementRecordOut1 = procurementRecordOutMapper.selectCode(dateFormat.format(now)); Long aLong = procurementRecordOut1 == null ? 1L : Long.valueOf(procurementRecordOut1.getCode().split("LS" + dateFormat.format(now))[1]); ProcurementRecordOut.ProcurementRecordOutBuilder procurementRecordOut = ProcurementRecordOut.builder() .procurementRecordStorageId(0) .code("LS" + dateFormat.format(now) + String.format("%03d", aLong + 1)) .salesLedgerProductId(productionProductMain.getId())//关联报工产出 .inboundBatches(aLong.equals(0L) ? "第1批次" : "第" + (aLong + 1) + "批次") .inboundNum(productionProductInput.getQuantity()) .type(4) .createBy(user.getNickName()) .productModelId(productModel1.getId()); procurementRecordOutMapper.insert(procurementRecordOut.build()); } /*新增报工产出表*/ ProductionProductOutput productionProductOutput = new ProductionProductOutput(); productionProductOutput.setProductMainId(productionProductMain.getId()); productionProductOutput.setProductModelId(productProcessRouteItem.getProductModelId()); productionProductOutput.setQuantity(dto.getQuantity() != null ? dto.getQuantity() : BigDecimal.ZERO); productionProductOutputMapper.insert(productionProductOutput); //对应的过程检或者出厂检 List productProcessRouteItems = productProcessRouteItemMapper.selectList(Wrappers.lambdaQuery().eq(ProductProcessRouteItem::getProductRouteId, productProcessRouteItem.getProductRouteId())); int inspectType = 1; if (productProcessRouteItem.getDragSort()==productProcessRouteItems.size()){ //最后一道工序生成出厂检 inspectType = 2; } 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(dto.getQuantity()); qualityInspect.setProcess(productProcess.getName()); qualityInspect.setInspectState(0); qualityInspect.setInspectType(inspectType); qualityInspect.setProductMainId(productionProductMain.getId()); qualityInspect.setProductModelId(productModel.getId()); qualityInspectMapper.insert(qualityInspect); qualityTestStandardMapper.selectList( new LambdaQueryWrapper() .eq(QualityTestStandard::getProductId, product.getId()) ).forEach(standard -> { QualityInspectParam param = new QualityInspectParam(); BeanUtils.copyProperties(standard, param); param.setId(null); param.setInspectId(qualityInspect.getId()); qualityInspectParamMapper.insert(param); }); /*更新工单和生产订单*/ ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectById(dto.getWorkOrderId()); productWorkOrder.setCompleteQuantity(productWorkOrder.getCompleteQuantity().add(dto.getQuantity())); if (ObjectUtils.isNull(productWorkOrder.getActualStartTime())){ productWorkOrder.setActualStartTime(LocalDate.now());//实际开始时间 } if (productWorkOrder.getCompleteQuantity().compareTo(productWorkOrder.getPlanQuantity()) == 0){ productWorkOrder.setActualEndTime(LocalDate.now());//实际结束时间 } productWorkOrderMapper.updateById(productWorkOrder); //生产订单 ProductOrder productOrder = productOrderMapper.selectById(productWorkOrder.getProductOrderId()); if (ObjectUtils.isNull(productOrder.getStartTime())){ productOrder.setStartTime(LocalDateTime.now());//开始时间 } if (productProcessRouteItem.getDragSort()==productProcessRouteItems.size()){ //如果是最后一道工序报工之后生产订单完成数量+ productOrder.setCompleteQuantity(productOrder.getCompleteQuantity().add(dto.getQuantity())); if (productOrder.getCompleteQuantity().compareTo(productOrder.getQuantity()) == 0){ productOrder.setEndTime(LocalDateTime.now());//结束时间 } } productOrderMapper.updateById(productOrder); /*添加生产核算*/ SalesLedgerProductionAccounting salesLedgerProductionAccounting = SalesLedgerProductionAccounting.builder() .salesLedgerWorkId(productionProductMain.getId()) .salesLedgerSchedulingId(0L) .salesLedgerId(productOrder.getSalesLedgerId()) .salesLedgerProductId(productOrder.getProductModelId()) .schedulingUserId(user.getUserId()) .schedulingUserName(user.getNickName()) .finishedNum(dto.getQuantity() != null ? dto.getQuantity() : BigDecimal.ZERO) .workHours(productProcess.getSalaryQuota()) .process(productProcess.getName()) .schedulingDate(LocalDate.now()) .tenantId(dto.getTenantId()) .build(); salesLedgerProductionAccountingMapper.insert(salesLedgerProductionAccounting); return true; } @Override public Boolean removeProductMain(ProductionProductMainDto dto) { ProductionProductMain productionProductMain = productionProductMainMapper.selectById(dto.getId()); //该报工对应的工艺路线详情 ProductProcessRouteItem productProcessRouteItem = productProcessRouteItemMapper.selectById(productionProductMain.getProductProcessRouteItemId()); ProductionProductOutput productionProductOutput = productionProductOutputMapper.selectList(Wrappers.lambdaQuery().eq(ProductionProductOutput::getProductMainId, productionProductMain.getId())).get(0); /*删除核算*/ salesLedgerProductionAccountingMapper.delete( new LambdaQueryWrapper() .eq(SalesLedgerProductionAccounting::getSalesLedgerWorkId, productionProductMain.getId()) ); /*更新工单和生产订单*/ ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectById(productionProductMain.getWorkOrderId()); productWorkOrder.setCompleteQuantity(productWorkOrder.getCompleteQuantity().subtract(productionProductOutput.getQuantity())); productWorkOrder.setActualEndTime(null); productWorkOrderMapper.updateById(productWorkOrder); //判断是否是最后一道工序 List productProcessRouteItems = productProcessRouteItemMapper.selectList(Wrappers.lambdaQuery().eq(ProductProcessRouteItem::getProductRouteId, productProcessRouteItem.getProductRouteId())); if (productProcessRouteItem.getDragSort() == productProcessRouteItems.size()){ ProductOrder productOrder = productOrderMapper.selectById(productWorkOrder.getProductOrderId()); productOrder.setCompleteQuantity(productOrder.getCompleteQuantity().subtract(productionProductOutput.getQuantity())); productOrder.setEndTime(null); productOrderMapper.updateById(productOrder); } /*删除产出*/ //删除质检 qualityInspectMapper.selectList( new LambdaQueryWrapper() .eq(QualityInspect::getProductMainId, productionProductMain.getId()) ).forEach(q -> { qualityInspectParamMapper.delete( new LambdaQueryWrapper() .eq(QualityInspectParam::getInspectId, q.getId())); qualityInspectMapper.deleteById(q.getId()); }); // 删除产出记录 productionProductOutputMapper.delete(new LambdaQueryWrapper() .eq(ProductionProductOutput::getProductMainId, productionProductMain.getId())); /*删除投入*/ procurementRecordOutMapper.delete(new LambdaQueryWrapper() .eq(ProcurementRecordOut::getSalesLedgerProductId, productionProductMain.getId())); productionProductInputMapper.delete(new LambdaQueryWrapper() .eq(ProductionProductInput::getProductMainId, productionProductMain.getId())); // 删除主表 productionProductMainMapper.deleteById(productionProductMain.getId()); return true; } }