出库管理手动分配调整

This commit is contained in:
秦鸿展
2026-02-03 17:50:20 +08:00
parent db313639db
commit d436601507
3 changed files with 71 additions and 58 deletions
@@ -23,6 +23,7 @@ import com.mhd.system.api.domain.WarehouseFeignPO;
import com.mhd.system.api.domain.cache.AssociationWarehouseCacheDO;
import com.mhd.system.api.domain.cache.SystemServiceCacheUtil;
import com.mhd.system.api.model.LoginUser;
import com.mhd.wms.domain.materialInventory.repository.mapper.MaterialInventoryMapper;
import com.mhd.wms.domain.materialInventory.repository.po.MaterialInventoryPO;
import com.mhd.wms.domain.materialInventory.service.MaterialInventoryDomainService;
import com.mhd.wms.domain.materialMoreDetail.repository.po.MaterialMoreDetailPO;
@@ -61,6 +62,8 @@ public class StockOutOrderApplicationService {
@Autowired
private MaterialInventoryDomainService materialInventoryDomainService;
@Autowired
private MaterialInventoryMapper materialInventoryMapper;
@Autowired
private UserServiceFeign userServiceFeign;
@Autowired
private SystemServiceFeign systemServiceFeign;
@@ -173,7 +176,9 @@ public class StockOutOrderApplicationService {
}
/**
* 递归为出库物料明细设置更多属性(从物料明细表中获取值)
* 递归为出库物料明细设置更多属性
* 如果已分配库存(materialInventoryId不为空),则从库存表中获取批次属性值
* 否则从物料明细表中获取值
* @param outMaterialDetailPOList 出库物料明细列表
* @param batchDetailMap 批次属性Map
*/
@@ -185,6 +190,7 @@ public class StockOutOrderApplicationService {
outMaterialDetailPOList.forEach(outMaterialDetailPO -> {
Long materialBaseInfoId = outMaterialDetailPO.getMaterialBaseInfoId();
Long materialInventoryId = outMaterialDetailPO.getMaterialInventoryId();
// 只保留isDisplay=1的批次属性(从batchDetailMap中获取,已经过滤过了)
// 创建新的materialMoreDetailList,只包含isDisplay=1的属性
@@ -201,6 +207,17 @@ public class StockOutOrderApplicationService {
}
}
// 如果已分配库存,从库存表中获取批次属性值
MaterialInventoryPO inventoryPO = null;
if (materialInventoryId != null && materialInventoryId > 0) {
try {
inventoryPO = materialInventoryMapper.selectByIdWithBatchAttributes(materialInventoryId);
log.info("从库存表获取批次属性,materialInventoryId={}", materialInventoryId);
} catch (Exception e) {
log.warn("从库存表获取批次属性失败,materialInventoryId={},错误:{}", materialInventoryId, e.getMessage());
}
}
if (materialBaseInfoId != null && batchDetailMap.containsKey(materialBaseInfoId)) {
List<BatchDetailFeignPO> batchDetailFeignPOList = batchDetailMap.get(materialBaseInfoId);
// 用于跟踪已添加到列表中的batchDetailId
@@ -236,15 +253,39 @@ public class StockOutOrderApplicationService {
addedBatchDetailIds.add(batchDetailId);
}
// 根据fieldName或batchLabels从物料明细中获取对应的字段值
if (outMaterialDetailPO != null) {
String fieldValue = null;
String usedFieldName = null;
// 根据fieldName或batchLabels获取对应的字段值
String fieldValue = null;
String usedFieldName = null;
// 优先从库存表获取值(如果已分配库存)
if (inventoryPO != null) {
// 优先使用fieldName(如果存在)
if (StringUtils.isNotBlank(batchDetailFeignPO.getFieldName())) {
usedFieldName = batchDetailFeignPO.getFieldName();
fieldValue = getFieldValueByFieldName(inventoryPO, usedFieldName);
log.info("批次属性 batchDetailId={}, fieldName={}, 从库存表获取到的值={}",
batchDetailFeignPO.getBatchDetailId(), usedFieldName, fieldValue);
}
// 如果fieldName为空,尝试根据batchLabels映射到字段名
else if (StringUtils.isNotBlank(batchDetailFeignPO.getBatchLabels())) {
String fieldNameByLabel = getFieldNameByBatchLabel(batchDetailFeignPO.getBatchLabels());
if (StringUtils.isNotBlank(fieldNameByLabel)) {
usedFieldName = fieldNameByLabel;
fieldValue = getFieldValueByFieldName(inventoryPO, usedFieldName);
log.info("批次属性 batchDetailId={}, batchLabels={}, 映射字段名={}, 从库存表获取到的值={}",
batchDetailFeignPO.getBatchDetailId(), batchDetailFeignPO.getBatchLabels(),
usedFieldName, fieldValue);
}
}
}
// 如果从库存表没有获取到值,且未分配库存,则从物料明细表中获取值
if (fieldValue == null && inventoryPO == null && outMaterialDetailPO != null) {
// 优先使用fieldName(如果存在)
if (StringUtils.isNotBlank(batchDetailFeignPO.getFieldName())) {
usedFieldName = batchDetailFeignPO.getFieldName();
fieldValue = getFieldValueByFieldName(outMaterialDetailPO, usedFieldName);
log.info("批次属性 batchDetailId={}, fieldName={}, 获取到的值={}",
log.info("批次属性 batchDetailId={}, fieldName={}, 从物料明细表获取到的值={}",
batchDetailFeignPO.getBatchDetailId(), usedFieldName, fieldValue);
}
// 如果fieldName为空,尝试根据batchLabels映射到字段名
@@ -253,24 +294,26 @@ public class StockOutOrderApplicationService {
if (StringUtils.isNotBlank(fieldNameByLabel)) {
usedFieldName = fieldNameByLabel;
fieldValue = getFieldValueByFieldName(outMaterialDetailPO, usedFieldName);
log.info("批次属性 batchDetailId={}, batchLabels={}, 映射字段名={}, 获取到的值={}",
log.info("批次属性 batchDetailId={}, batchLabels={}, 映射字段名={}, 从物料明细表获取到的值={}",
batchDetailFeignPO.getBatchDetailId(), batchDetailFeignPO.getBatchLabels(),
usedFieldName, fieldValue);
}
}
// 只有当获取到值时才更新attributeValue(避免覆盖已有的值)
if (fieldValue != null) {
materialMoreDetailPO.setAttributeValue(fieldValue);
log.info("设置更多属性:batchDetailId={}, batchLabels={}, attributeValue={}",
materialMoreDetailPO.getBatchDetailId(), materialMoreDetailPO.getBatchLabels(),
materialMoreDetailPO.getAttributeValue());
}
}
// 只有当获取到值时才更新attributeValue(避免覆盖已有的值)
if (fieldValue != null) {
materialMoreDetailPO.setAttributeValue(fieldValue);
log.info("设置更多属性:batchDetailId={}, batchLabels={}, attributeValue={}",
materialMoreDetailPO.getBatchDetailId(), materialMoreDetailPO.getBatchLabels(),
materialMoreDetailPO.getAttributeValue());
}
}
}
outMaterialDetailPO.setMaterialMoreDetailList(materialMoreDetailList);
log.info("出库物料明细 uniqueId={}, materialBaseInfoId={}, materialMoreDetailList大小={}",
log.info("出库物料明细 uniqueId={}, materialBaseInfoId={}, materialInventoryId={}, materialMoreDetailList大小={}",
outMaterialDetailPO.getUniqueId(), outMaterialDetailPO.getMaterialBaseInfoId(),
outMaterialDetailPO.getMaterialInventoryId(),
materialMoreDetailList != null ? materialMoreDetailList.size() : 0);
// 递归处理子集
@@ -168,4 +168,16 @@ public class MaterialInventoryQueryListDTO extends MaterialBaseDTO {
@ApiModelProperty("物料/库位信息")
@Excel(name = "物料/库位信息")
private String storageInfo;
@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;
}
@@ -24,7 +24,6 @@ import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
@@ -165,48 +164,7 @@ public class StockOutOrderApi extends BaseController {
return toAjax(stockOutOrderApplicationService.cancelAssign(stockOutOrderDO));
}
/**
* 手动取消分配(点击确认后直接取消分配)
* 前端点击取消分配按钮时弹出确认对话框,点击确认后调用此接口
* 只需要传递出库单ID和物料明细ID,会自动取消该明细的所有已分配数量
*/
@ApiOperation("手动取消分配")
@PostMapping("/manualCancelAssign")
public AjaxResult manualCancelAssign(@RequestBody StockOutOrderDTO stockOutOrderDTO) {
// 检查参数
if (stockOutOrderDTO.getOutOrderId() == null) {
return error("出库单ID不能为空");
}
if (stockOutOrderDTO.getMaterialDetailList() == null || stockOutOrderDTO.getMaterialDetailList().isEmpty()) {
return error("物料明细不能为空,请选择要取消分配的物料明细");
}
StockOutOrderDO stockOutOrderDO = new StockOutOrderDO();
BeanUtils.copyProperties(stockOutOrderDTO, stockOutOrderDO);
// 转换物料明细列表,手动转换确保materialDetailId字段正确传递
List<OutMaterialDetailDO> materialDetailList = new ArrayList<>();
for (OutMaterialDetailDTO detailDTO : stockOutOrderDTO.getMaterialDetailList()) {
OutMaterialDetailDO detailDO = new OutMaterialDetailDO();
// 只复制必要的字段,确保materialDetailId被正确传递
detailDO.setMaterialDetailId(detailDTO.getMaterialDetailId());
detailDO.setUniqueId(detailDTO.getUniqueId());
detailDO.setAllocationQuantity(detailDTO.getAllocationQuantity());
// 如果有子明细,也转换
if (detailDTO.getMaterialDetailList() != null && !detailDTO.getMaterialDetailList().isEmpty()) {
List<OutMaterialDetailDO> children = new ArrayList<>();
for (OutMaterialDetailDTO childDTO : detailDTO.getMaterialDetailList()) {
OutMaterialDetailDO childDO = new OutMaterialDetailDO();
childDO.setMaterialDetailId(childDTO.getMaterialDetailId());
childDO.setAllocationQuantity(childDTO.getAllocationQuantity());
children.add(childDO);
}
detailDO.setChildren(children);
}
materialDetailList.add(detailDO);
}
stockOutOrderDO.setMaterialDetailList(materialDetailList);
return toAjax(stockOutOrderApplicationService.manualCancelAssign(stockOutOrderDO));
}
/**
* 生成拣货单