diff --git a/app/services/tax_rate_finder.rb b/app/services/tax_rate_finder.rb index 59d24dd052..a1b61bb406 100644 --- a/app/services/tax_rate_finder.rb +++ b/app/services/tax_rate_finder.rb @@ -8,16 +8,13 @@ class TaxRateFinder def self.tax_rates_of(adjustment) new.tax_rates( adjustment.originator, - adjustment.adjustable, - adjustment.amount, - adjustment.included_tax + adjustment.adjustable ) end # @return [Array] - def tax_rates(originator, adjustable, amount, included_tax) - find_associated_tax_rate(originator, adjustable) || - find_closest_tax_rates_from_included_tax(amount, included_tax) + def tax_rates(originator, adjustable) + find_associated_tax_rate(originator, adjustable) end private @@ -48,37 +45,4 @@ class TaxRateFinder enterprise_fee.tax_category end end - - # There are two cases in which a line item is not associated to a tax rate. - # - # 1. Shipping fees and adjustments created from the admin panel have taxes set - # at creation in the included_tax field without relation to the - # corresponding TaxRate. - # 2. Removing line items from an order doesn't always remove the associated - # enterprise fees. These orphaned fees don't have a line item any more to - # find the item's tax rate. - # - # In these cases we try to find the used tax rate based on the included tax. - # For example, if the included tax is 10% of the adjustment, we look for a tax - # rate of 10%. Due to rounding errors, the included tax may be 9.9% of the - # adjustment. That's why we call it an approximation of the tax rate and look - # for the closest and hopefully find the 10% tax rate. - # - # This attempt can fail. - # - # - If an admin created an adjustment with a miscalculated included tax then - # we don't know which tax rate the admin intended to use. - # - An admin may also enter included tax that doesn't correspond to any tax - # rate in the system. They may enter a fee of $1.2 with tax of $0.2, but - # that doesn't mean that there is a 20% tax rate in the database. - # - The used tax rate may also have been deleted. Maybe the tax law changed. - # - # In either of these cases, we will find a tax rate that doesn't correspond - # to the included tax. - def find_closest_tax_rates_from_included_tax(amount, included_tax) - approximation = (included_tax / (amount - included_tax)) - return [] if approximation.infinite? || approximation.zero? || approximation.nan? - - [Spree::TaxRate.order(Arel.sql("ABS(amount - #{approximation})")).first] - end end diff --git a/spec/services/tax_rate_finder_spec.rb b/spec/services/tax_rate_finder_spec.rb index b7bb07db73..1c1abe425a 100644 --- a/spec/services/tax_rate_finder_spec.rb +++ b/spec/services/tax_rate_finder_spec.rb @@ -5,61 +5,33 @@ require 'spec_helper' describe TaxRateFinder do describe "getting the corresponding tax rate" do let(:amount) { BigDecimal(120) } - let(:included_tax) { BigDecimal(20) } let(:tax_rate) { create_rate(0.2) } let(:tax_category) { create(:tax_category, tax_rates: [tax_rate]) } let(:zone) { create(:zone_with_member) } let(:shipment) { create(:shipment) } + let(:line_item) { create(:line_item) } let(:enterprise_fee) { create(:enterprise_fee, tax_category: tax_category) } let(:order) { create(:order_with_taxes, zone: zone) } it "finds the tax rate of a shipping fee" do - rates = TaxRateFinder.new.tax_rates( - tax_rate, - shipment, - amount, - included_tax - ) + rates = TaxRateFinder.new.tax_rates(tax_rate, shipment) expect(rates).to eq [tax_rate] end - it "finds a close match" do + it "deals with soft-deleted tax rates" do tax_rate.destroy - close_tax_rate = create_rate(tax_rate.amount + 0.05) - # other tax rates, not as close to the real one - create_rate(tax_rate.amount + 0.06) - create_rate(tax_rate.amount - 0.06) - - rates = TaxRateFinder.new.tax_rates( - nil, - shipment, - amount, - included_tax - ) - - expect(rates).to eq [close_tax_rate] + rates = TaxRateFinder.new.tax_rates(tax_rate, shipment) + expect(rates).to eq [tax_rate] end it "finds the tax rate of an enterprise fee" do - rates = TaxRateFinder.new.tax_rates( - enterprise_fee, - order, - amount, - included_tax - ) + rates = TaxRateFinder.new.tax_rates(enterprise_fee, order) expect(rates).to eq [tax_rate] end - # There is a bug that leaves orphan adjustments on an order after - # associated line items have been removed. - # https://github.com/openfoodfoundation/openfoodnetwork/issues/3127 - it "deals with a missing line item" do - rates = TaxRateFinder.new.tax_rates( - enterprise_fee, - nil, - amount, - included_tax - ) + it "deals with a soft-deleted line item" do + line_item.destroy + rates = TaxRateFinder.new.tax_rates(enterprise_fee, line_item) expect(rates).to eq [tax_rate] end