Using MLInvoice

Table of Contents

The idea with MLInvoice is that it would be possible to use it even without instructions, but there are some functions that require some guidance.

MLInvoice does not enforce certain workflows, but tries to warn about possible problems. It is, for instance, possible to resend an invoice which has a past date, but MLInvoice will alert the user about it.

See also the discussion area from which you can find for instance responses to users' questions and discussion about the features.


MLInvoice has three main things: company, client and invoice. Company is the biller, and it is created and updates at Settings -> Companies. Client is the person or organisation to be invoiced. Invoice in naturally the most central piece of the system. An invoice can contain one or more invoice rows, which resemble the invoiced items. To make it easier to add invoice rows, it is possible to define products in the settings. Selecting a product when adding an invoice row then prefills the row with data from the product.

The text of an invoice row (product name and description) is printed full-width if price and count are zero. This can be used to include notes etc. between the invoice rows. Also any leading whitespace is preserved so a couple of spaces can be used to indent the row as necessary.

Invoice information can also be used to print out dispatch notes etc.


Lists or tables are an important part of MLInvoice. You can adjust column widths by dragging from the end of each column heading and select displayed column using the button on the header of each list.

Lists can be sorted by clicking on a header. Secondary and even tertiary sort columns can be selected by clicking them while holding down the Shift key.

It is also possible to open entries to a new browser window or a tab by clicking an entry while holding down the Ctrl key (Cmd on Macs).


The Settings menu contains general settings and information about invoicing companies, products and default texts. General settings also contain many settings that affect the behavior of invoicing and printouts. Default texts etc. can be defined in invoicing companies, but default texts can be used to quickly pick predefined values as necessary.

The System menu contains e.g active print templates. By default only a part of the Finnish templates are active, but English and Swedish templates can be activated as necessary.

Text Translations

All translations are in MLInvoice's lang directory in textual .ini files. The files provided with MLInvoice should not be modified. Instead, if there's a need to change e.g. texts in en-US.ini, a new file with name en-US.local.ini should be created. New and changed translations can then be put there and they remain intact in future updates.

Printout translations are in invoice- etc. files. Like above, any changes to invoice texts are done in e.g. invoice_en-US.local.ini file.

Example: Add the following translation to invoice_en-US.local.ini:

  OwnTermsOfPayment = "14 days"
Now the translation can be used in the Payment Terms setting by entering OwnTermsOfPayment there.

Client-specific Prices

Products can have client-specific prices in addition to the basic price information. Definition of client-specific prices happens in the product list by selecting a client and clicking the Define button. The prices are based on a discount percentage or a multiplier, and they can have a validity date limit. When client-specific prices are valid, also prices of single products can be modified directly in the product list.

First Invoice

You can follow these steps to create the first invoice:

  1. Check the general settings (Settings -> General Settings). The defaults are meant to be sensible, but they don't suit all. Settings can only be modified with admin permissions.
  2. Add a new company (Settings -> Companies)
  3. Add a couple of products (Settings -> Products)
  4. Add a new client
  5. Add a new invoice, save it and add a couple of invoice rows
  6. The invoice is now ready to be sent via email or saved as PDF

Handling Paid Invoices

It usually makes sense to archive received invoices so that they don't stick in the invoice lists. Archived invoices can be found in the Archive function, and they can be handled just like any other invoices. The normal workflow is to mark the invoice paid, set its payment date and check the Archived checkbox. There is a setting in General settings where you can define whether invoices that get a payment date are automatically marked paid and archived.

Repeating Invoices

If you give an invoice a repeating interval and next date, MLInvoice will notify on the main screen when the invoice needs to be processed. Then a copy of the invoice can be made and the repeating information will be updated accordingly (old invoice marked as non-repeating, new invoice given interval and new next repeat date).


Offers behave much like invoices, but they have different printouts and slightly different fields. They are displayed in their own list on the front page, and by default they are excluded from the invoicing reports but can be included by selecting the appropriate states.

If there's a need to collect statistics for offers, make sure not to delete them but to mark them archived and realized or unrealized.

Deleting Records

