-
-
Notifications
You must be signed in to change notification settings - Fork 730
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
[Vouchers] Fix tax included in price amount #11593
[Vouchers] Fix tax included in price amount #11593
Conversation
When tax are included in price, voucher tax is stored in the voucher adjustment and not as its own adjustment. So we add a "fake adjustment" for display purposes.
8493792
to
7f2c1fe
Compare
app/helpers/admin/orders_helper.rb
Outdated
adjustments_for_display = order.adjustments + order.all_adjustments.payment_fee.eligible | ||
|
||
if VoucherAdjustmentsService.new(order).voucher_included_tax.negative? | ||
adjustment = order.voucher_adjustments.first | ||
adjustments_for_display << Spree::Adjustment.new( | ||
label: I18n.t("admin.orders.edit.voucher_tax_included_in_price", label: adjustment.label), | ||
amount: adjustment.included_tax | ||
) | ||
end | ||
|
||
adjustments_for_display |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The whole if
block could have been somewhere else, e.g. the service and then this could be simpler:
adjustments_for_display = order.adjustments + order.all_adjustments.payment_fee.eligible | |
if VoucherAdjustmentsService.new(order).voucher_included_tax.negative? | |
adjustment = order.voucher_adjustments.first | |
adjustments_for_display << Spree::Adjustment.new( | |
label: I18n.t("admin.orders.edit.voucher_tax_included_in_price", label: adjustment.label), | |
amount: adjustment.included_tax | |
) | |
end | |
adjustments_for_display | |
voucher_service = VoucherAdjustmentsService.new(order) | |
order.adjustments + | |
order.all_adjustments.payment_fee.eligible + | |
voucher_service.included_tax_adjustment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice suggestion!
I'm uncomfortable with instantiating a new Adjustment here though; I think it could cause trouble (I can't think of any in the current circumstances, but circumstances could change). Or at least confusion.
The good thing is we don't need the model, just something like it. I suggest a struct would be enough to implement the label and amount values. As it's display-related logic, I would try to keep the logic here in the orders_helper, but perhaps in a private method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good fix.
I think it would be worth refactoring the helper though, what do you think?
app/helpers/admin/orders_helper.rb
Outdated
adjustments_for_display = order.adjustments + order.all_adjustments.payment_fee.eligible | ||
|
||
if VoucherAdjustmentsService.new(order).voucher_included_tax.negative? | ||
adjustment = order.voucher_adjustments.first | ||
adjustments_for_display << Spree::Adjustment.new( | ||
label: I18n.t("admin.orders.edit.voucher_tax_included_in_price", label: adjustment.label), | ||
amount: adjustment.included_tax | ||
) | ||
end | ||
|
||
adjustments_for_display |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice suggestion!
I'm uncomfortable with instantiating a new Adjustment here though; I think it could cause trouble (I can't think of any in the current circumstances, but circumstances could change). Or at least confusion.
The good thing is we don't need the model, just something like it. I suggest a struct would be enough to implement the label and amount values. As it's display-related logic, I would try to keep the logic here in the orders_helper, but perhaps in a private method.
subject(:display_checkout_tax_total) { helper.display_checkout_tax_total(order) } | ||
|
||
let(:order) { instance_double(Spree::Order, total_tax: 123.45, currency: 'AUD') } | ||
let(:service) { instance_double(VoucherAdjustmentsService, voucher_included_tax: ) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would have set up real data and used the real VoucherAdjustmentsService. What if the method VoucherAdjustmentsService#voucher_included_tax
go renamed one day, or returned a different value? This test would still pass.
But maybe that's just opinion :)
If it's because the test data is complicated to set up, then maybe we need to create a factory for it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instance_double
verifies that the methods are present. https://www.simplybusiness.co.uk/about-us/tech/2020/05/rspec-instance-doubles/
But in general I agree that mocking is to be avoided if possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I didn't know that!
We are not creating a new adjustment here.
The whole concept is confusing. Maybe translators will find better versions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great, thanks for doing this.
I agree that it's still confusing using a Struct. But I like how it's a bit clearer that it's not an actual adjustment, so I suggest we proceed this way.
However it looks like the adjustments for display are in the wrong order now, can you please check?
order.adjustments + | ||
voucher_included_tax_representations(order) + | ||
order.all_adjustments.payment_fee.eligible |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should voucher_included_tax_representations(order)
be the last one in the list? It looks like it was before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought that that was looking odd. It seems clearer to me to put the voucher tax under the voucher.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
Hi @rioug, I compared before and after staging and did some test shopping.
I have also tested:
All looking good! Excellent! 🎉 Thanks again! |
What? Why?
When tax are included in price, we store the tax part of the voucher in the voucher adjustment itself. The issue is, this value isn't displayed anywhere nor is it used to display the discount tax to the customer. This PR fix this.
In the case of tax excluded from price, we store the tax part of the voucher as its own adjustment, which are both displayed to the customer and in the backoffice, so we no fix is needed there.
What should we test?
Release notes
Changelog Category (reviewers may add a label for the release notes):
The title of the pull request will be included in the release notes.
Dependencies
Based on #11543, it will need to be merged first