From a76e1d17d67641993dea6335cb8e1465a94df58d Mon Sep 17 00:00:00 2001
From: liding <756868258@qq.com>
Date: 星期四, 21 五月 2026 15:39:05 +0800
Subject: [PATCH] feat(stock): 优化库存管理和成品树结构功能 1- 为ApproveProcessMapper.xml和ProductBomMapper.xml添加排序功能 2- 在ProductionProductMainDto中新增bomInputQty字段用于产品结构投入数量 3- 修改ProductionProductMainServiceImpl中投入数量计算逻辑,使用前端传入的bomInputQty值 4- 在ProductWorkOrderDto中添加bomInputQty字段并在服务实现中计算标准投入数量 5- 更新SalesLedgerMapper.xml查询逻辑,从product_summary获取电压信息 6- 为SalesLedgerProduct添加stockId字段并修改库存扣减逻辑使用具体库存ID 7- 重构StockInventoryController中的成品库存树查询接口和导入导出功能 8- 新增成品和非成品库存导入导出的数据模型和Excel工具类 9- 优化StockInventoryServiceImpl中的库存扣减逻辑,支持按特定库存ID操作 10- 更新库存导入导出功能,区分成品和非成品类型并提供相应模板
---
src/main/java/com/ruoyi/stock/dto/StockOutRecordDto.java | 4
src/main/java/com/ruoyi/stock/service/StockInventoryService.java | 4
src/main/resources/mapper/sales/SalesLedgerMapper.xml | 5
src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java | 4
src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java | 17 +
src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java | 3
src/main/resources/mapper/sales/SalesLedgerProductMapper.xml | 7
src/main/java/com/ruoyi/stock/execl/FinishedProductInventoryExportData.java | 54 +++
src/main/java/com/ruoyi/production/dto/ProductWorkOrderDto.java | 4
src/main/java/com/ruoyi/stock/dto/FinishedProductTreeDto.java | 34 +
src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java | 382 ++++++++++++++------------
src/main/java/com/ruoyi/stock/dto/StockInventoryDto.java | 5
src/main/resources/mapper/stock/StockOutRecordMapper.xml | 14
src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java | 13
src/main/resources/mapper/production/ProductBomMapper.xml | 1
src/main/java/com/ruoyi/stock/execl/NonFinishedProductInventoryExportData.java | 48 +++
src/main/resources/mapper/stock/StockInventoryMapper.xml | 33 ++
src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java | 33 ++
src/main/java/com/ruoyi/stock/controller/StockInventoryController.java | 39 +
src/main/resources/mapper/approve/ApproveProcessMapper.xml | 1
src/main/java/com/ruoyi/production/dto/ProductionProductMainDto.java | 3
src/main/java/com/ruoyi/stock/execl/StockOutRecordExportData.java | 3
src/main/java/com/ruoyi/production/service/impl/ProductWorkOrderServiceImpl.java | 63 ++++
src/main/java/com/ruoyi/stock/execl/StockInventoryExportData.java | 10
src/main/java/com/ruoyi/stock/mapper/StockInventoryMapper.java | 3
25 files changed, 566 insertions(+), 221 deletions(-)
diff --git a/src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java b/src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
index 288f721..27ebea8 100644
--- a/src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
+++ b/src/main/java/com/ruoyi/procurementrecord/utils/StockUtils.java
@@ -152,7 +152,7 @@
* @param recordType
* @param recordId
*/
- public void substractStock(Long productModelId, BigDecimal quantity, String recordType, Long recordId,String batchNo) {
+ public void substractStock(Long productModelId, BigDecimal quantity, String recordType, Long recordId,String batchNo,Long stockId) {
StockInventoryDto stockInventoryDto = new StockInventoryDto();
stockInventoryDto.setRecordId(recordId);
stockInventoryDto.setRecordType(String.valueOf(recordType));
@@ -161,6 +161,7 @@
if (batchNo !=null && !batchNo.isEmpty()) {
stockInventoryDto.setBatchNo(batchNo);
}
+ stockInventoryDto.setStockId(stockId);
stockInventoryService.subtractStockInventory(stockInventoryDto);
}
@@ -185,4 +186,18 @@
stockOutRecordService.batchDelete(idList);
}
}
+
+ /**
+ * 浠呮寜recordId鍒犻櫎鍑哄簱璁板綍锛堢敤浜巖ecordType涓哄姩鎬佸�肩殑鍦烘櫙锛�
+ */
+ public void deleteStockOutRecordByRecordId(Long recordId) {
+ List<StockOutRecord> one = stockOutRecordService.list(new QueryWrapper<StockOutRecord>()
+ .lambda().eq(StockOutRecord::getRecordId, recordId));
+ if (ObjectUtils.isNotEmpty(one)) {
+ List<Long> idList = one.stream()
+ .map(StockOutRecord::getId)
+ .collect(Collectors.toList());
+ stockOutRecordService.batchDelete(idList);
+ }
+ }
}
diff --git a/src/main/java/com/ruoyi/production/dto/ProductWorkOrderDto.java b/src/main/java/com/ruoyi/production/dto/ProductWorkOrderDto.java
index 2ba3567..ee9e07b 100644
--- a/src/main/java/com/ruoyi/production/dto/ProductWorkOrderDto.java
+++ b/src/main/java/com/ruoyi/production/dto/ProductWorkOrderDto.java
@@ -62,6 +62,10 @@
@ApiModelProperty(value = "鎶曞叆鏁伴噺")
private BigDecimal inputQty;
+ // 浜у搧缁撴瀯鎶曞叆鏁伴噺
+ @ApiModelProperty(value = "浜у搧缁撴瀯鎶曞叆鏁伴噺")
+ private BigDecimal bomInputQty;
+
@ApiModelProperty(value = "宸ュ崟绫诲瀷 姝e父 /杩斿伐杩斾慨")
private String workOrderType;
diff --git a/src/main/java/com/ruoyi/production/dto/ProductionProductMainDto.java b/src/main/java/com/ruoyi/production/dto/ProductionProductMainDto.java
index 5518c27..a02e40c 100644
--- a/src/main/java/com/ruoyi/production/dto/ProductionProductMainDto.java
+++ b/src/main/java/com/ruoyi/production/dto/ProductionProductMainDto.java
@@ -86,4 +86,7 @@
@ApiModelProperty(value = "鐢熶骇鎵瑰彿")
private String batchNo;
+
+ @ApiModelProperty(value = "浜у搧缁撴瀯鎶曞叆鏁伴噺")
+ private BigDecimal bomInputQty;
}
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductWorkOrderServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductWorkOrderServiceImpl.java
index 982009f..b73d629 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductWorkOrderServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductWorkOrderServiceImpl.java
@@ -11,6 +11,7 @@
import com.deepoove.poi.data.Pictures;
import com.ruoyi.common.utils.MatrixToImageWriter;
import com.ruoyi.production.dto.ProductWorkOrderDto;
+import com.ruoyi.production.dto.ProductStructureDto;
import com.ruoyi.production.mapper.*;
import com.ruoyi.production.pojo.*;
import com.ruoyi.production.service.ProductWorkOrderService;
@@ -30,6 +31,7 @@
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.util.*;
+import java.util.function.Function;
import java.util.stream.Collectors;
@Service
@@ -44,6 +46,10 @@
private ProductProcessRouteItemMapper productProcessRouteItemMapper;
@Autowired
private ProductProcessMapper productProcessMapper;
+ @Autowired
+ private ProductProcessRouteMapper productProcessRouteMapper;
+ @Autowired
+ private ProductStructureMapper productStructureMapper;
@Autowired
private ProductionProductMainMapper productionProductMainMapper;
@Autowired
@@ -61,6 +67,7 @@
@Override
public IPage<ProductWorkOrderDto> listPage(Page<ProductWorkOrderDto> page, ProductWorkOrderDto productWorkOrder) {
IPage<ProductWorkOrderDto> productWorkOrderDtoIPage = productWorkOrdermapper.pageProductWorkOrder(page, productWorkOrder);
+ Map<String, BigDecimal> bomInputQtyCache = new HashMap<>();
productWorkOrderDtoIPage.getRecords().forEach(record -> {
// 鏄惁鑳芥姤宸ワ細 1. 绗竴涓伐搴忚兘鎶ュ伐 2. 涓婁竴涓伐搴忓凡鎶ュ伐 3. 涔嬪墠鐨勫伐搴忔湭琚殧绂�
Integer currentDragSort = record.getDragSort();
@@ -126,6 +133,62 @@
} else {
record.setActualQualifiedRate((record.getCompleteQuantity().subtract(totalScrapQty)).multiply(BigDecimal.valueOf(100)));
}
+
+ // 鏌ヨ褰撳墠宸ュ崟瀵瑰簲浜у搧缁撴瀯涓殑鏍囧噯鎶曞叆鏁伴噺
+ String bomInputQtyCacheKey = record.getProductRouteId() + "_" + record.getProcessId() + "_" + record.getPlanQuantity();
+ BigDecimal bomInputQty = bomInputQtyCache.get(bomInputQtyCacheKey);
+ if (bomInputQty == null) {
+ bomInputQty = BigDecimal.ZERO;
+ ProductProcessRoute productProcessRoute = productProcessRouteMapper.selectById(record.getProductRouteId());
+ if (productProcessRoute != null && productProcessRoute.getBomId() != null && record.getProcessId() != null) {
+ List<ProductStructureDto> productStructureDtos = productStructureMapper.listBybomAndProcess(
+ productProcessRoute.getBomId(),
+ record.getProcessId()
+ );
+
+ if (CollectionUtils.isEmpty(productStructureDtos)) {
+ bomInputQty = record.getPlanQuantity() == null ? BigDecimal.ZERO : record.getPlanQuantity();
+ } else {
+ Set<Long> parentIds = productStructureDtos.stream()
+ .map(ProductStructureDto::getParentId)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toSet());
+
+ Map<Long, ProductStructureDto> parentMap = new HashMap<>();
+ if (CollectionUtils.isNotEmpty(parentIds)) {
+ parentMap = productStructureMapper.selectByIds(parentIds)
+ .stream()
+ .collect(Collectors.toMap(ProductStructureDto::getId, Function.identity(), (a, b) -> a));
+ }
+
+ BigDecimal planQty = record.getPlanQuantity() == null ? BigDecimal.ZERO : record.getPlanQuantity();
+ for (ProductStructureDto productStructureDto : productStructureDtos) {
+ BigDecimal childQty = productStructureDto.getUnitQuantity();
+ if (childQty == null || childQty.compareTo(BigDecimal.ZERO) <= 0) {
+ continue;
+ }
+
+ BigDecimal parentQty = BigDecimal.ONE;
+ if (productStructureDto.getParentId() != null) {
+ ProductStructureDto parent = parentMap.get(productStructureDto.getParentId());
+ if (parent != null && parent.getUnitQuantity() != null && parent.getUnitQuantity().compareTo(BigDecimal.ZERO) > 0) {
+ parentQty = parent.getUnitQuantity();
+ }
+ }
+
+ if (parentQty.compareTo(BigDecimal.ZERO) <= 0) {
+ continue;
+ }
+
+ bomInputQty = bomInputQty.add(
+ childQty.divide(parentQty, 6, RoundingMode.HALF_UP).multiply(planQty)
+ );
+ }
+ }
+ }
+ bomInputQtyCache.put(bomInputQtyCacheKey, bomInputQty);
+ }
+ record.setBomInputQty(bomInputQty);
});
return productWorkOrderDtoIPage;
}
diff --git a/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java b/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
index 47e7fcd..5b1177c 100644
--- a/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
+++ b/src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
@@ -37,7 +37,6 @@
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
-import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@@ -99,6 +98,7 @@
BigDecimal reportQty = dto.getQuantity();
BigDecimal scrapQty = dto.getScrapQty() == null ? BigDecimal.ZERO : dto.getScrapQty();
+ BigDecimal bomInputQty = dto.getBomInputQty();
if (reportQty == null || reportQty.compareTo(BigDecimal.ZERO) <= 0) {
throw new ServiceException("鎶ュ伐鏁伴噺蹇呴』澶т簬0");
}
@@ -107,6 +107,9 @@
}
if (scrapQty.compareTo(reportQty) > 0) {
throw new ServiceException("鎶ュ簾鏁伴噺涓嶈兘澶т簬鎶ュ伐鏁伴噺");
+ }
+ if (bomInputQty == null || bomInputQty.compareTo(BigDecimal.ZERO) < 0) {
+ throw new ServiceException("浜у搧缁撴瀯鎶曞叆鏁伴噺涓嶈兘灏忎簬0");
}
// 绗簩姝ワ細鍔犺浇褰撳墠宸ュ簭銆佸伐鍗曘�佸伐鑹鸿矾绾垮拰璁㈠崟鏁版嵁锛屽苟鏍¢獙鍩虹鍏宠仈鍏崇郴
@@ -313,6 +316,9 @@
.collect(Collectors.toMap(ProductStructureDto::getId, Function.identity(), (a, b) -> a));
}
+ // 绗竷姝�-1锛氭姇鍏ユ暟閲忓己鍒跺彇鍓嶇浼犲叆鐨� bomInputQty
+ BigDecimal inputBaseQty = bomInputQty;
+
for (ProductStructureDto productStructureDto : productStructureDtos) {
if (productStructureDto.getProductModelId() == null) {
throw new ServiceException("鎶曞叆鐗╂枡浜у搧鍨嬪彿涓嶈兘涓虹┖");
@@ -335,9 +341,7 @@
throw new ServiceException("鐖剁骇鐗╂枡鐢ㄩ噺蹇呴』澶т簬0");
}
- BigDecimal needQty = childQty
- .divide(parentQty, 6, RoundingMode.HALF_UP)
- .multiply(reportQty);
+ BigDecimal needQty = inputBaseQty;
ProductionProductInput productionProductInput = new ProductionProductInput();
productionProductInput.setProductModelId(productStructureDto.getProductModelId());
@@ -350,6 +354,7 @@
needQty,
StockOutQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode(),
productionProductMain.getId(),
+ null,
null
);
}
diff --git a/src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java b/src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
index 299ac3f..67219f7 100644
--- a/src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
+++ b/src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
@@ -13,7 +13,6 @@
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
-import java.util.List;
/**
* 浜у搧淇℃伅瀵硅薄 sales_ledger_product
@@ -261,4 +260,7 @@
@ApiModelProperty("鎵瑰彿")
private String batchNo;
+
+ @ApiModelProperty("搴撳瓨id")
+ private Long stockId;
}
diff --git a/src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java
index a39cb72..5735ffb 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java
@@ -66,7 +66,8 @@
//鎵e噺搴撳瓨
if(!"宸插彂璐�".equals(byId.getStatus())){
SalesLedgerProduct salesLedgerProduct = salesLedgerProductMapper.selectById(byId.getSalesLedgerProductId());
- stockUtils.substractStock(salesLedgerProduct.getProductModelId(), salesLedgerProduct.getQuantity(), StockOutQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode(), req.getId(),null);
+ stockUtils.substractStock(salesLedgerProduct.getProductModelId(), salesLedgerProduct.getQuantity(),
+ StockOutQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode(), req.getId(),null,salesLedgerProduct.getStockId());
}
byId.setExpressNumber(req.getExpressNumber());
byId.setExpressCompany(req.getExpressCompany());
diff --git a/src/main/java/com/ruoyi/stock/controller/StockInventoryController.java b/src/main/java/com/ruoyi/stock/controller/StockInventoryController.java
index 8781257..76ac7c5 100644
--- a/src/main/java/com/ruoyi/stock/controller/StockInventoryController.java
+++ b/src/main/java/com/ruoyi/stock/controller/StockInventoryController.java
@@ -10,6 +10,8 @@
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.stock.dto.FinishedProductTreeDto;
import com.ruoyi.stock.dto.StockInventoryDto;
+import com.ruoyi.stock.execl.FinishedProductInventoryExportData;
+import com.ruoyi.stock.execl.NonFinishedProductInventoryExportData;
import com.ruoyi.stock.execl.StockInventoryExportData;
import com.ruoyi.stock.service.StockInventoryService;
import io.swagger.annotations.Api;
@@ -48,11 +50,13 @@
return R.ok(stockInventoryDtoIPage);
}
- @GetMapping("/finishedProductList")
+ /**
+ * 鏌ヨ鎴愬搧搴撳瓨鏍�
+ */
@ApiOperation("鏌ヨ鎴愬搧搴撳瓨鏍�")
- public R finishedProductList(StockInventoryDto stockInventoryDto) {
- List<FinishedProductTreeDto> list = stockInventoryService.finishedProductList(stockInventoryDto);
- return R.ok(list);
+ @GetMapping("/finishedProductList")
+ public List<FinishedProductTreeDto> finishedProductList(StockInventoryDto stockInventoryDto) {
+ return stockInventoryService.finishedProductList(stockInventoryDto);
}
@@ -85,22 +89,33 @@
@PostMapping("importStockInventory")
@ApiOperation("瀵煎叆搴撳瓨")
- public R importStockInventory(MultipartFile file) {
- return stockInventoryService.importStockInventory(file);
+ public R importStockInventory(MultipartFile file,
+ @RequestParam Integer productType) {
+ return stockInventoryService.importStockInventory(file, productType);
}
@Log(title = "涓嬭浇搴撳瓨瀵煎叆妯℃澘", businessType = BusinessType.EXPORT)
@PostMapping("/downloadStockInventory")
- public void downloadStockInventory(HttpServletResponse response) {
- List<StockInventoryExportData> list = new ArrayList<>();
- ExcelUtil<StockInventoryExportData> util = new ExcelUtil<>(StockInventoryExportData.class);
- util.exportExcel(response, list, "搴撳瓨妯℃澘");
+ public void downloadStockInventory(HttpServletResponse response,
+ @RequestParam Integer productType) {
+ // productType: 1=鎴愬搧, 0=闈炴垚鍝�
+ if (productType == 1) {
+ List<FinishedProductInventoryExportData> list = new ArrayList<>();
+ ExcelUtil<FinishedProductInventoryExportData> util = new ExcelUtil<>(FinishedProductInventoryExportData.class);
+ util.exportExcel(response, list, "鎴愬搧搴撳瓨妯℃澘");
+ } else {
+ List<NonFinishedProductInventoryExportData> list = new ArrayList<>();
+ ExcelUtil<NonFinishedProductInventoryExportData> util = new ExcelUtil<>(NonFinishedProductInventoryExportData.class);
+ util.exportExcel(response, list, "闈炴垚鍝佸簱瀛樻ā鏉�");
+ }
}
@PostMapping("/exportStockInventory")
@ApiOperation("瀵煎嚭搴撳瓨")
- public void exportStockInventory(HttpServletResponse response, StockInventoryDto stockInventoryDto) {
- stockInventoryService.exportStockInventory(response, stockInventoryDto);
+ public void exportStockInventory(HttpServletResponse response,
+ StockInventoryDto stockInventoryDto,
+ @RequestParam Integer productType) {
+ stockInventoryService.exportStockInventory(response, stockInventoryDto, productType);
}
@GetMapping("stockInventoryPage")
diff --git a/src/main/java/com/ruoyi/stock/dto/FinishedProductTreeDto.java b/src/main/java/com/ruoyi/stock/dto/FinishedProductTreeDto.java
index 9f78801..a17d163 100644
--- a/src/main/java/com/ruoyi/stock/dto/FinishedProductTreeDto.java
+++ b/src/main/java/com/ruoyi/stock/dto/FinishedProductTreeDto.java
@@ -1,31 +1,45 @@
package com.ruoyi.stock.dto;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@Data
+@ApiModel(value = "FinishedProductTreeDto", description = "鎴愬搧鏍戝舰DTO")
public class FinishedProductTreeDto {
- private Long id;
-
- private Long parentId;
-
- private String productName;
-
- private String label;
-
+ @ApiModelProperty(value = "浜у搧ID")
private Long productId;
+ @ApiModelProperty(value = "浜у搧鍚嶇О")
+ private String productName;
+
+ @ApiModelProperty(value = "鏍囩/鏄剧ず鍚嶇О")
+ private String label;
+
+ @ApiModelProperty(value = "搴撳瓨ID")
+ private Long stockId;
+
+ @ApiModelProperty(value = "浜у搧鍨嬪彿ID")
private Long productModelId;
+ @ApiModelProperty(value = "鍨嬪彿")
private String model;
- private String materialCode;
-
+ @ApiModelProperty(value = "宸ュ簭绫诲埆")
private String processCategory;
+ @ApiModelProperty(value = "鐢靛帇")
private String voltage;
+ @ApiModelProperty(value = "鐗╂枡缂栫爜")
+ private String materialCode;
+
+ @ApiModelProperty(value = "鍗曚綅")
+ private String unit;
+
+ @ApiModelProperty(value = "瀛愯妭鐐瑰垪琛�")
private List<FinishedProductTreeDto> children;
}
diff --git a/src/main/java/com/ruoyi/stock/dto/StockInventoryDto.java b/src/main/java/com/ruoyi/stock/dto/StockInventoryDto.java
index 40de24a..7dcddf7 100644
--- a/src/main/java/com/ruoyi/stock/dto/StockInventoryDto.java
+++ b/src/main/java/com/ruoyi/stock/dto/StockInventoryDto.java
@@ -2,13 +2,16 @@
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.stock.pojo.StockInventory;
+import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
+import lombok.EqualsAndHashCode;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.time.LocalDate;
+@EqualsAndHashCode(callSuper = true)
@Data
public class StockInventoryDto extends StockInventory {
@@ -74,4 +77,6 @@
@Schema(description = "涓嶅悎鏍兼壒娆″彿")
private String unQualifiedBatchNo;
+ @ApiModelProperty("搴撳瓨id")
+ private Long stockId;
}
diff --git a/src/main/java/com/ruoyi/stock/dto/StockOutRecordDto.java b/src/main/java/com/ruoyi/stock/dto/StockOutRecordDto.java
index a39c30d..9f42e3e 100644
--- a/src/main/java/com/ruoyi/stock/dto/StockOutRecordDto.java
+++ b/src/main/java/com/ruoyi/stock/dto/StockOutRecordDto.java
@@ -30,6 +30,10 @@
private String createBy;
+ private String processName;
+
+ private String recordTypeName;
+
// 椤堕儴鐖朵骇鍝乮d
private Long topParentProductId;
}
diff --git a/src/main/java/com/ruoyi/stock/execl/FinishedProductInventoryExportData.java b/src/main/java/com/ruoyi/stock/execl/FinishedProductInventoryExportData.java
new file mode 100644
index 0000000..647a4fd
--- /dev/null
+++ b/src/main/java/com/ruoyi/stock/execl/FinishedProductInventoryExportData.java
@@ -0,0 +1,54 @@
+package com.ruoyi.stock.execl;
+
+import com.ruoyi.framework.aspectj.lang.annotation.Excel;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 鎴愬搧搴撳瓨瀵煎叆瀵煎嚭瀹炰綋锛堝寘鍚伐搴忕被鍒拰鐢靛帇锛�
+ */
+@Data
+public class FinishedProductInventoryExportData {
+ @Excel(name = "浜у搧鍚嶇О")
+ private String productName;
+
+ @Excel(name = "瑙勬牸鍨嬪彿")
+ private String model;
+
+ @Excel(name = "鍗曚綅")
+ private String unit;
+
+ @Excel(name = "鏂欏彿")
+ private String materialCode;
+
+ @Excel(name = "宸ュ簭绫诲埆")
+ private String processCategory;
+
+ @Excel(name = "鐢靛帇")
+ private String voltage;
+
+ // @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 qualifiedLockedQuantity;
+
+ @Excel(name = "涓嶅悎鏍煎喕缁撴暟閲�")
+ private BigDecimal unQualifiedLockedQuantity;
+
+ @Excel(name = "澶囨敞")
+ private String remark;
+}
diff --git a/src/main/java/com/ruoyi/stock/execl/NonFinishedProductInventoryExportData.java b/src/main/java/com/ruoyi/stock/execl/NonFinishedProductInventoryExportData.java
new file mode 100644
index 0000000..5e33f9f
--- /dev/null
+++ b/src/main/java/com/ruoyi/stock/execl/NonFinishedProductInventoryExportData.java
@@ -0,0 +1,48 @@
+package com.ruoyi.stock.execl;
+
+import com.ruoyi.framework.aspectj.lang.annotation.Excel;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 闈炴垚鍝佸簱瀛樺鍏ュ鍑哄疄浣擄紙涓嶅寘鍚伐搴忕被鍒拰鐢靛帇锛�
+ */
+@Data
+public class NonFinishedProductInventoryExportData {
+ @Excel(name = "浜у搧鍚嶇О")
+ private String productName;
+
+ @Excel(name = "瑙勬牸鍨嬪彿")
+ private String model;
+
+ @Excel(name = "鍗曚綅")
+ private String unit;
+
+ @Excel(name = "鏂欏彿")
+ private String materialCode;
+
+ // @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 qualifiedLockedQuantity;
+
+ @Excel(name = "涓嶅悎鏍煎喕缁撴暟閲�")
+ private BigDecimal unQualifiedLockedQuantity;
+
+ @Excel(name = "澶囨敞")
+ private String remark;
+}
diff --git a/src/main/java/com/ruoyi/stock/execl/StockInventoryExportData.java b/src/main/java/com/ruoyi/stock/execl/StockInventoryExportData.java
index 128d708..771f52b 100644
--- a/src/main/java/com/ruoyi/stock/execl/StockInventoryExportData.java
+++ b/src/main/java/com/ruoyi/stock/execl/StockInventoryExportData.java
@@ -10,25 +10,25 @@
@Excel(name = "浜у搧鍚嶇О")
private String productName;
- @Excel(name = "鍨嬪彿")
+ @Excel(name = "瑙勬牸鍨嬪彿")
private String model;
@Excel(name = "鍗曚綅")
private String unit;
- @Excel(name = "鐗╂枡缂栫爜")
+ @Excel(name = "鏂欏彿")
private String materialCode;
- @Excel(name = "鎴愬搧绫诲埆")
+ @Excel(name = "宸ュ簭绫诲埆")
private String processCategory;
@Excel(name = "鐢靛帇")
private String voltage;
- @Excel(name = "鍚堟牸搴撳瓨鎵瑰彿")
+ // @Excel(name = "鍚堟牸搴撳瓨鎵瑰彿")
private String qualifiedBatchNo;
- @Excel(name = "涓嶅悎鏍煎簱瀛樻壒鍙�")
+ // @Excel(name = "涓嶅悎鏍煎簱瀛樻壒鍙�")
private String unQualifiedBatchNo;
@Excel(name = "鍚堟牸搴撳瓨鏁伴噺")
diff --git a/src/main/java/com/ruoyi/stock/execl/StockOutRecordExportData.java b/src/main/java/com/ruoyi/stock/execl/StockOutRecordExportData.java
index e70fc96..28334e6 100644
--- a/src/main/java/com/ruoyi/stock/execl/StockOutRecordExportData.java
+++ b/src/main/java/com/ruoyi/stock/execl/StockOutRecordExportData.java
@@ -30,4 +30,7 @@
@Excel(isExport = false)
private String type;
+
+ @Excel(isExport = false)
+ private String processName;
}
diff --git a/src/main/java/com/ruoyi/stock/mapper/StockInventoryMapper.java b/src/main/java/com/ruoyi/stock/mapper/StockInventoryMapper.java
index 29e85d9..d668368 100644
--- a/src/main/java/com/ruoyi/stock/mapper/StockInventoryMapper.java
+++ b/src/main/java/com/ruoyi/stock/mapper/StockInventoryMapper.java
@@ -3,6 +3,7 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.stock.dto.FinishedProductTreeDto;
import com.ruoyi.stock.dto.StockInRecordDto;
import com.ruoyi.stock.dto.StockInventoryDto;
import com.ruoyi.stock.execl.StockInventoryExportData;
@@ -54,4 +55,6 @@
List<StockInventoryDto> selectProductList();
List<StockInventoryDto> selectFinishedProductInventoryList(@Param("ew") StockInventoryDto stockInventoryDto);
+
+ List<FinishedProductTreeDto> selectFinishedProductList(@Param("ew") StockInventoryDto stockInventoryDto);
}
diff --git a/src/main/java/com/ruoyi/stock/service/StockInventoryService.java b/src/main/java/com/ruoyi/stock/service/StockInventoryService.java
index ddf851c..5fb5f8a 100644
--- a/src/main/java/com/ruoyi/stock/service/StockInventoryService.java
+++ b/src/main/java/com/ruoyi/stock/service/StockInventoryService.java
@@ -35,9 +35,9 @@
Boolean subtractStockInventory(StockInventoryDto stockInventoryDto);
- R importStockInventory(MultipartFile file);
+ R importStockInventory(MultipartFile file, Integer productType);
- void exportStockInventory(HttpServletResponse response, StockInventoryDto stockInventoryDto);
+ void exportStockInventory(HttpServletResponse response, StockInventoryDto stockInventoryDto, Integer productType);
IPage<StockInRecordDto> stockInventoryPage(StockInventoryDto stockInventoryDto,Page page);
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 5a2681f..bda2907 100644
--- a/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
+++ b/src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
@@ -16,17 +16,14 @@
import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
-import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.security.LoginUser;
import com.ruoyi.framework.web.domain.R;
-import com.ruoyi.stock.dto.FinishedProductTreeDto;
import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
-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.dto.*;
+import com.ruoyi.stock.execl.FinishedProductInventoryExportData;
+import com.ruoyi.stock.execl.NonFinishedProductInventoryExportData;
import com.ruoyi.stock.execl.StockInventoryExportData;
import com.ruoyi.stock.mapper.StockInventoryMapper;
import com.ruoyi.stock.pojo.StockInRecord;
@@ -45,12 +42,7 @@
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -79,40 +71,40 @@
return stockInventoryMapper.pagestockInventory(page, stockInventoryDto);
}
- /**
- * 鏌ヨ鎴愬搧搴撳瓨鏍戙��
- * 杩斿洖缁撴瀯娌跨敤鍩虹璧勬枡浜у搧鏍戯紝鍙跺瓙鑺傜偣琛ュ厖鎴愬搧搴撳瓨缁村害锛氬瀷鍙枫�佸伐搴忓垎绫汇�佺數鍘嬨��
- */
@Override
public List<FinishedProductTreeDto> finishedProductList(StockInventoryDto stockInventoryDto) {
- List<StockInventoryDto> inventoryList = stockInventoryMapper.selectFinishedProductInventoryList(stockInventoryDto);
- if (inventoryList.isEmpty()) {
+ // 鏌ヨ搴撳瓨鏁版嵁
+ List<FinishedProductTreeDto> dataList = stockInventoryMapper.selectFinishedProductList(stockInventoryDto);
+ if (dataList.isEmpty()) {
return new ArrayList<>();
}
- List<Product> allProducts = productMapper.selectList(null);
- Map<Long, Product> productMap = new HashMap<>();
- Map<Long, List<Product>> childrenMap = new HashMap<>();
- for (Product product : allProducts) {
- productMap.put(product.getId(), product);
- childrenMap.computeIfAbsent(product.getParentId(), key -> new ArrayList<>()).add(product);
+ // 鎸変骇鍝両D鍒嗙粍锛屾瀯寤烘爲褰㈢粨鏋�
+ Map<Long, FinishedProductTreeDto> productMap = new LinkedHashMap<>();
+ for (FinishedProductTreeDto data : dataList) {
+ Long productId = data.getProductId();
+ if (!productMap.containsKey(productId)) {
+ // 鍒涘缓浜у搧澶х被鑺傜偣
+ FinishedProductTreeDto productNode = new FinishedProductTreeDto();
+ productNode.setProductId(productId);
+ productNode.setProductName(data.getProductName());
+ productNode.setLabel(data.getLabel());
+ productNode.setChildren(new ArrayList<>());
+ productMap.put(productId, productNode);
+ }
+ // 娣诲姞搴撳瓨鍙跺瓙鑺傜偣
+ FinishedProductTreeDto leafNode = new FinishedProductTreeDto();
+ leafNode.setStockId(data.getStockId());
+ leafNode.setProductModelId(data.getProductModelId());
+ leafNode.setModel(data.getModel());
+ leafNode.setProcessCategory(data.getProcessCategory());
+ leafNode.setVoltage(data.getVoltage());
+ leafNode.setMaterialCode(data.getMaterialCode());
+ leafNode.setUnit(data.getUnit());
+ productMap.get(productId).getChildren().add(leafNode);
}
- Map<Long, List<FinishedProductTreeDto>> leafMap = buildFinishedProductLeafMap(inventoryList);
- Set<Long> visibleProductIds = collectVisibleProductIds(leafMap.keySet(), productMap);
-
- List<FinishedProductTreeDto> result = new ArrayList<>();
- for (Product rootProduct : allProducts) {
- if (!isFinishedRoot(rootProduct)) {
- continue;
- }
- FinishedProductTreeDto rootNode = buildProductNode(rootProduct);
- rootNode.setChildren(buildFinishedChildren(rootProduct.getId(), childrenMap, leafMap, visibleProductIds));
- if (!rootNode.getChildren().isEmpty()) {
- result.add(rootNode);
- }
- }
- return result;
+ return new ArrayList<>(productMap.values());
}
@Override
@@ -279,6 +271,25 @@
stockOutRecordDto.setType("0");
stockOutRecordService.add(stockOutRecordDto);
+ //閿�鍞嚭搴撴寜鐓т繚瀛樼殑搴撳瓨id
+ if (stockInventoryDto.getStockId() != null) {
+ StockInventory stockInventory = stockInventoryMapper.selectById(stockInventoryDto.getStockId());
+ if (ObjectUtils.isEmpty(stockInventory)) {
+ throw new RuntimeException("浜у搧搴撳瓨涓嶅瓨鍦�");
+ }
+ BigDecimal lockedQty = defaultDecimal(stockInventory.getLockedQuantity());
+ if (stockInventoryDto.getQualitity().compareTo(defaultDecimal(stockInventory.getQualitity()).subtract(lockedQty)) > 0) {
+ ProductModel productModel = productModelMapper.selectById(stockInventoryDto.getProductModelId());
+ Product product = productMapper.selectById(productModel.getProductId());
+ throw new RuntimeException(product.getProductName() + "/" + productModel.getModel() + "搴撳瓨涓嶈冻锛屾棤娉曞嚭搴�");
+ }
+ stockInventory.setQualitity(defaultDecimal(stockInventory.getQualitity()).subtract(stockInventoryDto.getQualitity()));
+ stockInventory.setVersion(stockInventory.getVersion() == null ? 1 : stockInventory.getVersion() + 1);
+ stockInventory.setUpdateTime(LocalDateTime.now());
+ stockInventoryMapper.updateById(stockInventory);
+ return true;
+ }
+
if (StringUtils.isBlank(stockInventoryDto.getBatchNo()) && !usesDimensionIdentity(normalizeDimension(stockInventoryDto.getProcessCategory()), normalizeDimension(stockInventoryDto.getVoltage()))) {
List<StockInventory> stockInventories = stockInventoryMapper.selectList(new QueryWrapper<StockInventory>().lambda()
.eq(StockInventory::getProductModelId, stockInventoryDto.getProductModelId())
@@ -335,7 +346,7 @@
}
@Override
- public R importStockInventory(MultipartFile file) {
+ public R importStockInventory(MultipartFile file, Integer productType) {
try {
List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductMapper.selectProduct();
Map<String, SalesLedgerProduct> productMap = new HashMap<>();
@@ -344,65 +355,129 @@
productMap.put(key, product);
}
- ExcelUtil<StockInventoryExportData> util = new ExcelUtil<>(StockInventoryExportData.class);
- List<StockInventoryExportData> list = util.importExcel(file.getInputStream());
List<String> unmatchedRecords = new ArrayList<>();
int successCount = 0;
- for (StockInventoryExportData dto : list) {
- String key = dto.getProductName() + "|" + dto.getModel();
- SalesLedgerProduct matchedProduct = productMap.get(key);
+ // productType: 1=鎴愬搧, 0=闈炴垚鍝�
+ if (productType == 1) {
+ // 鎴愬搧瀵煎叆锛堝寘鍚伐搴忕被鍒拰鐢靛帇锛�
+ ExcelUtil<FinishedProductInventoryExportData> util = new ExcelUtil<>(FinishedProductInventoryExportData.class);
+ List<FinishedProductInventoryExportData> list = util.importExcel(file.getInputStream());
- 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.getQualifiedQuantity());
- stockInventoryDto.setRemark(dto.getRemark());
- stockInventoryDto.setWarnNum(dto.getWarnNum());
- stockInventoryDto.setBatchNo(dto.getQualifiedBatchNo());
- stockInventoryDto.setProcessCategory(dto.getProcessCategory());
- stockInventoryDto.setVoltage(dto.getVoltage());
+ for (FinishedProductInventoryExportData dto : list) {
+ String key = dto.getProductName() + "|" + dto.getModel();
+ SalesLedgerProduct matchedProduct = productMap.get(key);
- if (ObjectUtils.isNotEmpty(dto.getQualifiedLockedQuantity())) {
- if (dto.getQualifiedLockedQuantity().compareTo(dto.getQualifiedQuantity()) > 0) {
- throw new RuntimeException("鍚堟牸鍐荤粨鏁伴噺涓嶈兘瓒呰繃鏈瀵煎叆鐨勫悎鏍煎簱瀛樻暟閲�");
+ 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.getQualifiedQuantity());
+ stockInventoryDto.setRemark(dto.getRemark());
+ stockInventoryDto.setWarnNum(dto.getWarnNum());
+ stockInventoryDto.setBatchNo(dto.getQualifiedBatchNo());
+ stockInventoryDto.setProcessCategory(dto.getProcessCategory());
+ stockInventoryDto.setVoltage(dto.getVoltage());
+
+ 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.getQualifiedLockedQuantity());
- } else {
- stockInventoryDto.setLockedQuantity(BigDecimal.ZERO);
+
+ stockInventoryDto.setProductModelId(matchedProduct.getProductModelId());
+ this.addstockInventory(stockInventoryDto);
+ successCount++;
}
- stockInventoryDto.setProductModelId(matchedProduct.getProductModelId());
- this.addstockInventory(stockInventoryDto);
- 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 (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("涓嶅悎鏍煎喕缁撴暟閲忎笉鑳借秴杩囨湰娆″鍏ョ殑涓嶅悎鏍煎簱瀛樻暟閲�");
+ 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.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);
+ }
+ }
+ } else {
+ // 闈炴垚鍝佸鍏ワ紙涓嶅寘鍚伐搴忕被鍒拰鐢靛帇锛�
+ ExcelUtil<NonFinishedProductInventoryExportData> util = new ExcelUtil<>(NonFinishedProductInventoryExportData.class);
+ List<NonFinishedProductInventoryExportData> list = util.importExcel(file.getInputStream());
+
+ for (NonFinishedProductInventoryExportData 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.getQualifiedQuantity());
+ stockInventoryDto.setRemark(dto.getRemark());
+ stockInventoryDto.setWarnNum(dto.getWarnNum());
+ 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.setProductModelId(matchedProduct.getProductModelId());
+ this.addstockInventory(stockInventoryDto);
+ successCount++;
}
- stockUninventoryDto.setProductModelId(matchedProduct.getProductModelId());
- stockUninventoryService.addStockUninventory(stockUninventoryDto);
- 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);
}
- } else {
- String unmatchedRecord = "浜у搧鍚嶇О锛�" + dto.getProductName() + "锛屽瀷鍙凤細" + dto.getModel() + " 鏈尮閰嶅埌搴撳瓨浜у搧";
- unmatchedRecords.add(unmatchedRecord);
}
}
@@ -423,10 +498,55 @@
}
@Override
- public void exportStockInventory(HttpServletResponse response, StockInventoryDto stockInventoryDto) {
+ public void exportStockInventory(HttpServletResponse response, StockInventoryDto stockInventoryDto, Integer productType) {
List<StockInventoryExportData> list = stockInventoryMapper.listStockInventoryExportData(stockInventoryDto);
- ExcelUtil<StockInventoryExportData> util = new ExcelUtil<>(StockInventoryExportData.class);
- util.exportExcel(response, list, "搴撳瓨淇℃伅");
+
+ // productType: 1=鎴愬搧, 0=闈炴垚鍝�
+ if (productType == 1) {
+ // 鎴愬搧瀵煎嚭锛堝寘鍚伐搴忕被鍒拰鐢靛帇锛�
+ List<FinishedProductInventoryExportData> finishedList = new ArrayList<>();
+ for (StockInventoryExportData data : list) {
+ FinishedProductInventoryExportData finishedData = new FinishedProductInventoryExportData();
+ finishedData.setProductName(data.getProductName());
+ finishedData.setModel(data.getModel());
+ finishedData.setUnit(data.getUnit());
+ finishedData.setMaterialCode(data.getMaterialCode());
+ finishedData.setProcessCategory(data.getProcessCategory());
+ finishedData.setVoltage(data.getVoltage());
+ finishedData.setQualifiedBatchNo(data.getQualifiedBatchNo());
+ finishedData.setUnQualifiedBatchNo(data.getUnQualifiedBatchNo());
+ finishedData.setQualifiedQuantity(data.getQualifiedQuantity());
+ finishedData.setUnQualifiedQuantity(data.getUnQualifiedQuantity());
+ finishedData.setWarnNum(data.getWarnNum());
+ finishedData.setQualifiedLockedQuantity(data.getQualifiedLockedQuantity());
+ finishedData.setUnQualifiedLockedQuantity(data.getUnQualifiedLockedQuantity());
+ finishedData.setRemark(data.getRemark());
+ finishedList.add(finishedData);
+ }
+ ExcelUtil<FinishedProductInventoryExportData> util = new ExcelUtil<>(FinishedProductInventoryExportData.class);
+ util.exportExcel(response, finishedList, "鎴愬搧搴撳瓨淇℃伅");
+ } else {
+ // 闈炴垚鍝佸鍑猴紙涓嶅寘鍚伐搴忕被鍒拰鐢靛帇锛�
+ List<NonFinishedProductInventoryExportData> nonFinishedList = new ArrayList<>();
+ for (StockInventoryExportData data : list) {
+ NonFinishedProductInventoryExportData nonFinishedData = new NonFinishedProductInventoryExportData();
+ nonFinishedData.setProductName(data.getProductName());
+ nonFinishedData.setModel(data.getModel());
+ nonFinishedData.setUnit(data.getUnit());
+ nonFinishedData.setMaterialCode(data.getMaterialCode());
+ nonFinishedData.setQualifiedBatchNo(data.getQualifiedBatchNo());
+ nonFinishedData.setUnQualifiedBatchNo(data.getUnQualifiedBatchNo());
+ nonFinishedData.setQualifiedQuantity(data.getQualifiedQuantity());
+ nonFinishedData.setUnQualifiedQuantity(data.getUnQualifiedQuantity());
+ nonFinishedData.setWarnNum(data.getWarnNum());
+ nonFinishedData.setQualifiedLockedQuantity(data.getQualifiedLockedQuantity());
+ nonFinishedData.setUnQualifiedLockedQuantity(data.getUnQualifiedLockedQuantity());
+ nonFinishedData.setRemark(data.getRemark());
+ nonFinishedList.add(nonFinishedData);
+ }
+ ExcelUtil<NonFinishedProductInventoryExportData> util = new ExcelUtil<>(NonFinishedProductInventoryExportData.class);
+ util.exportExcel(response, nonFinishedList, "闈炴垚鍝佸簱瀛樹俊鎭�");
+ }
}
@Override
@@ -505,89 +625,5 @@
private BigDecimal defaultDecimal(BigDecimal value) {
return value == null ? BigDecimal.ZERO : value;
- }
-
- private Map<Long, List<FinishedProductTreeDto>> buildFinishedProductLeafMap(List<StockInventoryDto> inventoryList) {
- Map<Long, List<FinishedProductTreeDto>> leafMap = new HashMap<>();
- for (StockInventoryDto inventory : inventoryList) {
- FinishedProductTreeDto leafNode = new FinishedProductTreeDto();
- leafNode.setId(inventory.getId() == null ? null : -inventory.getId());
- leafNode.setParentId(inventory.getProductId());
- leafNode.setProductId(inventory.getProductId());
- leafNode.setProductModelId(inventory.getProductModelId());
- leafNode.setProductName(inventory.getProductName());
- leafNode.setLabel(buildLeafLabel(inventory));
- leafNode.setModel(inventory.getModel());
- leafNode.setMaterialCode(inventory.getMaterialCode());
- leafNode.setProcessCategory(inventory.getProcessCategory());
- leafNode.setVoltage(inventory.getVoltage());
- leafNode.setChildren(new ArrayList<>());
- leafMap.computeIfAbsent(inventory.getProductId(), key -> new ArrayList<>()).add(leafNode);
- }
- return leafMap;
- }
-
- private Set<Long> collectVisibleProductIds(Set<Long> leafProductIds, Map<Long, Product> productMap) {
- Set<Long> visibleIds = new HashSet<>();
- for (Long productId : leafProductIds) {
- Long currentId = productId;
- while (currentId != null) {
- Product current = productMap.get(currentId);
- if (current == null) {
- break;
- }
- visibleIds.add(currentId);
- currentId = current.getParentId();
- }
- }
- return visibleIds;
- }
-
- private List<FinishedProductTreeDto> buildFinishedChildren(Long parentId,
- Map<Long, List<Product>> childrenMap,
- Map<Long, List<FinishedProductTreeDto>> leafMap,
- Set<Long> visibleProductIds) {
- List<FinishedProductTreeDto> children = new ArrayList<>();
- List<Product> childProducts = childrenMap.getOrDefault(parentId, new ArrayList<>());
- for (Product childProduct : childProducts) {
- if (!visibleProductIds.contains(childProduct.getId())) {
- continue;
- }
- FinishedProductTreeDto childNode = buildProductNode(childProduct);
- List<FinishedProductTreeDto> subChildren = buildFinishedChildren(childProduct.getId(), childrenMap, leafMap, visibleProductIds);
- subChildren.addAll(leafMap.getOrDefault(childProduct.getId(), new ArrayList<>()));
- childNode.setChildren(subChildren);
- children.add(childNode);
- }
- return children;
- }
-
- private FinishedProductTreeDto buildProductNode(Product product) {
- FinishedProductTreeDto node = new FinishedProductTreeDto();
- BeanUtils.copyProperties(product, node);
- node.setLabel(product.getProductName());
- node.setChildren(new ArrayList<>());
- return node;
- }
-
- private boolean isFinishedRoot(Product product) {
- return product.getParentId() == null && "鎴愬搧".equals(StringUtils.trimToEmpty(product.getProductName()));
- }
-
- private String buildLeafLabel(StockInventoryDto inventory) {
- List<String> parts = new ArrayList<>();
- if (StringUtils.isNotBlank(inventory.getProductName())) {
- parts.add(StringUtils.trim(inventory.getProductName()));
- }
- if (StringUtils.isNotBlank(inventory.getModel())) {
- parts.add(StringUtils.trim(inventory.getModel()));
- }
- if (StringUtils.isNotBlank(inventory.getProcessCategory())) {
- parts.add(StringUtils.trim(inventory.getProcessCategory()));
- }
- if (StringUtils.isNotBlank(inventory.getVoltage())) {
- parts.add(StringUtils.trim(inventory.getVoltage()));
- }
- return String.join(" / ", parts);
}
}
diff --git a/src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java b/src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java
index cb8c395..08be3ba 100644
--- a/src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java
+++ b/src/main/java/com/ruoyi/stock/service/impl/StockOutRecordServiceImpl.java
@@ -10,6 +10,7 @@
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.EnumUtil;
import com.ruoyi.common.utils.OrderUtils;
+import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.stock.dto.StockInventoryDto;
@@ -49,7 +50,11 @@
@Override
public IPage<StockOutRecordDto> listPage(Page page, StockOutRecordDto stockOutRecordDto) {
- return stockOutRecordMapper.listPage(page, stockOutRecordDto);
+ IPage<StockOutRecordDto> result = stockOutRecordMapper.listPage(page, stockOutRecordDto);
+ for (StockOutRecordDto record : result.getRecords()) {
+ record.setRecordTypeName(resolveRecordTypeName(record.getType(), record.getRecordType(), record.getProcessName()));
+ }
+ return result;
}
@Override
@@ -131,7 +136,7 @@
List<StockOutRecordExportData> list = stockOutRecordMapper.listStockOutRecordExportData(stockOutRecordDto);
for (StockOutRecordExportData stockInRecordExportData : list) {
if (stockInRecordExportData.getType().equals("0")) {
- stockInRecordExportData.setRecordType(EnumUtil.fromCode(StockOutQualifiedRecordTypeEnum.class, Integer.parseInt(stockInRecordExportData.getRecordType())).getValue());
+ stockInRecordExportData.setRecordType(resolveQualifiedRecordType(stockInRecordExportData.getRecordType(), stockInRecordExportData.getProcessName()));
}else {
stockInRecordExportData.setRecordType(EnumUtil.fromCode(StockOutUnQualifiedRecordTypeEnum.class, Integer.parseInt(stockInRecordExportData.getRecordType())).getValue());
}
@@ -139,4 +144,26 @@
ExcelUtil<StockOutRecordExportData> util = new ExcelUtil<>(StockOutRecordExportData.class);
util.exportExcel(response,list, "鍑哄簱璁板綍淇℃伅");
}
-}
\ No newline at end of file
+
+ private String resolveRecordTypeName(String type, String recordType, String processName) {
+ if ("0".equals(type)) {
+ return resolveQualifiedRecordType(recordType, processName);
+ }
+ return EnumUtil.fromCode(StockOutUnQualifiedRecordTypeEnum.class, Integer.parseInt(recordType)).getValue();
+ }
+
+ private String resolveQualifiedRecordType(String recordType, String processName) {
+ if (StockOutQualifiedRecordTypeEnum.PRODUCTION_REPORT_STOCK_OUT.getCode().equals(recordType)
+ && StringUtils.isNotEmpty(processName)) {
+ return "鐢熶骇鎶ュ伐-" + processName + "-鍑哄簱";
+ }
+ if (recordType == null) {
+ return null;
+ }
+ try {
+ return EnumUtil.fromCode(StockOutQualifiedRecordTypeEnum.class, Integer.parseInt(recordType)).getValue();
+ } catch (NumberFormatException ex) {
+ return recordType;
+ }
+ }
+}
diff --git a/src/main/resources/mapper/approve/ApproveProcessMapper.xml b/src/main/resources/mapper/approve/ApproveProcessMapper.xml
index 33b29a9..ca02119 100644
--- a/src/main/resources/mapper/approve/ApproveProcessMapper.xml
+++ b/src/main/resources/mapper/approve/ApproveProcessMapper.xml
@@ -38,5 +38,6 @@
<if test="req.approveType != null ">
and approve_type = #{req.approveType}
</if>
+ order by approve_time desc
</select>
</mapper>
diff --git a/src/main/resources/mapper/production/ProductBomMapper.xml b/src/main/resources/mapper/production/ProductBomMapper.xml
index 4ac2125..7ce0192 100644
--- a/src/main/resources/mapper/production/ProductBomMapper.xml
+++ b/src/main/resources/mapper/production/ProductBomMapper.xml
@@ -36,6 +36,7 @@
<if test="c.version != null">
and version = #{c.version}
</if>
+ order by create_time desc
</select>
<select id="getById" resultType="com.ruoyi.production.dto.ProductBomDto">
select pb.*,
diff --git a/src/main/resources/mapper/sales/SalesLedgerMapper.xml b/src/main/resources/mapper/sales/SalesLedgerMapper.xml
index fe36cdc..243b400 100644
--- a/src/main/resources/mapper/sales/SalesLedgerMapper.xml
+++ b/src/main/resources/mapper/sales/SalesLedgerMapper.xml
@@ -69,7 +69,7 @@
T1.delivery_date,
DATEDIFF(T1.delivery_date, CURDATE()) AS delivery_days_diff,
product_summary.model,
- '' AS voltage,
+ product_summary.voltage,
product_summary.qty,
CASE
WHEN shipping_status_counts.total_count = 0 THEN false
@@ -90,7 +90,8 @@
SELECT
sales_ledger_id,
GROUP_CONCAT(IFNULL(specification_model, '') ORDER BY id SEPARATOR ',') AS model,
- GROUP_CONCAT(IFNULL(CAST(quantity AS CHAR), '') ORDER BY id SEPARATOR ',') AS qty
+ GROUP_CONCAT(IFNULL(CAST(quantity AS CHAR), '') ORDER BY id SEPARATOR ',') AS qty,
+ GROUP_CONCAT(IFNULL(SUBSTRING_INDEX(specification_model, '-', -1), '') ORDER BY id SEPARATOR ',') AS voltage
FROM sales_ledger_product
WHERE type = 1
GROUP BY sales_ledger_id
diff --git a/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml b/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
index 7f11d07..5d1232c 100644
--- a/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
+++ b/src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
@@ -14,10 +14,9 @@
END as has_sufficient_stock
FROM
sales_ledger_product T1
- LEFT JOIN (
- select product_model_id,SUM(qualitity) as qualitity,sum(locked_quantity) as locked_quantity from stock_inventory
- group by product_model_id
- ) t2 ON T1.product_model_id = t2.product_model_id
+ LEFT JOIN stock_inventory t2
+ ON T1.product_model_id = t2.product_model_id
+ AND t2.id = T1.stock_id
LEFT JOIN product_model T3 ON T1.product_model_id = T3.id
<where>
<if test="salesLedgerProduct.salesLedgerId != null">
diff --git a/src/main/resources/mapper/stock/StockInventoryMapper.xml b/src/main/resources/mapper/stock/StockInventoryMapper.xml
index e23f2fd..72f6e6f 100644
--- a/src/main/resources/mapper/stock/StockInventoryMapper.xml
+++ b/src/main/resources/mapper/stock/StockInventoryMapper.xml
@@ -90,6 +90,7 @@
<if test="ew.voltage != null and ew.voltage != ''">
AND si.voltage = #{ew.voltage}
</if>
+ order by si.create_time desc
</select>
<select id="pageListCombinedStockInventory" resultType="com.ruoyi.stock.dto.StockInventoryDto">
@@ -510,4 +511,36 @@
order by p.id asc, pm.id asc, si.id asc
</select>
+ <select id="selectFinishedProductList" resultType="com.ruoyi.stock.dto.FinishedProductTreeDto">
+ select si.id as stockId,
+ p.id as productId,
+ p.product_name as productName,
+ p.product_name as label,
+ pm.id as productModelId,
+ pm.model,
+ si.process_category as processCategory,
+ si.voltage,
+ pm.material_code as materialCode,
+ pm.unit
+ from stock_inventory si
+ inner join product_model pm on si.product_model_id = pm.id
+ inner join product p on pm.product_id = p.id
+ inner join product pp on p.parent_id = pp.id
+ <where>
+ pp.product_name = '鎴愬搧'
+ <if test="ew.productName != null and ew.productName != ''">
+ and (p.product_name like concat('%', #{ew.productName}, '%')
+ or pm.model like concat('%', #{ew.productName}, '%')
+ or pm.material_code like concat('%', #{ew.productName}, '%'))
+ </if>
+ <if test="ew.processCategory != null and ew.processCategory != ''">
+ and si.process_category = #{ew.processCategory}
+ </if>
+ <if test="ew.voltage != null and ew.voltage != ''">
+ and si.voltage = #{ew.voltage}
+ </if>
+ </where>
+ order by p.id asc, pm.id asc, si.id asc
+ </select>
+
</mapper>
diff --git a/src/main/resources/mapper/stock/StockOutRecordMapper.xml b/src/main/resources/mapper/stock/StockOutRecordMapper.xml
index 3c21f33..782f525 100644
--- a/src/main/resources/mapper/stock/StockOutRecordMapper.xml
+++ b/src/main/resources/mapper/stock/StockOutRecordMapper.xml
@@ -35,11 +35,15 @@
pm.model,
pm.unit,
pm.material_code as materialCode,
- u.nick_name as createBy
+ u.nick_name as createBy,
+ pp.name as processName
FROM stock_out_record as sor
LEFT JOIN product_model as pm on sor.product_model_id = pm.id
LEFT JOIN product as p on pm.product_id = p.id
LEFT JOIN sys_user as u on sor.create_user = u.user_id
+ LEFT JOIN production_product_main as ppm on sor.record_type = '3' and ppm.id = sor.record_id
+ LEFT JOIN product_process_route_item as ppri on ppri.id = ppm.product_process_route_item_id
+ LEFT JOIN product_process as pp on pp.id = ppri.process_id
<where>
<if test="params.timeStr != null and params.timeStr != ''">
and sor.create_time like concat('%',#{params.timeStr},'%')
@@ -77,11 +81,15 @@
pm.model,
pm.unit,
pm.material_code as materialCode,
- u.nick_name as createBy
+ u.nick_name as createBy,
+ pp.name as processName
FROM stock_out_record as sor
LEFT JOIN product_model as pm on sor.product_model_id = pm.id
LEFT JOIN product as p on pm.product_id = p.id
LEFT JOIN sys_user as u on sor.create_user = u.user_id
+ LEFT JOIN production_product_main as ppm on sor.record_type = '3' and ppm.id = sor.record_id
+ LEFT JOIN product_process_route_item as ppri on ppri.id = ppm.product_process_route_item_id
+ LEFT JOIN product_process as pp on pp.id = ppri.process_id
<where>
<if test="params.timeStr != null and params.timeStr != ''">
and sor.create_time like concat('%',#{params.timeStr},'%')
@@ -102,4 +110,4 @@
order by sor.id desc
</select>
-</mapper>
\ No newline at end of file
+</mapper>
--
Gitblit v1.9.3