Commit Graph

632 Commits

Author SHA1 Message Date
Pau Perez
5bca7d1f8f Remove the old balance's code branch
This keeps the `OrderBalance` abstraction but removes the old code now
that the feature is enabled for all users in all instances and there are
no bugs reported. It's become dead code.
2021-04-19 11:52:41 +02:00
Matt-Yorkley
80d43c714d Remove TagRule::DiscountOrder
This class was removed from the UI in 2016 and hasn't been used since...
2021-04-08 12:37:17 +01:00
Andy Brett
1eb5ee9266 Merge pull request #7174 from Matt-Yorkley/dead-code-callbacks
Remove Spree ResourceController callbacks
2021-04-01 07:24:44 -07:00
Pau Perez
ead1ab31b4 Fix multiple N+1 on /admin/customers.json
This (should) considerably improve traces like
https://app.datadoghq.com/apm/trace/917632173599137280?spanID=3163385094622710144&env=production&sort=time&colorBy=service&spanViewType=metadata&graphType=flamegraph&shouldShowLegend=true
by fixing the following 3 N+1s

```
user: root
GET /admin/customers.json?enterprise_id=4
USE eager loading detected
  Customer => [:enterprise]
  Add to your query: .includes([:enterprise])
Call stack
  /usr/src/app/app/serializers/api/admin/customer_with_calculated_balance_serializer.rb:24:in `balance_value'
  /usr/src/app/app/serializers/api/admin/customer_with_calculated_balance_serializer.rb:9:in `balance'
  /usr/src/app/app/controllers/admin/customers_controller.rb:20:in `block (2 levels) in index'
  /usr/src/app/app/controllers/admin/customers_controller.rb:17:in `index'

user: root
GET /admin/customers.json?enterprise_id=4
USE eager loading detected
  Spree::Address => [:state]
  Add to your query: .includes([:state])
Call stack
  /usr/src/app/app/serializers/api/address_serializer.rb:14:in `state_name'
  /usr/src/app/app/controllers/admin/customers_controller.rb:20:in `block (2 levels) in index'
  /usr/src/app/app/controllers/admin/customers_controller.rb:17:in `index'

user: root
GET /admin/customers.json?enterprise_id=4
USE eager loading detected
  Spree::Address => [:country]
  Add to your query: .includes([:country])
Call stack
  /usr/src/app/app/serializers/api/address_serializer.rb:10:in `country_name'
  /usr/src/app/app/controllers/admin/customers_controller.rb:20:in `block (2 levels) in index'
  /usr/src/app/app/controllers/admin/customers_controller.rb:17:in `index'
```

This popped up after improving the balances calculation. Now, that it's
fast, it's clear that are more performance problems on that endpoint.
We'll see if there are any left after this.
2021-03-25 11:19:00 +01:00
Matt-Yorkley
50e0d78c0c Remove dead callback invocations 2021-03-21 14:06:23 +00:00
Matt-Yorkley
0da90ab834 Update schedules controller callbacks 2021-03-21 14:06:01 +00:00
Matt-Yorkley
a82bae2a46 Remove Spree resource controller custom callbacks 2021-03-21 13:25:32 +00:00
Andy Brett
afa7269f48 Merge branch 'master' into render_plain 2021-03-18 10:53:13 -07:00
Matt-Yorkley
826515874b Replace some uses of #alias_method_chain 2021-03-17 16:28:19 +00:00
Luis Ramos
cb8fd2131e Use body: nil instead of deprecated nothing:
Ideally we would be using render head status but it's issuing quite a lot of double render problems, we can improve later
2021-03-16 23:13:58 +00:00
Luis Ramos
53d758ca21 Replace render text with render plain for rails 5.1 2021-03-16 23:13:58 +00:00
Matt-Yorkley
25139178b5 Fix appending to collection (take 2) 2021-03-11 12:19:55 +00:00
Matt-Yorkley
4c2871e572 Refactor and fix params issues in Admin::OrderCyclesController 2021-03-11 12:19:55 +00:00
Matt-Yorkley
64b52527fd Fix params issues in Admin::SubsciptionsController 2021-03-11 12:19:55 +00:00
Matt-Yorkley
aea8d1dc99 Fix appending to Relation in in EnterpriseFeesController 2021-03-11 12:19:55 +00:00
Matt-Yorkley
ccf0556711 Fix params mangling in Admin::EnterprisesController 2021-03-11 12:19:55 +00:00
Matt-Yorkley
bd408e02b0 Update OrderCyclesController params usage 2021-03-11 12:19:55 +00:00
Matt-Yorkley
dcecfaea87 Fix params issues in OrderCyclescontroller spec 2021-03-11 12:19:54 +00:00
Matt-Yorkley
dcf982c1c3 Fix params mangling issues in SubscriptionsController 2021-03-11 12:06:00 +00:00
Matt-Yorkley
af8d497433 Fix handling of params in variant overrides bulk update actions 2021-03-11 12:06:00 +00:00
Matt-Yorkley
9852470ef6 Merge pull request #6913 from Matt-Yorkley/rails-5-backports
Rails 5 backports
2021-02-23 11:55:31 +01:00
Matt-Yorkley
0e3429dc35 Merge pull request #6758 from Matt-Yorkley/enterprise-fees-refactor
Enterprise fees refactor
2021-02-22 17:59:18 +01:00
Maikel Linke
5b94049620 Whitelist params for several settings for Rails 5
Rails 5 is a bit stricter and Spree's Config#set method doesn't work
with a Parameters object.
2021-02-19 14:20:15 +11:00
Matt-Yorkley
c47902d932 Fix params in Admin::EnterprisesController#register 2021-02-18 15:04:09 +00:00
Matt-Yorkley
76009c259f Ensure encodable object in StripeAccountsController
Fixes:
```
Admin::StripeAccountsController#connect redirects to Stripe Authorization url constructed OAuth
     Failure/Error: url_params = { state: JWT.encode(payload, key, 'HS256'), scope: "read_write" }

     JSON::GeneratorError:
       only generation of JSON objects or arrays allowed
     # ./app/controllers/admin/stripe_accounts_controller.rb:8:in `connect'
     # ./spec/controllers/admin/stripe_accounts_controller_spec.rb:18:in `block (3 levels) in <top (required)>'
