diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml index 03dca05259..cc327fa447 100644 --- a/.rubocop_manual_todo.yml +++ b/.rubocop_manual_todo.yml @@ -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 diff --git a/app/services/permissions/order.rb b/app/services/permissions/order.rb index b4c1e71a2a..4dcc1f6ffd 100644 --- a/app/services/permissions/order.rb +++ b/app/services/permissions/order.rb @@ -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: { diff --git a/lib/open_food_network/order_and_distributor_report.rb b/lib/open_food_network/order_and_distributor_report.rb index 529cf7a6f9..b32ab803cc 100644 --- a/lib/open_food_network/order_and_distributor_report.rb +++ b/lib/open_food_network/order_and_distributor_report.rb @@ -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 = []