From ebf1c8602f8b19d26ce3f65219dfa9e1775b2d0a Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 7 Feb 2013 10:29:48 +1100 Subject: [PATCH] Write new query for Product#in_distributor that queries order cycles instead of product_distributions --- app/models/spree/product_decorator.rb | 21 ++++++++++----- spec/factories.rb | 7 +++-- spec/models/product_spec.rb | 39 +++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 8 deletions(-) diff --git a/app/models/spree/product_decorator.rb b/app/models/spree/product_decorator.rb index cd809d880e..57e92f241b 100644 --- a/app/models/spree/product_decorator.rb +++ b/app/models/spree/product_decorator.rb @@ -11,14 +11,23 @@ Spree::Product.class_eval do validates_presence_of :supplier scope :in_supplier, lambda { |supplier| where(:supplier_id => supplier) } - scope :in_distributor, lambda { |distributor| joins(:product_distributions).where('product_distributions.distributor_id = ?', (distributor.respond_to?(:id) ? distributor.id : distributor.to_i)) } - scope :in_supplier_or_distributor, lambda { |enterprise| select('distinct spree_products.*'). - joins('LEFT OUTER JOIN product_distributions ON product_distributions.product_id=spree_products.id'). - where('supplier_id=? OR product_distributions.distributor_id=?', - enterprise.respond_to?(:id) ? enterprise.id : enterprise.to_i, - enterprise.respond_to?(:id) ? enterprise.id : enterprise.to_i) } + # scope :in_distributor, lambda { |distributor| joins(:product_distributions).where('product_distributions.distributor_id = ?', (distributor.respond_to?(:id) ? distributor.id : distributor.to_i)) } + # scope :in_supplier_or_distributor, lambda { |enterprise| select('distinct spree_products.*'). + # joins('LEFT OUTER JOIN product_distributions ON product_distributions.product_id=spree_products.id'). + # where('supplier_id=? OR product_distributions.distributor_id=?', + # enterprise.respond_to?(:id) ? enterprise.id : enterprise.to_i, + # enterprise.respond_to?(:id) ? enterprise.id : enterprise.to_i) } + scope :in_distributor, lambda { |distributor| + joins('LEFT JOIN spree_variants ON (spree_variants.product_id = spree_products.id)'). + joins('LEFT JOIN exchange_variants ON (exchange_variants.variant_id=spree_variants.id)'). + joins('LEFT JOIN exchanges ON (exchanges.id = exchange_variants.exchange_id)'). + joins('LEFT JOIN order_cycles ON (order_cycles.id = exchanges.order_cycle_id)'). + where('exchanges.sender_id = order_cycles.coordinator_id'). + where('exchanges.receiver_id = ?', (distributor.respond_to?(:id) ? distributor.id : distributor.to_i)) + } + def shipping_method_for_distributor(distributor) distribution = self.product_distributions.find_by_distributor_id(distributor) raise ArgumentError, "This product is not available through that distributor" unless distribution diff --git a/spec/factories.rb b/spec/factories.rb index ac8d7ea54a..199fef1dc3 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -34,15 +34,18 @@ FactoryGirl.define do ignore do suppliers [] distributors [] + variants [] end after(:create) do |oc, proxy| proxy.suppliers.each do |supplier| - create(:exchange, :order_cycle => oc, :sender => supplier, :receiver => oc.coordinator, :pickup_time => 'time', :pickup_instructions => 'instructions') + ex = create(:exchange, :order_cycle => oc, :sender => supplier, :receiver => oc.coordinator, :pickup_time => 'time', :pickup_instructions => 'instructions') + proxy.variants.each { |v| ex.variants << v } end proxy.distributors.each do |distributor| - create(:exchange, :order_cycle => oc, :sender => oc.coordinator, :receiver => distributor, :pickup_time => 'time', :pickup_instructions => 'instructions') + ex = create(:exchange, :order_cycle => oc, :sender => oc.coordinator, :receiver => distributor, :pickup_time => 'time', :pickup_instructions => 'instructions') + proxy.variants.each { |v| ex.variants << v } end end end diff --git a/spec/models/product_spec.rb b/spec/models/product_spec.rb index ef777ef5c7..f10f9bc269 100644 --- a/spec/models/product_spec.rb +++ b/spec/models/product_spec.rb @@ -20,6 +20,45 @@ describe Spree::Product do end describe "scopes" do + describe "in_distributor" do + it "finds products listed by master" do + s = create(:supplier_enterprise) + d = create(:distributor_enterprise) + p = create(:product) + create(:simple_order_cycle, :suppliers => [s], :distributors => [d], :variants => [p.master]) + Spree::Product.in_distributor(d).should == [p] + end + + it "finds products listed by variant" do + s = create(:supplier_enterprise) + d = create(:distributor_enterprise) + p = create(:product) + v = create(:variant, :product => p) + create(:simple_order_cycle, :suppliers => [s], :distributors => [d], :variants => [v]) + Spree::Product.in_distributor(d).should == [p] + end + + it "doesn't show products listed in the incoming exchange only" do + s = create(:supplier_enterprise) + d = create(:distributor_enterprise) + p = create(:product) + oc = create(:simple_order_cycle, :coordinator => d, :suppliers => [s], :distributors => [d]) + ex = oc.exchanges.where(:receiver_id => oc.coordinator_id).first + ex.variants << p.master + + Spree::Product.in_distributor(d).should be_empty + end + + it "doesn't show products for a different distributor" do + s = create(:supplier_enterprise) + d1 = create(:distributor_enterprise) + d2 = create(:distributor_enterprise) + p = create(:product) + create(:simple_order_cycle, :suppliers => [s], :distributors => [d1], :variants => [p.master]) + Spree::Product.in_distributor(d2).should be_empty + end + end + describe "in_supplier_or_distributor" do it "finds supplied products" do s0 = create(:supplier_enterprise)