Skip to content

Commit 43d7029

Browse files
Noah-SilveraforkataadammathysAlistairNormanbenjaminwil
committed
Make OrderTaxation mark adjustments for removal
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 does have the side effect of needing to check for tax adjustments that are marked for destruction when calculating tax totals elsewhere in the OrderUpdaters Co-authored-by: Chris Todorov <chris@super.gd> Co-authored-by: Adam Mueller <adam@super.gd> Co-authored-by: Alistair Norman <alistair@super.gd> Co-authored-by: benjamin wil <benjamin@super.gd> Co-authored-by: Harmony Bouvier <harmony@super.gd> Co-authored-by: Kendra Riga <kendra@super.gd> Co-authored-by: Senem <senem@super.gd>
1 parent be95ef2 commit 43d7029

File tree

6 files changed

+67
-15
lines changed

6 files changed

+67
-15
lines changed

TODO.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ In-Memory Order Updater TODO
66
- [x] Add test coverage for `recalculate_item_total` when line item totals change
77
- [ ] Handle persistence in `update_promotions`
88
- [ ] Handle persistence in `update_taxes`
9+
- [ ] Scope handling of tax adjustments in `InMemoryOrderUpdater` and `OrderUpdater` to *not* marked for destruction
910
- [ ] Write the `InMemoryOrderAdjuster` (also, should we rename this to `InMemoryOrderPromotionAdjuster`)
1011

1112
- [ ] Test coverage to ensure state changes aren't persisted (if someone changes current implementation)

core/app/models/spree/in_memory_order_updater.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ def update_adjustment_total(persist:)
148148
update_adjustments(persist:)
149149

150150
all_items = line_items + shipments
151+
# FIXME: We will need to ignore tax adjustments marked for destruction here and maybe elsewhere
151152
order_tax_adjustments = adjustments.select(&:tax?)
152153

153154
order.adjustment_total = all_items.sum(&:adjustment_total) + adjustments.sum(&:amount)

core/app/models/spree/order_taxation.rb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,8 @@ def update_adjustments(item, taxed_items)
5656

5757
# Remove any tax adjustments tied to rates which no longer match.
5858
unmatched_adjustments = tax_adjustments - active_adjustments
59-
# FIXME: Find a way to not have to destroy for in-memory recalculating
60-
# https://api.rubyonrails.org/classes/ActiveRecord/AutosaveAssociation.html#method-i-mark_for_destruction
61-
item.adjustments.destroy(unmatched_adjustments)
59+
60+
unmatched_adjustments.each(&:mark_for_destruction)
6261
end
6362

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

core/app/models/spree/order_updater.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ def update_taxes
202202
Spree::Config.tax_adjuster_class.new(order).adjust!
203203

204204
[*line_items, *shipments].each do |item|
205+
# FIXME: We will need to ignore tax adjustments marked for destruction here and maybe elsewhere
205206
tax_adjustments = item.adjustments.select(&:tax?)
206207
# Tax adjustments come in not one but *two* exciting flavours:
207208
# Included & additional

core/spec/models/spree/in_memory_order_updater_spec.rb

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,21 @@ module Spree
147147
end
148148

149149
describe 'tax recalculation' do
150-
let!(:ship_address) { create(:address) }
151-
let!(:tax_zone) { create(:global_zone) } # will include the above address
152-
let!(:tax_rate) { create(:tax_rate, zone: tax_zone, tax_categories: [tax_category]) }
150+
let(:tax_category) { create(:tax_category) }
151+
let(:ship_address) { create(:address, state: new_york) }
152+
let(:new_york) { create(:state, state_code: "NY") }
153+
let(:tax_zone) { create(:zone, states: [new_york]) }
154+
155+
let!(:tax_rate) do
156+
create(
157+
:tax_rate,
158+
name: "New York Sales Tax",
159+
tax_categories: [tax_category],
160+
zone: tax_zone,
161+
included_in_price: false,
162+
amount: 0.05
163+
)
164+
end
153165

154166
let(:order) do
155167
create(
@@ -161,22 +173,37 @@ module Spree
161173
let(:line_item) { order.line_items[0] }
162174

163175
let(:variant) { create(:variant, tax_category: tax_category) }
164-
let(:tax_category) { create(:tax_category) }
165176

166177
context 'when the item quantity has changed' do
167178
before do
168179
line_item.update!(quantity: 2)
169180
end
170181

171-
it 'updates the promotion amount' do
182+
it 'updates the additional tax total' do
172183
expect {
173184
order.recalculate
174185
}.to change {
175-
line_item.additional_tax_total
186+
line_item.reload.additional_tax_total
176187
}.from(1).to(2)
177188
end
178189

179190
context "when recalculating the order in memory" do
191+
it "does not persist the tax totals" do
192+
expect {
193+
described_class.new(order).recalculate(persist: false)
194+
}.to change {
195+
line_item.additional_tax_total
196+
}.from(1).to(2)
197+
198+
expect(line_item.reload.additional_tax_total).to eq(1)
199+
end
200+
201+
it 'does not make manipulative queries' do
202+
expect {
203+
described_class.new(order).recalculate(persist: false)
204+
}.not_to make_database_queries(manipulative: true)
205+
end
206+
180207
it "raises an error" do
181208
order_adjuster = double
182209
allow(order_adjuster).to receive(:call) { raise NotImplementedError }
@@ -188,6 +215,30 @@ module Spree
188215
end
189216
end
190217

218+
context 'when the address has changed to a different state' do
219+
let(:new_shipping_address) { create(:address) }
220+
221+
before do
222+
order.ship_address = new_shipping_address
223+
end
224+
225+
it 'removes the old taxes' do
226+
expect {
227+
described_class.new(order).recalculate(persist: true)
228+
}.to change {
229+
order.all_adjustments.tax.count
230+
}.from(1).to(0)
231+
end
232+
233+
context "when the persist flag is set to 'false'" do
234+
it "doesn't make manipulative database queries" do
235+
expect {
236+
described_class.new(order).recalculate(persist: false)
237+
}.not_to make_database_queries(manipulative: true)
238+
end
239+
end
240+
end
241+
191242
context 'with a custom tax_calculator_class' do
192243
let(:custom_calculator_class) { double }
193244
let(:custom_calculator_instance) { double }

core/spec/models/spree/order_taxation_spec.rb

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,11 @@
116116
)
117117
end
118118

119-
it "removes the tax adjustment" do
120-
expect {
121-
taxation.apply(new_taxes)
122-
}.to change {
123-
line_item.adjustments.size
124-
}.from(1).to(0)
119+
it "marks the tax adjustment for destruction" do
120+
order.save!
121+
taxation.apply(new_taxes)
122+
123+
expect(line_item.adjustments.first).to be_marked_for_destruction
125124
end
126125
end
127126

0 commit comments

Comments
 (0)