| | |
| | | import java.time.LocalDateTime; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.HashMap; |
| | | import java.util.LinkedHashMap; |
| | | import java.util.LinkedHashSet; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | import java.util.Set; |
| | | import java.util.stream.Collectors; |
| | | |
| | | @Service |
| | |
| | | |
| | | @Override |
| | | public IPage<ProductionProductMainDto> listPageProductionProductMainDto(Page page, ProductionProductMainDto productionProductMainDto) { |
| | | return productionProductMainMapper.listPageProductionProductMainDto(page, productionProductMainDto); |
| | | IPage<ProductionProductMainDto> result = productionProductMainMapper.listPageProductionProductMainDto(page, productionProductMainDto); |
| | | fillOperationParamList(result.getRecords()); |
| | | return result; |
| | | } |
| | | |
| | | @Override |
| | |
| | | |
| | | @Override |
| | | public ProductionProductMainDto getProductionProductMainInfo(Long id) { |
| | | return productionProductMainMapper.listPageProductionProductMainDto(new Page<>(1, 1), new ProductionProductMainDto() {{ |
| | | return listPageProductionProductMainDto(new Page<>(1, 1), new ProductionProductMainDto() {{ |
| | | setId(id); |
| | | }}).getRecords().stream().findFirst().orElse(null); |
| | | } |
| | | |
| | | private void fillOperationParamList(List<ProductionProductMainDto> recordList) { |
| | | if (recordList == null || recordList.isEmpty()) { |
| | | return; |
| | | } |
| | | Set<Long> mainIdSet = recordList.stream() |
| | | .map(ProductionProductMainDto::getId) |
| | | .filter(Objects::nonNull) |
| | | .collect(Collectors.toCollection(LinkedHashSet::new)); |
| | | if (mainIdSet.isEmpty()) { |
| | | recordList.forEach(item -> item.setProductionOperationParamList(Collections.emptyList())); |
| | | return; |
| | | } |
| | | |
| | | List<ProductionOrderRoutingOperationParam> paramList = productionOrderRoutingOperationParamMapper.selectList( |
| | | Wrappers.<ProductionOrderRoutingOperationParam>lambdaQuery() |
| | | .in(ProductionOrderRoutingOperationParam::getProductionProductMainId, mainIdSet) |
| | | .orderByAsc(ProductionOrderRoutingOperationParam::getId)); |
| | | Map<Long, List<ProductionOrderRoutingOperationParam>> paramGroupMap = new HashMap<>(); |
| | | for (ProductionOrderRoutingOperationParam param : paramList) { |
| | | if (param == null || param.getProductionProductMainId() == null) { |
| | | continue; |
| | | } |
| | | paramGroupMap.computeIfAbsent(param.getProductionProductMainId(), key -> new ArrayList<>()).add(param); |
| | | } |
| | | |
| | | Set<Long> missingMainIdSet = new LinkedHashSet<>(); |
| | | for (ProductionProductMainDto item : recordList) { |
| | | Long mainId = item.getId(); |
| | | if (mainId == null) { |
| | | item.setProductionOperationParamList(Collections.emptyList()); |
| | | continue; |
| | | } |
| | | List<ProductionOrderRoutingOperationParam> params = paramGroupMap.get(mainId); |
| | | if (params != null && !params.isEmpty()) { |
| | | item.setProductionOperationParamList(params); |
| | | continue; |
| | | } |
| | | missingMainIdSet.add(mainId); |
| | | } |
| | | if (missingMainIdSet.isEmpty()) { |
| | | return; |
| | | } |
| | | |
| | | // 兼容历史数据:旧报工记录没有按报工ID落参数快照时,回退展示工序模板参数。 |
| | | List<ProductionProductMain> mainList = productionProductMainMapper.selectBatchIds(missingMainIdSet); |
| | | Map<Long, Long> mainIdToTaskIdMap = mainList.stream() |
| | | .filter(Objects::nonNull) |
| | | .filter(item -> item.getId() != null) |
| | | .collect(Collectors.toMap(ProductionProductMain::getId, |
| | | ProductionProductMain::getProductionOperationTaskId, (left, right) -> left)); |
| | | Set<Long> taskIdSet = mainIdToTaskIdMap.values().stream() |
| | | .filter(Objects::nonNull) |
| | | .collect(Collectors.toCollection(LinkedHashSet::new)); |
| | | if (taskIdSet.isEmpty()) { |
| | | for (ProductionProductMainDto item : recordList) { |
| | | if (item.getId() != null && missingMainIdSet.contains(item.getId())) { |
| | | item.setProductionOperationParamList(Collections.emptyList()); |
| | | } |
| | | } |
| | | return; |
| | | } |
| | | |
| | | List<ProductionOperationTask> taskList = productionOperationTaskMapper.selectList( |
| | | Wrappers.<ProductionOperationTask>lambdaQuery() |
| | | .in(ProductionOperationTask::getId, taskIdSet)); |
| | | Map<Long, Long> taskIdToRoutingOperationIdMap = taskList.stream() |
| | | .filter(Objects::nonNull) |
| | | .filter(item -> item.getId() != null) |
| | | .collect(Collectors.toMap(ProductionOperationTask::getId, |
| | | ProductionOperationTask::getProductionOrderRoutingOperationId, (left, right) -> left)); |
| | | Set<Long> routingOperationIdSet = taskIdToRoutingOperationIdMap.values().stream() |
| | | .filter(Objects::nonNull) |
| | | .collect(Collectors.toCollection(LinkedHashSet::new)); |
| | | if (routingOperationIdSet.isEmpty()) { |
| | | for (ProductionProductMainDto item : recordList) { |
| | | if (item.getId() != null && missingMainIdSet.contains(item.getId())) { |
| | | item.setProductionOperationParamList(Collections.emptyList()); |
| | | } |
| | | } |
| | | return; |
| | | } |
| | | |
| | | List<ProductionOrderRoutingOperationParam> fallbackParamList = productionOrderRoutingOperationParamMapper.selectList( |
| | | Wrappers.<ProductionOrderRoutingOperationParam>lambdaQuery() |
| | | .in(ProductionOrderRoutingOperationParam::getProductionOrderRoutingOperationId, routingOperationIdSet) |
| | | .isNull(ProductionOrderRoutingOperationParam::getProductionProductMainId) |
| | | .orderByAsc(ProductionOrderRoutingOperationParam::getId)); |
| | | Map<Long, List<ProductionOrderRoutingOperationParam>> fallbackGroupMap = new HashMap<>(); |
| | | for (ProductionOrderRoutingOperationParam param : fallbackParamList) { |
| | | if (param == null || param.getProductionOrderRoutingOperationId() == null) { |
| | | continue; |
| | | } |
| | | fallbackGroupMap.computeIfAbsent(param.getProductionOrderRoutingOperationId(), key -> new ArrayList<>()).add(param); |
| | | } |
| | | |
| | | for (ProductionProductMainDto item : recordList) { |
| | | Long mainId = item.getId(); |
| | | if (mainId == null || !missingMainIdSet.contains(mainId)) { |
| | | continue; |
| | | } |
| | | Long taskId = mainIdToTaskIdMap.get(mainId); |
| | | Long routingOperationId = taskId == null ? null : taskIdToRoutingOperationIdMap.get(taskId); |
| | | if (routingOperationId == null) { |
| | | item.setProductionOperationParamList(Collections.emptyList()); |
| | | continue; |
| | | } |
| | | item.setProductionOperationParamList(fallbackGroupMap.getOrDefault(routingOperationId, Collections.emptyList())); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | |
| | | if (productionOrder == null) { |
| | | throw new ServiceException("生产订单不存在"); |
| | | } |
| | | syncOperationParamInputValue(dto, routingOperation.getId()); |
| | | TechnologyRoutingOperation technologyRoutingOperation = technologyRoutingOperationMapper.selectById(routingOperation.getTechnologyRoutingOperationId()); |
| | | TechnologyOperation technologyOperation = technologyRoutingOperation == null ? null |
| | | : technologyOperationMapper.selectById(technologyRoutingOperation.getTechnologyOperationId()); |
| | |
| | | productionProductMain.setProductionOperationTaskId(taskId); |
| | | productionProductMain.setStatus(0); |
| | | productionProductMainMapper.insert(productionProductMain); |
| | | syncOperationParamInputValue(dto, routingOperation.getId(), productionProductMain.getId()); |
| | | |
| | | List<ProductStructureDto> productStructureDtos = resolveInputStructures( |
| | | productionOrder.getId(), routingOperation, productModel.getId()); |
| | | // 如果没有bom子节点了,那么投入就是他本身 |
| | | if (productStructureDtos.isEmpty()) { |
| | | throw new ServiceException("未找到当前工序对应的BOM投入节点"); |
| | | ProductStructureDto fallbackInput = new ProductStructureDto(); |
| | | fallbackInput.setProductModelId(productModel.getId()); |
| | | fallbackInput.setUnitQuantity(BigDecimal.ONE); |
| | | productStructureDtos.add(fallbackInput); |
| | | } |
| | | for (ProductStructureDto item : productStructureDtos) { |
| | | // 当前实现按工序成品直接作为投入,后续若接入领料记录可在这里替换来源。 |
| | |
| | | qualityInspect.setProductModelId(productModel.getId()); |
| | | qualityInspectMapper.insert(qualityInspect); |
| | | List<QualityTestStandard> qualityTestStandard = qualityTestStandardMapper.getQualityTestStandardByProductId(product.getId(), inspectType, process); |
| | | if (qualityTestStandard.size() > 0) { |
| | | if (!qualityTestStandard.isEmpty()) { |
| | | qualityInspect.setTestStandardId(qualityTestStandard.get(0).getId()); |
| | | qualityInspectMapper.updateById(qualityInspect); |
| | | qualityTestStandardParamMapper.selectList(Wrappers.<QualityTestStandardParam>lambdaQuery() |
| | |
| | | return true; |
| | | } |
| | | |
| | | private void syncOperationParamInputValue(ProductionProductMainDto dto, Long productionOrderRoutingOperationId) { |
| | | if (dto == null || productionOrderRoutingOperationId == null) { |
| | | private void syncOperationParamInputValue(ProductionProductMainDto dto, |
| | | Long productionOrderRoutingOperationId, |
| | | Long productionProductMainId) { |
| | | if (dto == null || productionOrderRoutingOperationId == null || productionProductMainId == null) { |
| | | return; |
| | | } |
| | | List<ProductionOrderRoutingOperationParam> paramList = dto.getProductionOperationParamList(); |
| | | if (paramList == null || paramList.isEmpty()) { |
| | | return; |
| | | } |
| | | Set<Long> sourceParamIdSet = paramList.stream() |
| | | .filter(Objects::nonNull) |
| | | .map(ProductionOrderRoutingOperationParam::getId) |
| | | .filter(Objects::nonNull) |
| | | .collect(Collectors.toCollection(LinkedHashSet::new)); |
| | | if (sourceParamIdSet.isEmpty()) { |
| | | return; |
| | | } |
| | | |
| | | List<ProductionOrderRoutingOperationParam> dbParamList = productionOrderRoutingOperationParamMapper.selectList( |
| | | Wrappers.<ProductionOrderRoutingOperationParam>lambdaQuery() |
| | | .in(ProductionOrderRoutingOperationParam::getId, sourceParamIdSet) |
| | | .eq(ProductionOrderRoutingOperationParam::getProductionOrderRoutingOperationId, productionOrderRoutingOperationId)); |
| | | if (dbParamList == null || dbParamList.isEmpty()) { |
| | | return; |
| | | } |
| | | |
| | | Map<Long, ProductionOrderRoutingOperationParam> dbParamMap = dbParamList.stream() |
| | | .filter(item -> item != null && item.getId() != null) |
| | | .collect(Collectors.toMap(ProductionOrderRoutingOperationParam::getId, item -> item, (left, right) -> left)); |
| | |
| | | if (dbParam == null) { |
| | | throw new ServiceException("工序参数不存在或不属于当前工单工序,ID=" + param.getId()); |
| | | } |
| | | if (Objects.equals(dbParam.getInputValue(), param.getInputValue())) { |
| | | continue; |
| | | productionOrderRoutingOperationParamMapper.insert(buildReportParamSnapshot(dbParam, param.getInputValue(), productionProductMainId)); |
| | | } |
| | | ProductionOrderRoutingOperationParam updateParam = new ProductionOrderRoutingOperationParam(); |
| | | updateParam.setId(dbParam.getId()); |
| | | updateParam.setInputValue(param.getInputValue()); |
| | | productionOrderRoutingOperationParamMapper.updateById(updateParam); |
| | | } |
| | | |
| | | private ProductionOrderRoutingOperationParam buildReportParamSnapshot(ProductionOrderRoutingOperationParam source, |
| | | String inputValue, |
| | | Long productionProductMainId) { |
| | | ProductionOrderRoutingOperationParam target = new ProductionOrderRoutingOperationParam(); |
| | | target.setProductionOrderId(source.getProductionOrderId()); |
| | | target.setTechnologyRoutingOperationParamId(source.getTechnologyRoutingOperationParamId()); |
| | | target.setParamCode(source.getParamCode()); |
| | | target.setParamName(source.getParamName()); |
| | | target.setParamType(source.getParamType()); |
| | | target.setParamFormat(source.getParamFormat()); |
| | | target.setUnit(source.getUnit()); |
| | | target.setIsRequired(source.getIsRequired()); |
| | | target.setRemark(source.getRemark()); |
| | | target.setParamId(source.getParamId()); |
| | | target.setTechnologyOperationId(source.getTechnologyOperationId()); |
| | | target.setTechnologyOperationParamId(source.getTechnologyOperationParamId()); |
| | | target.setStandardValue(source.getStandardValue()); |
| | | target.setInputValue(inputValue); |
| | | target.setProductionOrderRoutingOperationId(source.getProductionOrderRoutingOperationId()); |
| | | target.setProductionProductMainId(productionProductMainId); |
| | | return target; |
| | | } |
| | | |
| | | private List<ProductStructureDto> resolveInputStructures(Long productionOrderId, |
| | |
| | | .eq(ProductionProductOutput::getProductionProductMainId, productionProductMain.getId())); |
| | | productionProductInputMapper.delete(new LambdaQueryWrapper<ProductionProductInput>() |
| | | .eq(ProductionProductInput::getProductionProductMainId, productionProductMain.getId())); |
| | | productionOrderRoutingOperationParamMapper.delete( |
| | | Wrappers.<ProductionOrderRoutingOperationParam>lambdaQuery() |
| | | .eq(ProductionOrderRoutingOperationParam::getProductionProductMainId, productionProductMain.getId())); |
| | | stockUtils.deleteStockInRecord(productionProductMain.getId(), StockInUnQualifiedRecordTypeEnum.PRODUCTION_SCRAP.getCode()); |
| | | stockUtils.deleteStockInRecord(productionProductMain.getId(), StockInQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_IN.getCode()); |
| | | stockUtils.deleteStockOutRecord(productionProductMain.getId(), StockOutQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode()); |