Create an ODT or ODS document template: Difference between revisions

From Dolibarr ERP CRM Wiki
Jump to navigation Jump to search
(Adding ODT substitution and lines custom substitution function)
Line 91: Line 91:
This an example of what you may have in your office suite:
This an example of what you may have in your office suite:
[[File:Line for document generation.png|500px]]
[[File:Line for document generation.png|500px]]
=== Conditional substitution ===
Starting from Dolibarr v3.3, you can use conditional substitutions, which in layman terms means that you can decide to print something if a variable is true, or print something else if it's false (or nothing at all) - including text but also any more complex structures like tables and images.
Example:
<pre>
[!-- IF {my_var} --]
Print this text if {my_var} is true (can be any value but null/0/empty string)
[!-- ELSE {my_var} --]
Or print this if it's false (null/0/empty string)
[!-- ENDIF {my_var} --]
</pre>


=== Other personalized tags ===
=== Other personalized tags ===
If you want to add a field that is not predefined, this is the solution:
If you want to add a field that is not predefined, this is the solution:
* Add a file into '''htdocs/core/substitutions/functions_mymodule.lib.php''' (htdocs/includes/modules/substitutions/functions_mymodule.lib.php with version 3.1 or previous)
* Create a file into one of those locations:
'''htdocs/core/substitutions/functions_mymodule.lib.php''' with v3.2 or above
'''htdocs/mymodule/core/substitutions/functions_mymodule.lib.php''' with v3.2 or above
'''htdocs/includes/modules/substitutions/functions_mymodule.lib.php''' with version 3.1 or previous
* Inside this file, just write one function like this:
* Inside this file, just write one function like this:
<source lang="php">
<source lang="php">
Line 125: Line 141:
</source>
</source>
and module has been activated.
and module has been activated.
Note2: this only allows to define global, static ODT variables (ie: to make dynamic variables that changes for every line of product, please see the next chapter).
=== Other personalized tags for lines ===
This function is available since Dolibarr v3.3 (future development version).
Similarly to the previous chapter, you have to define a function, and it works about the same, but with a few twists:
* Create or edit the same file as before (see the previous chapter).
* Here are the twists: in the file, write another function with almost the same name but with '_lines' appended, and also add a new $lines variable:
<source lang="php">
/** Function called to complete substitution array for lines (before generating on ODT, or a personalized email)
* functions xxx_completesubstitutionarray_lines are called by make_substitutions() if file
* is inside directory htdocs/core/substitutions
*
* @param array $substitutionarray Array with substitution key=>val
* @param Translate $langs Output langs
* @param Object $object Object to use to get values
*              @param  Object          $line                  Current line being processed, use this object to get values
* @return void The entry parameter $substitutionarray is modified
*/
function mymodule_completesubstitutionarray_lines(&$substitutionarray,$langs,$object,$line) {
{
  global $conf,$db;
  $myvalue='Put here calculated value to insert';
  $substitutionarray['myowntag']=$myvalue;
}
</source>
Contrary to the previous function which was called only once, this function will be called everytime a line of product will be processed, giving you each time a new $line object that you can process.


== Store your document ==
== Store your document ==
To have your document to appear in list of available documents, put it into correct subdirectory found into
To have your document to appear in list of available documents, put it into correct subdirectory found into
directory '''documents/doctemplates'''
directory '''documents/doctemplates'''

Revision as of 20:20, 17 August 2012

This page describe how to build an ODT document template to build documents using ODT generation.

To know how to build a PDF template, see page Create a PDF document template. Building a PDF template require PHP development knowledge, but not building an ODT template.

Prerequisite

  • Dolibarr: 3.1+
  • OpenOffice: 3.2+, LibreOffice, ...

Create your document

  • Create from scratch an empty openoffice document and take a provided example. You may find them installed into a subdirectory of directory documents/doctemplates
  • Edit your document using all your Office suite features.

Include in your document the tags you want to see. Tags will be replaced during generation of document automatically by Dolibarr. List of all available tags are provided in next chapter.

Warning.png Warning, tags must be rounded with {} or [] for arrays (see later) and must be typed with no stop using Office suite (with no backward and no copy-paste). If not doing that, Office suite add some invisible informations making replacement not possible.

Tags

This is a list of tags that will be replaced with your informations:

Company/foundation information

mycompany_logo = {mycompany_logo}
mycompany_name = {mycompany_name}
mycompany_address = {mycompany_address}
mycompany_zip = {mycompany_zip}
mycompany_town = {mycompany_town}
mycompany_country = {mycompany_country}
mycompany_phone = {mycompany_phone}
mycompany_fax = {mycompany_fax}
mycompany_email = {mycompany_email}
mycompany_web = {mycompany_web}
mycompany_barcode = {mycompany_barcode}
mycompany_capital= {mycompany_capital}
mycompany_juridicalstatus= {mycompany_juridicalstatus}
mycompany_idprof1 = {mycompany_idprof1}
mycompany_idprof2 = {mycompany_idprof2}
mycompany_idprof3 = {mycompany_idprof3}
mycompany_idprof4 = {mycompany_idprof4}
mycompany_vatnumber = {mycompany_vatnumber}
mycompany_note = {mycompany_note}
...

Customers, prospects or suppliers information

company_name = {company_name}
company_address = {company_address}
company_zip = {company_zip}
company_town = {company_town}
company_country = {company_country}
company_phone = {company_phone}
company_fax = {company_fax}
company_email = {company_email}
company_web = {company_web}
company_barcode = {company_barcode}
company_customercode = {company_customercode}
company_suppliercode = {company_suppliercode}
company_capital = {company_capital}
company_juridicalstatus = {company_juridicalstatus}
company_idprof1 = {company_idprof1}
company_idprof2 = {company_idprof2}
company_idprof3 = {company_idprof3}
company_idprof4 = {company_idprof4}
company_vatnumber = {company_vatnumber}
company_note = {company_note}

User information

myuser_lastname = {myuser_lastname}
myuser_firstname = {myuser_firstname}
myuser_login = {myuser_login}
myuser_email = {myuser_email}
...

Object information (invoice, commercial proposal, order, ...)

{object_id}
{object_ref}
{object_ref_ext}
{object_label}
{object_ref_customer}
{object_ref_supplier}
{object_note_private}
{object_note_public}
or
{object_note}

Dates
{object_hour}
{object_date}
{object_date_rfc}
{object_date_creation}
{object_date_modification}
{object_date_validation}
{object_date_limit} : Specific to invoices
{object_date_end} : Specific to proposals : End date of validity of proposal
{object_date_delivery_planed} : Specific to order
{object_date_close}

Amounts (numeric data):
{object_total_ht}
{object_total_vat}
{object_total_localtax1}
{object_total_localtax2}
{object_total_ttc}
{object_total_discount_ht}
{object_total_vat_x} (is vat total for rate x. x can be for example 20, 8.5, 5.99 ... See also note*}

Amounts (in output language format):
{object_total_ht_locale} 
{object_total_vat_locale} 
{object_total_localtax1_locale}
{object_total_localtax2_locale}
{object_total_ttc_locale}
{object_total_discount_ht_locale}
{object_total_vat_locale_x} (is vat total for rate x. x can be for example 20, 8.5, 5.99 ... See also note*}

Multicurrency:
{object_multicurrency_code}
{object_multicurrency_tx}
{object_multicurrency_total_ht}
{object_multicurrency_total_tva}
{object_multicurrency_total_ttc}
{object_multicurrency_total_ht_locale}
{object_multicurrency_total_tva_locale}
{object_multicurrency_total_ttc_locale}

Specific to proposals :
{object_availability_id}
{object_availability_code}
{object_availability}

Specific to invoices :
{object_payment_mode}
{object_payment_mode_code}
{object_payment_term}
{object_payment_term_code}
{object_incoterms}
{object_bank_iban}
{object_bank_bic}
{object_bank_label}
{object_bank_number}
{object_bank_proprio}
{object_source_invoice_ref}
{object_already_payed} : Amount already payed (numeric)
{object_already_deposit}
{object_already_creditnote}
{object_already_payed_all}
{object_remain_to_pay} : Remaining to pay amount (numeric)
{object_already_payed_locale} : Amount already payed (output language format)
{object_already_deposit_locale}
{object_already_creditnote_locale}
{object_already_payed_all_locale}
{object_remain_to_pay_locale} : Remaining to pay amount (output language format)

Specific to Shipments :
{object_date_delivery}
{object_hour_delivery} 
{object_tracking_number}
{object_tracking_url}
{object_shipping_method}
{object_weight}
{object_width}
{object_height}
{object_depth}
{object_size}
{order_ref} : Ref of origin order used to generate the shipment
{order_ref_customer} : Ref on customer side of origin order used to generate the shipment

Specific to the Project linked to the object (if applicable):
{object_project_ref}
{object_project_title}
{object_project_description}
{object_project_date_start}
{object_project_date_end}

Specific to the Product directly linked to the object (if applicable):
{object_product_ref}
{object_product_label}

Extra fields:
{object_options_xxx} : Value of extra field (where xxx is code of extra field)

For ODT with supplier prices, you may need also to surround the substitutions variables with

[!-- BEGIN supplierprices--][!-- END supplierprices--]

Lines of object

This is how to use arrays for lines of objects (invoices, commercial proposal, orders, etc...). You must create your array in the document and use a begin and end tag to define a line of the array. The line will then be repeated as much as required during generation.

[!-- BEGIN row.lines --]
...
[!-- END row.lines --]

Then, you can use following tags into your line:

{line_pos}
{line_desc}
{line_product_ref}
{line_product_ref_fourn}
{line_product_label}
{line_product_type}
{line_product_barcode}
{line_vatrate}
{line_localtax1_rate}
{line_localtax2_rate}
{line_up}
{line_up_locale}
{line_qty}
{line_discount_percent}
{line_price_ht}
{line_price_ht_locale}
{line_price_vat}
{line_price_vat_locale}
{line_price_ttc}
{line_price_ttc_locale}
{line_date_start}
{line_date_start_locale}
{line_date_start_rfc}
{line_date_end}
{line_date_end_locale}
{line_date_end_rfc}
{line_unit} : Needs PRODUCT_USE_UNITS to 1
{line_unit_short} : Needs PRODUCT_USE_UNITS to 1

{line_fulldesc} : contains both line_desc and line_product_ref and line_product_label

Multicurrency :
{line_multicurrency_code}
{line_multicurrency_subprice}
{line_multicurrency_total_ht}
{line_multicurrency_total_tva}
{line_multicurrency_total_ttc}
{line_multicurrency_subprice_locale}
{line_multicurrency_total_ht_locale}
{line_multicurrency_total_tva_locale}
{line_multicurrency_total_ttc_locale}

Specific to Shipments :
{line_qty_shipped}
{line_qty_asked}
{line_weight}
{line_length}
{line_surface}
{line_volume}

Extra fields:
{line_options_xxx} : Value of extra field (where xxx is code of extra field)
{line_product_options_xxx} : If the line is a product, Value of the Product extra filed (where xxx is code of Product extra field)

This an example of what you may have in your office suite: Line for document generation.png

Conditional substitution

Starting from Dolibarr v3.3, you can use conditional substitutions, which in layman terms means that you can decide to print something if a variable is true, or print something else if it's false (or nothing at all) - including text but also any more complex structures like tables and images.

Example:

[!-- IF {my_var} --]
Print this text if {my_var} is true (can be any value but null/0/empty string)
[!-- ELSE {my_var} --]
Or print this if it's false (null/0/empty string)
[!-- ENDIF {my_var} --]

Other personalized tags

If you want to add a field that is not predefined, this is the solution:

  • Create a file into one of those locations:

htdocs/core/substitutions/functions_mymodule.lib.php with v3.2 or above htdocs/mymodule/core/substitutions/functions_mymodule.lib.php with v3.2 or above htdocs/includes/modules/substitutions/functions_mymodule.lib.php with version 3.1 or previous

  • Inside this file, just write one function like this:
/** 		Function called to complete substitution array (before generating on ODT, or a personalized email)
 * 		functions xxx_completesubstitutionarray are called by make_substitutions() if file
 * 		is inside directory htdocs/core/substitutions
 * 
 *		@param	array		$substitutionarray	Array with substitution key=>val
 *		@param	Translate	$langs			Output langs
 *		@param	Object		$object			Object to use to get values
 * 		@return	void					The entry parameter $substitutionarray is modified
 */
function mymodule_completesubstitutionarray(&$substitutionarray,$langs,$object)
{
   global $conf,$db;

   $myvalue='Put here calculated value to insert';
   $substitutionarray['myowntag']=$myvalue;
}

Function will be called before generating document to complete the array used for substitution and to replace tag myowntag with value $myvalue. You can add as many tags as you need and put all personalized code you want to define values (search into database, into files, calculation, from received parameters or from global variables)...

Warning: First parameter in function parameter declaration must start with & as valu is modified by your code and must be returned modified.

Note: With 3.2 and higher, if you have build your own module (See page Module development), you can put the substitution file inside a subdirectory of this module called htdocs/mymodule/core/substitutions. Moreover, function will be called only if module mymodule contains an entry

$this->module_parts = array('substitutions' => 1)

and module has been activated.

Note2: this only allows to define global, static ODT variables (ie: to make dynamic variables that changes for every line of product, please see the next chapter).

Other personalized tags for lines

This function is available since Dolibarr v3.3 (future development version).

Similarly to the previous chapter, you have to define a function, and it works about the same, but with a few twists:

  • Create or edit the same file as before (see the previous chapter).
  • Here are the twists: in the file, write another function with almost the same name but with '_lines' appended, and also add a new $lines variable:
/** 		Function called to complete substitution array for lines (before generating on ODT, or a personalized email)
 * 		functions xxx_completesubstitutionarray_lines are called by make_substitutions() if file
 * 		is inside directory htdocs/core/substitutions
 * 
 *		@param	array		$substitutionarray	Array with substitution key=>val
 *		@param	Translate	$langs			Output langs
 *		@param	Object		$object			Object to use to get values
 *              @param  Object          $line                   Current line being processed, use this object to get values
 * 		@return	void					The entry parameter $substitutionarray is modified
 */
function mymodule_completesubstitutionarray_lines(&$substitutionarray,$langs,$object,$line) {
{
   global $conf,$db;

   $myvalue='Put here calculated value to insert';
   $substitutionarray['myowntag']=$myvalue;
}

Contrary to the previous function which was called only once, this function will be called everytime a line of product will be processed, giving you each time a new $line object that you can process.

Store your document

To have your document to appear in list of available documents, put it into correct subdirectory found into directory documents/doctemplates