Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include adjustments with negative taxes on Sales Tax reports #5492

Conversation

pacodelaluna
Copy link
Contributor

What? Why?

Closes #5428

On Sales Tax reports, with the Tax Rates filter, you can see that the tax is not managed when an adjustment is negative. This was because we were not including negative tax rate in the calculation, so I just removed the scope applying this filter.

What should we test?

Add a negative adjustment on an order. Then go on /admin/reports/sales_tax, select the Tax Rates filter, then control that you can see the negative amount for the tax.

Release notes

  • Deal with negative tax amounts for adjustments on Sales Tax reports

Changelog Category: Changed

@pacodelaluna pacodelaluna changed the title Include adjustments without positive taxes Include adjustments with negative taxes on Sales Tax reports May 24, 2020
Spree::Money.new(tax_amount, currency: currency)]
end]
end

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is not used anywhere.

Copy link
Contributor

@luisramos0 luisramos0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR François!

It's great to see some of this code go 🎉 price_adjustment_totals

I am not sure if this change is correct. You may be adding zero value entries in some reports? Or even in the invoices where these methods are used?
I think this change requires at least new unit tests, ideally feature specs would cover the report and the order invoices (the 2 parts that use this code).

I have an idea: you could extract this tax_adjustment_totals and tax_adjustments methods to a separate service.
You could move these two methods to a service under app/services called OrderTaxAdjustments
with only one public method OrderTaxAdjustments.totals
The method tax_adjustments can be private.
You would need to update app/helpers/checkout_helper.rb and the sales tax report to do
OrderTaxAdjustments.new(order).totals
instead of
order.tax_adjustment_totals

This would enable you to copy the related specs in spec/models/spree/order_spec.rb to a separate service unit test file and add more tests for the new cases (zero included tax and negative included tax).

I hope this makes sense to you.

end

def tax_adjustment_totals
tax_adjustments.each_with_object({}) do |adjustment, hash|
# No need of dealing with a missing Tax Rate if no tax setup
next if adjustment.included_tax.zero?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

included_tax means that there is no included tax in the adjustment amount but some adjustments may have tax that is not included!?
in that case you would need to go forward in the method and still use the tax that is not included?

@@ -305,12 +305,14 @@ def total_tax
end

def tax_adjustments
adjustments.with_tax +
line_items.includes(:adjustments).map { |li| li.adjustments.with_tax }.flatten
adjustments + price_adjustments
Copy link
Contributor

@luisramos0 luisramos0 May 25, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you want to include negatives you can change the scope to include negatives
scope :with_tax, -> { where('spree_adjustments.included_tax > 0') }

but here you are just including all adjustments, including the ones with zero tax. that means the method becomes non-sense where tax_adjustments returns all adjustments.

I think you want to keep the method as tax_adjustment but exclude included_tax ZERO.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you are right, I was not thinking of this case, and it will also solve the comment you put above for adjustment.included_tax.zero? control. I will fix this, need to cross-check side effect related to this scope use.

@pacodelaluna
Copy link
Contributor Author

@luisramos0 Thanks for your feedback, I will take a look at it this weekend, extract the logic into a service makes sense yes.

@pacodelaluna
Copy link
Contributor Author

@luisramos0 Sorry I was busy lately but I have refactored the code within a service. I have changed the scope to now include also the negative tax values, there will be a side effect but I think it is a desired effect. Tell me if any issue.

Copy link
Contributor

@luisramos0 luisramos0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice, I think this is correct 👍

