Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial orders documentation #2498

Merged
merged 6 commits into from
Mar 15, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions guides/orders/display-total-methods.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Display total methods

The `Spree::Order` model includes a number of useful methods for displaying
totals and balances:

- `display_outstanding_balance`: The outstanding balance for the order, calculated by
taking the `total` and subtracting the current `payment_total`.
- `display_item_total`: The total of the line items on the order.
- `display_adjustment_total`: The total of the adjustments on the order.
- `display_total`: The order total.
- `display_total_available_store_credit`: The total available store credit.
- `display_order_total_after_store_credit`: The order total after store credit
has been applied.
- `display_store_credit_remaining_after_capture`: The amount of store credit
remaining after an order payment has been captured.

<!-- TODO:
Write and link to documentation about store credit in the Payments
documentation.
-->

By default, the following methods return `Spree::Money` objects configured with
the order's currency symbol. For example:

```ruby
@order.display_total.to_html
# => "$10.99"
```

Because `Spree::Money` objects are based on the [Ruby Money
library][ruby-money], you can further change what information is displayed using
its [`format`][ruby-money-format] method:

```ruby
@order.display_total.format(with_currency: true)
# => "$10.99 USD"
```

[ruby-money]: https://github.com/RubyMoney/money
[ruby-money-format]: http://www.rubydoc.info/gems/money/Money/Formatting

72 changes: 72 additions & 0 deletions guides/orders/order-state-machine.md
Original file line number Diff line number Diff line change
@@ -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.

<!-- TODO:
Once it's merged, link to documentation about checkout. This section only
attempts to summarize some of what happens during the checkout flow.

It may be useful to link to the payments documentation once it's merged, too.
-->

163 changes: 163 additions & 0 deletions guides/orders/overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
# Overview

The `Spree::Order` model is one of the key models in Solidus. It provides a
central place around which to collect information about a customer order. It
collects line items, adjustments, payments, addresses, return authorizations,
and shipments.

Whenever information about the order is updated, the `Spree::OrderUpdater`
should update the order. If your store creates or changes the functionality
around the order, you may need to [manually call the order
updater][update-orders].

Orders have the following attributes:

- `number`: The unique identifier for this order generated by
`Spree::Order::NumberGeneratr`. It begins with the letter `R` and ends in a
nine-digit number (for example, `R123456789`). This number is shown to the
users, and can be used to find the order by calling
`Spree::Order.find_by(number: "R123456789")`.
- `item_total`: The sum of all the line items for this order.
- `total`: The sum of the `item_total` and the `adjustment_total` attributes.
- `state`: The current state of the order. See the [Order state
machine][order-state-machine] article for more information.
- `adjustment_total`: The sum of all adjustments on this order.
- `user_id`: The ID for the order's corresponding user. Stored only if the order
is placed by a signed-in user.
- `completed_at`: The timestamp that logs when the order is completed.
- `bill_address_id` and `ship_address_id`: The IDs for the related
`Spree::Address` objects with billing and shipping address information.
- `payment_total`: The sum of all the *finalized* payments on the order.
- `shipment_state`: The current [shipment state][shipment-states] of the order.
- `payment_state`: The current payment state of the order. <!-- TODO: Add link. -->
- `email`: The customer-provided email address for the order. This is stored in
case the order is for a guest user.
- `special_instructions`: Any [special shipping
instructions][special-instructions] that shave been specified by the customer
during checkout.
- `currency`: The currency for this order. Determined by the
`Spree::Config[:currency]` value that was set at the time of order.
- `last_ip_address`: The last IP address used to update this order in the
frontend.
- `created_by_id`: The ID of object that created this order.
- `shipment_total`: The sum of all the shipments associated with an order.
- `additional_tax_total`: The sum of all the `additional_tax_total`s (sales tax)
on an order's line items and shipments.
- `promo_total`: The sum of all of the `promo_total`s on an order's shipments,
line items, and promotions.
- `channel`: The channel specified when importing orders from other stores. For
example, if you operate as an Amazon Seller and import orders from Amazon,
some orders may have a channel value of `amazon`. Otherwise, this value is
`spree`.
- `included_tax_total`: The sum of all the `included_tax_total`s (value-added
tax) on an order's line items and shipments.
- `item_count`: The total amount of line items associated with the order.
- `approver_id`: The ID of user that approved the order.
- `approver_name`: The name of the user that approved the order.
- `approved_at`: The timestamp logging when this order is approved by the
approver.
- `confirmation_delivered`: Boolean value that indicates that an order
confirmation email has been delivered.
- `guest_token`: The guest token that links an uncompleted order to a specific
guest user (via browser cookies).
- `canceler_id`: The ID of user that canceled this order.
- `canceled_at`: If the order is cancelled, this timestamp logs when the order
was cancelled.
- `store_id`: The ID of `Spree::Store` in which the order has been created.

