Skip to content

Commit c2cd061

Browse files
Noah-SilveraadammathysAlistairNormanforkataHarmony Bouvier
authored andcommitted
Mark adjustments for removal in OrderTaxation
Instead of actually destroying adjustments in the OrderTaxation class, we can just mark them for removal. This will allow them to be removed when the order is persisted, instead of being removed during the recalculate process. This is an improvement in service of recalculating order changes without writing to the database. We also need to ensure `Order#adjustments` association has autosave enabled so that the marked for destruction adjustments are removed when we persist the order. We're also improving our OrderUpdater tests to better verify our changes maintain the existing behaviour. Co-authored-by: Adam Mueller <[email protected]> Co-authored-by: Alistair Norman <[email protected]> Co-authored-by: Chris Todorov <[email protected]> Co-authored-by: Harmony Bouvier <[email protected]> Co-authored-by: Kendra Riga <[email protected]> Co-authored-by: Senem Soy <[email protected]> Co-authored-by: Sofia Besenski <[email protected]> Co-authored-by: benjamin wil <[email protected]>
1 parent 5979f25 commit c2cd061

File tree

5 files changed

+84
-17
lines changed

5 files changed

+84
-17
lines changed

core/app/models/spree/order.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ def states
102102
has_many :cartons, -> { distinct }, through: :inventory_units
103103

104104
# Adjustments and promotions
105-
has_many :adjustments, -> { order(:created_at) }, as: :adjustable, inverse_of: :adjustable, dependent: :destroy
105+
has_many :adjustments, -> { order(:created_at) }, as: :adjustable, inverse_of: :adjustable, dependent: :destroy, autosave: true
106106
has_many :line_item_adjustments, through: :line_items, source: :adjustments
107107
has_many :shipment_adjustments, through: :shipments, source: :adjustments
108108
has_many :all_adjustments,

core/app/models/spree/order_taxation.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def update_adjustments(item, taxed_items)
5757

5858
# Remove any tax adjustments tied to rates which no longer match.
5959
unmatched_adjustments = tax_adjustments - active_adjustments
60-
item.adjustments.destroy(unmatched_adjustments)
60+
unmatched_adjustments.each(&:mark_for_destruction)
6161
end
6262

6363
# Update or create a new tax adjustment on an item.

core/app/models/spree/order_updater.rb

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,12 @@ def update_adjustment_total
157157
recalculate_adjustments
158158

159159
all_items = line_items + shipments
160-
order_tax_adjustments = adjustments.select(&:tax?)
160+
# Ignore any adjustments that have been marked for destruction in our
161+
# calculations. They'll get removed when/if we persist the order.
162+
valid_adjustments = adjustments.reject(&:marked_for_destruction?)
163+
order_tax_adjustments = valid_adjustments.select(&:tax?)
161164

162-
order.adjustment_total = all_items.sum(&:adjustment_total) + adjustments.sum(&:amount)
165+
order.adjustment_total = all_items.sum(&:adjustment_total) + valid_adjustments.sum(&:amount)
163166
order.included_tax_total = all_items.sum(&:included_tax_total) + order_tax_adjustments.select(&:included?).sum(&:amount)
164167
order.additional_tax_total = all_items.sum(&:additional_tax_total) + order_tax_adjustments.reject(&:included?).sum(&:amount)
165168

core/spec/models/spree/order_taxation_spec.rb

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -132,12 +132,11 @@
132132
)
133133
end
134134

135-
it "removes the tax adjustment" do
136-
expect {
137-
taxation.apply(new_taxes)
138-
}.to change {
139-
line_item.adjustments.size
140-
}.from(1).to(0)
135+
it "marks the tax adjustment for destruction" do
136+
order.save!
137+
taxation.apply(new_taxes)
138+
139+
expect(line_item.adjustments.first).to be_marked_for_destruction
141140
end
142141
end
143142

core/spec/models/spree/order_updater_spec.rb

Lines changed: 72 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,28 +69,39 @@ module Spree
6969
end
7070

7171
describe 'tax recalculation' do
72-
let!(:ship_address) { create(:address) }
73-
let!(:tax_zone) { create(:global_zone) } # will include the above address
74-
let!(:tax_rate) { create(:tax_rate, zone: tax_zone, tax_categories: [tax_category]) }
72+
let(:tax_category) { create(:tax_category) }
73+
let(:ship_address) { create(:address, state: new_york) }
74+
let(:new_york) { create(:state, state_code: "NY") }
75+
let(:tax_zone) { create(:zone, states: [new_york]) }
76+
77+
let!(:tax_rate) do
78+
create(
79+
:tax_rate,
80+
name: "New York Sales Tax",
81+
tax_categories: [tax_category],
82+
zone: tax_zone,
83+
included_in_price: false,
84+
amount: 0.1
85+
)
86+
end
7587

7688
let(:order) do
7789
create(
7890
:order_with_line_items,
79-
line_items_attributes: [{ price: 10, variant: }],
80-
ship_address:,
91+
line_items_attributes: [{ price: 10, variant: variant }],
92+
ship_address: ship_address,
8193
)
8294
end
8395
let(:line_item) { order.line_items[0] }
8496

8597
let(:variant) { create(:variant, tax_category:) }
86-
let(:tax_category) { create(:tax_category) }
8798

8899
context 'when the item quantity has changed' do
89100
before do
90101
line_item.update!(quantity: 2)
91102
end
92103

93-
it 'updates the promotion amount' do
104+
it 'updates the additional_tax_total' do
94105
expect {
95106
order.recalculate
96107
}.to change {
@@ -99,6 +110,60 @@ module Spree
99110
end
100111
end
101112

113+
context 'when the address has changed to a different state' do
114+
let(:new_shipping_address) { create(:address) }
115+
116+
before do
117+
order.ship_address = new_shipping_address
118+
end
119+
120+
it 'removes the old taxes' do
121+
expect {
122+
order.recalculate
123+
}.to change {
124+
order.all_adjustments.tax.count
125+
}.from(1).to(0)
126+
127+
expect(order.additional_tax_total).to eq 0
128+
expect(order.adjustment_total).to eq 0
129+
end
130+
end
131+
132+
context "with an order-level tax adjustment" do
133+
let(:colorado) { create(:state, state_code: "CO") }
134+
let(:colorado_tax_zone) { create(:zone, states: [colorado]) }
135+
let(:ship_address) { create(:address, state: colorado) }
136+
137+
let!(:colorado_delivery_fee) do
138+
create(
139+
:tax_rate,
140+
amount: 0.27,
141+
calculator: Spree::Calculator::FlatFee.new,
142+
level: "order",
143+
name: "Colorado Delivery Fee",
144+
tax_categories: [tax_category],
145+
zone: colorado_tax_zone
146+
)
147+
end
148+
149+
before { order.recalculate }
150+
151+
it "updates the order-level tax adjustment" do
152+
expect {
153+
order.ship_address = create(:address)
154+
order.recalculate
155+
}.to change { order.additional_tax_total }.from(0.27).to(0).
156+
and change { order.adjustment_total }.from(0.27).to(0)
157+
end
158+
159+
it "deletes the order-level tax adjustments when it persists the order" do
160+
expect {
161+
order.ship_address = create(:address)
162+
order.recalculate
163+
}.to change { order.all_adjustments.count }.from(1).to(0)
164+
end
165+
end
166+
102167
context 'with a custom tax_calculator_class' do
103168
let(:custom_calculator_class) { double }
104169
let(:custom_calculator_instance) { double }

0 commit comments

Comments
 (0)