When working with product attributes for order items it is not OK to get the product details by loading the product data for 2 reasons:
- the product might be missing (deleted at some point)
- it affects the performance because you have to load every attribute
In my opinion it's best to add the product attributes you need to the quote item and carry them for all the other item types (order item, invoice item, shipment item and credit memo item).
In order to achieve this you will need (yes you guest it) an extension that adds a column for each attribute you need on the corresponding item table. After that you will not need this code:
$_product = Mage::getModel('catalog/product')->load($_item->getProduct()->getId())
You will be able to make a simple call like:
Verpakking: <?php echo $_item->getVerpakking(); ?><br>
The following is an example for one attribute, but you can just mimic the behavior for the rest of the attributes. I will take the attribute with code verpakking
.
Let's call the extension Easylife_Sales
. For the extension you need the following files:
app/etc/modules/Easylife_Sales.xml
- declaration file: (I'm anxious to work with Magento 2.0 so I won't need this declaration file anymore).
<?xml version="1.0"?>
<config>
<modules>
<Easylife_Sales>
<active>true</active>
<codePool>local</codePool>
<depends>
<Mage_Sales /><!-- your extension should depend on Mage_Sales -->
</depends>
</Easylife_Sales>
</modules>
</config>
app/code/local/Easylife/Sales/etc/config.xml
- the configuration file:
<?xml version="1.0"?>
<config>
<modules>
<Easylife_Sales>
<version>0.0.1</version>
</Easylife_Sales>
</modules>
<global>
<models>
<easylife_sales><!-- model declaration -->
<class>Easylife_Sales_Model</class>
</easylife_sales>
</models>
<events>
<sales_quote_item_save_before><!-- event to attach the custom attributes to the quote items -->
<observers>
<easylife_sales>
<class>easylife_sales/observer</class>
<method>addCustomAttributes</method>
</easylife_sales>
</observers>
</sales_quote_item_save_before>
</events>
<fieldsets>
<sales_convert_quote_item>
<verpakking><!-- all attributes that need to be passed from the quote item to the order item-->
<to_order_item>*</to_order_item>
</verpakking>
<!-- add here one tag for each attribute you want to pass to the order item -->
</sales_convert_quote_item>
<sales_convert_order_item><!-- This is not mandatory but useful for consistency-->
<verpakking><!-- all attributes that need to be passed from the order item to quote item, invoice item, shipping item and cm item-->
<to_quote_item>*</to_quote_item>
<to_invoice_item>*</to_invoice_item>
<to_shipment_item>*</to_shipment_item>
<to_cm_item>*</to_cm_item>
</verpakking>
<!-- add here one section for each attribute -->
</sales_convert_order_item>
</fieldsets>
<sales>
<quote>
<item>
<product_attributes>
<verpakking /><!-- each product attribute code that needs to be loaded when using a quote item -->
<!-- add here one tag for each attribute with the attribute code-->
</product_attributes>
</item>
</quote>
</sales>
<resources>
<easylife_sales_setup><!-- install scripts that will add the new columns to the sales tables-->
<setup>
<module>Easylife_Sales</module>
<class>Mage_Sales_Model_Resource_Setup</class>
</setup>
</easylife_sales_setup>
</resources>
</global>
</config>
app/code/local/Easylife/Sales/Model/Observer.php
- used for filling the additional columns of the quote item.
<?php
class Easylife_Sales_Model_Observer{
public function addCustomAttributes($observer){
$item = $observer->getEvent()->getItem();
if ($product = $item->getProduct()){
$item->setVerpakking($product->getVerpakking());
//add here one line for each product attribute
}
return $this;
}
}
app/code/local/Easylife/Sales/sql/easylife_sales_setup/install-0.0.1.php
- the extension install script that adds the columns to the needed tables.
<?php
$this->startSetup();
//add a column to the quote item table
$this->getConnection()
->addColumn($this->getTable('sales/quote_item'), 'verpakking', array(
'type' => Varien_Db_Ddl_Table::TYPE_TEXT, //type should match the product type. see the class `Varien_Db_Ddl_Table` for other column types
'length' => 32,
'nullable' => true,
'comment' => 'Verpakking'
));
//add a column to the order item table
$this->getConnection()
->addColumn($this->getTable('sales/order_item'), 'verpakking', array(
'type' => Varien_Db_Ddl_Table::TYPE_TEXT,//type should match the product type. see the class `Varien_Db_Ddl_Table` for other column types
'length' => 32,
'nullable' => true,
'comment' => 'Verpakking'
));
//add a column to the shipment item table
$this->getConnection()
->addColumn($this->getTable('sales/shipment_item'), 'verpakking', array(
'type' => Varien_Db_Ddl_Table::TYPE_TEXT,//type should match the product type. see the class `Varien_Db_Ddl_Table` for other column types
'length' => 32,
'nullable' => true,
'comment' => 'Verpakking'
));
//add a column to the invoice item table
$this->getConnection()
->addColumn($this->getTable('sales/invoice_item'), 'verpakking', array(
'type' => Varien_Db_Ddl_Table::TYPE_TEXT,//type should match the product type. see the class `Varien_Db_Ddl_Table` for other column types
'length' => 32,
'nullable' => true,
'comment' => 'Verpakking'
));
//add a column to the credit memo item table
$this->getConnection()
->addColumn($this->getTable('sales/creditmemo_item'), 'verpakking', array(
'type' => Varien_Db_Ddl_Table::TYPE_TEXT,//type should match the product type. see the class `Varien_Db_Ddl_Table` for other column types
'length' => 32,
'nullable' => true,
'comment' => 'Verpakking'
));
//add here columns for additional attributes by cloning the statements above and changing the column names.
//The column names must be the same as the product attribute code for an easier use
$this->endSetup();
That's it. Clear the cache and make a call to your website (backend or frontend) to install the extension. Just to make sure, check the tables sales_flat_*_item
to see if your columns have been added.
Now you can use in your e-mail (like I've said before):
Verpakking: <?php echo $_item->getVerpakking(); ?><br>