19

I'm developing a script (external to Magento, not a module) which aims to output a text list of all available products, their prices and some other attributes. However, catalog price rules don't seem to be applied to product prices. If I use any of the following:

$_product->getPrice()
$_product->getFinalPrice()

I get the normal price (without rules being applied).

If I use:

$_product->getSpecialPrice()

I get null unless the product actually has a special price inserted in the product itself (i.e. if special price is not related with catalog rules).

I also tried

Mage::getModel('catalogrule/rule')->calcProductPriceRule($product,$product->getPrice())

as suggested in the answer given by Fabian Blechschmidt, but interestingly it returns the normal price only if the product is affected by any catalog rule, returning null otherwise.

There was a similar question in StackOverflow and Magento Forums some time ago, but the provided answer (which is to insert the code bellow) doesn't work for me (returned prices remain the same).

Mage::app()->loadAreaPart(Mage_Core_Model_App_Area::AREA_FRONTEND,Mage_Core_Model_App_Area::PART_EVENTS);

Does anybody have an idea of how to achieve this?

I'm using Magento 1.6.2.0. Thanks in advance.

Community
  • 1
  • 1
faken
  • 6,572
  • 4
  • 27
  • 28
  • 2
    Perhaps there is something else going on involving your data or indexing. Does the discounted price display as you expect in the default theme with all custom modules disabled? – benmarks Dec 31 '12 at 01:18
  • Yes, the discounted prices display Ok in the frontend. The problem was that this was not a Magento module, but an "external" script. It seems Magento loads additional stuff which is required for everything to work properly. In other words, everything in Magento must really be a module... – faken Dec 31 '12 at 02:50
  • 1
    *"everything in Magento must really be a module"* - Not really. There are however many modules which interact in many ways when the app is executing. I would check that `Mage_CatalogRule_Model_Observer` is instantiating. Perhaps you should paste the relevant parts of the remote script (`Mage::app()` instantiation, `loadAreaPart()` call, product load, etc.) – benmarks Dec 31 '12 at 03:15
  • Yes, you are correct, just replace "must really" by "should" or "is probably easier if". Thanks for the input. – faken Dec 31 '12 at 03:45

4 Answers4

20

Thanks to you, I found a new site: http://www.catgento.com/magento-useful-functions-cheatsheet/

And they mentioned:

Mage::getModel('catalogrule/rule')->calcProductPriceRule($product,$product->getPrice())

HTH

B00MER
  • 5,471
  • 1
  • 24
  • 41
Fabian Blechschmidt
  • 4,113
  • 22
  • 39
  • Hi, thanks for the answer (I missed that website in my searches). That seems exactly what I need but it doesn't work: returned prices are the same as original prices (and it doesn't return any price at all if product is not affected by any rule, although the later could be easily solved). I'm looking at the code from Mage_CatalogRule_Model_Rule and associated classes, it seems to do what I want, but it doesn't. I also tried to flush cache, reindex, etc., but result is always the same. Thanks once again. – faken Dec 30 '12 at 22:22
  • try to load the product beforehand $_product->load($_product->getId()) if this works, then you miss an attribute. DONT STOP hat this point. Look which attribute is missing and add it to the collection. the code you posted looks like view.phtml or something, then you can just change the attribute settings in the backend. – Fabian Blechschmidt Dec 31 '12 at 11:20
  • I tried to use this but I´m getting this error : Invalid method Mage_CatalogRule_Model_Rule::calcProductPriceRule Anything I can do there? – Klettseb Aug 25 '15 at 13:25
  • I would assume your magento version is too old. You can look it up in one of the magento mirror, e.g. https://github.com/OpenMage/magento-mirror – Fabian Blechschmidt Sep 02 '15 at 17:41
  • Even after filling up groupId, storeId this is not usable. Especially if you make use of "Stop Further Rule processing". The best solution is what from augsteyer – zzarbi Mar 14 '19 at 00:26
12

As catalog price rules heavily depend on time, store and visiting customer, you need to set those parameters when you want to retrieve the product final price with it's price rules applied.

So, in your case, make sure that provided product is passed with the desired store and customer group id, which can be set as:

Mage::getModel('catalogrule/rule')->calcProductPriceRule($product->setStoreId('STORE_ID')->setCustomerGroupId('CUSTOMER_GROUP_ID'),$product->getPrice())
Jernej Golja
  • 520
  • 2
  • 9
  • Thanks a lot. I had the problem that the Cronjob of the Lengow Feed Export extension didn't considered the catalog rules correctly for price export. After applied setCustomerGroupId() to the product instance it worked well. I think this solution is much better then to simulate store frontends by Mage::app()->loadAreaPart() etc. – ahe_borriglione Sep 01 '17 at 09:18
12

I discovered the problem. The discounted prices display Ok in the store frontend. The problem was that I was developing a script "external" to Magento (thus not a Magento module), something like:

<?php

set_time_limit(0);
ignore_user_abort();
error_reporting(E_ALL^E_NOTICE);
header("Content-Type: text/plain; charset=utf-8");

require_once "app/Mage.php";

// Get default store code
$default_store = Mage::app()->getStore();
...

For everything to work properly it seems that one must follow the proper Magento bootstrap, and develop everything as a module. My script was so simple that I thought it wouldn't be necessary to code a complete module. In other words, everything in Magento should really be a module.

Concluding, using the module approach, all the methods work as expected:

$_product->getPrice()
$_product->getFinalPrice()
$_product->getSpecialPrice()

Thank you all for your input.

faken
  • 6,572
  • 4
  • 27
  • 28
12

This helped me in this issue: http://www.magentocommerce.com/boards/viewthread/176883/ . Jernej's solution seems plausible, but it does not handle rules that Overwrite other rules by using 'stop processing' and therefore can apply more than one rule.

$original_price = $_product->getPrice();
$store_id = 1; // Use the default store
$discounted_price = Mage::getResourceModel('catalogrule/rule')->getRulePrice( 
                        Mage::app()->getLocale()->storeTimeStamp($store_id), 
                        Mage::app()->getStore($store_id)->getWebsiteId(), 
                        Mage::getSingleton('customer/session')->getCustomerGroupId(), 
                        $_product->getId());

// if the product isn't discounted then default back to the original price
if ($discounted_price===false) {
    $discounted_price=$original_price;
}
augsteyer
  • 1,039
  • 10
  • 25