Merge branch 'refs/heads/dev-ty1.2' into dev
This commit is contained in:
@@ -18,7 +18,7 @@ import java.util.Set;
|
||||
/**
|
||||
* bms财务结算系统feign调用接口
|
||||
*/
|
||||
@FeignClient(contextId = "BmsService", value = ServiceNameConstants.BMS_SERVICE, url = "http://10.102.192.3:8019",fallbackFactory = RemoteBmsFeignFallbackFactory.class, configuration = FeignAutoConfiguration.class)
|
||||
@FeignClient(contextId = "BmsService", value = ServiceNameConstants.BMS_SERVICE, url = "http://10.33.0.129:8012",fallbackFactory = RemoteBmsFeignFallbackFactory.class, configuration = FeignAutoConfiguration.class)
|
||||
public interface BmsServiceFeign {
|
||||
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import org.springframework.web.bind.annotation.RequestBody;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@FeignClient(contextId = "OmsService", value = ServiceNameConstants.OMS_SERVICE,url = "http://10.102.192.4:8017",fallbackFactory = RemoteOmsFeignFallbackFactory.class, configuration = FeignAutoConfiguration.class)
|
||||
@FeignClient(contextId = "OmsService", value = ServiceNameConstants.OMS_SERVICE,url = "http://10.33.0.99:8017",fallbackFactory = RemoteOmsFeignFallbackFactory.class, configuration = FeignAutoConfiguration.class)
|
||||
public interface OmsServiceFeign {
|
||||
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ import org.springframework.web.bind.annotation.*;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@FeignClient(contextId = "commonWlhyServiceFeign",url = "http://10.102.192.30:8014",value = ServiceNameConstants.WLHY_SERVICE,configuration = FeignAutoConfiguration.class)
|
||||
@FeignClient(contextId = "commonWlhyServiceFeign",value = ServiceNameConstants.WLHY_SERVICE,url = "http://10.33.0.129:8014",configuration = FeignAutoConfiguration.class)
|
||||
public interface WlhyServiceFeign {
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,7 +21,7 @@ import java.util.Map;
|
||||
* @description: TODO
|
||||
* @date 2024/5/10 8:58
|
||||
**/
|
||||
@FeignClient(contextId = "remoteWmsServiceFeign",value = ServiceNameConstants.WMS_SERVICE, url = "http://10.102.192.3:8016",fallbackFactory = RemoteWmsFallbackFactory.class, configuration = FeignAutoConfiguration.class)
|
||||
@FeignClient(contextId = "remoteWmsServiceFeign",value = ServiceNameConstants.WMS_SERVICE, url = "http://10.33.0.109:8016",fallbackFactory = RemoteWmsFallbackFactory.class, configuration = FeignAutoConfiguration.class)
|
||||
public interface WmsServiceFeign {
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,7 +9,7 @@ import com.mhd.system.api.feign.FeignAutoConfiguration;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@FeignClient(contextId = "YmsService", value = ServiceNameConstants.YMS_SERVICE,url = "http://10.102.192.4:8018",fallbackFactory = RemoteBmsFeignFallbackFactory.class, configuration = FeignAutoConfiguration.class)
|
||||
@FeignClient(contextId = "YmsService", value = ServiceNameConstants.YMS_SERVICE,url = "http://10.33.0.99:8018",fallbackFactory = RemoteBmsFeignFallbackFactory.class, configuration = FeignAutoConfiguration.class)
|
||||
public interface YmsServiceFeign {
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@FeignClient(value = "mhd-third-party-service",url = "http://10.102.192.30:8012", configuration = FeignAutoConfiguration.class)
|
||||
@FeignClient(value = "mhd-third-party-service",url = "http://10.33.0.129:8012",configuration = FeignAutoConfiguration.class)
|
||||
public interface ThirdPartyServiceFeign {
|
||||
|
||||
//查询当前组织所有三方接口信息
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ import java.util.List;
|
||||
public interface ExecutionInboundRankMapper {
|
||||
|
||||
/**
|
||||
* 商品入库排名列表(仓单+货品汇总,按件数降序)
|
||||
* 商品入库排名列表(按物料编码合并,按件数降序,过滤0件行)
|
||||
*/
|
||||
List<ExecutionInboundMaterialRankPO> queryMaterialRankList(ExecutionInboundRankDO executionInboundRankDO);
|
||||
|
||||
|
||||
+10
-31
@@ -1,24 +1,21 @@
|
||||
package com.mhd.oms.domain.inboundRank.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(一行 = 某仓单内某货品的合计,按件数降序排名)
|
||||
* 入库排名统计PO(一行 = 一个物料的合计(按物料编码合并,查询区间内全部已入库仓单),按件数降序排名)
|
||||
*
|
||||
* <p>数据源跨库取 WMS 入库表(NGWL_TEST_WMS.stock_in_order / in_material_detail,OMS 执行单状态/上架量不回传),
|
||||
* 口径与 WMS 端 /inboundRankApi 完全一致,两边数字一致。
|
||||
* 字段口径:入仓日期=WMS入仓单入仓日期(为空兜底建档时间);仓单编号=WMS入库单号;客户编号/存货人=入仓单货主;
|
||||
* 件数/毛重/体积=仓单内该货品明细合计(件数取实际上架量 SHELVES_QUANTITY);毛重(吨)=明细总毛重KG/1000;
|
||||
* 投保总额=货品档案保额(NGWL_TEST_WMS.material_base_info.insure_amount,组内取MAX防多批次明细行重复累加)</p>
|
||||
* 字段口径:件数=实际上架量(SHELVES_QUANTITY)合计;毛重(吨)=明细总毛重KG/1000;体积=明细合计;
|
||||
* 投保总额=货品档案保额(NGWL_TEST_WMS.material_base_info.insure_amount,物料维度单一值取MAX,不跨仓单累加);
|
||||
* 仓单编号/客户编号/存货人/入仓日期为单据级字段,按物料合并后单值失真,仅作查询条件不返回</p>
|
||||
*
|
||||
* @author rcx
|
||||
* @date 2026-08-31
|
||||
@@ -29,26 +26,8 @@ public class ExecutionInboundMaterialRankPO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty("入仓日期")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
@Excel(name = "入仓日期", width = 30, dateFormat = "yyyy-MM-dd")
|
||||
private Date warehouseDate;
|
||||
|
||||
@ApiModelProperty("仓单编号(WMS入库单号)")
|
||||
@Excel(name = "仓单编号")
|
||||
private String inOrderNumber;
|
||||
|
||||
@ApiModelProperty("客户编号")
|
||||
@Excel(name = "客户编号")
|
||||
private String shipperCode;
|
||||
|
||||
@ApiModelProperty("存货人(客户名称)")
|
||||
@Excel(name = "存货人")
|
||||
private String shipperName;
|
||||
|
||||
@ApiModelProperty("商品货号")
|
||||
@Excel(name = "商品货号")
|
||||
@ApiModelProperty("物料编码(合并依据)")
|
||||
@Excel(name = "物料编码")
|
||||
private String materialCode;
|
||||
|
||||
@ApiModelProperty("货名/商品名称")
|
||||
@@ -63,19 +42,19 @@ public class ExecutionInboundMaterialRankPO implements Serializable {
|
||||
@Excel(name = "单位")
|
||||
private String unitName;
|
||||
|
||||
@ApiModelProperty("件数(仓单内该货品实际上架量合计 SHELVES_QUANTITY,排名依据)")
|
||||
@ApiModelProperty("件数(该物料实际上架量合计 SHELVES_QUANTITY,排名依据)")
|
||||
@Excel(name = "件数")
|
||||
private BigDecimal pieceCount;
|
||||
|
||||
@ApiModelProperty("毛重(吨)(仓单内该货品合计,KG/1000)")
|
||||
@ApiModelProperty("毛重(吨)(该物料合计,KG/1000)")
|
||||
@Excel(name = "毛重(吨)")
|
||||
private BigDecimal grossWeightTon;
|
||||
|
||||
@ApiModelProperty("投保总额(货品档案保额)")
|
||||
@ApiModelProperty("投保总额(货品档案保额,物料维度单一值)")
|
||||
@Excel(name = "投保总额")
|
||||
private BigDecimal insureAmount;
|
||||
|
||||
@ApiModelProperty("体积(CBM)(仓单内该货品合计)")
|
||||
@ApiModelProperty("体积(CBM)(该物料合计)")
|
||||
@Excel(name = "体积(CBM)")
|
||||
private BigDecimal totalVolume;
|
||||
}
|
||||
|
||||
+2
-2
@@ -28,12 +28,12 @@ public class ExecutionInboundRankTotalPO implements Serializable {
|
||||
@ApiModelProperty("毛重(吨)合计")
|
||||
private BigDecimal totalGrossWeightTon;
|
||||
|
||||
@ApiModelProperty("投保总额合计(各仓单+货品行保额之和)")
|
||||
@ApiModelProperty("投保总额合计(各物料保额之和,每物料计一次)")
|
||||
private BigDecimal totalInsureAmount;
|
||||
|
||||
@ApiModelProperty("体积(CBM)合计")
|
||||
private BigDecimal totalVolume;
|
||||
|
||||
@ApiModelProperty("仓单数合计")
|
||||
@ApiModelProperty("涉及仓单数(当前筛选条件下去重统计)")
|
||||
private Long totalOrderCount;
|
||||
}
|
||||
|
||||
+22
-4
@@ -5,6 +5,7 @@ import com.mhd.oms.domain.reservationMaterialInventory.entity.ReservationMateria
|
||||
import com.mhd.oms.domain.reservationMaterialInventory.repository.mapper.ReservationMaterialInventoryMapper;
|
||||
import com.mhd.oms.domain.reservationStockInOrder.repository.mapper.ReservationStockInOrderMapper;
|
||||
import com.mhd.oms.domain.reservationStockInOrder.repository.po.MaterialBaseInfoPO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -13,6 +14,7 @@ import org.springframework.stereotype.Service;
|
||||
* 解决客户端推单把 materialInventoryId 传进 materialBaseInfoId 字段、或漏传导致明细存脏ID的问题。
|
||||
* 三级解析:1.按baseId直查 → 2.按库存ID反查纠正 → 3.按物料编码+组织兜底
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class MaterialBaseInfoResolveService {
|
||||
|
||||
@@ -30,11 +32,23 @@ public class MaterialBaseInfoResolveService {
|
||||
* @return 解析成功返回物料信息(调用方需用 po.getMaterialBaseInfoId() 回填纠正后的ID);全部失败返回 null
|
||||
*/
|
||||
public MaterialBaseInfoPO resolve(Long materialBaseInfoId, Long materialInventoryId, String materialCode, Long organizationId) {
|
||||
// 1. 优先按 baseId 直查(有效ID不受影响)
|
||||
// 1. 优先按 baseId 直查(有效ID不受影响)。
|
||||
// 防张冠李戴:客户端曾把库存ID传进 materialBaseInfoId,若该库存ID恰好撞上另一条有效档案的主键
|
||||
// (如库存1201撞上编码=名称的脏档案"水箱"),按ID查到的档案编码会与明细编码对不上。
|
||||
// 此时 baseId 不可信,继续走库存反查/编码兜底;两级都落空时才退回按ID查到的档案
|
||||
MaterialBaseInfoPO byId = null;
|
||||
if (materialBaseInfoId != null && materialBaseInfoId > 0) {
|
||||
MaterialBaseInfoPO po = reservationStockInOrderMapper.getinfo(materialBaseInfoId);
|
||||
if (po != null) {
|
||||
return po;
|
||||
if (StringUtils.isNotBlank(materialCode) && po.getMaterialCode() != null
|
||||
&& !po.getMaterialCode().trim().equals(materialCode.trim())) {
|
||||
log.warn("物料ID疑似误传:baseInfoId={} 按主键查到档案[{}({})],与明细编码[{}]不一致," +
|
||||
"转库存反查/编码兜底(客户端可能把库存ID传进了materialBaseInfoId)",
|
||||
materialBaseInfoId, po.getMaterialCode(), po.getMaterialName(), materialCode);
|
||||
byId = po;
|
||||
} else {
|
||||
return po;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 2. baseId 无效但带了库存ID → 反查库存表拿正确 baseInfoId(修复"库存ID传进baseId"场景)
|
||||
@@ -50,8 +64,12 @@ public class MaterialBaseInfoResolveService {
|
||||
}
|
||||
// 3. 兜底:按物料编码+组织查(修复 baseId=0 漏传场景)
|
||||
if (StringUtils.isNotBlank(materialCode) && organizationId != null) {
|
||||
return reservationStockInOrderMapper.getByCode(materialCode.trim(), organizationId);
|
||||
MaterialBaseInfoPO po = reservationStockInOrderMapper.getByCode(materialCode.trim(), organizationId);
|
||||
if (po != null) {
|
||||
return po;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
// 编码不一致已证明 baseId 不可信,但库存反查/编码兜底都落空时,退回按ID查到的档案,保持原有兜底行为
|
||||
return byId;
|
||||
}
|
||||
}
|
||||
|
||||
+17
-6
@@ -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<ExecutionOutboundDetailRankPO> queryDetailList(ExecutionOutboundRankDO executionOutboundRankDO);
|
||||
List<ExecutionOutboundMaterialRankPO> queryMaterialRankList(ExecutionOutboundRankDO executionOutboundRankDO);
|
||||
|
||||
/**
|
||||
* 出库明细合计(不分页)
|
||||
* 商品出库排名合计(不分页)
|
||||
*/
|
||||
ExecutionOutboundDetailRankTotalPO queryDetailTotal(ExecutionOutboundRankDO executionOutboundRankDO);
|
||||
ExecutionOutboundDetailRankTotalPO queryMaterialRankTotal(ExecutionOutboundRankDO executionOutboundRankDO);
|
||||
|
||||
/**
|
||||
* 线路出库排名列表(线路×货品聚合)
|
||||
*/
|
||||
List<ExecutionOutboundLineRankPO> queryLineRankList(ExecutionOutboundRankDO executionOutboundRankDO);
|
||||
|
||||
/**
|
||||
* 线路出库排名合计(不分页)
|
||||
*/
|
||||
ExecutionOutboundDetailRankTotalPO queryLineRankTotal(ExecutionOutboundRankDO executionOutboundRankDO);
|
||||
}
|
||||
|
||||
+17
-6
@@ -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<ExecutionOutboundDetailRankPO> queryDetailList(ExecutionOutboundRankDO executionOutboundRankDO);
|
||||
List<ExecutionOutboundMaterialRankPO> queryMaterialRankList(ExecutionOutboundRankDO executionOutboundRankDO);
|
||||
|
||||
/**
|
||||
* 出库明细合计(不分页,当前筛选条件全量合计)
|
||||
* 商品出库排名合计(不分页,当前筛选条件全量合计)
|
||||
*/
|
||||
ExecutionOutboundDetailRankTotalPO queryDetailTotal(ExecutionOutboundRankDO executionOutboundRankDO);
|
||||
ExecutionOutboundDetailRankTotalPO queryMaterialRankTotal(ExecutionOutboundRankDO executionOutboundRankDO);
|
||||
|
||||
/**
|
||||
* 线路出库排名列表(一行=线路×货品,按实际出库量降序,仅统计带线路的单)
|
||||
*/
|
||||
List<ExecutionOutboundLineRankPO> queryLineRankList(ExecutionOutboundRankDO executionOutboundRankDO);
|
||||
|
||||
/**
|
||||
* 线路出库排名合计(不分页,当前筛选条件全量合计)
|
||||
*/
|
||||
ExecutionOutboundDetailRankTotalPO queryLineRankTotal(ExecutionOutboundRankDO executionOutboundRankDO);
|
||||
}
|
||||
|
||||
+17
-6
@@ -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<ExecutionOutboundDetailRankPO> queryDetailList(ExecutionOutboundRankDO executionOutboundRankDO) {
|
||||
return executionOutboundRankMapper.queryDetailList(executionOutboundRankDO);
|
||||
public List<ExecutionOutboundMaterialRankPO> 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<ExecutionOutboundLineRankPO> queryLineRankList(ExecutionOutboundRankDO executionOutboundRankDO) {
|
||||
return executionOutboundRankMapper.queryLineRankList(executionOutboundRankDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecutionOutboundDetailRankTotalPO queryLineRankTotal(ExecutionOutboundRankDO executionOutboundRankDO) {
|
||||
return executionOutboundRankMapper.queryLineRankTotal(executionOutboundRankDO);
|
||||
}
|
||||
}
|
||||
|
||||
-85
@@ -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(一行 = 仓单×货品,件数/毛重/体积按行汇总)
|
||||
*
|
||||
* <p>字段口径:种类=出库单据类型;仓单编号=出库单号;收货人=出库单 TO 栏(为空取联系人);
|
||||
* 毛重(吨)=明细总毛重KG/1000;出仓日期=出仓日期(为空依次兜底完成时间/创建时间);
|
||||
* 退保总额为占位字段,后端暂无对应数据来源,恒为 null(候选:货品档案保额 insure_amount,确认后可补)</p>
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
+6
-3
@@ -8,16 +8,16 @@ import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 出库排名统计(明细)合计PO
|
||||
* 出库排名统计合计PO
|
||||
*
|
||||
* <p>当前筛选条件下不分页的全量合计,随分页列表一起返回
|
||||
* (totalPieceCount/totalGrossWeightTon/totalVolume/totalOrderCount)</p>
|
||||
* (totalPieceCount/totalGrossWeightTon/totalVolume/totalOrderCount/totalLineCount)</p>
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
|
||||
+59
@@ -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(一行 = 线路×货品,日期区间内汇总)
|
||||
*
|
||||
* <p>按线路+物料编码合并:多张出库单合并为一行,单据级字段(种类/仓单编号/入库单号/客户编号/收货人/出仓日期)不提供;
|
||||
* 仅统计带线路的出库单(line_code 为 2026-08-20 新增冗余字段,历史单为空,不参与线路排名);
|
||||
* 件数 = SUM(CHECK_QUANTITY) 复核确认的实际出库量(与入库排名的实际上架量对称);
|
||||
* 退保总额为占位字段,后端暂无对应数据来源,恒为 null</p>
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
+50
@@ -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(一行 = 一个货品,日期区间内跨出库单汇总)
|
||||
*
|
||||
* <p>按物料编码合并:一个货品会走多条线路/多张单,单据级字段(种类/仓单编号/入库单号/客户编号/收货人/出仓日期)与
|
||||
* 线路字段均无单值可返,不提供;件数 = SUM(CHECK_QUANTITY) 复核确认的实际出库量(与入库排名的实际上架量对称);
|
||||
* 退保总额为占位字段,后端暂无对应数据来源,恒为 null</p>
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
+35
-11
@@ -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;
|
||||
|
||||
/**
|
||||
* 出库排名统计(明细)应用服务
|
||||
* 出库排名统计应用服务
|
||||
*
|
||||
* <p>负责登录用户组织隔离注入、日期区间校验,查询逻辑在 ExecutionOutboundRankDomainService → ExecutionOutboundRankMapper.xml(跨库取 WMS 出库数据)</p>
|
||||
*
|
||||
@@ -29,26 +30,49 @@ public class ExecutionOutboundRankApplicationService {
|
||||
private ExecutionOutboundRankDomainService executionOutboundRankDomainService;
|
||||
|
||||
/**
|
||||
* 分页查询出库明细列表
|
||||
* 分页查询商品出库排名列表(货品聚合)
|
||||
*/
|
||||
public List<ExecutionOutboundDetailRankPO> queryDetailList(ExecutionOutboundRankDO executionOutboundRankDO) {
|
||||
public List<ExecutionOutboundMaterialRankPO> 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<ExecutionOutboundDetailRankPO> exportDetailList(ExecutionOutboundRankDO executionOutboundRankDO) {
|
||||
public List<ExecutionOutboundMaterialRankPO> exportMaterialRankList(ExecutionOutboundRankDO executionOutboundRankDO) {
|
||||
fillLoginContext(executionOutboundRankDO);
|
||||
return executionOutboundRankDomainService.queryDetailList(executionOutboundRankDO);
|
||||
return executionOutboundRankDomainService.queryMaterialRankList(executionOutboundRankDO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询线路出库排名列表(线路×货品聚合)
|
||||
*/
|
||||
public List<ExecutionOutboundLineRankPO> queryLineRankList(ExecutionOutboundRankDO executionOutboundRankDO) {
|
||||
fillLoginContext(executionOutboundRankDO);
|
||||
return executionOutboundRankDomainService.queryLineRankList(executionOutboundRankDO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 线路出库排名合计(当前筛选条件全量,不分页)
|
||||
*/
|
||||
public ExecutionOutboundDetailRankTotalPO queryLineRankTotal(ExecutionOutboundRankDO executionOutboundRankDO) {
|
||||
return executionOutboundRankDomainService.queryLineRankTotal(executionOutboundRankDO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出线路出库排名(不分页全量)
|
||||
*/
|
||||
public List<ExecutionOutboundLineRankPO> exportLineRankList(ExecutionOutboundRankDO executionOutboundRankDO) {
|
||||
fillLoginContext(executionOutboundRankDO);
|
||||
return executionOutboundRankDomainService.queryLineRankList(executionOutboundRankDO);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+23
-8
@@ -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<ExecutionOutboundDetailRankPO> queryDetailList(ExecutionOutboundRankDO executionOutboundRankDO) {
|
||||
return executionOutboundRankService.queryDetailList(executionOutboundRankDO);
|
||||
public List<ExecutionOutboundMaterialRankPO> 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<ExecutionOutboundLineRankPO> queryLineRankList(ExecutionOutboundRankDO executionOutboundRankDO) {
|
||||
return executionOutboundRankService.queryLineRankList(executionOutboundRankDO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 线路出库排名合计(不分页)
|
||||
*/
|
||||
public ExecutionOutboundDetailRankTotalPO queryLineRankTotal(ExecutionOutboundRankDO executionOutboundRankDO) {
|
||||
return executionOutboundRankService.queryLineRankTotal(executionOutboundRankDO);
|
||||
}
|
||||
}
|
||||
|
||||
+15
@@ -232,4 +232,19 @@ public class ReservationMaterialInventoryPO extends MaterialBasePO {
|
||||
@ApiModelProperty("LOT编号")
|
||||
@Excel(name = "LOT编号")
|
||||
private String lotNumber;
|
||||
|
||||
// 入库时间(createTime)/更新时间(updateTime)继承自 BaseVOEntity,默认带时分秒;
|
||||
// 库存查询导出复用 /list 接口,前端取 JSON 值直接进 Excel,这里覆盖 getter 只保留年月日。
|
||||
// 不改 BaseVOEntity(全系统基类,其他模块时间列仍需时分秒),仅收窄本 PO 的序列化格式(与 WMS 库存查询一致)
|
||||
@Override
|
||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
public Date getCreateTime() {
|
||||
return super.getCreateTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
public Date getUpdateTime() {
|
||||
return super.getUpdateTime();
|
||||
}
|
||||
}
|
||||
+34
-32
@@ -297,16 +297,39 @@ public class ReservationStockInOrderImpl extends ServiceImpl<ReservationStockInO
|
||||
}
|
||||
}
|
||||
|
||||
// ====== 第三步:物料/客户存在性校验全部完成后,统一提示两类编号各自有哪些不存在 ======
|
||||
if (!missingMaterials.isEmpty() || !missingCustomers.isEmpty()) {
|
||||
List<String> problems = new ArrayList<>();
|
||||
if (!missingMaterials.isEmpty()) {
|
||||
problems.add("物料[" + String.join("、", missingMaterials) + "]不存在,请先维护物料信息");
|
||||
// ====== 第三步:物料/客户/库存三类校验全部完成后统一报错(不再分阶段各自中断) ======
|
||||
List<String> problems = new ArrayList<>();
|
||||
if (!missingMaterials.isEmpty()) {
|
||||
problems.add("物料[" + String.join("、", missingMaterials) + "]不存在,请先维护物料信息");
|
||||
}
|
||||
if (!missingCustomers.isEmpty()) {
|
||||
problems.add("客户[" + String.join("、", missingCustomers) + "]不存在,请先维护客户信息");
|
||||
}
|
||||
|
||||
// 库存预检:只对已存在的物料比较批次库存(不存在的物料问题已收集),不足的同样收集
|
||||
if (!productDetailList.isEmpty()) {
|
||||
Set<String> insufficientMaterials = new HashSet<>();
|
||||
for (ProductDetail productDetail : productDetailList) {
|
||||
// materialCache 的 key 是 trim 过的编码,取用时同样 trim,避免 Excel 编号带空格导致校验被静默跳过
|
||||
String productCode = productDetail.getProductCode() == null ? "" : productDetail.getProductCode().trim();
|
||||
MaterialBaseInfoPO materialBaseInfoPO = materialCache.get(productCode);
|
||||
if (materialBaseInfoPO == null) {
|
||||
continue; // 物料不存在的问题已收集
|
||||
}
|
||||
BigDecimal requireQty = new BigDecimal(productDetail.getPieceCount()).setScale(2, BigDecimal.ROUND_HALF_UP);
|
||||
List<ReservationMaterialInventoryPO> inventoryList = stockInOrderMapper.getkcId(
|
||||
materialBaseInfoPO.getMaterialBaseInfoId(), requireQty, warehouseId);
|
||||
if (inventoryList == null || inventoryList.isEmpty()) {
|
||||
insufficientMaterials.add(productCode);
|
||||
}
|
||||
}
|
||||
if (!missingCustomers.isEmpty()) {
|
||||
problems.add("客户[" + String.join("、", missingCustomers) + "]不存在,请先维护客户信息");
|
||||
if (!insufficientMaterials.isEmpty()) {
|
||||
problems.add("物料[" + String.join("、", insufficientMaterials) + "]"
|
||||
+ (warehouseId != null && warehouseId > 0 ? "在当前仓库" : "") + "批次库存数量少于出库数量");
|
||||
}
|
||||
throw new Exception(String.join(";", problems) + ",维护完成后重新导入");
|
||||
}
|
||||
if (!problems.isEmpty()) {
|
||||
throw new Exception(String.join(";", problems) + ",请处理后重新导入");
|
||||
}
|
||||
|
||||
// ====== 后续处理(编号均已存在):货主归属校验、建单落库 ======
|
||||
@@ -332,28 +355,6 @@ public class ReservationStockInOrderImpl extends ServiceImpl<ReservationStockInO
|
||||
}
|
||||
}
|
||||
|
||||
// ====== 库存预检:所有物料的批次库存全部比较完成后再统一报错 ======
|
||||
// (原为逐行分配时立即抛错,首个不足即中断,排在后面的物料不再参与比较)
|
||||
if (!productDetailList.isEmpty()) {
|
||||
Set<String> insufficientMaterials = new HashSet<>();
|
||||
for (ProductDetail productDetail : productDetailList) {
|
||||
MaterialBaseInfoPO materialBaseInfoPO = materialCache.get(productDetail.getProductCode());
|
||||
if (materialBaseInfoPO == null) {
|
||||
continue; // 存在性已在前面统一校验
|
||||
}
|
||||
BigDecimal requireQty = new BigDecimal(productDetail.getPieceCount()).setScale(2, BigDecimal.ROUND_HALF_UP);
|
||||
List<ReservationMaterialInventoryPO> inventoryList = stockInOrderMapper.getkcId(
|
||||
materialBaseInfoPO.getMaterialBaseInfoId(), requireQty, warehouseId);
|
||||
if (inventoryList == null || inventoryList.isEmpty()) {
|
||||
insufficientMaterials.add(productDetail.getProductCode());
|
||||
}
|
||||
}
|
||||
if (!insufficientMaterials.isEmpty()) {
|
||||
throw new Exception("物料[" + String.join("、", insufficientMaterials) + "]"
|
||||
+ (warehouseId != null && warehouseId > 0 ? "在当前仓库" : "") + "批次库存数量少于出库数量!");
|
||||
}
|
||||
}
|
||||
|
||||
ReservationStockOutOrderDO reservationStockOutOrderDO = new ReservationStockOutOrderDO();
|
||||
// 生成出库业务单号
|
||||
String orderNumber = reservationStockOutOrderApplicationService.generateReserveOrderNumber();
|
||||
@@ -407,8 +408,9 @@ public class ReservationStockInOrderImpl extends ServiceImpl<ReservationStockInO
|
||||
for (ProductDetail productDetail : productDetailList) {
|
||||
ReservationOutMaterialDetailDO reservationOutMaterialDetailDO = new ReservationOutMaterialDetailDO();
|
||||
reservationOutMaterialDetailDO.setOutOrderNumber(reservationStockOutOrderDO.getOutOrderNumber());
|
||||
// 物料信息取自前置校验的缓存(已确认存在,避免逐行重复查库)
|
||||
MaterialBaseInfoPO materialBaseInfoPO = materialCache.get(productDetail.getProductCode());
|
||||
// 物料信息取自前置校验的缓存(已确认存在,避免逐行重复查库);key 与存入侧一致使用 trim 后的编码
|
||||
MaterialBaseInfoPO materialBaseInfoPO = materialCache.get(
|
||||
productDetail.getProductCode() == null ? "" : productDetail.getProductCode().trim());
|
||||
reservationOutMaterialDetailDO.setQuantity(new BigDecimal(productDetail.getPieceCount()).setScale(2, BigDecimal.ROUND_HALF_UP));
|
||||
if (materialBaseInfoPO != null) {
|
||||
Long materialBaseInfoId = materialBaseInfoPO.getMaterialBaseInfoId();
|
||||
|
||||
+7
@@ -514,6 +514,13 @@ public class ReservationStockOutOrderDomainService {
|
||||
for (Long inOrderId : inOrderIds) {
|
||||
ReservationStockOutOrder byId = stockOutOrderService.getById(inOrderId);
|
||||
String inOrderNumber = byId.getOutOrderNumber();
|
||||
// 幂等拦截:已存在有效执行单时禁止重复下发(重复下发会生成新执行单并原样复制明细uniqueId,撞执行明细表唯一约束)
|
||||
long activeExecutionCount = executionStockOutOrderService.count(new QueryWrapper<ExecutionStockOutOrder>().lambda()
|
||||
.eq(ExecutionStockOutOrder::getBusinessOutOrderNumber, inOrderNumber)
|
||||
.eq(ExecutionStockOutOrder::getDelFlag, 1));
|
||||
if (activeExecutionCount > 0) {
|
||||
throw new ServiceException("出库单[" + inOrderNumber + "]已下发,请勿重复下发;如需重新下发请先取消下发");
|
||||
}
|
||||
List<String> executionInOrderNumbers = new ArrayList<>();
|
||||
List<ReservationOutMaterialDetail> materialDetailList = outMaterialDetailService.list(new QueryWrapper<ReservationOutMaterialDetail>().lambda().eq(ReservationOutMaterialDetail::getOutOrderNumber, inOrderNumber));
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ import java.util.Map;
|
||||
/**
|
||||
* 三方服务 Feign
|
||||
*/
|
||||
@FeignClient(contextId = "thirdPartyServiceFeign",url = "http://10.102.192.30:8012", value = ServiceNameConstants.THIRDPARTY_CENTER, configuration = FeignAutoConfiguration.class)
|
||||
@FeignClient(contextId = "thirdPartyServiceFeign",url = "http://10.33.0.129:8012", value = ServiceNameConstants.THIRDPARTY_CENTER, configuration = FeignAutoConfiguration.class)
|
||||
public interface ThirdPartyServiceFeign {
|
||||
|
||||
//查询当前组织所有三方接口信息
|
||||
|
||||
+3
-1
@@ -30,7 +30,9 @@ import java.util.List;
|
||||
* 故数据源跨库取 WMS 入库表(NGWL_TEST_WMS.stock_in_order/in_material_detail,与 OMS 出库排名跨库修法一致);
|
||||
* 口径与 WMS 端 /inboundRankApi 完全一致,两边数字一致:仅已入库(5) + 明细 level=1 主行 +
|
||||
* 入仓日期(为空的历史单按建档时间兜底) + 件数=实际上架量(SHELVES_QUANTITY);
|
||||
* 一行 = 某仓单内某货品的合计,按件数降序排名。
|
||||
* 一行 = 一个物料的合计(按物料编码合并区间内全部已入库仓单),按件数降序排名,件数为0的物料不返回。
|
||||
* 返回字段:物料编码/货名/规格型号/单位/件数/毛重(吨)/投保总额/体积(CBM);
|
||||
* 仓单编号/客户编号/存货人/入仓日期为单据级字段仅作查询条件,不返回。
|
||||
* 字段:入仓日期/仓单编号/客户编号/存货人/货名/件数/毛重(吨)/投保总额/体积(CBM)。
|
||||
* 与出库排名(/executionOutboundRankApi)配对,前端用 tab 页区分</p>
|
||||
*
|
||||
|
||||
+29
-26
@@ -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
|
||||
*
|
||||
* <p>按日期区间筛选出库明细列表(一行 = 仓单×货品,件数/毛重/体积按行汇总,按件数(实际复核出库量)降序,出仓日期/单号次之)。
|
||||
* OMS 库出库单状态不流转(无"已出库"数据),数据源跨库取 WMS 库出库表(NGWL_TEST_WMS.stock_out_order / out_material_detail),
|
||||
* 口径与 WMS 端 /outboundRankApi 完全一致,两边数字一致;统计条件:出库单创建时间 + 已出库及之后状态(9,12,13),明细仅取 level=1 主行。
|
||||
* 商品/线路两个 tab 各自独立接口,内部为同一份明细查询:商品接口忽略线路筛选参数,线路接口忽略商品筛选参数。
|
||||
* 字段:种类/仓单编号/入库单号/客户编号/收货人/货名/线路/件数/毛重(吨)/体积(CBM)/退保总额(占位null)/出仓日期</p>
|
||||
* <p>按日期区间筛选出库量统计排名,按出库数量(实际复核出库量)降序。
|
||||
* 商品tab:一行 = 一个货品(货号/货名/件数/毛重(吨)/体积(CBM)/退保总额占位),跨出库单汇总,忽略线路筛选参数;
|
||||
* 线路tab:一行 = 线路×货品(线路编码/线路/货号/货名/件数/毛重(吨)/体积(CBM)/退保总额占位),按线路+物料编码合并,
|
||||
* 仅统计带线路的单,商品/线路筛选参数均生效;
|
||||
* 统计口径:出库单创建时间 + 已出库及之后状态(9,12,13),明细仅取 level=1 主行;
|
||||
* 件数 = SUM(CHECK_QUANTITY) 复核确认的实际出库量(与入库排名的实际上架量对称);
|
||||
* 数据源跨库取 WMS 库出库表,口径与 WMS 端 /outboundRankApi 完全一致,两边数字一致;
|
||||
* 退保总额后端暂无对应数据来源,恒为 null</p>
|
||||
*
|
||||
* @author rcx
|
||||
* @date 2026-08-31
|
||||
@@ -58,25 +62,22 @@ public class ExecutionOutboundRankApi {
|
||||
executionOutboundRankDO.setLineCode(null);
|
||||
executionOutboundRankDO.setLineName(null);
|
||||
startPage();
|
||||
List<ExecutionOutboundDetailRankPO> list = executionOutboundRankApplicationService.queryDetailList(executionOutboundRankDO);
|
||||
ExecutionOutboundDetailRankTotalPO total = executionOutboundRankApplicationService.queryDetailTotal(executionOutboundRankDO);
|
||||
List<ExecutionOutboundMaterialRankPO> list = executionOutboundRankApplicationService.queryMaterialRankList(executionOutboundRankDO);
|
||||
ExecutionOutboundDetailRankTotalPO total = executionOutboundRankApplicationService.queryMaterialRankTotal(executionOutboundRankDO);
|
||||
return getDataTableWithTotal(list, total);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询线路出库排名列表(含合计行,线路tab;忽略商品筛选参数)
|
||||
* 分页查询线路出库排名列表(含合计行,线路tab;一行=线路×货品,仅统计带线路的单)
|
||||
*/
|
||||
@ApiOperation("分页查询线路出库排名列表")
|
||||
@GetMapping("/queryLineRankList")
|
||||
public HashMap<String, Object> queryLineRankList(ExecutionOutboundRankDTO executionOutboundRankDTO) {
|
||||
//转换实体
|
||||
//转换实体(线路tab:商品/线路筛选参数均生效,按线路+物料编码合并)
|
||||
ExecutionOutboundRankDO executionOutboundRankDO = executionOutboundRankAssembler.toDO(executionOutboundRankDTO);
|
||||
//线路tab:忽略商品筛选参数
|
||||
executionOutboundRankDO.setMaterialCode(null);
|
||||
executionOutboundRankDO.setMaterialName(null);
|
||||
startPage();
|
||||
List<ExecutionOutboundDetailRankPO> list = executionOutboundRankApplicationService.queryDetailList(executionOutboundRankDO);
|
||||
ExecutionOutboundDetailRankTotalPO total = executionOutboundRankApplicationService.queryDetailTotal(executionOutboundRankDO);
|
||||
List<ExecutionOutboundLineRankPO> 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<ExecutionOutboundDetailRankPO> list = executionOutboundRankApplicationService.exportDetailList(executionOutboundRankDO);
|
||||
List<ExecutionOutboundMaterialRankPO> 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<ExecutionOutboundDetailRankPO> util = new ExcelUtil<>(ExecutionOutboundDetailRankPO.class);
|
||||
ExcelUtil<ExecutionOutboundMaterialRankPO> 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<ExecutionOutboundDetailRankPO> list = executionOutboundRankApplicationService.exportDetailList(executionOutboundRankDO);
|
||||
List<ExecutionOutboundLineRankPO> 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<ExecutionOutboundDetailRankPO> util = new ExcelUtil<>(ExecutionOutboundDetailRankPO.class);
|
||||
ExcelUtil<ExecutionOutboundLineRankPO> 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<String, Object> getDataTableWithTotal(List<?> list, ExecutionOutboundDetailRankTotalPO total) {
|
||||
HashMap<String, Object> 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;
|
||||
}
|
||||
|
||||
@@ -18,15 +18,15 @@ spring:
|
||||
discovery:
|
||||
# server-addr: 127.0.0.1:8848
|
||||
# 线上测试环境配置 容器名+端口号
|
||||
# server-addr: 10.33.0.129:6010
|
||||
server-addr: 10.102.192.30:6848
|
||||
server-addr: 10.33.0.129:6010
|
||||
# server-addr: 10.102.192.30:6848
|
||||
username: nacos
|
||||
password: manhuoda@2023
|
||||
config:
|
||||
# server-addr: 127.0.0.1:8848
|
||||
# 线上测试环境配置 容器名+端口号
|
||||
# server-addr: 10.33.0.129:6010
|
||||
server-addr: 10.102.192.30:6848
|
||||
server-addr: 10.33.0.129:6010
|
||||
# server-addr: 10.102.192.30:6848
|
||||
username: nacos
|
||||
password: manhuoda@2023
|
||||
#线上正式环境
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
口径与 WMS 端 /inboundRankApi 完全一致,两边数字一致;
|
||||
条件:b.status = 5已入库(排除已取消(6)/已关闭(7)及未完成单据);
|
||||
日期筛选按入仓单入仓日期 b.warehouse_date(与列表"入仓日期"列同源,为空的历史单按建档时间兜底);
|
||||
一行 = 某仓单(b.in_order_number)内某货品(a.material_code)的合计,
|
||||
按件数(实际上架量 SUM(a.SHELVES_QUANTITY))降序排名
|
||||
一行 = 一个物料的合计(按物料编码合并,区间内全部已入库仓单),按件数(实际上架量 SUM(a.SHELVES_QUANTITY))降序排名,
|
||||
件数为0的物料不返回(HAVING过滤);仓单编号/客户编号/存货人/入仓日期为单据级字段仅作查询条件不返回
|
||||
-->
|
||||
<sql id="inboundRankConditions">
|
||||
a.del_flag = 1
|
||||
@@ -57,14 +57,10 @@
|
||||
left join NGWL_TEST_WMS.material_base_info c on a.material_base_info_id = c.material_base_info_id
|
||||
</sql>
|
||||
|
||||
<!-- 商品入库排名列表(仓单+货品汇总,按件数=实际上架量降序) -->
|
||||
<!-- 商品入库排名列表(按物料编码合并,按件数=实际上架量降序,过滤0件行) -->
|
||||
<select id="queryMaterialRankList" parameterType="com.mhd.oms.domain.inboundRank.repository.todo.ExecutionInboundRankDO"
|
||||
resultType="com.mhd.oms.domain.inboundRank.repository.po.ExecutionInboundMaterialRankPO">
|
||||
select
|
||||
IFNULL(MAX(b.warehouse_date), MAX(b.create_time)) AS warehouseDate,
|
||||
b.in_order_number AS inOrderNumber,
|
||||
MAX(b.shipper_code) AS shipperCode,
|
||||
MAX(b.shipper_name) AS shipperName,
|
||||
a.material_code AS materialCode,
|
||||
MAX(a.material_name) AS materialName,
|
||||
MAX(a.SPECIFICATION_MODEL) AS specificationModel,
|
||||
@@ -77,11 +73,13 @@
|
||||
<where>
|
||||
<include refid="inboundRankConditions"/>
|
||||
</where>
|
||||
GROUP BY b.in_order_number, a.material_code
|
||||
order by pieceCount desc, warehouseDate desc, inOrderNumber desc
|
||||
GROUP BY a.material_code
|
||||
HAVING pieceCount > 0
|
||||
order by pieceCount desc, materialCode
|
||||
</select>
|
||||
|
||||
<!-- 商品入库排名合计(当前筛选条件全量;外层对分组结果再汇总,保证投保总额合计=各行列值之和) -->
|
||||
<!-- 商品入库排名合计(当前筛选条件全量;外层对物料分组结果再汇总,投保总额合计=各物料保额之和(每物料计一次);
|
||||
涉及仓单数按明细行去重统计仓单) -->
|
||||
<select id="queryMaterialRankTotal" parameterType="com.mhd.oms.domain.inboundRank.repository.todo.ExecutionInboundRankDO"
|
||||
resultType="com.mhd.oms.domain.inboundRank.repository.po.ExecutionInboundRankTotalPO">
|
||||
select
|
||||
@@ -89,10 +87,14 @@
|
||||
ROUND(IFNULL(SUM(t.grossWeightKG), 0) / 1000, 3) AS totalGrossWeightTon,
|
||||
IFNULL(SUM(t.insureAmount), 0) AS totalInsureAmount,
|
||||
IFNULL(SUM(t.totalVolume), 0) AS totalVolume,
|
||||
COUNT(DISTINCT t.inOrderNumber) AS totalOrderCount
|
||||
(select COUNT(DISTINCT b.in_order_number)
|
||||
<include refid="inboundRankFrom"/>
|
||||
<where>
|
||||
<include refid="inboundRankConditions"/>
|
||||
</where>) AS totalOrderCount
|
||||
from (
|
||||
select
|
||||
b.in_order_number AS inOrderNumber,
|
||||
a.material_code AS materialCode,
|
||||
IFNULL(SUM(a.SHELVES_QUANTITY), 0) AS pieceCount,
|
||||
IFNULL(SUM(a.TOTAL_GROSS_WEIGHT), 0) AS grossWeightKG,
|
||||
MAX(IFNULL(c.insure_amount, 0)) AS insureAmount,
|
||||
@@ -101,7 +103,7 @@
|
||||
<where>
|
||||
<include refid="inboundRankConditions"/>
|
||||
</where>
|
||||
GROUP BY b.in_order_number, a.material_code
|
||||
GROUP BY a.material_code
|
||||
) t
|
||||
</select>
|
||||
</mapper>
|
||||
|
||||
@@ -5,15 +5,17 @@
|
||||
<mapper namespace="com.mhd.oms.domain.outboundRank.repository.mapper.ExecutionOutboundRankMapper">
|
||||
|
||||
<!--
|
||||
出库排名统计(明细)公共查询条件(OMS 端,跨库取 WMS 出库数据)
|
||||
出库排名统计公共查询条件(OMS 端,跨库取 WMS 出库数据)
|
||||
数据源:WMS 库出库明细 NGWL_TEST_WMS.out_material_detail(a,仅 level=1 主行防重复)
|
||||
join WMS 库出库单 NGWL_TEST_WMS.stock_out_order(b)
|
||||
说明:OMS 库出库单状态不流转(无"已出库"数据),"已出库"状态的真实数据在 WMS 库,
|
||||
故跨库取数(与 OMS 库存查询跨库 join NGWL_TEST_WMS.material_base_info 同一模式),
|
||||
口径与 WMS 端 /outboundRankApi 完全一致,两边数字一致;
|
||||
条件:b.status in (9已出库,12已复核,13已交接),排除已取消(10)/已关闭(11);
|
||||
日期按出库单创建时间 b.create_time;一行 = 某仓单内某货品的合计;
|
||||
件数 = SUM(a.CHECK_QUANTITY) 复核确认的实际出库量(与入库排名的实际上架量 SHELVES_QUANTITY 对称),按件数降序排名
|
||||
日期按出库单创建时间 b.create_time;
|
||||
商品排名:一行 = 一个货品(GROUP BY a.material_code),区间内跨单汇总,按实际出库量降序;
|
||||
线路排名:一行 = 线路×货品(GROUP BY b.line_code, a.material_code),仅统计带线路的单;
|
||||
件数 = SUM(a.CHECK_QUANTITY) 复核确认的实际出库量(与入库排名的实际上架量 SHELVES_QUANTITY 对称)
|
||||
-->
|
||||
<sql id="outboundRankConditions">
|
||||
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
|
||||
</sql>
|
||||
|
||||
<!-- 出库明细列表(仓单+货品汇总,按件数(实际复核出库量)降序;退保总额暂无后端字段不提供) -->
|
||||
<select id="queryDetailList" parameterType="com.mhd.oms.domain.outboundRank.repository.todo.ExecutionOutboundRankDO"
|
||||
resultType="com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundDetailRankPO">
|
||||
<!-- 商品出库排名列表(按物料编码合并,跨单汇总;退保总额暂无后端字段不提供) -->
|
||||
<select id="queryMaterialRankList" parameterType="com.mhd.oms.domain.outboundRank.repository.todo.ExecutionOutboundRankDO"
|
||||
resultType="com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundMaterialRankPO">
|
||||
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
|
||||
<include refid="outboundRankFrom"/>
|
||||
<where>
|
||||
<include refid="outboundRankConditions"/>
|
||||
</where>
|
||||
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>
|
||||
|
||||
<!-- 出库明细合计(当前筛选条件全量;外层对分组结果再汇总,与入库排名同模板) -->
|
||||
<select id="queryDetailTotal" parameterType="com.mhd.oms.domain.outboundRank.repository.todo.ExecutionOutboundRankDO"
|
||||
<!-- 商品出库排名合计(当前筛选条件全量) -->
|
||||
<select id="queryMaterialRankTotal" parameterType="com.mhd.oms.domain.outboundRank.repository.todo.ExecutionOutboundRankDO"
|
||||
resultType="com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundDetailRankTotalPO">
|
||||
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
|
||||
<include refid="outboundRankFrom"/>
|
||||
<where>
|
||||
<include refid="outboundRankConditions"/>
|
||||
</where>
|
||||
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
|
||||
<include refid="outboundRankFrom"/>
|
||||
<where>
|
||||
<include refid="outboundRankConditions"/>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<!-- 线路出库排名列表(线路+物料编码合并,仅统计带线路的单;商品/线路筛选参数均生效) -->
|
||||
<select id="queryLineRankList" parameterType="com.mhd.oms.domain.outboundRank.repository.todo.ExecutionOutboundRankDO"
|
||||
resultType="com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundLineRankPO">
|
||||
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
|
||||
<include refid="outboundRankFrom"/>
|
||||
<where>
|
||||
<include refid="outboundRankConditions"/>
|
||||
and b.line_code is not null and b.line_code != ''
|
||||
</where>
|
||||
GROUP BY b.line_code, a.material_code
|
||||
order by pieceCount desc, lineCode asc, materialCode asc
|
||||
</select>
|
||||
|
||||
<!-- 线路出库排名合计(当前筛选条件全量) -->
|
||||
<select id="queryLineRankTotal" parameterType="com.mhd.oms.domain.outboundRank.repository.todo.ExecutionOutboundRankDO"
|
||||
resultType="com.mhd.oms.domain.outboundRank.repository.po.ExecutionOutboundDetailRankTotalPO">
|
||||
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
|
||||
<include refid="outboundRankFrom"/>
|
||||
<where>
|
||||
<include refid="outboundRankConditions"/>
|
||||
and b.line_code is not null and b.line_code != ''
|
||||
</where>
|
||||
</select>
|
||||
</mapper>
|
||||
|
||||
+3
-5
@@ -471,15 +471,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</resultMap>
|
||||
|
||||
<!-- 按客户编号+组织查询客户(用户表):出入库导入校验客户存在性并自动匹配客户名称,结果为空表示客户不存在。
|
||||
客户编码有两处维护:USER.USER_MEMBER_CODE(客户编码)与 USER_SHIPPER.CUSTOMER_NC_CODE(NC客户代码,即单据khdm),
|
||||
模板填写的客户编号两者任一命中即可匹配到客户 -->
|
||||
客户编码只认 USER.USER_MEMBER_CODE(客户编码);
|
||||
2026-09-03 起不再放行 USER_SHIPPER.CUSTOMER_NC_CODE(NC客户代码),避免会员/NC编码撞车导致不存在的客户编号误通过 -->
|
||||
<select id="queryCustomerByCode" resultType="com.mhd.common.core.domain.po.UserPo">
|
||||
select max(u.user_id) as user_id, max(u.user_name) as user_name, max(u.user_member_code) as user_member_code
|
||||
from NGWL_TEST_USER."USER" u
|
||||
left join NGWL_TEST_USER.USER_SHIPPER us
|
||||
on us.USER_ID = u.USER_ID and us.DEL_FLAG = 1
|
||||
where u.ORGANIZATION_ID = #{organizationId} and u.DEL_FLAG = 1
|
||||
and (u.USER_MEMBER_CODE = #{userMemberCode} or us.CUSTOMER_NC_CODE = #{userMemberCode})
|
||||
and u.USER_MEMBER_CODE = #{userMemberCode}
|
||||
</select>
|
||||
|
||||
<select id="countByOrderNumberPrefix" resultType="java.lang.Integer" parameterType="java.lang.String">
|
||||
|
||||
+3
-1
@@ -361,6 +361,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<result property="topOrganizationId" column="top_organization_id" />
|
||||
<result property="uniqueId" column="unique_id" />
|
||||
<result property="outOrderNumber" column="out_order_number" />
|
||||
<result property="status" column="status" />
|
||||
<result property="issueStatus" column="issue_status" />
|
||||
<result property="materialBaseInfoId" column="material_base_info_id" />
|
||||
<result property="materialCode" column="material_code" />
|
||||
<result property="materialName" column="material_name" />
|
||||
@@ -452,7 +454,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
|
||||
<select id="detailsList" parameterType="com.mhd.oms.domain.reserveStockOutOrder.repository.todo.ReserveStockOutOrderDO" resultMap="MaterialDetailResult">
|
||||
select
|
||||
b.*
|
||||
b.*, a.status, a.issue_status
|
||||
from reserve_stock_out_order a left join reserve_out_material_detail b on a.OUT_ORDER_NUMBER = b.OUT_ORDER_NUMBER
|
||||
<where>
|
||||
<include refid="selectStockOutOrderPo1"/>
|
||||
|
||||
+35
-11
@@ -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;
|
||||
|
||||
/**
|
||||
* 出库排名统计(明细)应用服务
|
||||
* 出库排名统计应用服务
|
||||
*
|
||||
* <p>负责登录用户组织隔离注入、日期区间校验,查询逻辑在 OutboundRankDomainService → OutboundRankMapper.xml</p>
|
||||
*
|
||||
@@ -32,26 +33,49 @@ public class OutboundRankApplicationService {
|
||||
private OutboundRankDomainService outboundRankDomainService;
|
||||
|
||||
/**
|
||||
* 分页查询出库明细列表
|
||||
* 分页查询商品出库排名列表(货品聚合)
|
||||
*/
|
||||
public List<OutboundDetailRankPO> queryDetailList(OutboundRankDO outboundRankDO) {
|
||||
public List<OutboundMaterialRankPO> 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<OutboundDetailRankPO> exportDetailList(OutboundRankDO outboundRankDO) {
|
||||
public List<OutboundMaterialRankPO> exportMaterialRankList(OutboundRankDO outboundRankDO) {
|
||||
fillLoginContext(outboundRankDO);
|
||||
return outboundRankDomainService.queryDetailList(outboundRankDO);
|
||||
return outboundRankDomainService.queryMaterialRankList(outboundRankDO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询线路出库排名列表(线路×货品聚合)
|
||||
*/
|
||||
public List<OutboundLineRankPO> queryLineRankList(OutboundRankDO outboundRankDO) {
|
||||
fillLoginContext(outboundRankDO);
|
||||
return outboundRankDomainService.queryLineRankList(outboundRankDO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 线路出库排名合计(当前筛选条件全量,不分页)
|
||||
*/
|
||||
public OutboundDetailRankTotalPO queryLineRankTotal(OutboundRankDO outboundRankDO) {
|
||||
return outboundRankDomainService.queryLineRankTotal(outboundRankDO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出线路出库排名(不分页全量)
|
||||
*/
|
||||
public List<OutboundLineRankPO> exportLineRankList(OutboundRankDO outboundRankDO) {
|
||||
fillLoginContext(outboundRankDO);
|
||||
return outboundRankDomainService.queryLineRankList(outboundRankDO);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ import java.util.List;
|
||||
public interface InboundRankMapper {
|
||||
|
||||
/**
|
||||
* 商品入库排名列表(仓单+货品汇总,按件数降序)
|
||||
* 商品入库排名列表(按物料编码合并,按件数降序,过滤0件行)
|
||||
*/
|
||||
List<InboundMaterialRankPO> queryMaterialRankList(InboundRankDO inboundRankDO);
|
||||
|
||||
|
||||
+10
-31
@@ -1,22 +1,19 @@
|
||||
package com.mhd.wms.domain.inboundRank.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(一行 = 某仓单内某货品的合计,按件数降序排名)
|
||||
* 入库排名统计PO(一行 = 一个物料的合计(按物料编码合并,查询区间内全部已入库仓单),按件数降序排名)
|
||||
*
|
||||
* <p>字段口径:入仓日期=入仓单入仓日期(为空兜底建档时间);仓单编号=入库单号;客户编号/存货人=入仓单货主;
|
||||
* 件数/毛重/体积=仓单内该货品明细合计(件数取实际上架量 SHELVES_QUANTITY);毛重(吨)=明细总毛重KG/1000;
|
||||
* 投保总额=货品档案保额(material_base_info.insure_amount,组内取MAX防多批次明细行重复累加)</p>
|
||||
* <p>字段口径:件数=实际上架量(SHELVES_QUANTITY)合计;毛重(吨)=明细总毛重KG/1000;体积=明细合计;
|
||||
* 投保总额=货品档案保额(material_base_info.insure_amount,物料维度单一值取MAX,不跨仓单累加);
|
||||
* 仓单编号/客户编号/存货人/入仓日期为单据级字段,按物料合并后单值失真,仅作查询条件不返回</p>
|
||||
*
|
||||
* @author rcx
|
||||
* @date 2026-08-31
|
||||
@@ -27,26 +24,8 @@ public class InboundMaterialRankPO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty("入仓日期")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
@Excel(name = "入仓日期", width = 30, dateFormat = "yyyy-MM-dd")
|
||||
private Date warehouseDate;
|
||||
|
||||
@ApiModelProperty("仓单编号(入库单号)")
|
||||
@Excel(name = "仓单编号")
|
||||
private String inOrderNumber;
|
||||
|
||||
@ApiModelProperty("客户编号")
|
||||
@Excel(name = "客户编号")
|
||||
private String shipperCode;
|
||||
|
||||
@ApiModelProperty("存货人(客户名称)")
|
||||
@Excel(name = "存货人")
|
||||
private String shipperName;
|
||||
|
||||
@ApiModelProperty("商品货号")
|
||||
@Excel(name = "商品货号")
|
||||
@ApiModelProperty("物料编码(合并依据)")
|
||||
@Excel(name = "物料编码")
|
||||
private String materialCode;
|
||||
|
||||
@ApiModelProperty("货名/商品名称")
|
||||
@@ -61,19 +40,19 @@ public class InboundMaterialRankPO implements Serializable {
|
||||
@Excel(name = "单位")
|
||||
private String unitName;
|
||||
|
||||
@ApiModelProperty("件数(仓单内该货品实际上架量合计 SHELVES_QUANTITY,排名依据)")
|
||||
@ApiModelProperty("件数(该物料实际上架量合计 SHELVES_QUANTITY,排名依据)")
|
||||
@Excel(name = "件数")
|
||||
private BigDecimal pieceCount;
|
||||
|
||||
@ApiModelProperty("毛重(吨)(仓单内该货品合计,KG/1000)")
|
||||
@ApiModelProperty("毛重(吨)(该物料合计,KG/1000)")
|
||||
@Excel(name = "毛重(吨)")
|
||||
private BigDecimal grossWeightTon;
|
||||
|
||||
@ApiModelProperty("投保总额(货品档案保额)")
|
||||
@ApiModelProperty("投保总额(货品档案保额,物料维度单一值)")
|
||||
@Excel(name = "投保总额")
|
||||
private BigDecimal insureAmount;
|
||||
|
||||
@ApiModelProperty("体积(CBM)(仓单内该货品合计)")
|
||||
@ApiModelProperty("体积(CBM)(该物料合计)")
|
||||
@Excel(name = "体积(CBM)")
|
||||
private BigDecimal totalVolume;
|
||||
}
|
||||
|
||||
+2
-2
@@ -28,12 +28,12 @@ public class InboundRankTotalPO implements Serializable {
|
||||
@ApiModelProperty("毛重(吨)合计")
|
||||
private BigDecimal totalGrossWeightTon;
|
||||
|
||||
@ApiModelProperty("投保总额合计(各仓单+货品行保额之和)")
|
||||
@ApiModelProperty("投保总额合计(各物料保额之和,每物料计一次)")
|
||||
private BigDecimal totalInsureAmount;
|
||||
|
||||
@ApiModelProperty("体积(CBM)合计")
|
||||
private BigDecimal totalVolume;
|
||||
|
||||
@ApiModelProperty("仓单数合计")
|
||||
@ApiModelProperty("涉及仓单数(当前筛选条件下去重统计)")
|
||||
private Long totalOrderCount;
|
||||
}
|
||||
|
||||
+15
@@ -240,4 +240,19 @@ public class MaterialInventoryPO extends MaterialBasePO {
|
||||
@ApiModelProperty("规格型号")
|
||||
@Excel(name = "规格型号")
|
||||
private String specificationModel;
|
||||
|
||||
// 入库时间(createTime)/更新时间(updateTime)继承自 BaseVOEntity,默认带时分秒;
|
||||
// 库存查询导出复用 /list 接口,前端取 JSON 值直接进 Excel,这里覆盖 getter 只保留年月日。
|
||||
// 不改 BaseVOEntity(全系统基类,其他模块时间列仍需时分秒),仅收窄本 PO 的序列化格式(与 OMS 库存查询一致)
|
||||
@Override
|
||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
public Date getCreateTime() {
|
||||
return super.getCreateTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
public Date getUpdateTime() {
|
||||
return super.getUpdateTime();
|
||||
}
|
||||
}
|
||||
+17
-6
@@ -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<OutboundDetailRankPO> queryDetailList(OutboundRankDO outboundRankDO);
|
||||
List<OutboundMaterialRankPO> queryMaterialRankList(OutboundRankDO outboundRankDO);
|
||||
|
||||
/**
|
||||
* 出库明细合计(不分页)
|
||||
* 商品出库排名合计(不分页)
|
||||
*/
|
||||
OutboundDetailRankTotalPO queryDetailTotal(OutboundRankDO outboundRankDO);
|
||||
OutboundDetailRankTotalPO queryMaterialRankTotal(OutboundRankDO outboundRankDO);
|
||||
|
||||
/**
|
||||
* 线路出库排名列表(线路×货品聚合)
|
||||
*/
|
||||
List<OutboundLineRankPO> queryLineRankList(OutboundRankDO outboundRankDO);
|
||||
|
||||
/**
|
||||
* 线路出库排名合计(不分页)
|
||||
*/
|
||||
OutboundDetailRankTotalPO queryLineRankTotal(OutboundRankDO outboundRankDO);
|
||||
}
|
||||
|
||||
+17
-6
@@ -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<OutboundDetailRankPO> queryDetailList(OutboundRankDO outboundRankDO);
|
||||
List<OutboundMaterialRankPO> queryMaterialRankList(OutboundRankDO outboundRankDO);
|
||||
|
||||
/**
|
||||
* 出库明细合计(不分页,当前筛选条件全量合计)
|
||||
* 商品出库排名合计(不分页,当前筛选条件全量合计)
|
||||
*/
|
||||
OutboundDetailRankTotalPO queryDetailTotal(OutboundRankDO outboundRankDO);
|
||||
OutboundDetailRankTotalPO queryMaterialRankTotal(OutboundRankDO outboundRankDO);
|
||||
|
||||
/**
|
||||
* 线路出库排名列表(一行=线路×货品,按实际出库量降序,仅统计带线路的单)
|
||||
*/
|
||||
List<OutboundLineRankPO> queryLineRankList(OutboundRankDO outboundRankDO);
|
||||
|
||||
/**
|
||||
* 线路出库排名合计(不分页,当前筛选条件全量合计)
|
||||
*/
|
||||
OutboundDetailRankTotalPO queryLineRankTotal(OutboundRankDO outboundRankDO);
|
||||
}
|
||||
|
||||
+17
-6
@@ -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<OutboundDetailRankPO> queryDetailList(OutboundRankDO outboundRankDO) {
|
||||
return outboundRankMapper.queryDetailList(outboundRankDO);
|
||||
public List<OutboundMaterialRankPO> 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<OutboundLineRankPO> queryLineRankList(OutboundRankDO outboundRankDO) {
|
||||
return outboundRankMapper.queryLineRankList(outboundRankDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutboundDetailRankTotalPO queryLineRankTotal(OutboundRankDO outboundRankDO) {
|
||||
return outboundRankMapper.queryLineRankTotal(outboundRankDO);
|
||||
}
|
||||
}
|
||||
|
||||
-85
@@ -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(一行 = 仓单×货品,件数/毛重/体积按行汇总)
|
||||
*
|
||||
* <p>字段口径:种类=出库单据类型;仓单编号=出库单号;收货人=出库单 TO 栏(为空取联系人);
|
||||
* 毛重(吨)=明细总毛重KG/1000;出仓日期=出仓日期(为空依次兜底完成时间/创建时间);
|
||||
* 退保总额为占位字段,后端暂无对应数据来源,恒为 null(候选:货品档案保额 insure_amount,确认后可补)</p>
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
+3
@@ -33,4 +33,7 @@ public class OutboundDetailRankTotalPO implements Serializable {
|
||||
|
||||
@ApiModelProperty("仓单数合计(去重出库单数)")
|
||||
private Long totalOrderCount;
|
||||
|
||||
@ApiModelProperty("线路数合计(去重线路数,线路排名使用)")
|
||||
private Long totalLineCount;
|
||||
}
|
||||
|
||||
+59
@@ -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(一行 = 线路×货品,日期区间内汇总)
|
||||
*
|
||||
* <p>按线路+物料编码合并:多张出库单合并为一行,单据级字段(种类/仓单编号/入库单号/客户编号/收货人/出仓日期)不提供;
|
||||
* 仅统计带线路的出库单(line_code 为 2026-08-20 新增冗余字段,历史单为空,不参与线路排名);
|
||||
* 件数 = SUM(CHECK_QUANTITY) 复核确认的实际出库量(与入库排名的实际上架量对称);
|
||||
* 退保总额为占位字段,后端暂无对应数据来源,恒为 null</p>
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
+50
@@ -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(一行 = 一个货品,日期区间内跨出库单汇总)
|
||||
*
|
||||
* <p>按物料编码合并:一个货品会走多条线路/多张单,单据级字段(种类/仓单编号/入库单号/客户编号/收货人/出仓日期)与
|
||||
* 线路字段均无单值可返,不提供;件数 = SUM(CHECK_QUANTITY) 复核确认的实际出库量(与入库排名的实际上架量对称);
|
||||
* 退保总额为占位字段,后端暂无对应数据来源,恒为 null</p>
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
+23
-8
@@ -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<OutboundDetailRankPO> queryDetailList(OutboundRankDO outboundRankDO) {
|
||||
return outboundRankService.queryDetailList(outboundRankDO);
|
||||
public List<OutboundMaterialRankPO> 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<OutboundLineRankPO> queryLineRankList(OutboundRankDO outboundRankDO) {
|
||||
return outboundRankService.queryLineRankList(outboundRankDO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 线路出库排名合计(不分页)
|
||||
*/
|
||||
public OutboundDetailRankTotalPO queryLineRankTotal(OutboundRankDO outboundRankDO) {
|
||||
return outboundRankService.queryLineRankTotal(outboundRankDO);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@ import java.io.Serializable;
|
||||
* 入库排名统计入参DTO
|
||||
*
|
||||
* <p>按入仓日期区间筛选商品入库量统计排名,统计口径:入仓日期 + 仅已入库状态(5) + 明细仅取 level=1 主行;
|
||||
* 一行 = 某仓单内某货品的合计,按件数降序排名</p>
|
||||
* 一行 = 一个物料的合计(按物料编码合并),按件数降序排名;
|
||||
* 仓单编号/客户编号/存货人/入仓日期为单据级字段仅作查询条件,返回列不含这些字段</p>
|
||||
*
|
||||
* @author rcx
|
||||
* @date 2026-08-31
|
||||
|
||||
+4
-2
@@ -26,8 +26,10 @@ import java.util.List;
|
||||
* 入库排名统计Api
|
||||
*
|
||||
* <p>按入仓日期区间筛选商品入库量统计排名。统计口径:入仓日期(为空的历史单按建档时间兜底) + 仅已入库状态(5),
|
||||
* 明细仅取 level=1 主行;一行 = 某仓单内某货品的合计,按件数(实际上架量 SHELVES_QUANTITY)降序排名。
|
||||
* 字段:入仓日期/仓单编号/客户编号/存货人/货名/件数/毛重(吨)/投保总额/体积(CBM)。
|
||||
* 明细仅取 level=1 主行;一行 = 一个物料的合计(按物料编码合并区间内全部已入库仓单),
|
||||
* 按件数(实际上架量 SHELVES_QUANTITY)降序排名,件数为0的物料不返回。
|
||||
* 返回字段:物料编码/货名/规格型号/单位/件数/毛重(吨)/投保总额/体积(CBM);
|
||||
* 仓单编号/客户编号/存货人/入仓日期为单据级字段仅作查询条件,不返回。
|
||||
* 与出库排名(/outboundRankApi)配对,前端用 tab 页区分</p>
|
||||
*
|
||||
* @author rcx
|
||||
|
||||
+28
-25
@@ -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
|
||||
*
|
||||
* <p>按日期区间筛选出库明细列表(一行 = 仓单×货品,件数/毛重/体积按行汇总,按件数(实际复核出库量)降序,出仓日期/单号次之)。
|
||||
* 统计口径:出库单创建时间 + 已出库及之后状态(9,12,13),明细仅取 level=1 主行。
|
||||
* 商品/线路两个 tab 各自独立接口,内部为同一份明细查询:商品接口忽略线路筛选参数,线路接口忽略商品筛选参数。
|
||||
* 字段:种类/仓单编号/入库单号/客户编号/收货人/货名/线路/件数/毛重(吨)/体积(CBM)/退保总额(占位null)/出仓日期</p>
|
||||
* <p>按日期区间筛选出库量统计排名,按出库数量(实际复核出库量)降序。
|
||||
* 商品tab:一行 = 一个货品(货号/货名/件数/毛重(吨)/体积(CBM)/退保总额占位),跨出库单汇总,忽略线路筛选参数;
|
||||
* 线路tab:一行 = 线路×货品(线路编码/线路/货号/货名/件数/毛重(吨)/体积(CBM)/退保总额占位),按线路+物料编码合并,
|
||||
* 仅统计带线路的单,商品/线路筛选参数均生效;
|
||||
* 统计口径:出库单创建时间 + 已出库及之后状态(9,12,13),明细仅取 level=1 主行;
|
||||
* 件数 = SUM(CHECK_QUANTITY) 复核确认的实际出库量(与入库排名的实际上架量对称);
|
||||
* 退保总额后端暂无对应数据来源,恒为 null</p>
|
||||
*
|
||||
* @author rcx
|
||||
* @date 2026-08-31
|
||||
@@ -55,25 +59,22 @@ public class OutboundRankApi {
|
||||
outboundRankDO.setLineCode(null);
|
||||
outboundRankDO.setLineName(null);
|
||||
startPage();
|
||||
List<OutboundDetailRankPO> list = outboundRankApplicationService.queryDetailList(outboundRankDO);
|
||||
OutboundDetailRankTotalPO total = outboundRankApplicationService.queryDetailTotal(outboundRankDO);
|
||||
List<OutboundMaterialRankPO> list = outboundRankApplicationService.queryMaterialRankList(outboundRankDO);
|
||||
OutboundDetailRankTotalPO total = outboundRankApplicationService.queryMaterialRankTotal(outboundRankDO);
|
||||
return getDataTableWithTotal(list, total);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询线路出库排名列表(含合计行,线路tab;忽略商品筛选参数)
|
||||
* 分页查询线路出库排名列表(含合计行,线路tab;一行=线路×货品,仅统计带线路的单)
|
||||
*/
|
||||
@ApiOperation("分页查询线路出库排名列表")
|
||||
@GetMapping("/queryLineRankList")
|
||||
public HashMap<String, Object> queryLineRankList(OutboundRankDTO outboundRankDTO) {
|
||||
//转换实体
|
||||
//转换实体(线路tab:商品/线路筛选参数均生效,按线路+物料编码合并)
|
||||
OutboundRankDO outboundRankDO = outboundRankAssembler.toDO(outboundRankDTO);
|
||||
//线路tab:忽略商品筛选参数
|
||||
outboundRankDO.setMaterialCode(null);
|
||||
outboundRankDO.setMaterialName(null);
|
||||
startPage();
|
||||
List<OutboundDetailRankPO> list = outboundRankApplicationService.queryDetailList(outboundRankDO);
|
||||
OutboundDetailRankTotalPO total = outboundRankApplicationService.queryDetailTotal(outboundRankDO);
|
||||
List<OutboundLineRankPO> 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<OutboundDetailRankPO> list = outboundRankApplicationService.exportDetailList(outboundRankDO);
|
||||
List<OutboundMaterialRankPO> 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<OutboundDetailRankPO> util = new ExcelUtil<>(OutboundDetailRankPO.class);
|
||||
ExcelUtil<OutboundMaterialRankPO> 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<OutboundDetailRankPO> list = outboundRankApplicationService.exportDetailList(outboundRankDO);
|
||||
List<OutboundLineRankPO> 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<OutboundDetailRankPO> util = new ExcelUtil<>(OutboundDetailRankPO.class);
|
||||
ExcelUtil<OutboundLineRankPO> 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<String, Object> getDataTableWithTotal(List<?> list, OutboundDetailRankTotalPO total) {
|
||||
HashMap<String, Object> 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;
|
||||
}
|
||||
|
||||
@@ -14,18 +14,18 @@ spring:
|
||||
nacos:
|
||||
discovery:
|
||||
# server-addr: 127.0.0.1:8848
|
||||
# server-addr: 10.33.0.129:6010
|
||||
server-addr: 10.33.0.129:6010
|
||||
# 线上测试环境配置 容器名+端口号
|
||||
server-addr: 10.102.192.31:6848
|
||||
# server-addr: 10.102.192.30:6848
|
||||
username: nacos
|
||||
password: manhuoda@2023
|
||||
#线上正式环境
|
||||
# server-addr: 10.102.192.105:6848
|
||||
config:
|
||||
# server-addr: 127.0.0.1:8848
|
||||
# server-addr: 10.33.0.129:
|
||||
server-addr: 10.33.0.129:6010
|
||||
# 线上测试环境配置 容器名+端口号
|
||||
server-addr: 10.102.192.31:6848
|
||||
# server-addr: 10.102.192.30:6848
|
||||
username: nacos
|
||||
password: manhuoda@2023
|
||||
#线上正式环境
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
left join 货品档案 material_base_info(c,取保额作投保总额)
|
||||
口径:b.status = 5已入库(排除已取消(6)/已关闭(7)及未完成单据);
|
||||
日期筛选按入仓单入仓日期 b.warehouse_date(与列表"入仓日期"列同源,为空的历史单按建档时间兜底);
|
||||
一行 = 某仓单(b.in_order_number)内某货品(a.material_code)的合计,按件数(实际上架量 SUM(a.SHELVES_QUANTITY))降序排名
|
||||
一行 = 一个物料的合计(按物料编码合并,区间内全部已入库仓单),按件数(实际上架量 SUM(a.SHELVES_QUANTITY))降序排名,
|
||||
件数为0的物料不返回(HAVING过滤);仓单编号/客户编号/存货人/入仓日期为单据级字段仅作查询条件不返回
|
||||
-->
|
||||
<sql id="inboundRankConditions">
|
||||
a.del_flag = 1
|
||||
@@ -54,14 +55,10 @@
|
||||
left join material_base_info c on a.material_base_info_id = c.material_base_info_id
|
||||
</sql>
|
||||
|
||||
<!-- 商品入库排名列表(仓单+货品汇总,按件数=实际上架量降序) -->
|
||||
<!-- 商品入库排名列表(按物料编码合并,按件数=实际上架量降序,过滤0件行) -->
|
||||
<select id="queryMaterialRankList" parameterType="com.mhd.wms.domain.inboundRank.repository.todo.InboundRankDO"
|
||||
resultType="com.mhd.wms.domain.inboundRank.repository.po.InboundMaterialRankPO">
|
||||
select
|
||||
IFNULL(MAX(b.warehouse_date), MAX(b.create_time)) AS warehouseDate,
|
||||
b.in_order_number AS inOrderNumber,
|
||||
MAX(b.shipper_code) AS shipperCode,
|
||||
MAX(b.shipper_name) AS shipperName,
|
||||
a.material_code AS materialCode,
|
||||
MAX(a.material_name) AS materialName,
|
||||
MAX(a.SPECIFICATION_MODEL) AS specificationModel,
|
||||
@@ -74,11 +71,13 @@
|
||||
<where>
|
||||
<include refid="inboundRankConditions"/>
|
||||
</where>
|
||||
GROUP BY b.in_order_number, a.material_code
|
||||
order by pieceCount desc, warehouseDate desc, inOrderNumber desc
|
||||
GROUP BY a.material_code
|
||||
HAVING pieceCount > 0
|
||||
order by pieceCount desc, materialCode
|
||||
</select>
|
||||
|
||||
<!-- 商品入库排名合计(当前筛选条件全量;外层对分组结果再汇总,保证投保总额合计=各行列值之和) -->
|
||||
<!-- 商品入库排名合计(当前筛选条件全量;外层对物料分组结果再汇总,投保总额合计=各物料保额之和(每物料计一次);
|
||||
涉及仓单数按明细行去重统计仓单) -->
|
||||
<select id="queryMaterialRankTotal" parameterType="com.mhd.wms.domain.inboundRank.repository.todo.InboundRankDO"
|
||||
resultType="com.mhd.wms.domain.inboundRank.repository.po.InboundRankTotalPO">
|
||||
select
|
||||
@@ -86,10 +85,14 @@
|
||||
ROUND(IFNULL(SUM(t.grossWeightKG), 0) / 1000, 3) AS totalGrossWeightTon,
|
||||
IFNULL(SUM(t.insureAmount), 0) AS totalInsureAmount,
|
||||
IFNULL(SUM(t.totalVolume), 0) AS totalVolume,
|
||||
COUNT(DISTINCT t.inOrderNumber) AS totalOrderCount
|
||||
(select COUNT(DISTINCT b.in_order_number)
|
||||
<include refid="inboundRankFrom"/>
|
||||
<where>
|
||||
<include refid="inboundRankConditions"/>
|
||||
</where>) AS totalOrderCount
|
||||
from (
|
||||
select
|
||||
b.in_order_number AS inOrderNumber,
|
||||
a.material_code AS materialCode,
|
||||
IFNULL(SUM(a.SHELVES_QUANTITY), 0) AS pieceCount,
|
||||
IFNULL(SUM(a.TOTAL_GROSS_WEIGHT), 0) AS grossWeightKG,
|
||||
MAX(IFNULL(c.insure_amount, 0)) AS insureAmount,
|
||||
@@ -98,7 +101,7 @@
|
||||
<where>
|
||||
<include refid="inboundRankConditions"/>
|
||||
</where>
|
||||
GROUP BY b.in_order_number, a.material_code
|
||||
GROUP BY a.material_code
|
||||
) t
|
||||
</select>
|
||||
</mapper>
|
||||
|
||||
@@ -5,12 +5,13 @@
|
||||
<mapper namespace="com.mhd.wms.domain.outboundRank.repository.mapper.OutboundRankMapper">
|
||||
|
||||
<!--
|
||||
出库排名统计(明细)公共查询条件
|
||||
出库排名统计公共查询条件
|
||||
数据源:出库明细 out_material_detail(a,仅 level=1 主行防重复) join 出库单 stock_out_order(b)
|
||||
口径:b.status in (9已出库,12已复核,13已交接),排除已取消(10)/已关闭(11);
|
||||
日期按出库单创建时间 b.create_time(与出库单列表日期筛选一致);
|
||||
一行 = 某仓单(b.out_order_number)内某货品(a.material_code)的合计;
|
||||
件数 = SUM(a.CHECK_QUANTITY) 复核确认的实际出库量(与入库排名的实际上架量 SHELVES_QUANTITY 对称),按件数降序排名
|
||||
商品排名:一行 = 一个货品(GROUP BY a.material_code),区间内跨单汇总,按实际出库量降序;
|
||||
线路排名:一行 = 线路×货品(GROUP BY b.line_code, a.material_code),仅统计带线路的单;
|
||||
件数 = SUM(a.CHECK_QUANTITY) 复核确认的实际出库量(与入库排名的实际上架量 SHELVES_QUANTITY 对称)
|
||||
-->
|
||||
<sql id="outboundRankConditions">
|
||||
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
|
||||
</sql>
|
||||
|
||||
<!-- 出库明细列表(仓单+货品汇总,按件数(实际复核出库量)降序;退保总额暂无后端字段不提供) -->
|
||||
<select id="queryDetailList" parameterType="com.mhd.wms.domain.outboundRank.repository.todo.OutboundRankDO"
|
||||
resultType="com.mhd.wms.domain.outboundRank.repository.po.OutboundDetailRankPO">
|
||||
<!-- 商品出库排名列表(按物料编码合并,跨单汇总;退保总额暂无后端字段不提供) -->
|
||||
<select id="queryMaterialRankList" parameterType="com.mhd.wms.domain.outboundRank.repository.todo.OutboundRankDO"
|
||||
resultType="com.mhd.wms.domain.outboundRank.repository.po.OutboundMaterialRankPO">
|
||||
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
|
||||
<include refid="outboundRankFrom"/>
|
||||
<where>
|
||||
<include refid="outboundRankConditions"/>
|
||||
</where>
|
||||
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>
|
||||
|
||||
<!-- 出库明细合计(当前筛选条件全量;外层对分组结果再汇总,与入库排名同模板) -->
|
||||
<select id="queryDetailTotal" parameterType="com.mhd.wms.domain.outboundRank.repository.todo.OutboundRankDO"
|
||||
<!-- 商品出库排名合计(当前筛选条件全量) -->
|
||||
<select id="queryMaterialRankTotal" parameterType="com.mhd.wms.domain.outboundRank.repository.todo.OutboundRankDO"
|
||||
resultType="com.mhd.wms.domain.outboundRank.repository.po.OutboundDetailRankTotalPO">
|
||||
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
|
||||
<include refid="outboundRankFrom"/>
|
||||
<where>
|
||||
<include refid="outboundRankConditions"/>
|
||||
</where>
|
||||
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
|
||||
<include refid="outboundRankFrom"/>
|
||||
<where>
|
||||
<include refid="outboundRankConditions"/>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<!-- 线路出库排名列表(线路+物料编码合并,仅统计带线路的单;商品/线路筛选参数均生效) -->
|
||||
<select id="queryLineRankList" parameterType="com.mhd.wms.domain.outboundRank.repository.todo.OutboundRankDO"
|
||||
resultType="com.mhd.wms.domain.outboundRank.repository.po.OutboundLineRankPO">
|
||||
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
|
||||
<include refid="outboundRankFrom"/>
|
||||
<where>
|
||||
<include refid="outboundRankConditions"/>
|
||||
and b.line_code is not null and b.line_code != ''
|
||||
</where>
|
||||
GROUP BY b.line_code, a.material_code
|
||||
order by pieceCount desc, lineCode asc, materialCode asc
|
||||
</select>
|
||||
|
||||
<!-- 线路出库排名合计(当前筛选条件全量) -->
|
||||
<select id="queryLineRankTotal" parameterType="com.mhd.wms.domain.outboundRank.repository.todo.OutboundRankDO"
|
||||
resultType="com.mhd.wms.domain.outboundRank.repository.po.OutboundDetailRankTotalPO">
|
||||
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
|
||||
<include refid="outboundRankFrom"/>
|
||||
<where>
|
||||
<include refid="outboundRankConditions"/>
|
||||
and b.line_code is not null and b.line_code != ''
|
||||
</where>
|
||||
</select>
|
||||
</mapper>
|
||||
|
||||
Reference in New Issue
Block a user