PDA收货修改批次属性
This commit is contained in:
+232
-28
@@ -259,19 +259,16 @@ public class StockReceiptOrderApplicationService {
|
|||||||
BigDecimal totalArea = BigDecimal.ZERO;
|
BigDecimal totalArea = BigDecimal.ZERO;
|
||||||
if (!CollectionUtils.isEmpty(receiptMaterialDetailPOList)) {
|
if (!CollectionUtils.isEmpty(receiptMaterialDetailPOList)) {
|
||||||
for (ReceiptMaterialDetailPO detail : receiptMaterialDetailPOList) {
|
for (ReceiptMaterialDetailPO detail : receiptMaterialDetailPOList) {
|
||||||
if (detail.getLevel() == null || detail.getLevel() == 1) {
|
|
||||||
totalNetWeight = totalNetWeight.add(sumDetailRecursively(detail, ReceiptMaterialDetailPO::getTotalNetWeight));
|
totalNetWeight = totalNetWeight.add(sumDetailRecursively(detail, ReceiptMaterialDetailPO::getTotalNetWeight));
|
||||||
totalGrossWeight = totalGrossWeight.add(sumDetailRecursively(detail, ReceiptMaterialDetailPO::getTotalGrossWeight));
|
totalGrossWeight = totalGrossWeight.add(sumDetailRecursively(detail, ReceiptMaterialDetailPO::getTotalGrossWeight));
|
||||||
totalVolume = totalVolume.add(sumDetailRecursively(detail, ReceiptMaterialDetailPO::getTotalVolume));
|
totalVolume = totalVolume.add(sumDetailRecursively(detail, ReceiptMaterialDetailPO::getTotalVolume));
|
||||||
totalArea = totalArea.add(sumDetailRecursively(detail, ReceiptMaterialDetailPO::getTotalArea));
|
totalArea = totalArea.add(sumDetailRecursively(detail, ReceiptMaterialDetailPO::getTotalArea));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
stockReceiptOrderPO.setTotalNetWeight(totalNetWeight);
|
stockReceiptOrderPO.setTotalNetWeight(totalNetWeight);
|
||||||
stockReceiptOrderPO.setTotalGrossWeight(totalGrossWeight);
|
stockReceiptOrderPO.setTotalGrossWeight(totalGrossWeight);
|
||||||
stockReceiptOrderPO.setTotalVolume(totalVolume);
|
stockReceiptOrderPO.setTotalVolume(totalVolume);
|
||||||
stockReceiptOrderPO.setTotalArea(totalArea);
|
stockReceiptOrderPO.setTotalArea(totalArea);
|
||||||
|
|
||||||
stockReceiptOrderPO.setMaterialDetailList(receiptMaterialDetailPOList);
|
stockReceiptOrderPO.setMaterialDetailList(receiptMaterialDetailPOList);
|
||||||
log.info("返回收货单信息,receiptOrderId={}, materialDetailList大小={}, totalNetWeight={}, totalGrossWeight={}, totalVolume={}, totalArea={}",
|
log.info("返回收货单信息,receiptOrderId={}, materialDetailList大小={}, totalNetWeight={}, totalGrossWeight={}, totalVolume={}, totalArea={}",
|
||||||
stockReceiptOrderPO.getReceiptOrderId(),
|
stockReceiptOrderPO.getReceiptOrderId(),
|
||||||
@@ -806,11 +803,68 @@ public class StockReceiptOrderApplicationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取收货单详细信息
|
* 获取收货单详细信息(PDA 端)
|
||||||
|
* 在 Domain 层结果基础上,补充包装规格填充,与 PC 端 getInfo 一致
|
||||||
*/
|
*/
|
||||||
public StockReceiptOrderPO getInfoByApp(Long receiptOrderId)
|
public StockReceiptOrderPO getInfoByApp(Long receiptOrderId)
|
||||||
{
|
{
|
||||||
return stockReceiptOrderDomainService.getInfoByApp(receiptOrderId);
|
StockReceiptOrderPO stockReceiptOrderPO = stockReceiptOrderDomainService.getInfoByApp(receiptOrderId);
|
||||||
|
List<ReceiptMaterialDetailPO> materialDetailList = stockReceiptOrderPO.getMaterialDetailList();
|
||||||
|
if (!CollectionUtils.isEmpty(materialDetailList)) {
|
||||||
|
Set<Long> materialBaseInfoIdSet = new HashSet<>();
|
||||||
|
collectMaterialBaseInfoIdsRecursively(materialDetailList, materialBaseInfoIdSet);
|
||||||
|
Map<Long, MaterialBaseInfoPO> materialBaseInfoMap = new HashMap<>();
|
||||||
|
for (Long materialBaseInfoId : materialBaseInfoIdSet) {
|
||||||
|
try {
|
||||||
|
MaterialBaseInfoPO materialBaseInfoPO = materialBaseInfoService.getInfo(materialBaseInfoId);
|
||||||
|
if (materialBaseInfoPO != null) {
|
||||||
|
materialBaseInfoMap.put(materialBaseInfoId, materialBaseInfoPO);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("获取物料基础信息失败,物料基础信息ID:{},错误:{}", materialBaseInfoId, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Map<Long, PackDetailFeignPO> packDetailMap = new HashMap<>();
|
||||||
|
for (Long materialBaseInfoId : materialBaseInfoIdSet) {
|
||||||
|
MaterialBaseInfoPO materialBaseInfoPO = materialBaseInfoMap.get(materialBaseInfoId);
|
||||||
|
if (materialBaseInfoPO != null && materialBaseInfoPO.getPackId() != null) {
|
||||||
|
try {
|
||||||
|
AjaxResult packDetailResult = systemServiceFeign.getInfoByPackIdAndUnitCode(materialBaseInfoPO.getPackId(), "EA");
|
||||||
|
if (packDetailResult != null && "200".equals(String.valueOf(packDetailResult.get("code")))
|
||||||
|
&& packDetailResult.get("data") != null) {
|
||||||
|
PackDetailFeignPO packDetailFeignPO = JSON.parseObject(
|
||||||
|
JSONObject.toJSONString(packDetailResult.get("data")),
|
||||||
|
PackDetailFeignPO.class);
|
||||||
|
if (packDetailFeignPO != null) {
|
||||||
|
packDetailMap.put(materialBaseInfoId, packDetailFeignPO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("获取包装规格EA单位信息失败,物料基础信息ID:{},包装ID:{},错误:{}",
|
||||||
|
materialBaseInfoId, materialBaseInfoPO.getPackId(), e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fillMaterialDetailUnitInfoRecursively(materialDetailList, materialBaseInfoMap, packDetailMap);
|
||||||
|
}
|
||||||
|
return stockReceiptOrderPO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 递归收集明细树中所有物料基础信息ID
|
||||||
|
*/
|
||||||
|
private void collectMaterialBaseInfoIdsRecursively(List<ReceiptMaterialDetailPO> list, Set<Long> set) {
|
||||||
|
if (CollectionUtils.isEmpty(list)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (ReceiptMaterialDetailPO po : list) {
|
||||||
|
if (po.getMaterialBaseInfoId() != null) {
|
||||||
|
set.add(po.getMaterialBaseInfoId());
|
||||||
|
}
|
||||||
|
if (!CollectionUtils.isEmpty(po.getChildren())) {
|
||||||
|
collectMaterialBaseInfoIdsRecursively(po.getChildren(), set);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -887,14 +941,100 @@ public class StockReceiptOrderApplicationService {
|
|||||||
* @return Boolean
|
* @return Boolean
|
||||||
*/
|
*/
|
||||||
public Boolean receivingGoodsByApp(StockReceiptOrderDO stockReceiptOrderDO){
|
public Boolean receivingGoodsByApp(StockReceiptOrderDO stockReceiptOrderDO){
|
||||||
// PDA 收货回传时,将第一项作为主项,其余作为其子项
|
List<ReceiptMaterialDetailDO> list = stockReceiptOrderDO.getMaterialDetailList();
|
||||||
|
// 记录 PDA 传入时第一项是否已有 children
|
||||||
|
boolean firstItemHadChildrenBefore = !CollectionUtils.isEmpty(list)
|
||||||
|
&& !CollectionUtils.isEmpty(list.get(0).getChildren());
|
||||||
|
// PDA 可能以平铺 [主项, 子项] 回传,此时主项无 children,需先转换为父子结构,否则主项 ALREADY_RECEIPT_QUANTITY 无法累加子项数量
|
||||||
|
if (!CollectionUtils.isEmpty(list) && list.size() > 1) {
|
||||||
ensureFirstItemAsParent(stockReceiptOrderDO);
|
ensureFirstItemAsParent(stockReceiptOrderDO);
|
||||||
|
}
|
||||||
|
if (firstItemHadChildrenBefore) {
|
||||||
|
// 主项子项结构:将 children 第一条(parent_copy)赋值给主项并删除
|
||||||
|
assignFirstChildToParentAndRemove(stockReceiptOrderDO);
|
||||||
|
}
|
||||||
StockReceiptOrderDO assembleStockReceiptOrderDO = assembleParamByReceipt(stockReceiptOrderDO);
|
StockReceiptOrderDO assembleStockReceiptOrderDO = assembleParamByReceipt(stockReceiptOrderDO);
|
||||||
|
if (CollectionUtils.isEmpty(assembleStockReceiptOrderDO.getMaterialDetailList())) {
|
||||||
|
throw new ServiceException("无有效收货数据,请确认已填写收货数量(收货数量不能全部为0)");
|
||||||
|
}
|
||||||
return stockReceiptOrderDomainService.receivingGoods(assembleStockReceiptOrderDO);
|
return stockReceiptOrderDomainService.receivingGoods(assembleStockReceiptOrderDO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 收货时:将 children 中第一条(parent_copy)的值赋给主项(1),并删除第一条;不合并数量,仅赋值替换。
|
||||||
|
* getInfoByApp 有子项时会将 parent_copy 作为 children 第一条,PDA 可能不传 materialDetailId/uniqueId,
|
||||||
|
* 故用 materialDetailId、uniqueId、materialBaseInfoId 综合判断,避免误合并真实子项导致第一条被覆盖。
|
||||||
|
*/
|
||||||
|
private void assignFirstChildToParentAndRemove(StockReceiptOrderDO stockReceiptOrderDO) {
|
||||||
|
List<ReceiptMaterialDetailDO> list = stockReceiptOrderDO.getMaterialDetailList();
|
||||||
|
if (CollectionUtils.isEmpty(list)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (ReceiptMaterialDetailDO parent : list) {
|
||||||
|
List<ReceiptMaterialDetailDO> children = parent.getChildren();
|
||||||
|
if (CollectionUtils.isEmpty(children)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ReceiptMaterialDetailDO firstChild = children.get(0);
|
||||||
|
if (!isParentCopy(parent, firstChild)) {
|
||||||
|
// 第一条是真实子项,不合并,保留主项和子项各自独立
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 将 parent_copy 的值赋给主项(赋值替换,不合并数量)
|
||||||
|
BeanUtils.copyProperties(firstChild, parent, "children", "parentUniqueId", "uniqueId", "materialDetailId",
|
||||||
|
"organizationIdList", "permissionMenuId", "receiptOrderNumberList", "compoundOrQuery");
|
||||||
|
// 删除 children 中的第一条(parent_copy)
|
||||||
|
List<ReceiptMaterialDetailDO> newChildren = new ArrayList<>();
|
||||||
|
for (int i = 1; i < children.size(); i++) {
|
||||||
|
newChildren.add(children.get(i));
|
||||||
|
}
|
||||||
|
parent.setChildren(newChildren);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断第一条子项是否为 parent_copy(主项拷贝,供 PDA 收货编辑用)。
|
||||||
|
* parent_copy 与主项同 materialDetailId/uniqueId/materialBaseInfoId;真实子项则不同。
|
||||||
|
* PDA 可能不传 materialDetailId/uniqueId/materialBaseInfoId,需综合判断。
|
||||||
|
*/
|
||||||
|
private boolean isParentCopy(ReceiptMaterialDetailDO parent, ReceiptMaterialDetailDO firstChild) {
|
||||||
|
Long parentId = parent.getMaterialDetailId();
|
||||||
|
Long firstChildId = firstChild.getMaterialDetailId();
|
||||||
|
Long parentUniqueId = parent.getUniqueId();
|
||||||
|
Long firstChildUniqueId = firstChild.getUniqueId();
|
||||||
|
Long parentBaseInfoId = parent.getMaterialBaseInfoId();
|
||||||
|
Long firstChildBaseInfoId = firstChild.getMaterialBaseInfoId();
|
||||||
|
// 1. materialDetailId 相同 → parent_copy
|
||||||
|
if (parentId != null && parentId.equals(firstChildId)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// 2. uniqueId 相同 → parent_copy
|
||||||
|
if (parentUniqueId != null && parentUniqueId.equals(firstChildUniqueId)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// 3. 子项有与主项不同的 materialDetailId → 真实子项
|
||||||
|
if (firstChildId != null && !firstChildId.equals(parentId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 4. 子项有与主项不同的 uniqueId → 真实子项
|
||||||
|
if (firstChildUniqueId != null && !firstChildUniqueId.equals(parentUniqueId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 5. 子项 materialBaseInfoId 与主项不同 → 真实子项(不同物料)
|
||||||
|
if (firstChildBaseInfoId != null && parentBaseInfoId != null && !firstChildBaseInfoId.equals(parentBaseInfoId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 6. PDA 未传 materialDetailId/uniqueId 时:getInfoByApp 的 parent_copy 总是 children 第一条,
|
||||||
|
// 真实子项通常会有 materialDetailId,故无 id 时视为 parent_copy 并合并
|
||||||
|
if (firstChildId == null && firstChildUniqueId == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PDA 收货回传时,将 materialDetailList 的第一项作为主项(level 1),其余项作为其子项(level 2)
|
* PDA 收货回传时,将 materialDetailList 的第一项作为主项(level 1),其余项作为其子项(level 2)
|
||||||
|
* 仅当数据库中第二项为 level 2(真实子项)时才转换,避免将两条平铺明细错误转为父子导致第一条被覆盖
|
||||||
*/
|
*/
|
||||||
private void ensureFirstItemAsParent(StockReceiptOrderDO stockReceiptOrderDO) {
|
private void ensureFirstItemAsParent(StockReceiptOrderDO stockReceiptOrderDO) {
|
||||||
List<ReceiptMaterialDetailDO> list = stockReceiptOrderDO.getMaterialDetailList();
|
List<ReceiptMaterialDetailDO> list = stockReceiptOrderDO.getMaterialDetailList();
|
||||||
@@ -919,6 +1059,14 @@ public class StockReceiptOrderApplicationService {
|
|||||||
if (firstPO == null || firstPO.getUniqueId() == null) {
|
if (firstPO == null || firstPO.getUniqueId() == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// 若第二项在数据库中也是 level 1,说明是平铺兄弟关系,不应转为父子,避免第一条被覆盖
|
||||||
|
ReceiptMaterialDetailDO second = list.get(1);
|
||||||
|
if (second != null && second.getMaterialDetailId() != null) {
|
||||||
|
ReceiptMaterialDetailPO secondPO = dbMap.get(second.getMaterialDetailId());
|
||||||
|
if (secondPO != null && secondPO.getLevel() != null && secondPO.getLevel() == 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
Long parentUniqueId = firstPO.getUniqueId();
|
Long parentUniqueId = firstPO.getUniqueId();
|
||||||
List<ReceiptMaterialDetailDO> children = new ArrayList<>();
|
List<ReceiptMaterialDetailDO> children = new ArrayList<>();
|
||||||
for (int i = 1; i < list.size(); i++) {
|
for (int i = 1; i < list.size(); i++) {
|
||||||
@@ -1087,15 +1235,29 @@ public class StockReceiptOrderApplicationService {
|
|||||||
receiptMaterialDetailDOByQuery.setReceiptOrderNumber(stockReceiptOrderPO.getReceiptOrderNumber());
|
receiptMaterialDetailDOByQuery.setReceiptOrderNumber(stockReceiptOrderPO.getReceiptOrderNumber());
|
||||||
List<ReceiptMaterialDetailPO> receiptMaterialDetailPODbList = receiptMaterialDetailDomainService.queryList(receiptMaterialDetailDOByQuery);
|
List<ReceiptMaterialDetailPO> receiptMaterialDetailPODbList = receiptMaterialDetailDomainService.queryList(receiptMaterialDetailDOByQuery);
|
||||||
Map<Long, ReceiptMaterialDetailPO> receiptMaterialDetailDbMap = receiptMaterialDetailPODbList.stream().collect(Collectors.toMap(ReceiptMaterialDetailPO::getMaterialDetailId, Function.identity()));
|
Map<Long, ReceiptMaterialDetailPO> receiptMaterialDetailDbMap = receiptMaterialDetailPODbList.stream().collect(Collectors.toMap(ReceiptMaterialDetailPO::getMaterialDetailId, Function.identity()));
|
||||||
|
Map<Long, ReceiptMaterialDetailPO> receiptMaterialDetailDbMapByUniqueId = receiptMaterialDetailPODbList.stream()
|
||||||
|
.filter(po -> po.getUniqueId() != null)
|
||||||
|
.collect(Collectors.toMap(ReceiptMaterialDetailPO::getUniqueId, Function.identity()));
|
||||||
BigDecimal totalActualQuantity = BigDecimal.ZERO;//收货单当前作业收货数
|
BigDecimal totalActualQuantity = BigDecimal.ZERO;//收货单当前作业收货数
|
||||||
int totalActualReceiptMaterialQuantity = 0;//收货单收货物料种数
|
int totalActualReceiptMaterialQuantity = 0;//收货单收货物料种数
|
||||||
List<ReceiptMaterialDetailDO> returnReceiptMaterialDetailDOList = new ArrayList<>();
|
List<ReceiptMaterialDetailDO> returnReceiptMaterialDetailDOList = new ArrayList<>();
|
||||||
for (ReceiptMaterialDetailDO receiptMaterialDetailDO : stockReceiptOrderDO.getMaterialDetailList()){
|
for (ReceiptMaterialDetailDO receiptMaterialDetailDO : stockReceiptOrderDO.getMaterialDetailList()){
|
||||||
//设置物料更多属性信息
|
//设置物料更多属性信息:优先用 materialDetailId 查找,若为空则用 uniqueId 查找(兼容 PDA 只传 uniqueId 的场景)
|
||||||
ReceiptMaterialDetailPO receiptMaterialDetailPO = receiptMaterialDetailDbMap.get(receiptMaterialDetailDO.getMaterialDetailId());
|
ReceiptMaterialDetailPO receiptMaterialDetailPO = receiptMaterialDetailDbMap.get(receiptMaterialDetailDO.getMaterialDetailId());
|
||||||
|
if (receiptMaterialDetailPO == null && receiptMaterialDetailDO.getUniqueId() != null) {
|
||||||
|
receiptMaterialDetailPO = receiptMaterialDetailDbMapByUniqueId.get(receiptMaterialDetailDO.getUniqueId());
|
||||||
|
if (receiptMaterialDetailPO != null) {
|
||||||
|
receiptMaterialDetailDO.setMaterialDetailId(receiptMaterialDetailPO.getMaterialDetailId());
|
||||||
|
}
|
||||||
|
}
|
||||||
if (receiptMaterialDetailPO == null){
|
if (receiptMaterialDetailPO == null){
|
||||||
throw new ServiceException("物料明细不存在");
|
throw new ServiceException("物料明细不存在");
|
||||||
}
|
}
|
||||||
|
// receiptQuantity 空值保护,PDA 未传时按 0 处理
|
||||||
|
BigDecimal receiptQuantity = receiptMaterialDetailDO.getReceiptQuantity();
|
||||||
|
if (receiptQuantity == null) {
|
||||||
|
receiptQuantity = BigDecimal.ZERO;
|
||||||
|
}
|
||||||
List<ReceiptMaterialDetailDO> children = receiptMaterialDetailDO.getChildren();
|
List<ReceiptMaterialDetailDO> children = receiptMaterialDetailDO.getChildren();
|
||||||
BigDecimal childrenTotalQuantity = BigDecimal.ZERO;
|
BigDecimal childrenTotalQuantity = BigDecimal.ZERO;
|
||||||
if (!CollectionUtils.isEmpty(children)) {
|
if (!CollectionUtils.isEmpty(children)) {
|
||||||
@@ -1104,43 +1266,70 @@ public class StockReceiptOrderApplicationService {
|
|||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||||
}
|
}
|
||||||
if (receiptMaterialDetailDO.getReceiptQuantity().compareTo(BigDecimal.ZERO) == 0 && childrenTotalQuantity.compareTo(BigDecimal.ZERO) == 0){
|
// 主项和子项收货数量均为 0 时仍保留该明细参与流程,避免多条平铺明细被“丢失”(batchReceiptUpdate、syncUpdateInMaterialDetail 等需感知全部明细)
|
||||||
//未进行收货直接跳过
|
boolean hasReceipt = receiptQuantity.compareTo(BigDecimal.ZERO) > 0 || childrenTotalQuantity.compareTo(BigDecimal.ZERO) > 0;
|
||||||
continue;
|
BigDecimal mainItemActualQuantity = BigDecimal.ZERO;//主项自身当前作业收货数(不包含子项)
|
||||||
}
|
BigDecimal orderLevelQuantity = BigDecimal.ZERO;//主项+子项合计,用于收货单级汇总
|
||||||
BigDecimal actualQuantity = BigDecimal.ZERO;//当前作业收货数
|
List<ReceiptMaterialDetailDO> returnReceiptMaterialDetailDOChildList = new ArrayList<>();
|
||||||
|
if (hasReceipt) {
|
||||||
//判断收否收货 第一次收货创建 更多属性 序列号
|
//判断收否收货 第一次收货创建 更多属性 序列号
|
||||||
if (receiptMaterialDetailPO.getReceiptQuantity().compareTo(BigDecimal.ZERO) == 0){
|
if (receiptMaterialDetailPO.getReceiptQuantity().compareTo(BigDecimal.ZERO) == 0){
|
||||||
//收货后 设置该记录不允许被修改
|
//收货后 设置该记录不允许被修改
|
||||||
receiptMaterialDetailDO.setAllowModify(2);
|
receiptMaterialDetailDO.setAllowModify(2);
|
||||||
//未收过货 统计到当前收货单作业收货数
|
|
||||||
actualQuantity = receiptMaterialDetailDO.getReceiptQuantity();
|
|
||||||
//设置物料状态及容器信息
|
//设置物料状态及容器信息
|
||||||
setMaterialMoreDetailInfo(receiptMaterialDetailDO);
|
setMaterialMoreDetailInfo(receiptMaterialDetailDO);
|
||||||
}
|
}
|
||||||
//判断是否存在子项
|
// 主项本次收货增量 = 新子项数量 + 已存在子项的本次收货增量(PDA 传子项累计值时:child.receiptQuantity - childDb.alreadyReceiptQuantity)
|
||||||
List<ReceiptMaterialDetailDO> returnReceiptMaterialDetailDOChildList = new ArrayList<>();
|
BigDecimal newChildrenTotalQuantity = BigDecimal.ZERO;
|
||||||
|
BigDecimal existingChildrenIncrement = BigDecimal.ZERO;
|
||||||
List<ReceiptMaterialDetailDO> receiptMaterialDetailDOChildList = receiptMaterialDetailDO.getChildren();
|
List<ReceiptMaterialDetailDO> receiptMaterialDetailDOChildList = receiptMaterialDetailDO.getChildren();
|
||||||
if (!CollectionUtils.isEmpty(receiptMaterialDetailDOChildList)){
|
if (!CollectionUtils.isEmpty(receiptMaterialDetailDOChildList)){
|
||||||
for (ReceiptMaterialDetailDO receiptMaterialDetailDOChild : receiptMaterialDetailDOChildList){
|
for (ReceiptMaterialDetailDO receiptMaterialDetailDOChild : receiptMaterialDetailDOChildList){
|
||||||
ReceiptMaterialDetailPO receiptMaterialDetailPOChildDb = receiptMaterialDetailDbMap.get(receiptMaterialDetailDOChild.getMaterialDetailId());
|
ReceiptMaterialDetailPO receiptMaterialDetailPOChildDb = receiptMaterialDetailDbMap.get(receiptMaterialDetailDOChild.getMaterialDetailId());
|
||||||
if (receiptMaterialDetailPOChildDb != null){
|
if (receiptMaterialDetailPOChildDb == null && receiptMaterialDetailDOChild.getUniqueId() != null) {
|
||||||
continue;
|
receiptMaterialDetailPOChildDb = receiptMaterialDetailDbMapByUniqueId.get(receiptMaterialDetailDOChild.getUniqueId());
|
||||||
}
|
}
|
||||||
|
BigDecimal childQty = receiptMaterialDetailDOChild.getReceiptQuantity() != null ? receiptMaterialDetailDOChild.getReceiptQuantity() : BigDecimal.ZERO;
|
||||||
|
BigDecimal childDbAlready = receiptMaterialDetailPOChildDb != null && receiptMaterialDetailPOChildDb.getAlreadyReceiptQuantity() != null
|
||||||
|
? receiptMaterialDetailPOChildDb.getAlreadyReceiptQuantity() : BigDecimal.ZERO;
|
||||||
|
if (receiptMaterialDetailPOChildDb == null) {
|
||||||
|
// 新子项:累加其收货数量
|
||||||
|
newChildrenTotalQuantity = newChildrenTotalQuantity.add(childQty);
|
||||||
|
} else {
|
||||||
|
// 已存在子项:累加本次增量(PDA 传累计值,增量 = 本次值 - DB 已收值)
|
||||||
|
BigDecimal delta = childQty.subtract(childDbAlready);
|
||||||
|
if (delta.compareTo(BigDecimal.ZERO) > 0) {
|
||||||
|
existingChildrenIncrement = existingChildrenIncrement.add(delta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BigDecimal childReceiptQty = receiptMaterialDetailDOChild.getReceiptQuantity() != null ? receiptMaterialDetailDOChild.getReceiptQuantity() : BigDecimal.ZERO;
|
||||||
ReceiptMaterialDetailDO returnReceiptMaterialDetailDOChild = new ReceiptMaterialDetailDO();
|
ReceiptMaterialDetailDO returnReceiptMaterialDetailDOChild = new ReceiptMaterialDetailDO();
|
||||||
|
if (receiptMaterialDetailPOChildDb != null){
|
||||||
|
// 子项已存在:用 DB 数据 + PDA 收货数据组装,保证不同明细独立收货不被丢失
|
||||||
|
BeanUtils.copyProperties(receiptMaterialDetailPOChildDb, returnReceiptMaterialDetailDOChild);
|
||||||
|
BeanUtils.copyProperties(receiptMaterialDetailDOChild, returnReceiptMaterialDetailDOChild, IgnoreNullUtil.getNullPropertyNames(receiptMaterialDetailDOChild));
|
||||||
|
// PDA 传子项累计值时,更新子项已收数量(取较大值,确保第二次及以后收货时子项已收数正确)
|
||||||
|
if (childQty.compareTo(childDbAlready) > 0) {
|
||||||
|
returnReceiptMaterialDetailDOChild.setAlreadyReceiptQuantity(childQty);
|
||||||
|
}
|
||||||
|
returnReceiptMaterialDetailDOChild.setAllowModify(2);
|
||||||
|
returnReceiptMaterialDetailDOChild.setLevel(2);
|
||||||
|
returnReceiptMaterialDetailDOChild.setParentUniqueId(receiptMaterialDetailPO.getUniqueId());
|
||||||
|
setMaterialMoreDetailInfo(returnReceiptMaterialDetailDOChild);
|
||||||
|
} else {
|
||||||
|
// 子项不存在:新增子项
|
||||||
BeanUtils.copyProperties(receiptMaterialDetailPO, returnReceiptMaterialDetailDOChild, "materialDetailId","createBy","createByName","createTime",
|
BeanUtils.copyProperties(receiptMaterialDetailPO, returnReceiptMaterialDetailDOChild, "materialDetailId","createBy","createByName","createTime",
|
||||||
"updateBy","updateByName","updateTime");
|
"updateBy","updateByName","updateTime");
|
||||||
BeanUtils.copyProperties(receiptMaterialDetailDOChild, returnReceiptMaterialDetailDOChild, IgnoreNullUtil.getNullPropertyNames(receiptMaterialDetailDOChild));
|
BeanUtils.copyProperties(receiptMaterialDetailDOChild, returnReceiptMaterialDetailDOChild, IgnoreNullUtil.getNullPropertyNames(receiptMaterialDetailDOChild));
|
||||||
if (ObjectUtil.isNotNull(returnReceiptMaterialDetailDOChild.getMaterialDetailId()) && returnReceiptMaterialDetailDOChild.getMaterialDetailId() == 0){
|
if (ObjectUtil.isNotNull(returnReceiptMaterialDetailDOChild.getMaterialDetailId()) && returnReceiptMaterialDetailDOChild.getMaterialDetailId() == 0){
|
||||||
returnReceiptMaterialDetailDOChild.setMaterialDetailId(null);
|
returnReceiptMaterialDetailDOChild.setMaterialDetailId(null);
|
||||||
}
|
}
|
||||||
//收货后 设置该记录不允许被修改
|
|
||||||
returnReceiptMaterialDetailDOChild.setAllowModify(2);
|
returnReceiptMaterialDetailDOChild.setAllowModify(2);
|
||||||
returnReceiptMaterialDetailDOChild.setUniqueId(idGenerator.snowflakeId(SnowFlakeConstants.wmsId));
|
returnReceiptMaterialDetailDOChild.setUniqueId(idGenerator.snowflakeId(SnowFlakeConstants.wmsId));
|
||||||
returnReceiptMaterialDetailDOChild.setLevel(2);
|
returnReceiptMaterialDetailDOChild.setLevel(2);
|
||||||
returnReceiptMaterialDetailDOChild.setParentUniqueId(receiptMaterialDetailPO.getUniqueId());
|
returnReceiptMaterialDetailDOChild.setParentUniqueId(receiptMaterialDetailPO.getUniqueId());
|
||||||
//设置物料状态及容器信息
|
|
||||||
setMaterialMoreDetailInfo(returnReceiptMaterialDetailDOChild);
|
setMaterialMoreDetailInfo(returnReceiptMaterialDetailDOChild);
|
||||||
|
}
|
||||||
//是否开启了序列号管理
|
//是否开启了序列号管理
|
||||||
if (receiptMaterialDetailPO.getSerialNumberManage() == 1){
|
if (receiptMaterialDetailPO.getSerialNumberManage() == 1){
|
||||||
if (CollectionUtils.isEmpty(receiptMaterialDetailDOChild.getMaterialDetailSerialNumberList())){
|
if (CollectionUtils.isEmpty(receiptMaterialDetailDOChild.getMaterialDetailSerialNumberList())){
|
||||||
@@ -1150,19 +1339,33 @@ public class StockReceiptOrderApplicationService {
|
|||||||
returnReceiptMaterialDetailDOChild.setMaterialDetailSerialNumberList(receiptMaterialDetailDOChild.getMaterialDetailSerialNumberList());
|
returnReceiptMaterialDetailDOChild.setMaterialDetailSerialNumberList(receiptMaterialDetailDOChild.getMaterialDetailSerialNumberList());
|
||||||
returnReceiptMaterialDetailDOChild.setMaterialMoreDetailList(receiptMaterialDetailDOChild.getMaterialMoreDetailList());
|
returnReceiptMaterialDetailDOChild.setMaterialMoreDetailList(receiptMaterialDetailDOChild.getMaterialMoreDetailList());
|
||||||
returnReceiptMaterialDetailDOChildList.add(returnReceiptMaterialDetailDOChild);
|
returnReceiptMaterialDetailDOChildList.add(returnReceiptMaterialDetailDOChild);
|
||||||
actualQuantity = actualQuantity.add(returnReceiptMaterialDetailDOChild.getReceiptQuantity());
|
orderLevelQuantity = orderLevelQuantity.add(childReceiptQty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//已收货数量 = 已收货数量 + 当前作业数量
|
// 主项本次收货增量 = 新子项数量 + 已存在子项增量;若均为 0 则使用主项 receiptQuantity 或子项合计(再次收货时 PDA 传相同值,主项可能为 0)
|
||||||
receiptMaterialDetailDO.setAlreadyReceiptQuantity(receiptMaterialDetailPO.getAlreadyReceiptQuantity().add(actualQuantity));
|
// 无子项时使用主项 receiptQuantity
|
||||||
//记录本次收货单收货总数
|
BigDecimal childrenTotalIncrement = newChildrenTotalQuantity.add(existingChildrenIncrement);
|
||||||
totalActualQuantity = totalActualQuantity.add(actualQuantity);
|
mainItemActualQuantity = CollectionUtils.isEmpty(receiptMaterialDetailDOChildList)
|
||||||
|
? receiptQuantity
|
||||||
|
: (childrenTotalIncrement.compareTo(BigDecimal.ZERO) > 0
|
||||||
|
? childrenTotalIncrement
|
||||||
|
: (receiptQuantity.compareTo(BigDecimal.ZERO) > 0 ? receiptQuantity : childrenTotalQuantity));
|
||||||
|
//主项已收货数量 = 原有 + 主项本次收货增量
|
||||||
|
receiptMaterialDetailDO.setAlreadyReceiptQuantity(receiptMaterialDetailPO.getAlreadyReceiptQuantity().add(mainItemActualQuantity));
|
||||||
|
//记录本次收货单收货总数(主项+子项合计,用于收货单级统计)
|
||||||
|
orderLevelQuantity = mainItemActualQuantity;
|
||||||
|
totalActualQuantity = totalActualQuantity.add(orderLevelQuantity);
|
||||||
//判断收货数量是否大于计划数量
|
//判断收货数量是否大于计划数量
|
||||||
Integer receiptStatus = judgeReceiptQuantity(receiptMaterialDetailDO.getAlreadyReceiptQuantity(), receiptMaterialDetailPO.getQuantity());
|
Integer receiptStatus = judgeReceiptQuantity(receiptMaterialDetailDO.getAlreadyReceiptQuantity(), receiptMaterialDetailPO.getQuantity());
|
||||||
receiptMaterialDetailDO.setReceiptStatus(receiptStatus);
|
receiptMaterialDetailDO.setReceiptStatus(receiptStatus);
|
||||||
if (receiptStatus > 2){
|
if (receiptStatus > 2){
|
||||||
totalActualReceiptMaterialQuantity += 1;
|
totalActualReceiptMaterialQuantity += 1;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// 收货为 0 的明细:保持已收货数量和状态不变,仍加入列表以保持明细完整
|
||||||
|
receiptMaterialDetailDO.setAlreadyReceiptQuantity(receiptMaterialDetailPO.getAlreadyReceiptQuantity());
|
||||||
|
receiptMaterialDetailDO.setReceiptStatus(receiptMaterialDetailPO.getReceiptStatus() != null ? receiptMaterialDetailPO.getReceiptStatus() : 1);
|
||||||
|
}
|
||||||
ReceiptMaterialDetailDO returnReceiptMaterialDetailDO = new ReceiptMaterialDetailDO();
|
ReceiptMaterialDetailDO returnReceiptMaterialDetailDO = new ReceiptMaterialDetailDO();
|
||||||
BeanUtils.copyProperties(receiptMaterialDetailPO, returnReceiptMaterialDetailDO);
|
BeanUtils.copyProperties(receiptMaterialDetailPO, returnReceiptMaterialDetailDO);
|
||||||
BeanUtils.copyProperties(receiptMaterialDetailDO, returnReceiptMaterialDetailDO, IgnoreNullUtil.getNullPropertyNames(receiptMaterialDetailDO));
|
BeanUtils.copyProperties(receiptMaterialDetailDO, returnReceiptMaterialDetailDO, IgnoreNullUtil.getNullPropertyNames(receiptMaterialDetailDO));
|
||||||
@@ -1285,8 +1488,9 @@ public class StockReceiptOrderApplicationService {
|
|||||||
receiptMaterialDetailDOChildByCopy.setLevel(2);
|
receiptMaterialDetailDOChildByCopy.setLevel(2);
|
||||||
receiptMaterialDetailDOChildByCopy.setParentUniqueId(receiptMaterialDetailDO.getUniqueId());
|
receiptMaterialDetailDOChildByCopy.setParentUniqueId(receiptMaterialDetailDO.getUniqueId());
|
||||||
receiptMaterialDetailDOChildByCopy.setInUniqueId(inMaterialDetailDO.getUniqueId());
|
receiptMaterialDetailDOChildByCopy.setInUniqueId(inMaterialDetailDO.getUniqueId());
|
||||||
receiptMaterialDetailDOChildByCopy.setQuantity(receiptMaterialDetailDOChild.getReceiptQuantity());
|
BigDecimal childQty = receiptMaterialDetailDOChild.getReceiptQuantity() != null ? receiptMaterialDetailDOChild.getReceiptQuantity() : BigDecimal.ZERO;
|
||||||
receiptMaterialDetailDOChildByCopy.setAlreadyReceiptQuantity(receiptMaterialDetailDOChild.getReceiptQuantity());
|
receiptMaterialDetailDOChildByCopy.setQuantity(childQty);
|
||||||
|
receiptMaterialDetailDOChildByCopy.setAlreadyReceiptQuantity(childQty);
|
||||||
BeanUtils.copyProperties(receiptMaterialDetailDOChildByCopy, receiptMaterialDetailDOChild);
|
BeanUtils.copyProperties(receiptMaterialDetailDOChildByCopy, receiptMaterialDetailDOChild);
|
||||||
//是否开启了序列号管理
|
//是否开启了序列号管理
|
||||||
if (receiptMaterialDetailDO.getSerialNumberManage() == 1){
|
if (receiptMaterialDetailDO.getSerialNumberManage() == 1){
|
||||||
@@ -1294,7 +1498,7 @@ public class StockReceiptOrderApplicationService {
|
|||||||
throw new ServiceException("物料【" + receiptMaterialDetailDO.getMaterialName() + "】开启了序列号管理的序列号不能为空");
|
throw new ServiceException("物料【" + receiptMaterialDetailDO.getMaterialName() + "】开启了序列号管理的序列号不能为空");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
actualQuantity = actualQuantity.add(receiptMaterialDetailDOChild.getReceiptQuantity());
|
actualQuantity = actualQuantity.add(childQty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//已收货数量 = 当前作业数量
|
//已收货数量 = 当前作业数量
|
||||||
|
|||||||
+2
@@ -1,6 +1,7 @@
|
|||||||
package com.mhd.wms.domain.inventoryStandingReport.entity;
|
package com.mhd.wms.domain.inventoryStandingReport.entity;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.mhd.common.core.annotation.Excel;
|
import com.mhd.common.core.annotation.Excel;
|
||||||
import com.mhd.common.core.web.domain.BaseVOEntity;
|
import com.mhd.common.core.web.domain.BaseVOEntity;
|
||||||
@@ -55,6 +56,7 @@ public class InventoryStandingReport extends BaseVOEntity {
|
|||||||
|
|
||||||
@ApiModelProperty("货主编码")
|
@ApiModelProperty("货主编码")
|
||||||
@Excel(name = "货主名称编码")
|
@Excel(name = "货主名称编码")
|
||||||
|
@TableField(exist = false)
|
||||||
private String shipperCode;
|
private String shipperCode;
|
||||||
|
|
||||||
@ApiModelProperty("货主名称")
|
@ApiModelProperty("货主名称")
|
||||||
|
|||||||
+286
-88
@@ -113,19 +113,29 @@ public class ReceiptMaterialDetailImpl extends ServiceImpl<ReceiptMaterialDetail
|
|||||||
if (CollectionUtils.isEmpty(materialMoreDetailList)) {
|
if (CollectionUtils.isEmpty(materialMoreDetailList)) {
|
||||||
ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(receiptMaterialDetailPO.getMaterialBaseInfoId());
|
ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(receiptMaterialDetailPO.getMaterialBaseInfoId());
|
||||||
if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) {
|
if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) {
|
||||||
materialMoreDetailList = JSON.parseArray(JSONObject.toJSONString(ajaxResult.get("data")), MaterialMoreDetailPO.class);
|
List<BatchDetailFeignPO> batchList = JSON.parseArray(JSONObject.toJSONString(ajaxResult.get("data")), BatchDetailFeignPO.class);
|
||||||
|
materialMoreDetailList = filterAndConvertToMaterialMoreDetail(batchList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 从入库单明细表中获取InvoiceNo、BatchRefNo、SheetRefNo、BoxPalletNo字段的值
|
// 从入库单明细表中获取InvoiceNo、BatchRefNo、SheetRefNo、BoxPalletNo字段的值
|
||||||
fillAttributeValueFromInMaterialDetail(receiptMaterialDetailPO, materialMoreDetailList);
|
fillAttributeValueFromInMaterialDetail(receiptMaterialDetailPO, materialMoreDetailList);
|
||||||
receiptMaterialDetailPO.setMaterialMoreDetailList(materialMoreDetailList);
|
receiptMaterialDetailPO.setMaterialMoreDetailList(materialMoreDetailList);
|
||||||
});
|
});
|
||||||
// 获取查询的层级
|
// 获取查询的层级:level 1 为顶级;level 2 且 parent_unique_id 为 null/0 的为孤儿项;level 2 且 parent_unique_id 在收货明细中无对应父项的也为孤儿(如 PDA 只收子项、父项在 in_material_detail 中),均作为顶级展示
|
||||||
|
java.util.Set<Long> receiptParentIds = receiptMaterialDetailPOList.stream()
|
||||||
|
.flatMap(po -> java.util.stream.Stream.of(po.getUniqueId(), po.getInUniqueId()))
|
||||||
|
.filter(id -> id != null)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
List<ReceiptMaterialDetailPO> receiptMaterialDetailPOParentList = receiptMaterialDetailPOList
|
List<ReceiptMaterialDetailPO> receiptMaterialDetailPOParentList = receiptMaterialDetailPOList
|
||||||
.stream().filter(e -> 1 == e.getLevel()).collect(Collectors.toList());
|
.stream().filter(e -> e.getLevel() != null && (
|
||||||
// 递归查询子集
|
1 == e.getLevel()
|
||||||
|
|| (2 == e.getLevel() && (e.getParentUniqueId() == null || Long.valueOf(0).equals(e.getParentUniqueId())))
|
||||||
|
|| (2 == e.getLevel() && e.getParentUniqueId() != null && !receiptParentIds.contains(e.getParentUniqueId()))
|
||||||
|
)).collect(Collectors.toList());
|
||||||
|
// 递归查询子集:parent_unique_id 可能指向 receipt.unique_id(PDA 收货创建的子项)或 in_material_detail.unique_id(从入库单复制),
|
||||||
|
// 需同时用 unique_id 和 in_unique_id 查找子项
|
||||||
for(ReceiptMaterialDetailPO materialDetailPO :receiptMaterialDetailPOParentList){
|
for(ReceiptMaterialDetailPO materialDetailPO :receiptMaterialDetailPOParentList){
|
||||||
List<ReceiptMaterialDetailPO> children = getChildren(materialDetailPO.getUniqueId(), receiptMaterialDetailPOList, 2);
|
List<ReceiptMaterialDetailPO> children = getChildren(materialDetailPO.getUniqueId(), materialDetailPO.getInUniqueId(), receiptMaterialDetailPOList, 2);
|
||||||
children.forEach(childrenDetailPO -> {
|
children.forEach(childrenDetailPO -> {
|
||||||
MaterialMoreDetailDO materialMoreDetailDO = new MaterialMoreDetailDO();
|
MaterialMoreDetailDO materialMoreDetailDO = new MaterialMoreDetailDO();
|
||||||
materialMoreDetailDO.setMaterialDetailUniqueId(childrenDetailPO.getUniqueId());
|
materialMoreDetailDO.setMaterialDetailUniqueId(childrenDetailPO.getUniqueId());
|
||||||
@@ -135,7 +145,8 @@ public class ReceiptMaterialDetailImpl extends ServiceImpl<ReceiptMaterialDetail
|
|||||||
if (CollectionUtils.isEmpty(materialMoreDetailList)) {
|
if (CollectionUtils.isEmpty(materialMoreDetailList)) {
|
||||||
ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(childrenDetailPO.getMaterialBaseInfoId());
|
ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(childrenDetailPO.getMaterialBaseInfoId());
|
||||||
if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) {
|
if (ajaxResult != null && "200".equals(String.valueOf(ajaxResult.get("code")))) {
|
||||||
materialMoreDetailList = JSON.parseArray(JSONObject.toJSONString(ajaxResult.get("data")), MaterialMoreDetailPO.class);
|
List<BatchDetailFeignPO> batchList = JSON.parseArray(JSONObject.toJSONString(ajaxResult.get("data")), BatchDetailFeignPO.class);
|
||||||
|
materialMoreDetailList = filterAndConvertToMaterialMoreDetail(batchList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 从入库单明细表中获取InvoiceNo、BatchRefNo、SheetRefNo、BoxPalletNo字段的值
|
// 从入库单明细表中获取InvoiceNo、BatchRefNo、SheetRefNo、BoxPalletNo字段的值
|
||||||
@@ -146,15 +157,70 @@ public class ReceiptMaterialDetailImpl extends ServiceImpl<ReceiptMaterialDetail
|
|||||||
materialDetailPO.setChildren(children);
|
materialDetailPO.setChildren(children);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// 兜底:若有 level 2 既不在顶级列表、也不在任何父项的 children 中,则提升为顶级(避免 PDA 收货后 PC 端漏显)
|
||||||
|
java.util.Set<Long> displayedUniqueIds = new java.util.HashSet<>();
|
||||||
|
receiptMaterialDetailPOParentList.forEach(p -> collectUniqueIdsRecursively(p, displayedUniqueIds));
|
||||||
|
for (ReceiptMaterialDetailPO po : receiptMaterialDetailPOList) {
|
||||||
|
if (po.getLevel() != null && 2 == po.getLevel() && po.getUniqueId() != null && !displayedUniqueIds.contains(po.getUniqueId())) {
|
||||||
|
receiptMaterialDetailPOParentList.add(po);
|
||||||
|
}
|
||||||
|
}
|
||||||
return receiptMaterialDetailPOParentList;
|
return receiptMaterialDetailPOParentList;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ReceiptMaterialDetailPO> getChildren(Long parentUniqueId, List<ReceiptMaterialDetailPO> receiptMaterialDetailPOList, Integer maxLevel){
|
private void collectUniqueIdsRecursively(ReceiptMaterialDetailPO po, java.util.Set<Long> set) {
|
||||||
List<ReceiptMaterialDetailPO> childrenCityList = receiptMaterialDetailPOList.stream().filter(materialDetailPO -> parentUniqueId.equals(materialDetailPO.getParentUniqueId())).collect(Collectors.toList());
|
if (po == null || po.getUniqueId() == null) return;
|
||||||
|
set.add(po.getUniqueId());
|
||||||
|
if (!CollectionUtils.isEmpty(po.getChildren())) {
|
||||||
|
po.getChildren().forEach(c -> collectUniqueIdsRecursively(c, set));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 过滤 isDisplay=1 的批次属性并转换为 MaterialMoreDetailPO,与 PC 端 getInfo 一致
|
||||||
|
*/
|
||||||
|
private List<MaterialMoreDetailPO> filterAndConvertToMaterialMoreDetail(List<BatchDetailFeignPO> batchList) {
|
||||||
|
List<MaterialMoreDetailPO> result = new ArrayList<>();
|
||||||
|
if (CollectionUtils.isEmpty(batchList)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
for (BatchDetailFeignPO po : batchList) {
|
||||||
|
if (po.getIsDisplay() == null || po.getIsDisplay() != 1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
MaterialMoreDetailPO mpo = new MaterialMoreDetailPO();
|
||||||
|
mpo.setBatchId(po.getBatchId());
|
||||||
|
mpo.setBatchDetailId(po.getBatchDetailId());
|
||||||
|
mpo.setBatchLabels(po.getBatchLabels());
|
||||||
|
mpo.setInputControl(po.getInputControl());
|
||||||
|
mpo.setAttributeFormat(po.getAttributeFormat());
|
||||||
|
mpo.setAttributeOption(po.getAttributeOption());
|
||||||
|
result.add(mpo);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查找子项:parent_unique_id 可能指向 receipt.unique_id(PDA 收货)或 in_material_detail.unique_id(从入库单复制)
|
||||||
|
*/
|
||||||
|
private List<ReceiptMaterialDetailPO> getChildren(Long parentUniqueId, Long parentInUniqueId,
|
||||||
|
List<ReceiptMaterialDetailPO> receiptMaterialDetailPOList, Integer maxLevel){
|
||||||
|
if (parentUniqueId == null && parentInUniqueId == null) {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
final Long pid = parentUniqueId;
|
||||||
|
final Long inPid = parentInUniqueId;
|
||||||
|
List<ReceiptMaterialDetailPO> childrenCityList = receiptMaterialDetailPOList.stream()
|
||||||
|
.filter(materialDetailPO -> {
|
||||||
|
Long p = materialDetailPO.getParentUniqueId();
|
||||||
|
if (p == null) return false;
|
||||||
|
return (pid != null && p.equals(pid)) || (inPid != null && p.equals(inPid));
|
||||||
|
})
|
||||||
|
.collect(Collectors.toList());
|
||||||
if (!CollectionUtils.isEmpty(childrenCityList)){
|
if (!CollectionUtils.isEmpty(childrenCityList)){
|
||||||
childrenCityList.forEach(childrenCity -> {
|
childrenCityList.forEach(childrenCity -> {
|
||||||
if (childrenCity.getLevel() < maxLevel){
|
if (childrenCity.getLevel() != null && childrenCity.getLevel() < maxLevel){
|
||||||
childrenCity.setChildren(getChildren(childrenCity.getUniqueId(), receiptMaterialDetailPOList, maxLevel));
|
childrenCity.setChildren(getChildren(childrenCity.getUniqueId(), childrenCity.getInUniqueId(), receiptMaterialDetailPOList, maxLevel));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -244,73 +310,7 @@ public class ReceiptMaterialDetailImpl extends ServiceImpl<ReceiptMaterialDetail
|
|||||||
List<MaterialMoreDetail> materialMoreDetailList = new ArrayList<>();
|
List<MaterialMoreDetail> materialMoreDetailList = new ArrayList<>();
|
||||||
List<InMaterialDetailSerialNumber> materialDetailSerialNumberList = new ArrayList<>();
|
List<InMaterialDetailSerialNumber> materialDetailSerialNumberList = new ArrayList<>();
|
||||||
for (ReceiptMaterialDetailDO receiptMaterialDetailDO : receiptMaterialDetailDOList){
|
for (ReceiptMaterialDetailDO receiptMaterialDetailDO : receiptMaterialDetailDOList){
|
||||||
List<MaterialMoreDetailDO> materialMoreDetailList1 = receiptMaterialDetailDO.getMaterialMoreDetailList();
|
extractBatchAttributesToReceiptDetail(receiptMaterialDetailDO);
|
||||||
if (CollectionUtils.isEmpty(materialMoreDetailList1)) {
|
|
||||||
materialMoreDetailList1 = new ArrayList<>();
|
|
||||||
}
|
|
||||||
for (MaterialMoreDetailDO materialMoreDetailDO : materialMoreDetailList1) {
|
|
||||||
String batchLabels = materialMoreDetailDO.getBatchLabels();
|
|
||||||
String attributeValue = materialMoreDetailDO.getAttributeValue();
|
|
||||||
if (attributeValue != null && !attributeValue.isEmpty() && attributeValue != "" && attributeValue.length() > 0 ) {
|
|
||||||
attributeValue = attributeValue.trim();
|
|
||||||
switch (batchLabels) {
|
|
||||||
case "扩展字段4":
|
|
||||||
receiptMaterialDetailDO.setExtAttr4(attributeValue);
|
|
||||||
break;
|
|
||||||
case "扩展字段3":
|
|
||||||
receiptMaterialDetailDO.setExtAttr3(attributeValue);
|
|
||||||
break;
|
|
||||||
case "扩展字段2":
|
|
||||||
receiptMaterialDetailDO.setExtAttr2(attributeValue);
|
|
||||||
break;
|
|
||||||
case "扩展字段1":
|
|
||||||
receiptMaterialDetailDO.setExtAttr1(attributeValue);
|
|
||||||
break;
|
|
||||||
case "箱号/卡板号":
|
|
||||||
receiptMaterialDetailDO.setBoxPalletNo(attributeValue);
|
|
||||||
break;
|
|
||||||
case "Sheet Ref NO's":
|
|
||||||
receiptMaterialDetailDO.setSheetRefNo(attributeValue);
|
|
||||||
break;
|
|
||||||
case "Batch Ref NO's":
|
|
||||||
receiptMaterialDetailDO.setBatchRefNo(attributeValue);
|
|
||||||
break;
|
|
||||||
case "存货日期":
|
|
||||||
// 判断是否是日期格式再赋值避免报错
|
|
||||||
try {
|
|
||||||
if (attributeValue.matches("\\d{4}-\\d{2}-\\d{2}.*")) {
|
|
||||||
receiptMaterialDetailDO.setInventoryDate(DateUtils.parseDate(attributeValue));
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.warn("库存日期格式转换失败,物料:{},原始值:{}", receiptMaterialDetailDO.getMaterialName(), attributeValue);
|
|
||||||
}
|
|
||||||
//receiptMaterialDetailDO.setInventoryDate(DateUtils.parseDate(attributeValue));
|
|
||||||
break;
|
|
||||||
case "过期日期":
|
|
||||||
// 判断是否是日期格式再赋值避免报错
|
|
||||||
try {
|
|
||||||
if (attributeValue.matches("\\d{4}-\\d{2}-\\d{2}.*")) {
|
|
||||||
receiptMaterialDetailDO.setExpiryDate(DateUtils.parseDate(attributeValue));
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.warn("库存日期格式转换失败,物料:{},原始值:{}", receiptMaterialDetailDO.getMaterialName(), attributeValue);
|
|
||||||
}
|
|
||||||
//receiptMaterialDetailDO.setExpiryDate(DateUtils.parseDate(attributeValue));
|
|
||||||
break;
|
|
||||||
case "生产日期":
|
|
||||||
// 判断是否是日期格式再赋值避免报错
|
|
||||||
try {
|
|
||||||
if (attributeValue.matches("\\d{4}-\\d{2}-\\d{2}.*")) {
|
|
||||||
receiptMaterialDetailDO.setProductionDate(DateUtils.parseDate(attributeValue));
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.warn("库存日期格式转换失败,物料:{},原始值:{}", receiptMaterialDetailDO.getMaterialName(), attributeValue);
|
|
||||||
}
|
|
||||||
//receiptMaterialDetailDO.setProductionDate(DateUtils.parseDate(attributeValue));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 自动生成批次号并校验唯一性(包括子项)
|
// 自动生成批次号并校验唯一性(包括子项)
|
||||||
generateAndValidateBatchNumber(receiptMaterialDetailDO, shipperId);
|
generateAndValidateBatchNumber(receiptMaterialDetailDO, shipperId);
|
||||||
// 当 materialMoreDetailList 为空时(如 PDA 未传),从 receiptMaterialDetailDO 的 batch_number、material_status_code 等字段构建,确保更多属性能保存并回显
|
// 当 materialMoreDetailList 为空时(如 PDA 未传),从 receiptMaterialDetailDO 的 batch_number、material_status_code 等字段构建,确保更多属性能保存并回显
|
||||||
@@ -331,6 +331,8 @@ public class ReceiptMaterialDetailImpl extends ServiceImpl<ReceiptMaterialDetail
|
|||||||
List<ReceiptMaterialDetail> receiptMaterialDetailChildList = new ArrayList<>();
|
List<ReceiptMaterialDetail> receiptMaterialDetailChildList = new ArrayList<>();
|
||||||
if (!CollectionUtils.isEmpty(receiptMaterialDetailDOChildList)){
|
if (!CollectionUtils.isEmpty(receiptMaterialDetailDOChildList)){
|
||||||
for (ReceiptMaterialDetailDO receiptMaterialDetailDOChild : receiptMaterialDetailDOChildList){
|
for (ReceiptMaterialDetailDO receiptMaterialDetailDOChild : receiptMaterialDetailDOChildList){
|
||||||
|
// 子项也需从批次属性提取净重、毛重、体积、面积等字段
|
||||||
|
extractBatchAttributesToReceiptDetail(receiptMaterialDetailDOChild);
|
||||||
ReceiptMaterialDetail receiptMaterialDetailChild = new ReceiptMaterialDetail();
|
ReceiptMaterialDetail receiptMaterialDetailChild = new ReceiptMaterialDetail();
|
||||||
BeanUtils.copyProperties(receiptMaterialDetailDOChild, receiptMaterialDetailChild);
|
BeanUtils.copyProperties(receiptMaterialDetailDOChild, receiptMaterialDetailChild);
|
||||||
receiptMaterialDetailChild.setCreateBy(loginUser.getUserid());
|
receiptMaterialDetailChild.setCreateBy(loginUser.getUserid());
|
||||||
@@ -361,8 +363,21 @@ public class ReceiptMaterialDetailImpl extends ServiceImpl<ReceiptMaterialDetail
|
|||||||
}
|
}
|
||||||
//保存物料明细信息
|
//保存物料明细信息
|
||||||
saveOrUpdateBatch(receiptMaterialDetailList);
|
saveOrUpdateBatch(receiptMaterialDetailList);
|
||||||
//批量新增物料信息
|
//批量新增/更新物料更多属性:先删除该收货单下所有明细的旧批次属性,再插入新值,避免重复插入导致更新失效
|
||||||
if (!CollectionUtils.isEmpty(materialMoreDetailList)){
|
if (!CollectionUtils.isEmpty(materialMoreDetailList)){
|
||||||
|
String receiptOrderNumber = stockReceiptOrderDO.getReceiptOrderNumber();
|
||||||
|
if (StringUtils.isBlank(receiptOrderNumber) && !CollectionUtils.isEmpty(receiptMaterialDetailDOList)) {
|
||||||
|
receiptOrderNumber = receiptMaterialDetailDOList.get(0).getReceiptOrderNumber();
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotBlank(receiptOrderNumber)) {
|
||||||
|
java.util.Set<Long> uniqueIds = collectReceiptDetailUniqueIds(receiptMaterialDetailDOList);
|
||||||
|
if (!uniqueIds.isEmpty()) {
|
||||||
|
IMaterialMoreDetailService.remove(new QueryWrapper<MaterialMoreDetail>()
|
||||||
|
.eq("order_number", receiptOrderNumber)
|
||||||
|
.in("material_detail_unique_id", uniqueIds)
|
||||||
|
.eq("del_flag", 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
IMaterialMoreDetailService.saveBatch(materialMoreDetailList);
|
IMaterialMoreDetailService.saveBatch(materialMoreDetailList);
|
||||||
}
|
}
|
||||||
//批量新增序列号
|
//批量新增序列号
|
||||||
@@ -603,22 +618,57 @@ public class ReceiptMaterialDetailImpl extends ServiceImpl<ReceiptMaterialDetail
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据attributeOption从入库单明细中获取对应的值并填充到attributeValue
|
// 根据attributeOption或batchLabels从入库单/收货单明细中获取对应的值并填充到attributeValue
|
||||||
for (MaterialMoreDetailPO materialMoreDetail : materialMoreDetailList) {
|
for (MaterialMoreDetailPO materialMoreDetail : materialMoreDetailList) {
|
||||||
String attributeOption = materialMoreDetail.getAttributeOption();
|
String attributeOption = materialMoreDetail.getAttributeOption();
|
||||||
|
String batchLabels = materialMoreDetail.getBatchLabels();
|
||||||
// 如果attributeValue已经有值,跳过
|
// 如果attributeValue已经有值,跳过
|
||||||
if (materialMoreDetail.getAttributeValue() != null && !materialMoreDetail.getAttributeValue().trim().isEmpty()) {
|
if (materialMoreDetail.getAttributeValue() != null && !materialMoreDetail.getAttributeValue().trim().isEmpty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// 根据attributeOption映射到入库单明细表的字段
|
// 根据attributeOption映射到入库单明细表的字段(兼容 batchLabels 兜底,如 "Batch Ref NO's"、"Sheet Ref NO's"、"箱号/卡板号")
|
||||||
if ("InvoiceNo".equalsIgnoreCase(attributeOption)) {
|
String refVal = null;
|
||||||
materialMoreDetail.setAttributeValue(inMaterialDetail.getInvoiceNo());
|
if ("InvoiceNo".equalsIgnoreCase(attributeOption) || "Invoice No".equalsIgnoreCase(batchLabels) || "发票号".equals(batchLabels)) {
|
||||||
} else if ("BatchRefNo".equalsIgnoreCase(attributeOption)) {
|
refVal = inMaterialDetail.getInvoiceNo();
|
||||||
materialMoreDetail.setAttributeValue(inMaterialDetail.getBatchRefNo());
|
} else if ("BatchRefNo".equalsIgnoreCase(attributeOption) || "Batch Ref NO's".equalsIgnoreCase(batchLabels) || "批次参考号".equals(batchLabels)) {
|
||||||
} else if ("SheetRefNo".equalsIgnoreCase(attributeOption)) {
|
refVal = inMaterialDetail.getBatchRefNo();
|
||||||
materialMoreDetail.setAttributeValue(inMaterialDetail.getSheetRefNo());
|
} else if ("SheetRefNo".equalsIgnoreCase(attributeOption) || "Sheet Ref NO's".equalsIgnoreCase(batchLabels) || "单据参考号".equals(batchLabels)) {
|
||||||
} else if ("BoxPalletNo".equalsIgnoreCase(attributeOption)) {
|
refVal = inMaterialDetail.getSheetRefNo();
|
||||||
materialMoreDetail.setAttributeValue(inMaterialDetail.getBoxPalletNo());
|
} else if ("BoxPalletNo".equalsIgnoreCase(attributeOption) || "Box No./Pallet No.".equalsIgnoreCase(batchLabels) || "箱号/卡板号".equals(batchLabels)) {
|
||||||
|
refVal = inMaterialDetail.getBoxPalletNo();
|
||||||
|
}
|
||||||
|
if (refVal != null) {
|
||||||
|
materialMoreDetail.setAttributeValue(refVal);
|
||||||
|
} else if (StringUtils.isNotBlank(batchLabels)) {
|
||||||
|
// 根据batchLabels填充净重、毛重、体积、面积(优先用收货明细,无则用入库明细)
|
||||||
|
String val = null;
|
||||||
|
switch (batchLabels.trim()) {
|
||||||
|
case "总净重":
|
||||||
|
case "净重(KG)":
|
||||||
|
case "净重":
|
||||||
|
val = receiptMaterialDetailPO.getTotalNetWeight() != null ? receiptMaterialDetailPO.getTotalNetWeight().toString() : (inMaterialDetail.getTotalNetWeight() != null ? inMaterialDetail.getTotalNetWeight().toString() : null);
|
||||||
|
break;
|
||||||
|
case "总毛重":
|
||||||
|
case "毛重(KG)":
|
||||||
|
case "毛重":
|
||||||
|
val = receiptMaterialDetailPO.getTotalGrossWeight() != null ? receiptMaterialDetailPO.getTotalGrossWeight().toString() : (inMaterialDetail.getTotalGrossWeight() != null ? inMaterialDetail.getTotalGrossWeight().toString() : null);
|
||||||
|
break;
|
||||||
|
case "总体积":
|
||||||
|
case "体积(CBM)":
|
||||||
|
case "体积":
|
||||||
|
val = receiptMaterialDetailPO.getTotalVolume() != null ? receiptMaterialDetailPO.getTotalVolume().toString() : (inMaterialDetail.getTotalVolume() != null ? inMaterialDetail.getTotalVolume().toString() : null);
|
||||||
|
break;
|
||||||
|
case "总面积":
|
||||||
|
case "面积(SQM)":
|
||||||
|
case "面积":
|
||||||
|
val = receiptMaterialDetailPO.getTotalArea() != null ? receiptMaterialDetailPO.getTotalArea().toString() : (inMaterialDetail.getTotalArea() != null ? inMaterialDetail.getTotalArea().toString() : null);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (val != null) {
|
||||||
|
materialMoreDetail.setAttributeValue(val);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -710,6 +760,145 @@ public class ReceiptMaterialDetailImpl extends ServiceImpl<ReceiptMaterialDetail
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从批次属性 materialMoreDetailList 提取值到收货明细字段(扩展字段、净重、毛重、体积、面积等)
|
||||||
|
*/
|
||||||
|
private void extractBatchAttributesToReceiptDetail(ReceiptMaterialDetailDO receiptMaterialDetailDO) {
|
||||||
|
List<MaterialMoreDetailDO> list = receiptMaterialDetailDO.getMaterialMoreDetailList();
|
||||||
|
if (CollectionUtils.isEmpty(list)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (MaterialMoreDetailDO materialMoreDetailDO : list) {
|
||||||
|
String batchLabels = materialMoreDetailDO.getBatchLabels();
|
||||||
|
String attributeValue = materialMoreDetailDO.getAttributeValue();
|
||||||
|
if (StringUtils.isBlank(batchLabels) || StringUtils.isBlank(attributeValue)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
attributeValue = attributeValue.trim();
|
||||||
|
switch (batchLabels) {
|
||||||
|
case "扩展字段4":
|
||||||
|
receiptMaterialDetailDO.setExtAttr4(attributeValue);
|
||||||
|
break;
|
||||||
|
case "扩展字段3":
|
||||||
|
receiptMaterialDetailDO.setExtAttr3(attributeValue);
|
||||||
|
break;
|
||||||
|
case "扩展字段2":
|
||||||
|
receiptMaterialDetailDO.setExtAttr2(attributeValue);
|
||||||
|
break;
|
||||||
|
case "扩展字段1":
|
||||||
|
receiptMaterialDetailDO.setExtAttr1(attributeValue);
|
||||||
|
break;
|
||||||
|
case "箱号/卡板号":
|
||||||
|
receiptMaterialDetailDO.setBoxPalletNo(attributeValue);
|
||||||
|
break;
|
||||||
|
case "Sheet Ref NO's":
|
||||||
|
receiptMaterialDetailDO.setSheetRefNo(attributeValue);
|
||||||
|
break;
|
||||||
|
case "Batch Ref NO's":
|
||||||
|
receiptMaterialDetailDO.setBatchRefNo(attributeValue);
|
||||||
|
break;
|
||||||
|
case "存货日期":
|
||||||
|
try {
|
||||||
|
if (attributeValue.matches("\\d{4}-\\d{2}-\\d{2}.*")) {
|
||||||
|
receiptMaterialDetailDO.setInventoryDate(DateUtils.parseDate(attributeValue));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("库存日期格式转换失败,物料:{},原始值:{}", receiptMaterialDetailDO.getMaterialName(), attributeValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "过期日期":
|
||||||
|
try {
|
||||||
|
if (attributeValue.matches("\\d{4}-\\d{2}-\\d{2}.*")) {
|
||||||
|
receiptMaterialDetailDO.setExpiryDate(DateUtils.parseDate(attributeValue));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("库存日期格式转换失败,物料:{},原始值:{}", receiptMaterialDetailDO.getMaterialName(), attributeValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "生产日期":
|
||||||
|
try {
|
||||||
|
if (attributeValue.matches("\\d{4}-\\d{2}-\\d{2}.*")) {
|
||||||
|
receiptMaterialDetailDO.setProductionDate(DateUtils.parseDate(attributeValue));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("库存日期格式转换失败,物料:{},原始值:{}", receiptMaterialDetailDO.getMaterialName(), attributeValue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "总净重":
|
||||||
|
case "净重(KG)":
|
||||||
|
case "净重":
|
||||||
|
setReceiptDetailBigDecimalField(receiptMaterialDetailDO, attributeValue, "totalNetWeight");
|
||||||
|
break;
|
||||||
|
case "总毛重":
|
||||||
|
case "毛重(KG)":
|
||||||
|
case "毛重":
|
||||||
|
setReceiptDetailBigDecimalField(receiptMaterialDetailDO, attributeValue, "totalGrossWeight");
|
||||||
|
break;
|
||||||
|
case "总体积":
|
||||||
|
case "体积(CBM)":
|
||||||
|
case "体积":
|
||||||
|
setReceiptDetailBigDecimalField(receiptMaterialDetailDO, attributeValue, "totalVolume");
|
||||||
|
break;
|
||||||
|
case "总面积":
|
||||||
|
case "面积(SQM)":
|
||||||
|
case "面积":
|
||||||
|
setReceiptDetailBigDecimalField(receiptMaterialDetailDO, attributeValue, "totalArea");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 递归收集收货明细及其子项的所有 uniqueId(用于删除旧批次属性)
|
||||||
|
*/
|
||||||
|
private java.util.Set<Long> collectReceiptDetailUniqueIds(List<ReceiptMaterialDetailDO> list) {
|
||||||
|
java.util.Set<Long> set = new java.util.HashSet<>();
|
||||||
|
if (CollectionUtils.isEmpty(list)) {
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
for (ReceiptMaterialDetailDO d : list) {
|
||||||
|
if (d.getUniqueId() != null) {
|
||||||
|
set.add(d.getUniqueId());
|
||||||
|
}
|
||||||
|
if (!CollectionUtils.isEmpty(d.getChildren())) {
|
||||||
|
set.addAll(collectReceiptDetailUniqueIds(d.getChildren()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从批次属性 attributeValue 解析 BigDecimal 并设置到收货明细对应字段(净重、毛重、体积、面积等)
|
||||||
|
*/
|
||||||
|
private void setReceiptDetailBigDecimalField(ReceiptMaterialDetailDO receiptMaterialDetailDO, String attributeValue, String fieldName) {
|
||||||
|
if (StringUtils.isBlank(attributeValue)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
BigDecimal val = new BigDecimal(attributeValue.trim());
|
||||||
|
switch (fieldName) {
|
||||||
|
case "totalNetWeight":
|
||||||
|
receiptMaterialDetailDO.setTotalNetWeight(val);
|
||||||
|
break;
|
||||||
|
case "totalGrossWeight":
|
||||||
|
receiptMaterialDetailDO.setTotalGrossWeight(val);
|
||||||
|
break;
|
||||||
|
case "totalVolume":
|
||||||
|
receiptMaterialDetailDO.setTotalVolume(val);
|
||||||
|
break;
|
||||||
|
case "totalArea":
|
||||||
|
receiptMaterialDetailDO.setTotalArea(val);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("批次属性数值解析失败,物料:{},字段:{},原始值:{}", receiptMaterialDetailDO.getMaterialName(), fieldName, attributeValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 当 PDA 未传 materialMoreDetailList 时,从 receiptMaterialDetailDO 的 batch_number、batch_ref_no、material_status_code 等字段构建,
|
* 当 PDA 未传 materialMoreDetailList 时,从 receiptMaterialDetailDO 的 batch_number、batch_ref_no、material_status_code 等字段构建,
|
||||||
* 确保更多属性能保存到 material_more_detail 表并正确回显
|
* 确保更多属性能保存到 material_more_detail 表并正确回显
|
||||||
@@ -729,6 +918,12 @@ public class ReceiptMaterialDetailImpl extends ServiceImpl<ReceiptMaterialDetail
|
|||||||
if (CollectionUtils.isEmpty(list)) {
|
if (CollectionUtils.isEmpty(list)) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
// 优先使用 attributeOption(如 BatchRefNo、SheetRefNo),其次 fieldName,最后 batchLabels 兜底映射
|
||||||
|
Map<String, String> attributeOptionToField = new HashMap<>();
|
||||||
|
attributeOptionToField.put("InvoiceNo", "invoiceNo");
|
||||||
|
attributeOptionToField.put("BatchRefNo", "batchRefNo");
|
||||||
|
attributeOptionToField.put("SheetRefNo", "sheetRefNo");
|
||||||
|
attributeOptionToField.put("BoxPalletNo", "boxPalletNo");
|
||||||
Map<String, String> labelToField = new HashMap<>();
|
Map<String, String> labelToField = new HashMap<>();
|
||||||
labelToField.put("Batch Ref NO's", "batchRefNo");
|
labelToField.put("Batch Ref NO's", "batchRefNo");
|
||||||
labelToField.put("Batch Ref NO", "batchRefNo");
|
labelToField.put("Batch Ref NO", "batchRefNo");
|
||||||
@@ -745,6 +940,9 @@ public class ReceiptMaterialDetailImpl extends ServiceImpl<ReceiptMaterialDetail
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
String fieldName = po.getFieldName();
|
String fieldName = po.getFieldName();
|
||||||
|
if (StringUtils.isBlank(fieldName) && StringUtils.isNotBlank(po.getAttributeOption())) {
|
||||||
|
fieldName = attributeOptionToField.get(po.getAttributeOption().trim());
|
||||||
|
}
|
||||||
if (StringUtils.isBlank(fieldName) && StringUtils.isNotBlank(po.getBatchLabels())) {
|
if (StringUtils.isBlank(fieldName) && StringUtils.isNotBlank(po.getBatchLabels())) {
|
||||||
fieldName = labelToField.get(po.getBatchLabels().trim());
|
fieldName = labelToField.get(po.getBatchLabels().trim());
|
||||||
}
|
}
|
||||||
|
|||||||
+35
-40
@@ -215,30 +215,9 @@ public class StockReceiptOrderDomainService {
|
|||||||
Map<Long, List<MaterialMoreDetailPO>> materialMoreDetailMap = materialMoreDetailPOList.stream()
|
Map<Long, List<MaterialMoreDetailPO>> materialMoreDetailMap = materialMoreDetailPOList.stream()
|
||||||
.collect(Collectors.groupingBy(MaterialMoreDetailPO::getMaterialDetailUniqueId));
|
.collect(Collectors.groupingBy(MaterialMoreDetailPO::getMaterialDetailUniqueId));
|
||||||
receiptMaterialDetailPOList.forEach(receiptMaterialDetailPO -> {
|
receiptMaterialDetailPOList.forEach(receiptMaterialDetailPO -> {
|
||||||
List<ReceiptMaterialDetailPO> receiptMaterialDetailPOChildrenNowList = new ArrayList<>();
|
//子集(level 2 的真实子项),PDA 端不添加 parent_copy,与 PC 端一致,避免主项重复展示
|
||||||
//子集(level 2 的真实子项)
|
|
||||||
List<ReceiptMaterialDetailPO> receiptMaterialDetailPOChildrenList = receiptMaterialDetailPO.getChildren();
|
List<ReceiptMaterialDetailPO> receiptMaterialDetailPOChildrenList = receiptMaterialDetailPO.getChildren();
|
||||||
if (CollectionUtils.isEmpty(receiptMaterialDetailPOChildrenList)) {
|
if (!CollectionUtils.isEmpty(receiptMaterialDetailPOChildrenList)) {
|
||||||
//无 level 2 子项时,不添加父级拷贝,避免 PC 端显示重复
|
|
||||||
receiptMaterialDetailPO.setChildren(receiptMaterialDetailPOChildrenNowList);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//有 level 2 子项时,添加父级拷贝(level 1)供 PDA 收货使用
|
|
||||||
ReceiptMaterialDetailPO receiptMaterialDetailPOChildrenNow = new ReceiptMaterialDetailPO();
|
|
||||||
BeanUtils.copyProperties(receiptMaterialDetailPO, receiptMaterialDetailPOChildrenNow, "children");
|
|
||||||
List<InMaterialDetailSerialNumberPO> materialDetailSerialNumberList = inMaterialDetailSerialNumberMap.get(receiptMaterialDetailPO.getUniqueId());
|
|
||||||
if (!CollectionUtils.isEmpty(materialDetailSerialNumberList)) {
|
|
||||||
receiptMaterialDetailPOChildrenNow.setMaterialDetailSerialNumberList(materialDetailSerialNumberList);
|
|
||||||
} else {
|
|
||||||
receiptMaterialDetailPOChildrenNow.setMaterialDetailSerialNumberList(new ArrayList<>());
|
|
||||||
}
|
|
||||||
List<MaterialMoreDetailPO> materialMoreDetailList = materialMoreDetailMap.get(receiptMaterialDetailPO.getUniqueId());
|
|
||||||
if (!CollectionUtils.isEmpty(materialMoreDetailList)) {
|
|
||||||
receiptMaterialDetailPOChildrenNow.setMaterialMoreDetailList(materialMoreDetailList);
|
|
||||||
} else {
|
|
||||||
receiptMaterialDetailPOChildrenNow.setMaterialMoreDetailList(getMaterialMoreDetail(receiptMaterialDetailPO));
|
|
||||||
}
|
|
||||||
receiptMaterialDetailPOChildrenNowList.add(receiptMaterialDetailPOChildrenNow);
|
|
||||||
receiptMaterialDetailPOChildrenList.forEach(receiptMaterialDetailPOChildren -> {
|
receiptMaterialDetailPOChildrenList.forEach(receiptMaterialDetailPOChildren -> {
|
||||||
List<InMaterialDetailSerialNumberPO> materialDetailSerialNumberChildrenList = inMaterialDetailSerialNumberMap.get(receiptMaterialDetailPOChildren.getUniqueId());
|
List<InMaterialDetailSerialNumberPO> materialDetailSerialNumberChildrenList = inMaterialDetailSerialNumberMap.get(receiptMaterialDetailPOChildren.getUniqueId());
|
||||||
if (!CollectionUtils.isEmpty(materialDetailSerialNumberChildrenList)) {
|
if (!CollectionUtils.isEmpty(materialDetailSerialNumberChildrenList)) {
|
||||||
@@ -249,35 +228,49 @@ public class StockReceiptOrderDomainService {
|
|||||||
List<MaterialMoreDetailPO> materialMoreDetailChildrenList = materialMoreDetailMap.get(receiptMaterialDetailPOChildren.getUniqueId());
|
List<MaterialMoreDetailPO> materialMoreDetailChildrenList = materialMoreDetailMap.get(receiptMaterialDetailPOChildren.getUniqueId());
|
||||||
if (!CollectionUtils.isEmpty(materialMoreDetailChildrenList)) {
|
if (!CollectionUtils.isEmpty(materialMoreDetailChildrenList)) {
|
||||||
receiptMaterialDetailPOChildren.setMaterialMoreDetailList(materialMoreDetailChildrenList);
|
receiptMaterialDetailPOChildren.setMaterialMoreDetailList(materialMoreDetailChildrenList);
|
||||||
} else {
|
} else if (CollectionUtils.isEmpty(receiptMaterialDetailPOChildren.getMaterialMoreDetailList())) {
|
||||||
receiptMaterialDetailPOChildren.setMaterialMoreDetailList(getMaterialMoreDetail(receiptMaterialDetailPO));
|
// material_more_detail 表无记录时,queryListChildren 已填充 attributeValue;仅当子项本身无批次属性时才从物料获取
|
||||||
|
receiptMaterialDetailPOChildren.setMaterialMoreDetailList(getMaterialMoreDetail(receiptMaterialDetailPOChildren));
|
||||||
}
|
}
|
||||||
|
// 否则保留 queryListChildren 已填充的 materialMoreDetailList(含 BatchRefNo、SheetRefNo、BoxPalletNo 等 attributeValue)
|
||||||
});
|
});
|
||||||
receiptMaterialDetailPOChildrenNowList.addAll(receiptMaterialDetailPOChildrenList);
|
} else {
|
||||||
receiptMaterialDetailPO.setChildren(receiptMaterialDetailPOChildrenNowList);
|
// 主项无子项时(点击分批收货前):确保主项也有批次属性,否则 PDA 不显示
|
||||||
|
if (CollectionUtils.isEmpty(receiptMaterialDetailPO.getMaterialMoreDetailList())) {
|
||||||
|
receiptMaterialDetailPO.setMaterialMoreDetailList(getMaterialMoreDetail(receiptMaterialDetailPO));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
receiptMaterialDetailPO.setChildren(receiptMaterialDetailPOChildrenList != null ? receiptMaterialDetailPOChildrenList : new ArrayList<>());
|
||||||
});
|
});
|
||||||
stockReceiptOrderPO.setMaterialDetailList(receiptMaterialDetailPOList);
|
stockReceiptOrderPO.setMaterialDetailList(receiptMaterialDetailPOList);
|
||||||
return stockReceiptOrderPO;
|
return stockReceiptOrderPO;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param receiptMaterialDetailPO
|
* 根据物料绑定的批次属性动态获取更多属性(按 materialBaseInfoId,不再使用 MaterialGoodsRule.batchId)
|
||||||
* @return List<MaterialMoreDetail>
|
* @param receiptMaterialDetailPO 收货明细
|
||||||
* @description 获取物料更多属性
|
* @return List<MaterialMoreDetailPO>
|
||||||
* @author ZhouGY
|
|
||||||
* @date 2024/7/3 13:46
|
|
||||||
*/
|
*/
|
||||||
public List<MaterialMoreDetailPO> getMaterialMoreDetail(ReceiptMaterialDetailPO receiptMaterialDetailPO) {
|
public List<MaterialMoreDetailPO> getMaterialMoreDetail(ReceiptMaterialDetailPO receiptMaterialDetailPO) {
|
||||||
MaterialGoodsRule materialGoodsRule = materialGoodsRuleService.getOne(new QueryWrapper<MaterialGoodsRule>().lambda()
|
|
||||||
.eq(MaterialGoodsRule::getMaterialBaseInfoId, receiptMaterialDetailPO.getMaterialBaseInfoId()));
|
|
||||||
List<MaterialMoreDetailPO> materialMoreDetailPOList = new ArrayList<>();
|
List<MaterialMoreDetailPO> materialMoreDetailPOList = new ArrayList<>();
|
||||||
if (materialGoodsRule != null) {
|
Long materialBaseInfoId = receiptMaterialDetailPO != null ? receiptMaterialDetailPO.getMaterialBaseInfoId() : null;
|
||||||
AjaxResult ajaxResult = systemServiceFeign.getBatchDetailListByBatchId(materialGoodsRule.getBatchId());
|
if (materialBaseInfoId == null) {
|
||||||
if (!"200".equals(String.valueOf(ajaxResult.get("code")))) {
|
return materialMoreDetailPOList;
|
||||||
throw new ServiceException("获取批次信息失败");
|
}
|
||||||
|
try {
|
||||||
|
AjaxResult ajaxResult = systemServiceFeign.getBatchDetailListByMaterialBaseInfoId(materialBaseInfoId);
|
||||||
|
if (ajaxResult == null || !"200".equals(String.valueOf(ajaxResult.get("code")))) {
|
||||||
|
return materialMoreDetailPOList;
|
||||||
}
|
}
|
||||||
List<BatchDetailFeignPO> batchDetailFeignPOList = JSON.parseArray(JSONObject.toJSONString(ajaxResult.get("data")), BatchDetailFeignPO.class);
|
List<BatchDetailFeignPO> batchDetailFeignPOList = JSON.parseArray(JSONObject.toJSONString(ajaxResult.get("data")), BatchDetailFeignPO.class);
|
||||||
batchDetailFeignPOList.forEach(batchDetailFeignPO -> {
|
if (CollectionUtils.isEmpty(batchDetailFeignPOList)) {
|
||||||
|
return materialMoreDetailPOList;
|
||||||
|
}
|
||||||
|
// 只保留 isDisplay=1 的批次属性,与 PC 端 getInfo 一致
|
||||||
|
for (BatchDetailFeignPO batchDetailFeignPO : batchDetailFeignPOList) {
|
||||||
|
if (batchDetailFeignPO.getIsDisplay() == null || batchDetailFeignPO.getIsDisplay() != 1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
MaterialMoreDetailPO materialMoreDetailPO = new MaterialMoreDetailPO();
|
MaterialMoreDetailPO materialMoreDetailPO = new MaterialMoreDetailPO();
|
||||||
materialMoreDetailPO.setBatchId(batchDetailFeignPO.getBatchId());
|
materialMoreDetailPO.setBatchId(batchDetailFeignPO.getBatchId());
|
||||||
materialMoreDetailPO.setBatchDetailId(batchDetailFeignPO.getBatchDetailId());
|
materialMoreDetailPO.setBatchDetailId(batchDetailFeignPO.getBatchDetailId());
|
||||||
@@ -286,7 +279,9 @@ public class StockReceiptOrderDomainService {
|
|||||||
materialMoreDetailPO.setAttributeFormat(batchDetailFeignPO.getAttributeFormat());
|
materialMoreDetailPO.setAttributeFormat(batchDetailFeignPO.getAttributeFormat());
|
||||||
materialMoreDetailPO.setAttributeOption(batchDetailFeignPO.getAttributeOption());
|
materialMoreDetailPO.setAttributeOption(batchDetailFeignPO.getAttributeOption());
|
||||||
materialMoreDetailPOList.add(materialMoreDetailPO);
|
materialMoreDetailPOList.add(materialMoreDetailPO);
|
||||||
});
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("获取物料批次属性失败,物料基础信息ID:{},错误:{}", materialBaseInfoId, e.getMessage());
|
||||||
}
|
}
|
||||||
return materialMoreDetailPOList;
|
return materialMoreDetailPOList;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -52,7 +52,7 @@ public class StockReceiptOrderAppApi extends BaseController {
|
|||||||
@ApiOperation("获取收货单")
|
@ApiOperation("获取收货单")
|
||||||
@GetMapping(value = "/getInfoByApp")
|
@GetMapping(value = "/getInfoByApp")
|
||||||
public AjaxResult getInfoByApp(Long receiptOrderId) {
|
public AjaxResult getInfoByApp(Long receiptOrderId) {
|
||||||
return AjaxResult.success(stockReceiptOrderApplicationService.getInfo(receiptOrderId));
|
return AjaxResult.success(stockReceiptOrderApplicationService.getInfoByApp(receiptOrderId));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user