From a829dd34332bbc10c6b42ef86635ed48e34c6207 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期二, 03 十一月 2026 10:21:50 +0800
Subject: [PATCH] fix: 原料领料批号按可用库存过滤并实现先进先出
---
src/main/java/com/ruoyi/production/service/impl/ProductionOrderPickServiceImpl.java | 76 +++++++++++++++++++++++++++++++++++--
1 files changed, 71 insertions(+), 5 deletions(-)
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionOrderPickServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionOrderPickServiceImpl.java
index 598ae6b..01187b1 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionOrderPickServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionOrderPickServiceImpl.java
@@ -31,6 +31,7 @@
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;
@@ -430,7 +431,7 @@
BigDecimal totalReturnQty = oldReturnQty.add(currentReturnQty);
if (currentReturnQty.compareTo(BigDecimal.ZERO) > 0) {
String returnBatchNo = resolveInventoryBatchNoFromStored(oldPick.getBatchNo());
- addInventory(oldPick.getId(), oldPick.getProductModelId(), returnBatchNo, currentReturnQty, FEED_RETURN_IN_RECORD_TYPE);
+ addInventoryRecordOnly(oldPick.getId(), oldPick.getProductModelId(), returnBatchNo, currentReturnQty, FEED_RETURN_IN_RECORD_TYPE);
}
BigDecimal actualQty = defaultDecimal(oldPick.getQuantity())
@@ -599,13 +600,53 @@
batchNoList = Collections.singletonList(null);
}
+ // 鍏堟煡璇㈠悇鎵规搴撳瓨璁板綍锛屽苟鎸夐娆″叆搴撴椂闂村崌搴忔帓鍒楋紙鍏堣繘鍏堝嚭锛夛紝
+ // 涓嶄緷璧栧墠绔嬀閫夐『搴忥紝閬垮厤浜哄伐澶氶�夋椂鎵i敊鎵规銆�
+ 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())
@@ -737,6 +778,31 @@
}
}
+ private void addInventoryRecordOnly(Long recordId,
+ Long productModelId,
+ String batchNo,
+ BigDecimal quantity,
+ String stockInRecordType) {
+ // 浠呰褰曞叆搴撶敵璇凤紝涓嶅仛瀹℃牳閫氳繃銆�
+ BigDecimal addQuantity = defaultDecimal(quantity);
+ if (addQuantity.compareTo(BigDecimal.ZERO) <= 0) {
+ return;
+ }
+ try {
+ StockInventoryDto stockInventoryDto = new StockInventoryDto();
+ stockInventoryDto.setProductModelId(productModelId);
+ stockInventoryDto.setBatchNo(batchNo);
+ stockInventoryDto.setQualitity(addQuantity);
+ stockInventoryDto.setRecordType(stockInRecordType);
+ stockInventoryDto.setRecordId(recordId == null ? 0L : recordId);
+ stockInventoryService.addStockInRecordOnly(stockInventoryDto);
+ } catch (ServiceException ex) {
+ throw ex;
+ } catch (Exception ex) {
+ throw new ServiceException("閫�鏂欏叆搴撹褰曚繚瀛樺け璐ワ細" + ex.getMessage());
+ }
+ }
+
private List<ProductionOrderPickDto> resolvePickItems(ProductionOrderPickDto dto) {
// 瑙f瀽鏂板鍦烘櫙鐨勯鏂欐槑缁嗛泦鍚堛��
if (dto == null) {
--
Gitblit v1.9.3