```
2021-02-18 13:51:01 +00:00
Matt-Yorkley
a8009d044b Use permit in StripeAccountsController 2021-02-18 12:20:29 +00:00
Matt-Yorkley
1535c680f5 Fix direct params access in StripeAccountsController 2021-02-18 12:20:28 +00:00
Pau Perez
aef0d28dd1 Do not load unmodified VOs from DB
Closes #6727.

This avoids the authorization of all the VOs of the hub, which will go
through VOs that may have become invalid due to their underlying product
not belonging to the supplier the hub has permissions with (or any other
data integrity issue).

This is utterly confusing for the user who is only given a generic error
and doesn't understand what's wrong with the particular VO they changed,
while it may be fine after all. What's more, this often results in
a customer support request, which then may end up with a dev finding out
which VO is broken.

Also, there's no point in loading them from DB if the users didn't touch
them.
2021-02-02 15:39:23 +01:00
Pau Perez
0ee1e2cd72 Eager load taggings related to variant overrides
This removes an N+1 with taggings but doesn't solve the one with tags.
Using `includes(taggings: :base_tags)` based on
47da5036de/lib/acts_as_taggable_on/taggable.rb (L83-L84)
wasn't enough to solve it and I got to stop here. This is scope-creeping
too much.
2021-02-01 16:38:40 +01:00
Pau Perez
ee4f2a7b02 Remove N+1 on variants and products
We get from an initial INNER JOIN with variants and products to fetch
the variant overrides + N queries like:

```sql
SELECT "spree_variants".* FROM "spree_variants" WHERE
"spree_variants"."deleted_at" IS NULL AND "spree_variants"."id" = $1
LIMIT 1  [["id", 1545]]

SELECT "spree_products".* FROM "spree_products" WHERE
"spree_products"."id" = $1 LIMIT 1  [["id", 604]]
```

to the same initial INNER JOIN + just 2 queries like:

```sql
SELECT "spree_variants".* FROM "spree_variants" WHERE
"spree_variants"."deleted_at" IS NULL AND "spree_variants"."id" IN
(1551, 1554)

SELECT "spree_products".* FROM "spree_products" WHERE
"spree_products"."deleted_at" IS NULL AND "spree_products"."id" IN (606,
607)
```
2021-02-01 16:38:40 +01:00
Pau Perez
060530cda8 Do not fetch VOs with deleted variant
In the line below we filter them out in Ruby so it's a waste of
resources. The fundamental difference is that `#includes` and
`#references` results in LEFT JOINs, whereas `#joins` results in INNER
JOIN, and because there's a default scope on `deleted_at IS NULL`, these
are not included in the result set.

This however, requires us to move away from the current algorithm but
unfortunately we can't refactor it completely yet.

Before:

