Customize invoice print with Javascript

In this article

The following examples show how to adapt invoice printing with custom JavaScript hook function codes.

See Javascript customization for more information.

Credit Notes without final text

Final text, notes and greetings are always printed, when defined, for both invoices and credit notes document types.
You can define a document type with the Type column of the Transactions table:

  • For credit notes insert the value 12.
  • For invoices insert the value 10.

In this example we want to make sure that all these texts are printed only for invoices but not for credit notes.

To do that, we simply define an hook function that replaces the default print_final_texts() function.

/** 
 * This function prints the final text only for INVOICES and not for CREDIT NOTES.
 * Invoices = DocType 10
 * Credit notes = DocType 12
 */
function hook_print_final_texts(repDocObj, invoiceObj, userParam) {
   // We can check the DocType and print the text only when is not 12
   if (invoiceObj.document_info.doc_type !== "12") {
      print_final_texts(repDocObj, invoiceObj, userParam);
   }
}

With this change the final text, notes and greetings are now printed only for invoices, and not for credit notes anymore.

Add information "Invoice paid" to the final text

This example shows how to add the information "Invoice paid" to the final text, when the invoice is paid.

/** 
 * This function prints the text "Invoice paid" on paid invoices.
 */
function hook_print_final_texts(repDocObj, invoiceObj, userParam) {
   if (invoiceObj.payment_info && invoiceObj.payment_info.payment_date) { 
      var paragraph = repDocObj.addParagraph("","final_texts");
      paragraph.addText("Invoice paid on " + Banana.Converter.toLocaleDateFormat(invoiceObj.payment_info.payment_date));
      // [Optionally] Add a signature
      repDocObj.addImage("documents:sign.jpg", "6cm", "auto");
   }
}

Add a custom table as final text

This example shows how to add a custom table in the final texts of the invoice.
The table consists of 2 columns and three rows:

  • Row 1: the header of the table. Contains the titles of the columns (Description and Amount).
  • Row 2: the first data row of the table.
  • Row 3: the second data row of the table.

To do that, we simply define an hook function that replaces the default print_final_texts() function.

/** 
 * This function adds at the end of the invoice a table with a custom text.
 */
function hook_print_final_texts(repDocObj, invoiceObj, userParam) {
   print_final_texts(repDocObj, invoiceObj, userParam);
   // Add a table
   var mytable = repDocObj.addTable("MyTable");
   var tableRow;
   
   // Row 1: the header of the table, columns titles
   var header = mytable.getHeader();
   tableRow = header.addRow();
   tableRow.addCell("Description").setStyleAttributes("text-align:left; font-weight:bold; border:thin solid black;");
   tableRow.addCell("Amount").setStyleAttributes("text-align:left; font-weight:bold; border:thin solid black;");
   // Row 2: first data row of the table
   tableRow = mytable.addRow();
   tableRow.addCell("Workshop").setStyleAttributes("text-align:left; border:thin solid black;");
   tableRow.addCell("2'600.00").setStyleAttributes("text-align:right; border:thin solid black;");
   // Row 3: second data row of the table
   tableRow = mytable.addRow();
   tableRow.addCell("Material").setStyleAttributes("text-align:left; border:thin solid black;");
   tableRow.addCell("76.00").setStyleAttributes("text-align:right; border:thin solid black;");
   
   //...
}

You can easily add as many columns and rows as you like.

Use the setStyleAttributes() to apply CSS styles, like text-align, font-weight, color, border, ... Find more information on Syntax of a CSS stylesheet.

Find more examples in Working with Report Tables.

Example print:
javascript invoice customization

Add a custom table as final text with bank details

This example shows how to add a custom table in the final texts of the invoice with the bank details for the payment.
The table consists of 2 columns and 6 rows:

  • Row 1: for the beneficiary data.
  • Row 2-3-4: for the bank name and address.
  • Row 5: for the IBAN code.
  • Row 6: for the Swift code.

To do that, we simply define an hook function that replaces the default print_final_texts() function.

/** 
 * This function adds at the end of the invoice a table with bank detais for the payment.
 */
