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;
```
Sometimes the objects are not paginated. In this case we need to avoid trying to render pagination data, as it will throw an error. This guard clause also means we can remove messy conditionals from several controllers.
The map is displayed using https://leafletjs.com/
To enable Open Street Map go to the Admin -> Configuration -> Content section and click 'Open Street Map Enabled'.
The 'Open Street Map Provider Name' setting can be used to configure different tile providers thanks to the Leaflet-providers extension (https://github.com/leaflet-extras/leaflet-providers)
Some tile providers require an API key, this can provided in JSON format e.g. '{ apiKey: 123 }' in the 'Open Street Map Provider Options' setting.
Each tile provider has their own usage policy so this should be checked before enabling Open Street Map.
The search field for the Open Street Map works differently than searching on Google Maps. It matches producers by their name or address because it was easier to implement instead of matching place names all over the world.
This makes it far easier to spot what's the difference between create
and update regarding subs syncing without having to mess with `#update`
and its callbacks (for now).
This makes it far easier to spot what's the difference between create
and update regarding the editable order cycles.
I stop here before a slightly deeper refactor which would make the PR
quite hard to review. This will come an upcoming one.
This way it can assign the order cycles to the schedule when this is
persisted. An OrderCycleSchedule (the join table) can't be created until
both schedule and order_cycle got an id.
Also, we do not call `#adapt_params` when creating the Schedule as that
assigns `order_cycle_ids` to `@object.attributes` thus, attempting to
create the OrderCycleSchedule without a schedule_id.