| | |
| | | package com.ruoyi.production.service.impl; |
| | | |
| | | import cn.hutool.core.util.BooleanUtil; |
| | | 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.conditions.update.LambdaUpdateWrapper; |
| | | 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.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.basic.dto.SelectOptionDTO; |
| | | import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum; |
| | | import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum; |
| | | import com.ruoyi.common.exception.base.BaseException; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.ruoyi.procurementrecord.utils.StockUtils; |
| | | import com.ruoyi.production.dto.DrawMaterialDto; |
| | | import com.ruoyi.production.dto.ProductOrderDto; |
| | | import com.ruoyi.production.dto.ProductStructureDto; |
| | | import com.ruoyi.production.mapper.*; |
| | | import com.ruoyi.production.pojo.*; |
| | | import com.ruoyi.production.service.ProductOrderService; |
| | | import com.ruoyi.quality.mapper.QualityInspectMapper; |
| | | import com.ruoyi.quality.pojo.QualityInspect; |
| | | import com.ruoyi.stock.dto.StockInventoryDto; |
| | | import com.ruoyi.stock.mapper.StockInventoryMapper; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDate; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.List; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @Service |
| | |
| | | @Autowired |
| | | private StockUtils stockUtils; |
| | | |
| | | @Autowired |
| | | private ProductStructureMapper productStructureMapper; |
| | | |
| | | @Autowired |
| | | private StockInventoryMapper stockInventoryMapper; |
| | | |
| | | |
| | | @Override |
| | | public IPage<ProductOrderDto> pageProductOrder(Page page, ProductOrderDto productOrder) { |
| | | return productOrderMapper.pageProductOrder(page, productOrder); |
| | | IPage<ProductOrderDto> productOrderDtoIPage = productOrderMapper.pageProductOrder(page, productOrder); |
| | | List<ProductOrderDto> productOrderDtos = productOrderDtoIPage.getRecords(); |
| | | for (int i = 0; i < productOrderDtos.size(); i++) { |
| | | ProductOrderDto productOrderDto = productOrderDtos.get(i); |
| | | if (BooleanUtil.isTrue(productOrderDto.getIsEnd())) { |
| | | // 如果生产订单被结束,则将完成进度设置为100% |
| | | productOrderDto.setCompletionStatus(BigDecimal.valueOf(100)); |
| | | } |
| | | } |
| | | |
| | | return productOrderDtoIPage; |
| | | } |
| | | |
| | | @Override |
| | |
| | | |
| | | @Override |
| | | public Boolean delete(Long[] ids) { |
| | | |
| | | //批量查询productOrder |
| | | List<ProductOrder> productOrders = productOrderMapper.selectList( |
| | | new LambdaQueryWrapper<ProductOrder>() |
| | | .in(ProductOrder::getId, ids) |
| | | ); |
| | | if (!org.springframework.util.CollectionUtils.isEmpty(productOrders)) { |
| | | |
| | | |
| | | // 批量查询processRouteItems |
| | | List<ProductProcessRouteItem> allRouteItems = productProcessRouteItemMapper.selectList( |
| | | new LambdaQueryWrapper<ProductProcessRouteItem>() |
| | | .in(ProductProcessRouteItem::getProductOrderId, ids) |
| | | ); |
| | | |
| | | if (!com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(allRouteItems)) { |
| | | // 获取要删除的工序项ID |
| | | List<Long> routeItemIds = allRouteItems.stream() |
| | | .map(ProductProcessRouteItem::getId) |
| | | .collect(Collectors.toList()); |
| | | |
| | | // 查询关联的工单ID |
| | | List<ProductWorkOrder> workOrders = productWorkOrderMapper.selectList( |
| | | new LambdaQueryWrapper<ProductWorkOrder>() |
| | | .in(ProductWorkOrder::getProductProcessRouteItemId, routeItemIds) |
| | | ); |
| | | if (!com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(workOrders)) { |
| | | List<Long> workOrderIds = workOrders.stream() |
| | | .map(ProductWorkOrder::getId) |
| | | .collect(Collectors.toList()); |
| | | |
| | | // 查询关联的生产主表ID |
| | | List<ProductionProductMain> productMains = productionProductMainMapper.selectList( |
| | | new LambdaQueryWrapper<ProductionProductMain>() |
| | | .in(ProductionProductMain::getWorkOrderId, workOrderIds) |
| | | ); |
| | | List<Long> productMainIds = productMains.stream() |
| | | .map(ProductionProductMain::getId) |
| | | .collect(Collectors.toList()); |
| | | |
| | | // 删除产出表、投入表数据 |
| | | if (!com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(productMainIds)) { |
| | | productionProductOutputMapper.deleteByProductMainIds(productMainIds); |
| | | productionProductInputMapper.deleteByProductMainIds(productMainIds); |
| | | List<QualityInspect> qualityInspects = qualityInspectMapper.selectList( |
| | | new LambdaQueryWrapper<QualityInspect>() |
| | | .in(QualityInspect::getProductMainId, productMainIds) |
| | | ); |
| | | //删除出库记录 |
| | | for (Long productMainId : productMainIds) { |
| | | //删除生产出库记录 |
| | | stockUtils.deleteStockOutRecord(productMainId, StockOutQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode()); |
| | | //删除报废的入库记录 |
| | | stockUtils.deleteStockInRecord(productMainId, StockInUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode()); |
| | | } |
| | | qualityInspects.forEach(qualityInspect -> { |
| | | //inspectState=1 已提交 不能删除 |
| | | if (qualityInspect.getInspectState() == 1) { |
| | | throw new RuntimeException("已提交的检验单不能删除"); |
| | | } |
| | | }); |
| | | qualityInspectMapper.deleteByProductMainIds(productMainIds); |
| | | salesLedgerProductionAccountingMapper.delete(new LambdaQueryWrapper<SalesLedgerProductionAccounting>() |
| | | .in(SalesLedgerProductionAccounting::getProductMainId, productMainIds)); |
| | | } |
| | | |
| | | // 删除生产主表数据 |
| | | productionProductMainMapper.deleteByWorkOrderIds(workOrderIds); |
| | | |
| | | // 删除工单数据 |
| | | productWorkOrderMapper.delete(new LambdaQueryWrapper<ProductWorkOrder>() |
| | | .in(ProductWorkOrder::getProductProcessRouteItemId, routeItemIds)); |
| | | } |
| | | //如果已经开始生产,不能删除 |
| | | //查询生产订单下的工单 |
| | | List<ProductWorkOrder> productWorkOrders = productWorkOrderMapper.selectList(Wrappers.<ProductWorkOrder>lambdaQuery().in(ProductWorkOrder::getProductOrderId, ids)); |
| | | if (productWorkOrders.size() > 0) { |
| | | //判断是否有报工数据 |
| | | List<ProductionProductMain> productionProductMains = productionProductMainMapper.selectList(Wrappers.<ProductionProductMain>lambdaQuery() |
| | | .in(ProductionProductMain::getWorkOrderId, productWorkOrders.stream().map(ProductWorkOrder::getId).collect(Collectors.toList()))); |
| | | if (productionProductMains.size() > 0) { |
| | | throw new RuntimeException("生产订单已经开始生产,不能删除"); |
| | | } |
| | | // 批量删除processRouteItem |
| | | productProcessRouteItemMapper.delete(new LambdaQueryWrapper<ProductProcessRouteItem>() |
| | | .in(ProductProcessRouteItem::getProductOrderId, ids)); |
| | | |
| | | // 批量删除productProcessRoute |
| | | productProcessRouteMapper.delete(new LambdaQueryWrapper<ProductProcessRoute>() |
| | | .in(ProductProcessRoute::getProductOrderId, ids)); |
| | | |
| | | // 批量删除productOrder |
| | | productOrderMapper.delete(new LambdaQueryWrapper<ProductOrder>() |
| | | .in(ProductOrder::getId, ids)); |
| | | //删除工单 |
| | | productWorkOrderMapper.delete(Wrappers.<ProductWorkOrder>lambdaQuery().in(ProductWorkOrder::getProductOrderId, ids)); |
| | | } |
| | | //删除工艺路线 |
| | | productProcessRouteItemMapper.delete(new LambdaQueryWrapper<ProductProcessRouteItem>() |
| | | .in(ProductProcessRouteItem::getProductOrderId, ids)); |
| | | productProcessRouteMapper.delete(new LambdaQueryWrapper<ProductProcessRoute>() |
| | | .in(ProductProcessRoute::getProductOrderId, ids)); |
| | | //删除生产订单 |
| | | productOrderMapper.delete(new LambdaQueryWrapper<ProductOrder>() |
| | | .in(ProductOrder::getId, ids)); |
| | | return true; |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | |
| | | @Override |
| | | public int finishOrder(Long orderId) { |
| | | ProductOrder productOrder = new ProductOrder(); |
| | | productOrder.setId(orderId); |
| | | productOrder.setIsEnd(true); |
| | | return productOrderMapper.updateById(productOrder); |
| | | } |
| | | |
| | | @Override |
| | | public int cleanRecord(Long id, Map<String, Object> cleanRecord) { |
| | | ProductOrder productOrder = productOrderMapper.selectById(id); |
| | | if (productOrder == null) { |
| | | throw new BaseException("订单不存在"); |
| | | } |
| | | productOrder.setCleanRecord(JSON.toJSONString(cleanRecord)); |
| | | return productOrderMapper.updateById(productOrder); |
| | | } |
| | | |
| | | @Override |
| | | public List<SelectOptionDTO<String>> getProductOrderBatchNo() { |
| | | List<ProductOrder> productOrders = productOrderMapper.selectList(null); |
| | | return productOrders.stream().map(productOrder -> new SelectOptionDTO<>(productOrder.getBatchNo(), productOrder.getBatchNo())).collect(Collectors.toList()); |
| | | } |
| | | |
| | | @Override |
| | | public List<StockInventoryDto> getByBomId(Long bomId) { |
| | | List<ProductStructureDto> structureList = productStructureMapper.listBybomId(bomId); |
| | | |
| | | if (CollectionUtils.isEmpty(structureList)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | |
| | | Set<Long> allNodeIds = structureList.stream() |
| | | .map(ProductStructureDto::getId) |
| | | .collect(Collectors.toSet()); |
| | | |
| | | Set<Long> parentIds = structureList.stream() |
| | | .filter(node -> node.getParentId() != null && node.getParentId() != 0) |
| | | .map(ProductStructureDto::getParentId) |
| | | .collect(Collectors.toSet()); |
| | | |
| | | Set<Long> leafNodeIds = new HashSet<>(allNodeIds); |
| | | leafNodeIds.removeAll(parentIds); |
| | | |
| | | // 获取叶子节点的 productModelId |
| | | List<Long> productModelIds = structureList.stream() |
| | | .filter(node -> leafNodeIds.contains(node.getId())) |
| | | .map(ProductStructureDto::getProductModelId) |
| | | .filter(Objects::nonNull) |
| | | .distinct() |
| | | .collect(Collectors.toList()); |
| | | |
| | | if (productModelIds.isEmpty()) { |
| | | return Collections.emptyList(); |
| | | } |
| | | |
| | | return stockInventoryMapper.getStockInventory(productModelIds); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public int drawMaterials(ProductOrderDto productOrderDto) { |
| | | if (productOrderDto == null || productOrderDto.getId() == null) { |
| | | throw new RuntimeException("参数错误"); |
| | | } |
| | | |
| | | String jsonString = productOrderDto.getDrawMaterials(); |
| | | if (StringUtils.isEmpty(jsonString)) { |
| | | throw new RuntimeException("领料明细不能为空"); |
| | | } |
| | | |
| | | List<DrawMaterialDto> drawMaterialsList; |
| | | try { |
| | | drawMaterialsList = JSON.parseArray(jsonString, DrawMaterialDto.class); |
| | | } catch (Exception e) { |
| | | throw new RuntimeException("领料明细格式错误"); |
| | | } |
| | | |
| | | if (CollectionUtils.isEmpty(drawMaterialsList)) { |
| | | throw new RuntimeException("领料明细不能为空"); |
| | | } |
| | | |
| | | // 处理领料(扣减库存) |
| | | try { |
| | | for (DrawMaterialDto drawMaterialDto : drawMaterialsList) { |
| | | if (drawMaterialDto.getProductModelId() == null) { |
| | | throw new RuntimeException("产品型号ID不能为空"); |
| | | } |
| | | stockUtils.substractStock(drawMaterialDto.getProductModelId(), drawMaterialDto.getRequisitionQty(), StockOutQualifiedRecordTypeEnum.DRAW_MATERIALS_STOCK_OUT.getCode(), productOrderDto.getId()); |
| | | } |
| | | } catch (Exception e) { |
| | | throw new RuntimeException("领料失败:" + e.getMessage()); |
| | | } |
| | | |
| | | // JSON字符串存储 |
| | | String newJsonString = JSON.toJSONString(drawMaterialsList); |
| | | int update = productOrderMapper.update(null, |
| | | new LambdaUpdateWrapper<ProductOrder>() |
| | | .eq(ProductOrder::getId, productOrderDto.getId()) |
| | | .set(ProductOrder::getDrawMaterials, newJsonString)); |
| | | |
| | | // 校验更新结果 |
| | | if (update == 0) { |
| | | throw new RuntimeException("更新订单失败"); |
| | | } |
| | | |
| | | return update; |
| | | } |
| | | } |