From 76c75298f15170ac556243df9833dbfb1002cbe2 Mon Sep 17 00:00:00 2001 From: Benjamin Willems Date: Wed, 10 Jan 2018 13:41:46 -0800 Subject: [PATCH] Rewrite split order state machine article --- guides/orders/order-state-machine.md | 72 ++++++++++++++++++++++++++++ guides/orders/overview.md | 32 ------------- 2 files changed, 72 insertions(+), 32 deletions(-) create mode 100644 guides/orders/order-state-machine.md diff --git a/guides/orders/order-state-machine.md b/guides/orders/order-state-machine.md new file mode 100644 index 00000000000..d03f10cfa01 --- /dev/null +++ b/guides/orders/order-state-machine.md @@ -0,0 +1,72 @@ +# Order state machine + +Orders flow through a state machine, which is defined in the +`Spree::Order::Checkout` module. It begins with a `cart` state and ends with +at a `complete` state. + +There are six order states by default: + +1. `cart` +2. `address` +3. `delivery` +4. `payment` +5. `confirm` +6. `complete` + +If you go through the checkout provided in the `solidus_frontend` gem, you can +see that there is a clearly defined step for each of these states during checkout. + +In some circumstances, the `payment` and `confirm` states are optional: + +- The `payment` state is only triggered if `payment_required?` returns `true`. +- The `confirm` state is only triggered if `confirmation_required?` returns + `true`. + +The `complete` state is triggered in one of two ways: + +1. No payment is required on the order. (The `total` equals `0`.) +2. Payment is required on the order, and at least the order total has been + received as payment. + +## State criteria + +Each order state has criteria that must be met before the state can change. For +example, before the state can change from `cart` to `address`, line items must be +present on the order. Then, to change from `address` to `delivery`, the user +must have a default address assigned. + +Once an order meets the criteria to go to the next state, you can call `next` on +the order object to transition into the next state. For example, in the +`solidus_frontend` gem, the [`Spree::CheckoutController`][checkout-controller] +defines a `transition_forward` method that always calls `next` unless the order +can be completed: + +```ruby +# /frontend/app/controllers/spree/checkout_controller.rb +def transition_forward + if @order.can_complete? + @order.complete + else + @order.next + end +end +``` + +If `next` returns `false`, then the order does not meet the criteria and does +not transition to the next state. + +[checkout-controller]: https://github.com/solidusio/solidus/blob/master/frontend/app/controllers/spree/checkout_controller.rb + +## Payments and shipments have their own state machines + +Note that a `Spree::Order` with the state `complete` does not mean that the +payment has been processed or the order shipments have been shipped. See also the +values of the `payment_state` and `shipment_state` attributes. + + + diff --git a/guides/orders/overview.md b/guides/orders/overview.md index 4290e062ff4..4c922fa6c5c 100644 --- a/guides/orders/overview.md +++ b/guides/orders/overview.md @@ -74,38 +74,6 @@ information, see the [Display totals methods][display-total-methods] article. [special-instructions]: ../shipments/user-interface-for-shipments.md#shipping-instructions [update-orders]: update-orders.md -## The Order State Machine - -Orders flow through a state machine, beginning at a `cart` state and ending up -at a `complete` state. The intermediary states can be configured using the -[Checkout Flow API](checkout). - -The default states are as follows: - -* `cart` -* `address` -* `delivery` -* `payment` -* `confirm` -* `complete` - -The `payment` state will only be triggered if `payment_required?` returns -`true`. - -The `confirm` state will only be triggered if `confirmation_required?` returns -`true`. - -The `complete` state can only be reached in one of two ways: - -1. No payment is required on the order. -2. Payment is required on the order, and at least the order total has been -received as payment. - -Assuming that an order meets the criteria for the next state, you will be able -to transition it to the next state by calling `next` on that object. If this -returns `false`, then the order does *not* meet the criteria. To work out why it -cannot transition, check the result of an `errors` method call. - ## Related models The `Spree::Order` model touches many other models. This section highlights