Apart from tags and client-specific prices, deleting a record in MLInvoice does not mean that it would be deleted from the database. Deleted records are just marked deleted. Admins can go to General Settings and switch on the setting "Show deleted records" to display also deleted records during the session. Saving a deleted record undeletes it. This way the risk of losing data is minimized. Note that while this protects from accidental deletes, saved changes cannot be undone.

Sending Invoices via Email

MLInvoice supports sending invoices via email. The invoice PDF is sent as an attachment. This requires that the PHP installation on the server can send email. To send email, it is not necessary to do more than click the Email button in invoice. It is, however, useful to add default settings into company so that they don't need to be entered again every time.

In email functions the address fields can take simple email addresses or name and address using format

Recipient Name <>

BCC field can be used to send a copy of each sent invoice to your own email address for archiving and verifying that the message was sent successfully.

All email recipient fields can also contain multiple recipient separated by a comma.

Placeholders can be used in the subject and message body fields in company information. They will be replaced with the proper information when the email is being sent. Placeholders are marked in curly brackets as follows:

Invoice {invoice:invoice_no}
Dear Recipient,

An invoice in PDF format is attached. This message has been sent from the system automatically,
but you can reply to this if you have any questions or comments regarding the invoice.

You can use the information below to pay the invoice. Always use a reference number, please.

Invoice Number                {invoice:invoice_no}
Payment Ecluding VAT          {invoice:totalsum}
 + VAT                        {invoice:totalvat}
Invoice Total                 {invoice:totalsumvat}
Amount to Pay                 {invoice:totalunpaid}

Account Number                {sender:bank_iban}
BIC                           {sender:bank_swiftbic}
Due date                      {invoice:due_date}
Reference Number              {invoice:ref_number}

Virtual Barcode               {invoice:barcode}

Best Regards,
The Company

For PDF links it is recommended to configure the web server so that there is a separate address that is directed to MLInvoice's invoice.php. The address could be something like https://company.something/show_doc. This way the actual MLInvoice installation can be kept separate from the link sent to the client. The .htaccess file that comes with MLInvoice contains a simple example that redirects docs/open_doc under the MLInvoice directory, but it is not recommended for production use. Naturally the links that are sent to the clients must be accessible from Internet even if other parts of MLInvoice are e.g. limited by IP address.

The this kind of address is available, it is entered into "Format of link to PDF file for clients" in General Settings. Then a suitable print template, such as "Email without attachment" needs to be enabled from print templates. Additionally it is recommended to create a new default text that contains the email messsage and the link so that it can be quickly selected when sending an email. If all invoices are to be sent with this mechanism, the changes can be made to the default texts defined in the invoicing company.

A very simple example default text:


You have a new invoice with total sum of {invoice:totalsumvat}.
The invoice can be downloaded in PDF format from: {invoice:pdf_link}

Best Regards,
The Company

The text can of course include other information about the invoice with additional placeholders. A generated PDF link remains valid for 90 days.

Sending with

To send printouts and Finvoice invoices via, you need to enter the settings at the end of the form of the invoicing company. When this is done, a button will be displayed on the top of the invoice screen.


N.B. Make sure you have the _ENCRYPTION_KEY_ setting defined in config.php. If not, see config.php.sample for an example.

Note that in addition to the settings listed below, you may need to modify the positioning of addresses. These are basic settings that can be used as initial settings and tweaked as necessary:

Horizontal offset of sender's address: 10
Vertical offset of sender's address: -2
Horizontal offset of recipient's address: 10
Vertical offset of recipient's address: 2

Field Description
Display Name Name displayed on the button. Leave empty to use the Service Name.
Service Name Select
User or Organisation ID User name in
Password or Key Password in
Reference or Unit ID Optional own reference
Mail Class Default mailing class for printouts
Send to Queue If selected, items are sent to queue in The queue and printouts can be reviewed in's user interface e.g. to verify positioning of address fields. Printouts sent to queue must be accepted to be sent in for them to be sent.
Finvoice via mail if necessary Whether to send Finvoice invoices via mail if the Finvoice cannot be sent to the recipient electronically

Default Texts