```sql
SELECT *
  FROM "variant_overrides"
  LEFT OUTER
  JOIN "spree_variants"
    ON "spree_variants"."id"              =  "variant_overrides"."variant_id"
   AND "spree_variants"."deleted_at" IS NULL
  LEFT OUTER
  JOIN "spree_products"
    ON "spree_products"."id"              =  "spree_variants"."product_id"
   AND "spree_products"."deleted_at" IS NULL
 WHERE "variant_overrides"."permission_revoked_at" IS NULL
   AND "variant_overrides"."hub_id" IN (
    SELECT "enterprises"."id"
      FROM "enterprises"
    INNER
      JOIN "enterprise_roles"
        ON "enterprise_roles"."enterprise_id" =  "enterprises"."id"
    WHERE (enterprise_roles.user_id          =  ?)
      AND (sells                             != 'none')
 ORDER BY name)
```

After:

```sql
SELECT "variant_overrides".*
  FROM "variant_overrides"
 INNER
  JOIN "spree_variants"
    ON "spree_variants"."id"              =  "variant_overrides"."variant_id"
   AND "spree_variants"."deleted_at" IS NULL
 INNER
  JOIN "spree_products"
    ON "spree_products"."id"              =  "spree_variants"."product_id"
   AND "spree_products"."deleted_at" IS NULL
 WHERE "variant_overrides"."permission_revoked_at" IS NULL
   AND "variant_overrides"."hub_id" IN (
    SELECT "enterprises"."id"
      FROM "enterprises"
    INNER
      JOIN "enterprise_roles"
        ON "enterprise_roles"."enterprise_id" =  "enterprises"."id"
    WHERE (enterprise_roles.user_id          =  ?)
      AND (sells                             != 'none')
 ORDER BY name)
```

This is covered in the test suite by
spec/controllers/admin/variant_overrides_controller_spec.rb:72. It keeps
passing so we're good to go.
2021-02-01 14:47:51 +01:00
Matt-Yorkley
793baca44f Update fees on single line item and then order fees in LineItemsController#delete
Fees on other line items are left alone (not recreated), and whatever fees on the order are updated.
2021-01-29 21:53:11 +00:00
Matt-Yorkley
9abf6cdcdf Rename expensive method Order#update_distribution_charge!
This method is named "update distribution charge". What this method actually does is delete all of the fee adjustments on an order and all it's line items, then recreate them all from scratch. We call this from lots of different places all the time, and it's incredibly expensive. It even gets called from inside of transactions being run inside callbacks. Renaming it hopefully will add a bit of clarity.

This needs to be a lot more granular!
2021-01-29 21:52:28 +00:00
Luis Ramos
fd0bba19a7 Adapt enterprises code and specs to new namespace Sets::EnterpriseSet 2021-01-14 09:41:07 +00:00
Luis Ramos
ed0441dc41 Fix a few more rubocop issues 2021-01-14 09:41:07 +00:00
Luis Ramos
5d6d7f7ad0 Adapt enterprise fees code and specs to new namespace of Sets::EnterpriseFeeSet 2021-01-14 09:41:07 +00:00
Luis Ramos
96a351ad0e Adapt usage of Sets to their new location 2021-01-14 09:41:07 +00:00
Pau Pérez Fabregat
9db4f9be15 Merge pull request #6634 from Matt-Yorkley/jobs-cleanup
Jobs cleanup
2021-01-14 10:08:15 +01:00
Pau Perez
398467e7ed Hide new balance impl. under feature toggle
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.
2021-01-11 15:50:19 +01:00
Pau Perez
2e9bae0ea5 Move relation includes out of query object
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.
2021-01-11 15:50:19 +01:00
Pau Perez
96a91969c9 Extract balance-specific serializer
So we only show the customer balance where really needed. Aggregating
the balance can be costly. Also, we avoid defensive coding.
2021-01-11 15:50:19 +01:00
Pau Perez
e404225de0 Extract query object 2021-01-11 15:50:19 +01:00
Pau Perez
d62ab06504 Refactor DB query to aggregate customer balance
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;
```
2021-01-11 15:50:19 +01:00
Matt-Yorkley
dd5a197fb3 Remove ManagerInvitationJob 2021-01-09 11:56:27 +00:00
Matt-Yorkley
496f2dab69 Ensure Jobs are instantiated correctly
We should not be using `Delayed::Job.enqueue` anywhere...
2021-01-08 23:18:55 +00:00
Matt-Yorkley
fe0a0395d8 Remove DEFAULT_PAGE constants 2021-01-05 19:07:46 +00:00
Matt-Yorkley
47f9a3f08a Add guard clause and remove conditionals
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.
2021-01-05 18:51:24 +00:00
Paulo Vilarinho
81c3c1cf32 remove default page 2021-01-05 11:57:54 -03:00
Paulo Vilarinho
ab586f58b1 apply pagination data concern to bulk line items controller 2021-01-04 20:22:58 -03:00
Luis Ramos
0f27f57cbb Use new Admin::ResourceController 2020-12-03 15:32:20 -08:00