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.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.utils.poi.ExcelUtil; import com.ruoyi.framework.web.domain.R; import com.ruoyi.sales.mapper.SalesLedgerProductMapper; import com.ruoyi.stock.dto.StockInRecordDto; import com.ruoyi.stock.dto.StockInventoryDto; import com.ruoyi.stock.dto.StockOutRecordDto; import com.ruoyi.stock.execl.StockInventoryExportData; import com.ruoyi.stock.mapper.StockInventoryMapper; 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.word.WeighbridgeDocGenerator; import lombok.RequiredArgsConstructor; import org.springframework.aop.framework.AopContext; import org.springframework.beans.BeanUtils; 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.util.List; /** *

* 库存表 服务实现类 *

* * @author 芯导软件(江苏)有限公司 * @since 2026-01-21 04:16:36 */ @Service @RequiredArgsConstructor(onConstructor_ = @Autowired) public class StockInventoryServiceImpl extends ServiceImpl implements StockInventoryService { private final StockInventoryMapper stockInventoryMapper; private final StockInRecordService stockInRecordService; private final StockOutRecordService stockOutRecordService; private final SalesLedgerProductMapper salesLedgerProductMapper; private final WeighbridgeDocGenerator weighbridgeDocGenerator; private final ProductMapper productMapper; private final ProductModelMapper productModelMapper; @Override public IPage pagestockInventory(Page page, StockInventoryDto stockInventoryDto) { return stockInventoryMapper.pagestockInventory(page, stockInventoryDto); } //入库调用 @Override @Transactional(rollbackFor = Exception.class) public Boolean addstockInventory(StockInventoryDto stockInventoryDto) { // 1. 创建入库记录 StockInRecordDto stockInRecordDto = new StockInRecordDto(); stockInRecordDto.setRecordId(stockInventoryDto.getRecordId()); stockInRecordDto.setRecordType(stockInventoryDto.getRecordType()); stockInRecordDto.setWeighingOperator(stockInventoryDto.getWeighingOperator()); if (stockInventoryDto.getProductId() != null) { stockInRecordDto.setProductId(stockInventoryDto.getProductId()); stockInRecordDto.setProductModelId(stockInventoryDto.getProductModelId()); }else { Product parent = productMapper.selectOne(new LambdaQueryWrapper().eq(Product::getProductName, "原材料").last("limit 1")); if (parent == null) { throw new RuntimeException("原材料分类不存在"); } Product product; Product existingProduct = productMapper.selectOne( new LambdaQueryWrapper() .eq(Product::getParentId, parent.getId()) .eq(Product::getProductName, stockInventoryDto.getProductName()) ); if (existingProduct != null) { // 已存在 product = existingProduct; } else { // 不存在 Product newProduct = new Product(); newProduct.setParentId(parent.getId()); newProduct.setProductName(stockInventoryDto.getProductName()); productMapper.insert(newProduct); product = newProduct; } // 先查询是否已存在相同的产品型号 ProductModel existingModel = productModelMapper.selectOne( new LambdaQueryWrapper() .eq(ProductModel::getProductId, product.getId()) .eq(ProductModel::getUnit, stockInventoryDto.getUnit()) .eq(ProductModel::getModel, stockInventoryDto.getModel()) ); Long productModelId; if (existingModel != null) { // 已存在 productModelId = existingModel.getId(); } else { // 不存在 ProductModel productModel = new ProductModel(); productModel.setProductId(product.getId()); productModel.setUnit(stockInventoryDto.getUnit()); productModel.setModel(stockInventoryDto.getModel()); productModelMapper.insert(productModel); productModelId = productModel.getId(); } stockInRecordDto.setProductId(product.getId()); stockInRecordDto.setProductModelId(productModelId); stockInventoryDto.setProductModelId(productModelId); } stockInRecordDto.setRemark(stockInventoryDto.getRemark()); stockInRecordDto.setType("0"); // 根据产品类型设置不同的重量字段 if (stockInventoryDto.getProductType() != null && stockInventoryDto.getProductType() == 0) { stockInRecordDto.setStockInNum(stockInventoryDto.getNetWeight()); stockInRecordDto.setWeighingDate(stockInventoryDto.getWeighingDate()); stockInRecordDto.setNetWeight(stockInventoryDto.getNetWeight()); stockInRecordDto.setGrossWeight(stockInventoryDto.getGrossWeight()); stockInRecordDto.setTareWeight(stockInventoryDto.getTareWeight()); stockInRecordDto.setLicensePlateNo(stockInventoryDto.getLicensePlateNo()); // 生成磅单 String absoluteDocPath = weighbridgeDocGenerator.generateWeighbridgeDoc(stockInRecordDto); stockInRecordDto.setWeighbridgeDocPath(absoluteDocPath); } else { stockInRecordDto.setStockInNum(stockInventoryDto.getQualitity()); stockInRecordDto.setNetWeight(stockInventoryDto.getQualitity()); } // 保存入库记录 stockInRecordService.add(stockInRecordDto); // 2. 更新库存 StockInventory oldStockInventory = stockInventoryMapper.selectOne( new QueryWrapper().lambda() .eq(StockInventory::getProductModelId, stockInventoryDto.getProductModelId()) ); if (ObjectUtils.isEmpty(oldStockInventory)) { // 新增库存 StockInventory newStockInventory = new StockInventory(); newStockInventory.setProductModelId(stockInventoryDto.getProductModelId()); newStockInventory.setQualitity(stockInventoryDto.getProductType() != null && stockInventoryDto.getProductType() == 0 ? stockInventoryDto.getNetWeight() : stockInventoryDto.getQualitity()); newStockInventory.setVersion(1); newStockInventory.setRemark(stockInventoryDto.getRemark()); newStockInventory.setLockedQuantity(stockInventoryDto.getLockedQuantity()); newStockInventory.setWarnNum(stockInventoryDto.getWarnNum()); newStockInventory.setProductId(stockInventoryDto.getProductId()); stockInventoryMapper.insert(newStockInventory); } else { // 更新库存 stockInventoryDto.setQualitity(stockInventoryDto.getProductType() != null && stockInventoryDto.getProductType() == 0 ? stockInventoryDto.getNetWeight() : stockInventoryDto.getQualitity()); stockInventoryMapper.updateAddStockInventory(stockInventoryDto); } return true; } //出库调用 @Override @Transactional(rollbackFor = Exception.class) public Boolean subtractStockInventory(StockInventoryDto stockInventoryDto) { // 新增出库记录 StockOutRecordDto stockOutRecordDto = new StockOutRecordDto(); stockOutRecordDto.setRecordId(stockInventoryDto.getRecordId()); stockOutRecordDto.setRecordType(stockInventoryDto.getRecordType()); stockOutRecordDto.setWeighingDate(stockInventoryDto.getWeighingDate()); stockOutRecordDto.setStockOutNum(stockInventoryDto.getNetWeight()); stockOutRecordDto.setNetWeight(stockInventoryDto.getNetWeight()); stockOutRecordDto.setGrossWeight(stockInventoryDto.getGrossWeight()); stockOutRecordDto.setTareWeight(stockInventoryDto.getTareWeight()); stockOutRecordDto.setWeighingOperator(stockInventoryDto.getWeighingOperator()); stockOutRecordDto.setProductModelId(stockInventoryDto.getProductModelId()); stockOutRecordDto.setLicensePlateNo(stockInventoryDto.getLicensePlateNo()); stockOutRecordDto.setProductId(stockInventoryDto.getProductId()); stockOutRecordDto.setRemark(stockInventoryDto.getRemark()); stockOutRecordDto.setType("0"); //生成磅单 StockInRecordDto stockInRecordDto = new StockInRecordDto(); BeanUtils.copyProperties(stockOutRecordDto, stockInRecordDto); String absoluteDocPath = weighbridgeDocGenerator.generateWeighbridgeDoc(stockInRecordDto); stockOutRecordDto.setWeighbridgeDocPath(absoluteDocPath); stockOutRecordService.add(stockOutRecordDto); StockInventory oldStockInventory = stockInventoryMapper.selectOne(new QueryWrapper().lambda().eq(StockInventory::getProductModelId, stockInventoryDto.getProductModelId())); if (ObjectUtils.isEmpty(oldStockInventory)) { throw new RuntimeException("产品库存不存在"); } BigDecimal lockedQty = oldStockInventory.getLockedQuantity(); if (lockedQty == null) { lockedQty = BigDecimal.ZERO; } if (stockInventoryDto.getQualitity().compareTo(oldStockInventory.getQualitity().subtract(lockedQty)) > 0) { throw new RuntimeException("库存不足无法出库"); } stockInventoryMapper.updateSubtractStockInventory(stockInventoryDto); return true; } @Override public R importStockInventory(MultipartFile file) { try { ExcelUtil util = new ExcelUtil(StockInventoryExportData.class); List list = util.importExcel(file.getInputStream()); for (StockInventoryExportData dto : list) { // 验证冻结数量 if (ObjectUtils.isNotEmpty(dto.getLockedQuantity()) && dto.getLockedQuantity().compareTo(dto.getQualitity()) > 0) { throw new RuntimeException(String.format("产品[%s %s]冻结数量不能超过库存数量", dto.getProductName(), dto.getModel())); } StockInventoryDto stockInventoryDto = new StockInventoryDto(); stockInventoryDto.setRecordId(0L); stockInventoryDto.setRecordType(StockInQualifiedRecordTypeEnum.CUSTOMIZATION_STOCK_IN.getCode()); stockInventoryDto.setQualitity(dto.getQualitity()); stockInventoryDto.setRemark(dto.getRemark()); stockInventoryDto.setNetWeight(dto.getNetWeight()); stockInventoryDto.setLockedQuantity(dto.getLockedQuantity()); stockInventoryDto.setProductName(dto.getProductName()); stockInventoryDto.setModel(dto.getModel()); stockInventoryDto.setUnit(dto.getUnit()); // 解决方案1:通过代理对象调用 ((StockInventoryService) AopContext.currentProxy()).addstockInventory(stockInventoryDto); } return R.ok("导入成功"); } catch (Exception e) { e.printStackTrace(); return R.fail("导入失败:" + e.getMessage()); } } @Override public void exportStockInventory(HttpServletResponse response, StockInventoryDto stockInventoryDto) { List list = stockInventoryMapper.listStockInventoryExportData(stockInventoryDto); ExcelUtil util = new ExcelUtil<>(StockInventoryExportData.class); util.exportExcel(response, list, "库存信息"); } @Override public IPage stockInventoryPage(StockInventoryDto stockInventoryDto, Page page) { return stockInventoryMapper.stockInventoryPage(stockInventoryDto, page); } @Override public IPage 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); } }