Extract compute_tax from EnterpriseFeeApplicator to Spree::TaxRate model

This commit is contained in:
Rohan Mitchell
2015-11-04 10:59:29 +11:00
parent d794981ecf
commit 46a9304ae1
4 changed files with 83 additions and 78 deletions

View File

@@ -1,20 +1,61 @@
Spree::TaxRate.class_eval do
class << self
def match_with_sales_tax_registration(order)
return [] if order.distributor && !order.distributor.charges_sales_tax
match_without_sales_tax_registration(order)
module Spree
TaxRate.class_eval do
class << self
def match_with_sales_tax_registration(order)
return [] if order.distributor && !order.distributor.charges_sales_tax
match_without_sales_tax_registration(order)
end
alias_method_chain :match, :sales_tax_registration
end
alias_method_chain :match, :sales_tax_registration
end
def adjust_with_included_tax(order)
adjust_without_included_tax(order)
def adjust_with_included_tax(order)
adjust_without_included_tax(order)
order.reload
(order.adjustments.tax + order.price_adjustments).each do |a|
a.set_absolute_included_tax! a.amount
order.reload
(order.adjustments.tax + order.price_adjustments).each do |a|
a.set_absolute_included_tax! a.amount
end
end
alias_method_chain :adjust, :included_tax
# Manually apply a TaxRate to a particular amount. TaxRates normally compute against
# LineItems or Orders, so we mock out a line item here to fit the interface
# that our calculator (usually DefaultTax) expects.
def compute_tax(amount)
product = OpenStruct.new tax_category: tax_category
line_item = LineItem.new quantity: 1
line_item.define_singleton_method(:product) { product }
line_item.define_singleton_method(:price) { amount }
# Tax on adjustments (represented by the included_tax field) is always inclusive of
# tax. However, there's nothing to stop an admin from setting one up with a tax rate
# that's marked as not inclusive of tax, and that would result in the DefaultTax
# calculator generating a slightly incorrect value. Therefore, we treat the tax
# rate as inclusive of tax for the calculations below, regardless of its original
# setting.
with_tax_included_in_price do
calculator.compute line_item
end
end
private
def with_tax_included_in_price
old_included_in_price = self.included_in_price
self.included_in_price = true
calculator.calculable.included_in_price = true
result = yield
# TODO: ensure
self.included_in_price = old_included_in_price
calculator.calculable.included_in_price = old_included_in_price
result
end
end
alias_method_chain :adjust, :included_tax
end

View File

@@ -35,43 +35,8 @@ module OpenFoodNetwork
tax_rates = enterprise_fee.tax_category ? enterprise_fee.tax_category.tax_rates.match(order) : []
tax_rates.sum do |rate|
compute_tax rate, adjustment.amount
rate.compute_tax adjustment.amount
end
end
# Apply a TaxRate to a particular amount. TaxRates normally compute against
# LineItems or Orders, so we mock out a line item here to fit the interface
# that our calculator (usually DefaultTax) expects.
def compute_tax(tax_rate, amount)
product = OpenStruct.new tax_category: tax_rate.tax_category
line_item = Spree::LineItem.new quantity: 1
line_item.define_singleton_method(:product) { product }
line_item.define_singleton_method(:price) { amount }
# The enterprise fee adjustments for which we're calculating tax are always inclusive of
# tax. However, there's nothing to stop an admin from setting one up with a tax rate
# that's marked as not inclusive of tax, and that would result in the DefaultTax
# calculator generating a slightly incorrect value. Therefore, we treat the tax
# rate as inclusive of tax for the calculations below, regardless of its original
# setting.
with_tax_included_in_price(tax_rate) do
tax_rate.calculator.compute line_item
end
end
def with_tax_included_in_price(tax_rate)
old_included_in_price = tax_rate.included_in_price
tax_rate.included_in_price = true
tax_rate.calculator.calculable.included_in_price = true
result = yield
tax_rate.included_in_price = old_included_in_price
tax_rate.calculator.calculable.included_in_price = old_included_in_price
result
end
end
end

View File

@@ -65,33 +65,4 @@ module OpenFoodNetwork
efa.send(:order_adjustment_label).should == "Whole order - packing fee by distributor Ballantyne"
end
end
describe "ensuring that tax rate is marked as tax included_in_price" do
let(:efa) { EnterpriseFeeApplicator.new nil, nil, nil }
let(:tax_rate) { create(:tax_rate, included_in_price: false, calculator: Spree::Calculator::DefaultTax.new) }
it "sets included_in_price to true" do
efa.send(:with_tax_included_in_price, tax_rate) do
tax_rate.included_in_price.should be_true
end
end
it "sets the included_in_price value accessible to the calculator to true" do
efa.send(:with_tax_included_in_price, tax_rate) do
tax_rate.calculator.calculable.included_in_price.should be_true
end
end
it "passes through the return value of the block" do
efa.send(:with_tax_included_in_price, tax_rate) do
'asdf'
end.should == 'asdf'
end
it "restores both values to their original afterwards" do
efa.send(:with_tax_included_in_price, tax_rate) {}
tax_rate.included_in_price.should be_false
tax_rate.calculator.calculable.included_in_price.should be_false
end
end
end

View File

@@ -29,5 +29,33 @@ module Spree
end
end
end
describe "ensuring that tax rate is marked as tax included_in_price" do
let(:tax_rate) { create(:tax_rate, included_in_price: false, calculator: Spree::Calculator::DefaultTax.new) }
it "sets included_in_price to true" do
tax_rate.send(:with_tax_included_in_price) do
tax_rate.included_in_price.should be_true
end
end
it "sets the included_in_price value accessible to the calculator to true" do
tax_rate.send(:with_tax_included_in_price) do
tax_rate.calculator.calculable.included_in_price.should be_true
end
end
it "passes through the return value of the block" do
tax_rate.send(:with_tax_included_in_price) do
'asdf'
end.should == 'asdf'
end
it "restores both values to their original afterwards" do
tax_rate.send(:with_tax_included_in_price) {}
tax_rate.included_in_price.should be_false
tax_rate.calculator.calculable.included_in_price.should be_false
end
end
end
end