diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/facade/IExecutionOutboundRankService.java b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/facade/IExecutionOutboundRankService.java
index 477fc1e99..239e6f118 100644
--- a/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/facade/IExecutionOutboundRankService.java
+++ b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/facade/IExecutionOutboundRankService.java
@@ -1,13 +1,14 @@
package com.mhd.oms.domain.outboundRank.repository.facade;
-import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundDetailRankPO;
import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundDetailRankTotalPO;
+import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundLineRankPO;
+import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundMaterialRankPO;
import com.mhd.oms.domain.outboundRank.repository.todo.ExecutionOutboundRankDO;
import java.util.List;
/**
- * 出库排名统计(明细)Service接口
+ * 出库排名统计Service接口
*
* @author rcx
* @date 2026-08-31
@@ -15,12 +16,22 @@ import java.util.List;
public interface IExecutionOutboundRankService {
/**
- * 出库明细列表
+ * 商品出库排名列表(货品聚合)
*/
- List queryDetailList(ExecutionOutboundRankDO executionOutboundRankDO);
+ List queryMaterialRankList(ExecutionOutboundRankDO executionOutboundRankDO);
/**
- * 出库明细合计(不分页)
+ * 商品出库排名合计(不分页)
*/
- ExecutionOutboundDetailRankTotalPO queryDetailTotal(ExecutionOutboundRankDO executionOutboundRankDO);
+ ExecutionOutboundDetailRankTotalPO queryMaterialRankTotal(ExecutionOutboundRankDO executionOutboundRankDO);
+
+ /**
+ * 线路出库排名列表(线路×货品聚合)
+ */
+ List queryLineRankList(ExecutionOutboundRankDO executionOutboundRankDO);
+
+ /**
+ * 线路出库排名合计(不分页)
+ */
+ ExecutionOutboundDetailRankTotalPO queryLineRankTotal(ExecutionOutboundRankDO executionOutboundRankDO);
}
diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/mapper/ExecutionOutboundRankMapper.java b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/mapper/ExecutionOutboundRankMapper.java
index 3f88c7823..411aaa893 100644
--- a/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/mapper/ExecutionOutboundRankMapper.java
+++ b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/mapper/ExecutionOutboundRankMapper.java
@@ -1,13 +1,14 @@
package com.mhd.oms.domain.outboundRank.repository.mapper;
-import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundDetailRankPO;
import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundDetailRankTotalPO;
+import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundLineRankPO;
+import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundMaterialRankPO;
import com.mhd.oms.domain.outboundRank.repository.todo.ExecutionOutboundRankDO;
import java.util.List;
/**
- * 出库排名统计(明细)Mapper接口
+ * 出库排名统计Mapper接口
*
* @author rcx
* @date 2026-08-31
@@ -15,12 +16,22 @@ import java.util.List;
public interface ExecutionOutboundRankMapper {
/**
- * 出库明细列表(一行=仓单×货品,按件数倒序)
+ * 商品出库排名列表(一行=一个货品,跨单汇总,按实际出库量降序)
*/
- List queryDetailList(ExecutionOutboundRankDO executionOutboundRankDO);
+ List queryMaterialRankList(ExecutionOutboundRankDO executionOutboundRankDO);
/**
- * 出库明细合计(不分页,当前筛选条件全量合计)
+ * 商品出库排名合计(不分页,当前筛选条件全量合计)
*/
- ExecutionOutboundDetailRankTotalPO queryDetailTotal(ExecutionOutboundRankDO executionOutboundRankDO);
+ ExecutionOutboundDetailRankTotalPO queryMaterialRankTotal(ExecutionOutboundRankDO executionOutboundRankDO);
+
+ /**
+ * 线路出库排名列表(一行=线路×货品,按实际出库量降序,仅统计带线路的单)
+ */
+ List queryLineRankList(ExecutionOutboundRankDO executionOutboundRankDO);
+
+ /**
+ * 线路出库排名合计(不分页,当前筛选条件全量合计)
+ */
+ ExecutionOutboundDetailRankTotalPO queryLineRankTotal(ExecutionOutboundRankDO executionOutboundRankDO);
}
diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/persistence/ExecutionOutboundRankImpl.java b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/persistence/ExecutionOutboundRankImpl.java
index 76e2abcd4..e4c23f36b 100644
--- a/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/persistence/ExecutionOutboundRankImpl.java
+++ b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/persistence/ExecutionOutboundRankImpl.java
@@ -2,8 +2,9 @@ package com.mhd.oms.domain.outboundRank.repository.persistence;
import com.mhd.oms.domain.outboundRank.repository.facade.IExecutionOutboundRankService;
import com.mhd.oms.domain.outboundRank.repository.mapper.ExecutionOutboundRankMapper;
-import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundDetailRankPO;
import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundDetailRankTotalPO;
+import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundLineRankPO;
+import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundMaterialRankPO;
import com.mhd.oms.domain.outboundRank.repository.todo.ExecutionOutboundRankDO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -11,7 +12,7 @@ import org.springframework.stereotype.Service;
import java.util.List;
/**
- * 出库排名统计(明细)Service业务层处理
+ * 出库排名统计Service业务层处理
*
* @author rcx
* @date 2026-08-31
@@ -23,12 +24,22 @@ public class ExecutionOutboundRankImpl implements IExecutionOutboundRankService
private ExecutionOutboundRankMapper executionOutboundRankMapper;
@Override
- public List queryDetailList(ExecutionOutboundRankDO executionOutboundRankDO) {
- return executionOutboundRankMapper.queryDetailList(executionOutboundRankDO);
+ public List queryMaterialRankList(ExecutionOutboundRankDO executionOutboundRankDO) {
+ return executionOutboundRankMapper.queryMaterialRankList(executionOutboundRankDO);
}
@Override
- public ExecutionOutboundDetailRankTotalPO queryDetailTotal(ExecutionOutboundRankDO executionOutboundRankDO) {
- return executionOutboundRankMapper.queryDetailTotal(executionOutboundRankDO);
+ public ExecutionOutboundDetailRankTotalPO queryMaterialRankTotal(ExecutionOutboundRankDO executionOutboundRankDO) {
+ return executionOutboundRankMapper.queryMaterialRankTotal(executionOutboundRankDO);
+ }
+
+ @Override
+ public List queryLineRankList(ExecutionOutboundRankDO executionOutboundRankDO) {
+ return executionOutboundRankMapper.queryLineRankList(executionOutboundRankDO);
+ }
+
+ @Override
+ public ExecutionOutboundDetailRankTotalPO queryLineRankTotal(ExecutionOutboundRankDO executionOutboundRankDO) {
+ return executionOutboundRankMapper.queryLineRankTotal(executionOutboundRankDO);
}
}
diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/po/ExecutionOutboundDetailRankPO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/po/ExecutionOutboundDetailRankPO.java
deleted file mode 100644
index 2c37d7725..000000000
--- a/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/po/ExecutionOutboundDetailRankPO.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package com.mhd.oms.domain.outboundRank.repository.po;
-
-import com.fasterxml.jackson.annotation.JsonFormat;
-import com.mhd.common.core.annotation.Excel;
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
-import org.springframework.format.annotation.DateTimeFormat;
-
-import java.io.Serializable;
-import java.math.BigDecimal;
-import java.util.Date;
-
-/**
- * 出库排名统计(明细)PO(一行 = 仓单×货品,件数/毛重/体积按行汇总)
- *
- * 字段口径:种类=出库单据类型;仓单编号=出库单号;收货人=出库单 TO 栏(为空取联系人);
- * 毛重(吨)=明细总毛重KG/1000;出仓日期=出仓日期(为空依次兜底完成时间/创建时间);
- * 退保总额为占位字段,后端暂无对应数据来源,恒为 null(候选:货品档案保额 insure_amount,确认后可补)
- *
- * @author rcx
- * @date 2026-08-31
- */
-@Data
-@ApiModel(value = "出库排名统计明细对象", description = "出库排名统计明细响应对象")
-public class ExecutionOutboundDetailRankPO implements Serializable {
-
- private static final long serialVersionUID = 1L;
-
- @ApiModelProperty("种类(出库单据类型)")
- @Excel(name = "种类")
- private String orderTypeName;
-
- @ApiModelProperty("仓单编号(出库单号)")
- @Excel(name = "仓单编号")
- private String outOrderNumber;
-
- @ApiModelProperty("入库单号")
- @Excel(name = "入库单号")
- private String inOrderNumber;
-
- @ApiModelProperty("客户编号")
- @Excel(name = "客户编号")
- private String customerCode;
-
- @ApiModelProperty("收货人(出库单 TO 栏,为空取联系人)")
- @Excel(name = "收货人")
- private String receiver;
-
- @ApiModelProperty("商品货号(辅助字段,不导出)")
- private String materialCode;
-
- @ApiModelProperty("货名")
- @Excel(name = "货名")
- private String materialName;
-
- @ApiModelProperty("线路编码(辅助字段,不导出)")
- private String lineCode;
-
- @ApiModelProperty("线路")
- @Excel(name = "线路")
- private String lineName;
-
- @ApiModelProperty("件数(复核确认的实际出库量合计,与入库排名的实际上架量对称)")
- @Excel(name = "件数")
- private BigDecimal pieceCount;
-
- @ApiModelProperty("毛重(吨)")
- @Excel(name = "毛重(吨)")
- private BigDecimal grossWeightTon;
-
- @ApiModelProperty("体积(CBM)")
- @Excel(name = "体积(CBM)")
- private BigDecimal totalVolume;
-
- @ApiModelProperty("退保总额(占位字段,后端暂无数据来源,恒为 null)")
- @Excel(name = "退保总额")
- private BigDecimal depositRefundAmount;
-
- @ApiModelProperty("出仓日期(出仓日期为空时依次兜底完成时间/创建时间)")
- @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
- @DateTimeFormat(pattern = "yyyy-MM-dd")
- @Excel(name = "出仓日期", width = 30, dateFormat = "yyyy-MM-dd")
- private Date outboundDate;
-}
diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/po/ExecutionOutboundDetailRankTotalPO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/po/ExecutionOutboundDetailRankTotalPO.java
index 355295a34..9ce960473 100644
--- a/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/po/ExecutionOutboundDetailRankTotalPO.java
+++ b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/po/ExecutionOutboundDetailRankTotalPO.java
@@ -8,16 +8,16 @@ import java.io.Serializable;
import java.math.BigDecimal;
/**
- * 出库排名统计(明细)合计PO
+ * 出库排名统计合计PO
*
* 当前筛选条件下不分页的全量合计,随分页列表一起返回
- * (totalPieceCount/totalGrossWeightTon/totalVolume/totalOrderCount)
+ * (totalPieceCount/totalGrossWeightTon/totalVolume/totalOrderCount/totalLineCount)
*
* @author rcx
* @date 2026-08-31
*/
@Data
-@ApiModel(value = "出库排名统计明细合计对象", description = "出库排名统计明细合计响应对象")
+@ApiModel(value = "出库排名统计合计对象", description = "出库排名统计合计响应对象")
public class ExecutionOutboundDetailRankTotalPO implements Serializable {
private static final long serialVersionUID = 1L;
@@ -33,4 +33,7 @@ public class ExecutionOutboundDetailRankTotalPO implements Serializable {
@ApiModelProperty("仓单数合计(去重出库单数)")
private Long totalOrderCount;
+
+ @ApiModelProperty("线路数合计(去重线路数,线路排名使用)")
+ private Long totalLineCount;
}
diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/po/ExecutionOutboundLineRankPO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/po/ExecutionOutboundLineRankPO.java
new file mode 100644
index 000000000..a1beead56
--- /dev/null
+++ b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/po/ExecutionOutboundLineRankPO.java
@@ -0,0 +1,59 @@
+package com.mhd.oms.domain.outboundRank.repository.po;
+
+import com.mhd.common.core.annotation.Excel;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * 线路出库排名PO(一行 = 线路×货品,日期区间内汇总)
+ *
+ * 按线路+物料编码合并:多张出库单合并为一行,单据级字段(种类/仓单编号/入库单号/客户编号/收货人/出仓日期)不提供;
+ * 仅统计带线路的出库单(line_code 为 2026-08-20 新增冗余字段,历史单为空,不参与线路排名);
+ * 件数 = SUM(CHECK_QUANTITY) 复核确认的实际出库量(与入库排名的实际上架量对称);
+ * 退保总额为占位字段,后端暂无对应数据来源,恒为 null
+ *
+ * @author rcx
+ * @date 2026-08-31
+ */
+@Data
+@ApiModel(value = "线路出库排名对象", description = "线路出库排名响应对象")
+public class ExecutionOutboundLineRankPO implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty("线路编码")
+ @Excel(name = "线路编码")
+ private String lineCode;
+
+ @ApiModelProperty("线路")
+ @Excel(name = "线路")
+ private String lineName;
+
+ @ApiModelProperty("商品货号")
+ @Excel(name = "商品货号")
+ private String materialCode;
+
+ @ApiModelProperty("货名")
+ @Excel(name = "货名")
+ private String materialName;
+
+ @ApiModelProperty("件数(复核确认的实际出库量合计,与入库排名的实际上架量对称)")
+ @Excel(name = "件数")
+ private BigDecimal pieceCount;
+
+ @ApiModelProperty("毛重(吨)")
+ @Excel(name = "毛重(吨)")
+ private BigDecimal grossWeightTon;
+
+ @ApiModelProperty("体积(CBM)")
+ @Excel(name = "体积(CBM)")
+ private BigDecimal totalVolume;
+
+ @ApiModelProperty("退保总额(占位字段,后端暂无数据来源,恒为 null)")
+ @Excel(name = "退保总额")
+ private BigDecimal depositRefundAmount;
+}
diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/po/ExecutionOutboundMaterialRankPO.java b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/po/ExecutionOutboundMaterialRankPO.java
new file mode 100644
index 000000000..497b9a205
--- /dev/null
+++ b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/repository/po/ExecutionOutboundMaterialRankPO.java
@@ -0,0 +1,50 @@
+package com.mhd.oms.domain.outboundRank.repository.po;
+
+import com.mhd.common.core.annotation.Excel;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * 商品出库排名PO(一行 = 一个货品,日期区间内跨出库单汇总)
+ *
+ * 按物料编码合并:一个货品会走多条线路/多张单,单据级字段(种类/仓单编号/入库单号/客户编号/收货人/出仓日期)与
+ * 线路字段均无单值可返,不提供;件数 = SUM(CHECK_QUANTITY) 复核确认的实际出库量(与入库排名的实际上架量对称);
+ * 退保总额为占位字段,后端暂无对应数据来源,恒为 null
+ *
+ * @author rcx
+ * @date 2026-08-31
+ */
+@Data
+@ApiModel(value = "商品出库排名对象", description = "商品出库排名响应对象")
+public class ExecutionOutboundMaterialRankPO implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty("商品货号")
+ @Excel(name = "商品货号")
+ private String materialCode;
+
+ @ApiModelProperty("货名")
+ @Excel(name = "货名")
+ private String materialName;
+
+ @ApiModelProperty("件数(复核确认的实际出库量合计,与入库排名的实际上架量对称)")
+ @Excel(name = "件数")
+ private BigDecimal pieceCount;
+
+ @ApiModelProperty("毛重(吨)")
+ @Excel(name = "毛重(吨)")
+ private BigDecimal grossWeightTon;
+
+ @ApiModelProperty("体积(CBM)")
+ @Excel(name = "体积(CBM)")
+ private BigDecimal totalVolume;
+
+ @ApiModelProperty("退保总额(占位字段,后端暂无数据来源,恒为 null)")
+ @Excel(name = "退保总额")
+ private BigDecimal depositRefundAmount;
+}
diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/service/ExecutionOutboundRankApplicationService.java b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/service/ExecutionOutboundRankApplicationService.java
index 2d68567c0..6b705c399 100644
--- a/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/service/ExecutionOutboundRankApplicationService.java
+++ b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/service/ExecutionOutboundRankApplicationService.java
@@ -4,8 +4,9 @@ import com.mhd.common.core.exception.ServiceException;
import com.mhd.common.core.utils.StringUtils;
import com.mhd.common.security.utils.SecurityUtils;
import com.mhd.system.api.model.LoginUser;
-import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundDetailRankPO;
import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundDetailRankTotalPO;
+import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundLineRankPO;
+import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundMaterialRankPO;
import com.mhd.oms.domain.outboundRank.repository.todo.ExecutionOutboundRankDO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@@ -14,7 +15,7 @@ import org.springframework.stereotype.Service;
import java.util.List;
/**
- * 出库排名统计(明细)应用服务
+ * 出库排名统计应用服务
*
* 负责登录用户组织隔离注入、日期区间校验,查询逻辑在 ExecutionOutboundRankDomainService → ExecutionOutboundRankMapper.xml(跨库取 WMS 出库数据)
*
@@ -29,26 +30,49 @@ public class ExecutionOutboundRankApplicationService {
private ExecutionOutboundRankDomainService executionOutboundRankDomainService;
/**
- * 分页查询出库明细列表
+ * 分页查询商品出库排名列表(货品聚合)
*/
- public List queryDetailList(ExecutionOutboundRankDO executionOutboundRankDO) {
+ public List queryMaterialRankList(ExecutionOutboundRankDO executionOutboundRankDO) {
fillLoginContext(executionOutboundRankDO);
- return executionOutboundRankDomainService.queryDetailList(executionOutboundRankDO);
+ return executionOutboundRankDomainService.queryMaterialRankList(executionOutboundRankDO);
}
/**
- * 出库明细合计(当前筛选条件全量,不分页)
+ * 商品出库排名合计(当前筛选条件全量,不分页)
*/
- public ExecutionOutboundDetailRankTotalPO queryDetailTotal(ExecutionOutboundRankDO executionOutboundRankDO) {
- return executionOutboundRankDomainService.queryDetailTotal(executionOutboundRankDO);
+ public ExecutionOutboundDetailRankTotalPO queryMaterialRankTotal(ExecutionOutboundRankDO executionOutboundRankDO) {
+ return executionOutboundRankDomainService.queryMaterialRankTotal(executionOutboundRankDO);
}
/**
- * 导出出库明细(不分页全量)
+ * 导出商品出库排名(不分页全量)
*/
- public List exportDetailList(ExecutionOutboundRankDO executionOutboundRankDO) {
+ public List exportMaterialRankList(ExecutionOutboundRankDO executionOutboundRankDO) {
fillLoginContext(executionOutboundRankDO);
- return executionOutboundRankDomainService.queryDetailList(executionOutboundRankDO);
+ return executionOutboundRankDomainService.queryMaterialRankList(executionOutboundRankDO);
+ }
+
+ /**
+ * 分页查询线路出库排名列表(线路×货品聚合)
+ */
+ public List queryLineRankList(ExecutionOutboundRankDO executionOutboundRankDO) {
+ fillLoginContext(executionOutboundRankDO);
+ return executionOutboundRankDomainService.queryLineRankList(executionOutboundRankDO);
+ }
+
+ /**
+ * 线路出库排名合计(当前筛选条件全量,不分页)
+ */
+ public ExecutionOutboundDetailRankTotalPO queryLineRankTotal(ExecutionOutboundRankDO executionOutboundRankDO) {
+ return executionOutboundRankDomainService.queryLineRankTotal(executionOutboundRankDO);
+ }
+
+ /**
+ * 导出线路出库排名(不分页全量)
+ */
+ public List exportLineRankList(ExecutionOutboundRankDO executionOutboundRankDO) {
+ fillLoginContext(executionOutboundRankDO);
+ return executionOutboundRankDomainService.queryLineRankList(executionOutboundRankDO);
}
/**
diff --git a/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/service/ExecutionOutboundRankDomainService.java b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/service/ExecutionOutboundRankDomainService.java
index 7966fe6bd..95b54e602 100644
--- a/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/service/ExecutionOutboundRankDomainService.java
+++ b/mhd_oms/src/main/java/com/mhd/oms/domain/outboundRank/service/ExecutionOutboundRankDomainService.java
@@ -1,8 +1,9 @@
package com.mhd.oms.domain.outboundRank.service;
import com.mhd.oms.domain.outboundRank.repository.facade.IExecutionOutboundRankService;
-import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundDetailRankPO;
import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundDetailRankTotalPO;
+import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundLineRankPO;
+import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundMaterialRankPO;
import com.mhd.oms.domain.outboundRank.repository.todo.ExecutionOutboundRankDO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@@ -11,7 +12,7 @@ import org.springframework.stereotype.Service;
import java.util.List;
/**
- * 出库排名统计(明细)领域服务
+ * 出库排名统计领域服务
*
* @author rcx
* @date 2026-08-31
@@ -24,16 +25,30 @@ public class ExecutionOutboundRankDomainService {
private IExecutionOutboundRankService executionOutboundRankService;
/**
- * 出库明细列表
+ * 商品出库排名列表(货品聚合)
*/
- public List queryDetailList(ExecutionOutboundRankDO executionOutboundRankDO) {
- return executionOutboundRankService.queryDetailList(executionOutboundRankDO);
+ public List queryMaterialRankList(ExecutionOutboundRankDO executionOutboundRankDO) {
+ return executionOutboundRankService.queryMaterialRankList(executionOutboundRankDO);
}
/**
- * 出库明细合计(不分页)
+ * 商品出库排名合计(不分页)
*/
- public ExecutionOutboundDetailRankTotalPO queryDetailTotal(ExecutionOutboundRankDO executionOutboundRankDO) {
- return executionOutboundRankService.queryDetailTotal(executionOutboundRankDO);
+ public ExecutionOutboundDetailRankTotalPO queryMaterialRankTotal(ExecutionOutboundRankDO executionOutboundRankDO) {
+ return executionOutboundRankService.queryMaterialRankTotal(executionOutboundRankDO);
+ }
+
+ /**
+ * 线路出库排名列表(线路×货品聚合)
+ */
+ public List queryLineRankList(ExecutionOutboundRankDO executionOutboundRankDO) {
+ return executionOutboundRankService.queryLineRankList(executionOutboundRankDO);
+ }
+
+ /**
+ * 线路出库排名合计(不分页)
+ */
+ public ExecutionOutboundDetailRankTotalPO queryLineRankTotal(ExecutionOutboundRankDO executionOutboundRankDO) {
+ return executionOutboundRankService.queryLineRankTotal(executionOutboundRankDO);
}
}
diff --git a/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/outboundRank/ExecutionOutboundRankApi.java b/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/outboundRank/ExecutionOutboundRankApi.java
index 81ae1b67a..e723269a6 100644
--- a/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/outboundRank/ExecutionOutboundRankApi.java
+++ b/mhd_oms/src/main/java/com/mhd/oms/interfaces/facade/outboundRank/ExecutionOutboundRankApi.java
@@ -4,8 +4,9 @@ import com.github.pagehelper.PageInfo;
import com.mhd.common.core.constant.HttpStatus;
import com.mhd.common.core.utils.PageUtils;
import com.mhd.common.core.utils.poi.ExcelUtil;
-import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundDetailRankPO;
import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundDetailRankTotalPO;
+import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundLineRankPO;
+import com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundMaterialRankPO;
import com.mhd.oms.domain.outboundRank.repository.todo.ExecutionOutboundRankDO;
import com.mhd.oms.domain.outboundRank.repository.todo.ExecutionOutboundRankDTO;
import com.mhd.oms.domain.outboundRank.service.ExecutionOutboundRankApplicationService;
@@ -26,11 +27,14 @@ import java.util.List;
/**
* 出库排名统计Api
*
- * 按日期区间筛选出库明细列表(一行 = 仓单×货品,件数/毛重/体积按行汇总,按件数(实际复核出库量)降序,出仓日期/单号次之)。
- * OMS 库出库单状态不流转(无"已出库"数据),数据源跨库取 WMS 库出库表(NGWL_TEST_WMS.stock_out_order / out_material_detail),
- * 口径与 WMS 端 /outboundRankApi 完全一致,两边数字一致;统计条件:出库单创建时间 + 已出库及之后状态(9,12,13),明细仅取 level=1 主行。
- * 商品/线路两个 tab 各自独立接口,内部为同一份明细查询:商品接口忽略线路筛选参数,线路接口忽略商品筛选参数。
- * 字段:种类/仓单编号/入库单号/客户编号/收货人/货名/线路/件数/毛重(吨)/体积(CBM)/退保总额(占位null)/出仓日期
+ * 按日期区间筛选出库量统计排名,按出库数量(实际复核出库量)降序。
+ * 商品tab:一行 = 一个货品(货号/货名/件数/毛重(吨)/体积(CBM)/退保总额占位),跨出库单汇总,忽略线路筛选参数;
+ * 线路tab:一行 = 线路×货品(线路编码/线路/货号/货名/件数/毛重(吨)/体积(CBM)/退保总额占位),按线路+物料编码合并,
+ * 仅统计带线路的单,商品/线路筛选参数均生效;
+ * 统计口径:出库单创建时间 + 已出库及之后状态(9,12,13),明细仅取 level=1 主行;
+ * 件数 = SUM(CHECK_QUANTITY) 复核确认的实际出库量(与入库排名的实际上架量对称);
+ * 数据源跨库取 WMS 库出库表,口径与 WMS 端 /outboundRankApi 完全一致,两边数字一致;
+ * 退保总额后端暂无对应数据来源,恒为 null
*
* @author rcx
* @date 2026-08-31
@@ -58,25 +62,22 @@ public class ExecutionOutboundRankApi {
executionOutboundRankDO.setLineCode(null);
executionOutboundRankDO.setLineName(null);
startPage();
- List list = executionOutboundRankApplicationService.queryDetailList(executionOutboundRankDO);
- ExecutionOutboundDetailRankTotalPO total = executionOutboundRankApplicationService.queryDetailTotal(executionOutboundRankDO);
+ List list = executionOutboundRankApplicationService.queryMaterialRankList(executionOutboundRankDO);
+ ExecutionOutboundDetailRankTotalPO total = executionOutboundRankApplicationService.queryMaterialRankTotal(executionOutboundRankDO);
return getDataTableWithTotal(list, total);
}
/**
- * 分页查询线路出库排名列表(含合计行,线路tab;忽略商品筛选参数)
+ * 分页查询线路出库排名列表(含合计行,线路tab;一行=线路×货品,仅统计带线路的单)
*/
@ApiOperation("分页查询线路出库排名列表")
@GetMapping("/queryLineRankList")
public HashMap queryLineRankList(ExecutionOutboundRankDTO executionOutboundRankDTO) {
- //转换实体
+ //转换实体(线路tab:商品/线路筛选参数均生效,按线路+物料编码合并)
ExecutionOutboundRankDO executionOutboundRankDO = executionOutboundRankAssembler.toDO(executionOutboundRankDTO);
- //线路tab:忽略商品筛选参数
- executionOutboundRankDO.setMaterialCode(null);
- executionOutboundRankDO.setMaterialName(null);
startPage();
- List list = executionOutboundRankApplicationService.queryDetailList(executionOutboundRankDO);
- ExecutionOutboundDetailRankTotalPO total = executionOutboundRankApplicationService.queryDetailTotal(executionOutboundRankDO);
+ List list = executionOutboundRankApplicationService.queryLineRankList(executionOutboundRankDO);
+ ExecutionOutboundDetailRankTotalPO total = executionOutboundRankApplicationService.queryLineRankTotal(executionOutboundRankDO);
return getDataTableWithTotal(list, total);
}
@@ -91,41 +92,38 @@ public class ExecutionOutboundRankApi {
//商品tab:忽略线路筛选参数
executionOutboundRankDO.setLineCode(null);
executionOutboundRankDO.setLineName(null);
- List list = executionOutboundRankApplicationService.exportDetailList(executionOutboundRankDO);
+ List list = executionOutboundRankApplicationService.exportMaterialRankList(executionOutboundRankDO);
String fileName = URLEncoder.encode("商品出库排名", "UTF-8").replaceAll("\\+", "%20");
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
- ExcelUtil util = new ExcelUtil<>(ExecutionOutboundDetailRankPO.class);
+ ExcelUtil util = new ExcelUtil<>(ExecutionOutboundMaterialRankPO.class);
util.exportExcel(response, list, "商品出库排名");
}
/**
- * 导出线路出库排名Excel(线路tab;忽略商品筛选参数)
+ * 导出线路出库排名Excel(线路tab;一行=线路×货品,仅统计带线路的单)
*/
@ApiOperation("导出线路出库排名Excel")
@GetMapping("/exportLineRank")
public void exportLineRank(HttpServletResponse response, ExecutionOutboundRankDTO executionOutboundRankDTO) throws Exception {
- //转换实体(不分页,导出全量)
+ //转换实体(不分页,导出全量;线路tab:商品/线路筛选参数均生效,按线路+物料编码合并)
ExecutionOutboundRankDO executionOutboundRankDO = executionOutboundRankAssembler.toDO(executionOutboundRankDTO);
- //线路tab:忽略商品筛选参数
- executionOutboundRankDO.setMaterialCode(null);
- executionOutboundRankDO.setMaterialName(null);
- List list = executionOutboundRankApplicationService.exportDetailList(executionOutboundRankDO);
+ List list = executionOutboundRankApplicationService.exportLineRankList(executionOutboundRankDO);
String fileName = URLEncoder.encode("线路出库排名", "UTF-8").replaceAll("\\+", "%20");
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
- ExcelUtil util = new ExcelUtil<>(ExecutionOutboundDetailRankPO.class);
+ ExcelUtil util = new ExcelUtil<>(ExecutionOutboundLineRankPO.class);
util.exportExcel(response, list, "线路出库排名");
}
/**
- * 分页结果 + 合计行:data/total/code/msg 之外追加 totalPieceCount/totalGrossWeightTon/totalVolume/totalOrderCount
+ * 分页结果 + 合计行:data/total/code/msg 之外追加合计字段(商品tab含 totalOrderCount,线路tab含 totalOrderCount/totalLineCount)
*/
private HashMap getDataTableWithTotal(List> list, ExecutionOutboundDetailRankTotalPO total) {
HashMap result = new HashMap<>();
@@ -137,7 +135,12 @@ public class ExecutionOutboundRankApi {
result.put("totalPieceCount", total.getTotalPieceCount());
result.put("totalGrossWeightTon", total.getTotalGrossWeightTon());
result.put("totalVolume", total.getTotalVolume());
- result.put("totalOrderCount", total.getTotalOrderCount());
+ if (total.getTotalOrderCount() != null) {
+ result.put("totalOrderCount", total.getTotalOrderCount());
+ }
+ if (total.getTotalLineCount() != null) {
+ result.put("totalLineCount", total.getTotalLineCount());
+ }
}
return result;
}
diff --git a/mhd_oms/src/main/resources/mapper/outboundRank/ExecutionOutboundRankMapper.xml b/mhd_oms/src/main/resources/mapper/outboundRank/ExecutionOutboundRankMapper.xml
index 62df4931f..260bf0f80 100644
--- a/mhd_oms/src/main/resources/mapper/outboundRank/ExecutionOutboundRankMapper.xml
+++ b/mhd_oms/src/main/resources/mapper/outboundRank/ExecutionOutboundRankMapper.xml
@@ -5,15 +5,17 @@
a.del_flag = 1
@@ -62,50 +64,70 @@
join NGWL_TEST_WMS.stock_out_order b on a.out_order_number = b.out_order_number and b.del_flag = 1
-
-
diff --git a/mhd_wms/src/main/java/com/mhd/wms/application/service/outboundRank/OutboundRankApplicationService.java b/mhd_wms/src/main/java/com/mhd/wms/application/service/outboundRank/OutboundRankApplicationService.java
index 0082a8ed4..d6980900f 100644
--- a/mhd_wms/src/main/java/com/mhd/wms/application/service/outboundRank/OutboundRankApplicationService.java
+++ b/mhd_wms/src/main/java/com/mhd/wms/application/service/outboundRank/OutboundRankApplicationService.java
@@ -6,8 +6,9 @@ import com.mhd.common.security.utils.SecurityUtils;
import com.mhd.system.api.domain.cache.AssociationWarehouseCacheDO;
import com.mhd.system.api.domain.cache.SystemServiceCacheUtil;
import com.mhd.system.api.model.LoginUser;
-import com.mhd.wms.domain.outboundRank.repository.po.OutboundDetailRankPO;
import com.mhd.wms.domain.outboundRank.repository.po.OutboundDetailRankTotalPO;
+import com.mhd.wms.domain.outboundRank.repository.po.OutboundLineRankPO;
+import com.mhd.wms.domain.outboundRank.repository.po.OutboundMaterialRankPO;
import com.mhd.wms.domain.outboundRank.repository.todo.OutboundRankDO;
import com.mhd.wms.domain.outboundRank.service.OutboundRankDomainService;
import lombok.extern.slf4j.Slf4j;
@@ -17,7 +18,7 @@ import org.springframework.stereotype.Service;
import java.util.List;
/**
- * 出库排名统计(明细)应用服务
+ * 出库排名统计应用服务
*
* 负责登录用户组织隔离注入、日期区间校验,查询逻辑在 OutboundRankDomainService → OutboundRankMapper.xml
*
@@ -32,26 +33,49 @@ public class OutboundRankApplicationService {
private OutboundRankDomainService outboundRankDomainService;
/**
- * 分页查询出库明细列表
+ * 分页查询商品出库排名列表(货品聚合)
*/
- public List queryDetailList(OutboundRankDO outboundRankDO) {
+ public List queryMaterialRankList(OutboundRankDO outboundRankDO) {
fillLoginContext(outboundRankDO);
- return outboundRankDomainService.queryDetailList(outboundRankDO);
+ return outboundRankDomainService.queryMaterialRankList(outboundRankDO);
}
/**
- * 出库明细合计(当前筛选条件全量,不分页)
+ * 商品出库排名合计(当前筛选条件全量,不分页)
*/
- public OutboundDetailRankTotalPO queryDetailTotal(OutboundRankDO outboundRankDO) {
- return outboundRankDomainService.queryDetailTotal(outboundRankDO);
+ public OutboundDetailRankTotalPO queryMaterialRankTotal(OutboundRankDO outboundRankDO) {
+ return outboundRankDomainService.queryMaterialRankTotal(outboundRankDO);
}
/**
- * 导出出库明细(不分页全量)
+ * 导出商品出库排名(不分页全量)
*/
- public List exportDetailList(OutboundRankDO outboundRankDO) {
+ public List exportMaterialRankList(OutboundRankDO outboundRankDO) {
fillLoginContext(outboundRankDO);
- return outboundRankDomainService.queryDetailList(outboundRankDO);
+ return outboundRankDomainService.queryMaterialRankList(outboundRankDO);
+ }
+
+ /**
+ * 分页查询线路出库排名列表(线路×货品聚合)
+ */
+ public List queryLineRankList(OutboundRankDO outboundRankDO) {
+ fillLoginContext(outboundRankDO);
+ return outboundRankDomainService.queryLineRankList(outboundRankDO);
+ }
+
+ /**
+ * 线路出库排名合计(当前筛选条件全量,不分页)
+ */
+ public OutboundDetailRankTotalPO queryLineRankTotal(OutboundRankDO outboundRankDO) {
+ return outboundRankDomainService.queryLineRankTotal(outboundRankDO);
+ }
+
+ /**
+ * 导出线路出库排名(不分页全量)
+ */
+ public List exportLineRankList(OutboundRankDO outboundRankDO) {
+ fillLoginContext(outboundRankDO);
+ return outboundRankDomainService.queryLineRankList(outboundRankDO);
}
/**
diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/facade/IOutboundRankService.java b/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/facade/IOutboundRankService.java
index f20e1a989..2bc25d4a3 100644
--- a/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/facade/IOutboundRankService.java
+++ b/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/facade/IOutboundRankService.java
@@ -1,13 +1,14 @@
package com.mhd.wms.domain.outboundRank.repository.facade;
-import com.mhd.wms.domain.outboundRank.repository.po.OutboundDetailRankPO;
import com.mhd.wms.domain.outboundRank.repository.po.OutboundDetailRankTotalPO;
+import com.mhd.wms.domain.outboundRank.repository.po.OutboundLineRankPO;
+import com.mhd.wms.domain.outboundRank.repository.po.OutboundMaterialRankPO;
import com.mhd.wms.domain.outboundRank.repository.todo.OutboundRankDO;
import java.util.List;
/**
- * 出库排名统计(明细)Service接口
+ * 出库排名统计Service接口
*
* @author rcx
* @date 2026-08-31
@@ -15,12 +16,22 @@ import java.util.List;
public interface IOutboundRankService {
/**
- * 出库明细列表
+ * 商品出库排名列表(货品聚合)
*/
- List queryDetailList(OutboundRankDO outboundRankDO);
+ List queryMaterialRankList(OutboundRankDO outboundRankDO);
/**
- * 出库明细合计(不分页)
+ * 商品出库排名合计(不分页)
*/
- OutboundDetailRankTotalPO queryDetailTotal(OutboundRankDO outboundRankDO);
+ OutboundDetailRankTotalPO queryMaterialRankTotal(OutboundRankDO outboundRankDO);
+
+ /**
+ * 线路出库排名列表(线路×货品聚合)
+ */
+ List queryLineRankList(OutboundRankDO outboundRankDO);
+
+ /**
+ * 线路出库排名合计(不分页)
+ */
+ OutboundDetailRankTotalPO queryLineRankTotal(OutboundRankDO outboundRankDO);
}
diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/mapper/OutboundRankMapper.java b/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/mapper/OutboundRankMapper.java
index ee09b891f..ff5f702d8 100644
--- a/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/mapper/OutboundRankMapper.java
+++ b/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/mapper/OutboundRankMapper.java
@@ -1,13 +1,14 @@
package com.mhd.wms.domain.outboundRank.repository.mapper;
-import com.mhd.wms.domain.outboundRank.repository.po.OutboundDetailRankPO;
import com.mhd.wms.domain.outboundRank.repository.po.OutboundDetailRankTotalPO;
+import com.mhd.wms.domain.outboundRank.repository.po.OutboundLineRankPO;
+import com.mhd.wms.domain.outboundRank.repository.po.OutboundMaterialRankPO;
import com.mhd.wms.domain.outboundRank.repository.todo.OutboundRankDO;
import java.util.List;
/**
- * 出库排名统计(明细)Mapper接口
+ * 出库排名统计Mapper接口
*
* @author rcx
* @date 2026-08-31
@@ -15,12 +16,22 @@ import java.util.List;
public interface OutboundRankMapper {
/**
- * 出库明细列表(一行=仓单×货品,按件数倒序)
+ * 商品出库排名列表(一行=一个货品,跨单汇总,按实际出库量降序)
*/
- List queryDetailList(OutboundRankDO outboundRankDO);
+ List queryMaterialRankList(OutboundRankDO outboundRankDO);
/**
- * 出库明细合计(不分页,当前筛选条件全量合计)
+ * 商品出库排名合计(不分页,当前筛选条件全量合计)
*/
- OutboundDetailRankTotalPO queryDetailTotal(OutboundRankDO outboundRankDO);
+ OutboundDetailRankTotalPO queryMaterialRankTotal(OutboundRankDO outboundRankDO);
+
+ /**
+ * 线路出库排名列表(一行=线路×货品,按实际出库量降序,仅统计带线路的单)
+ */
+ List queryLineRankList(OutboundRankDO outboundRankDO);
+
+ /**
+ * 线路出库排名合计(不分页,当前筛选条件全量合计)
+ */
+ OutboundDetailRankTotalPO queryLineRankTotal(OutboundRankDO outboundRankDO);
}
diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/persistence/OutboundRankImpl.java b/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/persistence/OutboundRankImpl.java
index 4108d2dd4..6555dc647 100644
--- a/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/persistence/OutboundRankImpl.java
+++ b/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/persistence/OutboundRankImpl.java
@@ -2,8 +2,9 @@ package com.mhd.wms.domain.outboundRank.repository.persistence;
import com.mhd.wms.domain.outboundRank.repository.facade.IOutboundRankService;
import com.mhd.wms.domain.outboundRank.repository.mapper.OutboundRankMapper;
-import com.mhd.wms.domain.outboundRank.repository.po.OutboundDetailRankPO;
import com.mhd.wms.domain.outboundRank.repository.po.OutboundDetailRankTotalPO;
+import com.mhd.wms.domain.outboundRank.repository.po.OutboundLineRankPO;
+import com.mhd.wms.domain.outboundRank.repository.po.OutboundMaterialRankPO;
import com.mhd.wms.domain.outboundRank.repository.todo.OutboundRankDO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -11,7 +12,7 @@ import org.springframework.stereotype.Service;
import java.util.List;
/**
- * 出库排名统计(明细)Service业务层处理
+ * 出库排名统计Service业务层处理
*
* @author rcx
* @date 2026-08-31
@@ -23,12 +24,22 @@ public class OutboundRankImpl implements IOutboundRankService {
private OutboundRankMapper outboundRankMapper;
@Override
- public List queryDetailList(OutboundRankDO outboundRankDO) {
- return outboundRankMapper.queryDetailList(outboundRankDO);
+ public List queryMaterialRankList(OutboundRankDO outboundRankDO) {
+ return outboundRankMapper.queryMaterialRankList(outboundRankDO);
}
@Override
- public OutboundDetailRankTotalPO queryDetailTotal(OutboundRankDO outboundRankDO) {
- return outboundRankMapper.queryDetailTotal(outboundRankDO);
+ public OutboundDetailRankTotalPO queryMaterialRankTotal(OutboundRankDO outboundRankDO) {
+ return outboundRankMapper.queryMaterialRankTotal(outboundRankDO);
+ }
+
+ @Override
+ public List queryLineRankList(OutboundRankDO outboundRankDO) {
+ return outboundRankMapper.queryLineRankList(outboundRankDO);
+ }
+
+ @Override
+ public OutboundDetailRankTotalPO queryLineRankTotal(OutboundRankDO outboundRankDO) {
+ return outboundRankMapper.queryLineRankTotal(outboundRankDO);
}
}
diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/po/OutboundDetailRankPO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/po/OutboundDetailRankPO.java
deleted file mode 100644
index 4be88b6a7..000000000
--- a/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/po/OutboundDetailRankPO.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package com.mhd.wms.domain.outboundRank.repository.po;
-
-import com.fasterxml.jackson.annotation.JsonFormat;
-import com.mhd.common.core.annotation.Excel;
-import io.swagger.annotations.ApiModel;
-import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
-import org.springframework.format.annotation.DateTimeFormat;
-
-import java.io.Serializable;
-import java.math.BigDecimal;
-import java.util.Date;
-
-/**
- * 出库排名统计(明细)PO(一行 = 仓单×货品,件数/毛重/体积按行汇总)
- *
- * 字段口径:种类=出库单据类型;仓单编号=出库单号;收货人=出库单 TO 栏(为空取联系人);
- * 毛重(吨)=明细总毛重KG/1000;出仓日期=出仓日期(为空依次兜底完成时间/创建时间);
- * 退保总额为占位字段,后端暂无对应数据来源,恒为 null(候选:货品档案保额 insure_amount,确认后可补)
- *
- * @author rcx
- * @date 2026-08-31
- */
-@Data
-@ApiModel(value = "出库排名统计明细对象", description = "出库排名统计明细响应对象")
-public class OutboundDetailRankPO implements Serializable {
-
- private static final long serialVersionUID = 1L;
-
- @ApiModelProperty("种类(出库单据类型)")
- @Excel(name = "种类")
- private String orderTypeName;
-
- @ApiModelProperty("仓单编号(出库单号)")
- @Excel(name = "仓单编号")
- private String outOrderNumber;
-
- @ApiModelProperty("入库单号")
- @Excel(name = "入库单号")
- private String inOrderNumber;
-
- @ApiModelProperty("客户编号")
- @Excel(name = "客户编号")
- private String customerCode;
-
- @ApiModelProperty("收货人(出库单 TO 栏,为空取联系人)")
- @Excel(name = "收货人")
- private String receiver;
-
- @ApiModelProperty("商品货号(辅助字段,不导出)")
- private String materialCode;
-
- @ApiModelProperty("货名")
- @Excel(name = "货名")
- private String materialName;
-
- @ApiModelProperty("线路编码(辅助字段,不导出)")
- private String lineCode;
-
- @ApiModelProperty("线路")
- @Excel(name = "线路")
- private String lineName;
-
- @ApiModelProperty("件数(复核确认的实际出库量合计,与入库排名的实际上架量对称)")
- @Excel(name = "件数")
- private BigDecimal pieceCount;
-
- @ApiModelProperty("毛重(吨)")
- @Excel(name = "毛重(吨)")
- private BigDecimal grossWeightTon;
-
- @ApiModelProperty("体积(CBM)")
- @Excel(name = "体积(CBM)")
- private BigDecimal totalVolume;
-
- @ApiModelProperty("退保总额(占位字段,后端暂无数据来源,恒为 null)")
- @Excel(name = "退保总额")
- private BigDecimal depositRefundAmount;
-
- @ApiModelProperty("出仓日期(出仓日期为空时依次兜底完成时间/创建时间)")
- @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
- @DateTimeFormat(pattern = "yyyy-MM-dd")
- @Excel(name = "出仓日期", width = 30, dateFormat = "yyyy-MM-dd")
- private Date outboundDate;
-}
diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/po/OutboundDetailRankTotalPO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/po/OutboundDetailRankTotalPO.java
index 5b37776c7..397126046 100644
--- a/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/po/OutboundDetailRankTotalPO.java
+++ b/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/po/OutboundDetailRankTotalPO.java
@@ -33,4 +33,7 @@ public class OutboundDetailRankTotalPO implements Serializable {
@ApiModelProperty("仓单数合计(去重出库单数)")
private Long totalOrderCount;
+
+ @ApiModelProperty("线路数合计(去重线路数,线路排名使用)")
+ private Long totalLineCount;
}
diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/po/OutboundLineRankPO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/po/OutboundLineRankPO.java
new file mode 100644
index 000000000..38b7ecc4a
--- /dev/null
+++ b/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/po/OutboundLineRankPO.java
@@ -0,0 +1,59 @@
+package com.mhd.wms.domain.outboundRank.repository.po;
+
+import com.mhd.common.core.annotation.Excel;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * 线路出库排名PO(一行 = 线路×货品,日期区间内汇总)
+ *
+ * 按线路+物料编码合并:多张出库单合并为一行,单据级字段(种类/仓单编号/入库单号/客户编号/收货人/出仓日期)不提供;
+ * 仅统计带线路的出库单(line_code 为 2026-08-20 新增冗余字段,历史单为空,不参与线路排名);
+ * 件数 = SUM(CHECK_QUANTITY) 复核确认的实际出库量(与入库排名的实际上架量对称);
+ * 退保总额为占位字段,后端暂无对应数据来源,恒为 null
+ *
+ * @author rcx
+ * @date 2026-08-31
+ */
+@Data
+@ApiModel(value = "线路出库排名对象", description = "线路出库排名响应对象")
+public class OutboundLineRankPO implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty("线路编码")
+ @Excel(name = "线路编码")
+ private String lineCode;
+
+ @ApiModelProperty("线路")
+ @Excel(name = "线路")
+ private String lineName;
+
+ @ApiModelProperty("商品货号")
+ @Excel(name = "商品货号")
+ private String materialCode;
+
+ @ApiModelProperty("货名")
+ @Excel(name = "货名")
+ private String materialName;
+
+ @ApiModelProperty("件数(复核确认的实际出库量合计,与入库排名的实际上架量对称)")
+ @Excel(name = "件数")
+ private BigDecimal pieceCount;
+
+ @ApiModelProperty("毛重(吨)")
+ @Excel(name = "毛重(吨)")
+ private BigDecimal grossWeightTon;
+
+ @ApiModelProperty("体积(CBM)")
+ @Excel(name = "体积(CBM)")
+ private BigDecimal totalVolume;
+
+ @ApiModelProperty("退保总额(占位字段,后端暂无数据来源,恒为 null)")
+ @Excel(name = "退保总额")
+ private BigDecimal depositRefundAmount;
+}
diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/po/OutboundMaterialRankPO.java b/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/po/OutboundMaterialRankPO.java
new file mode 100644
index 000000000..d58cac1d5
--- /dev/null
+++ b/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/repository/po/OutboundMaterialRankPO.java
@@ -0,0 +1,50 @@
+package com.mhd.wms.domain.outboundRank.repository.po;
+
+import com.mhd.common.core.annotation.Excel;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * 商品出库排名PO(一行 = 一个货品,日期区间内跨出库单汇总)
+ *
+ * 按物料编码合并:一个货品会走多条线路/多张单,单据级字段(种类/仓单编号/入库单号/客户编号/收货人/出仓日期)与
+ * 线路字段均无单值可返,不提供;件数 = SUM(CHECK_QUANTITY) 复核确认的实际出库量(与入库排名的实际上架量对称);
+ * 退保总额为占位字段,后端暂无对应数据来源,恒为 null
+ *
+ * @author rcx
+ * @date 2026-08-31
+ */
+@Data
+@ApiModel(value = "商品出库排名对象", description = "商品出库排名响应对象")
+public class OutboundMaterialRankPO implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty("商品货号")
+ @Excel(name = "商品货号")
+ private String materialCode;
+
+ @ApiModelProperty("货名")
+ @Excel(name = "货名")
+ private String materialName;
+
+ @ApiModelProperty("件数(复核确认的实际出库量合计,与入库排名的实际上架量对称)")
+ @Excel(name = "件数")
+ private BigDecimal pieceCount;
+
+ @ApiModelProperty("毛重(吨)")
+ @Excel(name = "毛重(吨)")
+ private BigDecimal grossWeightTon;
+
+ @ApiModelProperty("体积(CBM)")
+ @Excel(name = "体积(CBM)")
+ private BigDecimal totalVolume;
+
+ @ApiModelProperty("退保总额(占位字段,后端暂无数据来源,恒为 null)")
+ @Excel(name = "退保总额")
+ private BigDecimal depositRefundAmount;
+}
diff --git a/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/service/OutboundRankDomainService.java b/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/service/OutboundRankDomainService.java
index 0b21ed65e..18af50291 100644
--- a/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/service/OutboundRankDomainService.java
+++ b/mhd_wms/src/main/java/com/mhd/wms/domain/outboundRank/service/OutboundRankDomainService.java
@@ -1,8 +1,9 @@
package com.mhd.wms.domain.outboundRank.service;
import com.mhd.wms.domain.outboundRank.repository.facade.IOutboundRankService;
-import com.mhd.wms.domain.outboundRank.repository.po.OutboundDetailRankPO;
import com.mhd.wms.domain.outboundRank.repository.po.OutboundDetailRankTotalPO;
+import com.mhd.wms.domain.outboundRank.repository.po.OutboundLineRankPO;
+import com.mhd.wms.domain.outboundRank.repository.po.OutboundMaterialRankPO;
import com.mhd.wms.domain.outboundRank.repository.todo.OutboundRankDO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@@ -11,7 +12,7 @@ import org.springframework.stereotype.Service;
import java.util.List;
/**
- * 出库排名统计(明细)领域服务
+ * 出库排名统计领域服务
*
* @author rcx
* @date 2026-08-31
@@ -24,16 +25,30 @@ public class OutboundRankDomainService {
private IOutboundRankService outboundRankService;
/**
- * 出库明细列表
+ * 商品出库排名列表(货品聚合)
*/
- public List queryDetailList(OutboundRankDO outboundRankDO) {
- return outboundRankService.queryDetailList(outboundRankDO);
+ public List queryMaterialRankList(OutboundRankDO outboundRankDO) {
+ return outboundRankService.queryMaterialRankList(outboundRankDO);
}
/**
- * 出库明细合计(不分页)
+ * 商品出库排名合计(不分页)
*/
- public OutboundDetailRankTotalPO queryDetailTotal(OutboundRankDO outboundRankDO) {
- return outboundRankService.queryDetailTotal(outboundRankDO);
+ public OutboundDetailRankTotalPO queryMaterialRankTotal(OutboundRankDO outboundRankDO) {
+ return outboundRankService.queryMaterialRankTotal(outboundRankDO);
+ }
+
+ /**
+ * 线路出库排名列表(线路×货品聚合)
+ */
+ public List queryLineRankList(OutboundRankDO outboundRankDO) {
+ return outboundRankService.queryLineRankList(outboundRankDO);
+ }
+
+ /**
+ * 线路出库排名合计(不分页)
+ */
+ public OutboundDetailRankTotalPO queryLineRankTotal(OutboundRankDO outboundRankDO) {
+ return outboundRankService.queryLineRankTotal(outboundRankDO);
}
}
diff --git a/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/outboundRank/OutboundRankApi.java b/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/outboundRank/OutboundRankApi.java
index a7cccda65..649e3906a 100644
--- a/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/outboundRank/OutboundRankApi.java
+++ b/mhd_wms/src/main/java/com/mhd/wms/interfaces/facadeApi/outboundRank/OutboundRankApi.java
@@ -5,8 +5,9 @@ import com.mhd.common.core.constant.HttpStatus;
import com.mhd.common.core.utils.PageUtils;
import com.mhd.common.core.utils.poi.ExcelUtil;
import com.mhd.wms.application.service.outboundRank.OutboundRankApplicationService;
-import com.mhd.wms.domain.outboundRank.repository.po.OutboundDetailRankPO;
import com.mhd.wms.domain.outboundRank.repository.po.OutboundDetailRankTotalPO;
+import com.mhd.wms.domain.outboundRank.repository.po.OutboundLineRankPO;
+import com.mhd.wms.domain.outboundRank.repository.po.OutboundMaterialRankPO;
import com.mhd.wms.domain.outboundRank.repository.todo.OutboundRankDO;
import com.mhd.wms.interfaces.assember.outboundRank.OutboundRankAssembler;
import com.mhd.wms.interfaces.dto.outboundRank.OutboundRankDTO;
@@ -25,10 +26,13 @@ import java.util.List;
/**
* 出库排名统计Api
*
- * 按日期区间筛选出库明细列表(一行 = 仓单×货品,件数/毛重/体积按行汇总,按件数(实际复核出库量)降序,出仓日期/单号次之)。
- * 统计口径:出库单创建时间 + 已出库及之后状态(9,12,13),明细仅取 level=1 主行。
- * 商品/线路两个 tab 各自独立接口,内部为同一份明细查询:商品接口忽略线路筛选参数,线路接口忽略商品筛选参数。
- * 字段:种类/仓单编号/入库单号/客户编号/收货人/货名/线路/件数/毛重(吨)/体积(CBM)/退保总额(占位null)/出仓日期
+ * 按日期区间筛选出库量统计排名,按出库数量(实际复核出库量)降序。
+ * 商品tab:一行 = 一个货品(货号/货名/件数/毛重(吨)/体积(CBM)/退保总额占位),跨出库单汇总,忽略线路筛选参数;
+ * 线路tab:一行 = 线路×货品(线路编码/线路/货号/货名/件数/毛重(吨)/体积(CBM)/退保总额占位),按线路+物料编码合并,
+ * 仅统计带线路的单,商品/线路筛选参数均生效;
+ * 统计口径:出库单创建时间 + 已出库及之后状态(9,12,13),明细仅取 level=1 主行;
+ * 件数 = SUM(CHECK_QUANTITY) 复核确认的实际出库量(与入库排名的实际上架量对称);
+ * 退保总额后端暂无对应数据来源,恒为 null
*
* @author rcx
* @date 2026-08-31
@@ -55,25 +59,22 @@ public class OutboundRankApi {
outboundRankDO.setLineCode(null);
outboundRankDO.setLineName(null);
startPage();
- List list = outboundRankApplicationService.queryDetailList(outboundRankDO);
- OutboundDetailRankTotalPO total = outboundRankApplicationService.queryDetailTotal(outboundRankDO);
+ List list = outboundRankApplicationService.queryMaterialRankList(outboundRankDO);
+ OutboundDetailRankTotalPO total = outboundRankApplicationService.queryMaterialRankTotal(outboundRankDO);
return getDataTableWithTotal(list, total);
}
/**
- * 分页查询线路出库排名列表(含合计行,线路tab;忽略商品筛选参数)
+ * 分页查询线路出库排名列表(含合计行,线路tab;一行=线路×货品,仅统计带线路的单)
*/
@ApiOperation("分页查询线路出库排名列表")
@GetMapping("/queryLineRankList")
public HashMap queryLineRankList(OutboundRankDTO outboundRankDTO) {
- //转换实体
+ //转换实体(线路tab:商品/线路筛选参数均生效,按线路+物料编码合并)
OutboundRankDO outboundRankDO = outboundRankAssembler.toDO(outboundRankDTO);
- //线路tab:忽略商品筛选参数
- outboundRankDO.setMaterialCode(null);
- outboundRankDO.setMaterialName(null);
startPage();
- List list = outboundRankApplicationService.queryDetailList(outboundRankDO);
- OutboundDetailRankTotalPO total = outboundRankApplicationService.queryDetailTotal(outboundRankDO);
+ List list = outboundRankApplicationService.queryLineRankList(outboundRankDO);
+ OutboundDetailRankTotalPO total = outboundRankApplicationService.queryLineRankTotal(outboundRankDO);
return getDataTableWithTotal(list, total);
}
@@ -88,41 +89,38 @@ public class OutboundRankApi {
//商品tab:忽略线路筛选参数
outboundRankDO.setLineCode(null);
outboundRankDO.setLineName(null);
- List list = outboundRankApplicationService.exportDetailList(outboundRankDO);
+ List list = outboundRankApplicationService.exportMaterialRankList(outboundRankDO);
String fileName = URLEncoder.encode("商品出库排名", "UTF-8").replaceAll("\\+", "%20");
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
- ExcelUtil util = new ExcelUtil<>(OutboundDetailRankPO.class);
+ ExcelUtil util = new ExcelUtil<>(OutboundMaterialRankPO.class);
util.exportExcel(response, list, "商品出库排名");
}
/**
- * 导出线路出库排名Excel(线路tab;忽略商品筛选参数)
+ * 导出线路出库排名Excel(线路tab;一行=线路×货品,仅统计带线路的单)
*/
@ApiOperation("导出线路出库排名Excel")
@GetMapping("/exportLineRank")
public void exportLineRank(HttpServletResponse response, OutboundRankDTO outboundRankDTO) throws Exception {
- //转换实体(不分页,导出全量)
+ //转换实体(不分页,导出全量;线路tab:商品/线路筛选参数均生效,按线路+物料编码合并)
OutboundRankDO outboundRankDO = outboundRankAssembler.toDO(outboundRankDTO);
- //线路tab:忽略商品筛选参数
- outboundRankDO.setMaterialCode(null);
- outboundRankDO.setMaterialName(null);
- List list = outboundRankApplicationService.exportDetailList(outboundRankDO);
+ List list = outboundRankApplicationService.exportLineRankList(outboundRankDO);
String fileName = URLEncoder.encode("线路出库排名", "UTF-8").replaceAll("\\+", "%20");
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
- ExcelUtil util = new ExcelUtil<>(OutboundDetailRankPO.class);
+ ExcelUtil util = new ExcelUtil<>(OutboundLineRankPO.class);
util.exportExcel(response, list, "线路出库排名");
}
/**
- * 分页结果 + 合计行:data/total/code/msg 之外追加 totalPieceCount/totalGrossWeightTon/totalVolume/totalOrderCount
+ * 分页结果 + 合计行:data/total/code/msg 之外追加合计字段(商品tab含 totalOrderCount,线路tab含 totalOrderCount/totalLineCount)
*/
private HashMap getDataTableWithTotal(List> list, OutboundDetailRankTotalPO total) {
HashMap result = new HashMap<>();
@@ -134,7 +132,12 @@ public class OutboundRankApi {
result.put("totalPieceCount", total.getTotalPieceCount());
result.put("totalGrossWeightTon", total.getTotalGrossWeightTon());
result.put("totalVolume", total.getTotalVolume());
- result.put("totalOrderCount", total.getTotalOrderCount());
+ if (total.getTotalOrderCount() != null) {
+ result.put("totalOrderCount", total.getTotalOrderCount());
+ }
+ if (total.getTotalLineCount() != null) {
+ result.put("totalLineCount", total.getTotalLineCount());
+ }
}
return result;
}
diff --git a/mhd_wms/src/main/resources/mapper/outboundRank/OutboundRankMapper.xml b/mhd_wms/src/main/resources/mapper/outboundRank/OutboundRankMapper.xml
index 095d5eba0..b35a01337 100644
--- a/mhd_wms/src/main/resources/mapper/outboundRank/OutboundRankMapper.xml
+++ b/mhd_wms/src/main/resources/mapper/outboundRank/OutboundRankMapper.xml
@@ -5,12 +5,13 @@
a.del_flag = 1
@@ -62,50 +63,70 @@
join stock_out_order b on a.out_order_number = b.out_order_number and b.del_flag = 1
-
-
+
+
select
- MAX(b.ORDER_TYPE_NAME) AS orderTypeName,
- b.out_order_number AS outOrderNumber,
- MAX(a.in_order_number) AS inOrderNumber,
- MAX(b.customer_code) AS customerCode,
- MAX(IFNULL(b."TO", b.contact_person)) AS receiver,
a.material_code AS materialCode,
MAX(a.material_name) AS materialName,
- MAX(b.line_code) AS lineCode,
- MAX(b.line_name) AS lineName,
IFNULL(SUM(a.CHECK_QUANTITY), 0) AS pieceCount,
ROUND(IFNULL(SUM(a.TOTAL_GROSS_WEIGHT), 0) / 1000, 3) AS grossWeightTon,
- IFNULL(SUM(a.TOTAL_VOLUME), 0) AS totalVolume,
- MAX(IFNULL(b.OUTBOUND_DATE, IFNULL(b.COMPLETE_TIME, b.create_time))) AS outboundDate
+ IFNULL(SUM(a.TOTAL_VOLUME), 0) AS totalVolume
- GROUP BY b.out_order_number, a.material_code
- order by pieceCount desc, outboundDate desc, outOrderNumber desc
+ GROUP BY a.material_code
+ order by pieceCount desc, materialCode asc
-
-
+
select
- IFNULL(SUM(t.pieceCount), 0) AS totalPieceCount,
- ROUND(IFNULL(SUM(t.grossWeightKG), 0) / 1000, 3) AS totalGrossWeightTon,
- IFNULL(SUM(t.totalVolume), 0) AS totalVolume,
- COUNT(DISTINCT t.outOrderNumber) AS totalOrderCount
- from (
- select
- b.out_order_number AS outOrderNumber,
- IFNULL(SUM(a.CHECK_QUANTITY), 0) AS pieceCount,
- IFNULL(SUM(a.TOTAL_GROSS_WEIGHT), 0) AS grossWeightKG,
- IFNULL(SUM(a.TOTAL_VOLUME), 0) AS totalVolume
-
-
-
-
- GROUP BY b.out_order_number, a.material_code
- ) t
+ IFNULL(SUM(a.CHECK_QUANTITY), 0) AS totalPieceCount,
+ ROUND(IFNULL(SUM(a.TOTAL_GROSS_WEIGHT), 0) / 1000, 3) AS totalGrossWeightTon,
+ IFNULL(SUM(a.TOTAL_VOLUME), 0) AS totalVolume,
+ COUNT(DISTINCT a.out_order_number) AS totalOrderCount
+
+
+
+
+
+
+
+
+ select
+ b.line_code AS lineCode,
+ MAX(b.line_name) AS lineName,
+ a.material_code AS materialCode,
+ MAX(a.material_name) AS materialName,
+ IFNULL(SUM(a.CHECK_QUANTITY), 0) AS pieceCount,
+ ROUND(IFNULL(SUM(a.TOTAL_GROSS_WEIGHT), 0) / 1000, 3) AS grossWeightTon,
+ IFNULL(SUM(a.TOTAL_VOLUME), 0) AS totalVolume
+
+
+
+ and b.line_code is not null and b.line_code != ''
+
+ GROUP BY b.line_code, a.material_code
+ order by pieceCount desc, lineCode asc, materialCode asc
+
+
+
+
+ select
+ IFNULL(SUM(a.CHECK_QUANTITY), 0) AS totalPieceCount,
+ ROUND(IFNULL(SUM(a.TOTAL_GROSS_WEIGHT), 0) / 1000, 3) AS totalGrossWeightTon,
+ IFNULL(SUM(a.TOTAL_VOLUME), 0) AS totalVolume,
+ COUNT(DISTINCT b.line_code) AS totalLineCount,
+ COUNT(DISTINCT b.out_order_number) AS totalOrderCount
+
+
+
+ and b.line_code is not null and b.line_code != ''
+