feat(wms): 新增WMS报表管理功能
1.退库原因分析报表returnReasonAnalysis 统计各类退库(生产退库、销售退库等)的数量、占比及主要退库原因(如质量问题、订单变更),为改进生产、销售和质量管理提供数据支持。 2.库存变动趋势分析表inventoryTrendAnalysis 内容:以折线图/柱状图展示某物料或类别在一段时间内的库存数量变化(如近3个月每周结存),标注关键节点(如大额入库/出库)。 作用:识别库存波动规律(如季节性增减),预测未来库存需求,避免积压或短缺。 3.安全库存预警表safetyStockAlert 内容:对比物料当前库存与设定的“安全库存值”,列出“低于安全库存”(短缺预警)或“高于最高库存”(积压预警)的物料及差异量。 4.呆滞料库存报表stagnantInventory 内容:定义“呆滞标准”(如6个月未出库),统计符合标准的物料及数量、金额,标注呆滞原因(如订单取消/设计变更)。 作用:推动呆滞料处理(如折价处理、返工利用),减少资金占用和仓储成本。 5.库存差异报表inventoryDifference 内容:记录盘点后实际数量与系统账面数量的差异(差异量、差异率),标注差异物料及可能原因(如漏记、丢失、计数错误)。 作用:跟踪差异处理进度(如调账、追责),改进仓库操作规范(如加强入库扫码校验)。 6定期生成库存周转报表inventoryTurnover 库存周转率=(销售数量/库存数量)x100%例如6月销售31台,期末库存65台库存周转率=(31/65)*100%=47.69% 库存周转率=(该期间的出库总金额/该期间的平均库存金额)x100%=该期间出库总金额x2/(期初库存金额+期末库存金额)x100%库存周转率=312*2/(490+589)=56.9%hwmom-htk
parent
4d14ea4268
commit
cdd8502c11
@ -0,0 +1,90 @@
|
||||
package org.dromara.mes.domain.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 报工工时数据报表VO
|
||||
*
|
||||
* @author Yinq
|
||||
* @date 2025-01-17
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class WorkHourReportVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 派工单
|
||||
*/
|
||||
@ExcelProperty(value = "派工单")
|
||||
private String dispatchCode;
|
||||
|
||||
/**
|
||||
* 班组
|
||||
*/
|
||||
@ExcelProperty(value = "班组")
|
||||
private String teamName;
|
||||
|
||||
/**
|
||||
* 工位
|
||||
*/
|
||||
@ExcelProperty(value = "工位")
|
||||
private String stationName;
|
||||
|
||||
/**
|
||||
* 物料名称
|
||||
*/
|
||||
@ExcelProperty(value = "物料名称")
|
||||
private String materialName;
|
||||
|
||||
/**
|
||||
* 工序名称
|
||||
*/
|
||||
@ExcelProperty(value = "工序名称")
|
||||
private String processName;
|
||||
|
||||
/**
|
||||
* 报工数量
|
||||
*/
|
||||
@ExcelProperty(value = "报工数量")
|
||||
private BigDecimal completeAmount;
|
||||
|
||||
/**
|
||||
* 标准工时(h)
|
||||
*/
|
||||
@ExcelProperty(value = "标准工时(h)")
|
||||
private BigDecimal standardWorkHour;
|
||||
|
||||
/**
|
||||
* 报工工时(h)
|
||||
*/
|
||||
@ExcelProperty(value = "报工工时(h)")
|
||||
private BigDecimal reportWorkHour;
|
||||
|
||||
/**
|
||||
* 生产效率
|
||||
*/
|
||||
@ExcelProperty(value = "生产效率")
|
||||
private BigDecimal productionEfficiency;
|
||||
|
||||
/**
|
||||
* 派工单状态
|
||||
*/
|
||||
@ExcelProperty(value = "派工单状态")
|
||||
private String planStatus;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@ExcelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
}
|
||||
@ -0,0 +1,187 @@
|
||||
package org.dromara.wms.controller;
|
||||
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.excel.utils.ExcelUtil;
|
||||
import org.dromara.common.log.annotation.Log;
|
||||
import org.dromara.common.log.enums.BusinessType;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.dromara.wms.domain.vo.*;
|
||||
import org.dromara.wms.service.IWmsReportService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* WMS报表管理
|
||||
* 前端访问路由地址为:/wms/report
|
||||
*
|
||||
* @author hwmom
|
||||
* @date 2025-01-20
|
||||
*/
|
||||
@Validated
|
||||
@RequiredArgsConstructor
|
||||
@RestController
|
||||
@RequestMapping("/report")
|
||||
public class WmsReportController extends BaseController {
|
||||
|
||||
private final IWmsReportService wmsReportService;
|
||||
|
||||
/**
|
||||
* 查询退库原因分析报表
|
||||
*/
|
||||
//@SaCheckPermission("wms:report:returnReason")
|
||||
@GetMapping("/returnReasonAnalysis")
|
||||
public R<List<WmsReturnReasonAnalysisVo>> getReturnReasonAnalysis(
|
||||
@RequestParam(required = false) String tenantId,
|
||||
@RequestParam(required = false) Long materialCategoryId) {
|
||||
List<WmsReturnReasonAnalysisVo> list = wmsReportService.getReturnReasonAnalysis(tenantId, materialCategoryId);
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出退库原因分析报表
|
||||
*/
|
||||
//@SaCheckPermission("wms:report:returnReason")
|
||||
@Log(title = "退库原因分析报表", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/returnReasonAnalysis/export")
|
||||
public void exportReturnReasonAnalysis(
|
||||
@RequestParam(required = false) String tenantId,
|
||||
@RequestParam(required = false) Long materialCategoryId,
|
||||
HttpServletResponse response) {
|
||||
List<WmsReturnReasonAnalysisVo> list = wmsReportService.getReturnReasonAnalysis(tenantId, materialCategoryId);
|
||||
ExcelUtil.exportExcel(list, "退库原因分析报表", WmsReturnReasonAnalysisVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询库存变动趋势分析报表
|
||||
*/
|
||||
//@SaCheckPermission("wms:report:inventoryTrend")
|
||||
@GetMapping("/inventoryTrendAnalysis")
|
||||
public R<List<WmsInventoryTrendAnalysisVo>> getInventoryTrendAnalysis(
|
||||
@RequestParam(required = false) String tenantId,
|
||||
@RequestParam(required = false) Long materialCategoryId) {
|
||||
List<WmsInventoryTrendAnalysisVo> list = wmsReportService.getInventoryTrendAnalysis(tenantId, materialCategoryId);
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出库存变动趋势分析报表
|
||||
*/
|
||||
//@SaCheckPermission("wms:report:inventoryTrend")
|
||||
@Log(title = "库存变动趋势分析报表", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/inventoryTrendAnalysis/export")
|
||||
public void exportInventoryTrendAnalysis(
|
||||
@RequestParam(required = false) String tenantId,
|
||||
@RequestParam(required = false) Long materialCategoryId,
|
||||
HttpServletResponse response) {
|
||||
List<WmsInventoryTrendAnalysisVo> list = wmsReportService.getInventoryTrendAnalysis(tenantId, materialCategoryId);
|
||||
ExcelUtil.exportExcel(list, "库存变动趋势分析报表", WmsInventoryTrendAnalysisVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询安全库存预警报表
|
||||
*/
|
||||
//@SaCheckPermission("wms:report:safetyStock")
|
||||
@GetMapping("/safetyStockAlert")
|
||||
public R<List<WmsSafetyStockAlertVo>> getSafetyStockAlert(
|
||||
@RequestParam(required = false) String tenantId,
|
||||
@RequestParam(required = false) Long materialCategoryId) {
|
||||
List<WmsSafetyStockAlertVo> list = wmsReportService.getSafetyStockAlert(tenantId, materialCategoryId);
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出安全库存预警报表
|
||||
*/
|
||||
//@SaCheckPermission("wms:report:safetyStock")
|
||||
@Log(title = "安全库存预警报表", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/safetyStockAlert/export")
|
||||
public void exportSafetyStockAlert(
|
||||
@RequestParam(required = false) String tenantId,
|
||||
@RequestParam(required = false) Long materialCategoryId,
|
||||
HttpServletResponse response) {
|
||||
List<WmsSafetyStockAlertVo> list = wmsReportService.getSafetyStockAlert(tenantId, materialCategoryId);
|
||||
ExcelUtil.exportExcel(list, "安全库存预警报表", WmsSafetyStockAlertVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询呆滞料库存报表
|
||||
*/
|
||||
//@SaCheckPermission("wms:report:stagnantInventory")
|
||||
@GetMapping("/stagnantInventory")
|
||||
public R<List<WmsStagnantInventoryVo>> getStagnantInventory(
|
||||
@RequestParam(required = false) String tenantId,
|
||||
@RequestParam(required = false) Long materialCategoryId) {
|
||||
List<WmsStagnantInventoryVo> list = wmsReportService.getStagnantInventory(tenantId, materialCategoryId);
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出呆滞料库存报表
|
||||
*/
|
||||
//@SaCheckPermission("wms:report:stagnantInventory")
|
||||
@Log(title = "呆滞料库存报表", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/stagnantInventory/export")
|
||||
public void exportStagnantInventory(
|
||||
@RequestParam(required = false) String tenantId,
|
||||
@RequestParam(required = false) Long materialCategoryId,
|
||||
HttpServletResponse response) {
|
||||
List<WmsStagnantInventoryVo> list = wmsReportService.getStagnantInventory(tenantId, materialCategoryId);
|
||||
ExcelUtil.exportExcel(list, "呆滞料库存报表", WmsStagnantInventoryVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询库存差异报表
|
||||
*/
|
||||
//@SaCheckPermission("wms:report:inventoryDifference")
|
||||
@GetMapping("/inventoryDifference")
|
||||
public R<List<WmsInventoryDifferenceVo>> getInventoryDifference(
|
||||
@RequestParam(required = false) String tenantId,
|
||||
@RequestParam(required = false) Long materialCategoryId) {
|
||||
List<WmsInventoryDifferenceVo> list = wmsReportService.getInventoryDifference(tenantId, materialCategoryId);
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出库存差异报表
|
||||
*/
|
||||
//@SaCheckPermission("wms:report:inventoryDifference")
|
||||
@Log(title = "库存差异报表", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/inventoryDifference/export")
|
||||
public void exportInventoryDifference(
|
||||
@RequestParam(required = false) String tenantId,
|
||||
@RequestParam(required = false) Long materialCategoryId,
|
||||
HttpServletResponse response) {
|
||||
List<WmsInventoryDifferenceVo> list = wmsReportService.getInventoryDifference(tenantId, materialCategoryId);
|
||||
ExcelUtil.exportExcel(list, "库存差异报表", WmsInventoryDifferenceVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询库存周转报表
|
||||
*/
|
||||
//@SaCheckPermission("wms:report:inventoryTurnover")
|
||||
@GetMapping("/inventoryTurnover")
|
||||
public R<List<WmsInventoryTurnoverVo>> getInventoryTurnover(
|
||||
@RequestParam(required = false) String tenantId,
|
||||
@RequestParam(required = false) Long materialCategoryId) {
|
||||
List<WmsInventoryTurnoverVo> list = wmsReportService.getInventoryTurnover(tenantId, materialCategoryId);
|
||||
return R.ok(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出库存周转报表
|
||||
*/
|
||||
//@SaCheckPermission("wms:report:inventoryTurnover")
|
||||
@Log(title = "库存周转报表", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/inventoryTurnover/export")
|
||||
public void exportInventoryTurnover(
|
||||
@RequestParam(required = false) String tenantId,
|
||||
@RequestParam(required = false) Long materialCategoryId,
|
||||
HttpServletResponse response) {
|
||||
List<WmsInventoryTurnoverVo> list = wmsReportService.getInventoryTurnover(tenantId, materialCategoryId);
|
||||
ExcelUtil.exportExcel(list, "库存周转报表", WmsInventoryTurnoverVo.class, response);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,126 @@
|
||||
package org.dromara.wms.domain.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 库存差异报表视图对象 wms_inventory_difference
|
||||
*
|
||||
* @author hwmom
|
||||
* @date 2025-01-20
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class WmsInventoryDifferenceVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 租户编号
|
||||
*/
|
||||
@ExcelProperty(value = "租户编号")
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* 盘点单号
|
||||
*/
|
||||
@ExcelProperty(value = "盘点单号")
|
||||
private String checkCode;
|
||||
|
||||
/**
|
||||
* 盘点类型
|
||||
*/
|
||||
@ExcelProperty(value = "盘点类型")
|
||||
private String checkType;
|
||||
|
||||
/**
|
||||
* 仓库ID
|
||||
*/
|
||||
@ExcelProperty(value = "仓库ID")
|
||||
private Long warehouseId;
|
||||
|
||||
/**
|
||||
* 仓库名称
|
||||
*/
|
||||
@ExcelProperty(value = "仓库名称")
|
||||
private String warehouseName;
|
||||
|
||||
/**
|
||||
* 物料ID
|
||||
*/
|
||||
@ExcelProperty(value = "物料ID")
|
||||
private Long materialId;
|
||||
|
||||
/**
|
||||
* 物料编码
|
||||
*/
|
||||
@ExcelProperty(value = "物料编码")
|
||||
private String materialCode;
|
||||
|
||||
/**
|
||||
* 物料名称
|
||||
*/
|
||||
@ExcelProperty(value = "物料名称")
|
||||
private String materialName;
|
||||
|
||||
/**
|
||||
* 物料大类
|
||||
*/
|
||||
@ExcelProperty(value = "物料大类")
|
||||
private String materialCategoryName;
|
||||
|
||||
/**
|
||||
* 账面数量
|
||||
*/
|
||||
@ExcelProperty(value = "账面数量")
|
||||
private BigDecimal bookInventoryQty;
|
||||
|
||||
/**
|
||||
* 实际盘点数量
|
||||
*/
|
||||
@ExcelProperty(value = "实际盘点数量")
|
||||
private BigDecimal actualInventoryQty;
|
||||
|
||||
/**
|
||||
* 差异量
|
||||
*/
|
||||
@ExcelProperty(value = "差异量")
|
||||
private BigDecimal differenceQty;
|
||||
|
||||
/**
|
||||
* 差异类型
|
||||
*/
|
||||
@ExcelProperty(value = "差异类型")
|
||||
private String differenceType;
|
||||
|
||||
/**
|
||||
* 差异率
|
||||
*/
|
||||
@ExcelProperty(value = "差异率(%)")
|
||||
private BigDecimal differenceRate;
|
||||
|
||||
/**
|
||||
* 差异等级
|
||||
*/
|
||||
@ExcelProperty(value = "差异等级")
|
||||
private String differenceLevel;
|
||||
|
||||
/**
|
||||
* 盘点时间
|
||||
*/
|
||||
@ExcelProperty(value = "盘点时间")
|
||||
private Date checkTime;
|
||||
|
||||
/**
|
||||
* 盘点人员
|
||||
*/
|
||||
@ExcelProperty(value = "盘点人员")
|
||||
private String checkBy;
|
||||
}
|
||||
@ -0,0 +1,95 @@
|
||||
package org.dromara.wms.domain.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 库存变动趋势分析报表视图对象 wms_inventory_trend_analysis
|
||||
*
|
||||
* @author hwmom
|
||||
* @date 2025-01-20
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class WmsInventoryTrendAnalysisVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 租户编号
|
||||
*/
|
||||
@ExcelProperty(value = "租户编号")
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* 物料ID
|
||||
*/
|
||||
@ExcelProperty(value = "物料ID")
|
||||
private Long materialId;
|
||||
|
||||
/**
|
||||
* 物料编码
|
||||
*/
|
||||
@ExcelProperty(value = "物料编码")
|
||||
private String materialCode;
|
||||
|
||||
/**
|
||||
* 物料名称
|
||||
*/
|
||||
@ExcelProperty(value = "物料名称")
|
||||
private String materialName;
|
||||
|
||||
/**
|
||||
* 物料大类
|
||||
*/
|
||||
@ExcelProperty(value = "物料大类")
|
||||
private String materialCategoryName;
|
||||
|
||||
/**
|
||||
* 统计月份
|
||||
*/
|
||||
@ExcelProperty(value = "统计月份")
|
||||
private String statisticsMonth;
|
||||
|
||||
/**
|
||||
* 统计周
|
||||
*/
|
||||
@ExcelProperty(value = "统计周")
|
||||
private Integer statisticsWeek;
|
||||
|
||||
/**
|
||||
* 当前库存数量
|
||||
*/
|
||||
@ExcelProperty(value = "当前库存数量")
|
||||
private BigDecimal currentInventoryQty;
|
||||
|
||||
/**
|
||||
* 本周入库数量
|
||||
*/
|
||||
@ExcelProperty(value = "本周入库数量")
|
||||
private BigDecimal weekInstockQty;
|
||||
|
||||
/**
|
||||
* 本周出库数量
|
||||
*/
|
||||
@ExcelProperty(value = "本周出库数量")
|
||||
private BigDecimal weekOutstockQty;
|
||||
|
||||
/**
|
||||
* 上周结存数量
|
||||
*/
|
||||
@ExcelProperty(value = "上周结存数量")
|
||||
private BigDecimal lastWeekInventoryQty;
|
||||
|
||||
/**
|
||||
* 关键节点标注
|
||||
*/
|
||||
@ExcelProperty(value = "关键节点标注")
|
||||
private String keyNodeMark;
|
||||
}
|
||||
@ -0,0 +1,95 @@
|
||||
package org.dromara.wms.domain.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 库存周转报表视图对象 wms_inventory_turnover
|
||||
*
|
||||
* @author hwmom
|
||||
* @date 2025-01-20
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class WmsInventoryTurnoverVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 租户编号
|
||||
*/
|
||||
@ExcelProperty(value = "租户编号")
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* 物料ID
|
||||
*/
|
||||
@ExcelProperty(value = "物料ID")
|
||||
private Long materialId;
|
||||
|
||||
/**
|
||||
* 物料编码
|
||||
*/
|
||||
@ExcelProperty(value = "物料编码")
|
||||
private String materialCode;
|
||||
|
||||
/**
|
||||
* 物料名称
|
||||
*/
|
||||
@ExcelProperty(value = "物料名称")
|
||||
private String materialName;
|
||||
|
||||
/**
|
||||
* 物料大类
|
||||
*/
|
||||
@ExcelProperty(value = "物料大类")
|
||||
private String materialCategoryName;
|
||||
|
||||
/**
|
||||
* 统计月份
|
||||
*/
|
||||
@ExcelProperty(value = "统计月份")
|
||||
private String statisticsMonth;
|
||||
|
||||
/**
|
||||
* 月初库存数量
|
||||
*/
|
||||
@ExcelProperty(value = "月初库存数量")
|
||||
private BigDecimal beginInventoryQty;
|
||||
|
||||
/**
|
||||
* 月末库存数量
|
||||
*/
|
||||
@ExcelProperty(value = "月末库存数量")
|
||||
private BigDecimal endInventoryQty;
|
||||
|
||||
/**
|
||||
* 月出库数量
|
||||
*/
|
||||
@ExcelProperty(value = "月出库数量")
|
||||
private BigDecimal monthOutstockQty;
|
||||
|
||||
/**
|
||||
* 库存周转率
|
||||
*/
|
||||
@ExcelProperty(value = "库存周转率(%)")
|
||||
private BigDecimal inventoryTurnoverRate;
|
||||
|
||||
/**
|
||||
* 简化周转率
|
||||
*/
|
||||
@ExcelProperty(value = "简化周转率(%)")
|
||||
private BigDecimal simpleTurnoverRate;
|
||||
|
||||
/**
|
||||
* 周转评价
|
||||
*/
|
||||
@ExcelProperty(value = "周转评价")
|
||||
private String turnoverEvaluation;
|
||||
}
|
||||
@ -0,0 +1,77 @@
|
||||
package org.dromara.wms.domain.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 退库原因分析报表视图对象 wms_return_reason_analysis
|
||||
*
|
||||
* @author hwmom
|
||||
* @date 2025-01-20
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class WmsReturnReasonAnalysisVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 租户编号
|
||||
*/
|
||||
@ExcelProperty(value = "租户编号")
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* 退库原因分类
|
||||
*/
|
||||
@ExcelProperty(value = "退库原因分类")
|
||||
private String returnReasonCategory;
|
||||
|
||||
/**
|
||||
* 退库单数
|
||||
*/
|
||||
@ExcelProperty(value = "退库单数")
|
||||
private Long returnOrderCount;
|
||||
|
||||
/**
|
||||
* 退库总数量
|
||||
*/
|
||||
@ExcelProperty(value = "退库总数量")
|
||||
private BigDecimal totalReturnAmount;
|
||||
|
||||
/**
|
||||
* 退库单数占比
|
||||
*/
|
||||
@ExcelProperty(value = "退库单数占比(%)")
|
||||
private BigDecimal orderCountRatio;
|
||||
|
||||
/**
|
||||
* 退库数量占比
|
||||
*/
|
||||
@ExcelProperty(value = "退库数量占比(%)")
|
||||
private BigDecimal amountRatio;
|
||||
|
||||
/**
|
||||
* 主要物料名称
|
||||
*/
|
||||
@ExcelProperty(value = "主要物料名称")
|
||||
private String materialName;
|
||||
|
||||
/**
|
||||
* 物料大类
|
||||
*/
|
||||
@ExcelProperty(value = "物料大类")
|
||||
private String materialCategoryName;
|
||||
|
||||
/**
|
||||
* 物料编码
|
||||
*/
|
||||
@ExcelProperty(value = "物料编码")
|
||||
private String materialCode;
|
||||
}
|
||||
@ -0,0 +1,96 @@
|
||||
package org.dromara.wms.domain.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 安全库存预警报表视图对象 wms_safety_stock_alert
|
||||
*
|
||||
* @author hwmom
|
||||
* @date 2025-01-20
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class WmsSafetyStockAlertVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 租户编号
|
||||
*/
|
||||
@ExcelProperty(value = "租户编号")
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* 物料ID
|
||||
*/
|
||||
@ExcelProperty(value = "物料ID")
|
||||
private Long materialId;
|
||||
|
||||
/**
|
||||
* 物料编码
|
||||
*/
|
||||
@ExcelProperty(value = "物料编码")
|
||||
private String materialCode;
|
||||
|
||||
/**
|
||||
* 物料名称
|
||||
*/
|
||||
@ExcelProperty(value = "物料名称")
|
||||
private String materialName;
|
||||
|
||||
/**
|
||||
* 物料大类
|
||||
*/
|
||||
@ExcelProperty(value = "物料大类")
|
||||
private String materialCategoryName;
|
||||
|
||||
/**
|
||||
* 当前库存数量
|
||||
*/
|
||||
@ExcelProperty(value = "当前库存数量")
|
||||
private BigDecimal currentInventoryQty;
|
||||
|
||||
/**
|
||||
* 安全库存值
|
||||
*/
|
||||
@ExcelProperty(value = "安全库存值")
|
||||
private BigDecimal safeStockAmount;
|
||||
|
||||
/**
|
||||
* 最小库存值
|
||||
*/
|
||||
@ExcelProperty(value = "最小库存值")
|
||||
private BigDecimal minStockAmount;
|
||||
|
||||
/**
|
||||
* 最大库存值
|
||||
*/
|
||||
@ExcelProperty(value = "最大库存值")
|
||||
private BigDecimal maxStockAmount;
|
||||
|
||||
/**
|
||||
* 预警状态
|
||||
*/
|
||||
@ExcelProperty(value = "预警状态")
|
||||
private String alertStatus;
|
||||
|
||||
/**
|
||||
* 差异量
|
||||
*/
|
||||
@ExcelProperty(value = "差异量")
|
||||
private BigDecimal differenceAmount;
|
||||
|
||||
/**
|
||||
* 最后更新时间
|
||||
*/
|
||||
@ExcelProperty(value = "最后更新时间")
|
||||
private Date lastUpdateTime;
|
||||
}
|
||||
@ -0,0 +1,102 @@
|
||||
package org.dromara.wms.domain.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 呆滞料库存报表视图对象 wms_stagnant_inventory
|
||||
*
|
||||
* @author hwmom
|
||||
* @date 2025-01-20
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class WmsStagnantInventoryVo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 租户编号
|
||||
*/
|
||||
@ExcelProperty(value = "租户编号")
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* 物料ID
|
||||
*/
|
||||
@ExcelProperty(value = "物料ID")
|
||||
private Long materialId;
|
||||
|
||||
/**
|
||||
* 物料编码
|
||||
*/
|
||||
@ExcelProperty(value = "物料编码")
|
||||
private String materialCode;
|
||||
|
||||
/**
|
||||
* 物料名称
|
||||
*/
|
||||
@ExcelProperty(value = "物料名称")
|
||||
private String materialName;
|
||||
|
||||
/**
|
||||
* 物料大类
|
||||
*/
|
||||
@ExcelProperty(value = "物料大类")
|
||||
private String materialCategoryName;
|
||||
|
||||
/**
|
||||
* 呆滞库存数量
|
||||
*/
|
||||
@ExcelProperty(value = "呆滞库存数量")
|
||||
private BigDecimal stagnantInventoryQty;
|
||||
|
||||
/**
|
||||
* 计量单位
|
||||
*/
|
||||
@ExcelProperty(value = "计量单位")
|
||||
private String materialUnit;
|
||||
|
||||
/**
|
||||
* 最后出库时间
|
||||
*/
|
||||
@ExcelProperty(value = "最后出库时间")
|
||||
private String lastOutstockTime;
|
||||
|
||||
/**
|
||||
* 呆滞天数
|
||||
*/
|
||||
@ExcelProperty(value = "呆滞天数")
|
||||
private Integer stagnantDays;
|
||||
|
||||
/**
|
||||
* 呆滞原因
|
||||
*/
|
||||
@ExcelProperty(value = "呆滞原因")
|
||||
private String stagnantReason;
|
||||
|
||||
/**
|
||||
* 物料规格
|
||||
*/
|
||||
@ExcelProperty(value = "物料规格")
|
||||
private String materialSpec;
|
||||
|
||||
/**
|
||||
* 所在仓库
|
||||
*/
|
||||
@ExcelProperty(value = "所在仓库")
|
||||
private String warehouseName;
|
||||
|
||||
/**
|
||||
* 最后活动时间
|
||||
*/
|
||||
@ExcelProperty(value = "最后活动时间")
|
||||
private String lastActivityTime;
|
||||
}
|
||||
@ -0,0 +1,341 @@
|
||||
package org.dromara.wms.mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.dromara.wms.domain.vo.*;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* WMS报表Mapper接口
|
||||
*
|
||||
* @author hwmom
|
||||
* @date 2025-01-20
|
||||
*/
|
||||
@Repository
|
||||
@Mapper
|
||||
public interface WmsReportMapper {
|
||||
|
||||
/**
|
||||
* 查询退库原因分析报表
|
||||
*/
|
||||
@Select("SELECT " +
|
||||
" ro.tenant_id AS tenantId, " +
|
||||
" CASE " +
|
||||
" WHEN ro.return_reason LIKE '%质量%' OR ro.return_reason LIKE '%不合格%' THEN '质量问题' " +
|
||||
" WHEN ro.return_reason LIKE '%订单%' OR ro.return_reason LIKE '%变更%' THEN '订单变更' " +
|
||||
" WHEN ro.return_reason LIKE '%损坏%' OR ro.return_reason LIKE '%破损%' THEN '物料损坏' " +
|
||||
" WHEN ro.return_reason LIKE '%过期%' OR ro.return_reason LIKE '%超期%' THEN '过期物料' " +
|
||||
" ELSE '其他原因' " +
|
||||
" END AS returnReasonCategory, " +
|
||||
" COUNT(*) AS returnOrderCount, " +
|
||||
" SUM(ro.return_amount) AS totalReturnAmount, " +
|
||||
" CAST(COUNT(*) * 100.0 / (SELECT COUNT(*) FROM wms_return_order WHERE tenant_id = ro.tenant_id AND order_status = '1') AS DECIMAL(10,2)) AS orderCountRatio, " +
|
||||
" CAST(SUM(ro.return_amount) * 100.0 / (SELECT SUM(return_amount) FROM wms_return_order WHERE tenant_id = ro.tenant_id AND order_status = '1') AS DECIMAL(10,2)) AS amountRatio, " +
|
||||
" mi.material_name AS materialName, " +
|
||||
" mc.material_category_name AS materialCategoryName, " +
|
||||
" mi.material_code AS materialCode " +
|
||||
"FROM wms_return_order ro " +
|
||||
"INNER JOIN base_material_info_copy1 mi ON ro.material_id = mi.material_id " +
|
||||
"INNER JOIN base_material_category mc ON mi.material_category_id = mc.material_category_id " +
|
||||
"WHERE ro.order_status = '1' " +
|
||||
" AND (#{tenantId} IS NULL OR ro.tenant_id = #{tenantId}) " +
|
||||
" AND (#{materialCategoryId} IS NULL OR mc.material_category_id = #{materialCategoryId}) " +
|
||||
"GROUP BY ro.tenant_id, " +
|
||||
" CASE " +
|
||||
" WHEN ro.return_reason LIKE '%质量%' OR ro.return_reason LIKE '%不合格%' THEN '质量问题' " +
|
||||
" WHEN ro.return_reason LIKE '%订单%' OR ro.return_reason LIKE '%变更%' THEN '订单变更' " +
|
||||
" WHEN ro.return_reason LIKE '%损坏%' OR ro.return_reason LIKE '%破损%' THEN '物料损坏' " +
|
||||
" WHEN ro.return_reason LIKE '%过期%' OR ro.return_reason LIKE '%超期%' THEN '过期物料' " +
|
||||
" ELSE '其他原因' " +
|
||||
" END, " +
|
||||
" mi.material_name, " +
|
||||
" mc.material_category_name, " +
|
||||
" mi.material_code " +
|
||||
"ORDER BY ro.tenant_id, totalReturnAmount DESC")
|
||||
List<WmsReturnReasonAnalysisVo> selectReturnReasonAnalysis(@Param("tenantId") String tenantId,
|
||||
@Param("materialCategoryId") Long materialCategoryId);
|
||||
|
||||
/**
|
||||
* 查询库存变动趋势分析报表
|
||||
*/
|
||||
@Select("SELECT " +
|
||||
" inv.tenant_id AS tenantId, " +
|
||||
" inv.material_id AS materialId, " +
|
||||
" mi.material_code AS materialCode, " +
|
||||
" mi.material_name AS materialName, " +
|
||||
" mc.material_category_name AS materialCategoryName, " +
|
||||
" CONVERT(VARCHAR(7), GETDATE(), 126) AS statisticsMonth, " +
|
||||
" DATEPART(WEEK, GETDATE()) AS statisticsWeek, " +
|
||||
" SUM(inv.inventory_qty) AS currentInventoryQty, " +
|
||||
" ISNULL(instock_data.weekInstockQty, 0) AS weekInstockQty, " +
|
||||
" ISNULL(outstock_data.weekOutstockQty, 0) AS weekOutstockQty, " +
|
||||
" (SUM(inv.inventory_qty) + ISNULL(outstock_data.weekOutstockQty, 0) - ISNULL(instock_data.weekInstockQty, 0)) AS lastWeekInventoryQty, " +
|
||||
" CASE " +
|
||||
" WHEN ISNULL(instock_data.weekInstockQty, 0) > 1000 THEN '大额入库' " +
|
||||
" WHEN ISNULL(outstock_data.weekOutstockQty, 0) > 1000 THEN '大额出库' " +
|
||||
" ELSE '正常变动' " +
|
||||
" END AS keyNodeMark " +
|
||||
"FROM wms_inventory inv " +
|
||||
"INNER JOIN base_material_info_copy1 mi ON inv.material_id = mi.material_id " +
|
||||
"INNER JOIN base_material_category mc ON mi.material_category_id = mc.material_category_id " +
|
||||
"LEFT JOIN ( " +
|
||||
" SELECT material_id, tenant_id, SUM(instock_qty) AS weekInstockQty " +
|
||||
" FROM wms_instock_record " +
|
||||
" WHERE create_time >= DATEADD(DAY, -7, GETDATE()) " +
|
||||
" GROUP BY material_id, tenant_id " +
|
||||
") instock_data ON inv.material_id = instock_data.material_id AND inv.tenant_id = instock_data.tenant_id " +
|
||||
"LEFT JOIN ( " +
|
||||
" SELECT material_id, tenant_id, SUM(outstock_qty) AS weekOutstockQty " +
|
||||
" FROM wms_outstock_record " +
|
||||
" WHERE create_time >= DATEADD(DAY, -7, GETDATE()) " +
|
||||
" GROUP BY material_id, tenant_id " +
|
||||
") outstock_data ON inv.material_id = outstock_data.material_id AND inv.tenant_id = outstock_data.tenant_id " +
|
||||
"WHERE inv.inventory_status = '1' " +
|
||||
" AND (#{tenantId} IS NULL OR inv.tenant_id = #{tenantId}) " +
|
||||
" AND (#{materialCategoryId} IS NULL OR mc.material_category_id = #{materialCategoryId}) " +
|
||||
"GROUP BY inv.tenant_id, inv.material_id, mi.material_code, mi.material_name, mc.material_category_name, " +
|
||||
" instock_data.weekInstockQty, outstock_data.weekOutstockQty " +
|
||||
"ORDER BY inv.tenant_id, currentInventoryQty DESC")
|
||||
List<WmsInventoryTrendAnalysisVo> selectInventoryTrendAnalysis(@Param("tenantId") String tenantId,
|
||||
@Param("materialCategoryId") Long materialCategoryId);
|
||||
|
||||
/**
|
||||
* 查询安全库存预警报表
|
||||
*/
|
||||
@Select("SELECT " +
|
||||
" inv.tenant_id AS tenantId, " +
|
||||
" inv.material_id AS materialId, " +
|
||||
" mi.material_code AS materialCode, " +
|
||||
" mi.material_name AS materialName, " +
|
||||
" mc.material_category_name AS materialCategoryName, " +
|
||||
" SUM(inv.inventory_qty) AS currentInventoryQty, " +
|
||||
" mi.safe_stock_amount AS safeStockAmount, " +
|
||||
" mi.min_stock_amount AS minStockAmount, " +
|
||||
" mi.max_stock_amount AS maxStockAmount, " +
|
||||
" CASE " +
|
||||
" WHEN SUM(inv.inventory_qty) < mi.min_stock_amount THEN '短缺预警' " +
|
||||
" WHEN SUM(inv.inventory_qty) > mi.max_stock_amount THEN '积压预警' " +
|
||||
" WHEN SUM(inv.inventory_qty) < mi.safe_stock_amount THEN '低于安全库存' " +
|
||||
" ELSE '正常' " +
|
||||
" END AS alertStatus, " +
|
||||
" CASE " +
|
||||
" WHEN SUM(inv.inventory_qty) < mi.min_stock_amount THEN mi.min_stock_amount - SUM(inv.inventory_qty) " +
|
||||
" WHEN SUM(inv.inventory_qty) > mi.max_stock_amount THEN SUM(inv.inventory_qty) - mi.max_stock_amount " +
|
||||
" WHEN SUM(inv.inventory_qty) < mi.safe_stock_amount THEN mi.safe_stock_amount - SUM(inv.inventory_qty) " +
|
||||
" ELSE 0 " +
|
||||
" END AS differenceAmount, " +
|
||||
" inv.update_time AS lastUpdateTime " +
|
||||
"FROM wms_inventory inv " +
|
||||
"INNER JOIN base_material_info_copy1 mi ON inv.material_id = mi.material_id " +
|
||||
"INNER JOIN base_material_category mc ON mi.material_category_id = mc.material_category_id " +
|
||||
"WHERE inv.inventory_status = '1' " +
|
||||
" AND mi.active_flag = '1' " +
|
||||
" AND (mi.safe_stock_amount IS NOT NULL OR mi.min_stock_amount IS NOT NULL OR mi.max_stock_amount IS NOT NULL) " +
|
||||
" AND (#{tenantId} IS NULL OR inv.tenant_id = #{tenantId}) " +
|
||||
" AND (#{materialCategoryId} IS NULL OR mc.material_category_id = #{materialCategoryId}) " +
|
||||
"GROUP BY inv.tenant_id, inv.material_id, mi.material_code, mi.material_name, mc.material_category_name, " +
|
||||
" mi.safe_stock_amount, mi.min_stock_amount, mi.max_stock_amount, inv.update_time " +
|
||||
"HAVING SUM(inv.inventory_qty) < mi.safe_stock_amount " +
|
||||
" OR SUM(inv.inventory_qty) < mi.min_stock_amount " +
|
||||
" OR SUM(inv.inventory_qty) > mi.max_stock_amount " +
|
||||
"ORDER BY inv.tenant_id, alertStatus, differenceAmount DESC")
|
||||
List<WmsSafetyStockAlertVo> selectSafetyStockAlert(@Param("tenantId") String tenantId,
|
||||
@Param("materialCategoryId") Long materialCategoryId);
|
||||
|
||||
/**
|
||||
* 查询呆滞料库存报表
|
||||
*/
|
||||
@Select("SELECT " +
|
||||
" inv.tenant_id AS tenantId, " +
|
||||
" inv.material_id AS materialId, " +
|
||||
" mi.material_code AS materialCode, " +
|
||||
" mi.material_name AS materialName, " +
|
||||
" mc.material_category_name AS materialCategoryName, " +
|
||||
" SUM(inv.inventory_qty) AS stagnantInventoryQty, " +
|
||||
" mi.material_unit AS materialUnit, " +
|
||||
" CASE " +
|
||||
" WHEN last_out.lastOutstockTime IS NULL THEN '从未出库' " +
|
||||
" ELSE CONVERT(VARCHAR(19), last_out.lastOutstockTime, 120) " +
|
||||
" END AS lastOutstockTime, " +
|
||||
" CASE " +
|
||||
" WHEN last_out.lastOutstockTime IS NULL THEN DATEDIFF(DAY, first_in.firstInstockTime, GETDATE()) " +
|
||||
" ELSE DATEDIFF(DAY, last_out.lastOutstockTime, GETDATE()) " +
|
||||
" END AS stagnantDays, " +
|
||||
" CASE " +
|
||||
" WHEN last_out.lastOutstockTime IS NULL THEN '从未出库' " +
|
||||
" WHEN DATEDIFF(DAY, last_out.lastOutstockTime, GETDATE()) > 180 THEN '超过6个月未出库' " +
|
||||
" ELSE '正常' " +
|
||||
" END AS stagnantReason, " +
|
||||
" mi.material_spec AS materialSpec, " +
|
||||
" w.warehouse_name AS warehouseName, " +
|
||||
" CASE " +
|
||||
" WHEN last_out.lastOutstockTime IS NULL THEN CONVERT(VARCHAR(19), first_in.firstInstockTime, 120) " +
|
||||
" ELSE CONVERT(VARCHAR(19), last_out.lastOutstockTime, 120) " +
|
||||
" END AS lastActivityTime " +
|
||||
"FROM wms_inventory inv " +
|
||||
"INNER JOIN base_material_info_copy1 mi ON inv.material_id = mi.material_id " +
|
||||
"INNER JOIN base_material_category mc ON mi.material_category_id = mc.material_category_id " +
|
||||
"INNER JOIN wms_base_warehouse w ON inv.warehouse_id = w.warehouse_id " +
|
||||
"LEFT JOIN ( " +
|
||||
" SELECT " +
|
||||
" material_id, " +
|
||||
" tenant_id, " +
|
||||
" MIN(create_time) AS firstInstockTime " +
|
||||
" FROM wms_instock_record " +
|
||||
" WHERE create_time IS NOT NULL " +
|
||||
" GROUP BY material_id, tenant_id " +
|
||||
") first_in ON inv.material_id = first_in.material_id AND inv.tenant_id = first_in.tenant_id " +
|
||||
"LEFT JOIN ( " +
|
||||
" SELECT " +
|
||||
" material_id, " +
|
||||
" tenant_id, " +
|
||||
" MAX(create_time) AS lastOutstockTime " +
|
||||
" FROM wms_outstock_record " +
|
||||
" WHERE create_time IS NOT NULL " +
|
||||
" GROUP BY material_id, tenant_id " +
|
||||
") last_out ON inv.material_id = last_out.material_id AND inv.tenant_id = last_out.tenant_id " +
|
||||
"WHERE inv.inventory_status = '1' " +
|
||||
" AND inv.inventory_qty > 0 " +
|
||||
" AND mi.active_flag = '1' " +
|
||||
" AND mi.del_flag = '0' " +
|
||||
" AND ( " +
|
||||
" last_out.lastOutstockTime IS NULL " +
|
||||
" OR DATEDIFF(DAY, last_out.lastOutstockTime, GETDATE()) >= 180 " +
|
||||
" ) " +
|
||||
" AND (#{tenantId} IS NULL OR inv.tenant_id = #{tenantId}) " +
|
||||
" AND (#{materialCategoryId} IS NULL OR mc.material_category_id = #{materialCategoryId}) " +
|
||||
"GROUP BY " +
|
||||
" inv.tenant_id, " +
|
||||
" inv.material_id, " +
|
||||
" mi.material_code, " +
|
||||
" mi.material_name, " +
|
||||
" mc.material_category_name, " +
|
||||
" mi.material_unit, " +
|
||||
" last_out.lastOutstockTime, " +
|
||||
" mi.material_spec, " +
|
||||
" w.warehouse_name, " +
|
||||
" first_in.firstInstockTime " +
|
||||
"ORDER BY inv.tenant_id, stagnantDays DESC, stagnantInventoryQty DESC")
|
||||
List<WmsStagnantInventoryVo> selectStagnantInventory(@Param("tenantId") String tenantId,
|
||||
@Param("materialCategoryId") Long materialCategoryId);
|
||||
|
||||
/**
|
||||
* 查询库存差异报表
|
||||
*/
|
||||
@Select("SELECT " +
|
||||
" ic.tenant_id AS tenantId, " +
|
||||
" ic.check_code AS checkCode, " +
|
||||
" CASE ic.check_type " +
|
||||
" WHEN '0' THEN '抽检' " +
|
||||
" WHEN '1' THEN '盘点' " +
|
||||
" WHEN '2' THEN '库位/货架盘点' " +
|
||||
" ELSE '未知' " +
|
||||
" END AS checkType, " +
|
||||
" ic.plan_warehouse_id AS warehouseId, " +
|
||||
" w.warehouse_name AS warehouseName, " +
|
||||
" icr.material_id AS materialId, " +
|
||||
" mi.material_code AS materialCode, " +
|
||||
" mi.material_name AS materialName, " +
|
||||
" mc.material_category_name AS materialCategoryName, " +
|
||||
" icr.inventory_qty AS bookInventoryQty, " +
|
||||
" icr.check_qty AS actualInventoryQty, " +
|
||||
" (icr.check_qty - icr.inventory_qty) AS differenceQty, " +
|
||||
" CASE " +
|
||||
" WHEN ABS(icr.check_qty - icr.inventory_qty) = 0 THEN '无差异' " +
|
||||
" WHEN (icr.check_qty - icr.inventory_qty) > 0 THEN '盘盈' " +
|
||||
" ELSE '盘亏' " +
|
||||
" END AS differenceType, " +
|
||||
" CASE " +
|
||||
" WHEN icr.inventory_qty > 0 THEN " +
|
||||
" ABS((icr.check_qty - icr.inventory_qty) / icr.inventory_qty * 100) " +
|
||||
" ELSE 0 " +
|
||||
" END AS differenceRate, " +
|
||||
" CASE " +
|
||||
" WHEN ABS(icr.check_qty - icr.inventory_qty) > 10 THEN '重大差异' " +
|
||||
" WHEN ABS(icr.check_qty - icr.inventory_qty) > 5 THEN '一般差异' " +
|
||||
" WHEN ABS(icr.check_qty - icr.inventory_qty) > 0 THEN '轻微差异' " +
|
||||
" ELSE '无差异' " +
|
||||
" END AS differenceLevel, " +
|
||||
" ic.create_time AS checkTime, " +
|
||||
" ic.create_by AS checkBy " +
|
||||
"FROM wms_inventory_check ic " +
|
||||
"INNER JOIN wms_base_warehouse w ON ic.plan_warehouse_id = w.warehouse_id " +
|
||||
"INNER JOIN wms_inventory_check_record icr ON icr.check_code = ic.check_code AND icr.tenant_id = ic.tenant_id " +
|
||||
"INNER JOIN base_material_info_copy1 mi ON icr.material_id = mi.material_id " +
|
||||
"INNER JOIN base_material_category mc ON mi.material_category_id = mc.material_category_id " +
|
||||
"WHERE ic.check_status = '3' " +
|
||||
" AND (#{tenantId} IS NULL OR ic.tenant_id = #{tenantId}) " +
|
||||
" AND (#{materialCategoryId} IS NULL OR mc.material_category_id = #{materialCategoryId}) " +
|
||||
"ORDER BY ic.tenant_id, ic.check_code, differenceRate DESC")
|
||||
List<WmsInventoryDifferenceVo> selectInventoryDifference(@Param("tenantId") String tenantId,
|
||||
@Param("materialCategoryId") Long materialCategoryId);
|
||||
|
||||
/**
|
||||
* 查询库存周转报表
|
||||
*/
|
||||
@Select("SELECT " +
|
||||
" base_data.tenantId, " +
|
||||
" base_data.materialId, " +
|
||||
" base_data.materialCode, " +
|
||||
" base_data.materialName, " +
|
||||
" base_data.materialCategoryName, " +
|
||||
" base_data.statisticsMonth, " +
|
||||
" base_data.beginInventoryQty, " +
|
||||
" base_data.endInventoryQty, " +
|
||||
" base_data.monthOutstockQty, " +
|
||||
" CASE " +
|
||||
" WHEN (base_data.beginInventoryQty + base_data.endInventoryQty) > 0 THEN " +
|
||||
" CAST(base_data.monthOutstockQty * 2.0 / (base_data.beginInventoryQty + base_data.endInventoryQty) * 100 AS DECIMAL(10,2)) " +
|
||||
" ELSE 0 " +
|
||||
" END AS inventoryTurnoverRate, " +
|
||||
" CASE " +
|
||||
" WHEN base_data.endInventoryQty > 0 THEN " +
|
||||
" CAST(base_data.monthOutstockQty / base_data.endInventoryQty * 100 AS DECIMAL(10,2)) " +
|
||||
" ELSE 0 " +
|
||||
" END AS simpleTurnoverRate, " +
|
||||
" CASE " +
|
||||
" WHEN base_data.monthOutstockQty = 0 THEN '无流动' " +
|
||||
" WHEN CAST(base_data.monthOutstockQty * 2.0 / (base_data.beginInventoryQty + base_data.endInventoryQty) * 100 AS DECIMAL(10,2)) >= 100 THEN '快速周转' " +
|
||||
" WHEN CAST(base_data.monthOutstockQty * 2.0 / (base_data.beginInventoryQty + base_data.endInventoryQty) * 100 AS DECIMAL(10,2)) >= 50 THEN '正常周转' " +
|
||||
" ELSE '缓慢周转' " +
|
||||
" END AS turnoverEvaluation " +
|
||||
"FROM ( " +
|
||||
" SELECT " +
|
||||
" inv.tenant_id AS tenantId, " +
|
||||
" inv.material_id AS materialId, " +
|
||||
" mi.material_code AS materialCode, " +
|
||||
" mi.material_name AS materialName, " +
|
||||
" mc.material_category_name AS materialCategoryName, " +
|
||||
" CONVERT(VARCHAR(7), GETDATE(), 126) AS statisticsMonth, " +
|
||||
" SUM(inv.inventory_qty) AS endInventoryQty, " +
|
||||
" SUM(inv.inventory_qty) + ISNULL(month_out.monthOutstockQty, 0) - ISNULL(month_in.monthInstockQty, 0) AS beginInventoryQty, " +
|
||||
" ISNULL(month_out.monthOutstockQty, 0) AS monthOutstockQty " +
|
||||
" FROM wms_inventory inv " +
|
||||
" INNER JOIN base_material_info_copy1 mi ON inv.material_id = mi.material_id " +
|
||||
" INNER JOIN base_material_category mc ON mi.material_category_id = mc.material_category_id " +
|
||||
" LEFT JOIN ( " +
|
||||
" SELECT material_id, tenant_id, SUM(outstock_qty) AS monthOutstockQty " +
|
||||
" FROM wms_outstock_record " +
|
||||
" WHERE create_time >= DATEADD(MONTH, -1, GETDATE()) " +
|
||||
" GROUP BY material_id, tenant_id " +
|
||||
" ) month_out ON inv.material_id = month_out.material_id AND inv.tenant_id = month_out.tenant_id " +
|
||||
" LEFT JOIN ( " +
|
||||
" SELECT material_id, tenant_id, SUM(instock_qty) AS monthInstockQty " +
|
||||
" FROM wms_instock_record " +
|
||||
" WHERE create_time >= DATEADD(MONTH, -1, GETDATE()) " +
|
||||
" GROUP BY material_id, tenant_id " +
|
||||
" ) month_in ON inv.material_id = month_in.material_id AND inv.tenant_id = month_in.tenant_id " +
|
||||
" WHERE inv.inventory_status = '1' " +
|
||||
" AND (#{tenantId} IS NULL OR inv.tenant_id = #{tenantId}) " +
|
||||
" AND (#{materialCategoryId} IS NULL OR mc.material_category_id = #{materialCategoryId}) " +
|
||||
" GROUP BY inv.tenant_id, inv.material_id, mi.material_code, mi.material_name, mc.material_category_name, " +
|
||||
" month_out.monthOutstockQty, month_in.monthInstockQty " +
|
||||
") base_data " +
|
||||
"WHERE base_data.beginInventoryQty > 0 OR base_data.endInventoryQty > 0 OR base_data.monthOutstockQty > 0 " +
|
||||
"ORDER BY base_data.tenantId, inventoryTurnoverRate DESC")
|
||||
List<WmsInventoryTurnoverVo> selectInventoryTurnover(@Param("tenantId") String tenantId,
|
||||
@Param("materialCategoryId") Long materialCategoryId);
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
package org.dromara.wms.service;
|
||||
|
||||
import org.dromara.wms.domain.vo.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* WMS报表Service接口
|
||||
*
|
||||
* @author hwmom
|
||||
* @date 2025-01-20
|
||||
*/
|
||||
public interface IWmsReportService {
|
||||
|
||||
/**
|
||||
* 查询退库原因分析报表
|
||||
*
|
||||
* @param tenantId 租户编号
|
||||
* @param materialCategoryId 物料大类ID
|
||||
* @return 退库原因分析报表列表
|
||||
*/
|
||||
List<WmsReturnReasonAnalysisVo> getReturnReasonAnalysis(String tenantId, Long materialCategoryId);
|
||||
|
||||
/**
|
||||
* 查询库存变动趋势分析报表
|
||||
*
|
||||
* @param tenantId 租户编号
|
||||
* @param materialCategoryId 物料大类ID
|
||||
* @return 库存变动趋势分析报表列表
|
||||
*/
|
||||
List<WmsInventoryTrendAnalysisVo> getInventoryTrendAnalysis(String tenantId, Long materialCategoryId);
|
||||
|
||||
/**
|
||||
* 查询安全库存预警报表
|
||||
*
|
||||
* @param tenantId 租户编号
|
||||
* @param materialCategoryId 物料大类ID
|
||||
* @return 安全库存预警报表列表
|
||||
*/
|
||||
List<WmsSafetyStockAlertVo> getSafetyStockAlert(String tenantId, Long materialCategoryId);
|
||||
|
||||
/**
|
||||
* 查询呆滞料库存报表
|
||||
*
|
||||
* @param tenantId 租户编号
|
||||
* @param materialCategoryId 物料大类ID
|
||||
* @return 呆滞料库存报表列表
|
||||
*/
|
||||
List<WmsStagnantInventoryVo> getStagnantInventory(String tenantId, Long materialCategoryId);
|
||||
|
||||
/**
|
||||
* 查询库存差异报表
|
||||
*
|
||||
* @param tenantId 租户编号
|
||||
* @param materialCategoryId 物料大类ID
|
||||
* @return 库存差异报表列表
|
||||
*/
|
||||
List<WmsInventoryDifferenceVo> getInventoryDifference(String tenantId, Long materialCategoryId);
|
||||
|
||||
/**
|
||||
* 查询库存周转报表
|
||||
*
|
||||
* @param tenantId 租户编号
|
||||
* @param materialCategoryId 物料大类ID
|
||||
* @return 库存周转报表列表
|
||||
*/
|
||||
List<WmsInventoryTurnoverVo> getInventoryTurnover(String tenantId, Long materialCategoryId);
|
||||
}
|
||||
@ -0,0 +1,70 @@
|
||||
package org.dromara.wms.service.impl;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.wms.domain.vo.*;
|
||||
import org.dromara.wms.mapper.WmsReportMapper;
|
||||
import org.dromara.wms.service.IWmsReportService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* WMS报表Service业务层处理
|
||||
*
|
||||
* @author hwmom
|
||||
* @date 2025-01-20
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class WmsReportServiceImpl implements IWmsReportService {
|
||||
|
||||
private final WmsReportMapper wmsReportMapper;
|
||||
|
||||
/**
|
||||
* 查询退库原因分析报表
|
||||
*/
|
||||
@Override
|
||||
public List<WmsReturnReasonAnalysisVo> getReturnReasonAnalysis(String tenantId, Long materialCategoryId) {
|
||||
return wmsReportMapper.selectReturnReasonAnalysis(tenantId, materialCategoryId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询库存变动趋势分析报表
|
||||
*/
|
||||
@Override
|
||||
public List<WmsInventoryTrendAnalysisVo> getInventoryTrendAnalysis(String tenantId, Long materialCategoryId) {
|
||||
return wmsReportMapper.selectInventoryTrendAnalysis(tenantId, materialCategoryId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询安全库存预警报表
|
||||
*/
|
||||
@Override
|
||||
public List<WmsSafetyStockAlertVo> getSafetyStockAlert(String tenantId, Long materialCategoryId) {
|
||||
return wmsReportMapper.selectSafetyStockAlert(tenantId, materialCategoryId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询呆滞料库存报表
|
||||
*/
|
||||
@Override
|
||||
public List<WmsStagnantInventoryVo> getStagnantInventory(String tenantId, Long materialCategoryId) {
|
||||
return wmsReportMapper.selectStagnantInventory(tenantId, materialCategoryId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询库存差异报表
|
||||
*/
|
||||
@Override
|
||||
public List<WmsInventoryDifferenceVo> getInventoryDifference(String tenantId, Long materialCategoryId) {
|
||||
return wmsReportMapper.selectInventoryDifference(tenantId, materialCategoryId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询库存周转报表
|
||||
*/
|
||||
@Override
|
||||
public List<WmsInventoryTurnoverVo> getInventoryTurnover(String tenantId, Long materialCategoryId) {
|
||||
return wmsReportMapper.selectInventoryTurnover(tenantId, materialCategoryId);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue