How to programmatically apply a magento sales rule to an quote item
Solution 1
unfortunately Chuck isn't currently doing consulting work. So I had to dig deeper into the entangled magento discount calculation.
The recalculation by totals_collected_flag
is IMHO no options, as it triggers tax calculation twice, which means the quote totals get totally wrong.
I had success to populate my own discount type by implementing a new Mage_Sales_Model_Quote_Address_Total_Abstract
. This one is using in it's collect()
-method a slightly customized version of Mage_SalesRule_Model_Validator
which loads custom sales rules according to my discount strategy.
The custom class is included into the Magento totals calculation by adding the following XML to the modules config.
<global>
...
<sales>
<quote>
<totals>
<requestquotation_discount>
<class>requestquotation/request_discount</class>
<after>discount</after>
<before>grand_total</before>
</requestquotation_discount>
</totals>
</quote>
</sales>
</global>
In the implementation the "code" of the totals-calculator is set to "discount" and no previous calculated discount is reset. With this method, the custom discount can run side by side with Magento's default discount system as well it doesn't interfere with tax-calculation, etc.
Hope, this helps somebody struggling with the same problems.
Solution 2
Chuck Norris is the only one who has Magento documentation. But never the less you could try to set the collected flag to false prior calling collectTotals():
$quote->setTotalsCollectedFlag(false)->collectTotals();
and optionally if you end up with wrong totals after calling collectTotals more than once within same object instance then you need to be aware of following issue:
http://www.magentocommerce.com/bug-tracking/issue?issue=11893
Joachim Rosskopf
Updated on June 17, 2022Comments
-
Joachim Rosskopf almost 2 years
I'm currently implementing a plugin to manage quotation requests in a magento shop system. The idea is, that the request is associated with an quote and somebody in the backend should be able to apply individual sales rules per quote item.
There was no problem to implement the functionality to create and edit the involved entities on the frontend as well in backend. But I'm unable to apply a certain sales-rule to a quote item and have that rule reflected in the row total as well as the subtotal of the quote.
My current approach is to use the
sales_quote_address_discount_item
-Hook. There I use an instance of a class derived fromMage_SalesRule_Model_Validator
which overloaded_getRules()
-Method gives the relevantMage_SalesRule_Model_Rule
s. The relevant code of the event-observer looks like:$quote_item = $event->getItem(); $request_item = $this->helper->getRequestItemByQuoteItemId($quote_item->getItemId()); if (! $this->isRelevantRequestItem($request_item)) return $this; $validator = Mage::getModel("requestquotation/request_validator") ->addRule($request_item->getRule()); $validator->process($quote_item);
When I step with the debugger through
process()
-Method, my supplied rule works and is applied to the quote item. But any furthercollectTotals()
on the quote and an$quote_item->save()
has no effects on the of row-totals and the subtotal of the quote.Is there any documentation or example how to add an sales-rule (better in my opinion as it is traceable) or an discount manually, programatically to an quote-item and/or to the quote itself.
Thank you in advance and best regards!
Joachim
-
Anton S over 12 yearsThe recalculation by totals_collected_flag is IMHO no options, as it triggers tax calculation twice, which means the quote totals get totally wrong. this is a simple bug to solve, collectTotals will cache prices of quote items in their objects and thus failing to calculate twice all you have to do is to reset the cached values as well before calling it twice. But +1 for fixing teeth through asshole as this shows the talent :)
-
Anton S over 12 yearsi created a ticket in magneto bug-list for this issue as well magentocommerce.com/bug-tracking/issue?issue=11893
-
Joachim Rosskopf over 12 yearsThank you for filing a bug report. I shared the above solution not only as an workaround for the discount-calculation bug. But with the above mentioned method you can add some custom logic to the totals calculation in a clean and non interfering way.
-
Anton S over 12 yearsits just a joke :) but sure implementing your own totals object is right approach