function hook_print_final_texts(repDocObj, invoiceObj, userParam) {
   print_final_texts(repDocObj, invoiceObj, userParam);
   // Add a table
   var mytable = repDocObj.addTable("MyTable");
   var tableRow;
   // Row 1
   tableRow = mytable.addRow();
   tableRow.addCell("Beneficiary:").setStyleAttributes("text-align:left;padding-left:1px;");
   tableRow.addCell("BENEFICIARY NAME, ADDRESS, ZIP LOCALITY, COUNTRY").setStyleAttributes("text-align:left;padding-left:1px;");
   
   // Row 2
   tableRow = mytable.addRow();
   tableRow.addCell("Bank: ").setStyleAttributes("text-align:left;padding-left:1px;");
   tableRow.addCell("BANK NAME").setStyleAttributes("text-align:left;padding-left:1px;");
   // Row 3
   tableRow = mytable.addRow();
   tableRow.addCell("").setStyleAttributes("text-align:left;padding-left:1px;");
   tableRow.addCell("ADDRESS").setStyleAttributes("text-align:left;padding-left:1px;");
   // Row 4
   tableRow = mytable.addRow();
   tableRow.addCell("").setStyleAttributes("text-align:left;padding-left:1px;");
   tableRow.addCell("ZIP LOCALITY").setStyleAttributes("text-align:left;padding-left:1px;");
   // Row 5
   tableRow = mytable.addRow();
   tableRow.addCell("IBAN: ").setStyleAttributes("text-align:left;padding-left:1px;");
   tableRow.addCell("CHXX XXXX XXXX XXXX XXXX X").setStyleAttributes("text-align:left;padding-left:1px;");
   // Row 6
   tableRow = mytable.addRow();
   tableRow.addCell("Swift:").setStyleAttributes("text-align:left;padding-left:1px;");
   tableRow.addCell("AAAABBCCXXX").setStyleAttributes("text-align:left;padding-left:1px;");
   
   //...
}

You can easily add as many columns and rows as you like.

Use the setStyleAttributes() to apply CSS styles, like text-align, font-weight, color, border, ... Find more information on Syntax of a CSS stylesheet.

Example print:
javascript invoice customization

Add a custom table with text translation

This example shows how to add a custom table in the final texts of the invoice with text translations for different languages.
The table consists of 2 columns and three rows:

  • Row 1: the header of the table. Contains the titles of the columns (Description and Amount).
  • Row 2: the first data row of the table.
  • Row 3: the second data row of the table.

To do that, we simply define an hook function that replaces the default print_final_texts() function.

/** 
 * This function adds at the end of the invoice a table with a custom text.
 * The text is translated in different languages.
 * We use the text in the language of the invoice.
 */
function hook_print_final_texts(repDocObj, invoiceObj, userParam) {
   // Define the texts for all languages you need (en, de, fr, it, nl, pt, zh, es, ...)
   // Check the language of the invoice to use the appropriate text translation
   if (lang === "de") {
      var text1 = "Beschreibung";
      var text2 = "Betrag";
      var text3 = "Werkstatt";
      var text4 = "2'600.00";
      var text5 = "Material";
      var text6 = "76.00";
   }
   else if (lang === "it") {
      var text1 = "Descrizione";
      var text2 = "Importo";
      var text3 = "Officina";
      var text4 = "2'600.00";
      var text5 = "Materiale";
      var text6 = "76.00";
   }
   else {
      var text1 = "Description";
      var text2 = "Amount";
      var text3 = "Workshop";
      var text4 = "2'600.00";
      var text5 = "Material";
      var text6 = "76.00";
   }
   // Add a table
   var mytable = repDocObj.addTable("MyTable");
   var tableRow;
   
   // Row 1: the header of the table, columns titles
   var header = mytable.getHeader();
   tableRow = header.addRow();
   tableRow.addCell(text1).setStyleAttributes("text-align:left; font-weight:bold; border:thin solid black;");
   tableRow.addCell(text2).setStyleAttributes("text-align:left; font-weight:bold; border:thin solid black;");
   // Row 2: first data row of the table
   tableRow = mytable.addRow();
   tableRow.addCell(text3).setStyleAttributes("text-align:left; border:thin solid black;");
   tableRow.addCell(text4).setStyleAttributes("text-align:right; border:thin solid black;");
   // Row 3: second data row of the table
   tableRow = mytable.addRow();
   tableRow.addCell(text5).setStyleAttributes("text-align:left; border:thin solid black;");
   tableRow.addCell(text6).setStyleAttributes("text-align:right; border:thin solid black;");
}

