-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Provide a way to use third party tax services #1252
Comments
An idea from our last core team meeting: Remove these two lines from ItemAdjustments: @item.included_tax_total = tax.select(&:included?).map(&:update!).compact.sum
@item.additional_tax_total = tax.reject(&:included?).map(&:update!).compact.sum And add another line right below this call to Spree::Config.order_taxes_calculator_class.new(order).calculate_taxes Possible problem: Anything using |
I think in the front-ends we've done where I am, we don't even show tax until the final 'confirm' step. Does default solidus frontend actually show tax in the cart? it would be interesting to do a survey of major e-commerce sites (including European-audience-focused ones) and see how many do, at what point they show tax, and if they show it line-item-specific. I think tax still needs to be (at least optionally) calculated, and ideally stored, on a line-by-line basis. This came up in the slack channel recently where someone was explaining how some U.S. states charge sales tax on only certain categories of products, and buy-something-get-something-else-free promotions complicate this further, especially when the two products are in different sales tax categories, and different states have different rules for how much sales tax is owed in that situation. I think the solution is probably just refraining from automatically calculating/assigning tax when a line item is added to an order/cart, but instead having an explicit |
Yes:
I actually did this once (six or so of the ones close to our field) and all of the ones I looked at only showed tax on the confirm step.
That's been my experience as well. But I know I've heard from others (@gmacdougall possibly?) that there are stores that want to show it at every step.
stored yes, calculated no. Or rather, taxes do need to be calculated at the line level, but the whole order needs to be submitted to the third party tax service at the same time. (And then the results get stored at the line level)
Agreed -- this is what the "idea from our last core team meeting" is suggesting. The customized calculator could hopefully decide at what states it should recalculate taxes? |
Right on.
I'm not sure if it makes sense for the calculator to decide this. I'd think ideally the calculator would simply calculate, and whatever was calling the calculator would decide when to call it and assign it's results to models. But that may not fit into the current architecture as well, as far as supporting the customization needed. But i think it's a confusion of responsibility to have the calculator deciding when to calculate. The decision of when to calculate has to do with your UI, when you need to show tax to the user -- the calculator should not be concerned with or aware of such, or have to be modified when your UI choices change, the calculator should just be concerned with calculating. |
Good point
Yeah, it's hard because there aren't any robust "stages" in Solidus right now. E.g., we could support something like |
Hmm, could it be in the Inside the You're already talking about having
I have to admit I've never understood the use case for changing an order's contents or totals/amounts after it's completed, I've thought it would be better if Spree didn't even allow it! But if you're talking about tax calc being triggered by the OrderUpdateAttributes obj in either case, this shouldn't make a difference I think. (Typing that a couple times, makes me think it really ought to have been called |
Theoretically that could be great, but
Agreed, but I'm not sure there's a reasonable alternative in the near term. We could offer something specific like |
Ah, yeah, I understand existing architecture constrains. I understood that in what was being proposed by jordan-brough, you'd miss out on tax calcs unless you used the |
@jrochkind ah, perhaps I misunderstood what you said. I'm talking about modifying |
Places in Solidus that invoke ItemAdjustments outside of OrderUpdater
|
Ah, it was me that was confused, I didn't realize/forgot the two things are different. I don't really entirely understand what's going on -- is OrderUpdater triggered from the front-end CheckoutsController? (That's where I saw the OrderUpdateAttributes being used; why is it using OrderUpdateAttributes instead of OrderUpdater? Is OrderUpdater still triggered at some point by frontend checkouts controller?) Anyway, yeah, if that works, great. You understand the arch better than me, I'm happy with any plan that plans for extension/customization points as to when tax calculation happens somewhere that's part of general order updating, not a tax calculator. |
I took a look:
|
(speaking big-picture here) It seems that the transition hook stuff we're never really going to get around as long as the order has state transitions before being complete, and that a sensible approach is to simply recalculate totals inside of the Updater as suggested. I know that our code relies heavily on the Updater doing its job, and we know that whenever any total might change we must call the Updater. As far as the lack of Finally, the tax gem we use is boomerdigital/spree_avatax_certified. As you discussed above, it submits the whole order (in XML I think), including individualized itemization of each lineitem, in a single transaction (that, yes, is resubmitted when thing change). Yes, because items can cross tax categories, the taxes need to be calculated on a line-by-line basis |
An update: Thanks to help from @jhawthorn the problem spots listed here have all been addressed. I'm now working on a PR to add extension points for tax calculation that will be usable by 3rd party tax services. |
@jordan-brough I think we've made huge progress here. What in your opinion is needed to close this. It would be great if we had a example of what a very basic tax plugin would look like. |
PR #1892 from @adammathys gets us nearly there I think. After that I'd just like us to finalize what the configurable interface should be exactly and call this done. |
Considering this fixed by #1892 and similar work 🎉 |
There is no good way to use third party tax services with Solidus. All solutions and extensions that the core team has seen so far are very hacky. This is because Solidus does not provide a good extension point for third party tax systems. We want to fix that.
One of the primary problems is that Solidus calculates taxes on a line-by-line basis, and third party tax systems generally calculate taxes on an entire order at once. This means that for a order with 5 line items, for example, Solidus will trigger tax calculation 5 times. If you submit the entire order to your third party tax service 5 times then 1) it will be fragile, 2) it will be slow, 3) some services (including Avatax) charge for every API call, so it may be costly.
One approach that some have tried is to attempt to cache api calls to the third party provider. However, this doesn't work in a scenario like this:
and so on.
Here's an example spec that demonstrates this problem:
https://github.com/jordan-brough/solidus/blob/d92c5b5/core/spec/tax_spec.rb
The text was updated successfully, but these errors were encountered: