|
@@ -6,15 +6,19 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
+import org.dromara.common.core.constant.BizConst;
|
|
import org.dromara.common.core.enums.biz.ProductType;
|
|
import org.dromara.common.core.enums.biz.ProductType;
|
|
import org.dromara.common.core.enums.biz.StockOperType;
|
|
import org.dromara.common.core.enums.biz.StockOperType;
|
|
import org.dromara.common.core.utils.MapstructUtils;
|
|
import org.dromara.common.core.utils.MapstructUtils;
|
|
import org.dromara.common.core.utils.StringUtils;
|
|
import org.dromara.common.core.utils.StringUtils;
|
|
import org.dromara.common.mybatis.core.page.PageQuery;
|
|
import org.dromara.common.mybatis.core.page.PageQuery;
|
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
|
|
|
+import org.dromara.system.domain.vo.SysDictDataVo;
|
|
|
|
+import org.dromara.system.service.ISysDictDataService;
|
|
import org.dromara.web.domain.*;
|
|
import org.dromara.web.domain.*;
|
|
import org.dromara.web.domain.bo.ProductInOutRecordBo;
|
|
import org.dromara.web.domain.bo.ProductInOutRecordBo;
|
|
import org.dromara.web.domain.vo.ProductInOutRecordVo;
|
|
import org.dromara.web.domain.vo.ProductInOutRecordVo;
|
|
|
|
+import org.dromara.web.domain.vo.ProductStockVo;
|
|
import org.dromara.web.mapper.*;
|
|
import org.dromara.web.mapper.*;
|
|
import org.dromara.web.service.IProductInOutRecordService;
|
|
import org.dromara.web.service.IProductInOutRecordService;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
@@ -37,6 +41,8 @@ public class ProductInOutRecordServiceImpl implements IProductInOutRecordService
|
|
|
|
|
|
private final ProductInOutRecordMapper baseMapper;
|
|
private final ProductInOutRecordMapper baseMapper;
|
|
|
|
|
|
|
|
+ private final ISysDictDataService dataService;
|
|
|
|
+
|
|
private final ProductStockMapper productStockMapper;
|
|
private final ProductStockMapper productStockMapper;
|
|
|
|
|
|
private final StorageLocationMapper locationMapper;
|
|
private final StorageLocationMapper locationMapper;
|
|
@@ -107,68 +113,139 @@ public class ProductInOutRecordServiceImpl implements IProductInOutRecordService
|
|
*/
|
|
*/
|
|
@Override
|
|
@Override
|
|
public Boolean insertByBo(List<ProductInOutRecordBo> boList) {
|
|
public Boolean insertByBo(List<ProductInOutRecordBo> boList) {
|
|
- boolean flag = false;
|
|
|
|
- if (CollUtil.isNotEmpty(boList)) {
|
|
|
|
- ProductInOutRecordBo bo = null;
|
|
|
|
- ProductInOutRecord add = null;
|
|
|
|
- List<ProductStock> stockList = null;
|
|
|
|
- ProductStock stock = null;
|
|
|
|
- List<StorageLocation> locationList = locationMapper.selectList(Wrappers.lambdaQuery(StorageLocation.class).select(StorageLocation::getId, StorageLocation::getStorageName));
|
|
|
|
- Map<Long, String> locationMap = locationList.stream().collect(Collectors.toMap(k1 -> k1.getId(), k2 -> String.valueOf(k2.getStorageName()), (k1, k2) -> k1));
|
|
|
|
-
|
|
|
|
- List<ProductCategory> productCategoryList = productCategoryMapper.selectList(Wrappers.lambdaQuery(ProductCategory.class).select(ProductCategory::getCategoryId, ProductCategory::getCategoryName));
|
|
|
|
- Map<Long, String> productCategoryMap = productCategoryList.stream().collect(Collectors.toMap(k1 -> k1.getCategoryId(), k2 -> String.valueOf(k2.getCategoryName()), (k1, k2) -> k1));
|
|
|
|
-
|
|
|
|
- List<SuppliesCategory> suppliesCategoryList = suppliesCategoryMapper.selectList(Wrappers.lambdaQuery(SuppliesCategory.class).select(SuppliesCategory::getCategoryId, SuppliesCategory::getCategoryName));
|
|
|
|
- Map<Long, String> suppliesCategoryMap = suppliesCategoryList.stream().collect(Collectors.toMap(k1 -> k1.getCategoryId(), k2 -> String.valueOf(k2.getCategoryName()), (k1, k2) -> k1));
|
|
|
|
- for (int i = 0; i < boList.size(); i++) {
|
|
|
|
- bo = boList.get(i);
|
|
|
|
- bo.setLocationName(locationMap.get(bo.getLocationId()));
|
|
|
|
- if (bo.getProductType().equals(ProductType.TYPE_ONE.getCode())) {
|
|
|
|
- bo.setCategoryName(productCategoryMap.get(bo.getCategoryId()));
|
|
|
|
- } else {
|
|
|
|
- bo.setCategoryName(suppliesCategoryMap.get(bo.getCategoryId()));
|
|
|
|
|
|
+ if (CollUtil.isEmpty(boList)) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
|
- add = MapstructUtils.convert(bo, ProductInOutRecord.class);
|
|
|
|
- validEntityBeforeSave(add);
|
|
|
|
-
|
|
|
|
- flag = baseMapper.insert(add) > 0;
|
|
|
|
- if (flag) {
|
|
|
|
- bo.setId(add.getId());
|
|
|
|
- stockList = productStockMapper.selectList(new LambdaQueryWrapper<ProductStock>().eq(ProductStock::getProductId, bo.getProductId()).eq(ProductStock::getLocationId, bo.getLocationId()));
|
|
|
|
- if (CollUtil.isNotEmpty(stockList)) {
|
|
|
|
- stock = stockList.get(0);
|
|
|
|
- if (bo.getType().equals(StockOperType.OPER_TYPE_ZERO.getCode())) {
|
|
|
|
- stock.setStockNum(stock.getStockNum() + bo.getNum());
|
|
|
|
- stock.setTotalStockNum(stock.getTotalStockNum() + bo.getNum());
|
|
|
|
- } else {
|
|
|
|
- stock.setStockNum(stock.getStockNum() - bo.getNum());
|
|
|
|
-// stock.setTotalStockNum(stock.getTotalStockNum() - bo.getNum()); 出库时总库存应保持不变 只修改可用库存
|
|
|
|
- }
|
|
|
|
- productStockMapper.updateById(stock);
|
|
|
|
- } else {
|
|
|
|
- stock = new ProductStock();
|
|
|
|
- stock.setProductType(add.getProductType());
|
|
|
|
- stock.setProductNo(add.getProductNo());
|
|
|
|
- stock.setCategoryId(add.getCategoryId());
|
|
|
|
- stock.setCategoryName(add.getCategoryName());
|
|
|
|
- stock.setProductId(add.getProductId());
|
|
|
|
- stock.setProductName(add.getProductName());
|
|
|
|
- stock.setSpecsName(add.getSpecsName());
|
|
|
|
- stock.setLocationId(add.getLocationId());
|
|
|
|
- stock.setLocationName(add.getLocationName());
|
|
|
|
- stock.setLineNo(add.getLineNo());
|
|
|
|
- stock.setTotalStockNum(add.getNum());
|
|
|
|
- stock.setStockNum(add.getNum());
|
|
|
|
- stock.setExpirationNum(0L);
|
|
|
|
- stock.setStockUnit(add.getUnit());
|
|
|
|
- productStockMapper.insert(stock);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ // 提前查询并缓存数据,避免在循环中重复查询
|
|
|
|
+ Map<Long, String> locationMap = getLocationMap();
|
|
|
|
+ Map<Long, String> productCategoryMap = getProductCategoryMap();
|
|
|
|
+ Map<Long, String> suppliesCategoryMap = getSuppliesCategoryMap();
|
|
|
|
+
|
|
|
|
+ boolean overallSuccess = false;
|
|
|
|
+
|
|
|
|
+ for (ProductInOutRecordBo bo : boList) {
|
|
|
|
+ boolean success = processSingleRecord(bo, locationMap, productCategoryMap, suppliesCategoryMap);
|
|
|
|
+ overallSuccess = overallSuccess || success;
|
|
}
|
|
}
|
|
- return flag;
|
|
|
|
|
|
+
|
|
|
|
+ return overallSuccess;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private Map<Long, String> getLocationMap() {
|
|
|
|
+ List<StorageLocation> locationList = locationMapper.selectList(
|
|
|
|
+ Wrappers.lambdaQuery(StorageLocation.class)
|
|
|
|
+ .select(StorageLocation::getId, StorageLocation::getStorageName));
|
|
|
|
+ return locationList.stream()
|
|
|
|
+ .collect(Collectors.toMap(StorageLocation::getId,
|
|
|
|
+ StorageLocation::getStorageName,
|
|
|
|
+ (k1, k2) -> k1));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private Map<Long, String> getProductCategoryMap() {
|
|
|
|
+ List<ProductCategory> productCategoryList = productCategoryMapper.selectList(
|
|
|
|
+ Wrappers.lambdaQuery(ProductCategory.class)
|
|
|
|
+ .select(ProductCategory::getCategoryId, ProductCategory::getCategoryName));
|
|
|
|
+ return productCategoryList.stream()
|
|
|
|
+ .collect(Collectors.toMap(ProductCategory::getCategoryId,
|
|
|
|
+ ProductCategory::getCategoryName,
|
|
|
|
+ (k1, k2) -> k1));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private Map<Long, String> getSuppliesCategoryMap() {
|
|
|
|
+ List<SuppliesCategory> suppliesCategoryList = suppliesCategoryMapper.selectList(
|
|
|
|
+ Wrappers.lambdaQuery(SuppliesCategory.class)
|
|
|
|
+ .select(SuppliesCategory::getCategoryId, SuppliesCategory::getCategoryName));
|
|
|
|
+ return suppliesCategoryList.stream()
|
|
|
|
+ .collect(Collectors.toMap(SuppliesCategory::getCategoryId,
|
|
|
|
+ SuppliesCategory::getCategoryName,
|
|
|
|
+ (k1, k2) -> k1));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private boolean processSingleRecord(ProductInOutRecordBo bo,
|
|
|
|
+ Map<Long, String> locationMap,
|
|
|
|
+ Map<Long, String> productCategoryMap,
|
|
|
|
+ Map<Long, String> suppliesCategoryMap) {
|
|
|
|
+ Map<String, List<SysDictDataVo>> dictMap = dataService.selectGroupByType(List.of(BizConst.PRODUCT_SPEC_UNIT, BizConst.PRODUCT_PACKAGE_UNIT)).getData();
|
|
|
|
+
|
|
|
|
+ Map<String, String> specMap = dictMap.get(BizConst.PRODUCT_SPEC_UNIT).stream().collect(Collectors.toMap(k1 -> k1.getDictLabel(), k2 -> k2.getDictValue(), (k1, k2) -> k1));
|
|
|
|
+ Map<String, String> packgeMap = dictMap.get(BizConst.PRODUCT_PACKAGE_UNIT).stream().collect(Collectors.toMap(k1 -> k1.getDictLabel(), k2 -> k2.getDictValue(), (k1, k2) -> k1));
|
|
|
|
+
|
|
|
|
+ // 设置位置名称
|
|
|
|
+ bo.setLocationName(locationMap.get(bo.getLocationId()));
|
|
|
|
+
|
|
|
|
+ // 设置分类名称
|
|
|
|
+ if (ProductType.TYPE_ONE.getCode().equals(bo.getProductType())) {
|
|
|
|
+ bo.setCategoryName(productCategoryMap.get(bo.getCategoryId()));
|
|
|
|
+ } else {
|
|
|
|
+ bo.setCategoryName(suppliesCategoryMap.get(bo.getCategoryId()));
|
|
|
|
+ }
|
|
|
|
+ bo.setUnit(specMap.get(bo.getUnit()));
|
|
|
|
+ bo.setPreUnit(packgeMap.get(bo.getPreUnit()));
|
|
|
|
+ // 转换并验证实体
|
|
|
|
+ ProductInOutRecord record = MapstructUtils.convert(bo, ProductInOutRecord.class);
|
|
|
|
+ validEntityBeforeSave(record);
|
|
|
|
+
|
|
|
|
+ // 插入记录
|
|
|
|
+ boolean insertSuccess = baseMapper.insert(record) > 0;
|
|
|
|
+ if (!insertSuccess) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ bo.setId(record.getId());
|
|
|
|
+
|
|
|
|
+ // 处理库存
|
|
|
|
+ processStock(bo, record);
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void processStock(ProductInOutRecordBo bo, ProductInOutRecord record) {
|
|
|
|
+ // 查询现有库存
|
|
|
|
+ List<ProductStock> stockList = productStockMapper.selectList(
|
|
|
|
+ new LambdaQueryWrapper<ProductStock>()
|
|
|
|
+ .eq(ProductStock::getProductId, bo.getProductId())
|
|
|
|
+ .eq(ProductStock::getLocationId, bo.getLocationId()));
|
|
|
|
+
|
|
|
|
+ if (CollUtil.isNotEmpty(stockList)) {
|
|
|
|
+ // 更新现有库存
|
|
|
|
+ updateExistingStock(stockList.get(0), bo);
|
|
|
|
+ } else {
|
|
|
|
+ // 创建新库存记录
|
|
|
|
+ createNewStock(record, bo);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void updateExistingStock(ProductStock stock, ProductInOutRecordBo bo) {
|
|
|
|
+ if (StockOperType.OPER_TYPE_ZERO.getCode().equals(bo.getType())) {
|
|
|
|
+ // 入库操作
|
|
|
|
+ stock.setStockNum(stock.getStockNum() + bo.getNum());
|
|
|
|
+ stock.setTotalStockNum(stock.getTotalStockNum() + bo.getNum());
|
|
|
|
+ } else {
|
|
|
|
+ // 出库操作
|
|
|
|
+ stock.setStockNum(stock.getStockNum() - bo.getNum());
|
|
|
|
+ // 出库时总库存保持不变,只修改可用库存
|
|
|
|
+ }
|
|
|
|
+ productStockMapper.updateById(stock);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void createNewStock(ProductInOutRecord record, ProductInOutRecordBo bo) {
|
|
|
|
+ ProductStock stock = new ProductStock();
|
|
|
|
+ stock.setProductType(record.getProductType());
|
|
|
|
+ stock.setProductNo(record.getProductNo());
|
|
|
|
+ stock.setCategoryId(record.getCategoryId());
|
|
|
|
+ stock.setCategoryName(record.getCategoryName());
|
|
|
|
+ stock.setProductId(record.getProductId());
|
|
|
|
+ stock.setProductName(record.getProductName());
|
|
|
|
+ stock.setSpecsName(record.getSpecsName());
|
|
|
|
+ stock.setLocationId(record.getLocationId());
|
|
|
|
+ stock.setLocationName(record.getLocationName());
|
|
|
|
+ stock.setLineNo(record.getLineNo());
|
|
|
|
+ stock.setTotalStockNum(record.getNum());
|
|
|
|
+ stock.setStockNum(record.getNum());
|
|
|
|
+ stock.setExpirationNum(0L);
|
|
|
|
+ stock.setStockUnit(record.getUnit());
|
|
|
|
+
|
|
|
|
+ productStockMapper.insert(stock);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -191,8 +268,24 @@ public class ProductInOutRecordServiceImpl implements IProductInOutRecordService
|
|
|
|
|
|
// 计算正确的offset
|
|
// 计算正确的offset
|
|
int offset = (pageQuery.getPageNum() - 1) * pageQuery.getPageSize();
|
|
int offset = (pageQuery.getPageNum() - 1) * pageQuery.getPageSize();
|
|
- Integer count = baseMapper.queryStockBalanceCount(bo.getSearchValue());
|
|
|
|
- List<ProductInOutRecordVo> balanceVoList = baseMapper.queryStockBalance(bo.getSearchValue(), offset, pageQuery.getPageSize());
|
|
|
|
|
|
+ Integer count = baseMapper.queryStockBalanceCount(bo.getProductType(), bo.getLocationId(), bo.getCategoryId(), bo.getSearchValue());
|
|
|
|
+ List<ProductInOutRecordVo> balanceVoList = baseMapper.queryStockBalance(bo.getProductType(), bo.getLocationId(), bo.getCategoryId(), bo.getSearchValue(), offset, pageQuery.getPageSize());
|
|
|
|
+ List<ProductStockVo> stockVoList =null;
|
|
|
|
+ List<ProductStockVo> oldInStockVoList =null;
|
|
|
|
+ if (CollUtil.isNotEmpty(balanceVoList)){
|
|
|
|
+ for (ProductInOutRecordVo recordVo : balanceVoList) {
|
|
|
|
+ stockVoList = productStockMapper.selectVoList(new LambdaQueryWrapper<ProductStock>().eq(ProductStock::getProductId, recordVo.getProductId()).eq(ProductStock::getLocationId, recordVo.getLocationId()));
|
|
|
|
+ if (CollUtil.isNotEmpty(stockVoList)) {
|
|
|
|
+ recordVo.setTotalStockNum(stockVoList.get(0).getStockNum());
|
|
|
|
+ }
|
|
|
|
+ if (null!=bo.getInLocationId()){
|
|
|
|
+ oldInStockVoList = productStockMapper.selectVoList(new LambdaQueryWrapper<ProductStock>().eq(ProductStock::getProductId, recordVo.getProductId()).eq(ProductStock::getLocationId, bo.getInLocationId()));
|
|
|
|
+ if (CollUtil.isNotEmpty(stockVoList)) {
|
|
|
|
+ recordVo.setOldInStockNum(oldInStockVoList.get(0).getStockNum());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
TableDataInfo tableDataInfo = new TableDataInfo();
|
|
TableDataInfo tableDataInfo = new TableDataInfo();
|
|
tableDataInfo.setRows(balanceVoList);
|
|
tableDataInfo.setRows(balanceVoList);
|
|
tableDataInfo.setTotal(count);
|
|
tableDataInfo.setTotal(count);
|