Merge pull request #4549 from luisramos0/arelize_order_permissions

Use arel in order permissions visible orders and editable orders so that we dont have queries with gigantic IN clauses
This commit is contained in:
Luis Ramos
2020-01-14 14:24:34 +00:00
committed by GitHub
3 changed files with 53 additions and 23 deletions

View File

@@ -114,7 +114,6 @@ Layout/LineLength:
- lib/open_food_network/enterprise_issue_validator.rb
- lib/open_food_network/group_buy_report.rb
- lib/open_food_network/lettuce_share_report.rb
- lib/open_food_network/order_and_distributor_report.rb
- lib/open_food_network/order_cycle_form_applicator.rb
- lib/open_food_network/order_cycle_management_report.rb
- lib/open_food_network/payments_report.rb

View File

@@ -7,17 +7,17 @@ module Permissions
# Find orders that the user can see
def visible_orders
Spree::Order.where(id:
managed_orders.select(:id) |
coordinated_orders.select(:id) |
produced_orders.select("spree_orders.id"))
Spree::Order.
with_line_items_variants_and_products_outer.
where(visible_orders_where_values)
end
# Any orders that the user can edit
def editable_orders
Spree::Order.where(id:
managed_orders.select(:id) |
coordinated_orders.select(:id) )
Spree::Order.where(
managed_orders_where_values.
or(coordinated_orders_where_values)
)
end
def visible_line_items
@@ -28,27 +28,45 @@ module Permissions
# Any line items that I can edit
def editable_line_items
Spree::LineItem.where(order_id: editable_orders)
Spree::LineItem.where(order_id: editable_orders.select(:id))
end
private
def visible_orders_where_values
# Grouping keeps the 2 where clauses from produced_orders_where_values inside parentheses
# This way it makes the OR work between the 3 types of orders:
# produced, managed and coordinated
Spree::Order.arel_table.
grouping(produced_orders_where_values).
or(managed_orders_where_values).
or(coordinated_orders_where_values)
end
# Any orders placed through any hub that I manage
def managed_orders
Spree::Order.where(distributor_id: @permissions.managed_enterprises.select("enterprises.id"))
def managed_orders_where_values
Spree::Order.
where(distributor_id: @permissions.managed_enterprises.select("enterprises.id")).
where_values.
reduce(:and)
end
# Any order that is placed through an order cycle one of my managed enterprises coordinates
def coordinated_orders
Spree::Order.where(order_cycle_id: @permissions.coordinated_order_cycles.select(:id))
def coordinated_orders_where_values
Spree::Order.
where(order_cycle_id: @permissions.coordinated_order_cycles.select(:id)).
where_values.
reduce(:and)
end
def produced_orders
def produced_orders_where_values
Spree::Order.with_line_items_variants_and_products_outer.
where(
distributor_id: granted_distributor_ids,
spree_products: { supplier_id: enterprises_with_associated_orders }
)
).
where_values.
reduce(:and)
end
def enterprises_with_associated_orders
@@ -69,7 +87,7 @@ module Permissions
# Any from visible orders, where the product is produced by one of my managed producers
def produced_line_items
Spree::LineItem.where(order_id: visible_orders.select(:id)).
Spree::LineItem.where(order_id: visible_orders.select("DISTINCT spree_orders.id")).
joins(:product).
where(spree_products:
{

View File

@@ -42,15 +42,17 @@ module OpenFoodNetwork
orders = search.result
# If empty array is passed in, the where clause will return all line_items, which is bad
orders_with_hidden_details =
@permissions.editable_orders.empty? ? orders : orders.where('id NOT IN (?)', @permissions.editable_orders)
orders.select{ |order| orders_with_hidden_details.include? order }.each do |order|
orders.select{ |order| orders_with_hidden_details(orders).include? order }.each do |order|
# TODO We should really be hiding customer code here too, but until we
# have an actual association between order and customer, it's a bit tricky
order.bill_address.andand.assign_attributes(firstname: I18n.t('admin.reports.hidden'), lastname: "", phone: "", address1: "", address2: "", city: "", zipcode: "", state: nil)
order.ship_address.andand.assign_attributes(firstname: I18n.t('admin.reports.hidden'), lastname: "", phone: "", address1: "", address2: "", city: "", zipcode: "", state: nil)
order.bill_address.andand.
assign_attributes(firstname: I18n.t('admin.reports.hidden'),
lastname: "", phone: "", address1: "", address2: "",
city: "", zipcode: "", state: nil)
order.ship_address.andand.
assign_attributes(firstname: I18n.t('admin.reports.hidden'),
lastname: "", phone: "", address1: "", address2: "",
city: "", zipcode: "", state: nil)
order.assign_attributes(email: I18n.t('admin.reports.hidden'))
end
@@ -59,6 +61,17 @@ module OpenFoodNetwork
private
def orders_with_hidden_details(orders)
# If empty array is passed in, the where clause will return all line_items, which is bad
if @permissions.editable_orders.empty?
orders
else
orders.
where('spree_orders.id NOT IN (?)',
@permissions.editable_orders)
end
end
def line_item_details(orders)
order_and_distributor_details = []