diff --git a/core/app/models/spree/tax/item_adjuster.rb b/core/app/models/spree/tax/item_adjuster.rb index 0ac66e17e19..37a862934dd 100644 --- a/core/app/models/spree/tax/item_adjuster.rb +++ b/core/app/models/spree/tax/item_adjuster.rb @@ -22,14 +22,10 @@ def initialize(item, options = {}) # Deletes all existing tax adjustments and creates new adjustments for all # (geographically and category-wise) applicable tax rates. - # - # @return [Array] newly created adjustments def adjust! - return unless order.tax_address.country_id - item.adjustments.destroy(item.adjustments.select(&:tax?)) - rates_for_item(item).map { |rate| rate.adjust(nil, item) } + rates_for_item(item).each { |rate| rate.adjust(nil, item) } end end end diff --git a/core/app/models/spree/tax/order_adjuster.rb b/core/app/models/spree/tax/order_adjuster.rb index 7b49dfb6244..d5fd91bcfbe 100644 --- a/core/app/models/spree/tax/order_adjuster.rb +++ b/core/app/models/spree/tax/order_adjuster.rb @@ -14,8 +14,6 @@ def initialize(order) # Creates tax adjustments for all taxable items (shipments and line items) # in the given order. def adjust! - return unless order.tax_address.country_id - (order.line_items + order.shipments).each do |item| ItemAdjuster.new(item, order_wide_options).adjust! end diff --git a/core/spec/models/spree/tax/item_adjuster_spec.rb b/core/spec/models/spree/tax/item_adjuster_spec.rb index 419e1a9da34..6ef3b28647d 100644 --- a/core/spec/models/spree/tax/item_adjuster_spec.rb +++ b/core/spec/models/spree/tax/item_adjuster_spec.rb @@ -3,7 +3,11 @@ RSpec.describe Spree::Tax::ItemAdjuster do subject(:adjuster) { described_class.new(item) } let(:order) { create(:order) } - let(:item) { Spree::LineItem.new(order: order) } + let(:item) { create(:line_item, order: order) } + + def tax_adjustments + item.adjustments.tax.to_a + end describe 'initialization' do it 'sets order to item order' do @@ -15,6 +19,25 @@ end end + shared_examples_for 'untaxed item' do + it 'creates no adjustments' do + adjuster.adjust! + expect(tax_adjustments).to eq([]) + end + + context 'with an existing tax adjustment' do + let!(:existing_adjustment) { create(:tax_adjustment, adjustable: item) } + + it 'removes the existing adjustment' do + adjuster.adjust! + aggregate_failures do + expect(tax_adjustments).to eq([]) + expect(Spree::Adjustment).to_not be_exists(existing_adjustment.id) + end + end + end + end + describe '#adjust!' do before do expect(order).to receive(:tax_address).at_least(:once).and_return(address) @@ -23,16 +46,10 @@ context 'when the order has no tax zone' do let(:address) { Spree::Tax::TaxLocation.new } - before do - adjuster.adjust! - end - - it 'returns nil early' do - expect(adjuster.adjust!).to be_nil - end + it_behaves_like 'untaxed item' end - context 'when the order has an address thats taxable' do + context 'when the order has a taxable address' do let(:item) { build_stubbed :line_item, order: order } let(:address) { order.tax_address } @@ -43,9 +60,7 @@ context 'when there are no matching rates' do let(:rates_for_order_zone) { [] } - it 'returns no adjustments' do - expect(adjuster.adjust!).to eq([]) - end + it_behaves_like 'untaxed item' end context 'when there are matching rates for the zone' do @@ -58,7 +73,8 @@ before { allow(item).to receive(:tax_category).and_return(item_tax_category) } it 'creates an adjustment for every matching rate' do - expect(adjuster.adjust!.length).to eq(1) + adjuster.adjust! + expect(tax_adjustments.length).to eq(1) end end end diff --git a/core/spec/models/spree/tax/taxation_integration_spec.rb b/core/spec/models/spree/tax/taxation_integration_spec.rb index df7095bd035..48f802ec7a8 100644 --- a/core/spec/models/spree/tax/taxation_integration_spec.rb +++ b/core/spec/models/spree/tax/taxation_integration_spec.rb @@ -624,6 +624,25 @@ federal_books_tax.destroy! expect(line_item.adjustments.count).to eq(2) end + + context 'when tax address is later cleared' do + before do + order.ship_address = nil + order.update! + end + + it 'removes all tax adjustments' do + aggregate_failures do + expect(line_item.adjustments.tax.count).to eq(0) + expect(line_item).to have_attributes( + price: 20, + total: 20, + included_tax_total: 0, + additional_tax_total: 0 + ) + end + end + end end context 'an order with a book and a shipment' do