diff --git a/app/models/spree/adjustment_decorator.rb b/app/models/spree/adjustment_decorator.rb index fb3b190394..0d1bc941f6 100644 --- a/app/models/spree/adjustment_decorator.rb +++ b/app/models/spree/adjustment_decorator.rb @@ -35,5 +35,19 @@ module Spree def display_included_tax Spree::Money.new(included_tax, { :currency => currency }) end + + def self.without_callbacks + skip_callback :save, :after, :update_adjustable + skip_callback :destroy, :after, :update_adjustable + + result = yield + + ensure + set_callback :save, :after, :update_adjustable + set_callback :destroy, :after, :update_adjustable + + result + end + end end diff --git a/app/models/spree/order_decorator.rb b/app/models/spree/order_decorator.rb index 8f1c0381b1..53e80bbdef 100644 --- a/app/models/spree/order_decorator.rb +++ b/app/models/spree/order_decorator.rb @@ -164,21 +164,29 @@ Spree::Order.class_eval do def update_distribution_charge! with_lock do - EnterpriseFee.clear_all_adjustments_on_order self - line_items.each do |line_item| - if provided_by_order_cycle? line_item - OpenFoodNetwork::EnterpriseFeeCalculator.new.create_line_item_adjustments_for line_item + # Without intervention, the Spree::Adjustment#update_adjustable callback is called + # once for every (line item x fee), which triggers a costly Spree::Order#update! + Spree::Adjustment.without_callbacks do + EnterpriseFee.clear_all_adjustments_on_order self - else - pd = product_distribution_for line_item - pd.create_adjustment_for line_item if pd + line_items.each do |line_item| + if provided_by_order_cycle? line_item + OpenFoodNetwork::EnterpriseFeeCalculator.new.create_line_item_adjustments_for line_item + + else + pd = product_distribution_for line_item + pd.create_adjustment_for line_item if pd + end + end + + if order_cycle + OpenFoodNetwork::EnterpriseFeeCalculator.new.create_order_adjustments_for self end end - if order_cycle - OpenFoodNetwork::EnterpriseFeeCalculator.new.create_order_adjustments_for self - end + # After fees are calculated, we update the order once + update! end end diff --git a/spec/models/spree/order_spec.rb b/spec/models/spree/order_spec.rb index e50a64a4d9..300cf26bac 100644 --- a/spec/models/spree/order_spec.rb +++ b/spec/models/spree/order_spec.rb @@ -54,6 +54,8 @@ describe Spree::Order do product_distribution.should_receive(:create_adjustment_for).with(line_item) subject.stub(:product_distribution_for) { product_distribution } + subject.should_receive(:update!) + subject.update_distribution_charge! end @@ -65,6 +67,8 @@ describe Spree::Order do subject.stub(:product_distribution_for) { nil } + subject.should_receive(:update!) + subject.update_distribution_charge! end @@ -90,6 +94,8 @@ describe Spree::Order do OpenFoodNetwork::EnterpriseFeeCalculator.any_instance.stub(:create_order_adjustments_for) subject.stub(:order_cycle) { order_cycle } + subject.should_receive(:update!) + subject.update_distribution_charge! end