diff --git a/app/models/spree/product_decorator.rb b/app/models/spree/product_decorator.rb index 57e92f241b..454f821035 100644 --- a/app/models/spree/product_decorator.rb +++ b/app/models/spree/product_decorator.rb @@ -11,23 +11,36 @@ 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_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)'). + 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_order_cycle_distributor, lambda { |distributor| + joins('INNER JOIN spree_variants ON (spree_variants.product_id = spree_products.id)'). + joins('INNER JOIN exchange_variants ON (exchange_variants.variant_id=spree_variants.id)'). + joins('INNER JOIN exchanges ON (exchanges.id = exchange_variants.exchange_id)'). + joins('INNER 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)) } + scope :in_supplier_or_order_cycle_distributor, lambda { |enterprise| + enterprise_id = enterprise.respond_to?(:id) ? enterprise.id : enterprise.to_i + + select('distinct spree_products.*'). + joins('LEFT OUTER JOIN spree_variants ON (spree_variants.product_id = spree_products.id)'). + joins('LEFT OUTER JOIN exchange_variants ON (exchange_variants.variant_id=spree_variants.id)'). + joins('LEFT OUTER JOIN exchanges ON (exchanges.id = exchange_variants.exchange_id)'). + joins('LEFT OUTER JOIN order_cycles ON (order_cycles.id = exchanges.order_cycle_id)'). + where('(exchanges.sender_id = order_cycles.coordinator_id AND exchanges.receiver_id = ?) OR (spree_products.supplier_id=?)', enterprise_id, enterprise_id) + } + + 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/models/product_spec.rb b/spec/models/product_spec.rb index f10f9bc269..e892fb7e2f 100644 --- a/spec/models/product_spec.rb +++ b/spec/models/product_spec.rb @@ -20,13 +20,13 @@ describe Spree::Product do end describe "scopes" do - describe "in_distributor" do + describe "in_order_cycle_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] + Spree::Product.in_order_cycle_distributor(d).should == [p] end it "finds products listed by variant" do @@ -35,7 +35,7 @@ describe Spree::Product do 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] + Spree::Product.in_order_cycle_distributor(d).should == [p] end it "doesn't show products listed in the incoming exchange only" do @@ -46,7 +46,7 @@ describe Spree::Product do ex = oc.exchanges.where(:receiver_id => oc.coordinator_id).first ex.variants << p.master - Spree::Product.in_distributor(d).should be_empty + Spree::Product.in_order_cycle_distributor(d).should be_empty end it "doesn't show products for a different distributor" do @@ -55,11 +55,11 @@ describe Spree::Product do 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 + Spree::Product.in_order_cycle_distributor(d2).should be_empty end end - describe "in_supplier_or_distributor" do + describe "in_supplier_or_distributor" do it "finds supplied products" do s0 = create(:supplier_enterprise) s1 = create(:supplier_enterprise) @@ -99,6 +99,54 @@ describe Spree::Product do end end end + + describe "in_supplier_or_order_cycle_distributor" do + it "finds supplied products" do + s0 = create(:supplier_enterprise) + s1 = create(:supplier_enterprise) + p0 = create(:product, :supplier => s0) + p1 = create(:product, :supplier => s1) + + Spree::Product.in_supplier_or_order_cycle_distributor(s1).should == [p1] + end + + it "finds distributed products" do + d0 = create(:distributor_enterprise) + d1 = create(:distributor_enterprise) + p0 = create(:product) + p1 = create(:product) + + create(:simple_order_cycle, :distributors => [d0], :variants => [p0.master]) + create(:simple_order_cycle, :distributors => [d1], :variants => [p1.master]) + + Spree::Product.in_supplier_or_order_cycle_distributor(d1).should == [p1] + end + + it "finds products supplied and distributed by the same enterprise" do + s = create(:supplier_enterprise) + d = create(:distributor_enterprise) + p = create(:product, :supplier => s) + create(:simple_order_cycle, :distributors => [d], :variants => [p.master]) + + Spree::Product.in_supplier_or_order_cycle_distributor(s).should == [p] + Spree::Product.in_supplier_or_order_cycle_distributor(d).should == [p] + end + + it "shows each product once when it is distributed by many distributors" do + s = create(:supplier_enterprise) + d1 = create(:distributor_enterprise) + d2 = create(:distributor_enterprise) + d3 = create(:distributor_enterprise) + p = create(:product, :supplier => s) + + create(:simple_order_cycle, :distributors => [d1, d2, d3], :variants => [p.master]) + create(:simple_order_cycle, :distributors => [d1], :variants => [p.master]) + + [s, d1, d2, d3].each do |enterprise| + Spree::Product.in_supplier_or_order_cycle_distributor(enterprise).should == [p] + end + end + end end describe "finders" do