| | |
| | | import com.ruoyi.production.service.ProductionOrderService; |
| | | import com.ruoyi.sales.mapper.SalesLedgerMapper; |
| | | import com.ruoyi.sales.mapper.SalesLedgerProductMapper; |
| | | import com.ruoyi.stock.mapper.StockInRecordMapper; |
| | | import com.ruoyi.stock.mapper.StockInventoryMapper; |
| | | import com.ruoyi.stock.pojo.StockInRecord; |
| | | import com.ruoyi.stock.pojo.StockInventory; |
| | | import com.ruoyi.technology.mapper.*; |
| | | import com.ruoyi.technology.pojo.*; |
| | |
| | | private final QualityInspectFileMapper qualityInspectFileMapper; |
| | | private final ProductionPlanMapper productionPlanMapper; |
| | | private final StockInventoryMapper stockInventoryMapper; |
| | | private final StockInRecordMapper stockInRecordMapper; |
| | | private final StorageAttachmentMapper storageAttachmentMapper; |
| | | private final StorageBlobMapper storageBlobMapper; |
| | | private final SalesLedgerMapper salesLedgerMapper; |
| | |
| | | if (productModelIds.size() > 1) { |
| | | throw new ServiceException("所选生产计划必须属于同一产品规格"); |
| | | } |
| | | if (productionPlans.stream().anyMatch(item -> item.getStatus() != null && item.getStatus() == 2)) { |
| | | throw new ServiceException("所选生产计划已下发"); |
| | | } |
| | | ProductionPlan firstPlan = mainPlan; |
| | | if (productionOrder.getProductModelId() == null) { |
| | | productionOrder.setProductModelId(firstPlan.getProductModelId()); |
| | |
| | | List<StockInventory> stockList = stockInventoryMapper.selectList( |
| | | Wrappers.<StockInventory>lambdaQuery() |
| | | .in(StockInventory::getProductModelId, productModelIds)); |
| | | // 各批次首次入库时间,用于先进先出排序(历史数据导入时库存行的 create_time 可能相同) |
| | | Map<Long, Map<String, LocalDateTime>> firstInTimeMap = new HashMap<>(); |
| | | List<StockInRecord> stockInRecords = stockInRecordMapper.selectList( |
| | | Wrappers.<StockInRecord>lambdaQuery() |
| | | .in(StockInRecord::getProductModelId, productModelIds) |
| | | .isNotNull(StockInRecord::getBatchNo)); |
| | | for (StockInRecord stockInRecord : stockInRecords) { |
| | | if (stockInRecord == null || stockInRecord.getProductModelId() == null |
| | | || stockInRecord.getBatchNo() == null || stockInRecord.getCreateTime() == null) { |
| | | continue; |
| | | } |
| | | firstInTimeMap.computeIfAbsent(stockInRecord.getProductModelId(), key -> new HashMap<>()) |
| | | .merge(stockInRecord.getBatchNo(), stockInRecord.getCreateTime(), |
| | | (a, b) -> a.isBefore(b) ? a : b); |
| | | } |
| | | // 库存行按所属批次的首次入库时间升序,保证领料下拉框是先进先出顺序 |
| | | stockList.sort(Comparator |
| | | .comparing((StockInventory stockItem) -> { |
| | | Map<String, LocalDateTime> modelBatchTimeMap = firstInTimeMap.get(stockItem.getProductModelId()); |
| | | return modelBatchTimeMap == null ? null : modelBatchTimeMap.get(stockItem.getBatchNo()); |
| | | }, Comparator.nullsLast(Comparator.naturalOrder())) |
| | | .thenComparing(StockInventory::getCreateTime, Comparator.nullsLast(Comparator.naturalOrder())) |
| | | .thenComparing(stockItem -> stockItem.getId() == null ? Long.MAX_VALUE : stockItem.getId())); |
| | | for (StockInventory stockItem : stockList) { |
| | | if (stockItem == null || stockItem.getProductModelId() == null) { |
| | | continue; |
| | | } |
| | | Long productModelId = stockItem.getProductModelId(); |
| | | stockQuantityMap.merge(productModelId, defaultDecimal(stockItem.getQualitity()), BigDecimal::add); |
| | | // 已无可用库存(数量扣完或被锁定)的批次不再带到领料下拉框 |
| | | BigDecimal availableQuantity = defaultDecimal(stockItem.getQualitity()) |
| | | .subtract(defaultDecimal(stockItem.getLockedQuantity())); |
| | | if (availableQuantity.compareTo(BigDecimal.ZERO) <= 0) { |
| | | continue; |
| | | } |
| | | String batchNo = stockItem.getBatchNo(); |
| | | if (batchNo != null && !batchNo.trim().isEmpty()) { |
| | | stockBatchNoMap.computeIfAbsent(productModelId, key -> new LinkedHashSet<>()).add(batchNo); |