8

I am looking which collect_totals observer I can use. There are two observers, sales_quote_collect_totals_before and sales_quote_address_collect_totals_before.

They can be found in /app/code/core/Mage/Sales/Model/Quote.php and /app/code/core/Mage/Sales/Model/Quote/Address.php.

I wonder what is the difference between the two files as both files have the collect total functions?

1 Answer 1

14

/app/code/core/Mage/Sales/Model/Quote.php

is the Quote class for the quote object

/app/code/core/Mage/Sales/Model/Quote/Address.php

is the Quote Address class for any quote address objects

A quote object would normally contain 2 address objects, but can contain more if multiple delivery addresses are present.

In regards to the 'collecttotals' method(s): Lets first understand each method, and its purpose:

The method in Mage_Sales_Model_Quote, is the initial entry point for the Totals Collector subsystem, and is initiated by a cart save,

(this allows you to inject class methods into the cart calculations, to affect the outcome of the cart totals - example: calculations of cart discounts)

Code flow as follows:

Mage_Checkout_Model_Cart::save()

Mage_Sales_Model_Quote::collectTotals() <--- entry point of collector subsystem

Mage_Sales_Model_Quote_Address::collectTotals() <-- each address attached to the quote object is called, via a loop in the quote collect totals object.

Now, in the address collecttotals method, a loop is performed, using all the system defined 'collectors', calling each class/method, thus allowing the totals for the order to be adjusted by additional calculations (remember that all totals hang off the address object(s), not the actual quote object, which allows magento to perform checkout to multiple addresses)

foreach ($this->getTotalCollector()->getCollectors() as $model) {
            $model->collect($this);
} 

A list of possible 'collectors' would be:

enter image description here

You can inject your own totals collector via a module config as such, and must have a collect method as entry point.

<sales>
   <quote>
      <totals>
         <giftpromo>
           <class>giftpromo/promo_gift</class>
           <after>discount</after>
           <before>tax,grand_total</before>
           <sort_order>12410</sort_order>
         </giftpromo>
      </totals>
    </quote>
</sales>

Now, considering all that information, and the events fired:

sales_quote_collect_totals_before: Gets fired before any address object is loaded, and the totals collector is actioned

sales_quote_address_collect_totals_before: Gets fired inside the quote address object(s), before each address object runs the list of potential collector objects.

Not knowing your end-game, I would not be able to determine which is the right one for you, however, I would also suggest considering if neither is right, and that you'd be best suited with adding in a new collector for the totals collector system

I hope this information helps you determine the right way to extend functionality, and delivery a stable solution.

3
  • super explanation! Commented Jan 25, 2015 at 8:11
  • I read the first line and already decided +1.
    – pspahn
    Commented Jan 25, 2015 at 8:57
  • @ProxiBlue after reading your answer I believe you help me to sort one issue related to collectTotals() method. So I have two discount attribute in my Product table for applying discount on products in order placement. So when we create Quote we add these discount and after_discount amount in quote table which is fine. Now when I place order I see at line $quote->collectTotals()->save() the discount values becomes 0 and total amount becomes original price (without discount price). Please can you tell how to fix this.?
    – apandey846
    Commented Feb 20, 2016 at 7:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.