Add custom attribute to Magento’s PDF invoice

Featured Image

Hello everyone! Today I’ll show you how to add custom attribute to Magento’s generated PDF invoice in just a few steps. Since this article is pretty straight-forward, here we go.

One of my recent tasks was to create a custom attribute for products called inchoo_warehouse_location, and output it when click on “Print” (invoice in admin section) occurs. Since PDF generation is Magento’s core functionality, we’ll have to rewrite it a bit.

Step 1

Create the following three files in your Magento’s installation:
app/code/local/Inchoo/Invoice/Model/Order/Pdf/Items/Invoice/Default.php
app/code/local/Inchoo/Invoice/Model/Order/Pdf/Invoice.php
app/code/local/Inchoo/Invoice/etc/config.xml

Those will be used for our extension that will modify Magento’s core functionality.

Step 2

Fill in the data to according files:
config.xml

<?xml version="1.0"?>
<config>
    <modules>
        <Inchoo_Invoice>
            <version>0.1.0</version>
        </Inchoo_Invoice>
    </modules>
    <global>
        <models>
            <sales>
                <rewrite>
                    <order_pdf_invoice>Inchoo_Invoice_Model_Order_Pdf_Invoice</order_pdf_invoice>
                    <order_pdf_items_invoice_default>Inchoo_Invoice_Model_Order_Pdf_Items_Invoice_Default</order_pdf_items_invoice_default>
                </rewrite>
            </sales>
        </models>
    </global>
</config>

Default.php

<?php
/**
 * Inchoo PDF rewrite for custom attribute
 * Attribute "inchoo_warehouse_location" has to be set manually
 * Original: Sales Order Invoice Pdf default items renderer
 *
 * @category   Inchoo
 * @package    Inhoo_Invoice
 * @author     Mladen Lotar - Inchoo <mladen.lotar@inchoo.net>
 */
 
class Inchoo_Invoice_Model_Order_Pdf_Items_Invoice_Default extends Mage_Sales_Model_Order_Pdf_Items_Invoice_Default
{
    /**
     * Draw item line
	 **/
    public function draw()
    {
        $order  = $this->getOrder();
        $item   = $this->getItem();
        $pdf    = $this->getPdf();
        $page   = $this->getPage();
        $lines  = array();
 
		//Inchoo - Added custom attribute to PDF, first get it if exists
		$WarehouseLocation = $this->getWarehouseLocationValue($item);
 
        // draw Product name
        $lines[0] = array(array(
            'text' => Mage::helper('core/string')->str_split($item->getName(), 60, true, true),
            'feed' => 35,
        ));
 
		//Inchoo - Added custom attribute
		//draw Warehouse Location
        $lines[0][] = array(
            'text'  => Mage::helper('core/string')->str_split($WarehouseLocation, 25),
            'feed'  => 245
        );
 
        // draw SKU
        $lines[0][] = array(
            'text'  => Mage::helper('core/string')->str_split($this->getSku($item), 25),
            'feed'  => 325
        );
 
        // draw QTY
        $lines[0][] = array(
            'text'  => $item->getQty()*1,
            'feed'  => 435
        );
 
        // draw Price
        $lines[0][] = array(
            'text'  => $order->formatPriceTxt($item->getPrice()),
            'feed'  => 395,
            'font'  => 'bold',
            'align' => 'right'
        );
 
        // draw Tax
        $lines[0][] = array(
            'text'  => $order->formatPriceTxt($item->getTaxAmount()),
            'feed'  => 495,
            'font'  => 'bold',
            'align' => 'right'
        );
 
        // draw Subtotal
        $lines[0][] = array(
            'text'  => $order->formatPriceTxt($item->getRowTotal()),
            'feed'  => 565,
            'font'  => 'bold',
            'align' => 'right'
        );
 
        // custom options
        $options = $this->getItemOptions();
        if ($options) {
            foreach ($options as $option) {
                // draw options label
                $lines[][] = array(
                    'text' => Mage::helper('core/string')->str_split(strip_tags($option['label']), 70, true, true),
                    'font' => 'italic',
                    'feed' => 35
                );
 
                if ($option['value']) {
                    $_printValue = isset($option['print_value']) ? $option['print_value'] : strip_tags($option['value']);
                    $values = explode(', ', $_printValue);
                    foreach ($values as $value) {
                        $lines[][] = array(
                            'text' => Mage::helper('core/string')->str_split($value, 50, true, true),
                            'feed' => 40
                        );
                    }
                }
            }
        }
 
        $lineBlock = array(
            'lines'  => $lines,
            'height' => 10
        );
 
        $page = $pdf->drawLineBlocks($page, array($lineBlock), array('table_header' => true));
        $this->setPage($page);
 
    }
 
