3

I'm trying to style all of our company's order, invoice and shipping email. I need to add "Country of Origin" and "HS Code" attributes on to the invoice email.

How can I put these custom attributes in the email templates?

3
  • What did you try so far and what are you exactly trying to accomplish. Where do these attributes come from. Are the per product or one per invoice? – Sander Mangel Jan 24 '14 at 8:33
  • Every produkt in our webshop has a Country of Origin and a HS Code for export purpose. I want to get these attributes for every produkt on my invoice. I have trying to figure out what to write where. – Lasse Jan 24 '14 at 9:06
  • lassse, can you please tell me how.... you define relation between product, "Country of Origin" and "HS Code" attributes on to the invoice email.? – Amit Bera Sep 29 '15 at 14:39
1

The best way is to save this to the database, so you are not making extra load on the database every time you send a invoice email (which, though, should be once for most cases).

Making a module is very easy, just follow the directions below.

Module Definition: app/etc/modules/YourCompany_Invoice.xml

You can name your module whatever you want, but you need to keep it the same throughout the example.

<?xml version="1.0"?>
<config>
    <modules>
        <SwiftOtter_Invoice>
            <active>true</active>
            <codePool>local</codePool>
        </SwiftOtter_Invoice>
    </modules>
</config>

Module Configuration: app/code/local/YourCompany/Invoice/etc/config.xml

Now, we need to create the configuration file that tells Magento what files are where. This will be in app/code/local/YourCompany/Invoice/etc/config.xml:

<?xml version="1.0"?>
<config>
    <modules>
        <SwiftOtter_Invoice>
            <version>0.1.0</version>
        </SwiftOtter_Invoice>
    </modules>
    <global>
        <models>
            <SwiftOtter_Invoice>
                <class>SwiftOtter_Invoice_Model</class>
            </SwiftOtter_Invoice>
        </models>
        <helpers>
            <SwiftOtter_Invoice>
                <class>SwiftOtter_Invoice_Helper</class>
            </SwiftOtter_Invoice>
        </helpers>
        <events>
            <sales_order_invoice_register>
                <observers>
                    <SwiftOtter_Invoice>
                        <class>SwiftOtter_Invoice/Observer</class>
                        <method>salesOrderInvoiceRegister</method>
                    </SwiftOtter_Invoice>
                </observers>
            </sales_order_invoice_register>
        </events>
    </global>
</config>

The most notable portion of this is the events node below. We are telling Magento that we want to be notified when this event occurs. The sales_order_invoice_register happens after the invoice is constructed, but before it is saved: exactly when we need it to happen.

Now that we have the configuration in place, we can go to the fun part:

The code: app/code/local/YourCompany/Invoice/Model/Observer.php

This is where the fun part is, and where the action happens. Please note on the line that has array('name'), this is where you put the list of the attribute codes that you want to load. They will appear in a comma-delimited list, in parenthesis, after the name of the item.

class SwiftOtter_Invoice_Model_Observer
{
    protected $_attributes = array();

    public function salesOrderInvoiceRegister($observer)
    {
        /** @var Mage_Sales_Model_Order_Invoice $invoice */
        $invoice = $observer->getInvoice();
        $attributeCodes = array('name');

        /** @var Mage_Sales_Model_Order_Invoice_Item $item */
        foreach($invoice->getAllItems() as $item) {
            $productId = $item->getOrderItem()->getProductId();
            $additions = array();

            foreach ($attributeCodes as $attributeCode) {
                $additions[] = sprintf("%s: %s", $this->_getAttributeLabelFor($attributeCode), $this->_getAttributeValueFor($attributeCode, $productId));
            }

            if (count($additions)) {
                $item->setName(sprintf('%s (%s)', $item->getName(), implode(',', $additions)));
            }
        }
    }

    protected function _getAttributeLabelFor($code)
    {
        return $this->_getAttribute($code)->getFrontend()->getLabel();
    }

    protected function _getAttributeValueFor($code, $productId)
    {
        $productResource = Mage::getResourceModel('catalog/product');
        return $productResource->getAttributeRawValue($productId, $this->_getAttribute($code), Mage::app()->getStore());
    }

    /**
     * @param $code
     * @return Mage_Eav_Model_Entity_Attribute
     * @throws Mage_Core_Exception
     */
    protected function _getAttribute($code)
    {
        if (!isset($this->_attributes[$code])) {
            $this->_attributes[$code] = Mage::getModel('eav/entity_attribute')->loadByCode(
                Mage_Catalog_Model_Product::ENTITY, $code
            );
        }

        return $this->_attributes[$code];
    }
}

Finally, you will not see any effects in the invoice view. The invoice view pulls the name from the order item, not the invoice's name. The email does use the invoice's name.

If you want this applied to the order item (and thus visible in the admin panel and emails everywhere), that is a very simple change and I can add to this post.

0

Here is the article that should help.

Here is the code that should work for order and invoice emails to get additional PRODUCT ATTRIBUTES displayed:

$productId = $_item->getProduct()->getId(); //for order emails
//$productId = $_item->getProductId(); //for invoice emails
$product = Mage::getModel('catalog/product')->load($productId);
$attributes = $product->getAttributes();

//Get a list of all PRODUCT ATTRIBUTES you want to show in this array...
$dispAttribs = array('hardrive', 'memory', 'processor'); 

foreach ($attributes as $attribute) {    
    $attributeCode = $attribute->getAttributeCode();
    if(!in_array($attributeCode, $dispAttribs)) continue;
    $label = $attribute->getFrontend()->getLabel($product);
    $value = $attribute->getFrontend()->getValue($product); 
    echo "<br /><strong>" . $label . ":</strong> " . $value;
}

For adding code to ORDER emails, the file where the code should go is: app/design/frontend/base/default/template/email/order/items/order/default.phtml

For adding code to INVOICE emails, the file where the code should go is: app/design/frontend/base/default/template/email/order/items/invoice/default.phtml

Instead of base/default, you can put it in your custom theme location.

7
  • Also you can rewrite template app\design\frontend\base\default\template\email\order\invoice\items.phtml – oleksii.svarychevskyi Jan 24 '14 at 8:44
  • Rewrite with what ? – Lasse Jan 24 '14 at 9:12
  • Create some extension in local pool. In extensions layout xml file rewrite <block type="sales/order_email_invoice_items" name="items" template="your_extension_name/email/order/invoice/items.phtml"> Create file email/order/invoice/items.phtml in app\design\frontend\base\default\template\your_extension_name. Copy content from app\design\frontend\base\default\template\email\order\invoice\items.phtml and edit it as you want. – oleksii.svarychevskyi Jan 24 '14 at 9:18
  • I've allready made a theme for the company i work for. So i've got a path called "app/design/frontend/default/default_hsajet/template/email/order/invoice/Items.phtml". My question is still what to write where ? – Lasse Jan 24 '14 at 9:26
  • 3
    this might work, but it's not the best solution. An invoice should never change once it is created. But with this code, if you delete the products that are being invoiced, or if you delete the attribute, or if you change the value of the attributes, the invoice changes. – Marius Sep 28 '15 at 9:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.