You can easily add as many columns and rows as you like.

Use the setStyleAttributes() to apply CSS styles, like text-align, font-weight, color, border, ... Find more information on Syntax of a CSS stylesheet.

Find more examples in Working with Report Tables.

 

Add a begin text with Markdown

This example for the Estimates and Invoice application, shows how to add a begin text of the invoice/estimate using the Markdown (requires Banana+ Dev Channel).

/**
* This function adds the begin text as Markdown
* Works with the Estimate and Invoice Application
*/
function hook_print_text_begin(repDocObj, invoiceObj, texts, userParam) {
  var textTitle = getTitle(invoiceObj, texts, userParam);
  var textBegin = invoiceObj.document_info.text_begin;
  var table = repDocObj.addTable("begin_text_table");
  if (textTitle) {
    textTitle = textTitle.replace("<DocInvoice>", invoiceObj.document_info.number);
    var tableRow = table.addRow();
    var titleCell = tableRow.addCell("","",1);
    titleCell.addParagraph(textTitle, "title_text");
  }
  if (textBegin) {
    var tableRow = table.addRow();
    var textCell = tableRow.addCell("","begin_text",1);
    textCell.addStructuredText(textBegin, "md", "");
  }
}

 

Add a final text with Markdown

This example for the Estimates and Invoice application, shows how to add a final text of the invoice/estimate using the Markdown (requires Banana+ Dev Channel).

/**
* This function adds the final text as Markdown
* Works with the Estimate and Invoice Application
*/
function hook_print_final_texts(repDocObj, invoiceObj, userParam) {
  if (invoiceObj.note.length > 0) {
    for (var i = 0; i < invoiceObj.note.length; i++) {
      if (invoiceObj.note[i].description) {
        var text = invoiceObj.note[i].description;
        var paragraph = repDocObj.addParagraph("","final_texts");
        paragraph.addStructuredText(text, "md", "");
      }
    }    
  }
}

 

First page without page number

Normally the page number is printed on each page of the invoice in the information section.

In this example we want to make sure that the page number is not printed on the first page of the invoice.
To do that, we simply define an hook function that replaces the default print_info_first_page() function. 

/** 
* This function do not prints the PAGE NUMBER on first page
*/
function hook_print_info_first_page(repDocObj, invoiceObj, texts, userParam) {
   // Save the existing settings
   var originalInfoPage = userParam.info_page;
   // Set not to print the info_page
   userParam.info_page = false;
   // call the original function
   print_info_first_page(repDocObj, invoiceObj, texts, userParam);
   // Restore original values
   userParam.info_page = originalInfoPage ;
}

With this change the page number is now printed only from page two and above.

Add an additional image

In case you want to add an additional image in any section of the invoice, you can do it using the Documents table.

  • Add a new image to the Documents table.
    • In the ID column enter the file name (e.g. "myImage").
    • In the Description column enter a comment (optional).
    • In the Attachments column, double click on the cell or select the edit symbol, then select Image and comfirm with Ok.
    • Select the image you want to use and confirm.
  • Use javascript code to add the image in the hook function of the invoice section you want.
    • The code addImage("documents:<id_value>", "<width>", "<height>") allows to add the image to the ReportElement.
    • <id_value> the value of the ID column of the Documents table (e.g. "myImage").
    • <width> you can adjust the width of the image.
    • <height> you can adjust the height of the image.

Let's suppose for example that we want to add an image in the final text section, after the invoice details.
To do that, we simply define an hook function that replaces the default print_final_texts() function.

/*
 * This function adds an image in the final texts section
 */