def all
order.adjustments.with_tax +
order.line_items.includes(:adjustments).map { |li|
li.adjustments.with_tax
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason why we can't merge the AR relation at line 24 with this with_tax scope? otherwise, we'll be causing N+1 again. I bet we can fetch both order and line item adjustments in a single query, which would be the best in term of performance.

def totals
all.each_with_object({}) do |adjustment, hash|
tax_rates_hash = tax_rates_hash(adjustment)
hash.update(tax_rates_hash) { |_tax_rate, amount1, amount2| amount1 + amount2 }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm being picky here but I'd lean towards #merge instead of #update for readability purposes. They are synonyms, right? I didn't even know #update existed and I had to look it up to tell whether it belonged to AR or Ruby. Feel free to dismiss though.

Copy link
Contributor

@sauloperez sauloperez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm moving this to Test Ready but I'm already checking whether we are affecting performance too much. I don't know yet if we made it worse or not. Meanwhile, we can check the behavior is right and prepare a patch later if needed.

@sauloperez
Copy link
Contributor

sauloperez commented Jun 11, 2020

it doesn't look good. Using PROFILE and assets compiled:

from master:

Screenshot from 2020-06-11 12-12-42

from this branch:

Screenshot from 2020-06-11 12-13-14

@sauloperez sauloperez self-assigned this Jun 11, 2020
@pacodelaluna
Copy link
Contributor Author

pacodelaluna commented Jun 11, 2020

@sauloperez Oh ok, I am a bit surprised about this performance issue as I thought I was mostly moving code in the PR. I will take a deeper look this weekend, I saw that there was an other service, OrderAdjustmentsFetcher, I initially didn't want to add too much refactoring but it seems we really need it...

@sauloperez
Copy link
Contributor

sauloperez commented Jun 11, 2020

I'm pretty sure the problem is scoped within OrderTaxAdjustmentsFetcher#all. Surely can be refactored to a single query starting from Spree:Adjustment.

EDIT I'm not sure those numbers are totally accurate because I can't reproduce them exactly now but there's definitely an N+1 there.

@sauloperez
Copy link
Contributor

sauloperez commented Jun 12, 2020

@pacodelaluna I gave it a try and added a couple of commits. Take a look at them and let me know what you think. They remove the N+1 and effectively fetch the adjustments in one shot.

There is at least one more N+1 related to adjustments in this report but this PR brings already a better world. It'll be easier to tackle once this is shipped.

@pacodelaluna
Copy link
Contributor Author

@sauloperez Great job! Thanks for your help on this!

Copy link
Contributor

@luisramos0 luisramos0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice one.

@sigmundpetersen
Copy link
Contributor

The conflict on this branch needs to be resolved before testing. A rebase would be good?

@pacodelaluna pacodelaluna force-pushed the include-negative-tax-adjustments-in-sales-report branch from 6b8e278 to ff4d7fb Compare June 16, 2020 12:02
@pacodelaluna
Copy link
Contributor Author

@sigmundpetersen Just did the rebase, should be fine for testing.

Copy link
Contributor

@luisramos0 luisramos0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, the problem was that price_adjustments disappeared in spree 2.1
you could replace price_adjustments with the new order.line_item_adjustments
but that's out of scope here.

@filipefurtad0
Copy link
Contributor

Hey @pacodelaluna!

I checked/reproduced what @RachL described in the issue. So, placed order R006812641, which can be seen in Tax Rates report:

image

Below, the same order, after adjustment with the amount £-20.00 (£-3.33 included tax):
image

After this PR the report is rendered with the correct values:
image

Awesome, thanks Paco 🎉
Ready to go.

PS: I found that clicking on that order-hyperlink leads to /admin/orders/R006812641 -> which is neither related to this PR nor to the upgrade - checked on staging-es as well. Opening a separate issue.

@filipefurtad0 filipefurtad0 added the pr-staged-uk staging.openfoodnetwork.org.uk label Jun 16, 2020
@filipefurtad0 filipefurtad0 self-assigned this Jun 16, 2020
@filipefurtad0 filipefurtad0 removed the pr-staged-uk staging.openfoodnetwork.org.uk label Jun 16, 2020
@luisramos0 luisramos0 merged commit 01e27dd into openfoodfoundation:master Jun 16, 2020
@pacodelaluna pacodelaluna deleted the include-negative-tax-adjustments-in-sales-report branch March 21, 2021 17:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Sales tax report is showing amounts per types without adjustments
5 participants