From afdf7cc772baee20d5afc94d4ec3e3d691c3ed12 Mon Sep 17 00:00:00 2001
From: huminmin <mac@MacBook-Pro.local>
Date: 星期五, 24 四月 2026 14:15:55 +0800
Subject: [PATCH] 库存管理按照原材料和成品来区分
---
src/main/java/com/ruoyi/stock/service/StockInventoryService.java | 2
src/main/java/com/ruoyi/stock/dto/StockInventoryDto.java | 39 ++++
src/main/java/com/ruoyi/stock/execl/StockInventoryExportData.java | 24 +
src/main/java/com/ruoyi/stock/mapper/StockInventoryMapper.java | 1
src/main/java/com/ruoyi/stock/service/impl/StockUninventoryServiceImpl.java | 105 ++++++++++-
src/main/resources/mapper/stock/StockInventoryMapper.xml | 201 ++++++++++++++++++++-
src/main/java/com/ruoyi/stock/controller/StockInventoryController.java | 9 +
src/main/java/com/ruoyi/stock/pojo/StockUninventory.java | 2
src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java | 139 +++++++++++----
9 files changed, 450 insertions(+), 72 deletions(-)
diff --git a/src/main/java/com/ruoyi/stock/controller/StockInventoryController.java b/src/main/java/com/ruoyi/stock/controller/StockInventoryController.java
index 27ad046..9617d46 100644
--- a/src/main/java/com/ruoyi/stock/controller/StockInventoryController.java
+++ b/src/main/java/com/ruoyi/stock/controller/StockInventoryController.java
@@ -13,6 +13,7 @@
import com.ruoyi.stock.service.StockInventoryService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
+import io.swagger.v3.oas.annotations.Operation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
@@ -46,6 +47,14 @@
return R.ok(stockInventoryDtoIPage);
}
+
+ @GetMapping("/pageListCombinedStockInventory")
+ @Operation(summary = "鍒嗛〉鏌ヨ鑱斿悎搴撳瓨鍒楄〃")
+ public R pageListCombinedStockInventory(Page page, StockInventoryDto stockInventoryDto) {
+ IPage<StockInventoryDto> stockInventoryDtoIPage = stockInventoryService.pageListCombinedStockInventory(page, stockInventoryDto);
+ return R.ok(stockInventoryDtoIPage);
+ }
+
@PostMapping("/addstockInventory")
@PreAuthorize("@ss.hasPermi('add:stockInventory')")
@ApiOperation("鏂板搴撳瓨")
diff --git a/src/main/java/com/ruoyi/stock/dto/StockInventoryDto.java b/src/main/java/com/ruoyi/stock/dto/StockInventoryDto.java
index ec8f8b7..27ea5f8 100644
--- a/src/main/java/com/ruoyi/stock/dto/StockInventoryDto.java
+++ b/src/main/java/com/ruoyi/stock/dto/StockInventoryDto.java
@@ -2,6 +2,7 @@
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.stock.pojo.StockInventory;
+import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
@@ -43,4 +44,40 @@
//浜у搧id
private Long productId;
-}
+
+ @Schema(description = "椤堕儴鐖朵骇鍝乮d")
+ private Long topParentProductId;
+
+ @Schema(description = "搴撳瓨绫诲瀷锛歲ualified(鍚堟牸)銆乽nqualified(涓嶅悎鏍�)")
+ private String stockType;
+
+ @Schema(description = "鍚堟牸搴撳瓨鏁伴噺")
+ private BigDecimal qualifiedQuantity;
+
+ @Schema(description = "涓嶅悎鏍煎簱瀛樻暟閲�")
+ private BigDecimal unQualifiedQuantity;
+
+ @Schema(description = "鍚堟牸搴撳瓨鍐荤粨鏁伴噺")
+ private BigDecimal qualifiedLockedQuantity;
+
+ @Schema(description = "涓嶅悎鏍煎簱瀛樺喕缁撴暟閲�")
+ private BigDecimal unQualifiedLockedQuantity;
+
+ @Schema(description = "鍚堟牸搴撳瓨鏈喕缁撴暟閲�")
+ private BigDecimal qualifiedUnLockedQuantity;
+
+ @Schema(description = "涓嶅悎鏍煎簱瀛樻湭鍐荤粨鏁伴噺")
+ private BigDecimal unQualifiedUnLockedQuantity;
+
+ @Schema(description = "鍚堟牸搴撳瓨ID")
+ private Long qualifiedId;
+
+ @Schema(description = "涓嶅悎鏍煎簱瀛業D")
+ private Long unQualifiedId;
+
+ @Schema(description = "鍚堟牸搴撳瓨鎵瑰彿")
+ private String qualifiedBatchNo;
+
+ @Schema(description = "涓嶅悎鏍煎簱瀛樻壒鍙�")
+ private String unQualifiedBatchNo;
+}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/stock/execl/StockInventoryExportData.java b/src/main/java/com/ruoyi/stock/execl/StockInventoryExportData.java
index b8b2bc4..93249c1 100644
--- a/src/main/java/com/ruoyi/stock/execl/StockInventoryExportData.java
+++ b/src/main/java/com/ruoyi/stock/execl/StockInventoryExportData.java
@@ -7,9 +7,6 @@
@Data
public class StockInventoryExportData {
-
-
-
@Excel(name = "浜у搧鍚嶇О")
private String productName;
@@ -22,14 +19,26 @@
@Excel(name = "鏂欏彿")
private String materialCode;
- @Excel(name = "搴撳瓨鏁伴噺")
- private BigDecimal qualitity;
+ @Excel(name = "鍚堟牸搴撳瓨鎵瑰彿")
+ private String qualifiedBatchNo;
+
+ @Excel(name = "涓嶅悎鏍煎簱瀛樻壒鍙�")
+ private String unQualifiedBatchNo;
+
+ @Excel(name = "鍚堟牸搴撳瓨鏁伴噺")
+ private BigDecimal qualifiedQuantity;
+
+ @Excel(name = "涓嶅悎鏍煎簱瀛樻暟閲�")
+ private BigDecimal unQualifiedQuantity;
@Excel(name = "棰勮鏁伴噺")
private BigDecimal warnNum;
- @Excel(name = "鍐荤粨鏁伴噺")
- private BigDecimal lockedQuantity;
+ @Excel(name = "鍚堟牸鍐荤粨鏁伴噺")
+ private BigDecimal qualifiedLockedQuantity;
+
+ @Excel(name = "涓嶅悎鏍煎喕缁撴暟閲�")
+ private BigDecimal unQualifiedLockedQuantity;
@Excel(name = "澶囨敞")
private String remark;
@@ -39,4 +48,5 @@
// @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
// private LocalDateTime updateTime;
+
}
diff --git a/src/main/java/com/ruoyi/stock/mapper/StockInventoryMapper.java b/src/main/java/com/ruoyi/stock/mapper/StockInventoryMapper.java
index 21fffd4..f5ed7d9 100644
--- a/src/main/java/com/ruoyi/stock/mapper/StockInventoryMapper.java
+++ b/src/main/java/com/ruoyi/stock/mapper/StockInventoryMapper.java
@@ -29,6 +29,7 @@
IPage<StockInventoryDto> pagestockInventory(Page page, @Param("ew") StockInventoryDto stockInventoryDto);
+ IPage<StockInventoryDto> pageListCombinedStockInventory(Page page, @Param("ew") StockInventoryDto stockInventoryDto);
int updateAddStockInventory(@Param("ew") StockInventoryDto stockInventoryDto);
diff --git a/src/main/java/com/ruoyi/stock/pojo/StockUninventory.java b/src/main/java/com/ruoyi/stock/pojo/StockUninventory.java
index 6ed47de..a57f0c4 100644
--- a/src/main/java/com/ruoyi/stock/pojo/StockUninventory.java
+++ b/src/main/java/com/ruoyi/stock/pojo/StockUninventory.java
@@ -59,4 +59,6 @@
@ApiModelProperty("琚鍗曢攣瀹氭暟閲�")
private BigDecimal lockedQuantity;
+ @ApiModelProperty("鎵瑰彿")
+ private String batchNo;
}
diff --git a/src/main/java/com/ruoyi/stock/service/StockInventoryService.java b/src/main/java/com/ruoyi/stock/service/StockInventoryService.java
index f7b1b17..1b5b479 100644
--- a/src/main/java/com/ruoyi/stock/service/StockInventoryService.java
+++ b/src/main/java/com/ruoyi/stock/service/StockInventoryService.java
@@ -25,6 +25,8 @@
IPage<StockInventoryDto> pagestockInventory(Page page, StockInventoryDto stockInventoryDto);
+ IPage<StockInventoryDto> pageListCombinedStockInventory(Page page, StockInventoryDto stockInventoryDto);
+
Boolean addstockInventory(StockInventoryDto stockInventoryDto);
Boolean subtractStockInventory(StockInventoryDto stockInventoryDto);
diff --git a/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java b/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
index 72fc3fa..98ad6ca 100644
--- a/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
+++ b/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
@@ -1,5 +1,6 @@
package com.ruoyi.stock.service.impl;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -13,6 +14,7 @@
import com.ruoyi.basic.pojo.Product;
import com.ruoyi.basic.pojo.ProductModel;
import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum;
+import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.security.LoginUser;
@@ -22,6 +24,7 @@
import com.ruoyi.stock.dto.StockInRecordDto;
import com.ruoyi.stock.dto.StockInventoryDto;
import com.ruoyi.stock.dto.StockOutRecordDto;
+import com.ruoyi.stock.dto.StockUninventoryDto;
import com.ruoyi.stock.execl.StockInventoryExportData;
import com.ruoyi.stock.mapper.StockInventoryMapper;
import com.ruoyi.stock.pojo.StockInRecord;
@@ -29,6 +32,7 @@
import com.ruoyi.stock.service.StockInRecordService;
import com.ruoyi.stock.service.StockInventoryService;
import com.ruoyi.stock.service.StockOutRecordService;
+import com.ruoyi.stock.service.StockUninventoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -39,9 +43,7 @@
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
+import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -70,10 +72,17 @@
private ProductModelMapper productModelMapper;
@Autowired
private ProductMapper productMapper;
+ @Autowired
+ private StockUninventoryService stockUninventoryService;
@Override
public IPage<StockInventoryDto> pagestockInventory(Page page, StockInventoryDto stockInventoryDto) {
return stockInventoryMapper.pagestockInventory(page, stockInventoryDto);
+ }
+
+ @Override
+ public IPage<StockInventoryDto> pageListCombinedStockInventory(Page page, StockInventoryDto stockInventoryDto) {
+ return stockInventoryMapper.pageListCombinedStockInventory(page, stockInventoryDto);
}
//鍏ュ簱璋冪敤-娣诲姞鍏ュ簱璁板綍
@@ -106,7 +115,8 @@
String seqStr = String.format("%03d", newSeq);
// 缁勮batchNo
- batchNo = stockInventoryDto.getMaterialCode() + stockInventoryDto.getProductModelName() + "P" + monthFlag + seqStr;
+ ProductModel productModel = productModelMapper.selectById(stockInventoryDto.getProductModelId());
+ batchNo = stockInventoryDto.getMaterialCode() + productModel.getModel() + "P" + monthFlag + seqStr;
stockInRecordDto.setBatchNo(batchNo);
} else {
stockInRecordDto.setBatchNo(stockInventoryDto.getBatchNo());
@@ -171,11 +181,17 @@
*/
public void updateOrCreateStockInventory(StockInRecord stockInRecord) {
// 鍏堟煡璇㈠簱瀛樿〃涓殑浜у搧鏄惁瀛樺湪
- StockInventory oldStockInventory = stockInventoryMapper.selectOne(
- new QueryWrapper<StockInventory>().lambda()
- .eq(StockInventory::getProductModelId, stockInRecord.getProductModelId())
- .eq(StockInventory::getBatchNo, stockInRecord.getBatchNo())
- );
+ LambdaQueryWrapper<StockInventory> queryWrapper = new QueryWrapper<StockInventory>().lambda()
+ .eq(StockInventory::getProductModelId, stockInRecord.getProductModelId());
+
+ // 鏍规嵁 batchNo 鏄惁涓虹┖鏋勫缓涓嶅悓鐨勬煡璇㈡潯浠�
+ if (stockInRecord.getBatchNo() != null && !stockInRecord.getBatchNo().isEmpty()) {
+ queryWrapper.eq(StockInventory::getBatchNo, stockInRecord.getBatchNo());
+ } else {
+ queryWrapper.isNull(StockInventory::getBatchNo);
+ }
+
+ StockInventory oldStockInventory = stockInventoryMapper.selectOne(queryWrapper);
if (ObjectUtils.isEmpty(oldStockInventory)) {
// 涓嶅瓨鍦ㄥ垯鏂板
@@ -192,8 +208,16 @@
// 瀛樺湪鍒欐洿鏂�
LambdaUpdateWrapper<StockInventory> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper
- .eq(StockInventory::getProductModelId, stockInRecord.getProductModelId())
- .eq(StockInventory::getBatchNo, stockInRecord.getBatchNo())
+ .eq(StockInventory::getProductModelId, stockInRecord.getProductModelId());
+
+ // 鏍规嵁 batchNo 鏄惁涓虹┖鏋勫缓涓嶅悓鐨勬洿鏂版潯浠�
+ if (stockInRecord.getBatchNo() != null && !stockInRecord.getBatchNo().isEmpty()) {
+ updateWrapper.eq(StockInventory::getBatchNo, stockInRecord.getBatchNo());
+ } else {
+ updateWrapper.isNull(StockInventory::getBatchNo);
+ }
+
+ updateWrapper
.setSql(stockInRecord.getStockInNum() != null,
"qualitity = qualitity + " + stockInRecord.getStockInNum())
.setSql(true, "version = version + 1")
@@ -307,59 +331,100 @@
@Override
public R importStockInventory(MultipartFile file) {
try {
- // 鏌ヨ鎵�鏈夌殑浜у搧
+ // 鏌ヨ鎵�鏈夌殑浜у搧骞舵瀯寤烘槧灏勶紝鎻愰珮鏌ユ壘鏁堢巼
List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductMapper.selectProduct();
+ Map<String, SalesLedgerProduct> productMap = new HashMap<>();
+ for (SalesLedgerProduct product : salesLedgerProducts) {
+ // 浣跨敤浜у搧绫诲埆鍜岃鏍煎瀷鍙蜂綔涓洪敭
+ String key = product.getProductCategory() + "|" + product.getSpecificationModel();
+ productMap.put(key, product);
+ }
ExcelUtil<StockInventoryExportData> util = new ExcelUtil<StockInventoryExportData>(StockInventoryExportData.class);
List<StockInventoryExportData> list = util.importExcel(file.getInputStream());
// 璁板綍鏈壘鍒板尮閰嶉」鐨勬暟鎹�
List<String> unmatchedRecords = new ArrayList<>();
+ // 璁板綍澶勭悊缁撴灉
+ int successCount = 0;
- list.forEach(dto -> {
- boolean matched = false;
- for (SalesLedgerProduct item : salesLedgerProducts) {
- if (item.getProductCategory().equals(dto.getProductName()) &&
- item.getSpecificationModel().equals(dto.getModel())) {
+ for (StockInventoryExportData dto : list) {
+ // 鏋勫缓鏌ユ壘閿�
+ String key = dto.getProductName() + "|" + dto.getModel();
+ SalesLedgerProduct matchedProduct = productMap.get(key);
+
+ if (matchedProduct != null) {
+ // 澶勭悊鍚堟牸搴撳瓨
+ if (dto.getQualifiedQuantity() != null && dto.getQualifiedQuantity().compareTo(BigDecimal.ZERO) > 0) {
StockInventoryDto stockInventoryDto = new StockInventoryDto();
stockInventoryDto.setRecordId(0L);
stockInventoryDto.setRecordType(StockInQualifiedRecordTypeEnum.CUSTOMIZATION_STOCK_IN.getCode());
- stockInventoryDto.setQualitity(dto.getQualitity());
+ stockInventoryDto.setQualitity(dto.getQualifiedQuantity());
stockInventoryDto.setRemark(dto.getRemark());
stockInventoryDto.setWarnNum(dto.getWarnNum());
- if (ObjectUtils.isNotEmpty(dto.getLockedQuantity()) && dto.getLockedQuantity().compareTo(dto.getQualitity()) > 0) {
- throw new RuntimeException("鍐荤粨鏁伴噺涓嶈兘瓒呰繃鏈瀵煎叆鐨勫簱瀛樻暟閲�");
+ stockInventoryDto.setBatchNo(dto.getQualifiedBatchNo());
+
+ // 楠岃瘉鍚堟牸鍐荤粨鏁伴噺
+ if (ObjectUtils.isNotEmpty(dto.getQualifiedLockedQuantity())) {
+ if (dto.getQualifiedLockedQuantity().compareTo(dto.getQualifiedQuantity()) > 0) {
+ throw new RuntimeException("鍚堟牸鍐荤粨鏁伴噺涓嶈兘瓒呰繃鏈瀵煎叆鐨勫悎鏍煎簱瀛樻暟閲�");
+ }
+ stockInventoryDto.setLockedQuantity(dto.getQualifiedLockedQuantity());
+ } else {
+ stockInventoryDto.setLockedQuantity(BigDecimal.ZERO);
}
- stockInventoryDto.setLockedQuantity(dto.getLockedQuantity());
- stockInventoryDto.setProductModelId(item.getProductModelId());
+
+ stockInventoryDto.setProductModelId(matchedProduct.getProductModelId());
this.addstockInventory(stockInventoryDto);
- matched = true;
- break; // 鎵惧埌鍖归厤椤瑰悗璺冲嚭寰幆
+ successCount++;
}
+
+ // 澶勭悊涓嶅悎鏍煎簱瀛�
+ if (dto.getUnQualifiedQuantity() != null && dto.getUnQualifiedQuantity().compareTo(BigDecimal.ZERO) > 0) {
+ StockUninventoryDto stockUninventoryDto = new StockUninventoryDto();
+ stockUninventoryDto.setRecordId(0L);
+ stockUninventoryDto.setRecordType(StockInUnQualifiedRecordTypeEnum.CUSTOMIZATION_UNSTOCK_IN.getCode());
+ stockUninventoryDto.setQualitity(dto.getUnQualifiedQuantity());
+ stockUninventoryDto.setRemark(dto.getRemark());
+ stockUninventoryDto.setBatchNo(dto.getUnQualifiedBatchNo());
+
+ // 楠岃瘉涓嶅悎鏍煎喕缁撴暟閲�
+ if (ObjectUtils.isNotEmpty(dto.getUnQualifiedLockedQuantity())) {
+ if (dto.getUnQualifiedLockedQuantity().compareTo(dto.getUnQualifiedQuantity()) > 0) {
+ throw new RuntimeException("涓嶅悎鏍煎喕缁撴暟閲忎笉鑳借秴杩囨湰娆″鍏ョ殑涓嶅悎鏍煎簱瀛樻暟閲�");
+ }
+ stockUninventoryDto.setLockedQuantity(dto.getUnQualifiedLockedQuantity());
+ } else {
+ stockUninventoryDto.setLockedQuantity(BigDecimal.ZERO);
+ }
+
+ stockUninventoryDto.setProductModelId(matchedProduct.getProductModelId());
+ stockUninventoryService.addStockUninventory(stockUninventoryDto);
+ successCount++;
+ }
+ } else {
+ // 璁板綍鏈尮閰嶇殑浜у搧
+ String unmatchedRecord = "浜у搧鍚嶇О锛�" + dto.getProductName() + "锛屽瀷鍙凤細" + dto.getModel();
+ unmatchedRecords.add(unmatchedRecord);
}
- if (!matched) {
- // 璁板綍鏈尮閰嶇殑鏁版嵁
- String unmatchedInfo = String.format("浜у搧鍚嶇О锛�%s锛岃鏍煎瀷鍙凤細%s",
- dto.getProductName(), dto.getModel());
- unmatchedRecords.add(unmatchedInfo);
- }
- });
+ }
+
// 鏋勫缓杩斿洖淇℃伅
StringBuilder message = new StringBuilder();
if (!unmatchedRecords.isEmpty()) {
- message.append("浠ヤ笅浜у搧鏈壘鍒板尮閰嶉」锛歕n");
+ message.append("瀵煎叆鎴愬姛 " + successCount + " 鏉¤褰曪紝浠ヤ笅浜у搧鏈壘鍒板尮閰嶉」锛歕n");
for (String record : unmatchedRecords) {
message.append(record).append("\n");
}
- throw new RuntimeException(message.toString());
+ return R.ok(message.toString());
}
+
+ return R.ok("瀵煎叆鎴愬姛锛屽叡澶勭悊 " + successCount + " 鏉¤褰�");
} catch (Exception e) {
- e.printStackTrace();
+ log.error("瀵煎叆搴撳瓨澶辫触", e);
return R.fail("瀵煎叆澶辫触锛�" + e.getMessage());
}
- return R.ok("瀵煎叆鎴愬姛");
}
-
@Override
public void exportStockInventory(HttpServletResponse response, StockInventoryDto stockInventoryDto) {
@@ -402,4 +467,4 @@
stockInventory.setLockedQuantity(stockInventory.getLockedQuantity().subtract(stockInventoryDto.getLockedQuantity()));
return this.updateById(stockInventory);
}
-}
+}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/stock/service/impl/StockUninventoryServiceImpl.java b/src/main/java/com/ruoyi/stock/service/impl/StockUninventoryServiceImpl.java
index b315964..85f0e23 100644
--- a/src/main/java/com/ruoyi/stock/service/impl/StockUninventoryServiceImpl.java
+++ b/src/main/java/com/ruoyi/stock/service/impl/StockUninventoryServiceImpl.java
@@ -1,5 +1,6 @@
package com.ruoyi.stock.service.impl;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -8,6 +9,8 @@
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.approve.service.impl.ApproveProcessServiceImpl;
import com.ruoyi.approve.vo.ApproveProcessVO;
+import com.ruoyi.basic.mapper.ProductModelMapper;
+import com.ruoyi.basic.pojo.ProductModel;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.security.LoginUser;
@@ -18,6 +21,7 @@
import com.ruoyi.stock.execl.StockUnInventoryExportData;
import com.ruoyi.stock.mapper.StockUninventoryMapper;
import com.ruoyi.stock.pojo.StockInRecord;
+import com.ruoyi.stock.pojo.StockInventory;
import com.ruoyi.stock.pojo.StockUninventory;
import com.ruoyi.stock.service.StockInRecordService;
import com.ruoyi.stock.service.StockOutRecordService;
@@ -28,8 +32,11 @@
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* <p>
@@ -50,6 +57,8 @@
private StockInRecordService stockInRecordService;
@Autowired
private ApproveProcessServiceImpl approveProcessService;
+ @Autowired
+ private ProductModelMapper productModelMapper;
@Override
public IPage<StockUninventoryDto> pageStockUninventory(Page page, StockUninventoryDto stockUninventoryDto) {
@@ -59,6 +68,7 @@
@Override
@Transactional(rollbackFor = Exception.class)
public Integer addStockUninventory(StockUninventoryDto stockUninventoryDto) {
+ List<StockUninventory> stockUninventoryList = stockUninventoryMapper.selectList(null);
//鏂板鍏ュ簱璁板綍鍐嶆坊鍔犲簱瀛�
StockInRecordDto stockInRecordDto = new StockInRecordDto();
stockInRecordDto.setRecordId(stockUninventoryDto.getRecordId());
@@ -68,6 +78,26 @@
stockInRecordDto.setRemark(stockUninventoryDto.getRemark());
stockInRecordDto.setApproveStatus(0);
stockInRecordDto.setType("1");
+ if (stockUninventoryDto.getBatchNo() == null || stockUninventoryDto.getBatchNo().isEmpty()) {
+ String batchNo;
+ // 鑾峰彇褰撳墠鏈堜唤锛堜袱浣嶏級
+ LocalDate now = LocalDate.now();
+ String monthFlag = now.format(DateTimeFormatter.ofPattern("MM"));
+
+ // 鑾峰彇褰撳墠鏈堜唤鐨勬渶澶ф祦姘村彿
+ int maxSeq = getCurrentMonthMaxSeq(stockUninventoryDto, monthFlag, stockUninventoryList);
+
+ // 鏂版祦姘村彿 = 鏈�澶ф祦姘村彿 + 1
+ int newSeq = maxSeq + 1;
+ String seqStr = String.format("%03d", newSeq);
+
+ // 缁勮batchNo
+ ProductModel productModel = productModelMapper.selectById(stockUninventoryDto.getProductModelId());
+ batchNo = stockUninventoryDto.getMaterialCode() + productModel.getModel() + "P" + monthFlag + seqStr;
+ stockInRecordDto.setBatchNo(batchNo);
+ } else {
+ stockInRecordDto.setBatchNo(stockUninventoryDto.getBatchNo());
+ }
Long id = stockInRecordService.add(stockInRecordDto);
LoginUser loginUser = SecurityUtils.getLoginUser();
@@ -80,6 +110,33 @@
}
return 1;
+ }
+
+ /**
+ * 鏌ヨ褰撳墠鏈堜唤宸插瓨鍦ㄧ殑鏈�澶ф祦姘村彿
+ */
+ private static int getCurrentMonthMaxSeq(StockUninventoryDto dto, String monthFlag, List<StockUninventory> existingList) {
+ int maxSeq = 0;
+
+ String prefix = dto.getMaterialCode() + dto.getModel() + "P" + monthFlag;
+
+ // 姝e垯鍖归厤锛氬墠缂� + 3浣嶆暟瀛�
+ Pattern pattern = Pattern.compile(Pattern.quote(prefix) + "(\\d{3})");
+
+ for (StockUninventory item : existingList) {
+ String batchNo = item.getBatchNo();
+ if (batchNo == null) continue;
+
+ Matcher matcher = pattern.matcher(batchNo);
+ if (matcher.find()) {
+ int seq = Integer.parseInt(matcher.group(1));
+ if (seq > maxSeq) {
+ maxSeq = seq;
+ }
+ }
+ }
+
+ return maxSeq;
}
public void addApproveByPurchase(LoginUser loginUser, StockInRecordDto stockInRecordDto,Long id) throws Exception {
@@ -129,10 +186,17 @@
*/
public void updateOrCreateStockUninventory(StockInRecord stockInRecord) {
// 鍏堟煡璇㈠簱瀛樿〃涓殑浜у搧鏄惁瀛樺湪
- StockUninventory oldStockUnInventory = stockUninventoryMapper.selectOne(
- new QueryWrapper<StockUninventory>().lambda()
- .eq(StockUninventory::getProductModelId, stockInRecord.getProductModelId())
- );
+ LambdaQueryWrapper<StockUninventory> queryWrapper = new QueryWrapper<StockUninventory>().lambda()
+ .eq(StockUninventory::getProductModelId, stockInRecord.getProductModelId());
+
+ // 鏍规嵁 batchNo 鏄惁涓虹┖鏋勫缓涓嶅悓鐨勬煡璇㈡潯浠�
+ if (stockInRecord.getBatchNo() != null && !stockInRecord.getBatchNo().isEmpty()) {
+ queryWrapper.eq(StockUninventory::getBatchNo, stockInRecord.getBatchNo());
+ } else {
+ queryWrapper.isNull(StockUninventory::getBatchNo);
+ }
+
+ StockUninventory oldStockUnInventory = stockUninventoryMapper.selectOne(queryWrapper);
if (ObjectUtils.isEmpty(oldStockUnInventory)) {
// 涓嶅瓨鍦ㄥ垯鏂板
@@ -141,19 +205,32 @@
newStockUnInventory.setQualitity(stockInRecord.getStockInNum());
newStockUnInventory.setVersion(1);
newStockUnInventory.setRemark(stockInRecord.getRemark());
+ newStockUnInventory.setLockedQuantity(stockInRecord.getLockedQuantity());
+ newStockUnInventory.setBatchNo(stockInRecord.getBatchNo());
stockUninventoryMapper.insert(newStockUnInventory);
} else {
+ // 瀛樺湪鍒欐洿鏂�
LambdaUpdateWrapper<StockUninventory> updateWrapper = new LambdaUpdateWrapper<>();
- if (stockInRecord.getStockInNum() != null) {
- updateWrapper.setSql("qualitity = qualitity + " + stockInRecord.getStockInNum());
+ updateWrapper
+ .eq(StockUninventory::getProductModelId, stockInRecord.getProductModelId());
+
+ // 鏍规嵁 batchNo 鏄惁涓虹┖鏋勫缓涓嶅悓鐨勬洿鏂版潯浠�
+ if (stockInRecord.getBatchNo() != null && !stockInRecord.getBatchNo().isEmpty()) {
+ updateWrapper.eq(StockUninventory::getBatchNo, stockInRecord.getBatchNo());
+ } else {
+ updateWrapper.isNull(StockUninventory::getBatchNo);
}
- updateWrapper.setSql("version = version + 1");
- String remark = stockInRecord.getRemark();
- if (remark != null && !remark.isEmpty()) {
- updateWrapper.set(StockUninventory::getRemark, remark);
- }
- updateWrapper.set(StockUninventory::getUpdateTime, new Date());
- updateWrapper.eq(StockUninventory::getProductModelId, stockInRecord.getProductModelId());
+
+ updateWrapper
+ .setSql(stockInRecord.getStockInNum() != null,
+ "qualitity = qualitity + " + stockInRecord.getStockInNum())
+ .setSql(true, "version = version + 1")
+ .set(stockInRecord.getRemark() != null && !stockInRecord.getRemark().isEmpty(),
+ StockUninventory::getRemark, stockInRecord.getRemark())
+ .setSql(stockInRecord.getLockedQuantity() != null,
+ "locked_quantity = locked_quantity + " + stockInRecord.getLockedQuantity())
+ .set(StockUninventory::getUpdateTime, new Date());
+
stockUninventoryMapper.update(null, updateWrapper);
}
}
@@ -209,4 +286,4 @@
stockUninventory.setLockedQuantity(stockUninventory.getLockedQuantity().subtract(stockInventoryDto.getLockedQuantity()));
return this.updateById(stockUninventory);
}
-}
+}
\ No newline at end of file
diff --git a/src/main/resources/mapper/stock/StockInventoryMapper.xml b/src/main/resources/mapper/stock/StockInventoryMapper.xml
index db26cc9..9acd557 100644
--- a/src/main/resources/mapper/stock/StockInventoryMapper.xml
+++ b/src/main/resources/mapper/stock/StockInventoryMapper.xml
@@ -80,23 +80,198 @@
AND p.product_name LIKE CONCAT('%', #{ew.productName}, '%')
</if>
</select>
- <select id="listStockInventoryExportData" resultType="com.ruoyi.stock.execl.StockInventoryExportData">
- select si.qualitity,
+
+ <select id="pageListCombinedStockInventory" resultType="com.ruoyi.stock.dto.StockInventoryDto">
+ WITH RECURSIVE product_tree AS (
+ SELECT id
+ FROM product
+ WHERE id = #{ew.topParentProductId}
+
+ UNION ALL
+
+ SELECT p.id
+ FROM product p
+ INNER JOIN product_tree pt ON p.parent_id = pt.id
+ )
+ select
+ MAX(qualifiedId) as qualifiedId,
+ MAX(unQualifiedId) as unQualifiedId,
+ SUM(qualifiedQuantity) as qualifiedQuantity,
+ SUM(unQualifiedQuantity) as unQualifiedQuantity,
+ SUM(qualifiedLockedQuantity) as qualifiedLockedQuantity,
+ SUM(unQualifiedLockedQuantity) as unQualifiedLockedQuantity,
+ SUM(qualifiedQuantity - qualifiedLockedQuantity) as qualifiedUnLockedQuantity,
+ SUM(unQualifiedQuantity - unQualifiedLockedQuantity) as unQualifiedUnLockedQuantity,
+ product_model_id,
+ MAX(create_time) as create_time,
+ MAX(update_time) as update_time,
+ MAX(warn_num) as warn_num,
+ MAX(version) as version,
+ model,
+ MAX(remark) as remark,
+ unit,
+ product_name,
+ product_id,
+ MAX(qualifiedBatchNo) as qualifiedBatchNo,
+ MAX(unQualifiedBatchNo) as unQualifiedBatchNo,
+ MAX(materialCode) as materialCode,
+ 'combined' as stockType
+ from (
+ select
+ si.id as qualifiedId,
+ null as unQualifiedId,
+ si.qualitity as qualifiedQuantity,
+ 0 as unQualifiedQuantity,
+ COALESCE(si.locked_quantity, 0) as locked_quantity,
+ COALESCE(si.locked_quantity, 0) as qualifiedLockedQuantity,
+ 0 as unQualifiedLockedQuantity,
+ si.product_model_id,
+ si.create_time,
+ si.update_time,
+ COALESCE(si.warn_num, 0) as warn_num,
+ si.version,
+ (si.qualitity - COALESCE(si.locked_quantity, 0)) as un_locked_quantity,
pm.model,
- pm.unit,
- pm.material_code as materialCode,
- p.product_name,
- coalesce(si.warn_num, 0) as warn_num,
- coalesce(si.locked_quantity, 0) as locked_quantity,
si.remark,
- si.update_time
+ pm.unit,
+ p.product_name,
+ p.id as product_id,
+ si.batch_no as qualifiedBatchNo,
+ null as unQualifiedBatchNo,
+ pm.material_code as materialCode
from stock_inventory si
left join product_model pm on si.product_model_id = pm.id
left join product p on pm.product_id = p.id
- where 1 = 1
- <if test="ew.productName != null and ew.productName !=''">
- and p.product_name like concat('%',#{ew.productName},'%')
- </if>
+
+ union all
+
+ select
+ null as qualifiedId,
+ su.id as unQualifiedId,
+ 0 as qualifiedQuantity,
+ su.qualitity as unQualifiedQuantity,
+ COALESCE(su.locked_quantity, 0) as locked_quantity,
+ 0 as qualifiedLockedQuantity,
+ COALESCE(su.locked_quantity, 0) as unQualifiedLockedQuantity,
+ su.product_model_id,
+ su.create_time,
+ su.update_time,
+ 0 as warn_num,
+ su.version,
+ (su.qualitity - COALESCE(su.locked_quantity, 0)) as un_locked_quantity,
+ pm.model,
+ su.remark,
+ pm.unit,
+ p.product_name,
+ p.id as product_id,
+ null as qualifiedBatchNo,
+ su.batch_no as unQualifiedBatchNo,
+ pm.material_code as materialCode
+ from stock_uninventory su
+ left join product_model pm on su.product_model_id = pm.id
+ left join product p on pm.product_id = p.id
+ ) as combined
+ <where>
+ <if test="ew.productName != null and ew.productName !=''">
+ and combined.product_name in (
+ select distinct p.product_name
+ from product p
+ left join product_model pm on p.id = pm.product_id
+ where p.product_name like concat('%',#{ew.productName},'%') or pm.model like concat('%',#{ew.productName},'%')
+ )
+ </if>
+ <if test="ew.topParentProductId != null and ew.topParentProductId > 0">
+ and combined.product_id in (select id from product_tree)
+ </if>
+ </where>
+ group by product_model_id, model, unit, product_name, product_id, qualifiedBatchNo, unQualifiedBatchNo, materialCode, product_id, qualifiedBatchNo, unQualifiedBatchNo
+ </select>
+
+ <select id="listStockInventoryExportData" resultType="com.ruoyi.stock.execl.StockInventoryExportData">
+ WITH RECURSIVE product_tree AS (
+ SELECT id
+ FROM product
+ WHERE id = #{ew.topParentProductId}
+
+ UNION ALL
+
+ SELECT p.id
+ FROM product p
+ INNER JOIN product_tree pt ON p.parent_id = pt.id
+ )
+ select
+ SUM(qualifiedQuantity) as qualifiedQuantity,
+ SUM(unQualifiedQuantity) as unQualifiedQuantity,
+ SUM(qualifiedLockedQuantity) as qualifiedLockedQuantity,
+ SUM(unQualifiedLockedQuantity) as unQualifiedLockedQuantity,
+ model,
+ unit,
+ product_name,
+ MAX(warn_num) as warn_num,
+ MAX(remark) as remark,
+ MAX(update_time) as update_time,
+ MAX(qualifiedBatchNo) as qualifiedBatchNo,
+ MAX(unQualifiedBatchNo) as unQualifiedBatchNo,
+ MAX(materialCode) as materialCode
+ from (
+ select
+ si.qualitity as qualifiedQuantity,
+ 0 as unQualifiedQuantity,
+ COALESCE(si.locked_quantity, 0) as qualifiedLockedQuantity,
+ 0 as unQualifiedLockedQuantity,
+ si.product_model_id,
+ si.create_time,
+ si.update_time,
+ COALESCE(si.warn_num, 0) as warn_num,
+ si.remark,
+ pm.model,
+ pm.unit,
+ p.product_name,
+ p.id as product_id,
+ si.batch_no as qualifiedBatchNo,
+ null as unQualifiedBatchNo,
+ pm.material_code as materialCode
+ from stock_inventory si
+ left join product_model pm on si.product_model_id = pm.id
+ left join product p on pm.product_id = p.id
+
+ union all
+
+ select
+ 0 as qualifiedQuantity,
+ su.qualitity as unQualifiedQuantity,
+ 0 as qualifiedLockedQuantity,
+ COALESCE(su.locked_quantity, 0) as unQualifiedLockedQuantity,
+ su.product_model_id,
+ su.create_time,
+ su.update_time,
+ 0 as warn_num,
+ su.remark,
+ pm.model,
+ pm.unit,
+ p.product_name,
+ p.id as product_id,
+ null as qualifiedBatchNo,
+ su.batch_no as unQualifiedBatchNo,
+ pm.material_code as materialCode
+ from stock_uninventory su
+ left join product_model pm on su.product_model_id = pm.id
+ left join product p on pm.product_id = p.id
+ ) as combined
+ <where>
+ <if test="ew.productName != null and ew.productName !=''">
+ and combined.product_name in (
+ select distinct p.product_name
+ from product p
+ left join product_model pm on p.id = pm.product_id
+ where p.product_name like concat('%',#{ew.productName},'%') or pm.model like concat('%',#{ew.productName},'%')
+ )
+ </if>
+ <if test="ew.topParentProductId != null and ew.topParentProductId > 0">
+ and combined.product_id in (select id from product_tree)
+ </if>
+ </where>
+ group by product_model_id, model, unit, product_name, qualifiedBatchNo, unQualifiedBatchNo, materialCode
</select>
<select id="stockInventoryPage" resultType="com.ruoyi.stock.dto.StockInRecordDto">
select sir.*,si.qualitity as current_stock,
@@ -265,4 +440,4 @@
left join product p on pm.product_id = p.id
</select>
-</mapper>
+</mapper>
\ No newline at end of file
--
Gitblit v1.9.3