	/*
	 * Return Value of custom attribute
	 * */
	private function getWarehouseLocationValue($item)
	{
		$prod = Mage::getModel('catalog/product')->load($item->getProductId());
 
		if(!($return_location = $prod->getInchooWarehouseLocation()))
			return 'N/A';
		else
			return $return_location;
	}
}

And finally Invoice.php

<?php
/**
 * Inchoo PDF rewrite for custom attribute
 * * Attribute "inchoo_warehouse_location" has to be set manually
 * Original: Sales Order Invoice PDF model
 *
 * @category   Inchoo
 * @package    Inhoo_Invoice
 * @author     Mladen Lotar - Inchoo <mladen.lotar@inchoo.net>
 */
class Inchoo_Invoice_Model_Order_Pdf_Invoice extends Mage_Sales_Model_Order_Pdf_Invoice
{
	public function getPdf($invoices = array())
    {
        $this->_beforeGetPdf();
        $this->_initRenderer('invoice');
 
        $pdf = new Zend_Pdf();
        $this->_setPdf($pdf);
        $style = new Zend_Pdf_Style();
        $this->_setFontBold($style, 10);
 
        foreach ($invoices as $invoice) {
            if ($invoice->getStoreId()) {
                Mage::app()->getLocale()->emulate($invoice->getStoreId());
            }
            $page = $pdf->newPage(Zend_Pdf_Page::SIZE_A4);
            $pdf->pages[] = $page;
 
            $order = $invoice->getOrder();
 
            /* Add image */
            $this->insertLogo($page, $invoice->getStore());
 
            /* Add address */
            $this->insertAddress($page, $invoice->getStore());
 
            /* Add head */
            $this->insertOrder($page, $order, Mage::getStoreConfigFlag(self::XML_PATH_SALES_PDF_INVOICE_PUT_ORDER_ID, $order->getStoreId()));
 
            $page->setFillColor(new Zend_Pdf_Color_GrayScale(1));
            $this->_setFontRegular($page);
            $page->drawText(Mage::helper('sales')->__('Invoice # ') . $invoice->getIncrementId(), 35, 780, 'UTF-8');
 
            /* Add table */
            $page->setFillColor(new Zend_Pdf_Color_RGB(0.93, 0.92, 0.92));
            $page->setLineColor(new Zend_Pdf_Color_GrayScale(0.5));
            $page->setLineWidth(0.5);
 
            $page->drawRectangle(25, $this->y, 570, $this->y -15);
            $this->y -=10;
 
            /* Add table head */
            $page->setFillColor(new Zend_Pdf_Color_RGB(0.4, 0.4, 0.4));
            $page->drawText(Mage::helper('sales')->__('Products'), 35, $this->y, 'UTF-8');
			//Added for custom attribute "inchoo_warehouse_location"
            $page->drawText(Mage::helper('sales')->__('Warehouse Location'), 245, $this->y, 'UTF-8');
			$page->drawText(Mage::helper('sales')->__('SKU'), 325, $this->y, 'UTF-8');
            $page->drawText(Mage::helper('sales')->__('Price'), 380, $this->y, 'UTF-8');
            $page->drawText(Mage::helper('sales')->__('Qty'), 430, $this->y, 'UTF-8');
            $page->drawText(Mage::helper('sales')->__('Tax'), 480, $this->y, 'UTF-8');
            $page->drawText(Mage::helper('sales')->__('Subtotal'), 535, $this->y, 'UTF-8');
 
            $this->y -=15;
 
            $page->setFillColor(new Zend_Pdf_Color_GrayScale(0));
 
            /* Add body */
            foreach ($invoice->getAllItems() as $item){
                if ($item->getOrderItem()->getParentItem()) {
                    continue;
                }
 
                if ($this->y < 15) {
                    $page = $this->newPage(array('table_header' => true));
                }
 
                /* Draw item */
                $page = $this->_drawItem($item, $page, $order);
            }
 
            /* Add totals */
            $page = $this->insertTotals($page, $invoice);
 
            if ($invoice->getStoreId()) {
                Mage::app()->getLocale()->revert();
            }
        }
        $this->_afterGetPdf();
 
        return $pdf;
    }
 
