| | |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | import java.util.*; |
| | | import java.util.function.Function; |
| | | import java.util.stream.Collectors; |
| | |
| | | batchNoList = Collections.singletonList(null); |
| | | } |
| | | |
| | | // 先查询各批次库存记录,并按首次入库时间升序排列(先进先出), |
| | | // 不依赖前端勾选顺序,避免人工多选时扣错批次。 |
| | | Map<String, StockInventory> inventoryMap = new LinkedHashMap<>(); |
| | | for (String currentBatchNo : batchNoList) { |
| | | inventoryMap.put(currentBatchNo, |
| | | stockInventoryMapper.selectOne(buildStockWrapper(productModelId, currentBatchNo))); |
| | | } |
| | | // 首次入库时间以入库记录为准:历史数据批量导入时 stock_inventory.create_time 可能相同, |
| | | // 不能准确反映批次先后。 |
| | | Map<String, LocalDateTime> firstInTimeMap = new HashMap<>(); |
| | | List<String> nonNullBatchNoList = batchNoList.stream() |
| | | .filter(StringUtils::isNotEmpty) |
| | | .collect(Collectors.toList()); |
| | | if (!nonNullBatchNoList.isEmpty()) { |
| | | List<StockInRecord> stockInRecords = stockInRecordService.list( |
| | | Wrappers.<StockInRecord>lambdaQuery() |
| | | .eq(StockInRecord::getProductModelId, productModelId) |
| | | .in(StockInRecord::getBatchNo, nonNullBatchNoList)); |
| | | for (StockInRecord stockInRecord : stockInRecords) { |
| | | if (stockInRecord == null || stockInRecord.getBatchNo() == null |
| | | || stockInRecord.getCreateTime() == null) { |
| | | continue; |
| | | } |
| | | firstInTimeMap.merge(stockInRecord.getBatchNo(), stockInRecord.getCreateTime(), |
| | | (a, b) -> a.isBefore(b) ? a : b); |
| | | } |
| | | } |
| | | List<String> fifoBatchNoList = inventoryMap.entrySet().stream() |
| | | .sorted(Comparator |
| | | .comparing((Map.Entry<String, StockInventory> entry) -> firstInTimeMap.get(entry.getKey()), |
| | | Comparator.nullsLast(Comparator.naturalOrder())) |
| | | .thenComparing(entry -> entry.getValue() == null ? null : entry.getValue().getCreateTime(), |
| | | Comparator.nullsLast(Comparator.naturalOrder())) |
| | | .thenComparing(entry -> { |
| | | StockInventory inventory = entry.getValue(); |
| | | return inventory == null || inventory.getId() == null |
| | | ? Long.MAX_VALUE : inventory.getId(); |
| | | })) |
| | | .map(Map.Entry::getKey) |
| | | .collect(Collectors.toList()); |
| | | |
| | | // 先计算各批次可用量,避免边扣边算导致判断不一致。 |
| | | Map<String, BigDecimal> availableQuantityMap = new LinkedHashMap<>(); |
| | | BigDecimal totalAvailableQuantity = BigDecimal.ZERO; |
| | | // 遍历批次,计算每个批次可用库存。 |
| | | for (String currentBatchNo : batchNoList) { |
| | | // 查询当前规格+批次的库存记录。 |
| | | StockInventory stockInventory = stockInventoryMapper.selectOne(buildStockWrapper(productModelId, currentBatchNo)); |
| | | // 按先进先出顺序计算每个批次可用库存。 |
| | | for (String currentBatchNo : fifoBatchNoList) { |
| | | StockInventory stockInventory = inventoryMap.get(currentBatchNo); |
| | | BigDecimal availableQuantity = BigDecimal.ZERO; |
| | | if (stockInventory != null) { |
| | | availableQuantity = defaultDecimal(stockInventory.getQualitity()) |