solidus icon indicating copy to clipboard operation
solidus copied to clipboard

Tax adjustments should not be recalculated after an order is finalized (?)

Open aldesantis opened this issue 4 years ago • 5 comments

Right now, Solidus continues to recalculate tax adjustments after an order has been finalized. This leads to some weird situations where an order's total might change after the customer has already paid for the order, e.g. if the store starts collecting sales tax in the customer's state and some event triggers a recalculate on the order.

It looks like this is expected behavior that was introduced in 2.3 (see https://github.com/solidusio/solidus/issues/1916), but I can't really understand in what scenario this would be desirable. In fact, this has been a very common pain point and a source of confusion for a lot of Solidus stores, especially for larger brands with stricter financial/compliance requirements.

I'm curious to hear if anyone feels differently, but I propose that, once an order is finalized, Solidus doesn't continue to recalculate its amounts automatically. Any further adjustments should only be possible through the backend UI. At the very least, this should be a configuration option.

aldesantis avatar Jul 28 '21 10:07 aldesantis

There are a number of cases where we do need to force tax to be recalculated, though:

  • Tax was incorrect: businesses working in educational and other spaces often have exemption systems where customers notify the store that they were exempt and need to be reimbursed for the tax. For bookkeeping we usually have a system where the exemption is recorded in the database (or created in TaxJar) and then tax recomputed so that the order no longer has tax.
  • Items are added or removed.
  • The address on the order is changed.

@gmacdougall suggested that (at least for stores using Solidus' built-in tax system) we could give tax rates "start_at" and "ends_at" fields and only apply them for this range. This way if a store begins collecting tax (or changes the amount they collect) in a certain zone, then recalculating an order in that zone wouldn't change the tax as the historical rates would be preserved. It doesn't account for changing the tax category of items or anything, but that's likely much less of a real issue for stores.

jarednorman avatar Jul 28 '21 15:07 jarednorman

I don't know if a start/end time for tax rates would solve the problem, because all of our API-based sales tax integrations (as far as I know) use a single tax rate for all taxes, but stores will start collecting sales tax in different states at different times.

Imagine the following scenario (which actually happened to a client of ours):

  1. A store is currently only collecting sales tax in Florida. They use the TaxJar integration, which uses one tax rate, so the tax rate would be enabled since day 1.
  2. A customer places an order in Colorado. No sales tax is charged.
  3. The store starts collecting sales tax in Colorado. Because they use the same tax rate for all states, the sales tax for Colorado also applies retroactively.
  4. Some event triggers a recalculation of the order. As a result, the customer gets sales tax added to their order, even though they shouldn't.

A solution would be to use different tax rates for different states, but I'm not sure that's feasible or desirable, and it also doesn't solve the problem for different types of adjustments.

The core problem here is that, when we recalculate the order, we have no idea why we're recalculating it, so we don't know what needs to be recalculated exactly. I think giving OrderUpdater more context would deal with all the scenarios you mentioned:

  • Incorrect tax: you can just create a new manual adjustment to cancel out the old ones (or you could unfinalize the existing adjustments and let Solidus recalculate everything, maybe?).
  • Item added/removed: sales tax is only recalculated for that item.
  • Shipping address changed: in this case, it's perfectly okay and desirable to recalculate sales tax on the entire order.

Unfortunately, adding this kind of granularity would be pretty complex, given the amount of actions that currently trigger a full order recalculation (which people are most likely relying on)...

aldesantis avatar Jul 28 '21 15:07 aldesantis

Yeah, adding start/end doesn't help tax API integration setup at all.

Providing a way to do what you're suggesting sounds pretty difficult, but seems like it could work.

jarednorman avatar Jul 28 '21 17:07 jarednorman

What about adding an object (as a class preference) that is responsible to choose when taxes should be recalculated or not? In its basic shape, this object can just keep the existing behavior to avoid breaking changes.

kennyadsl avatar Aug 03 '21 08:08 kennyadsl

I like that idea.

jarednorman avatar Aug 09 '21 17:08 jarednorman