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>> 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> bizRules = TRANSITION_RULES.get(bizType); if (bizRules == null) { return false; } Set 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 getAllowedNextStatuses(String bizType, int fromStatus) { Map> bizRules = TRANSITION_RULES.get(bizType); if (bizRules == null) { return Collections.emptySet(); } return bizRules.getOrDefault(fromStatus, Collections.emptySet()); } }