Because orders are so integral to Solidus, there are a number of methods
available that let you easily display order totals and subtotals. For more
information, see the [Display totals methods][display-total-methods] article.

[display-total-methods]: display-total-methods.md
[order-state-machine]: order-state-machine.md
[shipment-states]: ../shipments/overview-of-shipments.md#shipping-states
[special-instructions]: ../shipments/user-interface-for-shipments.md#shipping-instructions
[update-orders]: update-orders.md

## Related models

The `Spree::Order` model touches many other models. This section highlights
essential models that orders depend on and links to their existing
documentation.

### Line items

The `Spree::LineItem` model provides the cost of each item added to an order.
Line items provide a link between the order and `Spree::Product`s and
`Spree::Variant`s.

<!-- For more information about line items, products, and variants, see the
[Products and variants][products-and-variants] documentation. -->

<!-- TODO:
Add link to products and variants documentaiton once it is merged.
Add link to line item-specific documentation once it has been written and
merged.
-->

### Adjustments

The `Spree::Adjustment` model provides the cost of each adjustment to an order,
line item, or shipment on an order. Adjustments can decrease the total (via
promotions) or increase it (via [shipments][shipments] and [taxes][taxes]).

<!-- For more information, see the [Adjustments][adjustments] documentation -->

<!-- TODO:
Add link to promotions guide once it is merged.
Add link to adjustments guide once it is merged.
-->

[taxes]: ../taxation/overview-of-taxation.md

### Shipments

The `Spree::Shipment` model creates shipments according to the items in an
order. An order may have multiple shipments: this depends on your store's
configured shipping categories and shipping methods and the item in the order.

Shipments use `Spree::InventoryUnit`s. An inventory unit is created for each
item added to an order for the purpose of tracking what order and shipment an
item belongs to. Inventory units provide a link between the order and
`Spree::Shipment`s.

For more information, see the [Shipments][shipments] documentation.

[shipments]: ../shipments/overview-of-shipment.md

### Addresses

The `Spree::Address` model stores customer addresses and shares them with the
order via the `ship_address_id` and `bill_address_id`. An order may have one or
two different addresses associated it, depending on the customer's preferred
shipping and billing address.

<!-- For more information, see the [Addresses][addresses] documentation. -->

<!-- TODO:
Add link to addresses guide once it is merged.
-->

### Payments

The `Spree::Payment` model stores payment information for the order. Once the
payment object is updated with the amount paid, this updates the corresponding
order's `payment_total` value.

<!-- For more information, see the [Payments][payments] documentation. -->

<!-- TODO:
Add link to payments guide once it is merged.
-->

### Return Authorizations

The `Spree::ReturnAuthorization` model stores information about customers
returns that have been authorized by an administrator.

<!-- TODO:
This sub-article is a stub! I need to learn more about return authorizations
before I can write about this.
-->

31 changes: 31 additions & 0 deletions guides/orders/update-orders.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Update orders

You need to use the `recalculate` method on a `Spree::Order` to keep its total
up-to-date. Note that the total changes every time that line items and
adjustments are added or modified. The `recalculate` method calls out to the
[`Spree::OrderUpdater` class][order-updater].

For example, the `solidus_backend` gem's
[`Spree::Admin::AdjustmentsController`][adjustments-controller] uses the
`recalculate` method to update totals throughout the lifetime of an order:

```ruby
def update_totals
@order.reload.recalculate
end
```

The `update_totals` method is called every time that adjustments are created,
destroyed, and updated.

Whenever you change the code that touches the values of a `Spree::Order`, use
the `recalculate` method to ensure your order's totals are accurate. For
example, you would want to call the `recalculate` method in the following
scenarios:

- Whenever you create or modify a `Spree::Payment` that changes the order's
`payment_state` value.
- Whenever a `Spree:LineItem` on the order has a price change.

[adjustments-controller]: https://github.com/solidusio/solidus/blob/master/backend/app/controllers/spree/admin/adjustments_controller.rb
[order-updater]: https://github.com/solidusio/solidus/blob/master/core/app/models/spree/order_updater.rb