From 04a7dedbcaea57288bd9c748ade8065f8699e61b Mon Sep 17 00:00:00 2001 From: zhou-hongcheng <1064771933@qq.com> Date: Mon, 26 Jan 2026 17:22:27 +0800 Subject: [PATCH 1/8] =?UTF-8?q?=E5=90=8C=E6=AD=A5wms=E7=89=A9=E6=96=99?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=B8=81=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/mhd/system/api/domain/MaterialBaseInfoFeign.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/domain/MaterialBaseInfoFeign.java b/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/domain/MaterialBaseInfoFeign.java index 7f5c9b913..6e8c58bf0 100644 --- a/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/domain/MaterialBaseInfoFeign.java +++ b/mhd-api/mhd-api-system/src/main/java/com/mhd/system/api/domain/MaterialBaseInfoFeign.java @@ -208,5 +208,8 @@ public class MaterialBaseInfoFeign extends BaseVOEntity{ @ApiModelProperty("规格型号") @Excel(name = "规格型号") private String specificationModel; + + @ApiModelProperty("币制") + private String currency; } From 7f35e4b37506308c82a65d1d27515a2121db6ca5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=A6=E9=B8=BF=E5=B1=95?= <18031053041@163.com> Date: Mon, 26 Jan 2026 17:32:23 +0800 Subject: [PATCH 2/8] =?UTF-8?q?=E5=85=A5=E5=BA=93=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../StockInOrderApplicationService.java | 419 +++++++++++++++--- .../po/ReceiptMaterialDetailPO.java | 16 + .../StockReceiptOrderDomainService.java | 24 + .../StockInOrderImportRowDTO.java | 2 +- .../ReceiptMaterialDetailMapper.xml | 14 +- 5 files changed, 415 insertions(+), 60 deletions(-) diff --git a/mhd_wms/src/main/java/com/mhd/wms/application/service/stockInOrder/StockInOrderApplicationService.java b/mhd_wms/src/main/java/com/mhd/wms/application/service/stockInOrder/StockInOrderApplicationService.java index 96e280efb..1442ecc57 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/application/service/stockInOrder/StockInOrderApplicationService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/application/service/stockInOrder/StockInOrderApplicationService.java @@ -8,6 +8,7 @@ import com.mhd.common.core.domain.po.UserPo; import com.mhd.common.core.enums.DictCode; import com.mhd.common.core.exception.ServiceException; import com.mhd.common.core.utils.StringUtils; +import com.mhd.common.core.utils.poi.ExcelUtil; import com.mhd.common.core.web.domain.AjaxResult; import com.mhd.common.security.utils.SecurityUtils; import com.mhd.system.api.SystemServiceFeign; @@ -17,20 +18,20 @@ 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.common.core.utils.poi.ExcelUtil; +import com.mhd.wms.domain.inMaterialDetail.repository.todo.InMaterialDetailDO; +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.stockInOrder.repository.po.StockInOrderPO; import com.mhd.wms.domain.stockInOrder.repository.todo.StockInOrderDO; -import com.mhd.wms.domain.inMaterialDetail.repository.todo.InMaterialDetailDO; import com.mhd.wms.domain.stockInOrder.service.StockInOrderDomainService; -import com.mhd.wms.domain.materialBaseInfo.repository.facade.IMaterialBaseInfoService; -import com.mhd.wms.domain.materialBaseInfo.repository.todo.MaterialBaseInfoDO; -import com.mhd.wms.domain.materialBaseInfo.repository.po.MaterialBaseInfoPO; import com.mhd.wms.interfaces.dto.stockInOrder.StockInOrderImportRowDTO; import lombok.extern.slf4j.Slf4j; import org.apache.poi.ss.usermodel.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; + import java.io.InputStream; import java.math.BigDecimal; import java.text.ParseException; @@ -260,9 +261,9 @@ public class StockInOrderApplicationService { } } // 客户名称 - else if (labelValue.contains("客户名称") && StringUtils.isBlank(headerInfo.getCustomerName())) { + else if (labelValue.contains("客户名称") && StringUtils.isBlank(headerInfo.getShipperName())) { if (!value.contains("客户") && !value.equals("客户名称")) { - headerInfo.setCustomerName(value); + headerInfo.setShipperName(value); log.info("从表头第{}行读取到客户名称: {}", rowIdx + 1, value); } } @@ -318,8 +319,87 @@ public class StockInOrderApplicationService { headerInfo.setContactPerson(value); log.info("从表头第{}行读取到联系人: {}", rowIdx + 1, value); } else if ((labelValue.contains("车型") || labelValue.contains("车牌")) && StringUtils.isBlank(headerInfo.getVehicleInfo())) { - headerInfo.setVehicleInfo(value); - log.info("从表头第{}行读取到车型及车牌: {}", rowIdx + 1, value); + // 过滤掉标签文本(包含冒号、常见标签关键词等) + if (StringUtils.isNotBlank(value) && + !value.contains(":") && !value.contains(":") && + !value.contains("委托编号") && !value.contains("NO") && !value.contains("司机签名") && + !value.contains("完成时间") && !value.contains("下单日期") && !value.contains("入仓日期") && + !value.contains("联系人") && !value.contains("Tel") && !value.contains("Fax") && + !value.contains("客户") && !value.contains("地址") && !value.contains("日期") && + !value.contains("方式") && !value.contains("关区") && !value.contains("关别") && + !value.contains("报关员") && !value.contains("生产商") && !value.contains("承运方") && + !value.contains("柜号") && !value.contains("车型") && !value.contains("车牌")) { + headerInfo.setVehicleInfo(value); + log.info("从表头第{}行读取到车型及车牌: {}", rowIdx + 1, value); + } else { + // 如果找到的值是标签,继续向后查找 + boolean found = false; + boolean stopSearch = false; // 是否遇到下一个标签,需要停止搜索 + for (int searchColIdx = colIdx + 2; searchColIdx < colIdx + 10 && searchColIdx < row.getPhysicalNumberOfCells(); searchColIdx++) { + Cell nextValueCell = row.getCell(searchColIdx); + if (nextValueCell != null) { + String nextValue = getCellValueAsString(nextValueCell); + if (StringUtils.isNotBlank(nextValue)) { + // 检查是否遇到下一个标签(如"委托编号NO"),如果遇到则停止搜索 + if (nextValue.contains("委托编号") || (nextValue.contains("NO") && nextValue.contains(":")) || + nextValue.contains("司机签名") || nextValue.contains("完成时间") || nextValue.contains("下单日期") || + nextValue.contains("入仓日期") || nextValue.contains("联系人") || nextValue.contains("Tel") || + nextValue.contains("Fax") || nextValue.contains("客户名称") || nextValue.contains("送货地址") || + nextValue.contains("申报地关区") || nextValue.contains("进出境关别") || nextValue.contains("起运") || + nextValue.contains("运抵国") || nextValue.contains("柜号") || nextValue.contains("运输方式") || + nextValue.contains("监管方式") || nextValue.contains("海关是否查验货物") || nextValue.contains("报关员")) { + // 遇到下一个标签,停止搜索 + stopSearch = true; + log.warn("表头第{}行,标签'{}'在第{}列,向后搜索到第{}列时遇到下一个标签'{}',停止搜索,车型及车牌字段将保持为空", + rowIdx + 1, labelValue, colIdx + 1, searchColIdx + 1, nextValue); + break; + } + // 跳过标签文本(包含冒号、常见标签关键词等) + if (!nextValue.contains(":") && !nextValue.contains(":") && + !nextValue.contains("委托编号") && !nextValue.contains("NO") && !nextValue.contains("司机签名") && + !nextValue.contains("完成时间") && !nextValue.contains("下单日期") && !nextValue.contains("入仓日期") && + !nextValue.contains("联系人") && !nextValue.contains("Tel") && !nextValue.contains("Fax") && + !nextValue.contains("客户") && !nextValue.contains("地址") && !nextValue.contains("日期") && + !nextValue.contains("方式") && !nextValue.contains("关区") && !nextValue.contains("关别") && + !nextValue.contains("报关员") && !nextValue.contains("生产商") && !nextValue.contains("承运方") && + !nextValue.contains("柜号") && !nextValue.contains("车型") && !nextValue.contains("车牌")) { + headerInfo.setVehicleInfo(nextValue); + log.info("从表头第{}行读取到车型及车牌: {}", rowIdx + 1, nextValue); + found = true; + break; + } + } + } + } + // 如果没找到合适的值且未遇到下一个标签,尝试查找下一行的同一列 + if (!found && !stopSearch) { + Row nextRow = sheet.getRow(rowIdx + 1); + if (nextRow != null) { + Cell nextRowCell = nextRow.getCell(colIdx); + if (nextRowCell != null) { + String nextRowValue = getCellValueAsString(nextRowCell); + if (StringUtils.isNotBlank(nextRowValue) && + !nextRowValue.contains(":") && !nextRowValue.contains(":") && + !nextRowValue.contains("委托编号") && !nextRowValue.contains("NO") && !nextRowValue.contains("司机签名") && + !nextRowValue.contains("完成时间") && !nextRowValue.contains("下单日期") && !nextRowValue.contains("入仓日期") && + !nextRowValue.contains("联系人") && !nextRowValue.contains("Tel") && !nextRowValue.contains("Fax") && + !nextRowValue.contains("客户") && !nextRowValue.contains("地址") && !nextRowValue.contains("日期") && + !nextRowValue.contains("方式") && !nextRowValue.contains("关区") && !nextRowValue.contains("关别") && + !nextRowValue.contains("报关员") && !nextRowValue.contains("生产商") && !nextRowValue.contains("承运方") && + !nextRowValue.contains("柜号") && !nextRowValue.contains("车型") && !nextRowValue.contains("车牌")) { + headerInfo.setVehicleInfo(nextRowValue); + log.info("从表头第{}行(下一行)读取到车型及车牌: {}", rowIdx + 2, nextRowValue); + found = true; + } + } + } + } + // 如果最终都没找到实际的值,不设置字段(保持为空) + if (!found && !stopSearch) { + log.warn("表头第{}行,标签'{}'在第{}列,找到的值是标签'{}',继续向后查找未找到实际值,车型及车牌字段将保持为空", + rowIdx + 1, labelValue, colIdx + 1, value); + } + } } else if ((labelValue.contains("承运方") || labelValue.contains("承运商")) && StringUtils.isBlank(headerInfo.getCarrier())) { headerInfo.setCarrier(value); log.info("从表头第{}行读取到承运方: {}", rowIdx + 1, value); @@ -390,9 +470,15 @@ public class StockInOrderApplicationService { !nextRowValue.contains("报关员") && !nextRowValue.contains("生产商") && !nextRowValue.contains("承运方")) { headerInfo.setCustomsBrokerInfo(nextRowValue); log.info("从表头第{}行(下一行)读取到报关员姓名及联系方式: {}", rowIdx + 2, nextRowValue); + found = true; } } } + // 如果最终都没找到实际的值,不设置字段(保持为空) + if (!found) { + log.warn("表头第{}行,标签'{}'在第{}列,找到的值是标签'{}',继续向后查找未找到实际值,报关员姓名及联系方式字段将保持为空", + rowIdx + 1, labelValue, colIdx + 1, value); + } } } } else if (labelValue.contains("送货地址") && StringUtils.isBlank(headerInfo.getDeliveryAddress())) { @@ -405,8 +491,87 @@ public class StockInOrderApplicationService { headerInfo.setOriginDestinationCountry(value); log.info("从表头第{}行读取到起运/运抵国(地区): {}", rowIdx + 1, value); } else if (labelValue.contains("柜号") && StringUtils.isBlank(headerInfo.getContainerNo())) { - headerInfo.setContainerNo(value); - log.info("从表头第{}行读取到柜号: {}", rowIdx + 1, value); + // 过滤掉标签文本(包含冒号、常见标签关键词等) + if (StringUtils.isNotBlank(value) && + !value.contains(":") && !value.contains(":") && + !value.contains("司机签名") && !value.contains("委托编号") && !value.contains("NO") && + !value.contains("完成时间") && !value.contains("下单日期") && !value.contains("入仓日期") && + !value.contains("联系人") && !value.contains("Tel") && !value.contains("Fax") && + !value.contains("客户") && !value.contains("地址") && !value.contains("日期") && + !value.contains("方式") && !value.contains("关区") && !value.contains("关别") && + !value.contains("报关员") && !value.contains("生产商") && !value.contains("承运方") && + !value.contains("车型") && !value.contains("车牌")) { + headerInfo.setContainerNo(value); + log.info("从表头第{}行读取到柜号: {}", rowIdx + 1, value); + } else { + // 如果找到的值是标签,继续向后查找 + boolean found = false; + boolean stopSearch = false; // 是否遇到下一个标签,需要停止搜索 + for (int searchColIdx = colIdx + 2; searchColIdx < colIdx + 10 && searchColIdx < row.getPhysicalNumberOfCells(); searchColIdx++) { + Cell nextValueCell = row.getCell(searchColIdx); + if (nextValueCell != null) { + String nextValue = getCellValueAsString(nextValueCell); + if (StringUtils.isNotBlank(nextValue)) { + // 检查是否遇到下一个标签(如"委托编号NO"、"司机签名"等),如果遇到则停止搜索 + if (nextValue.contains("委托编号") || (nextValue.contains("NO") && nextValue.contains(":")) || + nextValue.contains("司机签名") || nextValue.contains("完成时间") || nextValue.contains("下单日期") || + nextValue.contains("入仓日期") || nextValue.contains("联系人") || nextValue.contains("Tel") || + nextValue.contains("Fax") || nextValue.contains("客户名称") || nextValue.contains("送货地址") || + nextValue.contains("申报地关区") || nextValue.contains("进出境关别") || nextValue.contains("起运") || + nextValue.contains("运抵国") || nextValue.contains("运输方式") || nextValue.contains("监管方式") || + nextValue.contains("海关是否查验货物") || nextValue.contains("报关员")) { + // 遇到下一个标签,停止搜索 + stopSearch = true; + log.warn("表头第{}行,标签'{}'在第{}列,向后搜索到第{}列时遇到下一个标签'{}',停止搜索,柜号字段将保持为空", + rowIdx + 1, labelValue, colIdx + 1, searchColIdx + 1, nextValue); + break; + } + // 跳过标签文本(包含冒号、常见标签关键词等) + if (!nextValue.contains(":") && !nextValue.contains(":") && + !nextValue.contains("司机签名") && !nextValue.contains("委托编号") && !nextValue.contains("NO") && + !nextValue.contains("完成时间") && !nextValue.contains("下单日期") && !nextValue.contains("入仓日期") && + !nextValue.contains("联系人") && !nextValue.contains("Tel") && !nextValue.contains("Fax") && + !nextValue.contains("客户") && !nextValue.contains("地址") && !nextValue.contains("日期") && + !nextValue.contains("方式") && !nextValue.contains("关区") && !nextValue.contains("关别") && + !nextValue.contains("报关员") && !nextValue.contains("生产商") && !nextValue.contains("承运方") && + !nextValue.contains("车型") && !nextValue.contains("车牌")) { + headerInfo.setContainerNo(nextValue); + log.info("从表头第{}行读取到柜号: {}", rowIdx + 1, nextValue); + found = true; + break; + } + } + } + } + // 如果没找到合适的值且未遇到下一个标签,尝试查找下一行的同一列 + if (!found && !stopSearch) { + Row nextRow = sheet.getRow(rowIdx + 1); + if (nextRow != null) { + Cell nextRowCell = nextRow.getCell(colIdx); + if (nextRowCell != null) { + String nextRowValue = getCellValueAsString(nextRowCell); + if (StringUtils.isNotBlank(nextRowValue) && + !nextRowValue.contains(":") && !nextRowValue.contains(":") && + !nextRowValue.contains("司机签名") && !nextRowValue.contains("委托编号") && !nextRowValue.contains("NO") && + !nextRowValue.contains("完成时间") && !nextRowValue.contains("下单日期") && !nextRowValue.contains("入仓日期") && + !nextRowValue.contains("联系人") && !nextRowValue.contains("Tel") && !nextRowValue.contains("Fax") && + !nextRowValue.contains("客户") && !nextRowValue.contains("地址") && !nextRowValue.contains("日期") && + !nextRowValue.contains("方式") && !nextRowValue.contains("关区") && !nextRowValue.contains("关别") && + !nextRowValue.contains("报关员") && !nextRowValue.contains("生产商") && !nextRowValue.contains("承运方") && + !nextRowValue.contains("车型") && !nextRowValue.contains("车牌")) { + headerInfo.setContainerNo(nextRowValue); + log.info("从表头第{}行(下一行)读取到柜号: {}", rowIdx + 2, nextRowValue); + found = true; + } + } + } + } + // 如果最终都没找到实际的值,不设置字段(保持为空) + if (!found && !stopSearch) { + log.warn("表头第{}行,标签'{}'在第{}列,找到的值是标签'{}',继续向后查找未找到实际值,柜号字段将保持为空", + rowIdx + 1, labelValue, colIdx + 1, value); + } + } } else if (labelValue.contains("运输方式") && StringUtils.isBlank(headerInfo.getTransportMethod())) { headerInfo.setTransportMethod(value); log.info("从表头第{}行读取到运输方式: {}", rowIdx + 1, value); @@ -414,12 +579,99 @@ public class StockInOrderApplicationService { headerInfo.setSupervisionMethod(value); log.info("从表头第{}行读取到监管方式: {}", rowIdx + 1, value); } else if (labelValue.contains("海关是否查验货物")) { - if (value.contains("是") || value.equals("1")) { - headerInfo.setCustomsInspection(1); - } else if (value.contains("否") || value.equals("0")) { - headerInfo.setCustomsInspection(0); + // 过滤掉标签文本(包含冒号、常见标签关键词等) + if (StringUtils.isNotBlank(value) && + !value.contains(":") && !value.contains(":") && + !value.contains("进出境关别") && !value.contains("委托编号") && !value.contains("NO") && + !value.contains("司机签名") && !value.contains("完成时间") && !value.contains("下单日期") && + !value.contains("入仓日期") && !value.contains("联系人") && !value.contains("Tel") && + !value.contains("Fax") && !value.contains("客户") && !value.contains("地址") && + !value.contains("日期") && !value.contains("方式") && !value.contains("关区") && + !value.contains("报关员") && !value.contains("生产商") && !value.contains("承运方") && + !value.contains("车型") && !value.contains("车牌") && !value.contains("柜号")) { + if (value.contains("是") || value.equals("1")) { + headerInfo.setCustomsInspection(1); + } else if (value.contains("否") || value.equals("0")) { + headerInfo.setCustomsInspection(0); + } + log.info("从表头第{}行读取到海关是否查验货物: {}", rowIdx + 1, value); + } else { + // 如果找到的值是标签,继续向后查找 + boolean found = false; + boolean stopSearch = false; // 是否遇到下一个标签,需要停止搜索 + for (int searchColIdx = colIdx + 2; searchColIdx < colIdx + 10 && searchColIdx < row.getPhysicalNumberOfCells(); searchColIdx++) { + Cell nextValueCell = row.getCell(searchColIdx); + if (nextValueCell != null) { + String nextValue = getCellValueAsString(nextValueCell); + if (StringUtils.isNotBlank(nextValue)) { + // 检查是否遇到下一个标签(如"委托编号NO"、"进出境关别"等),如果遇到则停止搜索 + if (nextValue.contains("委托编号") || (nextValue.contains("NO") && nextValue.contains(":")) || + nextValue.contains("司机签名") || nextValue.contains("完成时间") || nextValue.contains("下单日期") || + nextValue.contains("入仓日期") || nextValue.contains("联系人") || nextValue.contains("Tel") || + nextValue.contains("Fax") || nextValue.contains("客户名称") || nextValue.contains("送货地址") || + nextValue.contains("申报地关区") || nextValue.contains("进出境关别") || nextValue.contains("起运") || + nextValue.contains("运抵国") || nextValue.contains("柜号") || nextValue.contains("运输方式") || + nextValue.contains("监管方式") || nextValue.contains("报关员")) { + // 遇到下一个标签,停止搜索 + stopSearch = true; + log.warn("表头第{}行,标签'{}'在第{}列,向后搜索到第{}列时遇到下一个标签'{}',停止搜索,海关是否查验货物字段将保持为空", + rowIdx + 1, labelValue, colIdx + 1, searchColIdx + 1, nextValue); + break; + } + // 跳过标签文本(包含冒号、常见标签关键词等) + if (!nextValue.contains(":") && !nextValue.contains(":") && + !nextValue.contains("进出境关别") && !nextValue.contains("委托编号") && !nextValue.contains("NO") && + !nextValue.contains("司机签名") && !nextValue.contains("完成时间") && !nextValue.contains("下单日期") && + !nextValue.contains("入仓日期") && !nextValue.contains("联系人") && !nextValue.contains("Tel") && + !nextValue.contains("Fax") && !nextValue.contains("客户") && !nextValue.contains("地址") && + !nextValue.contains("日期") && !nextValue.contains("方式") && !nextValue.contains("关区") && + !nextValue.contains("报关员") && !nextValue.contains("生产商") && !nextValue.contains("承运方") && + !nextValue.contains("车型") && !nextValue.contains("车牌") && !nextValue.contains("柜号")) { + if (nextValue.contains("是") || nextValue.equals("1")) { + headerInfo.setCustomsInspection(1); + } else if (nextValue.contains("否") || nextValue.equals("0")) { + headerInfo.setCustomsInspection(0); + } + log.info("从表头第{}行读取到海关是否查验货物: {}", rowIdx + 1, nextValue); + found = true; + break; + } + } + } + } + // 如果没找到合适的值且未遇到下一个标签,尝试查找下一行的同一列 + if (!found && !stopSearch) { + Row nextRow = sheet.getRow(rowIdx + 1); + if (nextRow != null) { + Cell nextRowCell = nextRow.getCell(colIdx); + if (nextRowCell != null) { + String nextRowValue = getCellValueAsString(nextRowCell); + if (StringUtils.isNotBlank(nextRowValue) && + !nextRowValue.contains(":") && !nextRowValue.contains(":") && + !nextRowValue.contains("进出境关别") && !nextRowValue.contains("委托编号") && !nextRowValue.contains("NO") && + !nextRowValue.contains("司机签名") && !nextRowValue.contains("完成时间") && !nextRowValue.contains("下单日期") && + !nextRowValue.contains("入仓日期") && !nextRowValue.contains("联系人") && !nextRowValue.contains("Tel") && + !nextRowValue.contains("Fax") && !nextRowValue.contains("客户") && !nextRowValue.contains("地址") && + !nextRowValue.contains("日期") && !nextRowValue.contains("方式") && !nextRowValue.contains("关区") && + !nextRowValue.contains("报关员") && !nextRowValue.contains("生产商") && !nextRowValue.contains("承运方") && + !nextRowValue.contains("车型") && !nextRowValue.contains("车牌") && !nextRowValue.contains("柜号")) { + if (nextRowValue.contains("是") || nextRowValue.equals("1")) { + headerInfo.setCustomsInspection(1); + } else if (nextRowValue.contains("否") || nextRowValue.equals("0")) { + headerInfo.setCustomsInspection(0); + } + log.info("从表头第{}行(下一行)读取到海关是否查验货物: {}", rowIdx + 2, nextRowValue); + found = true; + } + } + } + } + // 如果最终都没找到实际的值,不设置字段(保持为空) + if (!found && !stopSearch) { + log.warn("表头第{}行,标签'{}'在第{}列,找到的值是标签'{}',继续向后查找未找到实际值,海关是否查验货物字段将保持为空", + rowIdx + 1, labelValue, colIdx + 1, value); + } } - log.info("从表头第{}行读取到海关是否查验货物: {}", rowIdx + 1, value); } else if (labelValue.contains("是否需要报关")) { if (value.contains("是") || value.equals("1")) { headerInfo.setNeedCustomsDeclaration(1); @@ -449,28 +701,44 @@ public class StockInOrderApplicationService { } else { // 如果找到的值是标签,继续向后查找 boolean found = false; + boolean stopSearch = false; // 是否遇到下一个标签,需要停止搜索 for (int searchColIdx = colIdx + 2; searchColIdx < colIdx + 10 && searchColIdx < row.getPhysicalNumberOfCells(); searchColIdx++) { Cell nextValueCell = row.getCell(searchColIdx); if (nextValueCell != null) { String nextValue = getCellValueAsString(nextValueCell); - // 跳过标签文本(包含冒号、常见标签关键词等) - if (StringUtils.isNotBlank(nextValue) && - !nextValue.contains(":") && !nextValue.contains(":") && - !nextValue.contains("下单日期") && !nextValue.contains("入仓日期") && - !nextValue.contains("起运") && !nextValue.contains("运抵国") && !nextValue.contains("地区") && - !nextValue.contains("联系人") && !nextValue.contains("Tel") && !nextValue.contains("Fax") && - !nextValue.contains("客户") && !nextValue.contains("地址") && !nextValue.contains("日期") && - !nextValue.contains("方式") && !nextValue.contains("关区") && !nextValue.contains("关别") && - !nextValue.contains("报关员") && !nextValue.contains("生产商") && !nextValue.contains("承运方")) { - headerInfo.setCompletionTime(nextValue); - log.info("从表头第{}行读取到完成时间: {}", rowIdx + 1, nextValue); - found = true; - break; + if (StringUtils.isNotBlank(nextValue)) { + // 检查是否遇到下一个标签(如"委托编号NO"、"下单日期"等),如果遇到则停止搜索 + if (nextValue.contains("委托编号") || (nextValue.contains("NO") && nextValue.contains(":")) || + nextValue.contains("司机签名") || nextValue.contains("下单日期") || + nextValue.contains("入仓日期") || nextValue.contains("联系人") || nextValue.contains("Tel") || + nextValue.contains("Fax") || nextValue.contains("客户名称") || nextValue.contains("送货地址") || + nextValue.contains("申报地关区") || nextValue.contains("进出境关别") || nextValue.contains("起运") || + nextValue.contains("运抵国") || nextValue.contains("柜号") || nextValue.contains("运输方式") || + nextValue.contains("监管方式") || nextValue.contains("海关是否查验货物") || nextValue.contains("报关员")) { + // 遇到下一个标签,停止搜索 + stopSearch = true; + log.warn("表头第{}行,标签'{}'在第{}列,向后搜索到第{}列时遇到下一个标签'{}',停止搜索,完成时间字段将保持为空", + rowIdx + 1, labelValue, colIdx + 1, searchColIdx + 1, nextValue); + break; + } + // 跳过标签文本(包含冒号、常见标签关键词等) + if (!nextValue.contains(":") && !nextValue.contains(":") && + !nextValue.contains("下单日期") && !nextValue.contains("入仓日期") && + !nextValue.contains("起运") && !nextValue.contains("运抵国") && !nextValue.contains("地区") && + !nextValue.contains("联系人") && !nextValue.contains("Tel") && !nextValue.contains("Fax") && + !nextValue.contains("客户") && !nextValue.contains("地址") && !nextValue.contains("日期") && + !nextValue.contains("方式") && !nextValue.contains("关区") && !nextValue.contains("关别") && + !nextValue.contains("报关员") && !nextValue.contains("生产商") && !nextValue.contains("承运方")) { + headerInfo.setCompletionTime(nextValue); + log.info("从表头第{}行读取到完成时间: {}", rowIdx + 1, nextValue); + found = true; + break; + } } } } - // 如果没找到合适的值,尝试查找下一行的同一列 - if (!found) { + // 如果没找到合适的值且未遇到下一个标签,尝试查找下一行的同一列 + if (!found && !stopSearch) { Row nextRow = sheet.getRow(rowIdx + 1); if (nextRow != null) { Cell nextRowCell = nextRow.getCell(colIdx); @@ -486,10 +754,16 @@ public class StockInOrderApplicationService { !nextRowValue.contains("报关员") && !nextRowValue.contains("生产商") && !nextRowValue.contains("承运方")) { headerInfo.setCompletionTime(nextRowValue); log.info("从表头第{}行(下一行)读取到完成时间: {}", rowIdx + 2, nextRowValue); + found = true; } } } } + // 如果最终都没找到实际的值,不设置字段(保持为空) + if (!found && !stopSearch) { + log.warn("表头第{}行,标签'{}'在第{}列,找到的值是标签'{}',继续向后查找未找到实际值,完成时间字段将保持为空", + rowIdx + 1, labelValue, colIdx + 1, value); + } } } else if (labelValue.contains("下单日期") && StringUtils.isBlank(headerInfo.getOrderDate())) { // 过滤掉标签文本(包含冒号、常见标签关键词等) @@ -506,28 +780,44 @@ public class StockInOrderApplicationService { } else { // 如果找到的值是标签,继续向后查找 boolean found = false; + boolean stopSearch = false; // 是否遇到下一个标签,需要停止搜索 for (int searchColIdx = colIdx + 2; searchColIdx < colIdx + 10 && searchColIdx < row.getPhysicalNumberOfCells(); searchColIdx++) { Cell nextValueCell = row.getCell(searchColIdx); if (nextValueCell != null) { String nextValue = getCellValueAsString(nextValueCell); - // 跳过标签文本(包含冒号、常见标签关键词等) - if (StringUtils.isNotBlank(nextValue) && - !nextValue.contains(":") && !nextValue.contains(":") && - !nextValue.contains("起运") && !nextValue.contains("运抵国") && !nextValue.contains("地区") && - !nextValue.contains("完成时间") && !nextValue.contains("入仓日期") && - !nextValue.contains("联系人") && !nextValue.contains("Tel") && !nextValue.contains("Fax") && - !nextValue.contains("客户") && !nextValue.contains("地址") && !nextValue.contains("日期") && - !nextValue.contains("方式") && !nextValue.contains("关区") && !nextValue.contains("关别") && - !nextValue.contains("报关员") && !nextValue.contains("生产商") && !nextValue.contains("承运方")) { - headerInfo.setOrderDate(nextValue); - log.info("从表头第{}行读取到下单日期: {}", rowIdx + 1, nextValue); - found = true; - break; + if (StringUtils.isNotBlank(nextValue)) { + // 检查是否遇到下一个标签(如"委托编号NO"、"起运/运抵国"等),如果遇到则停止搜索 + if (nextValue.contains("委托编号") || (nextValue.contains("NO") && nextValue.contains(":")) || + nextValue.contains("司机签名") || nextValue.contains("完成时间") || + nextValue.contains("入仓日期") || nextValue.contains("联系人") || nextValue.contains("Tel") || + nextValue.contains("Fax") || nextValue.contains("客户名称") || nextValue.contains("送货地址") || + nextValue.contains("申报地关区") || nextValue.contains("进出境关别") || nextValue.contains("起运") || + nextValue.contains("运抵国") || nextValue.contains("柜号") || nextValue.contains("运输方式") || + nextValue.contains("监管方式") || nextValue.contains("海关是否查验货物") || nextValue.contains("报关员")) { + // 遇到下一个标签,停止搜索 + stopSearch = true; + log.warn("表头第{}行,标签'{}'在第{}列,向后搜索到第{}列时遇到下一个标签'{}',停止搜索,下单日期字段将保持为空", + rowIdx + 1, labelValue, colIdx + 1, searchColIdx + 1, nextValue); + break; + } + // 跳过标签文本(包含冒号、常见标签关键词等) + if (!nextValue.contains(":") && !nextValue.contains(":") && + !nextValue.contains("起运") && !nextValue.contains("运抵国") && !nextValue.contains("地区") && + !nextValue.contains("完成时间") && !nextValue.contains("入仓日期") && + !nextValue.contains("联系人") && !nextValue.contains("Tel") && !nextValue.contains("Fax") && + !nextValue.contains("客户") && !nextValue.contains("地址") && !nextValue.contains("日期") && + !nextValue.contains("方式") && !nextValue.contains("关区") && !nextValue.contains("关别") && + !nextValue.contains("报关员") && !nextValue.contains("生产商") && !nextValue.contains("承运方")) { + headerInfo.setOrderDate(nextValue); + log.info("从表头第{}行读取到下单日期: {}", rowIdx + 1, nextValue); + found = true; + break; + } } } } - // 如果没找到合适的值,尝试查找下一行的同一列 - if (!found) { + // 如果没找到合适的值且未遇到下一个标签,尝试查找下一行的同一列 + if (!found && !stopSearch) { Row nextRow = sheet.getRow(rowIdx + 1); if (nextRow != null) { Cell nextRowCell = nextRow.getCell(colIdx); @@ -543,10 +833,16 @@ public class StockInOrderApplicationService { !nextRowValue.contains("报关员") && !nextRowValue.contains("生产商") && !nextRowValue.contains("承运方")) { headerInfo.setOrderDate(nextRowValue); log.info("从表头第{}行(下一行)读取到下单日期: {}", rowIdx + 2, nextRowValue); + found = true; } } } } + // 如果最终都没找到实际的值,不设置字段(保持为空) + if (!found && !stopSearch) { + log.warn("表头第{}行,标签'{}'在第{}列,找到的值是标签'{}',继续向后查找未找到实际值,下单日期字段将保持为空", + rowIdx + 1, labelValue, colIdx + 1, value); + } } } else if (labelValue.contains("备注") && StringUtils.isBlank(headerInfo.getRemark())) { headerInfo.setRemark(value); @@ -559,7 +855,7 @@ public class StockInOrderApplicationService { } } log.info("表头信息读取完成 - 委托编号NO: {}, 客户名称: {}, To: {}, 联系人: {}, Tel: {}, Fax: {}, 送货地址: {}, 起运/运抵国: {}, 车型及车牌: {}, 承运方: {}, 司机签名: {}, 入仓日期: {}, 申报地关区: {}, 生产商: {}, 报关员: {}, 完成时间: {}, 进出境关别: {}, 下单日期: {}, 备注: {}", - headerInfo.getConsignmentNo(), headerInfo.getCustomerName(), headerInfo.getTo(), + headerInfo.getConsignmentNo(), headerInfo.getShipperName(), headerInfo.getTo(), headerInfo.getContactPerson(), headerInfo.getTel(), headerInfo.getFax(), headerInfo.getDeliveryAddress(), headerInfo.getOriginDestinationCountry(), headerInfo.getVehicleInfo(), headerInfo.getCarrier(), headerInfo.getDriverSignature(), @@ -573,7 +869,7 @@ public class StockInOrderApplicationService { // 为了兼容旧代码,保留这两个变量 String headerConsignmentNo = headerInfo.getConsignmentNo(); - String headerCustomerName = headerInfo.getCustomerName(); + String headerCustomerName = headerInfo.getShipperName(); // 先读取Excel第13行的列名,用于调试 try (InputStream isForDebug = file.getInputStream()) { @@ -635,8 +931,8 @@ public class StockInOrderApplicationService { row.setConsignmentNo(headerInfo.getConsignmentNo()); } // 应用表头中的客户名称(表头有客户名称时,强制应用到所有明细行) - if (StringUtils.isNotBlank(headerInfo.getCustomerName())) { - row.setCustomerName(headerInfo.getCustomerName()); + if (StringUtils.isNotBlank(headerInfo.getShipperName())) { + row.setShipperName(headerInfo.getShipperName()); } // 应用其他表头字段(如果明细行为空,则使用表头值) if (StringUtils.isBlank(row.getTo()) && StringUtils.isNotBlank(headerInfo.getTo())) { @@ -739,13 +1035,13 @@ public class StockInOrderApplicationService { warehouseId = associationWarehouseCacheDO.getWarehouseId(); // 客户名称应该从表头获取(优先使用表头,如果表头为空则使用明细行) - String customerName = StringUtils.isNotBlank(headerInfo.getCustomerName()) ? headerInfo.getCustomerName() : h.getCustomerName(); + String customerName = StringUtils.isNotBlank(headerInfo.getShipperName()) ? headerInfo.getShipperName() : h.getShipperName(); if (StringUtils.isBlank(customerName)) { throw new ServiceException("导入失败:客户名称不能为空(委托编号NO=" + h.getConsignmentNo() + ")。请确保Excel表头(第1-12行)中包含'客户名称'字段"); } // 如果明细行的客户名称为空,使用表头的客户名称 - if (StringUtils.isBlank(h.getCustomerName()) && StringUtils.isNotBlank(headerInfo.getCustomerName())) { - h.setCustomerName(headerInfo.getCustomerName()); + if (StringUtils.isBlank(h.getShipperName()) && StringUtils.isNotBlank(headerInfo.getShipperName())) { + h.setShipperName(headerInfo.getShipperName()); } StockInOrderDO order = new StockInOrderDO(); @@ -764,8 +1060,8 @@ public class StockInOrderApplicationService { setWarehouseInfo(order); // 货主ID不需要,直接设置为null,使用客户名称作为货主名称 order.setShipperId(null); - if (StringUtils.isNotBlank(h.getCustomerName())) { - order.setShipperName(h.getCustomerName()); + if (StringUtils.isNotBlank(h.getShipperName())) { + order.setShipperName(h.getShipperName()); } // order.setSupplierId(h.getSupplierId()); // order.setOrderTypeCode(h.getOrderTypeCode()); @@ -935,6 +1231,9 @@ public class StockInOrderApplicationService { InMaterialDetailDO d = new InMaterialDetailDO(); d.setMaterialBaseInfoId(materialBaseInfoId); + // 设置商品名称和料号(从Excel读取) + d.setMaterialName(r.getMaterialName()); + d.setMaterialCode(r.getMaterialCode()); d.setQuantity(quantity); d.setSpecificationModel(r.getSpecificationModel()); d.setSkuCode(r.getSkuCode()); @@ -945,7 +1244,15 @@ public class StockInOrderApplicationService { d.setBoxCount(r.getBoxCount()); d.setPieceCount(r.getPieceCount()); d.setDimensions(r.getDimensions()); - d.setInboundQuantity(r.getInboundQuantity()); + // 入库数量:优先使用入库数量,如果为空则使用仓库数量 + BigDecimal inboundQuantity = r.getInboundQuantity(); + if (inboundQuantity == null) { + inboundQuantity = r.getWarehouseQuantity(); + if (inboundQuantity != null) { + log.info("入库数量为空,使用仓库数量作为入库数量: [{}]", inboundQuantity); + } + } + d.setInboundQuantity(inboundQuantity); // 单位:优先使用"单位"字段,如果为空则使用"申报单位" String unit = StringUtils.isNotBlank(r.getUnit()) ? r.getUnit() : null; if (StringUtils.isBlank(unit) && StringUtils.isNotBlank(r.getDeclarationUnit())) { diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/repository/po/ReceiptMaterialDetailPO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/repository/po/ReceiptMaterialDetailPO.java index 2d68494c2..764fb4c11 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/repository/po/ReceiptMaterialDetailPO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/repository/po/ReceiptMaterialDetailPO.java @@ -216,6 +216,22 @@ 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("物料明细子集") private List children; diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/service/StockReceiptOrderDomainService.java b/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/service/StockReceiptOrderDomainService.java index 984567fcb..21c948911 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/service/StockReceiptOrderDomainService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/service/StockReceiptOrderDomainService.java @@ -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; @@ -703,6 +704,26 @@ public class StockReceiptOrderDomainService { List receiptMaterialDetailPOS = receiptMaterialDetailService.queryList(receiptMaterialDetailDO); //上架单明细集合 List shelfMaterialDetailDOList = new ArrayList<>(); + // 批量查询入库单明细,用于获取净重、毛重、体积、面积等字段 + List inUniqueIds = receiptMaterialDetailPOS.stream() + .filter(r -> 2 == r.getGenStockShelf() && r.getInUniqueId() != null) + .map(ReceiptMaterialDetailPO::getInUniqueId) + .distinct() + .collect(Collectors.toList()); + Map inMaterialDetailMap = new HashMap<>(); + if (!CollectionUtils.isEmpty(inUniqueIds)) { + // 使用 MyBatis-Plus 的 QueryWrapper 批量查询入库单明细 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.in("unique_id", inUniqueIds); + queryWrapper.eq("del_flag", 1); + List 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 +731,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()); } diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockInOrder/StockInOrderImportRowDTO.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockInOrder/StockInOrderImportRowDTO.java index d0141287d..ec470acd3 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockInOrder/StockInOrderImportRowDTO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockInOrder/StockInOrderImportRowDTO.java @@ -68,7 +68,7 @@ public class StockInOrderImportRowDTO { // 客户名称只在表头中,明细行不需要此字段(代码会从表头读取并应用到此字段) @Excel(name = "客户名称") - private String customerName; + private String shipperName; @Excel(name = "承运商") private String carrier; diff --git a/mhd_wms/src/main/resources/mapper/receiptMaterialDetail/ReceiptMaterialDetailMapper.xml b/mhd_wms/src/main/resources/mapper/receiptMaterialDetail/ReceiptMaterialDetailMapper.xml index 31f4faf9a..9d04c9a7a 100644 --- a/mhd_wms/src/main/resources/mapper/receiptMaterialDetail/ReceiptMaterialDetailMapper.xml +++ b/mhd_wms/src/main/resources/mapper/receiptMaterialDetail/ReceiptMaterialDetailMapper.xml @@ -56,11 +56,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + + + + - select MATERIAL_DETAIL_ID, ORGANIZATION_ID, ORGANIZATION_NAME, TOP_ORGANIZATION_ID, UNIQUE_ID, RECEIPT_ORDER_NUMBER, MATERIAL_BASE_INFO_ID, MATERIAL_CODE, MATERIAL_NAME, BAR_CODE, QUANTITY, ALREADY_RECEIPT_QUANTITY, RECEIPT_QUANTITY, RECEIPT_STATUS, PACK_ID, PACK_CODE, PACK_NAME, PACK_DETAIL_ID, UNIT_CODE, UNIT_NAME, UNIT_NUMBER, MATERIAL_WAREHOUSE_CONTROL_ID, SERIAL_NUMBER_MANAGE, QUALITY_INSPECTION_MANAGE, QUALITY_INSPECTION_STAGE, QUALITY_INSPECTION_RULE, QUALITY_INSPECTION_RATIO, QUALITY_INSPECTION_TERM, QUALITY_INSPECTION_RESULTS, ALLOW_OVERCHARGE, OVERCHARGE_RATIO, BATCH_NUMBER, MATERIAL_STATUS_CODE, MATERIAL_STATUS_NAME, DISTRIBUTE_RULE_ID, DISTRIBUTE_RULE_CODE, DISTRIBUTE_RULE_NAME, CONTAINER_ID, CONTAINER_CODE, CONTAINER_TYPE, CONTAINER_TYPE_NAME, LEVEL, PARENT_UNIQUE_ID, IN_UNIQUE_ID, ALLOW_MODIFY, REMARK, CREATE_TIME, CREATE_BY, CREATE_BY_NAME, UPDATE_TIME, UPDATE_BY, UPDATE_BY_NAME, GEN_STOCK_SHELF, DEL_FLAG from RECEIPT_MATERIAL_DETAIL + select a.MATERIAL_DETAIL_ID, a.ORGANIZATION_ID, a.ORGANIZATION_NAME, a.TOP_ORGANIZATION_ID, a.UNIQUE_ID, a.RECEIPT_ORDER_NUMBER, a.MATERIAL_BASE_INFO_ID, a.MATERIAL_CODE, a.MATERIAL_NAME, a.BAR_CODE, a.QUANTITY, a.ALREADY_RECEIPT_QUANTITY, a.RECEIPT_QUANTITY, a.RECEIPT_STATUS, a.PACK_ID, a.PACK_CODE, a.PACK_NAME, a.PACK_DETAIL_ID, a.UNIT_CODE, a.UNIT_NAME, a.UNIT_NUMBER, a.MATERIAL_WAREHOUSE_CONTROL_ID, a.SERIAL_NUMBER_MANAGE, a.QUALITY_INSPECTION_MANAGE, a.QUALITY_INSPECTION_STAGE, a.QUALITY_INSPECTION_RULE, a.QUALITY_INSPECTION_RATIO, a.QUALITY_INSPECTION_TERM, a.QUALITY_INSPECTION_RESULTS, a.ALLOW_OVERCHARGE, a.OVERCHARGE_RATIO, a.BATCH_NUMBER, a.MATERIAL_STATUS_CODE, a.MATERIAL_STATUS_NAME, a.DISTRIBUTE_RULE_ID, a.DISTRIBUTE_RULE_CODE, a.DISTRIBUTE_RULE_NAME, a.CONTAINER_ID, a.CONTAINER_CODE, a.CONTAINER_TYPE, a.CONTAINER_TYPE_NAME, a.LEVEL, a.PARENT_UNIQUE_ID, a.IN_UNIQUE_ID, a.ALLOW_MODIFY, a.REMARK, a.CREATE_TIME, a.CREATE_BY, a.CREATE_BY_NAME, a.UPDATE_TIME, a.UPDATE_BY, a.UPDATE_BY_NAME, a.GEN_STOCK_SHELF, a.DEL_FLAG, + b.TOTAL_NET_WEIGHT, b.TOTAL_GROSS_WEIGHT, b.TOTAL_VOLUME, b.TOTAL_AREA + from RECEIPT_MATERIAL_DETAIL a + LEFT JOIN IN_MATERIAL_DETAIL b ON a.IN_UNIQUE_ID = b.UNIQUE_ID AND b.DEL_FLAG = 1 @@ -212,8 +220,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - and del_flag = #{delFlag} - and del_flag = 1 + and a.del_flag = #{delFlag} + and a.del_flag = 1 From 18d479b55e74e52494a5a3e2513aa28d1ca5ceab Mon Sep 17 00:00:00 2001 From: zhou-hongcheng <1064771933@qq.com> Date: Tue, 27 Jan 2026 09:25:22 +0800 Subject: [PATCH 3/8] =?UTF-8?q?=E7=A7=BB=E4=BD=8D=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BF=9D=E5=AD=98bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../shiftManage/repository/persistence/ShiftManageImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/shiftManage/repository/persistence/ShiftManageImpl.java b/mhd_wms/src/main/java/com/mhd/wms/domain/shiftManage/repository/persistence/ShiftManageImpl.java index 2f52486c6..4a8a21958 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/shiftManage/repository/persistence/ShiftManageImpl.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/shiftManage/repository/persistence/ShiftManageImpl.java @@ -129,7 +129,7 @@ public class ShiftManageImpl extends ServiceImpl shiftMaterialDetailList.add(shiftMaterialDetail); }); iShiftMaterialDetailService.saveBatch(shiftMaterialDetailList); - return this.save(shiftManage); + return this.updateById(shiftManage); } /** From 2afe2061aff4439decb9e656b8dac07d508edcd7 Mon Sep 17 00:00:00 2001 From: zhou-hongcheng <1064771933@qq.com> Date: Tue, 27 Jan 2026 10:00:39 +0800 Subject: [PATCH 4/8] =?UTF-8?q?=E7=A7=BB=E4=BD=8D=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E7=A7=BB=E4=BD=8D=E6=95=B0=E9=87=8F=E8=B5=8B=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/shiftManage/ShiftManageApplicationService.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mhd_wms/src/main/java/com/mhd/wms/application/service/shiftManage/ShiftManageApplicationService.java b/mhd_wms/src/main/java/com/mhd/wms/application/service/shiftManage/ShiftManageApplicationService.java index 3a5477376..5af67514e 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/application/service/shiftManage/ShiftManageApplicationService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/application/service/shiftManage/ShiftManageApplicationService.java @@ -242,6 +242,8 @@ public class ShiftManageApplicationService { if (shiftMaterialDetailPO == null){ throw new ServiceException("物料明细不存在"); } + //ShiftQuantity前端传过来是0 他那边不好赋值 和Quantity参数统一 + shiftMaterialDetailDO.setShiftQuantity(shiftMaterialDetailDO.getQuantity()); if (shiftMaterialDetailDO.getShiftQuantity().compareTo(BigDecimal.ZERO) == 0){ //未进行移位直接跳过 continue; From 714bb1cce4817b7e4e696f35069bf31b992c7af6 Mon Sep 17 00:00:00 2001 From: zhou-hongcheng <1064771933@qq.com> Date: Tue, 27 Jan 2026 10:24:01 +0800 Subject: [PATCH 5/8] =?UTF-8?q?=E7=9B=98=E7=82=B9=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E7=BC=96=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../persistence/InvestigationManageImpl.java | 38 ++++++++++++++++--- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/investigationManage/repository/persistence/InvestigationManageImpl.java b/mhd_wms/src/main/java/com/mhd/wms/domain/investigationManage/repository/persistence/InvestigationManageImpl.java index d2e5f66e5..f0a3565de 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/investigationManage/repository/persistence/InvestigationManageImpl.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/investigationManage/repository/persistence/InvestigationManageImpl.java @@ -134,11 +134,39 @@ public class InvestigationManageImpl extends ServiceImpl investigetionManageDetailList = investigationManage.getInvestigetionManageDetailList(); - Long[] ids = new Long[investigetionManageDetailList.size()]; - for (int i = 0; i < investigetionManageDetailList.size(); i++) { - ids[i] = investigetionManageDetailList.get(i).getInvestigationManageDetailId(); - } - investigetionManageDetailService.delete(ids); +// Long[] ids = new Long[investigetionManageDetailList.size()]; +// for (int i = 0; i < investigetionManageDetailList.size(); i++) { +// ids[i] = investigetionManageDetailList.get(i).getInvestigationManageDetailId(); +// } +// investigetionManageDetailService.delete(ids); + List updateList = investigetionManageDetailList.stream().filter(detail -> + detail.getInvestigationManageDetailId() != null).collect(Collectors.toList()); + investigetionManageDetailService.updateBatchById(updateList); + + List 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); } From d25a957f13fd84fe7eddb934a130d93ba6e4b853 Mon Sep 17 00:00:00 2001 From: zhou-hongcheng <1064771933@qq.com> Date: Tue, 27 Jan 2026 10:37:11 +0800 Subject: [PATCH 6/8] =?UTF-8?q?=E7=9B=98=E7=82=B9=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=88=A0=E9=99=A4=E5=AD=90=E9=A1=B9bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../persistence/InvestigationManageImpl.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/investigationManage/repository/persistence/InvestigationManageImpl.java b/mhd_wms/src/main/java/com/mhd/wms/domain/investigationManage/repository/persistence/InvestigationManageImpl.java index f0a3565de..738d92dd5 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/investigationManage/repository/persistence/InvestigationManageImpl.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/investigationManage/repository/persistence/InvestigationManageImpl.java @@ -134,10 +134,14 @@ public class InvestigationManageImpl extends ServiceImpl investigetionManageDetailList = investigationManage.getInvestigetionManageDetailList(); -// Long[] ids = new Long[investigetionManageDetailList.size()]; -// for (int i = 0; i < investigetionManageDetailList.size(); i++) { -// ids[i] = investigetionManageDetailList.get(i).getInvestigationManageDetailId(); -// } + Long[] ids = new Long[investigetionManageDetailList.size()]; + for (int i = 0; i < investigetionManageDetailList.size(); i++) { + ids[i] = investigetionManageDetailList.get(i).getInvestigationManageDetailId(); + } + LambdaQueryWrapper detailLambdaQueryWrapper = new LambdaQueryWrapper() + .eq(InvestigetionManageDetail::getInvestigationNumber, investigationManage.getInvestigationNumber()) + .notIn(InvestigetionManageDetail::getInvestigationManageDetailId, ids); + investigetionManageDetailService.remove(detailLambdaQueryWrapper); // investigetionManageDetailService.delete(ids); List updateList = investigetionManageDetailList.stream().filter(detail -> detail.getInvestigationManageDetailId() != null).collect(Collectors.toList()); From 15b5c5443d0d15ac85effb25481090def02615a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=A6=E9=B8=BF=E5=B1=95?= <18031053041@163.com> Date: Tue, 27 Jan 2026 13:50:19 +0800 Subject: [PATCH 7/8] =?UTF-8?q?=E5=85=A5=E5=BA=93=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E4=BF=AE=E6=94=B9bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../StockInOrderApplicationService.java | 79 +++++++- .../entity/InMaterialDetail.java | 4 - .../ReceiptMaterialDetailImpl.java | 132 ++++++++++++- .../po/ReceiptMaterialDetailPO.java | 16 ++ .../StockReceiptOrderDomainService.java | 179 ++++++++++++++++++ .../service/StockShelfOrderDomainService.java | 21 +- .../InventoryStandingReportMapper.xml | 3 +- .../ReceiptMaterialDetailMapper.xml | 8 +- 8 files changed, 421 insertions(+), 21 deletions(-) diff --git a/mhd_wms/src/main/java/com/mhd/wms/application/service/stockInOrder/StockInOrderApplicationService.java b/mhd_wms/src/main/java/com/mhd/wms/application/service/stockInOrder/StockInOrderApplicationService.java index 1442ecc57..59c8600aa 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/application/service/stockInOrder/StockInOrderApplicationService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/application/service/stockInOrder/StockInOrderApplicationService.java @@ -1439,17 +1439,86 @@ public class StockInOrderApplicationService { * @param stockInOrderDO */ private void shipperParam(StockInOrderDO stockInOrderDO){ - if (stockInOrderDO.getShipperId() == null) { - throw new ServiceException("货主ID不能为空(货主信息就是客户)"); + Long shipperId = stockInOrderDO.getShipperId(); + String shipperName = stockInOrderDO.getShipperName(); + String shipperCode = stockInOrderDO.getShipperCode(); + + // 如果货主ID为空,尝试根据货主名称或编号查找 + if (shipperId == null) { + if (StringUtils.isNotEmpty(shipperName) || StringUtils.isNotEmpty(shipperCode)) { + // 尝试从货主列表中查找 + try { + AjaxResult shipperListResult = userServiceFeign.userShipperListAll(); + if ("200".equals(String.valueOf(shipperListResult.get("code"))) && shipperListResult.get("data") != null) { + Object data = shipperListResult.get("data"); + List> shipperList = null; + // 尝试解析为列表 + if (data instanceof List) { + @SuppressWarnings("unchecked") + List rawList = (List) data; + shipperList = new ArrayList<>(); + for (Object item : rawList) { + if (item instanceof Map) { + @SuppressWarnings("unchecked") + Map mapItem = (Map) item; + shipperList.add(mapItem); + } else { + // 如果不是Map,尝试转换为Map + Map mapItem = JSON.parseObject(JSONObject.toJSONString(item), Map.class); + shipperList.add(mapItem); + } + } + } else { + // 如果不是列表,尝试转换为列表 + String jsonStr = JSONObject.toJSONString(data); + shipperList = JSON.parseObject(jsonStr, new com.alibaba.fastjson.TypeReference>>(){}); + } + if (shipperList != null && !shipperList.isEmpty()) { + for (Map shipper : shipperList) { + Object userId = shipper.get("userId"); + Object userName = shipper.get("userName"); + // 根据名称匹配 + if (StringUtils.isNotEmpty(shipperName) && + userName != null && + shipperName.equals(String.valueOf(userName))) { + if (userId != null) { + shipperId = Long.valueOf(String.valueOf(userId)); + log.info("根据货主名称找到货主ID,货主名称:{},货主ID:{}", shipperName, shipperId); + break; + } + } + } + } + } + } catch (Exception e) { + log.warn("根据货主名称查找货主ID失败,货主名称:{},错误:{}", shipperName, e.getMessage()); + } + } + + // 如果仍然找不到货主ID,抛出异常 + if (shipperId == null) { + String errorMsg = "货主ID不能为空(货主信息就是客户)"; + if (StringUtils.isNotEmpty(shipperName)) { + errorMsg += "。已提供货主名称:" + shipperName + ",但未找到对应的货主ID,请确保货主名称正确或直接提供货主ID"; + } else if (StringUtils.isNotEmpty(shipperCode)) { + errorMsg += "。已提供货主编号:" + shipperCode + ",但未找到对应的货主ID,请确保货主编号正确或直接提供货主ID"; + } else { + errorMsg += "。请提供货主ID、货主名称或货主编号"; + } + throw new ServiceException(errorMsg); + } + stockInOrderDO.setShipperId(shipperId); } - AjaxResult ajaxResult = userServiceFeign.getInfo(stockInOrderDO.getShipperId()); + + // 根据货主ID获取详细信息 + AjaxResult ajaxResult = userServiceFeign.getInfo(shipperId); if(!"200".equals(String.valueOf(ajaxResult.get("code")))){ String errorMsg = ajaxResult.get("msg") != null ? String.valueOf(ajaxResult.get("msg")) : "未知错误"; - throw new ServiceException("获取货主信息失败(货主ID: " + stockInOrderDO.getShipperId() + "),错误信息: " + errorMsg); + throw new ServiceException("获取货主信息失败(货主ID: " + shipperId + "),错误信息: " + errorMsg); } UserPo userPo = JSON.parseObject(JSONObject.toJSONString(ajaxResult.get("data")), UserPo.class); if (userPo == null) { - throw new ServiceException("获取货主信息失败:返回数据为空(货主ID: " + stockInOrderDO.getShipperId() + ")"); + throw new ServiceException("获取货主信息失败:返回数据为空(货主ID: " + shipperId + ")"); } stockInOrderDO.setShipperCode(userPo.getUserMemberCode()); stockInOrderDO.setShipperName(userPo.getUserName()); diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/inMaterialDetail/entity/InMaterialDetail.java b/mhd_wms/src/main/java/com/mhd/wms/domain/inMaterialDetail/entity/InMaterialDetail.java index 15c8ff873..e62a67ce7 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/inMaterialDetail/entity/InMaterialDetail.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/inMaterialDetail/entity/InMaterialDetail.java @@ -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; diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/repository/persistence/ReceiptMaterialDetailImpl.java b/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/repository/persistence/ReceiptMaterialDetailImpl.java index 21a076543..ca59b61f7 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/repository/persistence/ReceiptMaterialDetailImpl.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/repository/persistence/ReceiptMaterialDetailImpl.java @@ -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 children = getChildren(materialDetailPO.getUniqueId(), receiptMaterialDetailPOList, 2); children.forEach(childrenDetailPO -> { MaterialMoreDetailDO materialMoreDetailDO = new MaterialMoreDetailDO(); - materialMoreDetailDO.setMaterialDetailUniqueId(childrenDetailPO.getMaterialDetailId()); + materialMoreDetailDO.setMaterialDetailUniqueId(childrenDetailPO.getUniqueId()); List 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 receiptMaterialDetailDOList) { + if (CollectionUtils.isEmpty(receiptMaterialDetailDOList)) { + return; + } + LoginUser loginUser = SecurityUtils.getLoginUser(); + for (ReceiptMaterialDetailDO receiptMaterialDetailDO : receiptMaterialDetailDOList) { + Long inUniqueId = receiptMaterialDetailDO.getInUniqueId(); + if (inUniqueId == null) { + continue; + } + List materialMoreDetailList = receiptMaterialDetailDO.getMaterialMoreDetailList(); + if (CollectionUtils.isEmpty(materialMoreDetailList)) { + continue; + } + // 构建UpdateWrapper + UpdateWrapper 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 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 materialMoreDetailList) { + if (CollectionUtils.isEmpty(materialMoreDetailList) || receiptMaterialDetailPO.getInUniqueId() == null) { + return; + } + // 查询入库单明细 + QueryWrapper 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()); + } + } } diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/repository/po/ReceiptMaterialDetailPO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/repository/po/ReceiptMaterialDetailPO.java index 764fb4c11..ef3835c3e 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/repository/po/ReceiptMaterialDetailPO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/receiptMaterialDetail/repository/po/ReceiptMaterialDetailPO.java @@ -232,6 +232,22 @@ public class ReceiptMaterialDetailPO extends BaseVOEntity { @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 children; diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/service/StockReceiptOrderDomainService.java b/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/service/StockReceiptOrderDomainService.java index 21c948911..190113ecc 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/service/StockReceiptOrderDomainService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/stockReceiptOrder/service/StockReceiptOrderDomainService.java @@ -32,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; @@ -110,6 +112,8 @@ public class StockReceiptOrderDomainService { @Autowired private IInventoryStandingDetailService inventoryStandingDetailService; @Autowired + private IInventoryStandingReportService inventoryStandingReportService; + @Autowired private IdGenerator idGenerator; @Autowired private IContainerUsageRecordService containerUsageRecordService; @@ -376,6 +380,8 @@ public class StockReceiptOrderDomainService { } //保存容器使用记录 genContainerUsageRecord(stockReceiptOrderDO); + //生成库存台账报表记录(收货虚拟库存)- 需要在batchReceiptUpdate之前调用,因为batchReceiptUpdate会将状态更新为3 + genInventoryStandingReport(stockReceiptOrderPO, stockReceiptOrderDO); //修改物料明细信息 receiptMaterialDetailService.batchReceiptUpdate(stockReceiptOrderDO); //生成 收货作业单 @@ -498,6 +504,8 @@ public class StockReceiptOrderDomainService { //生成收货追溯记录 genInventoryStandingDetail(stockReceiptOrderPO); + //生成库存台账报表记录(收货虚拟库存) + genInventoryStandingReport(stockReceiptOrderPO); //存在异常 生成记录 if (abnormal == 1){ genInOrderAbnormal(stockReceiptOrderPO); @@ -981,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 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 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 diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/stockShelfOrder/service/StockShelfOrderDomainService.java b/mhd_wms/src/main/java/com/mhd/wms/domain/stockShelfOrder/service/StockShelfOrderDomainService.java index f9987b1ef..264c9da99 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/stockShelfOrder/service/StockShelfOrderDomainService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/stockShelfOrder/service/StockShelfOrderDomainService.java @@ -413,13 +413,28 @@ public class StockShelfOrderDomainService { public void shelfAddMaterialInventory(List shelfMaterialDetailList){ List 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); materialInventoryDOList.add(materialInventoryDO); } - materialInventoryService.updateMaterialInventoryInfo(materialInventoryDOList, 1); + if (!CollectionUtils.isEmpty(materialInventoryDOList)) { + materialInventoryService.updateMaterialInventoryInfo(materialInventoryDOList, 1); + } } public void updateSerialNumberforInventory(List shelfMaterialDetailList){ diff --git a/mhd_wms/src/main/resources/mapper/inventoryStandingReport/InventoryStandingReportMapper.xml b/mhd_wms/src/main/resources/mapper/inventoryStandingReport/InventoryStandingReportMapper.xml index a8445e41c..b5a015aa2 100644 --- a/mhd_wms/src/main/resources/mapper/inventoryStandingReport/InventoryStandingReportMapper.xml +++ b/mhd_wms/src/main/resources/mapper/inventoryStandingReport/InventoryStandingReportMapper.xml @@ -63,13 +63,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" sio1.top_organization_id, 1 AS node_status, "收货" AS node_name, - SUM( rmd.quantity ) AS material_quantity + SUM( rmd.receipt_quantity ) AS material_quantity FROM receipt_material_detail rmd LEFT JOIN stock_receipt_order sro1 ON sro1.receipt_order_number = rmd.receipt_order_number LEFT JOIN stock_in_order sio1 ON sro1.in_order_number = sio1.in_order_number WHERE rmd.receipt_status IN ( 1, 2 ) + AND rmd.receipt_quantity > 0 GROUP BY rmd.material_base_info_id, sio1.shipper_id, diff --git a/mhd_wms/src/main/resources/mapper/receiptMaterialDetail/ReceiptMaterialDetailMapper.xml b/mhd_wms/src/main/resources/mapper/receiptMaterialDetail/ReceiptMaterialDetailMapper.xml index 9d04c9a7a..ffec31046 100644 --- a/mhd_wms/src/main/resources/mapper/receiptMaterialDetail/ReceiptMaterialDetailMapper.xml +++ b/mhd_wms/src/main/resources/mapper/receiptMaterialDetail/ReceiptMaterialDetailMapper.xml @@ -61,12 +61,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + + + - select a.MATERIAL_DETAIL_ID, a.ORGANIZATION_ID, a.ORGANIZATION_NAME, a.TOP_ORGANIZATION_ID, a.UNIQUE_ID, a.RECEIPT_ORDER_NUMBER, a.MATERIAL_BASE_INFO_ID, a.MATERIAL_CODE, a.MATERIAL_NAME, a.BAR_CODE, a.QUANTITY, a.ALREADY_RECEIPT_QUANTITY, a.RECEIPT_QUANTITY, a.RECEIPT_STATUS, a.PACK_ID, a.PACK_CODE, a.PACK_NAME, a.PACK_DETAIL_ID, a.UNIT_CODE, a.UNIT_NAME, a.UNIT_NUMBER, a.MATERIAL_WAREHOUSE_CONTROL_ID, a.SERIAL_NUMBER_MANAGE, a.QUALITY_INSPECTION_MANAGE, a.QUALITY_INSPECTION_STAGE, a.QUALITY_INSPECTION_RULE, a.QUALITY_INSPECTION_RATIO, a.QUALITY_INSPECTION_TERM, a.QUALITY_INSPECTION_RESULTS, a.ALLOW_OVERCHARGE, a.OVERCHARGE_RATIO, a.BATCH_NUMBER, a.MATERIAL_STATUS_CODE, a.MATERIAL_STATUS_NAME, a.DISTRIBUTE_RULE_ID, a.DISTRIBUTE_RULE_CODE, a.DISTRIBUTE_RULE_NAME, a.CONTAINER_ID, a.CONTAINER_CODE, a.CONTAINER_TYPE, a.CONTAINER_TYPE_NAME, a.LEVEL, a.PARENT_UNIQUE_ID, a.IN_UNIQUE_ID, a.ALLOW_MODIFY, a.REMARK, a.CREATE_TIME, a.CREATE_BY, a.CREATE_BY_NAME, a.UPDATE_TIME, a.UPDATE_BY, a.UPDATE_BY_NAME, a.GEN_STOCK_SHELF, a.DEL_FLAG, - b.TOTAL_NET_WEIGHT, b.TOTAL_GROSS_WEIGHT, b.TOTAL_VOLUME, b.TOTAL_AREA + select a.MATERIAL_DETAIL_ID, a.ORGANIZATION_ID, a.ORGANIZATION_NAME, a.TOP_ORGANIZATION_ID, a.UNIQUE_ID, a.RECEIPT_ORDER_NUMBER, a.MATERIAL_BASE_INFO_ID, a.MATERIAL_CODE, a.MATERIAL_NAME, a.BAR_CODE, a.QUANTITY, a.ALREADY_RECEIPT_QUANTITY, a.RECEIPT_QUANTITY, a.RECEIPT_STATUS, a.PACK_ID, a.PACK_CODE, a.PACK_NAME, a.PACK_DETAIL_ID, a.UNIT_CODE, a.UNIT_NAME, a.UNIT_NUMBER, a.MATERIAL_WAREHOUSE_CONTROL_ID, a.SERIAL_NUMBER_MANAGE, a.QUALITY_INSPECTION_MANAGE, a.QUALITY_INSPECTION_STAGE, a.QUALITY_INSPECTION_RULE, a.QUALITY_INSPECTION_RATIO, a.QUALITY_INSPECTION_TERM, a.QUALITY_INSPECTION_RESULTS, a.ALLOW_OVERCHARGE, a.OVERCHARGE_RATIO, a.BATCH_NUMBER, a.MATERIAL_STATUS_CODE, a.MATERIAL_STATUS_NAME, a.DISTRIBUTE_RULE_ID, a.DISTRIBUTE_RULE_CODE, a.DISTRIBUTE_RULE_NAME, a.CONTAINER_ID, a.CONTAINER_CODE, a.CONTAINER_TYPE, a.CONTAINER_TYPE_NAME, a.LEVEL, a.PARENT_UNIQUE_ID, a.IN_UNIQUE_ID, a.ALLOW_MODIFY, a.REMARK, a.CREATE_TIME, a.CREATE_BY, a.CREATE_BY_NAME, a.UPDATE_TIME, a.UPDATE_BY, a.UPDATE_BY_NAME, a.GEN_STOCK_SHELF, a.DEL_FLAG, + b.TOTAL_NET_WEIGHT, b.TOTAL_GROSS_WEIGHT, b.TOTAL_VOLUME, b.TOTAL_AREA, b.INVOICE_NO, b.BATCH_REF_NO, b.SHEET_REF_NO, b.BOX_PALLET_NO from RECEIPT_MATERIAL_DETAIL a LEFT JOIN IN_MATERIAL_DETAIL b ON a.IN_UNIQUE_ID = b.UNIQUE_ID AND b.DEL_FLAG = 1 From 0738c939ae62ed98721b0d3c0c56e9153f28392a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=A6=E9=B8=BF=E5=B1=95?= <18031053041@163.com> Date: Tue, 27 Jan 2026 15:22:42 +0800 Subject: [PATCH 8/8] =?UTF-8?q?=E5=85=A5=E5=BA=93=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E4=BF=AE=E6=94=B9bug1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../StockInOrderApplicationService.java | 59 +++++++++++--- .../persistence/MaterialInventoryImpl.java | 76 ++++++++++++++++++- .../service/StockShelfOrderDomainService.java | 70 ++++++++++++++++- .../StockInOrderImportRowDTO.java | 3 + 4 files changed, 192 insertions(+), 16 deletions(-) diff --git a/mhd_wms/src/main/java/com/mhd/wms/application/service/stockInOrder/StockInOrderApplicationService.java b/mhd_wms/src/main/java/com/mhd/wms/application/service/stockInOrder/StockInOrderApplicationService.java index 59c8600aa..5f43f739c 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/application/service/stockInOrder/StockInOrderApplicationService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/application/service/stockInOrder/StockInOrderApplicationService.java @@ -934,6 +934,10 @@ public class StockInOrderApplicationService { if (StringUtils.isNotBlank(headerInfo.getShipperName())) { row.setShipperName(headerInfo.getShipperName()); } + // 应用表头中的货主编号(表头有货主编号时,强制应用到所有明细行) + if (StringUtils.isNotBlank(headerInfo.getShipperCode())) { + row.setShipperCode(headerInfo.getShipperCode()); + } // 应用其他表头字段(如果明细行为空,则使用表头值) if (StringUtils.isBlank(row.getTo()) && StringUtils.isNotBlank(headerInfo.getTo())) { row.setTo(headerInfo.getTo()); @@ -1058,10 +1062,16 @@ public class StockInOrderApplicationService { order.setWarehouseId(warehouseId); // 设置仓库完整信息(warehouseCode 和 warehouseName) setWarehouseInfo(order); - // 货主ID不需要,直接设置为null,使用客户名称作为货主名称 + // 货主信息:优先使用表头,如果表头为空则使用明细行 + String shipperName = StringUtils.isNotBlank(headerInfo.getShipperName()) ? headerInfo.getShipperName() : h.getShipperName(); + String shipperCode = StringUtils.isNotBlank(headerInfo.getShipperCode()) ? headerInfo.getShipperCode() : h.getShipperCode(); + // 货主ID先设置为null,后续在shipperParam方法中根据名称或编号查找 order.setShipperId(null); - if (StringUtils.isNotBlank(h.getShipperName())) { - order.setShipperName(h.getShipperName()); + if (StringUtils.isNotBlank(shipperName)) { + order.setShipperName(shipperName); + } + if (StringUtils.isNotBlank(shipperCode)) { + order.setShipperCode(shipperCode); } // order.setSupplierId(h.getSupplierId()); // order.setOrderTypeCode(h.getOrderTypeCode()); @@ -1292,6 +1302,21 @@ public class StockInOrderApplicationService { } order.setMaterialDetailList(details); + + // 在导入时,需要调用shipperParam、supplierParam和setDataDict方法,确保货主信息被正确填充 + // 注意:这里只调用shipperParam,因为导入时只提供了货主名称,需要根据名称查找货主ID和编号 + try { + shipperParam(order); + } catch (Exception e) { + log.error("导入入库单时设置货主信息失败,委托编号NO:{},货主名称:{},错误:{}", + h.getConsignmentNo(), order.getShipperName(), e.getMessage()); + throw new ServiceException("导入失败:设置货主信息失败(委托编号NO=" + h.getConsignmentNo() + ",货主名称=" + order.getShipperName() + ")。" + e.getMessage()); + } + // 设置供应商信息(如果提供了供应商ID) + supplierParam(order); + // 设置数据字典键值 + setDataDict(order); + orderList.add(order); } @@ -1477,15 +1502,29 @@ public class StockInOrderApplicationService { for (Map shipper : shipperList) { Object userId = shipper.get("userId"); Object userName = shipper.get("userName"); - // 根据名称匹配 - if (StringUtils.isNotEmpty(shipperName) && + Object userCode = shipper.get("userCode"); + Object userMemberCode = shipper.get("userMemberCode"); + + boolean matched = false; + // 优先根据编号匹配(更准确) + if (StringUtils.isNotEmpty(shipperCode)) { + if ((userCode != null && shipperCode.equals(String.valueOf(userCode))) || + (userMemberCode != null && shipperCode.equals(String.valueOf(userMemberCode)))) { + matched = true; + } + } + // 如果编号不匹配,再根据名称匹配 + if (!matched && StringUtils.isNotEmpty(shipperName) && userName != null && shipperName.equals(String.valueOf(userName))) { - if (userId != null) { - shipperId = Long.valueOf(String.valueOf(userId)); - log.info("根据货主名称找到货主ID,货主名称:{},货主ID:{}", shipperName, shipperId); - break; - } + matched = true; + } + + if (matched && userId != null) { + shipperId = Long.valueOf(String.valueOf(userId)); + log.info("根据货主信息找到货主ID,货主名称:{},货主编号:{},货主ID:{}", + shipperName, shipperCode, shipperId); + break; } } } diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/persistence/MaterialInventoryImpl.java b/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/persistence/MaterialInventoryImpl.java index 93bb64ce4..51bf321b4 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/persistence/MaterialInventoryImpl.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/materialInventory/repository/persistence/MaterialInventoryImpl.java @@ -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 implements IMaterialInventoryService{ @Autowired private MaterialInventoryMapper materialInventoryMapper; + @Autowired + private IMaterialBaseInfoService materialBaseInfoService; /** * 查询物料库存列表 @@ -136,16 +142,80 @@ public class MaterialInventoryImpl extends ServiceImpl materialInventoryList = new ArrayList<>(); List materialInventoryDOListByUpdate = new ArrayList<>(); Map materialInventoryAddNowMap = new HashMap<>(); + + // 批量获取物料基础信息,以获取货主ID(用于查询和key生成) + Map materialBaseInfoIdToShipperIdMap = new HashMap<>(); + if (!CollectionUtils.isEmpty(materialInventoryDOList)) { + Set 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 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().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 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(); } diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/stockShelfOrder/service/StockShelfOrderDomainService.java b/mhd_wms/src/main/java/com/mhd/wms/domain/stockShelfOrder/service/StockShelfOrderDomainService.java index 264c9da99..32a8a61fe 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/domain/stockShelfOrder/service/StockShelfOrderDomainService.java +++ b/mhd_wms/src/main/java/com/mhd/wms/domain/stockShelfOrder/service/StockShelfOrderDomainService.java @@ -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 shelfMaterialDetailList = shelfMaterialDetailService.list(new QueryWrapper().lambda().eq(ShelfMaterialDetail::getShelfOrderNumber, stockShelfOrderPO.getShelfOrderNumber())); - //组装上架修改库存参数 - shelfAddMaterialInventory(shelfMaterialDetailList); + //组装上架修改库存参数(传入上架单信息,用于获取货主信息) + shelfAddMaterialInventory(shelfMaterialDetailList, stockShelfOrderPO); //修改上架对应的序列号的库存信息 updateSerialNumberforInventory(shelfMaterialDetailList); //生成上架追溯记录 @@ -408,9 +411,58 @@ public class StockShelfOrderDomainService { * @author ZhouGY * @date 2024/6/19 10:07 * @param shelfMaterialDetailList + * @param stockShelfOrderPO 上架单信息,用于获取货主信息 * @return Boolean */ - public void shelfAddMaterialInventory(List shelfMaterialDetailList){ + public void shelfAddMaterialInventory(List 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 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 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 materialInventoryDOList = new ArrayList<>(); for (ShelfMaterialDetail shelfMaterialDetail : shelfMaterialDetailList){ // 使用shelvesQuantity(本次上架数量)来增加库存 @@ -430,6 +482,18 @@ public class StockShelfOrderDomainService { BeanUtils.copyProperties(shelfMaterialDetail, materialInventoryDO); 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); } if (!CollectionUtils.isEmpty(materialInventoryDOList)) { diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockInOrder/StockInOrderImportRowDTO.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockInOrder/StockInOrderImportRowDTO.java index ec470acd3..c11526919 100644 --- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockInOrder/StockInOrderImportRowDTO.java +++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/dto/stockInOrder/StockInOrderImportRowDTO.java @@ -20,6 +20,9 @@ public class StockInOrderImportRowDTO { // @Excel(name = "货主ID") // private Long shipperId; + @Excel(name = "货主编号") + private String shipperCode; + // @Excel(name = "供应商ID") // private Long supplierId;