Predefined default texts can be used in invoice form and email form. Default texts are defined in settings. Where a default text is displayed depends on the type selected for it. Default texts can be selected by using the small arrow button to the right of the text fields. Placeholders can be used in default texts.

Texts of type "Email" can include additional field values for sending email. These are defined in the Additional Info field, one per line separated with a colon. The following values can be defined:

Value Content
From Sender's email address
CC Visible copy addresses
BCC Blind copy addresses
Subject Email subject


From: Ivor Invoicer <>
CC: Invoice Handler 1 <>, Invoice Handler 2 <>
Subject: Reminder for invoice {invoice:invoice_no}


All database fields can be used as placeholders (sender=base, recipient=company, invoice=invoice, settings=config, contact=first contact of correct type, contacts=all contacts of correct type). In addition, there are placeholders for invoice totals.

For placeholders of contacts type an additional separator that is used between values can be specified. Example:

Re: Offer {invoice:invoice_date} {recipient:company_name}/{contacts:contact_person:, }

The most important placeholders are:

Placeholder Contents
{sender:name} Sender name
{sender:contact_person} Sender contact person
{sender:street_address} Sender street address
{sender:zip_code} Sender postal code
{sender:city} Sender city
{sender:country} Sender country
{sender:phone} Sender phone number
{sender:www} Sender www address
{sender:email} Sender email address
{sender:company_id} Sender company ID
{recipient:company_name} Recipient name
{recipient:contact_person} Recipient contact person
{recipient:street_address} Recipient street address
{recipient:zip_code} Recipient postal code
{recipient:city} Recipient city
{recipient:country} Recipient country
{recipient:phone} Recipient phone number
{recipient:email} Recipient email address
{recipient:gsm} Recipient mobile phone
{recipient:billing_address} Recipient billing address
{recipient:company_id} Recipient company ID
{recipient:customer_no} Recipient customer number
{invoice:name} Invoice name
{invoice:invoice_no} Invoice number
{invoice:invoice_date} Invoice date
{invoice:due_date} Invoice due date
{invoice:printout_type} The printout type in lower case letters (e.g. "invoice", "dispatch note")
{invoice:printout_type_caps} The printout type with initial capitals (e.g. "Invoice", "Dispatch Note")
{invoice:ref_number} Invoice reference number
{invoice:reference} Invoice reference text
{invoice:info} Invoice additional information
{invoice:totalsum} Invoice total excluding VAT
{invoice:totalvat} Invoice total VAT
{invoice:totalsumvat} Invoice total including VAT
{invoice:totalunpaid} Unpaid amount on invoice including VAT (total - partial payments)
{invoice:barcode} Invoice barcode in numeric format ("virtual barcode", Finnish bank standard)
{invoice:pdf_link} Link to PDF based on the setup in general settings. See Sending a PDF Link via Email for more information.
{config:invoice_terms_of_payment} Invoice payment terms ("xx days net")
{config:invoice_period_for_complaints} Invoice period for complaints ("7 days")
{config:invoice_penalty_interest} Invoice penalty interest
{config:invoice_notification_fee} Invoice notification fee
{contact:contact_person} First contact person of correct type
{contact:person_title} Title of first contact person of correct type
{contact:email} Email of first contact person of correct type
{contact:phone} Phone number of first contact person of correct type
{contact:gsm} Mobile number of first contact person of correct type
{contacts:contact_person:separator} Names of contact persons of correct type
{contacts:person_title:separator} Titles of contact persons of correct type
{contacts:email:separator} Emails of contact persons of correct type
{contacts:phone:separator} Phone numbers of contact persons of correct type
{contacts:gsm:separator} Mobile numbers of contact persons of correct type
{var:date} Current date
{var:datetime} Current date and time


MLInvoice provides the possibility to create invoices in Finvoice format (Finvoice version 2.01). Finvoice invoices can be sent via an service provider directly to recipient.

The actual Finvoice XML is created via create_finvoice.xsl file, which is provided with sender, recipient and invoice information in addition to settings. It uses these to build the final XML. This mechanism can be used to create other XML formats too. The XSL file to be used is configured in print templates.

