The invoices produced by nBill are template-driven.  It is therefore possible to format your invoice to get whatever look-and-feel you want, and you can use a different template for different vendors if you are making use of the multi-company feature. 

Full instructions for creating an invoice template are in the comments of the default template file (/components/com_nbill/templates/invoice_default/index.php), but for your convenience are reproduced here:

You can create your own invoice template based on this one, but if you want to modify this one directly, it is recommended to backup this file first (you should also keep a record of any changes you make and backup your customised file, as your changes could be lost when you upgrade). It is best to add your own template to another folder inside the components/com_nbill/templates folder, and update the vendor record with your own template's folder name. Here are step-by-step instructions on how to do that:
  1. Create a new folder in /components/com_nbill/templates named invoice_customised.
  2. Copy all the files from the /components/com_nbill/templates/invoice_default folder into your new invoice_customised folder.
  3. Rename the file default_template_line_item.php to customised_template_line_item.php.
  4. Open the file customised_template_line_item.php using a text editor such as notepad, and change the class name from 'nBillDefaultTemplateLineItem' to 'nBillCustomisedTemplateLineItem' (the name of the class must correspond with the name of the file so that it can be autoloaded).
  5. Open the file index.php (in your customised folder), and change 'nBillDefaultTemplateLineItem' to 'nBillCustomisedTemplateLineItem' (it should only appear once in that file, about half way down).
  6. Log into nBill administrator, go to the vendor record, edit the vendor, click on the 'advanced' tab, and change the invoice template to 'invoice_customised', then click save.
There are various variables and objects available to you, and these are described below. You can use standard PHP code and HTML to define how the data is displayed (bear in mind that this file is included once for each invoice).

CSS class definitions can be stored in a separate file called 'template.css' in the same folder as this index.php file.  A link to this CSS file (if it exists)
will automatically be added by the component. However, for maximum compatability between PDF and HTML versions, and readability via online document readers, it is recommended to define inline styles at the start of the template.

Do not try to link to template.css or any other style sheet from this template file as this would result in invalid HTML (the <head> section has already been defined by the time we get to this file), and the PDF generator (if you are using it) will probably not read the stylesheet.

Variables available:
Some of the variables are arrays indexed by document id - this is because the data
for all documents to be printed is already stored in these variables before this
template file is invoked to provide the layout for each document. You can just use
$document->id as the index for these arrays.

