These states are reached when the order is complete and shipped. An
admin can create a new return authorization, which will set the order in
`awaiting_return` state. It's only after, when we call
`return_authorization#receive` that the return authorization moves to
`received` state and the order to `returned`.
You can do so from the UI by editing the return authorization and
clicking on Receive. However, we didn't find any order in such state in
UK, FR and AU. The UX is quite obfuscated. That must be why no users
clicked on it.
The `returned` state cannot count for the balance as is, since some of
the products are returned to the shop. That's enough for now.
This makes it possible to deploy it without releasing it to users since
the toggle is not enabled for anyone.
It aims to make the balance calculation consistent across pages.
This query object is meant to be reusable but those includes are
context-specific and will likely not be needed when reusing the query
elsewhere. If we keep them there, chances are next dev might not notice
it and will introduce a performance regression.
We only care about non-cart orders and skipping carts, saves PostgreSQL
query planner to go through thousands of records in production use cases
(my food hub).
We go from
```sql
-> Index Scan using index_spree_orders_on_customer_id on spree_orders (cost=0.42..12049.45 rows=152002 width=15) (actual time=0.015..11.703 rows=13867 loops=1)
```
to
```sql
-> Index Scan using index_spree_orders_on_customer_id on spree_orders (cost=0.42..12429.46 rows=10802 width=15) (actual time=0.025..17.705 rows=9954 loops=1)
```
As is, `payment_total` is only increased after successfully processing
a payment and never updated. This inconsistency breaks
`CustomerWithBalance` which relies on it.
Needless to say that if we keep this denormalized column, we better make
it consistent. I investigated current Spree's master branch (709e686cc0)
and they also realized it was broken. Now `Payment` runs the following
from the `after_save` `update_order` callback.
```rb
order.updater.update_payment_total if completed? || void?
```
I also took the chance to rearrange tests a bit.
Guest orders also have an associated customer record that is created
by Spree::Order#ensure_customer at checkout. Subsequent orders will use
that one due to Spree::Order#associate_customer.
It's simpler and many orders of magnitude more efficient to ask the DB
to aggregate the customer balance based on their orders. It removes
a nasty N+1.
The resulting SQL query is:
```sql
SELECT customers.*, SUM(spree_orders.total - spree_orders.payment_total) AS balance
FROM "customers"
INNER JOIN "spree_orders"
ON "spree_orders"."customer_id" = "customers"."id"
WHERE "customers"."enterprise_id" = 1
AND (completed_at IS NOT NULL)
AND (state != 'canceled')
GROUP BY customers.id
ORDER BY email;
```
DEPRECATION WARNING: `#deliver` is deprecated and will be removed in Rails 5. Use `#deliver_now` to deliver immediately or `#deliver_later` to deliver through Active Job.
This shuts the annoying lint error
```
Hash attribute should start with one space after the opening brace
Hash attribute should end with one space before the closing brace
```
and it aligns with our existing style. See
https://github.com/openfoodfoundation/openfoodnetwork/pull/6629 as an
example.