From dd3aaccf9fbec6214427164fd7211be7c04556f6 Mon Sep 17 00:00:00 2001 From: Andrew Spinks Date: Tue, 13 Aug 2013 09:27:07 +1000 Subject: [PATCH] When adding a variant to a cart, split into multiple orders depending on the distributors that it contains. --- app/models/cart.rb | 24 ++++++++---- spec/models/cart_spec.rb | 84 ++++++++++++++++++++++++++++++++++------ 2 files changed, 90 insertions(+), 18 deletions(-) diff --git a/app/models/cart.rb b/app/models/cart.rb index f604869ee5..61d1b32e7c 100644 --- a/app/models/cart.rb +++ b/app/models/cart.rb @@ -2,14 +2,24 @@ class Cart < ActiveRecord::Base has_many :orders, :class_name => 'Spree::Order' belongs_to :user, :class_name => Spree.user_class - def add_products hash, currency - if orders.empty? - order = Spree::Order.create - orders << order + def add_variant variant_id, quantity, currency + variant = Spree::Variant.find(variant_id) + variant.product.distributors.each do |distributor| + order = create_or_find_order_for_distributor distributor, currency + + populator = Spree::OrderPopulator.new(order, currency) + populator.populate({ :variants => { variant_id => quantity }, :distributor_id => distributor.id, :order_cycle_id => nil }) + end + end + + def create_or_find_order_for_distributor distributor, currency + order_for_distributor = orders.find { |order| order.distributor == distributor } + unless order_for_distributor + order_for_distributor = Spree::Order.create(:currency => currency, :distributor => distributor) + order_for_distributor.distributor = distributor + orders << order_for_distributor end - order = orders.first - populator = Spree::OrderPopulator.new(order, currency) - populator.populate(hash) + order_for_distributor end end diff --git a/spec/models/cart_spec.rb b/spec/models/cart_spec.rb index 1c8997f15b..7e40a2efba 100644 --- a/spec/models/cart_spec.rb +++ b/spec/models/cart_spec.rb @@ -8,25 +8,87 @@ describe Cart do describe 'adding a product' do - let(:product) { create(:product) } + let(:cart) { Cart.create(user: user) } + let(:distributor) { FactoryGirl.create(:distributor_enterprise) } + let(:other_distributor) { FactoryGirl.create(:distributor_enterprise) } + let(:currency) { "AUD" } + let(:product) { FactoryGirl.create(:product, :distributors => [distributor]) } + let(:product_from_other_distributor) { FactoryGirl.create(:product, :distributors => [other_distributor]) } - it 'when there are no orders in the cart, create one when a product is added' do - subject.add_variant product.master, 3 - subject.orders.size.should == 1 - subject.orders.first.line_items.first.product.should == product + describe 'to an empty cart' do + it 'when there are no orders in the cart, create one when a product is added' do + subject.add_variant product.master.id, 3, currency + + subject.orders.size.should == 1 + order = subject.orders.first.reload + order.currency.should == currency + order.line_items.first.product.should == product + end end - it 'should create an order when a product from a new distributor is added' + describe 'to a cart with an established order' do + let(:order) { FactoryGirl.create(:order, :distributor => other_distributor) } - it 'should create an order when a product from a new order cycle is added' + before (:each) do + subject.orders << order + subject.save! + end - it 'should create line items in an order for added product, when in the same distributor' + it 'should create an order when a product from a new distributor is added' do + subject.add_variant product.master.id, 3, currency - it 'should create line items in an order for added product, when in the same distributor and order cycle' + subject.reload + subject.orders.size.should == 2 + new_order_for_distributor = subject.orders.find { |order| order.distributor == distributor } + new_order_for_distributor.line_items.first.product.should == product + end - it 'should not create line items in an order, if the product is in a different order cycle to the order' + it 'should group line item in existing order, when product from the same distributor' do + subject.add_variant product_from_other_distributor.master.id, 3, currency - it 'should not create line items in an order, if the product is in a different distributor to the order' + subject.orders.size.should == 1 + order = subject.orders.first.reload + order.line_items.size.should == 1 + end + + it 'should create a line item in each order for a product that has multiple distributors' do + product.distributors << other_distributor + product.save! + + subject.add_variant product.master.id, 3, currency + + subject.orders.size.should == 2 + first_order = subject.orders.first.reload + second_order = subject.orders[1].reload + first_order.line_items.first.product.should == product + second_order.line_items.first.product.should == product + end + + it 'should create multiple line items for an order that has multiple order cycles' + + end + + describe 'products with order cycles' do + let(:order_cycle) { FactoryGirl.create :order_cycle } + + before(:each) do + product.order_cycles << order_cycle + product.save! + end + + it 'should create an order when a product from a new order cycle is added' do + subject.add_variant product.master.id, 3, currency + + subject.orders.size.should == 1 + subject.orders.first.order_cycle.should == order_cycle + end + + it 'should create line items in an order for added product, when in the same distributor and order cycle' + + it 'should not create line items in an order, if the product is in a different order cycle to the order' + + it 'should not create line items in an order, if the product is in a different distributor to the order' + end end end