function hook_print_final_texts(repDocObj, invoiceObj, userParam) {
  
  //Print final texts
  print_final_texts(repDocObj, invoiceObj, userParam);
  //Add an image of the table Documents at the end
  repDocObj.addImage("documents:myImage", "100%", "auto");
}

With this change, the image is printed at the end of the invoice.

Add additional notes based on quantity

Suppose you have an additional column called "AdditionalNotes", and you want to add a different text to this column depending on the quantity of the item.
For example, for quantities greater than 10 you want to add the text "Special price" in the "AdditionalNotes" column of the print, and you want to do it automatically without entering by hand the text on each invoice.

To do that, we define an hook function that replaces the default formatItemsValue() function.

function hook_formatItemsValue(value, columnName, className, item) {
  var itemFormatted = {};
  itemFormatted.value = "";
  itemFormatted.className = "";
  if (columnName === "additionalnotes") {
    if (item.quantity > 10) {
        itemFormatted.value = "Special price";
        itemFormatted.className = className;
    }
  }
  //If not used it must always return undefined
  return itemFormatted;
}

The itemFormatted object has two properties:

  • value is the value of the column that is printed in the invoice.
  • className is the name of the class in the CSS file.

With this, when you create the invoice all the items with the quantity greater than 10 have an additional text in the "AdditionalNotes" column. For all the others it remains empty.

Example print:
javascript invoice customization

Use macros to add texts

Suppose you want to add a different text to the Description column of the invoice print depending on the item, and you want to do it automatically without entering by hand the text on each invoice.
You could for example associate the desired text to macros, add the macros in the Description column of the Transactions table, and then replace these macros with the acutal text.

To do that:

  • Define the macro name and the text associated to it. For example, we want to associate the text "Special offer!" to the macro called "#macro1".
  • Add the "#macro1" text to the Description column of the Transaction table for all the items we want to add the "Special offer" text.
  • Define an hook function that replaces the default formatItemsValue() function. This automatically replaces "#macro1“ with "Special offer!".
function hook_formatItemsValue(value, columnName, className, item) {
  var itemFormatted = {};
  itemFormatted.value = "";
  itemFormatted.className = "";
  if (columnName === "description") {
    if (value && value.indexOf("#macro1") > -1) {
       itemFormatted.value = value.replace("#macro1","\nSpecial offer!");
       itemFormatted.className = className;
    }
  }
  return itemFormatted;
}

The itemFormatted object has two properties:

  • value is the value of the column that is printed in the invoice.
  • className is the name of the class in the CSS file.

With this, when you create the invoice, the “#macro1“ text contained in the items description are replaced with the "Special offer!" text.

Example print:
javascript invoice customization

Change style of an item value

Suppose you want to change the style of an item in the Description column of the invoice in order to print it bold.

To do that:

  • Define the macro name like for example "#bold".
  • Add the "#bold" text to the Description column of the Transaction table for all the items you want to change the text style to bold.
  • Define an hook function that replaces the default formatItemsValue() function. This automatically removes the "#bold“ text and change the style.
function hook_formatItemsValue(value, columnName, className, item) {
  var itemFormatted = {};
  itemFormatted.value = "";
  itemFormatted.className = "";
  if (columnName === "description") {
    if (value && value.indexOf("#bold") > -1) {
      itemFormatted.value = value.replace("#bold","");
      itemFormatted.className = "bold";
    }
  }
  return itemFormatted;
}

The itemFormatted object has two properties:

  • value is the value of the column that is printed in the invoice.
  • className is the name of the class in the CSS file.

In this case all the texts “#bold“ contained in the items description are not printed, and the styles are changed to bold.

The class "bold" that we set in the line itemFormatted.className = "bold" already exists in the CSS file of the invoice. If you want to use other classes that don't exist, you need also to use the CSS customization in order to create them first.

Example print:
javascript invoice customization

Change the font size of an item description

In this example, we want to change the font size of a specific item description text.

