Question

I need to apply different rates based on a custom attribute of product. I created an observer to change the rate before the cart (sales_quote_collect_totals_before).

Everything works fine but when I change the rate (see quote below) I end up changing global scope. So during checkout, if another user go to cart, the rate will be changed during the process generating a different price at checkout.

$taxRate = Mage::getSingleton('tax/calculation_rate')
    ->getCollection()
    ->addFieldToFilter('code', 'myCodeTaxRate')
    ->getFirstItem()
    ->setRate($myCustomRate)
    ->save();

You can apply the value for only one session? change only in memory and not in the database?

I saw this and I think is a bad solution: Modify Tax Rule Programmatically - set Tax Rate array

Was it helpful?

Solution

Since you've referenced a previous question of mine, I feel I should respond.

In the research I've done on modifying tax rates based on various factors (in my case, mostly an API call to a tax rate provider to discover a user's current/accurate tax rate) it seems safest to me to get out of Magento's way when possible.

By this, I mean that modifying core processes to change how tax is calculated is going to give you all sorts of fits and it may be less cumbersome and cleaner overall to instead create your own tax rates/rules dynamically based on the factors you require.

In my case it ended up being much cleaner to observe the same sales_quote_collect_totals_before event and simply determine if an existing rate/rule has been created and can be used based on current context (in my case, postal codes). If it is, then use it, if not, then let's create a new tax rate/rule programmatically which is then available to be used during collectTotals().

When I say "much cleaner", the main things are what Magento will already do with your tax rates if they exist as expected. If I was trying to set the tax rate itself, then you have additional areas you need to cover so that these values display properly during checkout. In contrast, simply creating a new tax rate/rule dynamically removes this constraint and all the other areas of Magento (frontend or backend) that display/modify/use these rates will function normally as if nothing changed.

Again, just to reiterate, I did try doing this both ways, using $item->setTaxAmount() as well as programmatically create tax rules. The module where I was modifying the item/quote's tax was much more complex and prone to error (especially front-end display issues). In the end I decided my method was better simply because we are dealing with monetary values that the customer is required to pay. I would rather have a server process that was a little "heavier" but did things correctly than one that was prone to error but was more obvious in its implementation. I cannot accept losing a customer because they were confused by the taxes during checkout.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top