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;
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.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;
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.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;
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 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;
/**
*
* 不合格库存表 服务实现类
*
*
* @author 芯导软件(江苏)有限公司
* @since 2026-01-22 10:17:45
*/
@Service
public class StockUninventoryServiceImpl extends ServiceImpl implements StockUninventoryService {
@Autowired
private StockUninventoryMapper stockUninventoryMapper;
@Autowired
private StockOutRecordService stockOutRecordService;
@Autowired
private StockInRecordService stockInRecordService;
@Autowired
private ApproveProcessServiceImpl approveProcessService;
@Autowired
private ProductModelMapper productModelMapper;
@Override
public IPage pageStockUninventory(Page page, StockUninventoryDto stockUninventoryDto) {
return stockUninventoryMapper.pageStockUninventory(page, stockUninventoryDto);
}
@Override
@Transactional(rollbackFor = Exception.class)
public Integer addStockUninventory(StockUninventoryDto stockUninventoryDto) {
List stockUninventoryList = stockUninventoryMapper.selectList(null);
//新增入库记录再添加库存
StockInRecordDto stockInRecordDto = new StockInRecordDto();
stockInRecordDto.setRecordId(stockUninventoryDto.getRecordId());
stockInRecordDto.setRecordType(stockUninventoryDto.getRecordType());
stockInRecordDto.setStockInNum(stockUninventoryDto.getQualitity());
stockInRecordDto.setProductModelId(stockUninventoryDto.getProductModelId());
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();
if (id != null) {
try {
addApproveByPurchase(loginUser, stockInRecordDto,id);
} catch (Exception e) {
e.printStackTrace();
}
}
return 1;
}
/**
* 查询当前月份已存在的最大流水号
*/
private static int getCurrentMonthMaxSeq(StockUninventoryDto dto, String monthFlag, List existingList) {
int maxSeq = 0;
String prefix = dto.getMaterialCode() + dto.getModel() + "P" + monthFlag;
// 正则匹配:前缀 + 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 {
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);
}
@Override
public Integer addStockUninventoryNoReview(StockUninventoryDto stockUninventoryDto) {
//新增入库记录再添加库存
StockInRecordDto stockInRecordDto = new StockInRecordDto();
stockInRecordDto.setRecordId(stockUninventoryDto.getRecordId());
stockInRecordDto.setRecordType(stockUninventoryDto.getRecordType());
stockInRecordDto.setStockInNum(stockUninventoryDto.getQualitity());
stockInRecordDto.setProductModelId(stockUninventoryDto.getProductModelId());
stockInRecordDto.setType("1");
stockInRecordService.add(stockInRecordDto);
//再进行新增库存数量库存
//先查询库存表中的产品是否存在,不存在新增,存在更新
StockUninventory oldStockUnInventory = stockUninventoryMapper.selectOne(new QueryWrapper().lambda().eq(StockUninventory::getProductModelId, stockUninventoryDto.getProductModelId()));
if (ObjectUtils.isEmpty(oldStockUnInventory)) {
StockUninventory newStockUnInventory = new StockUninventory();
newStockUnInventory.setProductModelId(stockUninventoryDto.getProductModelId());
newStockUnInventory.setQualitity(stockUninventoryDto.getQualitity());
newStockUnInventory.setVersion(1);
newStockUnInventory.setRemark(stockUninventoryDto.getRemark());
stockUninventoryMapper.insert(newStockUnInventory);
}else {
stockUninventoryMapper.updateAddStockUnInventory(stockUninventoryDto);
}
return 1;
}
/**
* 更新或创建非良品库存信息
*
* @param stockInRecord 非良品库存DTO对象
*/
public void updateOrCreateStockUninventory(StockInRecord stockInRecord) {
// 先查询库存表中的产品是否存在
LambdaQueryWrapper queryWrapper = new QueryWrapper().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)) {
// 不存在则新增
StockUninventory newStockUnInventory = new StockUninventory();
newStockUnInventory.setProductModelId(stockInRecord.getProductModelId());
newStockUnInventory.setQualitity(stockInRecord.getStockInNum());
newStockUnInventory.setVersion(1);
newStockUnInventory.setRemark(stockInRecord.getRemark());
newStockUnInventory.setLockedQuantity(stockInRecord.getLockedQuantity());
newStockUnInventory.setBatchNo(stockInRecord.getBatchNo());
stockUninventoryMapper.insert(newStockUnInventory);
} else {
// 存在则更新
LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>();
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(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);
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public Integer subtractStockUninventory(StockUninventoryDto stockUninventoryDto) {
// 新增出库记录
StockOutRecordDto stockOutRecordDto = new StockOutRecordDto();
stockOutRecordDto.setRecordId(stockUninventoryDto.getRecordId());
stockOutRecordDto.setRecordType(stockUninventoryDto.getRecordType());
stockOutRecordDto.setStockOutNum(stockUninventoryDto.getQualitity());
stockOutRecordDto.setProductModelId(stockUninventoryDto.getProductModelId());
stockOutRecordDto.setType("1");
stockOutRecordService.add(stockOutRecordDto);
StockUninventory oldStockInventory = stockUninventoryMapper.selectOne(new QueryWrapper().lambda().eq(StockUninventory::getProductModelId, stockUninventoryDto.getProductModelId()));
if (ObjectUtils.isEmpty(oldStockInventory)) {
throw new RuntimeException("产品库存不存在");
} else {
stockUninventoryMapper.updateSubtractStockUnInventory(stockUninventoryDto);
}
return 1;
}
@Override
public void exportStockUninventory(HttpServletResponse response, StockUninventoryDto stockUninventoryDto) {
List list = stockUninventoryMapper.listStockInventoryExportData(stockUninventoryDto);
ExcelUtil util = new ExcelUtil<>(StockUnInventoryExportData.class);
util.exportExcel(response, list, "不合格库存信息");
}
@Override
public Boolean frozenStock(StockInventoryDto stockInventoryDto) {
StockUninventory stockUninventory = stockUninventoryMapper.selectById(stockInventoryDto.getId());
if (stockUninventory.getQualitity().compareTo(stockInventoryDto.getLockedQuantity()) < 0) {
throw new RuntimeException("冻结数量不能超过库存数量");
}
if (ObjectUtils.isEmpty(stockUninventory.getLockedQuantity())) {
stockUninventory.setLockedQuantity(stockInventoryDto.getLockedQuantity());
} else {
stockUninventory.setLockedQuantity(stockUninventory.getLockedQuantity().add(stockInventoryDto.getLockedQuantity()));
}
return this.updateById(stockUninventory);
}
@Override
public Boolean thawStock(StockInventoryDto stockInventoryDto) {
StockUninventory stockUninventory = stockUninventoryMapper.selectById(stockInventoryDto.getId());
if (stockUninventory.getLockedQuantity().compareTo(stockInventoryDto.getLockedQuantity()) < 0) {
throw new RuntimeException("解冻数量不能超过冻结数量");
}
stockUninventory.setLockedQuantity(stockUninventory.getLockedQuantity().subtract(stockInventoryDto.getLockedQuantity()));
return this.updateById(stockUninventory);
}
}