package com.fzzy.igds.service;
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.fzzy.igds.constant.Constant;
|
import com.fzzy.igds.data.SuperInventoryReportData;
|
import com.fzzy.igds.data.SuperInventoryReportParam;
|
import com.fzzy.igds.domain.*;
|
import com.fzzy.igds.mapper.*;
|
import com.fzzy.igds.utils.ContextUtil;
|
import com.fzzy.igds.utils.DateUtil;
|
import com.ruoyi.common.utils.StringUtils;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.stereotype.Service;
|
|
import javax.annotation.Resource;
|
import java.util.*;
|
import java.util.stream.Collectors;
|
|
/**
|
* 监管库存报表Service
|
*
|
* @author sgj
|
* @date 2025/12/19
|
*/
|
@Slf4j
|
@Service
|
public class SuperInventoryReportService {
|
|
@Resource
|
private DepotStoreMapper depotStoreMapper;
|
@Resource
|
private InoutRecordMapper inoutRecordMapper;
|
@Resource
|
private InoutStockChangeMapper inoutStockChangeMapper;
|
@Resource
|
private CoreCompanyMapper coreCompanyMapper;
|
@Resource
|
private InoutLossOverMapper inoutLossOverMapper;
|
|
@Resource
|
private CoreDeptService coreDeptService;
|
@Resource
|
private DepotService depotService;
|
|
/**
|
* 查询报表数据
|
*
|
* @param param
|
* @author sgj
|
* @date 2025/12/19
|
*/
|
public List<SuperInventoryReportData> listSuperInventoryReportData(SuperInventoryReportParam param) {
|
//1.获取查询得起止时间,如果没有则,默认截止时间为当天,起始时间为30天前
|
Date end = new Date();
|
Date start = DateUtil.getNewByDay(end, -30);
|
if (null == param.getStart()) {
|
param.setStart(DateUtil.getCurZero(start));
|
}
|
if (null == param.getEnd()) {
|
param.setEnd(DateUtil.getCurZero(end));
|
}
|
|
//默认组织编码
|
String companyId = ContextUtil.getCompanyId();
|
//默认库区编码
|
String deptId = ContextUtil.subDeptId(null);
|
param.setCompanyId(companyId);
|
|
//region 查询条件收储公司和所属库区处理
|
if (StringUtils.isNotEmpty(param.getDeptId()) && StringUtils.isNotEmpty(param.getCustomerId())) {
|
String substring = param.getDeptId().substring(0, (param.getDeptId().length() - 3));
|
if (!substring.equals(param.getCustomerId())) {
|
return new ArrayList<SuperInventoryReportData>();
|
}
|
}
|
if (StringUtils.isEmpty(param.getDeptId())) {
|
param.setDeptId(param.getCustomerId());
|
}
|
//test提交
|
//test提交2
|
//收储公司,所属库区查询均为空,则查询默认库区
|
if (StringUtils.isEmpty(param.getCustomerId()) && StringUtils.isEmpty(param.getDeptId())) {
|
param.setDeptId(deptId);
|
}
|
//endregion
|
|
//region 初始化需要范围的数据
|
Map<String, SuperInventoryReportData> columsMap = new HashMap<>();
|
|
//查询当前用户下属的所有库区
|
List<Dept> deptList = coreDeptService.getDeptData();
|
if (null == deptList || deptList.isEmpty()) {
|
return new ArrayList<>();
|
}
|
|
//预加载所有部门下的仓库信息,减少重复查询
|
Map<String, Dept> deptCache = new HashMap<>();
|
Map<String, List<Depot>> deptDepotsMap = new HashMap<>();
|
Map<String, Company> companyCache = new HashMap<>();
|
|
for (Dept dept : deptList) {
|
deptCache.put(dept.getId(), dept);
|
//获取库区下所有仓库
|
List<Depot> depotList = depotService.getData(companyId, dept.getId(), true);
|
if (null == depotList || depotList.isEmpty()) {
|
continue;
|
}
|
deptDepotsMap.put(dept.getId(), depotList);
|
|
//缓存公司信息
|
int deptIdLength = dept.getId().length();
|
String companyCode = dept.getId().substring(0, deptIdLength - 3);
|
if (!companyCache.containsKey(companyCode)) {
|
Company company = coreCompanyMapper.selectById(companyCode);
|
companyCache.put(companyCode, company);
|
}
|
}
|
|
//构建结果数据映射map
|
for (Map.Entry<String, List<Depot>> entry : deptDepotsMap.entrySet()) {
|
String deptIdKey = entry.getKey();
|
Company company = companyCache.get(deptIdKey.substring(0, deptIdKey.length() - 3));
|
Dept dept = deptCache.get(deptIdKey);
|
for (Depot depot : entry.getValue()) {
|
//库区编码+仓库编码组成唯一键
|
String key = deptIdKey + "_" + depot.getId();
|
SuperInventoryReportData data = new SuperInventoryReportData();
|
data.setCustomerId(Optional.ofNullable(company)
|
.map(Company::getId)
|
.orElse("-"));
|
data.setCustomerName(Optional.ofNullable(company)
|
.map(Company::getDwmc)
|
.orElse("-"));
|
data.setDeptId(deptIdKey);
|
data.setDeptName(dept.getKqmc());
|
data.setDepotId(depot.getId());
|
data.setDepotName(depot.getName());
|
columsMap.put(key, data);
|
}
|
}
|
//endregion
|
if (columsMap.isEmpty()) {
|
return new ArrayList<>();
|
}
|
|
//2.查询时间范围内的各种数据
|
List<DepotStore> depotStores = queryDepotStores(param);
|
List<InoutRecord> inoutRecords = queryInoutRecords(param);
|
List<InoutStockChange> inoutStockChanges = queryInoutStockChanges(param);
|
List<InoutLossOver> inoutLossOvers = queryInoutLossOvers(param);
|
|
//3. 数据分组预处理,提高后续查找效率
|
Map<String, List<DepotStore>> storeGroupMap = depotStores.stream()
|
.collect(Collectors.groupingBy(store -> store.getDeptId() + "_" + store.getDepotId()));
|
|
Map<String, List<InoutRecord>> recordGroupMap = inoutRecords.stream()
|
.collect(Collectors.groupingBy(record -> record.getDeptId() + "_" + record.getDepotId()));
|
|
//4. 根据库区、仓库为唯一键,组装报表数据
|
List<SuperInventoryReportData> result = new ArrayList<>();
|
Date todayZero = DateUtil.getCurZero(new Date());
|
boolean isEndDateBeforeToday = param.getEnd().before(todayZero);
|
|
for (SuperInventoryReportData data : columsMap.values()) {
|
String dataKey = data.getDeptId() + "_" + data.getDepotId();
|
|
//获取库存数据
|
List<DepotStore> depotStoreList = storeGroupMap.getOrDefault(dataKey, new ArrayList<>());
|
if (depotStoreList.isEmpty()) {
|
continue;
|
}
|
|
//排序库存数据
|
depotStoreList.sort(Comparator.comparing(DepotStore::getCreateTime));
|
|
//获取出入库记录
|
List<InoutRecord> recordList = recordGroupMap.getOrDefault(dataKey, new ArrayList<>());
|
Map<Boolean, List<InoutRecord>> recordPartition = recordList.stream()
|
.collect(Collectors.partitioningBy(record -> Constant.TYPE_IN.equals(record.getType())));
|
|
List<InoutRecord> recordInList = recordPartition.get(true);
|
List<InoutRecord> recordOutList = recordPartition.get(false);
|
|
//获取倒仓数据
|
Map<Boolean, List<InoutStockChange>> stockChangePartition = inoutStockChanges.stream()
|
.filter(change -> data.getDeptId().equals(change.getDeptId()))
|
.collect(Collectors.partitioningBy(change -> data.getDepotId().equals(change.getDepotIdIn())));
|
|
List<InoutStockChange> stockChangeInList = new ArrayList<>();
|
List<InoutStockChange> stockChangeOutList = new ArrayList<>();
|
|
//倒入数据
|
stockChangeInList.addAll(stockChangePartition.get(true).stream()
|
.filter(change -> data.getDepotId().equals(change.getDepotIdIn()))
|
.collect(Collectors.toList()));
|
|
//倒出数据
|
stockChangeOutList.addAll(stockChangePartition.get(false).stream()
|
.filter(change -> data.getDepotId().equals(change.getDepotIdOut()))
|
.collect(Collectors.toList()));
|
|
//损益数据
|
List<InoutLossOver> lossOverList = inoutLossOvers.stream()
|
.filter(loss -> data.getDeptId().equals(loss.getDeptId())
|
&& data.getDepotId().equals(loss.getDepotId()))
|
.collect(Collectors.toList());
|
|
//计算各项统计数据
|
double sumRecordIn = recordInList.stream()
|
.mapToDouble(InoutRecord::getRecordWeight)
|
.sum();
|
|
double sumRecordOut = recordOutList.stream()
|
.mapToDouble(InoutRecord::getRecordWeight)
|
.sum();
|
|
double sumStockChangeIn = stockChangeInList.stream()
|
.mapToDouble(InoutStockChange::getNumber)
|
.sum();
|
|
double sumStockChangeOut = stockChangeOutList.stream()
|
.mapToDouble(InoutStockChange::getNumber)
|
.sum();
|
|
double sumLossOver = lossOverList.stream()
|
.mapToDouble(lossOver -> Constant.TYPE_LOSS.equals(lossOver.getType())
|
? -lossOver.getAmount()
|
: lossOver.getAmount())
|
.sum();
|
|
//计算期初期末重量
|
Double initialWeight = depotStoreList.get(0).getStorageReal();
|
Double finalWeight;
|
|
if (isEndDateBeforeToday) {
|
//如果截止时间为昨天(当天的0点0分0秒0毫秒)及之前,则最后一条数据为期末数量
|
finalWeight = depotStoreList.get(depotStoreList.size() - 1).getStorageReal();
|
} else {
|
//如果截止时间为今天及之后,则需要结合入出库记录数据来计算期末数量,规则:期末数量 = 期初数量 + 入库数量 - 出库数量 + 倒入数量 - 倒出数量+ 损益数据
|
finalWeight = initialWeight + sumRecordIn - sumRecordOut + sumStockChangeIn - sumStockChangeOut + sumLossOver;
|
}
|
|
//设置数据
|
data.setInitialWeight(initialWeight);
|
data.setRecordInWeight(sumRecordIn);
|
data.setChangeInWeight(sumStockChangeIn);
|
data.setRecordOutWeight(sumRecordOut);
|
data.setChangeOutWeight(sumStockChangeOut);
|
data.setLossWeight(sumLossOver);
|
data.setFinalWeight(finalWeight);
|
result.add(data);
|
}
|
|
return result;
|
}
|
|
/**
|
* 查询库存数据
|
*/
|
private List<DepotStore> queryDepotStores(SuperInventoryReportParam param) {
|
QueryWrapper<DepotStore> depotStoreQueryWrapper = new QueryWrapper<>();
|
depotStoreQueryWrapper.eq("company_id", param.getCompanyId());
|
if (StringUtils.isNotBlank(param.getDeptId())) {
|
depotStoreQueryWrapper.likeRight("dept_id", param.getDeptId());
|
}
|
depotStoreQueryWrapper.between("create_time", param.getStart(), param.getEnd());
|
depotStoreQueryWrapper.orderByAsc("create_time");
|
return depotStoreMapper.selectList(depotStoreQueryWrapper);
|
}
|
|
/**
|
* 查询出入库记录数据
|
*/
|
private List<InoutRecord> queryInoutRecords(SuperInventoryReportParam param) {
|
QueryWrapper<InoutRecord> inoutRecordQueryWrapper = new QueryWrapper<>();
|
inoutRecordQueryWrapper.eq("company_id", param.getCompanyId());
|
if (StringUtils.isNotBlank(param.getDeptId())) {
|
inoutRecordQueryWrapper.likeRight("dept_id", param.getDeptId());
|
}
|
inoutRecordQueryWrapper.between("create_time", param.getStart(), param.getEnd());
|
inoutRecordQueryWrapper.orderByAsc("create_time");
|
return inoutRecordMapper.selectList(inoutRecordQueryWrapper);
|
}
|
|
/**
|
* 查询倒仓数据
|
*/
|
private List<InoutStockChange> queryInoutStockChanges(SuperInventoryReportParam param) {
|
QueryWrapper<InoutStockChange> inoutStockChangeQueryWrapper = new QueryWrapper<>();
|
inoutStockChangeQueryWrapper.eq("company_id", param.getCompanyId());
|
if (StringUtils.isNotBlank(param.getDeptId())) {
|
inoutStockChangeQueryWrapper.likeRight("dept_id", param.getDeptId());
|
}
|
inoutStockChangeQueryWrapper.between("create_time", param.getStart(), param.getEnd());
|
inoutStockChangeQueryWrapper.orderByAsc("create_time");
|
return inoutStockChangeMapper.selectList(inoutStockChangeQueryWrapper);
|
}
|
|
/**
|
* 查询损益数据
|
*/
|
private List<InoutLossOver> queryInoutLossOvers(SuperInventoryReportParam param) {
|
QueryWrapper<InoutLossOver> inoutLossOverQueryWrapper = new QueryWrapper<>();
|
inoutLossOverQueryWrapper.eq("company_id", param.getCompanyId());
|
if (StringUtils.isNotBlank(param.getDeptId())) {
|
inoutLossOverQueryWrapper.likeRight("dept_id", param.getDeptId());
|
}
|
inoutLossOverQueryWrapper.between("create_time", param.getStart(), param.getEnd());
|
inoutLossOverQueryWrapper.orderByAsc("create_time");
|
return inoutLossOverMapper.selectList(inoutLossOverQueryWrapper);
|
}
|
}
|