I need to extend the Magento shopping cart to include an extra step for a store locator. I understand that I need to overwrite the core OnePage controller (Mage_Checkout_O
There are a number of steps required here to get the whole solution.
Firstly, create a new module. Use the ModuleCreator if you wish.
Then, write a setup script in your module to add the new fields to Magento's attribute structure, e.g. :
$setup = new Mage_Sales_Model_Mysql4_Setup('core_setup');
$setup->startSetup();
$setup->addAttribute('quote', 'my_attribute', array('type' => 'varchar', 'visible' => false, 'required' => false));
$setup->addAttribute('order', 'my_attribute', array('type' => 'varchar', 'visible' => false, 'required' => false));
$setup->addAttribute('invoice', 'my_attribute', array('type' => 'varchar', 'visible' => false, 'required' => false));
$setup->addAttribute('creditmemo', 'my_attribute', array('type' => 'varchar', 'visible' => false, 'required' => false));
Note the use of the Mage_Sales_Model_Mysql4_Setup
to add the fields to the relevant sales_flat_quote
and sales_flat_order
tables.
Now, insert the following values in your module's config.xml file:
<global>
<fieldsets>
<sales_convert_quote>
<my_attribute>
<to_order>*</to_order>
</my_attribute>
</sales_convert_quote>
<sales_convert_order>
<my_attribute>
<to_cm>*</to_cm>
<to_invoice>*</to_invoice>
</my_attribute>
</sales_convert_order>
</fieldsets>
That will instruct Magento to copy the values of your custom field from quote to order to invoice and credit_memo, etc.
Then in your custom block/controller code, you will be able to use Magento's magic getters and setters to persist the values.
$oQuote = Mage::getSingleton('checkout/session')->getQuote();
$oQuote->setMyAttribute('some_value');
$oQuote->save();
You should see the new column and value saved in sales_flat_quote
. Then once the customer completes checkout, the same value should be saved in sales_flat_order
.
Note that the above code can be extended to work for quote_item
and order_item
by just changing quote
to quote_item
etc, however, if you wish to save attribute values that have been set on your products, then some extra work is required.
Insert a new block of XML into your config.xml (again inside the global node):
<sales>
<quote>
<item>
<product_attributes>
<my_attribute />
</product_attributes>
</item>
</quote>
</sales>
Where my_attribute
is the attribute code on the product model. That will make the my_attribute available on the linked product, so you can access it via
$oQuoteItem->getProduct()->getMyAttribute()
without needing to perform a full Mage::getModel('catalog/product')->load($oQuoteItem->getProductId())
. This is much more efficient.
Then, you will need an observer to copy the values from the product object to the quote_item object. So, declare your observer in the config.xml:
<events>
<sales_quote_item_set_product>
<observers>
<quoteitem_set_custom_data>
<type>singleton</type>
<class>mymodule/observer</class>
<method>setCustomDataOnQuoteItem</method>
</quoteitem_set_custom_data>
</observers>
</sales_quote_item_set_product>
<events>
and write code in your observer class like this:
public function setCustomDataOnQuoteItem($oObserver){
$oProduct = $oObserver->getProduct();
$oQuoteItem = $oObserver->getQuoteItem();
foreach(array('my_attribute') as $vAttributeCode){
$oQuoteItem->setData($vAttributeCode,$oProduct->getData($vAttributeCode));
}
}
Here is a complete working module.. its (almost) the same as the above code of Johnatan. You will find it here: https://bitbucket.org/vovsky/adding-custom-product-attribute-to-quote-and-order-items-in/
And full explanation of every step here: http://www.atwix.com/magento/custom-product-attribute-quote-order-item/