Category Archives: Customization

Add an Item to the Cart with a Custom Price in Magento

Magento doesn’t offer the ability to add custom prices when adding items to your cart. This is a solution I’ve used on occasion.

You can use an observer class to listen to checkout_cart_product_add_after, and use a product’s “Super Mode” to set custom prices against the quote item.

In your /app/code/local/{namespace}/{yourmodule}/etc/config.xml:

    <config>
        ...
        <frontend>
            ...
            <events>
                <checkout_cart_product_add_after>
                    <observers>
                        <unique_event_name>
                            <class>{{modulename}}/observer</class>
                            <method>modifyPrice</method>
                        </unique_event_name>
                    </observers>
                </checkout_cart_product_add_after>
            </events>
            ...
        </frontend>
        ...
    </config>

And then create an Observer class at /app/code/local/{namespace}/{yourmodule}/Model/Observer.php

<?php
    class <namespace>_<modulename>_Model_Observer
    {
        public function modifyPrice(Varien_Event_Observer $obs)
        {
            // Get the quote item
            $item = $obs->getQuoteItem();
            // Ensure we have the parent item, if it has one
            $item = ( $item->getParentItem() ? $item->getParentItem() : $item );
            // Load the custom price
            $price = $this->_getPriceByItem($item);
            // Set the custom price
            $item->setCustomPrice($price);
            $item->setOriginalCustomPrice($price);
            // Enable super mode on the product.
            $item->getProduct()->setIsSuperMode(true);
        }
        
        protected function _getPriceByItem(Mage_Sales_Model_Quote_Item $item)
        {
            $price;
            
            //use $item to determine your custom price.
            
            return $price;
        }
        
    }

Adding Custom Data to a Cart Item in Magento

Sometimes, storing additional custom data against a cart line item is a very useful tool. There are many good and bad ways to do it, and there are a lot of things to consider. If anything it’s far from simple. I’m going to cover some of the approaches here, so that you can make an informed decision on which way you plan on doing it.

A) Firstly, see if this can be achieved with existing product custom options. If there’s any way you can do it without having to change a whole lot of core functionality it’ll make your life easier down the track.

B) Personally, I would create a model for your custom content and a relationship between that content and sales/quote_item and sales/order_item. You’ll need to modify the front end to bring this in, and also the admin area to display the info, and give administrators a means to add the custom content to items. This is probably the most thorough way to tackle the feature.

C) Alternatively, you can add an array of custom data to the quote when the item is added to quote. For this, you’ll have to hijack the add-to-cart controller completely. To start with, take all the functionality from the existing controller. Look at the Mage_Sales_Model_Quote::addProduct() function and you’ll see that it takes two parameters like so:

$quote->addProduct($product, $request);

where $request is of type Varien_Object formatted like this:

$request = new Varien_Object(array(
    'qty'=>$qty,
    'options'=>$options,
    'custom_options'=>$custom_options
));

and where $custom_options is an array of custom data.

This way can be useful, but is fraught with danger. You need to ensure that you duplicate all of the functionality of the original add-to-cart controller, including dispatching the event and setting all session flags. There are also other considerations. If your data is line item specific, then we can safely assume that you don’t want Magento simply incrementing the quantity of the line item in the cart, as the specific data applies to a specific line item. To do this, you would override Mage_Sales_Model_Quote, and duplicate the getItemByProduct() function to run a different set of checks on the line item to determine whether or not to increment the qty.

If you can’t do A, B is my recommended approach. It is more time consuming in the short-term but a better solution long-term.