| | |
| | | private final ProductionOperationTaskMapper productionOperationTaskMapper; |
| | | private final ProductionOrderBomMapper productionOrderBomMapper; |
| | | private final ProductionBomStructureMapper productionBomStructureMapper; |
| | | private final ProductionOrderMapper productionOrderMapper; |
| | | private final ProductionProductMainMapper productionProductMainMapper; |
| | | private final ProductionProductOutputMapper productionProductOutputMapper; |
| | | private final ProductionOrderPickMapper productionOrderPickMapper; |
| | |
| | | || !Objects.equals(oldOrder.getProductModelId(), productionOrder.getProductModelId()) |
| | | || compareDecimal(oldOrder.getQuantity(), productionOrder.getQuantity()) != 0 |
| | | || productionOrderRoutingMapper.selectCount(Wrappers.<ProductionOrderRouting>lambdaQuery() |
| | | .eq(ProductionOrderRouting::getProductionOrderId, productionOrder.getId())) == 0); |
| | | .eq(ProductionOrderRouting::getProductionOrderId, productionOrder.getId())) == 0); |
| | | if (needSync) { |
| | | syncProductionOrderSnapshot(productionOrder.getId()); |
| | | } |
| | |
| | | Map<String, BigDecimal> operationDemandedQuantityMap = |
| | | buildOperationDemandedQuantityMap(orderBomStructureList, rootProductModelId); |
| | | Map<Long, String> operationNameMap = technologyOperationMapper.selectBatchIds( |
| | | // 遍历处理数据并组装结果 |
| | | // 遍历处理数据并组装结果 |
| | | routingOperations.stream() |
| | | .map(TechnologyRoutingOperation::getTechnologyOperationId) |
| | | .filter(Objects::nonNull) |
| | |
| | | productionOrderBomMapper.insert(orderBom); |
| | | |
| | | Map<Long, Long> idMap = new HashMap<>(); |
| | | BigDecimal lastProcessDemandedQuantity = orderQuantity; |
| | | for (TechnologyBomStructure source : structureList) { |
| | | // 子节点 parentId 需要映射成新快照节点 id,才能保留原始 BOM 层级。 |
| | | ProductionBomStructure target = new ProductionBomStructure(); |
| | |
| | | target.setProductModelId(source.getProductModelId()); |
| | | target.setTechnologyOperationId(source.getOperationId()); |
| | | target.setUnitQuantity(source.getUnitQuantity()); |
| | | target.setDemandedQuantity(source.getUnitQuantity().multiply(orderQuantity)); |
| | | target.setDemandedQuantity(lastProcessDemandedQuantity.multiply(source.getUnitQuantity())); |
| | | target.setUnit(source.getUnit()); |
| | | productionBomStructureMapper.insert(target); |
| | | idMap.put(source.getId(), target.getId()); |
| | | lastProcessDemandedQuantity = target.getDemandedQuantity(); |
| | | } |
| | | return orderBom; |
| | | } |
| | |
| | | private void clearProductionSnapshot(Long productionOrderId) { |
| | | // 清理订单已生成的工艺与BOM快照数据 |
| | | boolean hasPickRecord = productionOrderPickRecordMapper.selectCount( |
| | | // 查询并准备业务数据 |
| | | // 查询并准备业务数据 |
| | | Wrappers.<ProductionOrderPickRecord>lambdaQuery() |
| | | .eq(ProductionOrderPickRecord::getProductionOrderId, productionOrderId)) > 0; |
| | | // 参数与前置条件校验 |
| | |
| | | List<Long> taskIds = productionOperationTaskMapper.selectList( |
| | | Wrappers.<ProductionOperationTask>lambdaQuery() |
| | | .eq(ProductionOperationTask::getProductionOrderId, productionOrderId)) |
| | | // 遍历处理数据并组装结果 |
| | | // 遍历处理数据并组装结果 |
| | | .stream().map(ProductionOperationTask::getId).collect(Collectors.toList()); |
| | | if (!taskIds.isEmpty()) { |
| | | // 已有报工记录说明订单已开工,此时不允许再重建快照。 |
| | |
| | | new Page<ProductionOperationTaskVo>(1, -1), taskQuery); |
| | | List<ProductionOperationTaskVo> workOrderList = workOrderPage == null || workOrderPage.getRecords() == null |
| | | ? Collections.emptyList() |
| | | // 遍历处理数据并组装结果 |
| | | // 遍历处理数据并组装结果 |
| | | : workOrderPage.getRecords().stream() |
| | | .filter(Objects::nonNull) |
| | | .sorted(Comparator.comparing(ProductionOperationTaskVo::getId, Comparator.nullsLast(Comparator.naturalOrder()))) |
| | |
| | | .collect(Collectors.toList()); |
| | | List<ProductionProductMain> reportMainList = workOrderIdList.isEmpty() |
| | | ? Collections.emptyList() |
| | | // 查询并准备业务数据 |
| | | // 查询并准备业务数据 |
| | | : productionProductMainMapper.selectList( |
| | | Wrappers.<ProductionProductMain>lambdaQuery() |
| | | .in(ProductionProductMain::getProductionOperationTaskId, workOrderIdList) |
| | |
| | | return Collections.emptyList(); |
| | | } |
| | | |
| | | List<ProductionBomStructureVo> bomStructureList = productionBomStructureMapper.pickByBomId(orderBom.getId()); |
| | | // 查询完整的BOM结构(包括根节点),用于计算层级需求数量 |
| | | List<ProductionBomStructureVo> bomStructureList = productionBomStructureMapper.listByBomId(orderBom.getId()); |
| | | if (bomStructureList == null || bomStructureList.isEmpty()) { |
| | | return Collections.emptyList(); |
| | | } |
| | | |
| | | // 查询生产订单获取订单数量 |
| | | ProductionOrder productionOrder = productionOrderMapper.selectById(productionOrderId); |
| | | BigDecimal orderQuantity = productionOrder != null ? defaultDecimal(productionOrder.getQuantity()) : BigDecimal.ZERO; |
| | | |
| | | // 构建树形结构并计算层级需求数量 |
| | | Map<Long, ProductionBomStructureVo> structureByIdMap = bomStructureList.stream() |
| | | .filter(s -> s != null && s.getId() != null) |
| | | .collect(Collectors.toMap(ProductionBomStructureVo::getId, s -> s)); |
| | | |
| | | // 按层级计算需求数量:子级需求数量 = 父级需求数量 × 子级单位产出所需数量 |
| | | for (ProductionBomStructureVo structure : bomStructureList) { |
| | | if (structure == null) continue; |
| | | |
| | | if (structure.getParentId() == null || structure.getParentId() == 0) { |
| | | // 根节点:需求数量 = 订单数量 |
| | | structure.setDemandedQuantity(orderQuantity); |
| | | } else { |
| | | // 子节点:需求数量 = 父级需求数量 × 子级单位产出所需数量 |
| | | ProductionBomStructureVo parent = structureByIdMap.get(structure.getParentId()); |
| | | if (parent != null) { |
| | | BigDecimal parentDemandedQty = defaultDecimal(parent.getDemandedQuantity()); |
| | | BigDecimal unitQuantity = defaultDecimal(structure.getUnitQuantity()); |
| | | structure.setDemandedQuantity(parentDemandedQty.multiply(unitQuantity)); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 过滤出非根节点(实际领料项) |
| | | List<ProductionBomStructureVo> childStructureList = bomStructureList.stream() |
| | | .filter(s -> s != null && s.getParentId() != null && s.getParentId() != 0) |
| | | .collect(Collectors.toList()); |
| | | |
| | | // 遍历处理数据并组装结果 |
| | | List<Long> productModelIds = bomStructureList.stream() |
| | | List<Long> productModelIds = childStructureList.stream() |
| | | .map(ProductionBomStructureVo::getProductModelId) |
| | | .filter(Objects::nonNull) |
| | | .distinct() |
| | |
| | | if (!productModelIds.isEmpty()) { |
| | | List<StockInventory> stockList = stockInventoryMapper.selectList( |
| | | Wrappers.<StockInventory>lambdaQuery() |
| | | .in(StockInventory::getProductModelId, productModelIds)); |
| | | .in(StockInventory::getProductModelId, productModelIds) |
| | | .gt(StockInventory::getQualitity, BigDecimal.ZERO)); |
| | | for (StockInventory stockItem : stockList) { |
| | | if (stockItem == null || stockItem.getProductModelId() == null) { |
| | | continue; |
| | |
| | | } |
| | | |
| | | Map<String, ProductionOrderPickVo> mergedPickMap = new LinkedHashMap<>(); |
| | | for (ProductionBomStructureVo structure : bomStructureList) { |
| | | for (ProductionBomStructureVo structure : childStructureList) { |
| | | if (structure == null || structure.getProductModelId() == null) { |
| | | continue; |
| | | } |