$pdf (boolean) Whether or not the output will be rendered as a PDF document (use this to suppress display of any elements that don't get rendered properly in PDF format - eg. shading and borders together can sometimes cause problems)
$template_path (string) Fully qualified path to this template
$logo_file (string) Fully qualified image file name for the logo associated with this vendor (use this to check whether a logo file exists)
$logo_src (string) HTTP src reference for the vendor logo (use this to actually include the image)
$currency_symbol (array) Array of currency symbols, indexed by document id
$date_format (string) Date format string (eg. "d/m/Y")
$document (object) Contains global information about the invoice, quote, or credit note:
        ->id (int) Unique document identifier
        ->vendor_id (int) Unique identifier for vendor (you can ignore this)
        ->client_id (int) Unique identifier for client (you can ignore this)
        ->document_no (string) The invoice, quote, or credit note number
        ->vendor_name (string) Name of the vendor
        ->vendor_address (string) Address of vendor (bear in mind that this might contain line breaks ("\n") which need converting to "<br />")
        ->billing_name (string) Name of person or company to whom document is made out
        ->billing_address (string) Billing address (bear in mind that this might contain line breaks ("\n") which need converting to "<br />")
        ->billing_country (string) 2 character country code
        ->billing_country_desc (string) Full country name (NOTE: This may appear in upper case - use nbf_common::nb_ucwords(nbf_common::nb_strtolower($document->billing_country_desc)) to convert to title case)
        ->reference (string) Your own reference
        ->document_date (int) Date expressed as number of seconds since UNIX epoch (1st Jan 1970) - use nbf_common::nb_date() function in conjunction with $date_format variable to return a readable date
        ->tax_desc (string) Description of Vendor's tax code (eg. "VAT Number")
        ->tax_no (string) Vendor's VAT number or equivalent
        ->tax_exemption_code (string) Client's VAT number or reseller certification number
        ->currency (string) 3 character currency code (eg. USD or GBP)
        ->total_net (decimal) Net total of document
        ->total_tax (decimal) Total tax for document
        ->total_shipping (decimal) Total shipping for document
        ->total_shipping_tax (decimal) Total tax for shipping
        ->total_gross (decimal) Gross total
        ->small_print (string) Legal information
        ->status (string) Quote status code (look up value on cross reference table) - not applicable to invoices or credit notes
        ->notes (string) Your own additional notes - NB. In most cases, you will not want this displayed on the invoice!
        ->document_type (string) 'IN' = Invoice; 'CR' = Credit Note; 'QU' = Quote;
        ->quote_status_desc (string) Quote status description (eg. Accepted, Rejected)
$document_items (array) Array of objects containing information about the individual items that make up the invoice, quote, or credit note
        ->id (int) Unique ITEM identifier
        ->document_id (int) Unique identifier (NB. ALWAYS check that this matches the value in $document->id otherwise you might end up writing items from other documents onto the current one!)
        ->vendor_id (int) Unique identifier for vendor (you can ignore this)
        ->client_id (int) Unique identifier for client (you can ignore this)
        ->nominal_ledger_code (string) This would not normally be included on the document, so ignore it
        ->product_description (string) Item description (max 255 characters)
        ->detailed_description (string) HTML description (unlimited size)
        ->net_price_per_unit (decimal) Cost per unit of the given item
        ->no_of_units (decimal) Quantity (note, this can be a decimal fraction)
        ->discount_amount (decimal) Amount of any discount applied to this item
        ->discount_description (string) Description of discount (ie. what it's for)
        ->net_price_for_item (decimal) Net price after multiplying unit price by quantity and subtracting any discount
        ->tax_for_item (decimal) Amount of tax
        ->shipping_id (int) Unique identifier for shipping service (you can ignore this)
        ->shipping_for_item (decimal) Cost of shipping for this item
        ->tax_for_shipping (decimal) Amount of tax applied to shipping amount
        ->gross_price_for_item (decimal) Total price for this item, including tax and shipping
        ->section_name (string) name of a section which groups this item with all previous items since the last section break
        ->section_discount_percent (decimal) Percentage discount to apply to items within this section
        ->section_discount_title (string) Description of discount

nBill v2.x only: The following "$hide_" variables allow you to determine whether it is possible to suppress the display of certain fields to save space (eg. if there is only one unit mentioned on the document, there is no need to display the unit price and quantity). However, you do not have to hide these fields if you don't want to. All of these "$hide_" variables are arrays indexed by document id.
$hide_unit_price
$hide_quantity
$hide_discount
$hide_net_price
$hide_tax
$hide_shipping
$hide_shipping_tax

Custom line item output

As of version 3 of nBill, the actual line items are output using the built-in document rendering engine. You can override the behaviour of that to change the way line items are output (for example to hide certain columns, change the order of columns, or change the format of the data). As an example of how to do this, here are instructions on how you could hide the net and gross total columns and swap round the order of the quantity and unit price columns. Naturally you can adapt this to make other changes.

First, create a new invoice template, as described in the numbered list at the top of this page.

Now you can override any of the output from /administrator/components/com_nbill/classes/document/line_item/view/line_item_html.php by copying the function you want to change from that file and pasting it into the class definition of your customised_template_line_item.php file - before you start making changes, check to make sure that invoices are still showing up correctly with no error messages.

For example, to hide the net total and gross total columns, you can override the canHideColumn function, so that your customised_template_line_item.php file looks like this:

<?php
class nBillCustomisedTemplateLineItem extends nBillLineItemHtml
{
    /**
    * You can override the default line item output here (the default output is in the file
    * /administrator/components/com_nbill/classes/document/line_item/view/line_item_html.php).
    * Just copy the function you want to override from that file into this, and make your changes in this file.
    * You can then upgrade nBill without losing your customisation. Please note however, that you still need to
    * copy the template folder (/components/com_nbill/templates/invoice_default), to a new folder (named whatever
    * you want, but use a prefix of invoice_) and select your new folder as the invoice template on the vendor
    * record in nBill (as this invoice_default folder will be overwritten when you upgrade nBill)
    */

    protected function canHideColumn($column)
    {
        switch ($column) {
case 'net_price_for_item':
            case 'gross_price_for_item':
                return true;
        }
        return parent::canHideColumn($column);
    }
}

The column names you can specify here are net_price_per_unit, discount_amount, net_price_for_item, tax_for_item, shipping_for_item, tax_for_shipping, and gross_price_for_item.

To swap round the quantity and unit price columns (so the quantity is shown first), we need to copy the renderHeadingColumns and renderColumnValues functions from /administrator/components/com_nbill/classes/document/line_item/view/line_item_html.php to our customised_template_line_item.php file, and simply swap the lines around so that the quantity is output first. Our customised_template_line_item.php file now looks like this:

<?php
class nBillCustomisedTemplateLineItem extends nBillLineItemHtml
{
    /**
    * You can override the default line item output here (the default output is in the file
    * /administrator/components/com_nbill/classes/document/line_item/view/line_item_html.php).
    * Just copy the function you want to override from that file into this, and make your changes in this file.
    * You can then upgrade nBill without losing your customisation. Please note however, that you still need to
    * copy the template folder (/components/com_nbill/templates/invoice_default), to a new folder (named whatever
    * you want, but use a prefix of invoice_) and select your new folder as the invoice template on the vendor
    * record in nBill (as this invoice_default folder will be overwritten when you upgrade nBill)
    */

    protected function canHideColumn($column)
    {
        switch ($column) {
            case 'net_price_for_item':
case 'gross_price_for_item':
                return true;
        }
        return parent::canHideColumn($column);
    }

    protected function renderHeadingColumns($styles)
    {
        list($style_th_left, $style_th) = $styles;
        $this->renderColumnHeading('product_description', 'NBILL_PRT_DESC', 'main_headings', 'style="' . $style_th_left . '"');
        $this->renderColumnHeading('no_of_units', 'NBILL_PRT_QUANTITY', 'main_headings', 'style="' . $style_th . '"');
        $this->renderColumnHeading('net_price_per_unit', 'NBILL_PRT_UNIT_PRICE', 'main_headings', 'style="' . $style_th . '"');
        $this->renderColumnHeading('discount_amount', 'NBILL_PRT_DISCOUNT', 'main_headings', 'style="' . $style_th . '"');
        $this->renderColumnHeading('net_price_for_item', 'NBILL_PRT_NET_PRICE', 'main_headings', 'style="' . $style_th . '"');
        $this->renderColumnHeading('tax_for_item', strlen(@$this->document->tax_abbreviation) == 0 ? 'NBILL_PRT_VAT' : $this->document->tax_abbreviation, 'main_headings', 'style="' . $style_th . '"');
        $this->renderColumnHeading('shipping_for_item', 'NBILL_PRT_SHIPPING', 'main_headings', 'style="' . $style_th . '"');
        $this->renderColumnHeading('tax_for_shipping', sprintf($this->translator->parseTranslation($this->document->language, 'NBILL_PRT_SHIPPING_VAT', "template.common"), strlen(@$this->document->tax_abbreviation) > 0 ? $this->document->tax_abbreviation : $this->translator->parseTranslation($this->document->language, 'NBILL_PRT_VAT', "template.common")), 'main_headings', 'style="' . $style_th . '"');
        $this->renderColumnHeading('gross_price_for_item', 'NBILL_PRT_TOTAL', 'main_headings', 'style="' . $style_th . '"');
    }

    protected function renderColumnValues(nBillLineItem $line_item, $styles)
    {
        list($style_td_left, $style_td_numeric) = $styles;
        $description = $this->getFullDescription($line_item);
        $this->renderColumnValue('product_description', $description, '', 'style="' . $style_td_left . '"');
        $this->renderColumnValue('no_of_units', $line_item->no_of_units, '', 'style="' . $style_td_numeric . '"');
        $this->renderColumnValue('net_price_per_unit', $line_item->net_price_per_unit, '', 'style="' . $style_td_numeric . '"');
        $discount = $line_item->discount_amount->format();
        if (strlen($line_item->discount_description) > 0) {
            $discount .= ' (' . $line_item->discount_description . ')';
        }
        $this->renderColumnValue('discount_amount', $discount, '', 'style="' . $style_td_numeric . '"');
        $this->renderColumnValue('net_price_for_item', $line_item->net_price_for_item, '', 'style="' . $style_td_numeric . '"');
        $this->renderColumnValue('tax_for_item', $line_item->tax_for_item, '', 'style="' . $style_td_numeric . '"');
        $this->renderColumnValue('shipping_for_item', $line_item->shipping_for_item, '', 'style="' . $style_td_numeric . '"');
        $this->renderColumnValue('tax_for_shipping', $line_item->tax_for_shipping, '', 'style="' . $style_td_numeric . '"');
        $this->renderGrossPriceColumnValue($line_item, $styles);
    }
}

That's it. Of course in this particular case, we could delete a couple of lines from each of those two functions, as we are not rendering the net or gross price columns, but that won't make any practical difference, as the canHideColumn function override already takes care of it.

© 2016 Encke Technologies SRL. All Rights Reserved.