refactor(purchase): 解决循环依赖问题
- 从 IMatPurchaseService 接口中移除 queryMaterialInventory 和 queryPurchasePlanMaterialInventory 方法 - 将库存查询实现从 MatPurchaseServiceImpl 迁移到 MatMaterialServiceImpl - 修改 MatMaterialServiceImpl 中的依赖注入,使用 MatPurchaseMapper 替代 IMatPurchaseService - 更新控制器 MatPurchaseController,移除库存相关 API 端点 - 优化 MatPurchaseServiceImpl 中的查询逻辑,改用批量查询减少 N+1 问题 - 在 MatMaterialServiceImpl 中实现完整的物料库存查询功能,包括当前库存、在途数量等信息
This commit is contained in:
@@ -102,34 +102,4 @@ public class MatPurchaseController extends BaseController {
|
||||
return toAjax(iMatPurchaseService.deleteWithValidByIds(Arrays.asList(purchaseIds), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取物料库存信息(当前库存和在途数量)
|
||||
*
|
||||
* @param materialId 物料ID
|
||||
*/
|
||||
@GetMapping("/inventory/{materialId}")
|
||||
public R<List<MaterialInventoryVo>> getMaterialInventory(@PathVariable Long materialId) {
|
||||
List<MaterialInventoryVo> inventoryList = iMatPurchaseService.queryMaterialInventory(materialId);
|
||||
return R.ok(inventoryList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有物料库存信息(当前库存和在途数量)
|
||||
*/
|
||||
@GetMapping("/inventory")
|
||||
public R<List<MaterialInventoryVo>> getAllMaterialInventory() {
|
||||
List<MaterialInventoryVo> inventoryList = iMatPurchaseService.queryMaterialInventory(null);
|
||||
return R.ok(inventoryList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取采购计划中所有物料的库存信息(当前库存和在途数量)
|
||||
*
|
||||
* @param purchaseId 采购单ID
|
||||
*/
|
||||
@GetMapping("/plan-inventory/{purchaseId}")
|
||||
public R<List<PurchasePlanMaterialInventoryVo>> getPurchasePlanMaterialInventory(@PathVariable Long purchaseId) {
|
||||
List<PurchasePlanMaterialInventoryVo> inventoryList = iMatPurchaseService.queryPurchasePlanMaterialInventory(purchaseId);
|
||||
return R.ok(inventoryList);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,13 +48,4 @@ public interface IMatPurchaseService {
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
/**
|
||||
* 查询物料库存信息(当前库存和在途数量)
|
||||
*/
|
||||
List<MaterialInventoryVo> queryMaterialInventory(Long materialId);
|
||||
|
||||
/**
|
||||
* 查询采购计划中所有物料的库存信息(当前库存和在途数量)
|
||||
*/
|
||||
List<PurchasePlanMaterialInventoryVo> queryPurchasePlanMaterialInventory(Long purchaseId);
|
||||
}
|
||||
|
||||
@@ -1,27 +1,32 @@
|
||||
package com.gear.mat.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.gear.common.utils.StringUtils;
|
||||
import com.gear.common.core.page.TableDataInfo;
|
||||
import com.gear.common.core.domain.PageQuery;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.gear.mat.domain.vo.MaterialInventoryVo;
|
||||
import com.gear.mat.domain.MatPurchase;
|
||||
import com.gear.mat.domain.bo.MatPurchaseBo;
|
||||
import com.gear.mat.domain.bo.MatPurchaseInDetailBo;
|
||||
import com.gear.mat.domain.vo.*;
|
||||
import com.gear.mat.mapper.MatPurchaseMapper;
|
||||
import com.gear.mat.service.IMatPurchaseInDetailService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.gear.mat.domain.bo.MatMaterialBo;
|
||||
import com.gear.mat.domain.vo.MatMaterialVo;
|
||||
import com.gear.mat.domain.vo.MatMaterialWithInventoryVo;
|
||||
import com.gear.mat.domain.MatMaterial;
|
||||
import com.gear.mat.mapper.MatMaterialMapper;
|
||||
import com.gear.mat.service.IMatMaterialService;
|
||||
import com.gear.mat.service.IMatPurchaseService;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 配料配件基础信息Service业务层处理
|
||||
@@ -34,7 +39,8 @@ import java.util.stream.Collectors;
|
||||
public class MatMaterialServiceImpl implements IMatMaterialService {
|
||||
|
||||
private final MatMaterialMapper baseMapper;
|
||||
private final IMatPurchaseService matPurchaseService;
|
||||
private final MatPurchaseMapper matPurchaseMapper;
|
||||
private final IMatPurchaseInDetailService matPurchaseInDetailService;
|
||||
|
||||
/**
|
||||
* 查询配料配件基础信息
|
||||
@@ -128,7 +134,7 @@ public class MatMaterialServiceImpl implements IMatMaterialService {
|
||||
MatMaterialWithInventoryVo inventoryVo = new MatMaterialWithInventoryVo(material);
|
||||
|
||||
// 查询该物料的库存信息
|
||||
List<MaterialInventoryVo> materialInventoryList = matPurchaseService.queryMaterialInventory(material.getMaterialId());
|
||||
List<MaterialInventoryVo> materialInventoryList = queryMaterialInventory(material.getMaterialId());
|
||||
|
||||
if (!materialInventoryList.isEmpty()) {
|
||||
MaterialInventoryVo inventoryInfo = materialInventoryList.get(0);
|
||||
@@ -159,7 +165,7 @@ public class MatMaterialServiceImpl implements IMatMaterialService {
|
||||
MatMaterialWithInventoryVo inventoryVo = new MatMaterialWithInventoryVo(material);
|
||||
|
||||
// 查询该物料的库存信息
|
||||
List<MaterialInventoryVo> materialInventoryList = matPurchaseService.queryMaterialInventory(material.getMaterialId());
|
||||
List<MaterialInventoryVo> materialInventoryList = queryMaterialInventory(material.getMaterialId());
|
||||
|
||||
if (!materialInventoryList.isEmpty()) {
|
||||
MaterialInventoryVo inventoryInfo = materialInventoryList.get(0);
|
||||
@@ -172,4 +178,95 @@ public class MatMaterialServiceImpl implements IMatMaterialService {
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
public List<MaterialInventoryVo> queryMaterialInventory(Long materialId) {
|
||||
// 创建结果列表
|
||||
List<MaterialInventoryVo> result = new ArrayList<>();
|
||||
|
||||
// 构建采购单查询条件(直接用QueryWrapper,和Service层逻辑保持一致)
|
||||
QueryWrapper<MatPurchase> purchaseQw = new QueryWrapper<>();
|
||||
if (materialId != null) {
|
||||
purchaseQw.eq("material_id", materialId);
|
||||
}
|
||||
// 直接查采购单PO
|
||||
List<MatPurchase> purchaseListPo = matPurchaseMapper.selectList(purchaseQw);
|
||||
|
||||
// 将PO转换为VO,以便后续处理
|
||||
List<MatPurchaseVo> purchaseList = purchaseListPo.stream()
|
||||
.map(purchase -> {
|
||||
MatPurchaseVo vo = new MatPurchaseVo();
|
||||
BeanUtils.copyProperties(purchase, vo);
|
||||
return vo;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 按物料ID分组
|
||||
Map<Long, List<MatPurchaseVo>> purchaseMap = purchaseList.stream()
|
||||
.collect(Collectors.groupingBy(MatPurchaseVo::getMaterialId));
|
||||
|
||||
for (Long matId : purchaseMap.keySet()) {
|
||||
|
||||
// 通过采购单中的物料ID查询物料详细信息
|
||||
MatMaterialVo material = baseMapper.selectVoById(matId);
|
||||
|
||||
MaterialInventoryVo inventory = new MaterialInventoryVo();
|
||||
inventory.setMaterialId(matId);
|
||||
|
||||
if (material != null) {
|
||||
inventory.setMaterialName(material.getMaterialName());
|
||||
inventory.setSpec(material.getSpec());
|
||||
inventory.setModel(material.getModel());
|
||||
inventory.setUnit(material.getUnit());
|
||||
inventory.setCurrentStock(material.getCurrentStock());
|
||||
}
|
||||
|
||||
List<MatPurchaseVo> purchases = purchaseMap.get(matId);
|
||||
|
||||
// 计算计划总数
|
||||
BigDecimal planTotal = purchases.stream()
|
||||
.map(MatPurchaseVo::getPlanNum)
|
||||
.filter(Objects::nonNull)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
inventory.setPlanNum(planTotal);
|
||||
|
||||
// 计算已入库数量和在途数量
|
||||
BigDecimal receivedTotal = BigDecimal.ZERO;
|
||||
BigDecimal inTransitTotal = BigDecimal.ZERO;
|
||||
|
||||
for (MatPurchaseVo purchase : purchases) {
|
||||
// 查询该采购单下的入库详情
|
||||
MatPurchaseInDetailBo detailBo = new MatPurchaseInDetailBo();
|
||||
detailBo.setPurchaseId(purchase.getPurchaseId());
|
||||
|
||||
List<MatPurchaseInDetailVo> details = matPurchaseInDetailService.queryList(detailBo);
|
||||
|
||||
// 计算该采购单的已入库数量
|
||||
BigDecimal receivedInPurchase = details.stream()
|
||||
.map(MatPurchaseInDetailVo::getInNum)
|
||||
.filter(Objects::nonNull)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
receivedTotal = receivedTotal.add(receivedInPurchase);
|
||||
|
||||
// 根据采购单状态判断在途数量
|
||||
// 1-待入(在途) 2-已完成(全部入库) 3-已取消(归零) 4-部分入库
|
||||
if (purchase.getStatus() != null && (purchase.getStatus() == 1 || purchase.getStatus() == 4)) {
|
||||
// 在途或部分入库,计算未入库数量
|
||||
BigDecimal pending = purchase.getPlanNum().subtract(receivedInPurchase);
|
||||
if (pending.compareTo(BigDecimal.ZERO) > 0) {
|
||||
inTransitTotal = inTransitTotal.add(pending);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inventory.setReceivedNum(receivedTotal);
|
||||
inventory.setInTransitNum(inTransitTotal);
|
||||
|
||||
result.add(inventory);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +1,30 @@
|
||||
package com.gear.mat.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.gear.common.utils.StringUtils;
|
||||
import com.gear.common.core.page.TableDataInfo;
|
||||
import com.gear.common.core.domain.PageQuery;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.gear.mat.domain.bo.MatPurchaseInDetailBo;
|
||||
import com.gear.mat.domain.vo.MatPurchaseInDetailVo;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.gear.common.utils.StringUtils;
|
||||
import com.gear.common.core.domain.PageQuery;
|
||||
import com.gear.common.core.page.TableDataInfo;
|
||||
import com.gear.mat.domain.MatMaterial;
|
||||
import com.gear.mat.domain.MatPriceHistory;
|
||||
import com.gear.mat.domain.MatPurchaseInDetail;
|
||||
import com.gear.mat.domain.bo.*;
|
||||
import com.gear.mat.domain.vo.*;
|
||||
import com.gear.mat.mapper.MatMaterialMapper;
|
||||
import com.gear.mat.mapper.MatPriceHistoryMapper;
|
||||
import com.gear.mat.mapper.MatPurchaseInDetailMapper;
|
||||
import com.gear.mat.service.IMatPurchaseInDetailService;
|
||||
import com.gear.mat.service.IMatMaterialService;
|
||||
import com.gear.mat.service.IMatPriceHistoryService;
|
||||
import com.gear.mat.domain.vo.MatMaterialVo;
|
||||
import com.gear.mat.domain.vo.MatPriceHistoryVo;
|
||||
import com.gear.mat.domain.bo.MatMaterialBo;
|
||||
import com.gear.mat.domain.bo.MatPriceHistoryBo;
|
||||
import com.gear.mat.service.IMatPurchaseInDetailService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -39,7 +38,8 @@ import java.util.stream.Collectors;
|
||||
public class MatPurchaseInDetailServiceImpl implements IMatPurchaseInDetailService {
|
||||
|
||||
private final MatPurchaseInDetailMapper baseMapper;
|
||||
private final IMatMaterialService matMaterialService;
|
||||
private final MatMaterialMapper matMaterialMapper; // 使用Mapper代替Service避免循环依赖
|
||||
private final MatPriceHistoryMapper matPriceHistoryMapper; // 添加PriceHistory的Mapper
|
||||
private final IMatPriceHistoryService matPriceHistoryService;
|
||||
|
||||
/**
|
||||
@@ -190,16 +190,13 @@ public class MatPurchaseInDetailServiceImpl implements IMatPurchaseInDetailServi
|
||||
* 更新库存数量
|
||||
*/
|
||||
private void updateInventory(Long materialId, BigDecimal quantity) {
|
||||
MatMaterialVo material = matMaterialService.queryById(materialId);
|
||||
MatMaterial material = matMaterialMapper.selectById(materialId);
|
||||
if (material != null) {
|
||||
MatMaterialBo materialBo = new MatMaterialBo();
|
||||
materialBo.setMaterialId(materialId);
|
||||
|
||||
// 计算新的库存数量
|
||||
BigDecimal newStock = material.getCurrentStock().add(quantity);
|
||||
materialBo.setCurrentStock(newStock);
|
||||
material.setCurrentStock(newStock);
|
||||
|
||||
matMaterialService.updateByBo(materialBo);
|
||||
matMaterialMapper.updateById(material);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,7 +205,7 @@ public class MatPurchaseInDetailServiceImpl implements IMatPurchaseInDetailServi
|
||||
*/
|
||||
private void insertPriceHistory(Long materialId, BigDecimal price, BigDecimal quantity, Long detailId) {
|
||||
// 获取当前库存和平均价格信息
|
||||
MatMaterialVo material = matMaterialService.queryById(materialId);
|
||||
MatMaterial material = matMaterialMapper.selectById(materialId);
|
||||
if (material != null) {
|
||||
// 计算新的平均价格
|
||||
BigDecimal avgPrice = calculateAveragePrice(materialId, price, quantity);
|
||||
@@ -244,7 +241,7 @@ public class MatPurchaseInDetailServiceImpl implements IMatPurchaseInDetailServi
|
||||
MatPriceHistoryVo lastHistory = historyList.get(0); // 最近的一条记录
|
||||
|
||||
// 获取当前物料的现有库存
|
||||
MatMaterialVo material = matMaterialService.queryById(materialId);
|
||||
MatMaterial material = matMaterialMapper.selectById(materialId);
|
||||
if (material == null) {
|
||||
return newPrice;
|
||||
}
|
||||
@@ -273,7 +270,7 @@ public class MatPurchaseInDetailServiceImpl implements IMatPurchaseInDetailServi
|
||||
* 还原库存数量(减少库存)
|
||||
*/
|
||||
private void revertInventory(Long materialId, BigDecimal quantity) {
|
||||
MatMaterialVo material = matMaterialService.queryById(materialId);
|
||||
MatMaterial material = matMaterialMapper.selectById(materialId);
|
||||
if (material != null) {
|
||||
// 验证要减少的数量不能大于当前库存
|
||||
if (quantity.compareTo(material.getCurrentStock()) > 0) {
|
||||
@@ -281,17 +278,14 @@ public class MatPurchaseInDetailServiceImpl implements IMatPurchaseInDetailServi
|
||||
}
|
||||
|
||||
|
||||
MatMaterialBo materialBo = new MatMaterialBo();
|
||||
materialBo.setMaterialId(materialId);
|
||||
|
||||
// 计算还原后的库存数量(减去本次入库的数量)
|
||||
BigDecimal newStock = material.getCurrentStock().subtract(quantity);
|
||||
if (newStock.compareTo(BigDecimal.ZERO) < 0) {
|
||||
newStock = BigDecimal.ZERO; // 库存不能为负数
|
||||
}
|
||||
materialBo.setCurrentStock(newStock);
|
||||
material.setCurrentStock(newStock);
|
||||
|
||||
matMaterialService.updateByBo(materialBo);
|
||||
matMaterialMapper.updateById(material);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,10 +20,12 @@ import com.gear.mat.service.IMatPurchaseService;
|
||||
import com.gear.mat.service.IMatMaterialService;
|
||||
import com.gear.mat.service.IMatPurchaseInDetailService;
|
||||
import com.gear.mat.domain.bo.MatPurchaseInDetailBo;
|
||||
import com.gear.mat.mapper.MatMaterialMapper;
|
||||
|
||||
import java.util.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 采购单主(管理在途库存)Service业务层处理
|
||||
@@ -36,7 +38,7 @@ import java.util.stream.Collectors;
|
||||
public class MatPurchaseServiceImpl implements IMatPurchaseService {
|
||||
|
||||
private final MatPurchaseMapper baseMapper;
|
||||
private final IMatMaterialService matMaterialService;
|
||||
private final MatMaterialMapper matMaterialMapper;
|
||||
private final IMatPurchaseInDetailService matPurchaseInDetailService;
|
||||
|
||||
/**
|
||||
@@ -145,98 +147,51 @@ public class MatPurchaseServiceImpl implements IMatPurchaseService {
|
||||
return baseMapper.deleteBatchIds(ids) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MaterialInventoryVo> queryMaterialInventory(Long materialId) {
|
||||
// 创建结果列表
|
||||
List<MaterialInventoryVo> result = new ArrayList<>();
|
||||
|
||||
// 构建查询条件
|
||||
MatPurchaseBo purchaseBo = new MatPurchaseBo();
|
||||
if (materialId != null) {
|
||||
purchaseBo.setMaterialId(materialId);
|
||||
}
|
||||
|
||||
// 查询所有相关的采购单
|
||||
List<MatPurchaseVo> purchaseList = queryList(purchaseBo);
|
||||
|
||||
// 按物料ID分组
|
||||
Map<Long, List<MatPurchaseVo>> purchaseMap = purchaseList.stream()
|
||||
.collect(Collectors.groupingBy(MatPurchaseVo::getMaterialId));
|
||||
|
||||
for (Long matId : purchaseMap.keySet()) {
|
||||
// 获取物料信息
|
||||
MatMaterialVo material = matMaterialService.queryById(matId);
|
||||
|
||||
MaterialInventoryVo inventory = new MaterialInventoryVo();
|
||||
inventory.setMaterialId(matId);
|
||||
|
||||
if (material != null) {
|
||||
inventory.setMaterialName(material.getMaterialName());
|
||||
inventory.setSpec(material.getSpec());
|
||||
inventory.setModel(material.getModel());
|
||||
inventory.setUnit(material.getUnit());
|
||||
inventory.setCurrentStock(material.getCurrentStock());
|
||||
}
|
||||
|
||||
List<MatPurchaseVo> purchases = purchaseMap.get(matId);
|
||||
|
||||
// 计算计划总数
|
||||
BigDecimal planTotal = purchases.stream()
|
||||
.map(MatPurchaseVo::getPlanNum)
|
||||
.filter(num -> num != null)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
inventory.setPlanNum(planTotal);
|
||||
|
||||
// 计算已入库数量和在途数量
|
||||
BigDecimal receivedTotal = BigDecimal.ZERO;
|
||||
BigDecimal inTransitTotal = BigDecimal.ZERO;
|
||||
|
||||
for (MatPurchaseVo purchase : purchases) {
|
||||
// 查询该采购单下的入库详情
|
||||
MatPurchaseInDetailBo detailBo = new MatPurchaseInDetailBo();
|
||||
detailBo.setPurchaseId(purchase.getPurchaseId());
|
||||
|
||||
List<MatPurchaseInDetailVo> details = matPurchaseInDetailService.queryList(detailBo);
|
||||
|
||||
// 计算该采购单的已入库数量
|
||||
BigDecimal receivedInPurchase = details.stream()
|
||||
.map(MatPurchaseInDetailVo::getInNum)
|
||||
.filter(num -> num != null)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
receivedTotal = receivedTotal.add(receivedInPurchase);
|
||||
|
||||
// 根据采购单状态判断在途数量
|
||||
// 1-待入(在途) 2-已完成(全部入库) 3-已取消(归零) 4-部分入库
|
||||
if (purchase.getStatus() != null && (purchase.getStatus() == 1 || purchase.getStatus() == 4)) {
|
||||
// 在途或部分入库,计算未入库数量
|
||||
BigDecimal pending = purchase.getPlanNum().subtract(receivedInPurchase);
|
||||
if (pending.compareTo(BigDecimal.ZERO) > 0) {
|
||||
inTransitTotal = inTransitTotal.add(pending);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inventory.setReceivedNum(receivedTotal);
|
||||
inventory.setInTransitNum(inTransitTotal);
|
||||
|
||||
result.add(inventory);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public List<MatPurchaseVo> convertToPurchaseWithInventoryVo(List<MatPurchaseVo> purchaseList) {
|
||||
List<MatPurchaseVo> result = new ArrayList<>();
|
||||
|
||||
// 批量获取所有物料ID
|
||||
Set<Long> materialIds = purchaseList.stream()
|
||||
.map(MatPurchaseVo::getMaterialId)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// 批量查询物料信息,避免N+1查询问题
|
||||
Map<Long, MatMaterialVo> materialMap = new HashMap<>();
|
||||
if (!materialIds.isEmpty()) {
|
||||
List<MatMaterialVo> materials = new ArrayList<>();
|
||||
for (Long materialId : materialIds) {
|
||||
MatMaterialVo material = matMaterialMapper.selectVoById(materialId);
|
||||
if (material != null) {
|
||||
materialMap.put(materialId, material);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 批量获取所有采购单ID
|
||||
List<Long> purchaseIds = purchaseList.stream()
|
||||
.map(MatPurchaseVo::getPurchaseId)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 批量查询所有入库详情,避免N+1查询问题
|
||||
Map<Long, List<MatPurchaseInDetailVo>> detailMap = new HashMap<>();
|
||||
if (!purchaseIds.isEmpty()) {
|
||||
for (Long purchaseId : purchaseIds) {
|
||||
MatPurchaseInDetailBo detailBo = new MatPurchaseInDetailBo();
|
||||
detailBo.setPurchaseId(purchaseId);
|
||||
List<MatPurchaseInDetailVo> details = matPurchaseInDetailService.queryList(detailBo);
|
||||
detailMap.put(purchaseId, details);
|
||||
}
|
||||
}
|
||||
|
||||
for (MatPurchaseVo purchase : purchaseList) {
|
||||
MatPurchaseVo vo = new MatPurchaseVo();
|
||||
|
||||
// 复制基本采购信息
|
||||
BeanUtils.copyProperties(purchase, vo);
|
||||
// 获取物料信息
|
||||
MatMaterialVo material = matMaterialService.queryById(purchase.getMaterialId());
|
||||
|
||||
// 获取物料信息 - 从预加载的Map中获取
|
||||
MatMaterialVo material = materialMap.get(purchase.getMaterialId());
|
||||
if (material != null) {
|
||||
vo.setMaterialName(material.getMaterialName());
|
||||
vo.setSpec(material.getSpec());
|
||||
@@ -245,15 +200,17 @@ public class MatPurchaseServiceImpl implements IMatPurchaseService {
|
||||
vo.setCurrentStock(material.getCurrentStock());
|
||||
}
|
||||
|
||||
// 计算已入库数量
|
||||
MatPurchaseInDetailBo detailBo = new MatPurchaseInDetailBo();
|
||||
detailBo.setPurchaseId(purchase.getPurchaseId());
|
||||
List<MatPurchaseInDetailVo> details = matPurchaseInDetailService.queryList(detailBo);
|
||||
// 获取入库详情 - 从预加载的Map中获取
|
||||
List<MatPurchaseInDetailVo> details = detailMap.get(purchase.getPurchaseId());
|
||||
|
||||
BigDecimal receivedTotal = details.stream()
|
||||
.map(MatPurchaseInDetailVo::getInNum)
|
||||
.filter(Objects::nonNull)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
// 计算已入库数量
|
||||
BigDecimal receivedTotal = BigDecimal.ZERO;
|
||||
if (details != null && !details.isEmpty()) {
|
||||
receivedTotal = details.stream()
|
||||
.map(MatPurchaseInDetailVo::getInNum)
|
||||
.filter(Objects::nonNull)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
}
|
||||
|
||||
vo.setReceivedNum(receivedTotal);
|
||||
|
||||
@@ -278,71 +235,4 @@ public class MatPurchaseServiceImpl implements IMatPurchaseService {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PurchasePlanMaterialInventoryVo> queryPurchasePlanMaterialInventory(Long purchaseId) {
|
||||
List<PurchasePlanMaterialInventoryVo> result = new ArrayList<>();
|
||||
|
||||
if (purchaseId == null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// 查询采购单信息
|
||||
MatPurchaseVo purchase = queryById(purchaseId);
|
||||
if (purchase == null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// 获取物料信息
|
||||
MatMaterialVo material = matMaterialService.queryById(purchase.getMaterialId());
|
||||
|
||||
// 创建库存信息对象
|
||||
PurchasePlanMaterialInventoryVo inventory = new PurchasePlanMaterialInventoryVo();
|
||||
inventory.setPurchaseId(purchase.getPurchaseId());
|
||||
inventory.setPurchaseNo(purchase.getPurchaseNo());
|
||||
inventory.setMaterialId(purchase.getMaterialId());
|
||||
|
||||
if (material != null) {
|
||||
inventory.setMaterialName(material.getMaterialName());
|
||||
inventory.setSpec(material.getSpec());
|
||||
inventory.setModel(material.getModel());
|
||||
inventory.setUnit(material.getUnit());
|
||||
inventory.setCurrentStock(material.getCurrentStock());
|
||||
}
|
||||
|
||||
// 设置计划采购数量
|
||||
inventory.setPlanNum(purchase.getPlanNum());
|
||||
|
||||
// 查询该采购单下的入库详情
|
||||
MatPurchaseInDetailBo detailBo = new MatPurchaseInDetailBo();
|
||||
detailBo.setPurchaseId(purchase.getPurchaseId());
|
||||
|
||||
List<MatPurchaseInDetailVo> details = matPurchaseInDetailService.queryList(detailBo);
|
||||
|
||||
// 计算已入库数量
|
||||
BigDecimal receivedTotal = details.stream()
|
||||
.map(MatPurchaseInDetailVo::getInNum)
|
||||
.filter(num -> num != null)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
inventory.setReceivedNum(receivedTotal);
|
||||
|
||||
// 根据采购单状态判断在途数量
|
||||
// 1-待入(在途) 2-已完成(全部入库) 3-已取消(归零) 4-部分入库
|
||||
if (purchase.getStatus() != null && (purchase.getStatus() == 1 || purchase.getStatus() == 4)) {
|
||||
// 在途或部分入库,计算未入库数量
|
||||
BigDecimal pending = purchase.getPlanNum().subtract(receivedTotal);
|
||||
if (pending.compareTo(BigDecimal.ZERO) > 0) {
|
||||
inventory.setInTransitNum(pending);
|
||||
} else {
|
||||
inventory.setInTransitNum(BigDecimal.ZERO);
|
||||
}
|
||||
} else {
|
||||
// 已完成或已取消,没有在途数量
|
||||
inventory.setInTransitNum(BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
result.add(inventory);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user