Please see the Finnish instructions for more information, or ask in the discussion forum.


You can add tags to clients and their contacts e.g. for classification. While there's currently not much you can do with tags in MLInvoice, they can be useful in SQL queries. There are many ways to use them, but here are a couple of example queries:

Invoice/offer States

Invoice/offer States found in the System menu define how an invoice or an offer in the given state behaves. E.g. records in state that's marked unfinished are displayed in the lists on the front page. By default finished offers are not displayed on the front page, but the state for Finished Offers can be set to unfinished to keep them on them displayed.

Print templates found in the System menu define which printouts are available. Some of the templates, such as English and Swedish versions, are disabled by default. Print templates also contain information whether the printout is opened in a new window and what is the default file name. Placeholders may be used in the filename.

Note! Information in this chapter is mostly for those familiar with PHP code.

MLInvoice print templates management is designed so that adding own templates is possible without changing the original code. Templates can be added or deleted in the print template settings. Print templates also define which print buttons are displayed in the invoice form.

A new print template can be copied from invoice_printer.php and modified as necessary. It is also useful to check out how invoice_printer_email.php replaces parts of the normal PDF creation (invoice_printer_base.php) with the email function. In general the process consists of the following steps:

  1. Load printer class defined in the print template
  2. Call the init method of the class. It will do the necessary initializations.
  3. Call the printInvoice method, which handles the actual "printing"

The default print template print_invoice_base.php is divided into small methods of which each is responsible for printing a certaion part of the invoice. This makes it possible to override only the methods that need to be changed, as others are inherited from InvoicePrinterBase class.

Note that the printInvoice method in InvoicePrinterBase class might call itself a second time if it finds out that invoice rows don't fit in the space on the first page and a separate invoice statement needs to be printed.

Steps to Create a new Print Template

In this example a new print template that prints less information on the recipient is created. The same idea can be used to modify other templates too.

  1. Copy invoice_printer.php to a new name, in this example invoice_printer_own.php
  2. Change class name to reflect file name (without underscores but all words start with capital letter)
  3. Copy printRecipient function and its contents from invoice_printer_base.php into invoice_printer_own.php. It should look like this:
    require_once 'invoice_printer_base.php';
    class InvoicePrinterOwn extends InvoicePrinterBase
      protected function printRecipient()
        $pdf = $this->pdf;
        $recipientData = $this->recipientData;
        $pdf->setX($pdf->GetX() + $this->addressXOffset);
        $pdf->Cell(120, 6, $this->recipientName, 0, 1);
        $pdf->setX($pdf->GetX() + $this->addressXOffset);
        $pdf->MultiCell(120, 6, $this->recipientAddress, 0, 1);
        if ($recipientData['email'])
          $pdf->SetY($pdf->GetY() + 4);
          $pdf->setX($pdf->GetX() + $this->addressXOffset);
          $pdf->Cell(120, 6, $recipientData['email'], 0, 1);
        $this->recipientMaxY = $pdf->GetY();
  4. Modify printRecipient function according to your needs. Here the address and email are left out:
    require_once 'invoice_printer_base.php';
    class InvoicePrinterOwn extends InvoicePrinterBase
      protected function printRecipient()
        $pdf = $this->pdf;
        $recipientData = $this->recipientData;
        $pdf->setX($pdf->GetX() + $this->addressXOffset);
        $pdf->Cell(120, 6, $this->recipientName, 0, 1);
        $this->recipientMaxY = $pdf->GetY();
    Note! recipientMaxY on the last line tells subsequent functions how far on the page did recipient information reach so that e.g. invoice rows start below it.
  5. Login to MLInvoice and go to System -> Print Templates.
  6. Open print template "Invoice" and create a copy of it.
  7. Change the name of the template and change the File field to invoice_printer_own.php.
  8. Save the template. As long as the Inactive checkbox has not been checked, a new button will be displayed in the invoice form.
  9. Test the results with an invoice and modify as necessary.

UI Customization

Custom css settings can be added to file css/custom.css. File does not exist by default and needs to be created first. For instance the following setting makes the forms very airy:

.field {
    padding: 10px;