diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml index e8dc590f17..1a0ec4404f 100644 --- a/.rubocop_manual_todo.yml +++ b/.rubocop_manual_todo.yml @@ -45,7 +45,6 @@ Metrics/LineLength: - app/controllers/spree/admin/base_controller_decorator.rb - app/controllers/spree/admin/orders_controller_decorator.rb - app/controllers/spree/admin/payments_controller_decorator.rb - - app/controllers/spree/admin/reports_controller_decorator.rb - app/controllers/spree/credit_cards_controller.rb - app/controllers/spree/paypal_controller_decorator.rb - app/controllers/stripe/callbacks_controller.rb @@ -121,7 +120,6 @@ Metrics/LineLength: - lib/open_food_network/order_cycle_management_report.rb - lib/open_food_network/payments_report.rb - lib/open_food_network/reports/bulk_coop_allocation_report.rb - - lib/open_food_network/reports/line_items.rb - lib/open_food_network/sales_tax_report.rb - lib/open_food_network/variant_and_line_item_naming.rb - lib/open_food_network/xero_invoices_report.rb diff --git a/app/controllers/admin/bulk_line_items_controller.rb b/app/controllers/admin/bulk_line_items_controller.rb index e7b4237652..86a2f539e2 100644 --- a/app/controllers/admin/bulk_line_items_controller.rb +++ b/app/controllers/admin/bulk_line_items_controller.rb @@ -5,10 +5,11 @@ module Admin def index order_params = params[:q].andand.delete :order - orders = OpenFoodNetwork::Permissions.new(spree_current_user). + order_permissions = ::Permissions::Order.new(spree_current_user) + orders = order_permissions. editable_orders.ransack(order_params).result - line_items = OpenFoodNetwork::Permissions.new(spree_current_user). + line_items = order_permissions. editable_line_items.where(order_id: orders). includes(variant: { option_values: :option_type }). ransack(params[:q]).result. diff --git a/app/controllers/spree/admin/reports_controller_decorator.rb b/app/controllers/spree/admin/reports_controller_decorator.rb index 3a7f5217fc..848fb8ec0d 100644 --- a/app/controllers/spree/admin/reports_controller_decorator.rb +++ b/app/controllers/spree/admin/reports_controller_decorator.rb @@ -23,7 +23,8 @@ Spree::Admin::ReportsController.class_eval do before_filter :cache_search_state # Fetches user's distributors, suppliers and order_cycles - before_filter :load_data, only: [:customers, :products_and_inventory, :order_cycle_management, :packing] + before_filter :load_data, + only: [:customers, :products_and_inventory, :order_cycle_management, :packing] def report_types OpenFoodNetwork::Reports::List.all @@ -49,7 +50,9 @@ Spree::Admin::ReportsController.class_eval do @report_type = params[:report_type] # -- Build Report with Order Grouper - @report = OpenFoodNetwork::OrderCycleManagementReport.new spree_current_user, params, render_content? + @report = OpenFoodNetwork::OrderCycleManagementReport.new spree_current_user, + params, + render_content? @table = @report.table_items render_report(@report.header, @table, params[:csv], "order_cycle_management_#{timestamp}.csv") @@ -69,7 +72,9 @@ Spree::Admin::ReportsController.class_eval do end def orders_and_distributors - @report = OpenFoodNetwork::OrderAndDistributorReport.new spree_current_user, params, render_content? + @report = OpenFoodNetwork::OrderAndDistributorReport.new spree_current_user, + params, + render_content? @search = @report.search csv_file_name = "orders_and_distributors_#{timestamp}.csv" render_report(@report.header, @report.table, params[:csv], csv_file_name) @@ -126,8 +131,9 @@ Spree::Admin::ReportsController.class_eval do @include_blank = I18n.t(:all) # -- Build Report with Order Grouper - @report = OpenFoodNetwork::OrdersAndFulfillmentsReport.new(permissions, - params, render_content?) + @report = OpenFoodNetwork::OrdersAndFulfillmentsReport.new spree_current_user, + params, + render_content? @table = order_grouper_table csv_file_name = "#{params[:report_type]}_#{timestamp}.csv" @@ -137,16 +143,24 @@ Spree::Admin::ReportsController.class_eval do def products_and_inventory @report_types = report_types[:products_and_inventory] @report = if params[:report_type] != 'lettuce_share' - OpenFoodNetwork::ProductsAndInventoryReport.new spree_current_user, params, render_content? + OpenFoodNetwork::ProductsAndInventoryReport.new spree_current_user, + params, + render_content? else OpenFoodNetwork::LettuceShareReport.new spree_current_user, params, render_content? end - render_report(@report.header, @report.table, params[:csv], "products_and_inventory_#{timestamp}.csv") + render_report(@report.header, + @report.table, + params[:csv], + "products_and_inventory_#{timestamp}.csv") end def users_and_enterprises @report = OpenFoodNetwork::UsersAndEnterprisesReport.new params, render_content? - render_report(@report.header, @report.table, params[:csv], "users_and_enterprises_#{timestamp}.csv") + render_report(@report.header, + @report.table, + params[:csv], + "users_and_enterprises_#{timestamp}.csv") end def xero_invoices diff --git a/app/services/permissions/order.rb b/app/services/permissions/order.rb new file mode 100644 index 0000000000..b4c1e71a2a --- /dev/null +++ b/app/services/permissions/order.rb @@ -0,0 +1,80 @@ +module Permissions + class Order + def initialize(user) + @user = user + @permissions = OpenFoodNetwork::Permissions.new(@user) + end + + # 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")) + end + + # Any orders that the user can edit + def editable_orders + Spree::Order.where(id: + managed_orders.select(:id) | + coordinated_orders.select(:id) ) + end + + def visible_line_items + Spree::LineItem.where(id: + editable_line_items.select(:id) | + produced_line_items.select("spree_line_items.id")) + end + + # Any line items that I can edit + def editable_line_items + Spree::LineItem.where(order_id: editable_orders) + end + + private + + # Any orders placed through any hub that I manage + def managed_orders + Spree::Order.where(distributor_id: @permissions.managed_enterprises.select("enterprises.id")) + 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)) + end + + def produced_orders + Spree::Order.with_line_items_variants_and_products_outer. + where( + distributor_id: granted_distributor_ids, + spree_products: { supplier_id: enterprises_with_associated_orders } + ) + end + + def enterprises_with_associated_orders + # Any orders placed through hubs that my producers have granted P-OC, + # and which contain their products. This is pretty complicated but it's looking for order + # where at least one of my producers has granted P-OC to the distributor + # AND the order contains products of at least one of THE SAME producers + @permissions.related_enterprises_granting(:add_to_order_cycle, to: granted_distributor_ids). + merge(@permissions.managed_enterprises.is_primary_producer) + end + + def granted_distributor_ids + @granted_distributor_ids ||= @permissions.related_enterprises_granted( + :add_to_order_cycle, + by: @permissions.managed_enterprises.is_primary_producer.select("enterprises.id") + ).select("enterprises.id") + end + + # 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)). + joins(:product). + where(spree_products: + { + supplier_id: @permissions.managed_enterprises.is_primary_producer.select("enterprises.id") + }) + end + end +end diff --git a/app/services/search_orders.rb b/app/services/search_orders.rb index 5d4f834cc0..4ff0f717da 100644 --- a/app/services/search_orders.rb +++ b/app/services/search_orders.rb @@ -24,7 +24,7 @@ class SearchOrders attr_reader :params, :current_user def fetch_orders - @search = OpenFoodNetwork::Permissions.new(current_user).editable_orders.ransack(params[:q]) + @search = ::Permissions::Order.new(current_user).editable_orders.ransack(params[:q]) return paginated_results if using_pagination? diff --git a/lib/open_food_network/bulk_coop_report.rb b/lib/open_food_network/bulk_coop_report.rb index 5339200185..e4a89dbbe5 100644 --- a/lib/open_food_network/bulk_coop_report.rb +++ b/lib/open_food_network/bulk_coop_report.rb @@ -46,12 +46,12 @@ module OpenFoodNetwork end def search - Reports::LineItems.search_orders(permissions, params) + report_line_items.orders end def table_items return [] unless @render_table - Reports::LineItems.list(permissions, report_options) + report_line_items.list(line_item_includes) end def rules @@ -121,18 +121,18 @@ module OpenFoodNetwork private - def report_options - @params.merge(line_item_includes: line_item_includes) - end - def line_item_includes [{ order: [:bill_address], variant: [{ option_values: :option_type }, { product: :supplier }] }] end - def permissions - return @permissions unless @permissions.nil? - @permissions = OpenFoodNetwork::Permissions.new(@user) + def order_permissions + return @order_permissions unless @order_permissions.nil? + @order_permissions = ::Permissions::Order.new(@user) + end + + def report_line_items + @report_line_items ||= Reports::LineItems.new(order_permissions, @params) end end end diff --git a/lib/open_food_network/order_and_distributor_report.rb b/lib/open_food_network/order_and_distributor_report.rb index d0b00d08b0..529cf7a6f9 100644 --- a/lib/open_food_network/order_and_distributor_report.rb +++ b/lib/open_food_network/order_and_distributor_report.rb @@ -5,7 +5,7 @@ module OpenFoodNetwork @user = user @render_table = render_table - @permissions = OpenFoodNetwork::Permissions.new(user) + @permissions = ::Permissions::Order.new(user) end def header diff --git a/lib/open_food_network/orders_and_fulfillments_report.rb b/lib/open_food_network/orders_and_fulfillments_report.rb index f930ba50c6..45d36b2a80 100644 --- a/lib/open_food_network/orders_and_fulfillments_report.rb +++ b/lib/open_food_network/orders_and_fulfillments_report.rb @@ -13,28 +13,24 @@ module OpenFoodNetwork delegate :header, :rules, :columns, to: :report - def initialize(permissions, options = {}, render_table = false) + def initialize(user, options = {}, render_table = false) + @user = user @options = options @report_type = options[:report_type] - @permissions = permissions @render_table = render_table end def search - Reports::LineItems.search_orders(permissions, options) + report_line_items.orders end def table_items return [] unless @render_table - - list_options = options.merge(line_item_includes: report.line_item_includes) - Reports::LineItems.list(permissions, list_options) + report_line_items.list(report.line_item_includes) end private - attr_reader :permissions - def report @report ||= report_klass.new(self) end @@ -84,5 +80,14 @@ module OpenFoodNetwork def scale_factor(product) product.variant_unit == 'weight' ? 1000 : 1 end + + def order_permissions + return @order_permissions unless @order_permissions.nil? + @order_permissions = ::Permissions::Order.new(@user) + end + + def report_line_items + @report_line_items ||= Reports::LineItems.new(order_permissions, options) + end end end diff --git a/lib/open_food_network/packing_report.rb b/lib/open_food_network/packing_report.rb index 3f5e420626..997059a666 100644 --- a/lib/open_food_network/packing_report.rb +++ b/lib/open_food_network/packing_report.rb @@ -38,12 +38,12 @@ module OpenFoodNetwork end def search - Reports::LineItems.search_orders(permissions, params) + report_line_items.orders end def table_items return [] unless @render_table - Reports::LineItems.list(permissions, report_options) + report_line_items.list(line_item_includes) end def rules @@ -120,18 +120,14 @@ module OpenFoodNetwork private - def report_options - @params.merge(line_item_includes: line_item_includes) - end - def line_item_includes [{ order: [:bill_address, :distributor], variant: [{ option_values: :option_type }, { product: :supplier }] }] end - def permissions - return @permissions unless @permissions.nil? - @permissions = OpenFoodNetwork::Permissions.new(@user) + def order_permissions + return @order_permissions unless @order_permissions.nil? + @order_permissions = ::Permissions::Order.new(@user) end def is_temperature_controlled?(line_item) @@ -150,5 +146,9 @@ module OpenFoodNetwork customer = Customer.where(email: email).first customer.nil? ? "" : customer.code end + + def report_line_items + @report_line_items ||= Reports::LineItems.new(order_permissions, @params) + end end end diff --git a/lib/open_food_network/permissions.rb b/lib/open_food_network/permissions.rb index 3c47b73b9c..fe132a9be2 100644 --- a/lib/open_food_network/permissions.rb +++ b/lib/open_food_network/permissions.rb @@ -58,55 +58,12 @@ module OpenFoodNetwork permissions end - # Find enterprises that an admin is allowed to add to an order cycle - def visible_orders - # Any orders that I can edit - editable = editable_orders.pluck(:id) - - produced = Spree::Order.with_line_items_variants_and_products_outer. - where( - distributor_id: granted_distributor_ids, - spree_products: { supplier_id: enterprises_with_associated_orders } - ).pluck(:id) - - Spree::Order.where(id: editable | produced) - end - - # Find enterprises that an admin is allowed to add to an order cycle - def editable_orders - # Any orders placed through any hub that I manage - managed = Spree::Order.where(distributor_id: managed_enterprises.pluck(:id)).pluck(:id) - - # Any order that is placed through an order cycle one of my managed enterprises coordinates - coordinated = Spree::Order. - where(order_cycle_id: coordinated_order_cycles.pluck(:id)). - pluck(:id) - - Spree::Order.where(id: managed | coordinated ) - end - - def visible_line_items - # Any line items that I can edit - editable = editable_line_items.pluck(:id) - - # Any from visible orders, where the product is produced by one of my managed producers - produced = Spree::LineItem.where(order_id: visible_orders.pluck(:id)). - joins(:product). - where(spree_products: { supplier_id: managed_enterprises.is_primary_producer.pluck(:id) }) - - Spree::LineItem.where(id: editable | produced) - end - - def editable_line_items - Spree::LineItem.where(order_id: editable_orders) - end - def editable_products permitted_enterprise_products_ids = product_ids_supplied_by( related_enterprises_granting(:manage_products) ) Spree::Product.where( - id: managed_enterprise_products.pluck(:id) | permitted_enterprise_products_ids + id: managed_enterprise_products.select(:id) | permitted_enterprise_products_ids ) end @@ -116,10 +73,14 @@ module OpenFoodNetwork related_enterprises_granting(:add_to_order_cycle) ) Spree::Product.where( - id: managed_enterprise_products.pluck(:id) | permitted_enterprise_products_ids + id: managed_enterprise_products.select(:id) | permitted_enterprise_products_ids ) end + def product_ids_supplied_by(supplier_ids) + Spree::Product.where(supplier_id: supplier_ids).select(:id) + end + def managed_product_enterprises managed_and_related_enterprises_granting :manage_products end @@ -129,14 +90,16 @@ module OpenFoodNetwork end def editable_schedules - Schedule.joins(:order_cycles). - where(order_cycles: { id: OrderCycle.managed_by(@user).pluck(:id) }). + Schedule. + joins(:order_cycles). + where(order_cycles: { id: OrderCycle.managed_by(@user).select("order_cycles.id") }). select("DISTINCT schedules.*") end def visible_schedules - Schedule.joins(:order_cycles). - where(order_cycles: { id: OrderCycle.accessible_by(@user).pluck(:id) }). + Schedule. + joins(:order_cycles). + where(order_cycles: { id: OrderCycle.managed_by(@user).select("order_cycles.id") }). select("DISTINCT schedules.*") end @@ -148,53 +111,6 @@ module OpenFoodNetwork editable_subscriptions end - private - - def admin? - @user.admin? - end - - def granted_distributor_ids - @granted_distributor_ids ||= related_enterprises_granted( - :add_to_order_cycle, - by: managed_enterprises.is_primary_producer.pluck(:id) - ).pluck(:id) - end - - def enterprises_with_associated_orders - # Any orders placed through hubs that my producers have granted P-OC, - # and which contain their products. This is pretty complicated but it's looking for order - # where at least one of my producers has granted P-OC to the distributor - # AND the order contains products of at least one of THE SAME producers - - related_enterprises_granting(:add_to_order_cycle, to: granted_distributor_ids). - merge(managed_enterprises.is_primary_producer) - end - - def managed_and_related_enterprises_granting(permission) - if admin? - Enterprise.scoped - else - Enterprise.where( - id: managed_enterprises.pluck(:id) | related_enterprises_granting(permission) - ) - end - end - - def managed_and_related_enterprises_with(permission) - if admin? - Enterprise.scoped - else - managed_enterprise_ids = managed_enterprises.pluck(:id) - granting_enterprise_ids = related_enterprises_granting(permission) - granted_enterprise_ids = related_enterprises_granted(permission) - - Enterprise.where( - id: managed_enterprise_ids | granting_enterprise_ids | granted_enterprise_ids - ) - end - end - def managed_enterprises @managed_enterprises ||= Enterprise.managed_by(@user) end @@ -209,7 +125,7 @@ module OpenFoodNetwork parent_ids = EnterpriseRelationship. permitting(options[:to] || managed_enterprises.select("enterprises.id")). with_permission(permission). - pluck(:parent_id) + select(:parent_id) (options[:scope] || Enterprise).where(id: parent_ids).select("enterprises.id") end @@ -218,17 +134,44 @@ module OpenFoodNetwork child_ids = EnterpriseRelationship. permitted_by(options[:by] || managed_enterprises.select("enterprises.id")). with_permission(permission). - pluck(:child_id) + select(:child_id) (options[:scope] || Enterprise).where(id: child_ids).select("enterprises.id") end + private + + def admin? + @user.admin? + end + + def managed_and_related_enterprises_granting(permission) + if admin? + Enterprise.scoped + else + Enterprise.where( + id: managed_enterprises.select("enterprises.id") | + related_enterprises_granting(permission) + ) + end + end + + def managed_and_related_enterprises_with(permission) + if admin? + Enterprise.scoped + else + managed_enterprise_ids = managed_enterprises.select("enterprises.id") + granting_enterprise_ids = related_enterprises_granting(permission) + granted_enterprise_ids = related_enterprises_granted(permission) + + Enterprise.where( + id: managed_enterprise_ids | granting_enterprise_ids | granted_enterprise_ids + ) + end + end + def managed_enterprise_products Spree::Product.managed_by(@user) end - - def product_ids_supplied_by(supplier_ids) - Spree::Product.where(supplier_id: supplier_ids).pluck(:id) - end end end diff --git a/lib/open_food_network/reports/line_items.rb b/lib/open_food_network/reports/line_items.rb index 7b85065b1f..4e272a7c13 100644 --- a/lib/open_food_network/reports/line_items.rb +++ b/lib/open_food_network/reports/line_items.rb @@ -1,43 +1,66 @@ module OpenFoodNetwork module Reports # shared code to search and list line items - module LineItems - def self.search_orders(permissions, params) - permissions.visible_orders.complete.not_state(:canceled).search(params[:q]) + class LineItems + def initialize(order_permissions, params) + @order_permissions = order_permissions + @params = params end - def self.list(permissions, params) - orders = search_orders(permissions, params).result + def orders + @orders ||= search_orders + end - line_items = permissions.visible_line_items.merge(Spree::LineItem.where(order_id: orders)) - line_items = line_items.supplied_by_any(params[:supplier_id_in]) if params[:supplier_id_in].present? + def list(line_item_includes = nil) + line_items = @order_permissions. + visible_line_items. + merge(Spree::LineItem.where(order_id: orders.result)) - if params[:line_item_includes].present? - line_items = line_items.includes(*params[:line_item_includes]) + if @params[:supplier_id_in].present? + line_items = line_items.supplied_by_any(@params[:supplier_id_in]) end - hidden_line_items = line_items_with_hidden_details(permissions, line_items) + if line_item_includes.present? + line_items = line_items.includes(*line_item_includes) + end + + editable_line_items = editable_line_items(line_items) line_items.select{ |li| - hidden_line_items.include? li + !editable_line_items.include? li }.each do |line_item| # 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 - line_item.order.bill_address.andand.assign_attributes(firstname: I18n.t('admin.reports.hidden'), lastname: "", phone: "", address1: "", address2: "", city: "", zipcode: "", state: nil) - line_item.order.ship_address.andand.assign_attributes(firstname: I18n.t('admin.reports.hidden'), lastname: "", phone: "", address1: "", address2: "", city: "", zipcode: "", state: nil) + line_item.order.bill_address.andand. + assign_attributes(firstname: I18n.t('admin.reports.hidden'), + lastname: "", phone: "", address1: "", address2: "", + city: "", zipcode: "", state: nil) + line_item.order.ship_address.andand. + assign_attributes(firstname: I18n.t('admin.reports.hidden'), + lastname: "", phone: "", address1: "", address2: "", + city: "", zipcode: "", state: nil) line_item.order.assign_attributes(email: I18n.t('admin.reports.hidden')) end + line_items end - def self.line_items_with_hidden_details(permissions, line_items) - editable_line_items = permissions.editable_line_items.pluck(:id) + private - if editable_line_items.empty? - line_items - else - line_items.where('"spree_line_items"."id" NOT IN (?)', editable_line_items) - end + def search_orders + @order_permissions.visible_orders.complete.not_state(:canceled).search(@params[:q]) + end + + # From the line_items given, returns the ones that are editable by the user + def editable_line_items(line_items) + editable_line_items_ids = @order_permissions.editable_line_items.select(:id) + + # Although merge could take a relation, here we convert line_items to array + # because, if we pass a relation, merge will overwrite the conditions on the same field + # In this case: the IN clause on spree_line_items.order_id from line_items + # overwrites the IN clause on spree_line_items.order_id on editable_line_items_ids + # We convert to array the relation with less elements: line_items + editable_line_items_ids.merge(line_items.to_a) end end end diff --git a/lib/open_food_network/sales_tax_report.rb b/lib/open_food_network/sales_tax_report.rb index af6ef44bf7..1ce3f860dd 100644 --- a/lib/open_food_network/sales_tax_report.rb +++ b/lib/open_food_network/sales_tax_report.rb @@ -34,7 +34,7 @@ module OpenFoodNetwork end def search - permissions = OpenFoodNetwork::Permissions.new(user) + permissions = ::Permissions::Order.new(user) permissions.editable_orders.complete.not_state(:canceled).search(params[:q]) end diff --git a/lib/open_food_network/xero_invoices_report.rb b/lib/open_food_network/xero_invoices_report.rb index 36bbdf9fe8..6a05c3e296 100644 --- a/lib/open_food_network/xero_invoices_report.rb +++ b/lib/open_food_network/xero_invoices_report.rb @@ -19,7 +19,7 @@ module OpenFoodNetwork end def search - permissions = OpenFoodNetwork::Permissions.new(@user) + permissions = ::Permissions::Order.new(@user) permissions.editable_orders.complete.not_state(:canceled).search(@opts[:q]) end diff --git a/spec/lib/open_food_network/bulk_coop_report_spec.rb b/spec/lib/open_food_network/bulk_coop_report_spec.rb index 4eeeae09dd..2d42928414 100644 --- a/spec/lib/open_food_network/bulk_coop_report_spec.rb +++ b/spec/lib/open_food_network/bulk_coop_report_spec.rb @@ -62,7 +62,7 @@ module OpenFoodNetwork o2.line_items << li2 end - it "shows line items supplied by my producers, with names hidden" do + it "does not show line items supplied by my producers" do expect(subject.table_items).to eq([]) end end diff --git a/spec/lib/open_food_network/orders_and_fulfillments_report/customer_totals_report_spec.rb b/spec/lib/open_food_network/orders_and_fulfillments_report/customer_totals_report_spec.rb index 261e52a925..d224830e0b 100644 --- a/spec/lib/open_food_network/orders_and_fulfillments_report/customer_totals_report_spec.rb +++ b/spec/lib/open_food_network/orders_and_fulfillments_report/customer_totals_report_spec.rb @@ -4,11 +4,10 @@ RSpec.describe OpenFoodNetwork::OrdersAndFulfillmentsReport::CustomerTotalsRepor let!(:distributor) { create(:distributor_enterprise) } let!(:customer) { create(:customer, enterprise: distributor) } let(:current_user) { distributor.owner } - let(:permissions) { OpenFoodNetwork::Permissions.new(current_user) } let(:report) do report_options = { report_type: described_class::REPORT_TYPE } - OpenFoodNetwork::OrdersAndFulfillmentsReport.new(permissions, report_options, true) + OpenFoodNetwork::OrdersAndFulfillmentsReport.new(current_user, report_options, true) end let(:report_table) do diff --git a/spec/lib/open_food_network/orders_and_fulfillments_report/distributor_totals_by_supplier_report_spec.rb b/spec/lib/open_food_network/orders_and_fulfillments_report/distributor_totals_by_supplier_report_spec.rb index 4b0b721caf..feb2903014 100644 --- a/spec/lib/open_food_network/orders_and_fulfillments_report/distributor_totals_by_supplier_report_spec.rb +++ b/spec/lib/open_food_network/orders_and_fulfillments_report/distributor_totals_by_supplier_report_spec.rb @@ -8,11 +8,10 @@ RSpec.describe OpenFoodNetwork::OrdersAndFulfillmentsReport::DistributorTotalsBy end let(:current_user) { distributor.owner } - let(:permissions) { OpenFoodNetwork::Permissions.new(current_user) } let(:report) do report_options = { report_type: described_class::REPORT_TYPE } - OpenFoodNetwork::OrdersAndFulfillmentsReport.new(permissions, report_options, true) + OpenFoodNetwork::OrdersAndFulfillmentsReport.new(current_user, report_options, true) end let(:report_table) do diff --git a/spec/lib/open_food_network/orders_and_fulfillments_report/supplier_totals_by_distributor_report_spec.rb b/spec/lib/open_food_network/orders_and_fulfillments_report/supplier_totals_by_distributor_report_spec.rb index f22ec80bae..654a1ed901 100644 --- a/spec/lib/open_food_network/orders_and_fulfillments_report/supplier_totals_by_distributor_report_spec.rb +++ b/spec/lib/open_food_network/orders_and_fulfillments_report/supplier_totals_by_distributor_report_spec.rb @@ -8,11 +8,10 @@ RSpec.describe OpenFoodNetwork::OrdersAndFulfillmentsReport::SupplierTotalsByDis end let(:current_user) { distributor.owner } - let(:permissions) { OpenFoodNetwork::Permissions.new(current_user) } let(:report) do report_options = { report_type: described_class::REPORT_TYPE } - OpenFoodNetwork::OrdersAndFulfillmentsReport.new(permissions, report_options, true) + OpenFoodNetwork::OrdersAndFulfillmentsReport.new(current_user, report_options, true) end let(:report_table) do diff --git a/spec/lib/open_food_network/orders_and_fulfillments_report/supplier_totals_report_spec.rb b/spec/lib/open_food_network/orders_and_fulfillments_report/supplier_totals_report_spec.rb index 143bc953e5..21d886cbb0 100644 --- a/spec/lib/open_food_network/orders_and_fulfillments_report/supplier_totals_report_spec.rb +++ b/spec/lib/open_food_network/orders_and_fulfillments_report/supplier_totals_report_spec.rb @@ -8,11 +8,10 @@ RSpec.describe OpenFoodNetwork::OrdersAndFulfillmentsReport::SupplierTotalsRepor end let(:current_user) { distributor.owner } - let(:permissions) { OpenFoodNetwork::Permissions.new(current_user) } let(:report) do report_options = { report_type: described_class::REPORT_TYPE } - OpenFoodNetwork::OrdersAndFulfillmentsReport.new(permissions, report_options, true) + OpenFoodNetwork::OrdersAndFulfillmentsReport.new(current_user, report_options, true) end let(:report_table) do diff --git a/spec/lib/open_food_network/orders_and_fulfillments_report_spec.rb b/spec/lib/open_food_network/orders_and_fulfillments_report_spec.rb index ce9a90ce29..210392d380 100644 --- a/spec/lib/open_food_network/orders_and_fulfillments_report_spec.rb +++ b/spec/lib/open_food_network/orders_and_fulfillments_report_spec.rb @@ -23,7 +23,7 @@ describe OpenFoodNetwork::OrdersAndFulfillmentsReport do before { order.line_items << line_item } context "as a site admin" do - subject { described_class.new OpenFoodNetwork::Permissions.new(admin_user), {}, true } + subject { described_class.new(admin_user, {}, true) } it "fetches completed orders" do o2 = create(:order) @@ -39,7 +39,7 @@ describe OpenFoodNetwork::OrdersAndFulfillmentsReport do end context "as a manager of a supplier" do - subject { described_class.new OpenFoodNetwork::Permissions.new(user), {}, true } + subject { described_class.new(user, {}, true) } let(:s1) { create(:supplier_enterprise) } @@ -91,14 +91,14 @@ describe OpenFoodNetwork::OrdersAndFulfillmentsReport do o2.line_items << li2 end - it "shows line items supplied by my producers, with names hidden" do + it "does not show line items supplied by my producers" do expect(subject.table_items).to eq([]) end end end context "as a manager of a distributor" do - subject { described_class.new OpenFoodNetwork::Permissions.new(user), {}, true } + subject { described_class.new(user, {}, true) } before do distributor.enterprise_roles.create!(user: user) @@ -133,8 +133,7 @@ describe OpenFoodNetwork::OrdersAndFulfillmentsReport do ] report_types.each do |report_type| - report = described_class.new OpenFoodNetwork::Permissions.new(admin_user), - report_type: report_type + report = described_class.new(admin_user, report_type: report_type) expect(report.header.size).to eq(report.columns.size) end end @@ -150,9 +149,7 @@ describe OpenFoodNetwork::OrdersAndFulfillmentsReport do end let(:items) { - report = described_class.new(OpenFoodNetwork::Permissions.new(admin_user), - { report_type: "order_cycle_customer_totals" }, - true) + report = described_class.new(admin_user, { report_type: "order_cycle_customer_totals" }, true) OpenFoodNetwork::OrderGrouper.new(report.rules, report.columns).table(report.table_items) } diff --git a/spec/lib/open_food_network/packing_report_spec.rb b/spec/lib/open_food_network/packing_report_spec.rb index 6bbb1b2687..1c39d24b6a 100644 --- a/spec/lib/open_food_network/packing_report_spec.rb +++ b/spec/lib/open_food_network/packing_report_spec.rb @@ -62,7 +62,7 @@ module OpenFoodNetwork o2.line_items << li2 end - it "shows line items supplied by my producers, with names hidden" do + it "does not show line items supplied by my producers" do expect(subject.table_items).to eq([]) end end diff --git a/spec/lib/open_food_network/permissions_spec.rb b/spec/lib/open_food_network/permissions_spec.rb index 473a65fb2b..83d6de78ae 100644 --- a/spec/lib/open_food_network/permissions_spec.rb +++ b/spec/lib/open_food_network/permissions_spec.rb @@ -269,137 +269,6 @@ module OpenFoodNetwork end end - describe "finding orders that are visible in reports" do - let(:distributor) { create(:distributor_enterprise) } - let(:coordinator) { create(:distributor_enterprise) } - let(:random_enterprise) { create(:distributor_enterprise) } - let(:order_cycle) { create(:simple_order_cycle, coordinator: coordinator, distributors: [distributor]) } - let(:order) { create(:order, order_cycle: order_cycle, distributor: distributor ) } - let!(:line_item) { create(:line_item, order: order) } - let!(:producer) { create(:supplier_enterprise) } - - before do - allow(permissions).to receive(:coordinated_order_cycles) { Enterprise.where("1=0") } - end - - context "as the hub through which the order was placed" do - before do - allow(permissions).to receive(:managed_enterprises) { Enterprise.where(id: distributor) } - end - - it "should let me see the order" do - expect(permissions.visible_orders).to include order - end - end - - context "as the coordinator of the order cycle through which the order was placed" do - before do - allow(permissions).to receive(:managed_enterprises) { Enterprise.where(id: coordinator) } - allow(permissions).to receive(:coordinated_order_cycles) { OrderCycle.where(id: order_cycle) } - end - - it "should let me see the order" do - expect(permissions.visible_orders).to include order - end - end - - context "as a producer which has granted P-OC to the distributor of an order" do - before do - allow(permissions).to receive(:managed_enterprises) { Enterprise.where(id: producer) } - create(:enterprise_relationship, parent: producer, child: distributor, permissions_list: [:add_to_order_cycle]) - end - - context "which contains my products" do - before do - line_item.product.supplier = producer - line_item.product.save - end - - it "should let me see the order" do - expect(permissions.visible_orders).to include order - end - end - - context "which does not contain my products" do - it "should not let me see the order" do - expect(permissions.visible_orders).to_not include order - end - end - end - - context "as an enterprise that is a distributor in the order cycle, but not the distributor of the order" do - before do - allow(permissions).to receive(:managed_enterprises) { Enterprise.where(id: random_enterprise) } - end - - it "should not let me see the order" do - expect(permissions.visible_orders).to_not include order - end - end - end - - describe "finding line items that are visible in reports" do - let(:distributor) { create(:distributor_enterprise) } - let(:coordinator) { create(:distributor_enterprise) } - let(:random_enterprise) { create(:distributor_enterprise) } - let(:order_cycle) { create(:simple_order_cycle, coordinator: coordinator, distributors: [distributor]) } - let(:order) { create(:order, order_cycle: order_cycle, distributor: distributor ) } - let!(:line_item1) { create(:line_item, order: order) } - let!(:line_item2) { create(:line_item, order: order) } - let!(:producer) { create(:supplier_enterprise) } - - before do - allow(permissions).to receive(:coordinated_order_cycles) { Enterprise.where("1=0") } - end - - context "as the hub through which the parent order was placed" do - before do - allow(permissions).to receive(:managed_enterprises) { Enterprise.where(id: distributor) } - end - - it "should let me see the line_items" do - expect(permissions.visible_line_items).to include line_item1, line_item2 - end - end - - context "as the coordinator of the order cycle through which the parent order was placed" do - before do - allow(permissions).to receive(:managed_enterprises) { Enterprise.where(id: coordinator) } - allow(permissions).to receive(:coordinated_order_cycles) { OrderCycle.where(id: order_cycle) } - end - - it "should let me see the line_items" do - expect(permissions.visible_line_items).to include line_item1, line_item2 - end - end - - context "as the manager producer which has granted P-OC to the distributor of the parent order" do - before do - allow(permissions).to receive(:managed_enterprises) { Enterprise.where(id: producer) } - create(:enterprise_relationship, parent: producer, child: distributor, permissions_list: [:add_to_order_cycle]) - - line_item1.product.supplier = producer - line_item1.product.save - end - - it "should let me see the line_items pertaining to variants I produce" do - ps = permissions.visible_line_items - expect(ps).to include line_item1 - expect(ps).to_not include line_item2 - end - end - - context "as an enterprise that is a distributor in the order cycle, but not the distributor of the parent order" do - before do - allow(permissions).to receive(:managed_enterprises) { Enterprise.where(id: random_enterprise) } - end - - it "should not let me see the line_items" do - expect(permissions.visible_line_items).to_not include line_item1, line_item2 - end - end - end - describe "finding visible subscriptions" do let!(:so1) { create(:subscription) } let!(:so2) { create(:subscription) } diff --git a/spec/services/permissions/order_spec.rb b/spec/services/permissions/order_spec.rb new file mode 100644 index 0000000000..1ccb6648ec --- /dev/null +++ b/spec/services/permissions/order_spec.rb @@ -0,0 +1,142 @@ +require 'spec_helper' + +module Permissions + describe Order do + let(:user) { double(:user) } + let(:permissions) { Permissions::Order.new(user) } + let!(:basic_permissions) { OpenFoodNetwork::Permissions.new(user) } + + before { allow(OpenFoodNetwork::Permissions).to receive(:new) { basic_permissions } } + + describe "finding orders that are visible in reports" do + let(:distributor) { create(:distributor_enterprise) } + let(:coordinator) { create(:distributor_enterprise) } + let(:random_enterprise) { create(:distributor_enterprise) } + let(:order_cycle) { create(:simple_order_cycle, coordinator: coordinator, distributors: [distributor]) } + let(:order) { create(:order, order_cycle: order_cycle, distributor: distributor ) } + let!(:line_item) { create(:line_item, order: order) } + let!(:producer) { create(:supplier_enterprise) } + + before do + allow(basic_permissions).to receive(:coordinated_order_cycles) { Enterprise.where("1=0") } + end + + context "as the hub through which the order was placed" do + before do + allow(basic_permissions).to receive(:managed_enterprises) { Enterprise.where(id: distributor) } + end + + it "should let me see the order" do + expect(permissions.visible_orders).to include order + end + end + + context "as the coordinator of the order cycle through which the order was placed" do + before do + allow(basic_permissions).to receive(:managed_enterprises) { Enterprise.where(id: coordinator) } + allow(basic_permissions).to receive(:coordinated_order_cycles) { OrderCycle.where(id: order_cycle) } + end + + it "should let me see the order" do + expect(permissions.visible_orders).to include order + end + end + + context "as a producer which has granted P-OC to the distributor of an order" do + before do + allow(basic_permissions).to receive(:managed_enterprises) { Enterprise.where(id: producer) } + create(:enterprise_relationship, parent: producer, child: distributor, permissions_list: [:add_to_order_cycle]) + end + + context "which contains my products" do + before do + line_item.product.supplier = producer + line_item.product.save + end + + it "should let me see the order" do + expect(permissions.visible_orders).to include order + end + end + + context "which does not contain my products" do + it "should not let me see the order" do + expect(permissions.visible_orders).to_not include order + end + end + end + + context "as an enterprise that is a distributor in the order cycle, but not the distributor of the order" do + before do + allow(basic_permissions).to receive(:managed_enterprises) { Enterprise.where(id: random_enterprise) } + end + + it "should not let me see the order" do + expect(permissions.visible_orders).to_not include order + end + end + end + + describe "finding line items that are visible in reports" do + let(:distributor) { create(:distributor_enterprise) } + let(:coordinator) { create(:distributor_enterprise) } + let(:random_enterprise) { create(:distributor_enterprise) } + let(:order_cycle) { create(:simple_order_cycle, coordinator: coordinator, distributors: [distributor]) } + let(:order) { create(:order, order_cycle: order_cycle, distributor: distributor ) } + let!(:line_item1) { create(:line_item, order: order) } + let!(:line_item2) { create(:line_item, order: order) } + let!(:producer) { create(:supplier_enterprise) } + + before do + allow(basic_permissions).to receive(:coordinated_order_cycles) { Enterprise.where("1=0") } + end + + context "as the hub through which the parent order was placed" do + before do + allow(basic_permissions).to receive(:managed_enterprises) { Enterprise.where(id: distributor) } + end + + it "should let me see the line_items" do + expect(permissions.visible_line_items).to include line_item1, line_item2 + end + end + + context "as the coordinator of the order cycle through which the parent order was placed" do + before do + allow(basic_permissions).to receive(:managed_enterprises) { Enterprise.where(id: coordinator) } + allow(basic_permissions).to receive(:coordinated_order_cycles) { OrderCycle.where(id: order_cycle) } + end + + it "should let me see the line_items" do + expect(permissions.visible_line_items).to include line_item1, line_item2 + end + end + + context "as the manager producer which has granted P-OC to the distributor of the parent order" do + before do + allow(basic_permissions).to receive(:managed_enterprises) { Enterprise.where(id: producer) } + create(:enterprise_relationship, parent: producer, child: distributor, permissions_list: [:add_to_order_cycle]) + + line_item1.product.supplier = producer + line_item1.product.save + end + + it "should let me see the line_items pertaining to variants I produce" do + ps = permissions.visible_line_items + expect(ps).to include line_item1 + expect(ps).to_not include line_item2 + end + end + + context "as an enterprise that is a distributor in the order cycle, but not the distributor of the parent order" do + before do + allow(basic_permissions).to receive(:managed_enterprises) { Enterprise.where(id: random_enterprise) } + end + + it "should not let me see the line_items" do + expect(permissions.visible_line_items).to_not include line_item1, line_item2 + end + end + end + end +end