This section describes how to modify and implement your own states and transitions for order states and delivery states, And also how to interact with payment states.
The default state transitions are implemented in the Litium.Studio.Plugins.ECommerce.StateTransitionPlugin assembly. The source code is available with the release package in the Plugin Source directory.
To change state transitions, implement the interface IStateTransitionBuilder or extend the StateTransitionBuilderBase class in your own class and place the assembly (.dll file) that contains that class in wwwroot\bin folder. More instructions on extending a plugin interface are here.
Do not change order during entry/exit actions or transition conditions
State transitions entry/exit actions should be used to invoke changes external to the order object. The concept is that the state of the order is used to modify the state of an entity or a system external to the order.
You should not modify the order object itself, during the entry/exit actions or transition conditions.
This is because the order itself is the source data of the actions we perform, and more than one interconnected system depends on the state of the order, (and therefore its data). Therefore, if you modify the order at this point the consistency and integrity of the system will be violated. If you modify the order, you may get concurrency exceptions during run time in code that may not be related at all to the customisation you have done. Also, even if you may not get concurrency exceptions, some other state transition conditions which looks at the order data may fail or may not work properly.
States are immutable
Once a state is added to a state machine, it will be reused in all subsequent calls to that state. Even if you try to add a new instance of the same state again, the instance that was added earlier will be reused, instead of using the one you tried to add later.
Bear in mind this important difference when you add the states. For example, in the following code example, the Confirmed state is not added twice, simply the instance added first in transition from Init to Confirmed is re-used when the transition from Confirmed to Processing is added.
//Confirmed state
Sts.Action<OrderCarrier> confirmOrderEntryAction = new Sts.Action<OrderCarrier>(OnOrderConfirmation);
State<OrderCarrier> confirmedState = new State<OrderCarrier>((short)OrderState.Confirmed, OrderState.Confirmed.ToString(), confirmOrderEntryAction, null);
//add transition Init to Confirmed
stateMachine.AddStateTransition(
new State<OrderCarrier>((short)OrderState.Init, OrderState.Init.ToString()),
confirmedState,
new TransitionCondition<OrderCarrier>(CanOrderMoveToConfirmedState),true);
//add transition Confirmed to Processing
stateMachine.AddStateTransition(
new State<OrderCarrier>((short)OrderState.Confirmed, OrderState.Confirmed.ToString()),
new State<OrderCarrier>((short)OrderState.Processing, OrderState.Processing.ToString()),
new TransitionCondition<OrderCarrier>(CanOrderMoveToProcessingState),true);
Creating enums for the order and delivery states
It's a better idea to create enums for order states and delivery states. The code will look cleaner and contain less bugs than when using magic text. For the examples in this section the following enums will be used.
/// <summary>
/// Sample order states.
/// </summary>
public enum SmplOrderState
{
Init = 0,
Confirmed = 1,
Completed = 2,
Returned = 3,
Cancelled = 4
}
/// <summary>
/// Sample delivery states.
/// </summary>
public enum SmplDeliveryState
{
Init = 0,
Delivered = 1,
Failed = 2,
Returned = 3,
Cancelled = 4
}