Initially booking system was not consistent. There was no single source of truth for state transition conditions and it was implemented by logic in entry files (e.g. signup.php) and lib.php functions (e.g. facetoface_user_import() and facetoface_user_signup() ). This lead to different, sometimes unexpected, results of how states were changed.
Implementation and adjusting of booking states
Booking system implements Finite State Machine (FSM) with current state and next states that can be moved with transition. All transitions are defined in function get_map() of each state subclass. Transitions are joined by "OR" rule, and there can be several transitions that lead to same state with different conditions and restrictions. All conditions/restrictions are processed with "AND" rule, so if "OR" required, then just create another transition with same state. This is very simple implementation can potentially lead to huge number of transitions for some complex rules, though it is not the case at the moment. As long as it practical it is better to keep it simple, unless we get to explosive that cannot be mitigated by special conditions.
Important rule to follow is to limit knowledge of any state outside of this state as much as possible. Coupling to state will make maintenance harder long-term. If state is part of the logic, try at least to group it in some class. For example see signup_helper. Class signup must not be coupled to any particular state.
Conditions/Restrictions are single rules that are used in transition to define if user can go from current state to next one.
Implement few simple simple over one complex Conditions and Restrictions. Prefer quantity over complexity.
This state is not supposed to be target state because it is "no state". It is similar to NULL in DB (which is no state, or state is not defined), unlike 0 (which is value).