Magento 1.7.0.2 – Always Display Shopping Cart Price Rules Label

cartcart-rulece-1.7.0.2shopping-cart-price-rules

I have just started using Amasty's Promo Items extension to add free items to the cart when certain products are purchased.

The label I wrote telling the shopper why a free item was added appears above the cart listing when the rule is first applied (I have store views available in 2 languages, and it works fine for both).

However, if the user continues to shop and adds more items, next time they see their cart the label isn't displayed. If they missed it the first time, they sometimes get confused about why stuff is appearing in their cart they didn't place there.

I asked Amasty about it, and they told me it is default Magento behavior for Shopping Cart Price Rules (only to display the label when the rule is first applied).

Is there a way to override this behavior and have the label always display above the cart?

Best Answer

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:

Promo Item Name in 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!

Related Topic