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.metadata.IPage;
|
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
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.ProductMapper;
|
import com.ruoyi.basic.mapper.ProductModelMapper;
|
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.StringUtils;
|
import com.ruoyi.common.utils.poi.ExcelUtil;
|
import com.ruoyi.framework.security.LoginUser;
|
import com.ruoyi.framework.web.domain.R;
|
import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
|
import com.ruoyi.sales.pojo.SalesLedgerProduct;
|
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;
|
import com.ruoyi.stock.pojo.StockInventory;
|
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;
|
import org.springframework.web.multipart.MultipartFile;
|
|
import javax.servlet.http.HttpServletResponse;
|
import java.math.BigDecimal;
|
import java.time.LocalDate;
|
import java.time.LocalDateTime;
|
import java.time.format.DateTimeFormatter;
|
import java.util.*;
|
import java.util.regex.Matcher;
|
import java.util.regex.Pattern;
|
|
@Service
|
public class StockInventoryServiceImpl extends ServiceImpl<StockInventoryMapper, StockInventory> implements StockInventoryService {
|
|
@Autowired
|
private StockInventoryMapper stockInventoryMapper;
|
@Autowired
|
private StockInRecordService stockInRecordService;
|
@Autowired
|
private StockOutRecordService stockOutRecordService;
|
@Autowired
|
private SalesLedgerProductMapper salesLedgerProductMapper;
|
@Autowired
|
private ApproveProcessServiceImpl approveProcessService;
|
@Autowired
|
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 List<FinishedProductTreeDto> finishedProductList(StockInventoryDto stockInventoryDto) {
|
// 查询库存数据
|
List<FinishedProductTreeDto> dataList = stockInventoryMapper.selectFinishedProductList(stockInventoryDto);
|
if (dataList.isEmpty()) {
|
return new ArrayList<>();
|
}
|
|
// 按产品ID分组,构建树形结构
|
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);
|
}
|
|
return new ArrayList<>(productMap.values());
|
}
|
|
@Override
|
public IPage<StockInventoryDto> pageListCombinedStockInventory(Page page, StockInventoryDto stockInventoryDto) {
|
return stockInventoryMapper.pageListCombinedStockInventory(page, stockInventoryDto);
|
}
|
|
/**
|
* 合格入库:先生成入库记录,再走审批流。
|
*/
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public Boolean addstockInventory(StockInventoryDto stockInventoryDto) {
|
List<StockInventory> stockInventoryList = stockInventoryMapper.selectList(null);
|
StockInRecordDto stockInRecordDto = new StockInRecordDto();
|
stockInRecordDto.setRecordId(stockInventoryDto.getRecordId());
|
stockInRecordDto.setRecordType(stockInventoryDto.getRecordType());
|
stockInRecordDto.setStockInNum(stockInventoryDto.getQualitity());
|
stockInRecordDto.setProductModelId(stockInventoryDto.getProductModelId());
|
stockInRecordDto.setRemark(stockInventoryDto.getRemark());
|
stockInRecordDto.setWarnNum(stockInventoryDto.getWarnNum());
|
stockInRecordDto.setLockedQuantity(stockInventoryDto.getLockedQuantity());
|
stockInRecordDto.setProcessCategory(normalizeDimension(stockInventoryDto.getProcessCategory()));
|
stockInRecordDto.setVoltage(normalizeDimension(stockInventoryDto.getVoltage()));
|
stockInRecordDto.setApproveStatus(0);
|
stockInRecordDto.setType("0");
|
if (StringUtils.isBlank(stockInventoryDto.getBatchNo())) {
|
String batchNo;
|
LocalDate now = LocalDate.now();
|
String monthFlag = now.format(DateTimeFormatter.ofPattern("MM"));
|
int maxSeq = getCurrentMonthMaxSeq(stockInventoryDto, monthFlag, stockInventoryList);
|
int newSeq = maxSeq + 1;
|
String seqStr = String.format("%03d", newSeq);
|
ProductModel productModel = productModelMapper.selectById(stockInventoryDto.getProductModelId());
|
batchNo = stockInventoryDto.getMaterialCode() + productModel.getModel() + "P" + monthFlag + seqStr;
|
stockInRecordDto.setBatchNo(batchNo);
|
} else {
|
stockInRecordDto.setBatchNo(stockInventoryDto.getBatchNo());
|
}
|
Long id = stockInRecordService.add(stockInRecordDto);
|
LoginUser loginUser = SecurityUtils.getLoginUser();
|
if (id != null) {
|
try {
|
addApproveByPurchase(loginUser, stockInRecordDto, id);
|
} catch (Exception e) {
|
throw new RuntimeException(e.getMessage());
|
}
|
}
|
return true;
|
}
|
|
private static int getCurrentMonthMaxSeq(StockInventoryDto dto, String monthFlag, List<StockInventory> existingList) {
|
int maxSeq = 0;
|
String prefix = dto.getMaterialCode() + dto.getProductModelName() + "P" + monthFlag;
|
Pattern pattern = Pattern.compile(Pattern.quote(prefix) + "(\\d{3})");
|
for (StockInventory 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;
|
}
|
|
@Override
|
public void addApproveByPurchase(LoginUser loginUser, StockInRecordDto stockInRecordDto, Long id) throws Exception {
|
ApproveProcessVO approveProcessVO = new ApproveProcessVO();
|
approveProcessVO.setApproveType(9);
|
approveProcessVO.setApproveDeptId(loginUser.getCurrentDeptId());
|
approveProcessVO.setApproveReason(stockInRecordDto.getInboundBatches());
|
approveProcessVO.setApproveUserIds(String.valueOf(1));
|
approveProcessVO.setApproveUser(loginUser.getUserId());
|
approveProcessVO.setApproveTime(LocalDate.now().toString());
|
approveProcessVO.setInventoryReview(false);
|
approveProcessVO.setStorageType("合格入库");
|
approveProcessVO.setRecordId(id);
|
approveProcessService.addApprove(approveProcessVO);
|
}
|
|
/**
|
* 按库存唯一键合并库存。
|
* 成品使用 product_model_id + processCategory + voltage;其他入库只按 product_model_id。
|
*/
|
@Override
|
public void updateOrCreateStockInventory(StockInRecord stockInRecord) {
|
String processCategory = normalizeDimension(stockInRecord.getProcessCategory());
|
String voltage = normalizeDimension(stockInRecord.getVoltage());
|
StockInventory oldStockInventory = findInventoryForMerge(
|
stockInRecord.getProductModelId(),
|
processCategory,
|
voltage
|
);
|
|
if (ObjectUtils.isEmpty(oldStockInventory)) {
|
StockInventory newStockInventory = new StockInventory();
|
newStockInventory.setProductModelId(stockInRecord.getProductModelId());
|
newStockInventory.setQualitity(defaultDecimal(stockInRecord.getStockInNum()));
|
newStockInventory.setVersion(1);
|
newStockInventory.setRemark(stockInRecord.getRemark());
|
newStockInventory.setLockedQuantity(defaultDecimal(stockInRecord.getLockedQuantity()));
|
newStockInventory.setWarnNum(stockInRecord.getWarnNum());
|
newStockInventory.setProcessCategory(processCategory);
|
newStockInventory.setVoltage(voltage);
|
newStockInventory.setBatchNo(StringUtils.trimToEmpty(stockInRecord.getBatchNo()));
|
stockInventoryMapper.insert(newStockInventory);
|
return;
|
}
|
|
oldStockInventory.setQualitity(defaultDecimal(oldStockInventory.getQualitity()).add(defaultDecimal(stockInRecord.getStockInNum())));
|
oldStockInventory.setVersion(oldStockInventory.getVersion() == null ? 1 : oldStockInventory.getVersion() + 1);
|
if (StringUtils.isNotBlank(stockInRecord.getRemark())) {
|
oldStockInventory.setRemark(stockInRecord.getRemark());
|
}
|
if (stockInRecord.getWarnNum() != null) {
|
oldStockInventory.setWarnNum(stockInRecord.getWarnNum());
|
}
|
if (stockInRecord.getLockedQuantity() != null) {
|
oldStockInventory.setLockedQuantity(defaultDecimal(oldStockInventory.getLockedQuantity()).add(stockInRecord.getLockedQuantity()));
|
}
|
oldStockInventory.setProcessCategory(processCategory);
|
oldStockInventory.setVoltage(voltage);
|
oldStockInventory.setUpdateTime(LocalDateTime.now());
|
stockInventoryMapper.updateById(oldStockInventory);
|
}
|
|
/**
|
* 不审核入库,直接写入入库记录和库存。
|
*/
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public Boolean addstockInventoryNoReview(StockInventoryDto stockInventoryDto) {
|
StockInRecordDto stockInRecordDto = new StockInRecordDto();
|
stockInRecordDto.setRecordId(stockInventoryDto.getRecordId());
|
stockInRecordDto.setRecordType(stockInventoryDto.getRecordType());
|
stockInRecordDto.setStockInNum(stockInventoryDto.getQualitity());
|
stockInRecordDto.setProductModelId(stockInventoryDto.getProductModelId());
|
stockInRecordDto.setRemark(stockInventoryDto.getRemark());
|
stockInRecordDto.setWarnNum(stockInventoryDto.getWarnNum());
|
stockInRecordDto.setLockedQuantity(stockInventoryDto.getLockedQuantity());
|
stockInRecordDto.setProcessCategory(normalizeDimension(stockInventoryDto.getProcessCategory()));
|
stockInRecordDto.setVoltage(normalizeDimension(stockInventoryDto.getVoltage()));
|
stockInRecordDto.setBatchNo(stockInventoryDto.getBatchNo());
|
stockInRecordDto.setType("0");
|
stockInRecordService.add(stockInRecordDto);
|
updateOrCreateStockInventory(toStockInRecord(stockInRecordDto));
|
return true;
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public Boolean subtractStockInventory(StockInventoryDto stockInventoryDto) {
|
if (stockInventoryDto.getQualitity() != null
|
&& stockInventoryDto.getQualitity().compareTo(BigDecimal.ZERO) == 0) {
|
return true;
|
}
|
|
StockOutRecordDto stockOutRecordDto = new StockOutRecordDto();
|
stockOutRecordDto.setRecordId(stockInventoryDto.getRecordId());
|
stockOutRecordDto.setRecordType(stockInventoryDto.getRecordType());
|
stockOutRecordDto.setStockOutNum(stockInventoryDto.getQualitity());
|
stockOutRecordDto.setProductModelId(stockInventoryDto.getProductModelId());
|
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())
|
.orderByAsc(StockInventory::getId));
|
if (ObjectUtils.isEmpty(stockInventories)) {
|
throw new RuntimeException("产品库存不存在");
|
}
|
|
BigDecimal remainingQty = stockInventoryDto.getQualitity() == null ? BigDecimal.ZERO : stockInventoryDto.getQualitity();
|
for (StockInventory stockInventory : stockInventories) {
|
BigDecimal lockedQty = defaultDecimal(stockInventory.getLockedQuantity());
|
BigDecimal availableQty = defaultDecimal(stockInventory.getQualitity()).subtract(lockedQty);
|
if (availableQty.compareTo(BigDecimal.ZERO) <= 0) {
|
continue;
|
}
|
|
BigDecimal deductQty = remainingQty.min(availableQty);
|
stockInventory.setQualitity(defaultDecimal(stockInventory.getQualitity()).subtract(deductQty));
|
stockInventory.setVersion(stockInventory.getVersion() == null ? 1 : stockInventory.getVersion() + 1);
|
stockInventory.setUpdateTime(LocalDateTime.now());
|
stockInventoryMapper.updateById(stockInventory);
|
|
remainingQty = remainingQty.subtract(deductQty);
|
if (remainingQty.compareTo(BigDecimal.ZERO) <= 0) {
|
return true;
|
}
|
}
|
|
ProductModel productModel = productModelMapper.selectById(stockInventoryDto.getProductModelId());
|
Product product = productMapper.selectById(productModel.getProductId());
|
throw new RuntimeException(product.getProductName() + "/" + productModel.getModel() + "库存不足,无法出库");
|
}
|
|
StockInventory oldStockInventory = findInventoryForMerge(
|
stockInventoryDto.getProductModelId(),
|
stockInventoryDto.getProcessCategory(),
|
stockInventoryDto.getVoltage()
|
);
|
if (ObjectUtils.isEmpty(oldStockInventory)) {
|
throw new RuntimeException("产品库存不存在");
|
}
|
BigDecimal lockedQty = defaultDecimal(oldStockInventory.getLockedQuantity());
|
if (stockInventoryDto.getQualitity().compareTo(defaultDecimal(oldStockInventory.getQualitity()).subtract(lockedQty)) > 0) {
|
ProductModel productModel = productModelMapper.selectById(stockInventoryDto.getProductModelId());
|
Product product = productMapper.selectById(productModel.getProductId());
|
throw new RuntimeException(product.getProductName() + "/" + productModel.getModel() + "库存不足,无法出库");
|
}
|
|
oldStockInventory.setQualitity(defaultDecimal(oldStockInventory.getQualitity()).subtract(stockInventoryDto.getQualitity()));
|
oldStockInventory.setVersion(oldStockInventory.getVersion() == null ? 1 : oldStockInventory.getVersion() + 1);
|
oldStockInventory.setUpdateTime(LocalDateTime.now());
|
stockInventoryMapper.updateById(oldStockInventory);
|
return true;
|
}
|
|
@Override
|
public R importStockInventory(MultipartFile file, Integer productType) {
|
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);
|
}
|
|
List<String> unmatchedRecords = new ArrayList<>();
|
int successCount = 0;
|
|
// productType: 1=成品, 0=非成品
|
if (productType == 1) {
|
// 成品导入(包含工序类别和电压)
|
ExcelUtil<FinishedProductInventoryExportData> util = new ExcelUtil<>(FinishedProductInventoryExportData.class);
|
List<FinishedProductInventoryExportData> list = util.importExcel(file.getInputStream());
|
|
for (FinishedProductInventoryExportData 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());
|
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.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 (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 {
|
// 非成品导入(不包含工序类别和电压)
|
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++;
|
}
|
|
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);
|
}
|
}
|
}
|
|
StringBuilder message = new StringBuilder();
|
if (!unmatchedRecords.isEmpty()) {
|
message.append("导入成功 ").append(successCount).append(" 条记录,以下产品未匹配:\n");
|
for (String record : unmatchedRecords) {
|
message.append(record).append("\n");
|
}
|
return R.ok(message.toString());
|
}
|
|
return R.ok("导入成功,共处理 " + successCount + " 条记录");
|
} catch (Exception e) {
|
log.error("库存导入失败", e);
|
return R.fail("库存导入失败:" + e.getMessage());
|
}
|
}
|
|
@Override
|
public void exportStockInventory(HttpServletResponse response, StockInventoryDto stockInventoryDto, Integer productType) {
|
List<StockInventoryExportData> list = stockInventoryMapper.listStockInventoryExportData(stockInventoryDto);
|
|
// 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
|
public IPage<StockInRecordDto> stockInventoryPage(StockInventoryDto stockInventoryDto, Page page) {
|
return stockInventoryMapper.stockInventoryPage(stockInventoryDto, page);
|
}
|
|
@Override
|
public IPage<StockInventoryDto> stockInAndOutRecord(StockInventoryDto stockInventoryDto, Page page) {
|
return stockInventoryMapper.stockInAndOutRecord(stockInventoryDto, page);
|
}
|
|
@Override
|
public Boolean frozenStock(StockInventoryDto stockInventoryDto) {
|
StockInventory stockInventory = stockInventoryMapper.selectById(stockInventoryDto.getId());
|
if (stockInventory.getQualitity().compareTo(stockInventoryDto.getLockedQuantity()) < 0) {
|
throw new RuntimeException("冻结数量不能超过库存数量");
|
}
|
if (ObjectUtils.isEmpty(stockInventory.getLockedQuantity())) {
|
stockInventory.setLockedQuantity(stockInventoryDto.getLockedQuantity());
|
} else {
|
stockInventory.setLockedQuantity(stockInventory.getLockedQuantity().add(stockInventoryDto.getLockedQuantity()));
|
}
|
return this.updateById(stockInventory);
|
}
|
|
@Override
|
public Boolean thawStock(StockInventoryDto stockInventoryDto) {
|
StockInventory stockInventory = stockInventoryMapper.selectById(stockInventoryDto.getId());
|
if (stockInventory.getLockedQuantity().compareTo(stockInventoryDto.getLockedQuantity()) < 0) {
|
throw new RuntimeException("解冻数量不能超过冻结数量");
|
}
|
stockInventory.setLockedQuantity(stockInventory.getLockedQuantity().subtract(stockInventoryDto.getLockedQuantity()));
|
return this.updateById(stockInventory);
|
}
|
|
// 入库合并唯一键:成品按类别和电压,其余只按产品规格。
|
private StockInventory findInventoryForMerge(Long productModelId, String processCategory, String voltage) {
|
LambdaQueryWrapper<StockInventory> queryWrapper = new LambdaQueryWrapper<StockInventory>()
|
.eq(StockInventory::getProductModelId, productModelId)
|
.orderByAsc(StockInventory::getId);
|
if (usesDimensionIdentity(processCategory, voltage)) {
|
queryWrapper.eq(StockInventory::getProcessCategory, normalizeDimension(processCategory));
|
queryWrapper.eq(StockInventory::getVoltage, normalizeDimension(voltage));
|
}
|
List<StockInventory> inventories = stockInventoryMapper.selectList(queryWrapper);
|
return inventories.isEmpty() ? null : inventories.get(0);
|
}
|
|
// 将入库记录 DTO 复制为持久化实体。
|
private StockInRecord toStockInRecord(StockInRecordDto stockInRecordDto) {
|
StockInRecord stockInRecord = new StockInRecord();
|
stockInRecord.setRecordId(stockInRecordDto.getRecordId());
|
stockInRecord.setRecordType(stockInRecordDto.getRecordType());
|
stockInRecord.setStockInNum(stockInRecordDto.getStockInNum());
|
stockInRecord.setProductModelId(stockInRecordDto.getProductModelId());
|
stockInRecord.setRemark(stockInRecordDto.getRemark());
|
stockInRecord.setType(stockInRecordDto.getType());
|
stockInRecord.setLockedQuantity(stockInRecordDto.getLockedQuantity());
|
stockInRecord.setWarnNum(stockInRecordDto.getWarnNum());
|
stockInRecord.setApproveStatus(stockInRecordDto.getApproveStatus());
|
stockInRecord.setBatchNo(stockInRecordDto.getBatchNo());
|
stockInRecord.setProcessCategory(stockInRecordDto.getProcessCategory());
|
stockInRecord.setVoltage(stockInRecordDto.getVoltage());
|
return stockInRecord;
|
}
|
|
// 只要带有成品维度,就按维度作为唯一键。
|
private boolean usesDimensionIdentity(String processCategory, String voltage) {
|
return StringUtils.isNotBlank(processCategory) || StringUtils.isNotBlank(voltage);
|
}
|
|
private String normalizeDimension(String value) {
|
return StringUtils.trimToEmpty(value);
|
}
|
|
private BigDecimal defaultDecimal(BigDecimal value) {
|
return value == null ? BigDecimal.ZERO : value;
|
}
|
}
|