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.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.ruoyi.basic.mapper.ProductModelMapper;
|
import com.ruoyi.basic.pojo.ProductModel;
|
import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum;
|
import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum;
|
import com.ruoyi.common.exception.base.BaseException;
|
import com.ruoyi.common.utils.EnumUtil;
|
import com.ruoyi.common.utils.OrderUtils;
|
import com.ruoyi.common.utils.bean.BeanUtils;
|
import com.ruoyi.common.utils.poi.ExcelUtil;
|
import com.ruoyi.stock.dto.StockInRecordDto;
|
import com.ruoyi.stock.dto.StockInventoryDto;
|
import com.ruoyi.stock.dto.StockUninventoryDto;
|
import com.ruoyi.stock.execl.StockInRecordExportData;
|
import com.ruoyi.stock.mapper.StockInRecordMapper;
|
import com.ruoyi.stock.mapper.StockInventoryMapper;
|
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.word.WeighbridgeDocGenerator;
|
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.math.BigDecimal;
|
import java.math.RoundingMode;
|
import java.util.List;
|
|
@Service
|
public class StockInRecordServiceImpl extends ServiceImpl<StockInRecordMapper, StockInRecord> implements StockInRecordService {
|
|
@Autowired
|
private StockInRecordMapper stockInRecordMapper;
|
@Autowired
|
private StockInventoryMapper stockInventoryMapper;
|
@Autowired
|
private StockUninventoryMapper stockUninventoryMapper;
|
@Autowired
|
private WeighbridgeDocGenerator weighbridgeDocGenerator;
|
@Autowired
|
private ProductModelMapper productModelMapper;
|
|
@Override
|
public IPage<StockInRecordDto> listPage(Page page, StockInRecordDto stockInRecordDto) {
|
return stockInRecordMapper.listPage(page, stockInRecordDto);
|
}
|
|
// 新增入库
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public int add(StockInRecordDto stockInRecordDto) {
|
String no = OrderUtils.countTodayByCreateTime(stockInRecordMapper, "RK");
|
stockInRecordDto.setInboundBatches(no);
|
StockInRecord stockInRecord = new StockInRecord();
|
BeanUtils.copyProperties(stockInRecordDto, stockInRecord);
|
return stockInRecordMapper.insert(stockInRecord);
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public int batchDelete(List<Long> ids) {
|
for (Long id : ids) {
|
StockInRecord stockInRecord = stockInRecordMapper.selectById(id);
|
if (stockInRecord == null) {
|
throw new BaseException("入库记录不存在,ID:" + id);
|
}
|
|
// 查询产品型号(用于单位转换)
|
ProductModel productModel = productModelMapper.selectById(stockInRecord.getProductModelId());
|
if (productModel == null) {
|
throw new BaseException("产品型号不存在,无法删除");
|
}
|
|
// 获取入库数量及其单位,转换为库存单位
|
BigDecimal stockInNum = stockInRecord.getStockInNum(); // 入库记录中存储的数量
|
String sourceUnit = stockInRecord.getUnit(); // 入库记录的单位
|
String stockUnit = productModel.getUnit(); // 库存单位
|
|
// 将入库数量转换为库存单位
|
BigDecimal convertedQuantity = convertQuantityToStockUnit(stockInNum, sourceUnit, stockUnit);
|
|
// 根据入库类型处理不同的库存表
|
if ("0".equals(stockInRecord.getType())) {
|
// 正常入库,删除时扣减库存
|
StockInventory stockInventory = stockInventoryMapper.selectOne(
|
new LambdaQueryWrapper<StockInventory>()
|
.eq(StockInventory::getProductModelId, stockInRecord.getProductModelId())
|
);
|
|
if (stockInventory == null) {
|
throw new BaseException("库存记录中没有对应的产品,无法删除");
|
}
|
|
StockInventoryDto inventoryDto = new StockInventoryDto();
|
inventoryDto.setProductModelId(stockInventory.getProductModelId());
|
inventoryDto.setQualitity(convertedQuantity);
|
|
// 扣减库存(删除入库记录相当于减少库存)
|
int affectedRows = stockInventoryMapper.updateSubtractStockInventory(inventoryDto);
|
if (affectedRows == 0) {
|
throw new BaseException("扣减库存失败,库存可能不足");
|
}
|
|
} else if ("1".equals(stockInRecord.getType())) {
|
// 非正常入库,删除时扣减非正常库存
|
StockUninventory stockUninventory = stockUninventoryMapper.selectOne(
|
new LambdaQueryWrapper<StockUninventory>()
|
.eq(StockUninventory::getProductModelId, stockInRecord.getProductModelId())
|
);
|
|
if (stockUninventory == null) {
|
throw new BaseException("非正常库存记录中没有对应的产品,无法删除");
|
}
|
|
// 创建非正常库存更新DTO
|
StockUninventoryDto uninventoryDto = new StockUninventoryDto();
|
uninventoryDto.setProductModelId(stockUninventory.getProductModelId());
|
uninventoryDto.setQualitity(convertedQuantity);
|
|
// 扣减非正常库存
|
int affectedRows = stockUninventoryMapper.updateSubtractStockUnInventory(uninventoryDto);
|
if (affectedRows == 0) {
|
throw new BaseException("扣减非正常库存失败");
|
}
|
}
|
}
|
|
// 5. 批量删除入库记录
|
return stockInRecordMapper.deleteBatchIds(ids);
|
}
|
|
@Override
|
public void exportStockInRecord(HttpServletResponse response, StockInRecordDto stockInRecordDto) {
|
List<StockInRecordExportData> list = stockInRecordMapper.listStockInRecordExportData(stockInRecordDto);
|
for (StockInRecordExportData stockInRecordExportData : list) {
|
if (stockInRecordExportData.getType().equals("0")) {
|
stockInRecordExportData.setRecordType(EnumUtil.fromCode(StockOutQualifiedRecordTypeEnum.class, Integer.parseInt(stockInRecordExportData.getRecordType())).getValue());
|
}else {
|
stockInRecordExportData.setRecordType(EnumUtil.fromCode(StockInUnQualifiedRecordTypeEnum.class, Integer.parseInt(stockInRecordExportData.getRecordType())).getValue());
|
}
|
}
|
ExcelUtil<StockInRecordExportData> util = new ExcelUtil<>(StockInRecordExportData.class);
|
util.exportExcel(response,list, "入库记录信息");
|
}
|
|
@Override
|
public int editStockInStock(StockInRecordDto stockInRecordDto) {
|
if (stockInRecordDto.getId() == null) {
|
throw new BaseException("入库记录ID不能为空");
|
}
|
|
// 1. 查询原始入库记录
|
StockInRecord originalRecord = stockInRecordMapper.selectById(stockInRecordDto.getId());
|
if (originalRecord == null) {
|
throw new BaseException("入库记录不存在");
|
}
|
|
// 2. 查询产品型号信息(用于单位转换)
|
ProductModel productModel = productModelMapper.selectById(originalRecord.getProductModelId());
|
if (productModel == null) {
|
throw new BaseException("产品型号不存在");
|
}
|
|
// 3. 获取原始入库数量及其单位
|
BigDecimal originalNetWeight = originalRecord.getStockInNum(); // 原始记录中存储的数量
|
String originalUnit = originalRecord.getUnit(); // 原始记录的单位
|
String stockUnit = productModel.getUnit(); // 库存单位
|
|
// 将原始入库数量转换为库存单位
|
BigDecimal originalNetWeightInStockUnit = convertQuantityToStockUnit(originalNetWeight, originalUnit, stockUnit);
|
|
// 4. 获取新入库数量及其单位
|
BigDecimal newNetWeight = stockInRecordDto.getNetWeight(); // 新输入的数量
|
if (newNetWeight == null) {
|
throw new BaseException("净重不能为空");
|
}
|
String newUnit = stockInRecordDto.getUnit(); // 新输入的单位
|
|
// 将新入库数量转换为库存单位
|
BigDecimal newNetWeightInStockUnit = convertQuantityToStockUnit(newNetWeight, newUnit, stockUnit);
|
|
// 5. 计算库存变化量(使用统一转换后的库存单位值)
|
// 入库数量变化量(正数表示入库变多,需要增加库存;负数表示入库变少,需要减少库存)
|
BigDecimal diffQuantity = newNetWeightInStockUnit.subtract(originalNetWeightInStockUnit);
|
|
// 6. 更新入库记录(保存用户输入的原始数值和单位)
|
stockInRecordDto.setStockInNum(stockInRecordDto.getNetWeight());
|
stockInRecordDto.setUnit(stockInRecordDto.getUnit());
|
|
// 7. 生成磅单
|
String absoluteDocPath = weighbridgeDocGenerator.generateWeighbridgeDoc(stockInRecordDto);
|
stockInRecordDto.setWeighbridgeDocPath(absoluteDocPath);
|
int updateResult = stockInRecordMapper.updateById(stockInRecordDto);
|
|
// 8. 更新库存(仅在数量发生变化时)
|
if (diffQuantity.compareTo(BigDecimal.ZERO) != 0) {
|
updateInventory(stockInRecordDto.getProductId(), diffQuantity);
|
}
|
|
return updateResult;
|
}
|
|
/**
|
* 将数量转换为库存单位
|
* @param quantity 原始数量
|
* @param sourceUnit 原始单位
|
* @param targetUnit 目标单位(库存单位)
|
* @return 转换后的数量
|
*/
|
private BigDecimal convertQuantityToStockUnit(BigDecimal quantity, String sourceUnit, String targetUnit) {
|
if (quantity == null) {
|
throw new BaseException("数量不能为空");
|
}
|
|
if (sourceUnit == null || sourceUnit.isEmpty()) {
|
return quantity;
|
}
|
|
if (sourceUnit.equals(targetUnit)) {
|
return quantity;
|
}
|
|
// 单位转换
|
if ("吨".equals(targetUnit)) {
|
// 目标单位是吨,需要将源单位转换为吨
|
if ("公斤".equals(sourceUnit)) {
|
// 公斤转吨:除以1000
|
return quantity.divide(BigDecimal.valueOf(1000), 2, RoundingMode.HALF_UP);
|
} else if ("克".equals(sourceUnit)) {
|
// 克转吨:除以1000000
|
return quantity.divide(BigDecimal.valueOf(1000000), 2, RoundingMode.HALF_UP);
|
}
|
} else if ("公斤".equals(targetUnit)) {
|
// 目标单位是公斤
|
if ("吨".equals(sourceUnit)) {
|
// 吨转公斤:乘以1000
|
return quantity.multiply(BigDecimal.valueOf(1000));
|
} else if ("克".equals(sourceUnit)) {
|
// 克转公斤:除以1000
|
return quantity.divide(BigDecimal.valueOf(1000), 2, RoundingMode.HALF_UP);
|
}
|
} else if ("克".equals(targetUnit)) {
|
// 目标单位是克
|
if ("吨".equals(sourceUnit)) {
|
// 吨转克:乘以1000000
|
return quantity.multiply(BigDecimal.valueOf(1000000));
|
} else if ("公斤".equals(sourceUnit)) {
|
// 公斤转克:乘以1000
|
return quantity.multiply(BigDecimal.valueOf(1000));
|
}
|
}
|
|
return quantity;
|
}
|
|
/**
|
* 更新库存
|
* @param productId 产品ID
|
* @param diffQuantity 库存变化量(正数为增加,负数为减少)
|
*/
|
private void updateInventory(Long productId, BigDecimal diffQuantity) {
|
// 查询当前库存
|
StockInventory stockInventory = stockInventoryMapper.selectOne(
|
new QueryWrapper<StockInventory>().lambda()
|
.eq(StockInventory::getProductId, productId)
|
);
|
|
if (stockInventory == null) {
|
throw new BaseException("库存记录不存在");
|
}
|
|
StockInventoryDto inventoryDto = new StockInventoryDto();
|
BeanUtils.copyProperties(stockInventory, inventoryDto);
|
inventoryDto.setQualitity(diffQuantity.abs());
|
|
// 根据变化量正负调用不同的更新方法
|
if (diffQuantity.compareTo(BigDecimal.ZERO) > 0) {
|
// 增加库存
|
int affectedRows = stockInventoryMapper.updateAddStockInventory(inventoryDto);
|
if (affectedRows == 0) {
|
throw new BaseException("更新库存失败");
|
}
|
} else {
|
// 减少库存
|
int affectedRows = stockInventoryMapper.updateSubtractStockInventory(inventoryDto);
|
if (affectedRows == 0) {
|
throw new BaseException("库存不足,无法扣减");
|
}
|
}
|
}
|
}
|