mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-24 20:36:49 +00:00
Support multiple orders when adding a product to a cart.
This commit is contained in:
@@ -2,21 +2,21 @@ class Cart < ActiveRecord::Base
|
||||
has_many :orders, :class_name => 'Spree::Order'
|
||||
belongs_to :user, :class_name => Spree.user_class
|
||||
|
||||
def add_variant variant_id, quantity, currency
|
||||
def add_variant variant_id, quantity, distributor, order_cycle, 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
|
||||
order = create_or_find_order_for_distributor distributor, order_cycle, currency
|
||||
|
||||
populator = Spree::OrderPopulator.new(order, currency)
|
||||
populator.populate({ :variants => { variant_id => quantity }, :distributor_id => distributor.id, :order_cycle_id => order_cycle })
|
||||
end
|
||||
|
||||
def create_or_find_order_for_distributor distributor, currency
|
||||
order_for_distributor = orders.find { |order| order.distributor == distributor }
|
||||
def create_or_find_order_for_distributor distributor, order_cycle, currency
|
||||
order_for_distributor = orders.find { |order| order.distributor == distributor && order.order_cycle == order_cycle }
|
||||
unless order_for_distributor
|
||||
order_for_distributor = Spree::Order.create(:currency => currency, :distributor => distributor)
|
||||
order_for_distributor.distributor = distributor
|
||||
order_for_distributor.order_cycle = order_cycle
|
||||
orders << order_for_distributor
|
||||
end
|
||||
|
||||
|
||||
@@ -4,15 +4,24 @@ Current cart for:
|
||||
= spree_current_user.andand.email
|
||||
%div{ 'ng-app' => 'store', 'ng-controller' => 'CartCtrl', 'ng-init' => "loadCart(#{spree_current_user.andand.cart.andand.id});" }
|
||||
{{cart}} {{state}}
|
||||
%br
|
||||
%br
|
||||
%ul
|
||||
%li(ng-repeat="order in cart.orders")
|
||||
Distributor: {{order.distributor}}
|
||||
%br
|
||||
Order cycle: {{order.order_cycle.andand.name}}
|
||||
%br
|
||||
From: {{order.order_cycle.andand.orders_open_at}} To: {{order.order_cycle.andand.orders_close_at}}
|
||||
%strong Distributor:
|
||||
{{order.distributor}}
|
||||
%strong Order cycle:
|
||||
{{order.order_cycle.andand.name}}
|
||||
%strong From:
|
||||
{{order.order_cycle.andand.orders_open_at}}
|
||||
%strong To:
|
||||
{{order.order_cycle.andand.orders_close_at}}
|
||||
%ul
|
||||
%li(ng-repeat="line_item in order.line_items")
|
||||
Product: {{line_item.name}} Quantity: {{line_item.quantity}}
|
||||
%strong Product:
|
||||
{{line_item.name}}
|
||||
%strong Quantity:
|
||||
{{line_item.quantity}}
|
||||
%button Buy me
|
||||
%br
|
||||
|
||||
|
||||
@@ -6,89 +6,125 @@ describe Cart do
|
||||
it { should have_many(:orders) }
|
||||
end
|
||||
|
||||
describe 'adding a product' do
|
||||
describe 'when adding a product' do
|
||||
|
||||
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]) }
|
||||
|
||||
let(:product) { FactoryGirl.create(:product, :distributors => [distributor]) }
|
||||
|
||||
let(:product_with_order_cycle) { create(:product) }
|
||||
let(:order_cycle) { create(:simple_order_cycle, distributors: [distributor, other_distributor], variants: [product_with_order_cycle.master]) }
|
||||
|
||||
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
|
||||
it 'should create an order for the product being added, and associate the product to the selected distribution' do
|
||||
subject.add_variant product.master.id, 3, distributor, nil, currency
|
||||
|
||||
subject.orders.size.should == 1
|
||||
order = subject.orders.first.reload
|
||||
order.currency.should == currency
|
||||
order.distributor.should == product.distributors.first
|
||||
order.order_cycle.should be_nil
|
||||
order.line_items.first.product.should == product
|
||||
end
|
||||
|
||||
it 'should create an order for the product being added, and associate the order with an order cycle and distributor' do
|
||||
subject.add_variant product_with_order_cycle.master.id, 3, distributor, order_cycle, currency
|
||||
|
||||
subject.orders.size.should == 1
|
||||
order = subject.orders.first.reload
|
||||
order.currency.should == currency
|
||||
order.distributor.should == distributor
|
||||
order.order_cycle.should == order_cycle
|
||||
order.line_items.first.product.should == product_with_order_cycle
|
||||
end
|
||||
end
|
||||
|
||||
describe 'to a cart with an established order' do
|
||||
let(:order) { FactoryGirl.create(:order, :distributor => other_distributor) }
|
||||
describe 'to a cart with an order for a distributor' do
|
||||
let(:product_from_other_distributor) { FactoryGirl.create(:product, :distributors => [other_distributor]) }
|
||||
let(:order) { FactoryGirl.create(:order, :distributor => distributor) }
|
||||
|
||||
before (:each) do
|
||||
subject.orders << order
|
||||
subject.save!
|
||||
end
|
||||
|
||||
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 a new order when product added for different distributor' do
|
||||
subject.add_variant product_from_other_distributor.master.id, 3, other_distributor, nil, currency
|
||||
|
||||
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
|
||||
new_order_for_other_distributor = subject.orders.find { |order| order.distributor == other_distributor }
|
||||
new_order_for_other_distributor.order_cycle.should be_nil
|
||||
new_order_for_other_distributor.line_items.first.product.should == product_from_other_distributor
|
||||
end
|
||||
|
||||
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 group line item in existing order, when product added for the same distributor' do
|
||||
subject.add_variant product.master.id, 3, distributor, nil, currency
|
||||
|
||||
subject.orders.size.should == 1
|
||||
order = subject.orders.first.reload
|
||||
order.line_items.size.should == 1
|
||||
order.line_items.first.product.should == product
|
||||
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'
|
||||
|
||||
it 'if the cart has a distributor set, then should only populate orders for that distributors'
|
||||
|
||||
it 'should create a new order for product in an order cycle' do
|
||||
subject.add_variant product_with_order_cycle.master.id, 3, distributor, order_cycle, currency
|
||||
|
||||
subject.orders.size.should == 2
|
||||
new_order_for_distributor = subject.orders.find { |order| order.order_cycle == order_cycle }
|
||||
new_order_for_distributor.reload
|
||||
new_order_for_distributor.line_items.first.product.should == product_with_order_cycle
|
||||
end
|
||||
end
|
||||
|
||||
describe 'existing order for distributor and order cycle' do
|
||||
let(:order) { FactoryGirl.create(:order, :distributor => distributor, :order_cycle => order_cycle) }
|
||||
|
||||
before (:each) do
|
||||
subject.orders << order
|
||||
subject.save!
|
||||
end
|
||||
|
||||
it 'should group line items in existing order when added for the same distributor and order cycle' do
|
||||
subject.add_variant product_with_order_cycle.master.id, 3, distributor, order_cycle, currency
|
||||
|
||||
subject.orders.size.should == 1
|
||||
order = subject.orders.first.reload
|
||||
order.line_items.size.should == 1
|
||||
order.line_items.find{ |line_item| line_item.product == product_with_order_cycle }.should_not be_nil
|
||||
end
|
||||
|
||||
it 'should create line item in new order when product added is for a different order cycle' do
|
||||
order_cycle2 = create(:simple_order_cycle, distributors: [distributor], variants: [product_with_order_cycle.master])
|
||||
|
||||
subject.add_variant product_with_order_cycle.master.id, 3, distributor, order_cycle2, currency
|
||||
|
||||
subject.orders.size.should == 2
|
||||
new_order_for_second_order_cycle = subject.orders.find { |order| order.order_cycle == order_cycle2 }
|
||||
new_order_for_second_order_cycle.reload
|
||||
new_order_for_second_order_cycle.line_items.size.should == 1
|
||||
new_order_for_second_order_cycle.line_items.first.product.should == product_with_order_cycle
|
||||
new_order_for_second_order_cycle.distributor.should == distributor
|
||||
new_order_for_second_order_cycle.order_cycle.should == order_cycle2
|
||||
end
|
||||
|
||||
it 'should create line_items in new order when added with different distributor, but same order_cycle' do
|
||||
subject.add_variant product_with_order_cycle.master.id, 3, other_distributor, order_cycle, currency
|
||||
|
||||
subject.orders.size.should == 2
|
||||
new_order_for_second_order_cycle = subject.orders.find { |order| order.distributor == other_distributor }
|
||||
new_order_for_second_order_cycle.reload
|
||||
new_order_for_second_order_cycle.line_items.size.should == 1
|
||||
new_order_for_second_order_cycle.line_items.find{ |line_item| line_item.product == product_with_order_cycle }.should_not be_nil
|
||||
new_order_for_second_order_cycle.order_cycle.should == order_cycle
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user