To do that we use the Javascript customization and also the CSS customization:

  • Define a macro name like for example "#myFontSize". For each items description you want to change the font size, add the "#myFontSize" text at the end of the description.
  • In Documents table:
    • Add a new Javascript-type attachment.
      Define then the hook function that replaces the default formatItemsValue() function.
      This automatically removes the "#myFontSize“ text and changes the font size.
      As ID name use for example "myStyle.js".
    • Add a new CSS-type attachment.
      Define then the CSS class with the font size you want to use. Since the class that defines the font size does not exist in the CSS file of the invoice, you also have to create it.
      As ID name use for example "myStyle.css".
  • In CH10 / UNI11 layout settings, section Javascript / CSS, enter the appropriate names ("myStyle.js" and "myStyle.css").

Javascript hook function code:

function hook_formatItemsValue(value, columnName, className, item) {
  var itemFormatted = {};
  itemFormatted.value = "";
  itemFormatted.className = "";
  if (columnName === "description") {
    if (value && value.indexOf("#myFontSize") > -1) {
      itemFormatted.value = value.replace("#myFontSize","");
      itemFormatted.className = "myFontSize";
    }
  }
  return itemFormatted;
}

CSS code:

.myFontSize {
   font-size: 8pt;
}

Change the font size value as you desire.

When you create the invoice, the size of the texts in the descriptions changes.

Use different IBAN codes

The IBAN code is normally set either in the File → File and accounting properties → Address section or directly from the Invoice Settings under the related IBAN entry.

If you have more than one IBAN code to use and you want to decide to use one rather than another, you must manually change it when creating each invoice from the Invoice Settings.

However, using customization with Javascript it is possible to associate a different IBAN code to each customer. In this way, when you create the invoice, the script will automatically assign and insert the IBAN.

To do that we define the hook_modify_settings_qr() function that replaces the default modify_settings_qr() function.

function hook_modify_settings_qr(invoiceObj, qrcodeData) {
   //Assign the IBAN code CHXXXXXXXXXXXXXXXXXXX to the customer 1101
   if (invoiceObj.customer_info.number === "1101") {
      qrcodeData.supplierIbanNumber = "CHXXXXXXXXXXXXXXXXXXX";
   }
   //Assign the IBAN code CHYYYYYYYYYYYYYYYYYYY to the customer 1102
   else if (invoiceObj.customer_info.number === "1102") {
      qrcodeData.supplierIbanNumber = "CHYYYYYYYYYYYYYYYYYYY";
   }
   //Assign the IBAN code CHZZZZZZZZZZZZZZZZZZZ to the customer numbers from 1103 to 1107
   else if (invoiceObj.customer_info.number >= "1103" && invoiceObj.customer_info.number <= "1107") { 
      qrcodeData.supplierIbanNumber = "CHZZZZZZZZZZZZZZZZZZZ";
   }
	// ...
}

Copy the code above and just replace:

  • the value of invoiceObj.customer_info.number with the customer account you want (e.g. 1101, 1102, 1103, ...)
  • the value of qrcodeData.supplierIbanNumber with the IBAN number you want (e.g. CHXXXXXXXXXXXXXXXXXXX, CHYYYYYYYYYYYYYYYYYYY, CHZZZZZZZZZZZZZZZZZZZ, ...)
  • You can also add/remove more cases.

With this, when you create the invoice the IBAN code is set automatically, and it is no longer necessary to change the invoice settings every time.

Use another date format

The date format is taken from the operating system settings.

This example shows how to use another date format for all Date-type columns in the invoice details, without changing the operating system settings.

To do that:

  • The XML name of the column in Transaction table must begin with the word Date (eg DateWork, DateExecution, DateXxx).
  • Define the hook_formatItemsValue() function.
  • In the function set the format of the date you want to use.
    Format examples:
    • dd.mm.yyyy
    • dd/mm/yyyy
    • dd-mm-yyyy
    • yyyy.mm.dd
    • yyyy/mm/dd
    • yyyy-mm-dd

function hook_formatItemsValue(value, columnName, className, item) {
  var itemFormatted = {};
  itemFormatted.value = "";
  itemFormatted.className = "";
  if (columnName.startsWith("date")) {
    itemFormatted.value = Banana.Converter.toLocaleDateFormat(value, "dd.mm.yyyy"); // insert here the format
    itemFormatted.className = className;
  }
  return itemFormatted;
}

