mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-27 01:43:22 +00:00
Correct calculation of tax on EnterpriseFees with TaxRates where included_in_price=false
This commit is contained in:
39
app/models/spree/calculator/default_tax_decorator.rb
Normal file
39
app/models/spree/calculator/default_tax_decorator.rb
Normal file
@@ -0,0 +1,39 @@
|
||||
require 'open_food_network/enterprise_fee_calculator'
|
||||
|
||||
Spree::Calculator::DefaultTax.class_eval do
|
||||
|
||||
private
|
||||
|
||||
# Override this method to enable calculation of tax for
|
||||
# enterprise fees with tax rates where included_in_price = false
|
||||
def compute_order(order)
|
||||
matched_line_items = order.line_items.select do |line_item|
|
||||
line_item.product.tax_category == rate.tax_category
|
||||
end
|
||||
|
||||
line_items_total = matched_line_items.sum(&:total)
|
||||
|
||||
# Added this line
|
||||
calculator = OpenFoodNetwork::EnterpriseFeeCalculator.new(order.distributor, order.order_cycle)
|
||||
|
||||
# Added this block, finds relevant fees for each line_item, calculates the tax on them, and returns the total tax
|
||||
per_item_fees_total = order.line_items.sum do |line_item|
|
||||
calculator.send(:per_item_enterprise_fee_applicators_for, line_item.variant)
|
||||
.select { |applicator| applicator.enterprise_fee.tax_category == rate.tax_category }
|
||||
.sum { |applicator| applicator.enterprise_fee.compute_amount(line_item) }
|
||||
end
|
||||
|
||||
# Added this block, finds relevant fees for whole order, calculates the tax on them, and returns the total tax
|
||||
per_order_fees_total = calculator.send(:per_order_enterprise_fee_applicators_for, order)
|
||||
.select { |applicator| applicator.enterprise_fee.tax_category == rate.tax_category }
|
||||
.sum { |applicator| applicator.enterprise_fee.compute_amount(order) }
|
||||
|
||||
# round_to_two_places(line_items_total * rate.amount) # Removed this line
|
||||
|
||||
# Added this block
|
||||
[line_items_total, per_item_fees_total, per_order_fees_total].sum do |total|
|
||||
round_to_two_places(total * rate.amount)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -34,7 +34,7 @@ module OpenFoodNetwork
|
||||
def adjustment_tax(order, adjustment)
|
||||
tax_rates = enterprise_fee.tax_category ? enterprise_fee.tax_category.tax_rates.match(order) : []
|
||||
|
||||
tax_rates.sum do |rate|
|
||||
tax_rates.select(&:included_in_price).sum do |rate|
|
||||
rate.compute_tax adjustment.amount
|
||||
end
|
||||
end
|
||||
|
||||
@@ -137,21 +137,25 @@ module Spree
|
||||
context "when enterprise fees are taxed per-order" do
|
||||
let(:enterprise_fee) { create(:enterprise_fee, enterprise: coordinator, tax_category: tax_category, calculator: Calculator::FlatRate.new(preferred_amount: 50.0)) }
|
||||
|
||||
it "records the tax on the enterprise fee adjustments" do
|
||||
# The fee is $50, tax is 10%, and the fee is inclusive of tax
|
||||
# Therefore, the included tax should be 0.1/1.1 * 50 = $4.55
|
||||
describe "when the tax rate includes the tax in the price" do
|
||||
it "records the tax on the enterprise fee adjustments" do
|
||||
# The fee is $50, tax is 10%, and the fee is inclusive of tax
|
||||
# Therefore, the included tax should be 0.1/1.1 * 50 = $4.55
|
||||
|
||||
adjustment.included_tax.should == 4.55
|
||||
adjustment.included_tax.should == 4.55
|
||||
end
|
||||
end
|
||||
|
||||
describe "when the tax rate does not include the tax in the price" do
|
||||
before do
|
||||
tax_rate.update_attribute :included_in_price, false
|
||||
order.create_tax_charge! # Updating line_item or order has the same effect
|
||||
order.update_distribution_charge!
|
||||
end
|
||||
|
||||
it "treats it as inclusive anyway" do
|
||||
adjustment.included_tax.should == 4.55
|
||||
it "records the tax on TaxRate adjustment on the order" do
|
||||
adjustment.included_tax.should == 0
|
||||
order.adjustments.tax.first.amount.should == 5.0
|
||||
end
|
||||
end
|
||||
|
||||
@@ -172,8 +176,23 @@ module Spree
|
||||
context "when enterprise fees are taxed per-item" do
|
||||
let(:enterprise_fee) { create(:enterprise_fee, enterprise: coordinator, tax_category: tax_category, calculator: Calculator::PerItem.new(preferred_amount: 50.0)) }
|
||||
|
||||
it "records the tax on the enterprise fee adjustments" do
|
||||
adjustment.included_tax.should == 4.55
|
||||
describe "when the tax rate includes the tax in the price" do
|
||||
it "records the tax on the enterprise fee adjustments" do
|
||||
adjustment.included_tax.should == 4.55
|
||||
end
|
||||
end
|
||||
|
||||
describe "when the tax rate does not include the tax in the price" do
|
||||
before do
|
||||
tax_rate.update_attribute :included_in_price, false
|
||||
order.create_tax_charge! # Updating line_item or order has the same effect
|
||||
order.update_distribution_charge!
|
||||
end
|
||||
|
||||
it "records the tax on TaxRate adjustment on the order" do
|
||||
adjustment.included_tax.should == 0
|
||||
order.adjustments.tax.first.amount.should == 5.0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user