	public function newPage(array $settings = array())
    {
        /* Add new table head */
        $page = $this->_getPdf()->newPage(Zend_Pdf_Page::SIZE_A4);
        $this->_getPdf()->pages[] = $page;
        $this->y = 800;
 
        if (!empty($settings['table_header'])) {
            $this->_setFontRegular($page);
            $page->setFillColor(new Zend_Pdf_Color_RGB(0.93, 0.92, 0.92));
            $page->setLineColor(new Zend_Pdf_Color_GrayScale(0.5));
            $page->setLineWidth(0.5);
            $page->drawRectangle(25, $this->y, 570, $this->y-15);
            $this->y -=10;
 
            $page->setFillColor(new Zend_Pdf_Color_RGB(0.4, 0.4, 0.4));
            $page->drawText(Mage::helper('sales')->__('Product'), 35, $this->y, 'UTF-8');
			//Added for custom attribute "inchoo_warehouse_location"
			$page->drawText(Mage::helper('sales')->__('Warehouse Location'), 245, $this->y, 'UTF-8');
            $page->drawText(Mage::helper('sales')->__('SKU'), 325, $this->y, 'UTF-8');
            $page->drawText(Mage::helper('sales')->__('Price'), 380, $this->y, 'UTF-8');
            $page->drawText(Mage::helper('sales')->__('Qty'), 430, $this->y, 'UTF-8');
            $page->drawText(Mage::helper('sales')->__('Tax'), 480, $this->y, 'UTF-8');
            $page->drawText(Mage::helper('sales')->__('Subtotal'), 535, $this->y, 'UTF-8');
 
            $page->setFillColor(new Zend_Pdf_Color_GrayScale(0));
            $this->y -=20;
        }
        return $page;
    }
}

Step 3

Now, you’ve done it. Test it out by going to “Sales->Invoices->(View any of them)->Print”. You shoud be asked to download PDF, and when you do, it should contain “Warehouse Location” by each of order items.

All you have to do is test it out and / or change it according to your needs!

I hope this was of help to someone!

Cheers!


62 comments

  1. Dear Sir,

    I want to display total weight of order in invoice pdf… please help me

  2. How can I get the warehouse location for a bundled product? The bundled simple products have different locations so can’t be gotten from the main bundled product.
    How would I get the attribute in the following loop?

    $options = $this->getItemOptions();
    if ($options) {
    foreach ($options as $option) {
    ...

  3. Call to a member function getPdf() on a non-object in /home/drcuser/public_html/magento-projects/hipsdead/app/code/core/Mage/Adminhtml/Controller/Sales/Invoice.php on line 119

  4. Hi I would like to display my company’s bank details in the footer area of the pdf invoice.

    Could you pls direct me with the proper code for this?

    Much appreciated

  5. How to get the seller information(the value present only in database not in attribute) from the database using sku no. and print the value in top of the invoice?

    1. Hi Chandra Sekar,
      I am also looking for a solution to get seller information in Invoice for a SKU/ order. If you have found any solution, kindly share.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <blockquote cite=""> <code> <del datetime=""> <em> <s> <strike> <strong>. You may use following syntax for source code: <pre><code>$current = "Inchoo";</code></pre>.