From 9e278d5b2f0e3574c57feda05c148e09f0785e86 Mon Sep 17 00:00:00 2001 From: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> Date: Thu, 4 Jun 2020 12:02:11 +0200 Subject: [PATCH] Improve performance in various reports --- .../spree/admin/reports_controller.rb | 6 ++-- app/models/spree/product_decorator.rb | 6 ++++ spec/models/spree/product_spec.rb | 31 +++++++++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/app/controllers/spree/admin/reports_controller.rb b/app/controllers/spree/admin/reports_controller.rb index 54f2868610..3ada1fbbcd 100644 --- a/app/controllers/spree/admin/reports_controller.rb +++ b/app/controllers/spree/admin/reports_controller.rb @@ -247,8 +247,10 @@ module Spree end def suppliers_of_products_distributed_by(distributors) - distributors.map { |d| Spree::Product.in_distributor(d).includes(:supplier).all }. - flatten.map(&:supplier).uniq + supplier_ids = Spree::Product.in_distributors(distributors). + select('spree_products.supplier_id') + + Enterprise.where(id: supplier_ids) end # Load order cycles the current user has access to diff --git a/app/models/spree/product_decorator.rb b/app/models/spree/product_decorator.rb index fe20fe5194..cd427376a8 100644 --- a/app/models/spree/product_decorator.rb +++ b/app/models/spree/product_decorator.rb @@ -84,6 +84,12 @@ Spree::Product.class_eval do select('distinct spree_products.*') } + scope :in_distributors, lambda { |distributors| + with_order_cycles_outer. + where('(o_exchanges.incoming = ? AND o_exchanges.receiver_id IN (?))', false, distributors). + uniq + } + # Products supplied by a given enterprise or distributed via that enterprise through an OC scope :in_supplier_or_distributor, lambda { |enterprise| enterprise = enterprise.respond_to?(:id) ? enterprise.id : enterprise.to_i diff --git a/spec/models/spree/product_spec.rb b/spec/models/spree/product_spec.rb index a8c6368a70..d3d47b21ca 100644 --- a/spec/models/spree/product_spec.rb +++ b/spec/models/spree/product_spec.rb @@ -257,6 +257,37 @@ module Spree end end + describe "in_distributors" do + let!(:distributor1) { create(:distributor_enterprise) } + let!(:distributor2) { create(:distributor_enterprise) } + let!(:product1) { create(:product) } + let!(:product2) { create(:product) } + let!(:product3) { create(:product) } + let!(:product4) { create(:product) } + let!(:order_cycle1) { + create(:order_cycle, distributors: [distributor1], + variants: [product1.variants.first, product2.variants.first]) + } + let!(:order_cycle2) { + create(:order_cycle, distributors: [distributor2], + variants: [product3.variants.first]) + } + + it "returns distributed products for a given Enterprise AR relation" do + distributors_relation = Enterprise.where(id: [distributor1.id, distributor2.id]) + + expect(Product.in_distributors(distributors_relation)).to include product1, product2, product3 + expect(Product.in_distributors(distributors_relation)).to_not include product4 + end + + it "returns distributed products for a given array of enterprise ids" do + distributors_ids = [distributor1.id, distributor2.id] + + expect(Product.in_distributors(distributors_ids)).to include product1, product2, product3 + expect(Product.in_distributors(distributors_ids)).to_not include product4 + end + end + describe "in_supplier_or_distributor" do it "shows products in supplier" do s1 = create(:supplier_enterprise)