Merge remote-tracking branch 'origin/wms_dev' into wms_dev

This commit is contained in:
王奎兴
2026-01-27 17:23:22 +08:00
14 changed files with 1056 additions and 88 deletions
@@ -317,10 +317,6 @@ public class InMaterialDetail extends BaseVOEntity {
@Excel(name = "入库数量")
private BigDecimal inboundQuantity;
@ApiModelProperty("出库数量")
@Excel(name = "出库数量")
private BigDecimal outboundQuantity;
@ApiModelProperty("总净重(KG)")
@Excel(name = "总净重(KG)")
private BigDecimal totalNetWeight;
@@ -138,7 +138,39 @@ public class InvestigationManageImpl extends ServiceImpl<InvestigationManageMapp
for (int i = 0; i < investigetionManageDetailList.size(); i++) {
ids[i] = investigetionManageDetailList.get(i).getInvestigationManageDetailId();
}
investigetionManageDetailService.delete(ids);
LambdaQueryWrapper<InvestigetionManageDetail> detailLambdaQueryWrapper = new LambdaQueryWrapper<InvestigetionManageDetail>()
.eq(InvestigetionManageDetail::getInvestigationNumber, investigationManage.getInvestigationNumber())
.notIn(InvestigetionManageDetail::getInvestigationManageDetailId, ids);
investigetionManageDetailService.remove(detailLambdaQueryWrapper);
// investigetionManageDetailService.delete(ids);
List<InvestigetionManageDetail> updateList = investigetionManageDetailList.stream().filter(detail ->
detail.getInvestigationManageDetailId() != null).collect(Collectors.toList());
investigetionManageDetailService.updateBatchById(updateList);
List<InvestigetionManageDetail> saveList = investigetionManageDetailList.stream()
.filter(detail -> detail.getInvestigationManageDetailId() == null)
.collect(Collectors.toList());
LoginUser loginUser = SecurityUtils.getLoginUser();
UserPo userPo = loginUser.getUserPo();
saveList.forEach(e -> {
e.setWarehouseCode(e.getWarehouseCode());
e.setWarehouseId(e.getWarehouseId());
e.setWarehouseName(e.getWarehouseName());
e.setOrganizationId(userPo.getOrganizationId());
e.setOrganizationName(userPo.getOrganizationName());
e.setTopOrganizationId(userPo.getTopOrganizationId());
e.setCreateByName(loginUser.getUsername());
e.setCreateBy(loginUser.getUserid());
e.setCreateTime(new Date());
e.setUpdateByName(loginUser.getUsername());
e.setUpdateBy(loginUser.getUserid());
e.setUpdateTime(new Date());
e.setInvestigationNumber(investigationManage.getInvestigationNumber());
e.setInvestigationFrequency(1);
InvestigetionManageDetailDO investigetionManageDetailDO = new InvestigetionManageDetailDO();
BeanUtils.copyProperties(e, investigetionManageDetailDO);
investigetionManageDetailService.insert(investigetionManageDetailDO);
});
return this.updateById(investigationManage);
}
@@ -14,6 +14,9 @@ import com.mhd.wms.domain.materialInventory.repository.po.MaterialInventoryQuery
import com.mhd.wms.domain.materialInventory.repository.todo.MaterialInventoryDO;
import com.mhd.wms.domain.materialInventory.repository.todo.MaterialInventoryParentDO;
import com.mhd.wms.domain.materialInventory.repository.todo.MaterialInventoryQueryListDO;
import com.mhd.wms.domain.materialBaseInfo.repository.facade.IMaterialBaseInfoService;
import com.mhd.wms.domain.materialBaseInfo.repository.po.MaterialBaseInfoPO;
import com.mhd.wms.domain.materialBaseInfo.repository.todo.MaterialBaseInfoDO;
import com.mhd.wms.domain.statementStatistics.po.ImmediateInventoryPO;
import com.mhd.wms.domain.statementStatistics.todo.ImmediateInventoryDO;
import org.springframework.beans.BeanUtils;
@@ -24,6 +27,7 @@ import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
/**
* 物料库存Service业务层处理
@@ -35,6 +39,8 @@ import java.util.*;
public class MaterialInventoryImpl extends ServiceImpl<MaterialInventoryMapper, MaterialInventory> implements IMaterialInventoryService{
@Autowired
private MaterialInventoryMapper materialInventoryMapper;
@Autowired
private IMaterialBaseInfoService materialBaseInfoService;
/**
* 查询物料库存列表
@@ -136,16 +142,80 @@ public class MaterialInventoryImpl extends ServiceImpl<MaterialInventoryMapper,
List<MaterialInventory> materialInventoryList = new ArrayList<>();
List<MaterialInventoryDO> materialInventoryDOListByUpdate = new ArrayList<>();
Map<String, MaterialInventory> materialInventoryAddNowMap = new HashMap<>();
// 批量获取物料基础信息,以获取货主ID(用于查询和key生成)
Map<Long, Long> materialBaseInfoIdToShipperIdMap = new HashMap<>();
if (!CollectionUtils.isEmpty(materialInventoryDOList)) {
Set<Long> materialBaseInfoIds = new HashSet<>();
for (MaterialInventoryDO materialInventoryDO : materialInventoryDOList) {
if (materialInventoryDO.getMaterialBaseInfoId() != null) {
materialBaseInfoIds.add(materialInventoryDO.getMaterialBaseInfoId());
}
}
// 批量查询物料基础信息,获取货主ID
for (Long materialBaseInfoId : materialBaseInfoIds) {
try {
MaterialBaseInfoDO materialBaseInfoDO = new MaterialBaseInfoDO();
materialBaseInfoDO.setMaterialBaseInfoId(materialBaseInfoId);
List<MaterialBaseInfoPO> materialBaseInfoList = materialBaseInfoService.queryList(materialBaseInfoDO);
if (!CollectionUtils.isEmpty(materialBaseInfoList)) {
MaterialBaseInfoPO materialBaseInfoPO = materialBaseInfoList.get(0);
if (materialBaseInfoPO.getShipperId() != null) {
materialBaseInfoIdToShipperIdMap.put(materialBaseInfoId, materialBaseInfoPO.getShipperId());
}
}
} catch (Exception e) {
// 如果查询失败,记录日志但继续处理
// log.warn("查询物料基础信息失败,物料基础信息ID:{},错误:{}", materialBaseInfoId, e.getMessage());
}
}
}
for (MaterialInventoryDO materialInventoryDO : materialInventoryDOList) {
// 获取货主ID(优先使用materialInventoryDO中的,如果没有则从物料基础信息中获取)
Long shipperId = materialInventoryDO.getShipperId();
if (shipperId == null && materialInventoryDO.getMaterialBaseInfoId() != null) {
shipperId = materialBaseInfoIdToShipperIdMap.get(materialInventoryDO.getMaterialBaseInfoId());
}
//TODO 若数据量升级 后期优化
// 查询现有库存时,需要通过关联查询包含货主ID条件
// 由于MaterialInventory实体没有shipperId字段,我们需要通过materialBaseInfoId来间接查询
// 如果materialInventoryDO中有shipperId,我们需要确保查询到的库存记录的物料基础信息对应的货主ID匹配
MaterialInventory materialInventoryDb = materialInventoryMapper.selectOne(new QueryWrapper<MaterialInventory>().lambda()
.eq(MaterialInventory::getStorageSectionId, materialInventoryDO.getStorageSectionId())
.eq(MaterialInventory::getMaterialBaseInfoId, materialInventoryDO.getMaterialBaseInfoId())
.eq(MaterialInventory::getBatchNumber, materialInventoryDO.getBatchNumber())
.eq(MaterialInventory::getContainerId, materialInventoryDO.getContainerId()));
.eq(MaterialInventory::getContainerId, materialInventoryDO.getContainerId())
.eq(MaterialInventory::getDelFlag, 1));
// 如果查询到了库存记录,需要验证货主ID是否匹配
if (ObjectUtil.isNotNull(materialInventoryDb) && shipperId != null) {
// 验证查询到的库存记录对应的物料基础信息的货主ID是否匹配
try {
MaterialBaseInfoDO materialBaseInfoDO = new MaterialBaseInfoDO();
materialBaseInfoDO.setMaterialBaseInfoId(materialInventoryDb.getMaterialBaseInfoId());
List<MaterialBaseInfoPO> materialBaseInfoList = materialBaseInfoService.queryList(materialBaseInfoDO);
if (!CollectionUtils.isEmpty(materialBaseInfoList)) {
MaterialBaseInfoPO materialBaseInfoPO = materialBaseInfoList.get(0);
// 如果货主ID不匹配,说明这是不同货主的库存,应该创建新记录
if (materialBaseInfoPO.getShipperId() == null || !materialBaseInfoPO.getShipperId().equals(shipperId)) {
materialInventoryDb = null; // 设置为null,后续会创建新记录
}
}
} catch (Exception e) {
// 如果验证失败,记录日志但继续处理(创建新记录)
// log.warn("验证库存记录货主ID失败,物料基础信息ID:{},错误:{}", materialInventoryDb.getMaterialBaseInfoId(), e.getMessage());
}
}
if (ObjectUtil.isNull(materialInventoryDb)){
String key = materialInventoryDO.getStorageLocationId() + "_" + materialInventoryDO.getMaterialBaseInfoId()
+ "_" + materialInventoryDO.getBatchNumber() + "_" + materialInventoryDO.getMaterialStatusCode();
// 生成key时包含货主ID,确保不同货主的库存不会合并
String key = (shipperId != null ? shipperId : "null") + "_"
+ materialInventoryDO.getStorageLocationId() + "_"
+ materialInventoryDO.getMaterialBaseInfoId()
+ "_" + materialInventoryDO.getBatchNumber() + "_"
+ materialInventoryDO.getMaterialStatusCode();
if (ObjectUtil.isNotNull(materialInventoryDO.getContainerId())){
key = key + "_" + materialInventoryDO.getContainerId();
}
@@ -14,6 +14,10 @@ import com.mhd.common.core.web.domain.AjaxResult;
import com.mhd.common.security.utils.SecurityUtils;
import com.mhd.system.api.SystemServiceFeign;
import com.mhd.system.api.model.LoginUser;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mhd.wms.domain.inMaterialDetail.entity.InMaterialDetail;
import com.mhd.wms.domain.inMaterialDetail.repository.facade.IInMaterialDetailService;
import com.mhd.wms.domain.inMaterialDetail.repository.po.InMaterialDetailPO;
import com.mhd.wms.domain.inMaterialDetailSerialNumber.entity.InMaterialDetailSerialNumber;
import com.mhd.wms.domain.inMaterialDetailSerialNumber.repository.facade.IInMaterialDetailSerialNumberService;
import com.mhd.wms.domain.inMaterialDetailSerialNumber.repository.todo.InMaterialDetailSerialNumberDO;
@@ -58,6 +62,8 @@ public class ReceiptMaterialDetailImpl extends ServiceImpl<ReceiptMaterialDetail
@Autowired
private IMaterialMoreDetailService IMaterialMoreDetailService;
@Autowired
private IInMaterialDetailService iInMaterialDetailService;
@Autowired
private IdGenerator idGenerator;
@Resource
private SystemServiceFeign systemServiceFeign;
@@ -92,6 +98,8 @@ public class ReceiptMaterialDetailImpl extends ServiceImpl<ReceiptMaterialDetail
materialMoreDetailList = JSON.parseArray(JSONObject.toJSONString(ajaxResult.get("data")), MaterialMoreDetailPO.class);
}
}
// 从入库单明细表中获取InvoiceNo、BatchRefNo、SheetRefNo、BoxPalletNo字段的值
fillAttributeValueFromInMaterialDetail(receiptMaterialDetailPO, materialMoreDetailList);
receiptMaterialDetailPO.setMaterialMoreDetailList(materialMoreDetailList);
});
// 获取查询的层级
@@ -102,17 +110,18 @@ public class ReceiptMaterialDetailImpl extends ServiceImpl<ReceiptMaterialDetail
List<ReceiptMaterialDetailPO> children = getChildren(materialDetailPO.getUniqueId(), receiptMaterialDetailPOList, 2);
children.forEach(childrenDetailPO -> {
MaterialMoreDetailDO materialMoreDetailDO = new MaterialMoreDetailDO();
materialMoreDetailDO.setMaterialDetailUniqueId(childrenDetailPO.getMaterialDetailId());
materialMoreDetailDO.setMaterialDetailUniqueId(childrenDetailPO.getUniqueId());
List<MaterialMoreDetailPO> materialMoreDetailList = IMaterialMoreDetailService.queryList(materialMoreDetailDO);
//如果收货单的物料批属性还没存入值,那么需要从批属性表获取
AjaxResult ajaxResult = null;
if (CollectionUtils.isEmpty(materialMoreDetailList)) {
ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(childrenDetailPO.getMaterialDetailId());
}
if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) {
materialMoreDetailList = JSON.parseArray(JSONObject.toJSONString(ajaxResult.get("data")), MaterialMoreDetailPO.class);
ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(childrenDetailPO.getMaterialBaseInfoId());
if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) {
materialMoreDetailList = JSON.parseArray(JSONObject.toJSONString(ajaxResult.get("data")), MaterialMoreDetailPO.class);
}
}
// 从入库单明细表中获取InvoiceNo、BatchRefNo、SheetRefNo、BoxPalletNo字段的值
fillAttributeValueFromInMaterialDetail(childrenDetailPO, materialMoreDetailList);
childrenDetailPO.setMaterialMoreDetailList(materialMoreDetailList);
});
@@ -253,6 +262,117 @@ public class ReceiptMaterialDetailImpl extends ServiceImpl<ReceiptMaterialDetail
if (!CollectionUtils.isEmpty(materialDetailSerialNumberList)){
inMaterialDetailSerialNumberService.saveBatch(materialDetailSerialNumberList);
}
//从materialMoreDetailList中根据attributeOption提取字段值并更新入库单明细
updateInMaterialDetailFromAttributeOption(receiptMaterialDetailDOList);
}
/**
* @description 从materialMoreDetailList中根据attributeOption提取字段值并更新入库单明细
* @author Auto
* @date 2026/1/24
* @param receiptMaterialDetailDOList
* @return void
*/
private void updateInMaterialDetailFromAttributeOption(List<ReceiptMaterialDetailDO> receiptMaterialDetailDOList) {
if (CollectionUtils.isEmpty(receiptMaterialDetailDOList)) {
return;
}
LoginUser loginUser = SecurityUtils.getLoginUser();
for (ReceiptMaterialDetailDO receiptMaterialDetailDO : receiptMaterialDetailDOList) {
Long inUniqueId = receiptMaterialDetailDO.getInUniqueId();
if (inUniqueId == null) {
continue;
}
List<MaterialMoreDetailDO> materialMoreDetailList = receiptMaterialDetailDO.getMaterialMoreDetailList();
if (CollectionUtils.isEmpty(materialMoreDetailList)) {
continue;
}
// 构建UpdateWrapper
UpdateWrapper<InMaterialDetail> updateWrapper = new UpdateWrapper<>();
updateWrapper.lambda().eq(InMaterialDetail::getUniqueId, inUniqueId);
boolean hasUpdate = false;
// 遍历materialMoreDetailList,根据attributeOption映射到对应字段
for (MaterialMoreDetailDO materialMoreDetail : materialMoreDetailList) {
String attributeOption = materialMoreDetail.getAttributeOption();
String attributeValue = materialMoreDetail.getAttributeValue();
// 如果attributeValue为空,跳过
if (attributeValue == null || attributeValue.trim().isEmpty()) {
continue;
}
// 根据attributeOption映射到入库单明细表的字段
if ("InvoiceNo".equalsIgnoreCase(attributeOption)) {
updateWrapper.lambda().set(InMaterialDetail::getInvoiceNo, attributeValue);
hasUpdate = true;
} else if ("BatchRefNo".equalsIgnoreCase(attributeOption)) {
updateWrapper.lambda().set(InMaterialDetail::getBatchRefNo, attributeValue);
hasUpdate = true;
} else if ("SheetRefNo".equalsIgnoreCase(attributeOption)) {
updateWrapper.lambda().set(InMaterialDetail::getSheetRefNo, attributeValue);
hasUpdate = true;
} else if ("BoxPalletNo".equalsIgnoreCase(attributeOption)) {
updateWrapper.lambda().set(InMaterialDetail::getBoxPalletNo, attributeValue);
hasUpdate = true;
}
}
// 如果有字段需要更新,则执行更新
if (hasUpdate) {
updateWrapper.lambda()
.set(InMaterialDetail::getUpdateBy, loginUser.getUserid())
.set(InMaterialDetail::getUpdateByName, loginUser.getUsername())
.set(InMaterialDetail::getUpdateTime, new Date());
iInMaterialDetailService.update(updateWrapper);
}
// 处理子项
List<ReceiptMaterialDetailDO> children = receiptMaterialDetailDO.getChildren();
if (!CollectionUtils.isEmpty(children)) {
updateInMaterialDetailFromAttributeOption(children);
}
}
}
/**
* @description 从入库单明细表中获取InvoiceNo、BatchRefNo、SheetRefNo、BoxPalletNo字段的值并填充到materialMoreDetailList的attributeValue中
* @author Auto
* @date 2026/1/24
* @param receiptMaterialDetailPO
* @param materialMoreDetailList
* @return void
*/
private void fillAttributeValueFromInMaterialDetail(ReceiptMaterialDetailPO receiptMaterialDetailPO, List<MaterialMoreDetailPO> materialMoreDetailList) {
if (CollectionUtils.isEmpty(materialMoreDetailList) || receiptMaterialDetailPO.getInUniqueId() == null) {
return;
}
// 查询入库单明细
QueryWrapper<InMaterialDetail> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("unique_id", receiptMaterialDetailPO.getInUniqueId());
queryWrapper.eq("del_flag", 1);
InMaterialDetail inMaterialDetail = iInMaterialDetailService.getOne(queryWrapper);
if (inMaterialDetail == null) {
return;
}
// 根据attributeOption从入库单明细中获取对应的值并填充到attributeValue
for (MaterialMoreDetailPO materialMoreDetail : materialMoreDetailList) {
String attributeOption = materialMoreDetail.getAttributeOption();
// 如果attributeValue已经有值,跳过
if (materialMoreDetail.getAttributeValue() != null && !materialMoreDetail.getAttributeValue().trim().isEmpty()) {
continue;
}
// 根据attributeOption映射到入库单明细表的字段
if ("InvoiceNo".equalsIgnoreCase(attributeOption)) {
materialMoreDetail.setAttributeValue(inMaterialDetail.getInvoiceNo());
} else if ("BatchRefNo".equalsIgnoreCase(attributeOption)) {
materialMoreDetail.setAttributeValue(inMaterialDetail.getBatchRefNo());
} else if ("SheetRefNo".equalsIgnoreCase(attributeOption)) {
materialMoreDetail.setAttributeValue(inMaterialDetail.getSheetRefNo());
} else if ("BoxPalletNo".equalsIgnoreCase(attributeOption)) {
materialMoreDetail.setAttributeValue(inMaterialDetail.getBoxPalletNo());
}
}
}
@@ -216,6 +216,38 @@ public class ReceiptMaterialDetailPO extends BaseVOEntity {
@Excel(name = "是否生成上架单: 1-是 2-否")
private Integer genStockShelf;
@ApiModelProperty("总净重(KG)")
@Excel(name = "总净重(KG)")
private BigDecimal totalNetWeight;
@ApiModelProperty("总毛重(KG)")
@Excel(name = "总毛重(KG)")
private BigDecimal totalGrossWeight;
@ApiModelProperty("总体积(CBM)")
@Excel(name = "总体积(CBM)")
private BigDecimal totalVolume;
@ApiModelProperty("总面积(SQM)")
@Excel(name = "总面积(SQM)")
private BigDecimal totalArea;
@ApiModelProperty("Invoice No.")
@Excel(name = "Invoice No.")
private String invoiceNo;
@ApiModelProperty("Batch Ref NO's")
@Excel(name = "Batch Ref NO's")
private String batchRefNo;
@ApiModelProperty("Sheet Ref NO's")
@Excel(name = "Sheet Ref NO's")
private String sheetRefNo;
@ApiModelProperty("箱号/卡板号")
@Excel(name = "箱号/卡板号")
private String boxPalletNo;
@ApiModelProperty("物料明细子集")
private List<ReceiptMaterialDetailPO> children;
@@ -129,7 +129,7 @@ public class ShiftManageImpl extends ServiceImpl<ShiftManageMapper, ShiftManage>
shiftMaterialDetailList.add(shiftMaterialDetail);
});
iShiftMaterialDetailService.saveBatch(shiftMaterialDetailList);
return this.save(shiftManage);
return this.updateById(shiftManage);
}
/**
@@ -24,6 +24,7 @@ import com.mhd.wms.domain.containerUsageRecord.repository.todo.ContainerUsageRec
import com.mhd.wms.domain.deliveTask.repository.facade.IDeliveTaskService;
import com.mhd.wms.domain.deliveTask.repository.todo.DeliveTaskDO;
import com.mhd.wms.domain.inMaterialDetail.repository.facade.IInMaterialDetailService;
import com.mhd.wms.domain.inMaterialDetail.repository.po.InMaterialDetailPO;
import com.mhd.wms.domain.inMaterialDetailSerialNumber.repository.facade.IInMaterialDetailSerialNumberService;
import com.mhd.wms.domain.inMaterialDetailSerialNumber.repository.po.InMaterialDetailSerialNumberPO;
import com.mhd.wms.domain.inMaterialDetailSerialNumber.repository.todo.InMaterialDetailSerialNumberDO;
@@ -31,6 +32,8 @@ import com.mhd.wms.domain.inOrderAbnormal.repository.facade.IInOrderAbnormalServ
import com.mhd.wms.domain.inOrderAbnormal.repository.todo.InOrderAbnormalBaseDO;
import com.mhd.wms.domain.inventoryStandingDetail.repository.facade.IInventoryStandingDetailService;
import com.mhd.wms.domain.inventoryStandingDetail.repository.todo.InventoryStandingDetailDO;
import com.mhd.wms.domain.inventoryStandingReport.repository.facade.IInventoryStandingReportService;
import com.mhd.wms.domain.inventoryStandingReport.repository.todo.InventoryStandingReportDO;
import com.mhd.wms.domain.materialGoodsRule.entity.MaterialGoodsRule;
import com.mhd.wms.domain.materialGoodsRule.repository.facade.IMaterialGoodsRuleService;
import com.mhd.wms.domain.materialMoreDetail.repository.facade.IMaterialMoreDetailService;
@@ -109,6 +112,8 @@ public class StockReceiptOrderDomainService {
@Autowired
private IInventoryStandingDetailService inventoryStandingDetailService;
@Autowired
private IInventoryStandingReportService inventoryStandingReportService;
@Autowired
private IdGenerator idGenerator;
@Autowired
private IContainerUsageRecordService containerUsageRecordService;
@@ -375,6 +380,8 @@ public class StockReceiptOrderDomainService {
}
//保存容器使用记录
genContainerUsageRecord(stockReceiptOrderDO);
//生成库存台账报表记录(收货虚拟库存)- 需要在batchReceiptUpdate之前调用,因为batchReceiptUpdate会将状态更新为3
genInventoryStandingReport(stockReceiptOrderPO, stockReceiptOrderDO);
//修改物料明细信息
receiptMaterialDetailService.batchReceiptUpdate(stockReceiptOrderDO);
//生成 收货作业单
@@ -497,6 +504,8 @@ public class StockReceiptOrderDomainService {
//生成收货追溯记录
genInventoryStandingDetail(stockReceiptOrderPO);
//生成库存台账报表记录(收货虚拟库存)
genInventoryStandingReport(stockReceiptOrderPO);
//存在异常 生成记录
if (abnormal == 1){
genInOrderAbnormal(stockReceiptOrderPO);
@@ -703,6 +712,26 @@ public class StockReceiptOrderDomainService {
List<ReceiptMaterialDetailPO> receiptMaterialDetailPOS = receiptMaterialDetailService.queryList(receiptMaterialDetailDO);
//上架单明细集合
List<ShelfMaterialDetailDO> shelfMaterialDetailDOList = new ArrayList<>();
// 批量查询入库单明细,用于获取净重、毛重、体积、面积等字段
List<Long> inUniqueIds = receiptMaterialDetailPOS.stream()
.filter(r -> 2 == r.getGenStockShelf() && r.getInUniqueId() != null)
.map(ReceiptMaterialDetailPO::getInUniqueId)
.distinct()
.collect(Collectors.toList());
Map<Long, InMaterialDetailPO> inMaterialDetailMap = new HashMap<>();
if (!CollectionUtils.isEmpty(inUniqueIds)) {
// 使用 MyBatis-Plus 的 QueryWrapper 批量查询入库单明细
QueryWrapper<com.mhd.wms.domain.inMaterialDetail.entity.InMaterialDetail> queryWrapper = new QueryWrapper<>();
queryWrapper.in("unique_id", inUniqueIds);
queryWrapper.eq("del_flag", 1);
List<com.mhd.wms.domain.inMaterialDetail.entity.InMaterialDetail> inMaterialDetailList = iInMaterialDetailService.list(queryWrapper);
// 转换为 PO 对象
for (com.mhd.wms.domain.inMaterialDetail.entity.InMaterialDetail inMaterialDetail : inMaterialDetailList) {
InMaterialDetailPO inMaterialDetailPO = new InMaterialDetailPO();
BeanUtils.copyProperties(inMaterialDetail, inMaterialDetailPO);
inMaterialDetailMap.put(inMaterialDetail.getUniqueId(), inMaterialDetailPO);
}
}
for (ReceiptMaterialDetailPO receiptMaterialDetailPO : receiptMaterialDetailPOS) {
if (2 == receiptMaterialDetailPO.getGenStockShelf()) {
ShelfMaterialDetailDO shelfMaterialDetailDO = new ShelfMaterialDetailDO();
@@ -710,6 +739,9 @@ public class StockReceiptOrderDomainService {
shelfMaterialDetailDO.setQuantity(receiptMaterialDetailPO.getReceiptQuantity());
shelfMaterialDetailDO.setInUniqueId(receiptMaterialDetailPO.getInUniqueId());
shelfMaterialDetailDO.setReceiptUniqueId(receiptMaterialDetailPO.getUniqueId());
// 从入库单明细中获取净重、毛重、体积、面积等字段
// 注意:由于 ShelfMaterialDetailDO 中没有这些字段,这些字段需要在查询时通过关联查询获取
// 或者需要先在上架单明细实体类中添加这些字段
shelfMaterialDetailDOList.add(shelfMaterialDetailDO);
receiptQuantity = receiptQuantity.add(receiptMaterialDetailPO.getReceiptQuantity());
}
@@ -957,6 +989,177 @@ public class StockReceiptOrderDomainService {
inventoryStandingDetailService.batchInsert(inventoryStandingDetailDOList);
}
/**
* @description 生成库存台账报表记录(收货虚拟库存)
* @author Auto
* @date 2026/1/24
* @param stockReceiptOrderPO
*/
public void genInventoryStandingReport(StockReceiptOrderPO stockReceiptOrderPO){
genInventoryStandingReport(stockReceiptOrderPO, null);
}
/**
* @description 生成库存台账报表记录(收货虚拟库存)- 重载方法,支持从stockReceiptOrderDO获取数据
* @author Auto
* @date 2026/1/24
* @param stockReceiptOrderPO
* @param stockReceiptOrderDO 如果提供,则从该对象中获取receipt_quantity,否则从数据库查询
*/
public void genInventoryStandingReport(StockReceiptOrderPO stockReceiptOrderPO, StockReceiptOrderDO stockReceiptOrderDO){
try {
// 重新查询最新的收货单信息,确保获取到最新的数据
StockReceiptOrderPO latestStockReceiptOrderPO = stockReceiptOrderService.getInfo(stockReceiptOrderPO.getReceiptOrderId());
if (latestStockReceiptOrderPO == null) {
log.warn("生成库存台账报表记录失败,收货单不存在,收货单ID:{}", stockReceiptOrderPO.getReceiptOrderId());
return;
}
// 如果提供了stockReceiptOrderDO,则从该对象中获取数据,否则从数据库查询
List<ReceiptMaterialDetailPO> receiptMaterialDetailPOList;
if (stockReceiptOrderDO != null && !CollectionUtils.isEmpty(stockReceiptOrderDO.getMaterialDetailList())) {
// 从stockReceiptOrderDO中获取数据,转换为ReceiptMaterialDetailPO
receiptMaterialDetailPOList = new ArrayList<>();
log.info("从stockReceiptOrderDO获取收货明细,收货单号:{},明细数量:{}",
latestStockReceiptOrderPO.getReceiptOrderNumber(),
stockReceiptOrderDO.getMaterialDetailList().size());
for (ReceiptMaterialDetailDO receiptMaterialDetailDO : stockReceiptOrderDO.getMaterialDetailList()) {
// 记录原始数据
log.debug("处理收货明细DO,物料编码:{},物料名称:{},收货数量:{},收货状态:{}",
receiptMaterialDetailDO.getMaterialCode(),
receiptMaterialDetailDO.getMaterialName(),
receiptMaterialDetailDO.getReceiptQuantity(),
receiptMaterialDetailDO.getReceiptStatus());
// 优先使用receiptMaterialDetailDO.getReceiptQuantity()的值(本次收货数量)
// 如果receiptQuantity为null或<=0,跳过该记录
if (receiptMaterialDetailDO.getReceiptQuantity() == null ||
receiptMaterialDetailDO.getReceiptQuantity().compareTo(BigDecimal.ZERO) <= 0) {
log.debug("跳过收货明细(收货数量为空或<=0),物料编码:{},收货数量:{}",
receiptMaterialDetailDO.getMaterialCode(),
receiptMaterialDetailDO.getReceiptQuantity());
continue;
}
ReceiptMaterialDetailPO receiptMaterialDetailPO = new ReceiptMaterialDetailPO();
BeanUtils.copyProperties(receiptMaterialDetailDO, receiptMaterialDetailPO);
// 设置收货单号
receiptMaterialDetailPO.setReceiptOrderNumber(latestStockReceiptOrderPO.getReceiptOrderNumber());
// 确保receiptQuantity字段被正确设置(使用DO中的值,因为已经验证过不为null且>0)
receiptMaterialDetailPO.setReceiptQuantity(receiptMaterialDetailDO.getReceiptQuantity());
// 如果receipt_status为空,则设置为2(收货中),因为这是在batchReceiptUpdate之前调用的
if (receiptMaterialDetailPO.getReceiptStatus() == null) {
receiptMaterialDetailPO.setReceiptStatus(2);
}
receiptMaterialDetailPOList.add(receiptMaterialDetailPO);
log.debug("添加收货明细PO到列表,物料编码:{},收货数量:{}",
receiptMaterialDetailPO.getMaterialCode(),
receiptMaterialDetailPO.getReceiptQuantity());
}
log.info("从stockReceiptOrderDO转换后的收货明细数量:{}", receiptMaterialDetailPOList.size());
} else {
// 从数据库查询
log.info("从数据库查询收货明细,收货单号:{}", latestStockReceiptOrderPO.getReceiptOrderNumber());
ReceiptMaterialDetailDO receiptMaterialDetailDO = new ReceiptMaterialDetailDO();
receiptMaterialDetailDO.setReceiptOrderNumber(latestStockReceiptOrderPO.getReceiptOrderNumber());
receiptMaterialDetailPOList = receiptMaterialDetailService.queryList(receiptMaterialDetailDO);
log.info("从数据库查询到的收货明细数量:{}", receiptMaterialDetailPOList != null ? receiptMaterialDetailPOList.size() : 0);
}
if (CollectionUtils.isEmpty(receiptMaterialDetailPOList)) {
log.warn("生成库存台账报表记录失败,收货明细为空,收货单号:{}", latestStockReceiptOrderPO.getReceiptOrderNumber());
return;
}
// 按物料、货主、仓库分组统计收货数量
Map<String, InventoryStandingReportDO> reportMap = new HashMap<>();
log.info("开始生成库存台账报表记录,收货单号:{},收货明细数量:{}",
latestStockReceiptOrderPO.getReceiptOrderNumber(), receiptMaterialDetailPOList.size());
for (ReceiptMaterialDetailPO receiptMaterialDetailPO : receiptMaterialDetailPOList){
// 记录每个明细的详细信息
log.debug("处理收货明细,物料编码:{},物料名称:{},收货数量:{},收货状态:{}",
receiptMaterialDetailPO.getMaterialCode(),
receiptMaterialDetailPO.getMaterialName(),
receiptMaterialDetailPO.getReceiptQuantity(),
receiptMaterialDetailPO.getReceiptStatus());
// 只统计有收货数量的记录
if (receiptMaterialDetailPO.getReceiptQuantity() == null ||
receiptMaterialDetailPO.getReceiptQuantity().compareTo(BigDecimal.ZERO) <= 0) {
log.debug("跳过收货明细(收货数量为空或<=0),物料编码:{},收货数量:{}",
receiptMaterialDetailPO.getMaterialCode(),
receiptMaterialDetailPO.getReceiptQuantity());
continue;
}
// 只统计收货状态为1(待收货)或2(收货中)的记录
// 注意:在receivingGoods调用时,我们从stockReceiptOrderDO中获取数据,状态设置为2
if (receiptMaterialDetailPO.getReceiptStatus() == null ||
receiptMaterialDetailPO.getReceiptStatus() < 1 ||
receiptMaterialDetailPO.getReceiptStatus() > 2) {
log.debug("跳过收货明细(收货状态不符合要求),物料编码:{},收货状态:{}(需要1或2)",
receiptMaterialDetailPO.getMaterialCode(),
receiptMaterialDetailPO.getReceiptStatus());
continue;
}
// 生成唯一key:物料编码_货主ID_仓库ID
String key = receiptMaterialDetailPO.getMaterialCode() + "_"
+ latestStockReceiptOrderPO.getShipperId() + "_"
+ latestStockReceiptOrderPO.getWarehouseId();
InventoryStandingReportDO reportDO = reportMap.get(key);
if (reportDO == null) {
reportDO = new InventoryStandingReportDO();
reportDO.setOrganizationId(latestStockReceiptOrderPO.getOrganizationId());
reportDO.setOrganizationName(latestStockReceiptOrderPO.getOrganizationName());
reportDO.setTopOrganizationId(latestStockReceiptOrderPO.getTopOrganizationId());
reportDO.setMaterialCode(receiptMaterialDetailPO.getMaterialCode());
reportDO.setMaterialName(receiptMaterialDetailPO.getMaterialName());
reportDO.setBarCode(receiptMaterialDetailPO.getBarCode());
reportDO.setShipperId(latestStockReceiptOrderPO.getShipperId());
reportDO.setShipperCode(latestStockReceiptOrderPO.getShipperCode());
reportDO.setShipperName(latestStockReceiptOrderPO.getShipperName());
reportDO.setWarehouseId(latestStockReceiptOrderPO.getWarehouseId());
reportDO.setWarehouseCode(latestStockReceiptOrderPO.getWarehouseCode());
reportDO.setWarehouseName(latestStockReceiptOrderPO.getWarehouseName());
reportDO.setNodeStatus(1); // 1-收货
reportDO.setMaterialQuantity(BigDecimal.ZERO);
reportMap.put(key, reportDO);
}
// 累加收货数量
reportDO.setMaterialQuantity(reportDO.getMaterialQuantity().add(receiptMaterialDetailPO.getReceiptQuantity()));
}
// 批量插入或更新库存台账报表记录
int successCount = 0;
for (InventoryStandingReportDO reportDO : reportMap.values()) {
try {
Boolean result = inventoryStandingReportService.insert(reportDO);
if (result) {
successCount++;
log.info("生成库存台账报表记录成功,收货单号:{},物料编码:{},物料名称:{},数量:{}",
latestStockReceiptOrderPO.getReceiptOrderNumber(),
reportDO.getMaterialCode(),
reportDO.getMaterialName(),
reportDO.getMaterialQuantity());
} else {
log.warn("生成库存台账报表记录失败,返回false,收货单号:{},物料编码:{}",
latestStockReceiptOrderPO.getReceiptOrderNumber(), reportDO.getMaterialCode());
}
} catch (Exception e) {
log.error("生成库存台账报表记录异常,收货单号:{},物料编码:{},物料名称:{}",
latestStockReceiptOrderPO.getReceiptOrderNumber(),
reportDO.getMaterialCode(),
reportDO.getMaterialName(), e);
}
}
log.info("生成库存台账报表记录完成,收货单号:{},成功:{},总计:{}",
latestStockReceiptOrderPO.getReceiptOrderNumber(), successCount, reportMap.size());
} catch (Exception e) {
log.error("生成库存台账报表记录异常,收货单号:{}", stockReceiptOrderPO.getReceiptOrderNumber(), e);
}
}
/**
* @description 收货生成任务下发
* @author ZhouGY
@@ -29,6 +29,7 @@ import com.mhd.wms.domain.inOrderAbnormal.repository.facade.IInOrderAbnormalServ
import com.mhd.wms.domain.inOrderAbnormal.repository.todo.InOrderAbnormalBaseDO;
import com.mhd.wms.domain.inventoryStandingDetail.repository.facade.IInventoryStandingDetailService;
import com.mhd.wms.domain.inventoryStandingDetail.repository.todo.InventoryStandingDetailDO;
import com.mhd.wms.domain.materialBaseInfo.repository.facade.IMaterialBaseInfoService;
import com.mhd.wms.domain.materialInventory.entity.MaterialInventory;
import com.mhd.wms.domain.materialInventory.repository.facade.IMaterialInventoryService;
import com.mhd.wms.domain.materialInventory.repository.todo.MaterialInventoryDO;
@@ -80,6 +81,8 @@ public class StockShelfOrderDomainService {
@Autowired
private IMaterialInventoryService materialInventoryService;
@Autowired
private IMaterialBaseInfoService materialBaseInfoService;
@Autowired
private IInMaterialDetailSerialNumberService inMaterialDetailSerialNumberService;
@Autowired
private IStockInTaskOrderService stockInTaskOrderService;
@@ -372,8 +375,8 @@ public class StockShelfOrderDomainService {
updateStockInOrder(stockShelfOrderPO, 5);
//上架修改物料库存
List<ShelfMaterialDetail> shelfMaterialDetailList = shelfMaterialDetailService.list(new QueryWrapper<ShelfMaterialDetail>().lambda().eq(ShelfMaterialDetail::getShelfOrderNumber, stockShelfOrderPO.getShelfOrderNumber()));
//组装上架修改库存参数
shelfAddMaterialInventory(shelfMaterialDetailList);
//组装上架修改库存参数(传入上架单信息,用于获取货主信息)
shelfAddMaterialInventory(shelfMaterialDetailList, stockShelfOrderPO);
//修改上架对应的序列号的库存信息
updateSerialNumberforInventory(shelfMaterialDetailList);
//生成上架追溯记录
@@ -408,18 +411,94 @@ public class StockShelfOrderDomainService {
* @author ZhouGY
* @date 2024/6/19 10:07
* @param shelfMaterialDetailList
* @param stockShelfOrderPO 上架单信息,用于获取货主信息
* @return Boolean
*/
public void shelfAddMaterialInventory(List<ShelfMaterialDetail> shelfMaterialDetailList){
public void shelfAddMaterialInventory(List<ShelfMaterialDetail> shelfMaterialDetailList, StockShelfOrderPO stockShelfOrderPO){
// 根据入库单号获取入库单信息,以获取货主信息
Long shipperId = null;
String shipperCode = null;
String shipperName = null;
if (stockShelfOrderPO != null && StringUtils.isNotBlank(stockShelfOrderPO.getInOrderNumber())) {
try {
// 根据入库单号查询入库单
com.mhd.wms.domain.stockInOrder.repository.todo.StockInOrderDO stockInOrderDO = new com.mhd.wms.domain.stockInOrder.repository.todo.StockInOrderDO();
stockInOrderDO.setInOrderNumber(stockShelfOrderPO.getInOrderNumber());
List<com.mhd.wms.domain.stockInOrder.repository.po.StockInOrderPO> stockInOrderList = stockInOrderService.queryList(stockInOrderDO);
if (!CollectionUtils.isEmpty(stockInOrderList)) {
com.mhd.wms.domain.stockInOrder.repository.po.StockInOrderPO stockInOrderPO = stockInOrderList.get(0);
shipperId = stockInOrderPO.getShipperId();
shipperCode = stockInOrderPO.getShipperCode();
shipperName = stockInOrderPO.getShipperName();
}
} catch (Exception e) {
log.warn("根据入库单号获取货主信息失败,入库单号:{},错误:{}", stockShelfOrderPO.getInOrderNumber(), e.getMessage());
}
}
// 如果从入库单获取不到货主信息,尝试从物料基础信息获取
if (shipperId == null && !CollectionUtils.isEmpty(shelfMaterialDetailList)) {
ShelfMaterialDetail firstDetail = shelfMaterialDetailList.get(0);
if (firstDetail.getMaterialBaseInfoId() != null) {
try {
com.mhd.wms.domain.materialBaseInfo.repository.todo.MaterialBaseInfoDO materialBaseInfoDO = new com.mhd.wms.domain.materialBaseInfo.repository.todo.MaterialBaseInfoDO();
materialBaseInfoDO.setMaterialBaseInfoId(firstDetail.getMaterialBaseInfoId());
List<com.mhd.wms.domain.materialBaseInfo.repository.po.MaterialBaseInfoPO> materialBaseInfoList = materialBaseInfoService.queryList(materialBaseInfoDO);
if (!CollectionUtils.isEmpty(materialBaseInfoList)) {
com.mhd.wms.domain.materialBaseInfo.repository.po.MaterialBaseInfoPO materialBaseInfoPO = materialBaseInfoList.get(0);
shipperId = materialBaseInfoPO.getShipperId();
shipperCode = materialBaseInfoPO.getShipperCode();
shipperName = materialBaseInfoPO.getShipperName();
}
} catch (Exception e) {
log.warn("根据物料基础信息获取货主信息失败,物料基础信息ID:{},错误:{}", firstDetail.getMaterialBaseInfoId(), e.getMessage());
}
}
}
if (shipperId == null) {
log.warn("上架时无法获取货主信息,上架单号:{},入库单号:{},将跳过货主信息设置",
stockShelfOrderPO != null ? stockShelfOrderPO.getShelfOrderNumber() : null,
stockShelfOrderPO != null ? stockShelfOrderPO.getInOrderNumber() : null);
}
List<MaterialInventoryDO> materialInventoryDOList = new ArrayList<>();
for (ShelfMaterialDetail shelfMaterialDetail : shelfMaterialDetailList){
// 使用shelvesQuantity(本次上架数量)来增加库存
// 如果shelvesQuantity为空,则使用alreadyShelvesQuantity(累计上架数量)作为备选
BigDecimal shelvesQuantity = shelfMaterialDetail.getShelvesQuantity() != null
? shelfMaterialDetail.getShelvesQuantity()
: (shelfMaterialDetail.getAlreadyShelvesQuantity() != null
? shelfMaterialDetail.getAlreadyShelvesQuantity()
: BigDecimal.ZERO);
// 如果数量为0或空,跳过该记录
if (shelvesQuantity.compareTo(BigDecimal.ZERO) <= 0) {
continue;
}
MaterialInventoryDO materialInventoryDO = new MaterialInventoryDO();
BeanUtils.copyProperties(shelfMaterialDetail, materialInventoryDO);
materialInventoryDO.setInventoryQuantity(shelfMaterialDetail.getShelvesQuantity());
materialInventoryDO.setAllocationQuantity(shelfMaterialDetail.getShelvesQuantity());
materialInventoryDO.setInventoryQuantity(shelvesQuantity);
materialInventoryDO.setAllocationQuantity(shelvesQuantity);
// 设置货主信息(从入库单或物料基础信息获取)
if (shipperId != null) {
materialInventoryDO.setShipperId(shipperId);
if (StringUtils.isNotBlank(shipperCode)) {
materialInventoryDO.setShipperCode(shipperCode);
}
if (StringUtils.isNotBlank(shipperName)) {
materialInventoryDO.setShipperName(shipperName);
}
}
materialInventoryDOList.add(materialInventoryDO);
}
materialInventoryService.updateMaterialInventoryInfo(materialInventoryDOList, 1);
if (!CollectionUtils.isEmpty(materialInventoryDOList)) {
materialInventoryService.updateMaterialInventoryInfo(materialInventoryDOList, 1);
}
}
public void updateSerialNumberforInventory(List<ShelfMaterialDetail> shelfMaterialDetailList){