Speed up add to cart: Update the order once per fee calculation, rather than for every line item x fee

This commit is contained in:
Rohan Mitchell
2016-01-07 10:52:36 +11:00
parent a27e593924
commit e24027a8d0
3 changed files with 38 additions and 10 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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