package cn.iocoder.yudao.module.mes.enums.wm;
|
|
import cn.iocoder.yudao.module.mes.enums.MesOrderStatusConstants;
|
|
import java.util.*;
|
|
/**
|
* 单据状态流转校验工具
|
*
|
* 定义各业务单据的合法状态流转,防止非法状态跳转
|
*/
|
public class WmStatusTransitionUtils {
|
|
/**
|
* 通用状态常量(便于阅读)
|
*/
|
private static final int PREPARE = MesOrderStatusConstants.PREPARE; // 草稿
|
private static final int APPROVING = MesOrderStatusConstants.APPROVING; // 待审批/待上架/待拣货
|
private static final int CONFIRMED = MesOrderStatusConstants.CONFIRMED; // 待确认/待检测
|
private static final int APPROVED = MesOrderStatusConstants.APPROVED; // 已审批/待执行
|
private static final int FINISHED = MesOrderStatusConstants.FINISHED; // 已完成
|
private static final int CANCELLED = MesOrderStatusConstants.CANCELLED; // 已取消
|
private static final int SHIPPING = 10; // 待填写运单(销售出库专用)
|
|
/**
|
* 状态流转规则定义
|
* Key: 当前状态, Value: 允许流转到的状态集合
|
*/
|
private static final Map<String, Map<Integer, Set<Integer>>> TRANSITION_RULES = new HashMap<>();
|
|
static {
|
// 采购入库单状态流转
|
registerTransition("ITEM_RECEIPT",
|
PREPARE, APPROVING, CANCELLED);
|
registerTransition("ITEM_RECEIPT",
|
APPROVING, APPROVED, CANCELLED);
|
registerTransition("ITEM_RECEIPT",
|
APPROVED, FINISHED, CANCELLED);
|
// 已完成和已取消不允许流转
|
|
// 销售出库单状态流转
|
registerTransition("PRODUCT_SALES",
|
PREPARE, CONFIRMED, APPROVING, CANCELLED); // 提交时可能去待检测或待拣货
|
registerTransition("PRODUCT_SALES",
|
CONFIRMED, APPROVING, CANCELLED); // OQC通过后去待拣货
|
registerTransition("PRODUCT_SALES",
|
APPROVING, SHIPPING, CANCELLED); // 拣货后去待填写运单
|
registerTransition("PRODUCT_SALES",
|
SHIPPING, APPROVED, CANCELLED); // 填写运单后去待执行出库
|
registerTransition("PRODUCT_SALES",
|
APPROVED, FINISHED, CANCELLED); // 出库后去已完成
|
|
// 转移调拨单状态流转
|
registerTransition("TRANSFER",
|
PREPARE, CONFIRMED, APPROVING, CANCELLED); // 提交时可能去待确认或待上架
|
registerTransition("TRANSFER",
|
CONFIRMED, APPROVING, CANCELLED); // 确认后去待上架
|
registerTransition("TRANSFER",
|
APPROVING, APPROVED, CANCELLED); // 上架后去待执行
|
registerTransition("TRANSFER",
|
APPROVED, FINISHED, CANCELLED); // 执行后去已完成
|
|
// 生产领料单状态流转
|
registerTransition("PRODUCT_ISSUE",
|
PREPARE, APPROVING, CANCELLED);
|
registerTransition("PRODUCT_ISSUE",
|
APPROVING, APPROVED, CANCELLED);
|
registerTransition("PRODUCT_ISSUE",
|
APPROVED, FINISHED, CANCELLED);
|
|
// 生产入库单状态流转
|
registerTransition("PRODUCT_RECEIPT",
|
PREPARE, APPROVING, CANCELLED);
|
registerTransition("PRODUCT_RECEIPT",
|
APPROVING, APPROVED, CANCELLED);
|
registerTransition("PRODUCT_RECEIPT",
|
APPROVED, FINISHED, CANCELLED);
|
|
// 杂项入库单状态流转
|
registerTransition("MISC_RECEIPT",
|
PREPARE, APPROVING, CANCELLED);
|
registerTransition("MISC_RECEIPT",
|
APPROVING, APPROVED, CANCELLED);
|
registerTransition("MISC_RECEIPT",
|
APPROVED, FINISHED, CANCELLED);
|
|
// 杂项出库单状态流转
|
registerTransition("MISC_ISSUE",
|
PREPARE, APPROVING, CANCELLED);
|
registerTransition("MISC_ISSUE",
|
APPROVING, APPROVED, CANCELLED);
|
registerTransition("MISC_ISSUE",
|
APPROVED, FINISHED, CANCELLED);
|
|
// 供应商退货单状态流转
|
registerTransition("RETURN_VENDOR",
|
PREPARE, APPROVING, CANCELLED);
|
registerTransition("RETURN_VENDOR",
|
APPROVING, APPROVED, CANCELLED);
|
registerTransition("RETURN_VENDOR",
|
APPROVED, FINISHED, CANCELLED);
|
|
// 销售退货单状态流转
|
registerTransition("RETURN_SALES",
|
PREPARE, APPROVING, CANCELLED);
|
registerTransition("RETURN_SALES",
|
APPROVING, APPROVED, CANCELLED);
|
registerTransition("RETURN_SALES",
|
APPROVED, FINISHED, CANCELLED);
|
|
// 外协发料单状态流转
|
registerTransition("OUTSOURCE_ISSUE",
|
PREPARE, APPROVING, CANCELLED);
|
registerTransition("OUTSOURCE_ISSUE",
|
APPROVING, APPROVED, CANCELLED);
|
registerTransition("OUTSOURCE_ISSUE",
|
APPROVED, FINISHED, CANCELLED);
|
|
// 外协入库单状态流转
|
registerTransition("OUTSOURCE_RECEIPT",
|
PREPARE, APPROVING, CANCELLED);
|
registerTransition("OUTSOURCE_RECEIPT",
|
APPROVING, APPROVED, CANCELLED);
|
registerTransition("OUTSOURCE_RECEIPT",
|
APPROVED, FINISHED, CANCELLED);
|
}
|
|
/**
|
* 注册状态流转规则
|
*/
|
private static void registerTransition(String bizType, int fromStatus, int... toStatuses) {
|
TRANSITION_RULES
|
.computeIfAbsent(bizType, k -> new HashMap<>())
|
.computeIfAbsent(fromStatus, k -> new HashSet<>())
|
.addAll(Arrays.stream(toStatuses).boxed().toList());
|
}
|
|
/**
|
* 校验状态流转是否合法
|
*
|
* @param bizType 业务类型(如 ITEM_RECEIPT, PRODUCT_SALES)
|
* @param fromStatus 当前状态
|
* @param toStatus 目标状态
|
* @return 是否允许流转
|
*/
|
public static boolean isValidTransition(String bizType, int fromStatus, int toStatus) {
|
Map<Integer, Set<Integer>> bizRules = TRANSITION_RULES.get(bizType);
|
if (bizRules == null) {
|
return false;
|
}
|
Set<Integer> allowedToStatuses = bizRules.get(fromStatus);
|
return allowedToStatuses != null && allowedToStatuses.contains(toStatus);
|
}
|
|
/**
|
* 校验状态流转,非法则抛出异常
|
*
|
* @param bizType 业务类型
|
* @param fromStatus 当前状态
|
* @param toStatus 目标状态
|
* @param documentName 单据名称(用于错误提示)
|
*/
|
public static void validateTransition(String bizType, int fromStatus, int toStatus, String documentName) {
|
if (!isValidTransition(bizType, fromStatus, toStatus)) {
|
throw new IllegalStateException(String.format(
|
"%s状态流转非法:不允许从状态[%d]流转到状态[%d]", documentName, fromStatus, toStatus));
|
}
|
}
|
|
/**
|
* 获取单据允许的下一步状态列表
|
*
|
* @param bizType 业务类型
|
* @param fromStatus 当前状态
|
* @return 允许流转的状态列表
|
*/
|
public static Set<Integer> getAllowedNextStatuses(String bizType, int fromStatus) {
|
Map<Integer, Set<Integer>> bizRules = TRANSITION_RULES.get(bizType);
|
if (bizRules == null) {
|
return Collections.emptySet();
|
}
|
return bizRules.getOrDefault(fromStatus, Collections.emptySet());
|
}
|
|
}
|