When you create the invoice, all dates in details table will be printed with the new format.

Example print:
javascript invoice customization

Print images of items

This example shows how to add and print items images on the invoice details. Each item in the Items table is associated with an image and the image is then printed on the invoice.

To do this:

  • Add Images to each item:
    • Save all the images of your items
      • Use the same directory or in a sub-directory where you have estimates and invoices .ac2 file.
      • Supported image formats are: png and jpg.
      • It is recommended to use small and light images.
        The size of the pdf file will depend on the weight of the images.
        The lighter the images, the less the pdf will weigh.
        The heavier the images, the heavier the pdf file will also weigh.
    • Make the Links column visible.
      In the Items table, make the Links column visible.
      See also: Columns setup.
      If the Links column should not be available in the list of available columns, visible in the Columns Setup window, the column can be added manually via the Data menu → Columns setup → Add Columns button, (For files in the Dutch language, enter Koppelingen for the Name, Links for the XML name and select Koppelingen for the Data Type/Gegevenstype).
    • Link images to items.
      In the Links column of the Items table, now add an image link for each item in the table.
      Click on the small icon at the top right of the cell and select the image you want to use.
  • Add the javascript hook replacement function
    For this example we use the function that prints the invoice with net amounts (VAT excluded).
    Define the hook_print_details_net_amounts() function that will replace the default one.
    You can find the code in GitHub.
  • Set invoice layout parameters.
    • In the Invoice Settings → Invoice details, add the columns "I.Links" (image link column) and "Number" (item number column) .
      • I.Links;Number;Description;Quantity;ReferenceUnit;UnitPrice;Amount
        10%;10%;30%;10%;10%;15%;15%
        left;left;left;right;center;right;right
        left;left;left;right;center;right;right
    • In the Invoice SettingsTexts, add the column names.
      • Image;Item;Description;Quantity;Unit;Unit Price;Amount

When you print the invoice, the items will be printed with an image.

Example print:
javascript invoice customization

Print 0% VAT rate

This example shows how to print the VAT amounts with a rate of 0%.

To do this:

  • add the following javascript snippet to your accounting in the documents table (see image below)
  • add the reference to this hook in the settings dialog of the invoice extension (see image below)

function hook_print_details_net_amounts(banDoc, repDocObj, invoiceObj, texts, userParam, detailsTable, variables) {
  //PRINT 0% VAT RATE
  if (invoiceObj.billing_info.total_vat_rate_zero) {
    invoiceObj.billing_info.total_vat_rate_zero.vat_rate="0.00";
    invoiceObj.billing_info.total_vat_rates.unshift(invoiceObj.billing_info.total_vat_rate_zero);
  }
  print_details_net_amounts(banDoc, repDocObj, invoiceObj, texts, userParam, detailsTable, variables); 
}

Example print:

javascript invoice customization

Table documents where the custom javascript is defined

javascript invoice customization

Settings dialog of the invoice extension where you have to indicate the hook that overwrites the original function

javascript invoice customization

Print quantities without decimals

This example for the Integrated Invoice, shows how to print quantities without decimals.

To do this:


function hook_set_variables(variables, userParam) {
	variables.decimals_quantity = 0;
}

 

Change decimals of amounts

This example for the integrated invoice shows how to change the decimals of the invoice amounts (quantity, unit price and amounts).

To do this:

  • Add the following javascript code to your accounting in the Documents table.
  • Change the number of decimals according to your needs.
  • Add the reference to this javascript file in the Invoice Settings.
    For more information see Add your custom Javascript file.
function hook_set_variables(variables, userParam) {
   variables.decimals_quantity = 4;
   variables.decimals_unit_price = 4;
   variables.decimals_amounts = 4;
}

Other examples and needs

With CSS and Javascript you can completely customize the invoice appearance.
If you have other specific needs, you can contact our customer service.

 

Tell us how we can help you better
If the information on this page is not what you're looking for, is not clear enough, or is not up-to-date, let us know.

Share this article: Twitter | Facebook | LinkedIn | Email