From d65dda4dc590cfef597964d63258e0072121324e Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Sat, 18 May 2013 19:21:01 +1000 Subject: [PATCH] When order distributor changes, update line item shipping method --- app/models/spree/line_item_decorator.rb | 8 ++++ app/models/spree/order_decorator.rb | 2 +- ...distributor_info_rich_text_feature_spec.rb | 1 + spec/features/consumer/checkout_spec.rb | 37 +++++++++++++++++ spec/models/line_item_spec.rb | 41 +++++++++++++++---- 5 files changed, 80 insertions(+), 9 deletions(-) diff --git a/app/models/spree/line_item_decorator.rb b/app/models/spree/line_item_decorator.rb index aac21c1225..7bda8c2a06 100644 --- a/app/models/spree/line_item_decorator.rb +++ b/app/models/spree/line_item_decorator.rb @@ -5,7 +5,15 @@ Spree::LineItem.class_eval do before_create :set_itemwise_shipping_method + def itemwise_shipping_cost + # When order has not yet been placed, update shipping method in case order + # has changed to a distributor with a different shipping method + if %w(cart address delivery resumed).include? self.order.state + set_itemwise_shipping_method + save! if shipping_method_id_changed? + end + order = OpenStruct.new :line_items => [self] shipping_method.compute_amount(order) end diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb index 17dbe09405..5d26b9af27 100644 --- a/app/models/spree/order_decorator.rb +++ b/app/models/spree/order_decorator.rb @@ -3,10 +3,10 @@ require 'open_food_web/distributor_change_validator' Spree::Order.class_eval do belongs_to :distributor, :class_name => 'Enterprise' - before_validation :shipping_address_from_distributor validate :products_available_from_new_distributor, :if => :distributor_id_changed? attr_accessible :distributor_id + before_validation :shipping_address_from_distributor after_create :set_default_shipping_method diff --git a/spec/features/chili/enterprises_distributor_info_rich_text_feature_spec.rb b/spec/features/chili/enterprises_distributor_info_rich_text_feature_spec.rb index 1d6e53ffc8..85536889fd 100644 --- a/spec/features/chili/enterprises_distributor_info_rich_text_feature_spec.rb +++ b/spec/features/chili/enterprises_distributor_info_rich_text_feature_spec.rb @@ -73,6 +73,7 @@ feature "enterprises distributor info as rich text" do # -- Purchase email complete_purchase_from_checkout_address_page + wait_until { ActionMailer::Base.deliveries.length == 1 } ActionMailer::Base.deliveries.length.should == 1 email = ActionMailer::Base.deliveries.last email.body.should =~ /Chu ge sai yubi dan bisento tobi ashi yubi ge omote./ diff --git a/spec/features/consumer/checkout_spec.rb b/spec/features/consumer/checkout_spec.rb index c88f0da8ca..ed44f18d6a 100644 --- a/spec/features/consumer/checkout_spec.rb +++ b/spec/features/consumer/checkout_spec.rb @@ -79,6 +79,42 @@ feature %q{ page.should have_selector '#delivery-fees span.order-total', :text => '$3.00' end + scenario "changing distributor updates delivery fees" do + # Given two distributors and shipping methods + d1 = create(:distributor_enterprise) + d2 = create(:distributor_enterprise) + sm1 = create(:shipping_method) + sm1.calculator.set_preference :amount, 1.23; sm1.calculator.save! + sm2 = create(:free_shipping_method) + sm2.calculator.set_preference :amount, 2.34; sm2.calculator.save! + + # And two products both available from both distributors + p1 = create(:product) + create(:product_distribution, product: p1, distributor: d1, shipping_method: sm1) + create(:product_distribution, product: p1, distributor: d2, shipping_method: sm2) + p2 = create(:product) + create(:product_distribution, product: p2, distributor: d1, shipping_method: sm1) + create(:product_distribution, product: p2, distributor: d2, shipping_method: sm2) + + # When I add the first product to my cart with the first distributor + #visit spree.root_path + login_to_consumer_section + click_link p1.name + select d1.name, :from => 'distributor_id' + click_button 'Add To Cart' + + # Then I should see shipping costs for the first distributor + page.should have_selector 'span.shipping-total', text: '$1.23' + + # When add the second with the second distributor + click_link 'Continue shopping' + click_link p2.name + select d2.name, :from => 'distributor_id' + click_button 'Add To Cart' + + # Then I should see shipping costs for the second distributor + page.should have_selector 'span.shipping-total', text: '$4.68' + end scenario "buying a product", :js => true do login_to_consumer_section @@ -143,4 +179,5 @@ feature %q{ # page.should have_content('On Tuesday, 4 PM') # page.should have_content('12 Bungee Rd, Carion') end + end diff --git a/spec/models/line_item_spec.rb b/spec/models/line_item_spec.rb index 5b62b802f1..d17aca6f06 100644 --- a/spec/models/line_item_spec.rb +++ b/spec/models/line_item_spec.rb @@ -2,17 +2,42 @@ require 'spec_helper' module Spree describe LineItem do - it "computes shipping cost for its product" do - # Create a shipping method with flat rate of 10 - shipping_method = create(:shipping_method) - shipping_method.calculator.set_preference :amount, 10 + describe "computing shipping cost for its product" do + let(:shipping_method) do + sm = create(:shipping_method) + sm.calculator.set_preference :amount, 10 + sm + end + let(:order) { double(:order, :distributor => nil, :state => 'complete') } + let(:line_item) do + li = LineItem.new + li.stub(:shipping_method).and_return(shipping_method) + li.stub(:order).and_return(order) + li + end - order = double(:order, :distributor => nil) + it "computes shipping cost for its product" do + line_item.itemwise_shipping_cost.should == 10 + end - subject.stub(:shipping_method).and_return(shipping_method) - subject.stub(:order).and_return(order) + it "updates shipping method when order has not yet been placed" do + %w(cart address delivery resumed).each do |state| + order.stub(:state).and_return(state) + line_item.should_receive(:set_itemwise_shipping_method) + line_item.should_receive(:shipping_method_id_changed?).and_return(true) + line_item.should_receive(:save!) + line_item.itemwise_shipping_cost + end + end - subject.itemwise_shipping_cost.should == 10 + it "does not update shipping method when order has been placed" do + %w(payment confirm complete cancelled returned awaiting_return).each do |state| + order.stub(:state).and_return(state) + line_item.should_receive(:set_itemwise_shipping_method).never + line_item.should_receive(:save!).never + line_item.itemwise_shipping_cost + end + end end end end