I'm looking for place at code where shopping cart price rules are applied. Lets say, I've created a rule and when I add some product to shopping cart which match this rule, this rule will be applied and can change a price. I'm trying to explore module SalesRules
, but without success. Maybe someone can give me a right direction?
Cart Price Rules – How to Find When Shopping Cart Price Rules Are Applied
cartprice
Related Solutions
If I understood correctly, you need the price at which the product has been sold.
You can get that price directly from the order item.
On the success page you have access to the last order it with:
$orderId = Mage::getSingleton('checkout/session')->getLastOrderId()
Then loop through the order items until you find the product you need:
Let's say the product you are looking for is $productId
$order = Mage::getModel('sales/order')->load($orderId);
$price = null;
foreach ($order->getAllItems() as $item){
if ($item->getProductId() == $productId){
$price = $item->getPrice() - $item->getDiscountAmount();
break;
}
}
if (!is_null($price)){
//do something with $price
}
There is no point on applying a rule to the main product. You can get wrong results. For example some rules may be applied only on a certain combination of products are in cart, or when a specific shipping address is set. Also one rule cannot be valid anymore (customer or total capping can be reached).
I just ran into this with a client recently. I wound up writing a module that creates a new quote item attribute, sets it from an observer, and displays it below the product details in the cart, on the checkout page, in the new order e-mail, and in the admin order/invoice view.
In order to display the custom quote item where I wanted to show it, I call a helper method from whatever template I need to modify. I might turn this into an actual generic module some day, and when I do I'll figure out a better way to display that attribute rather hacking a bunch of templates. Due to time constraints, I had to use the "quick and dirty" method.
Following is the code I used to create, set, and get the attribute, plus a list of the templates I modified:
config.xml
<config>
<modules>
<Company_PromoName>
<version>0.2.0</version>
</Company_PromoName>
</modules>
<global>
<models>
<company_promoname>
<class>Company_PromoName_Model</class>
</company_promoname>
</models>
<helpers>
<company_promoname>
<class>Company_PromoName_Helper</class>
</company_promoname>
</helpers>
<resources>
<company_promoname_setup>
<setup>
<module>Company_PromoName</module>
<class>Company_PromoName_Model_Resource_Setup</class>
</setup>
</company_promoname_setup>
</resources>
<events>
<sales_quote_add_item>
<observers>
<company_promoname>
<class>company_promoname/observer</class>
<method>salesQuoteAddItem</method>
</company_promoname>
</observers>
</sales_quote_add_item>
</events>
<fieldsets>
<sales_convert_quote_item>
<promo_name>
<to_order_item>*</to_order_item>
</promo_name>
</sales_convert_quote_item>
<sales_convert_order_item>
<promo_name>
<to_quote_item>*</to_quote_item>
<to_invoice_item>*</to_invoice_item>
</promo_name>
</sales_convert_order_item>
</fieldsets>
</global>
</config>
Model/Resource/Setup.php
class Company_PromoName_Model_Resource_Setup extends Mage_Sales_Model_Resource_Setup
{
}
data-install-1.0.0.php
$installer = $this;
$entities = array(
'quote_item',
'order_item',
'invoice_item',
);
$options = array(
'type' => Varien_Db_Ddl_Table::TYPE_VARCHAR,
'visible' => true,
'required' => false
);
$installer->startSetup();
foreach ($entities as $entity) {
$installer->addAttribute($entity, 'promo_name', $options);
}
$installer->endSetup();
Observer.php
class Company_PromoName_Model_Observer
{
/**
* Adds the promo name to the quote item if it is a promo item when the item
* is added to the quote
*
* @param Varien_Event_Observer $observer Object containing data passed
* from the event
* @see Mage_Sales_Model_Quote::addItem()
* @return void
*/
public function salesQuoteAddItem(Varien_Event_Observer $observer)
{
$quoteItem = $observer->getEvent()->getQuoteItem();
$amPromoRule = $quoteItem->getOptionByCode('ampromo_rule');
if ($amPromoRule && $amPromoRule->getValue()) {
$rule = Mage::getModel('salesrule/rule')->load($amPromoRule->getValue());
if ($rule) {
$quoteItem->setPromoName($rule->getName());
}
}
}
}
Helper/Data.php
class Company_PromoName_Helper_Data extends Mage_Core_Helper_Abstract
{
/**
* Gets the name of the promotion from a custom item attribute
*
* @param Mage_Core_Model_Abstract $item The promo item
* @return string
*/
public function getPromoName(Mage_Core_Model_Abstract $item)
{
$promoName = '';
if ($item->getPromoName()) {
$promoName = $item->getPromoName();
}
return $promoName;
}
}
Modified templates:
frontend:
checkout/cart/item/default.phtml
checkout/onepage/review/item.phtml
adminhtml:
sales/items/column/name.phtml
Screenshot of the promo item in the cart:
Note: The name of the extension and the screenshot have been redacted to protect the privacy of the client.
I hope the code I provided gets you on your way. Enjoy!
Best Answer
The starting point for all salesrules are in the Observer:
There
\Mage_SalesRule_Model_Validator::process()
is called, where it is checked whether the rule should be applied:and afterwards the discounts are applied.
I hope this helps you on your way into the salesrules.