OrderStatus.java
package com.rbctcsworld.ecommerce.order;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Order lifecycle as an explicit state machine (stored as VARCHAR, guarded by a DB CHECK constraint).
*
* PLACED ──pay──> PAID ──ship──> SHIPPED ──deliver──> DELIVERED ──request return──> RETURN_REQUESTED
* │ │ ^ │ │
* └──cancel──┐ └──cancel (refund)──┐ └──────── reject return ───────┘ │
* v v approve
* CANCELLED <─────────────────┘ (refund)│
* v
* RETURNED
* Every move not listed in ALLOWED is rejected with 409.
*/
public final class OrderStatus {
public static final String PLACED = "PLACED";
public static final String PAID = "PAID";
public static final String SHIPPED = "SHIPPED";
public static final String DELIVERED = "DELIVERED";
public static final String RETURN_REQUESTED = "RETURN_REQUESTED";
public static final String RETURNED = "RETURNED";
public static final String CANCELLED = "CANCELLED";
public static final List<String> ALL =
List.of(PLACED, PAID, SHIPPED, DELIVERED, RETURN_REQUESTED, RETURNED, CANCELLED);
public static final Map<String, Set<String>> ALLOWED = Map.of(
PLACED, Set.of(PAID, CANCELLED),
PAID, Set.of(SHIPPED, CANCELLED),
SHIPPED, Set.of(DELIVERED),
DELIVERED, Set.of(RETURN_REQUESTED),
RETURN_REQUESTED, Set.of(RETURNED, DELIVERED),
RETURNED, Set.of(),
CANCELLED, Set.of());
private OrderStatus() {
}
public static boolean canMove(String from, String to) {
return ALLOWED.getOrDefault(from, Set.of()).contains(to);
}
}