At Infiniroot we asked ourselves a couple of years ago: How can we improve our invoicing mechanism and reduce the time investment in creating invoices? The old method (basically using Excel and Word, creating a PDF of it and sending to the customers) could definitely be improved.
We realized that creating invoices of one-shot projects would still require a certain amount of time, but invoices on recurring services (such as server hosting) could definitely be automated.
But we didn't just want any invoicing solution:
This is when we finally found Invoiceninja! And we were amazed. Working with invoices finally made fun.
The automatically created PDF invoices contain our payment information at the footer. We've (probably) been lucky so far, that all our customers never requested an "old style" payment slip, also known as "Einzahlungsschein" or "ESR" (containing a reference number), and copied the payment information from the invoice footer directly into their own payment system.
As ESR's are at the end of their life in Switzerland in 2020, a new kind of "invoice coding" emerges: QR codes on invoices.
The Swiss QR Invoice has a standardized data structure which is documented in the Swiss Implementation Guidelines QR-Bill document. With a bit of technical flair and some "thinking outside the box", the automatic creation of such QR codes can be implemented into InvoiceNinja.
Behind the optical QR code resides the "SPC data", which is short for "Swiss Payments Code". This data basically contains a couple of lines, each line with a value for a certain field, for example the currency. Here's such an example:
Robert Schneider AG
Rue du Lac
Bill no. 3139 for gardening work and disposal of waste material
Without going too much into details (read the implementation guide for this), the data starts with SPC internal reference codes (SPC, Version 0200, 1) followed by the invoice sender's (Debitor) IBAN bank account and a structured (S) address of the sender. After exactly 7 new lines the amount of the invoice followed by the currency shows up. Adding the invoice recipient's (Kreditor) address is optional. Finally the data ends with an optional reference code or string and "EPD".
The example data above use the "S" address format, which is short for structured format. This basically means that the address is split into multiple fields as this:
When using the "K" (combined) address format, certain elements can be put on the same line:
Street Name House Number
ZIP Code City
Street name and house number are merged into one line. The same happens with ZIP code and the city name. The remaining two lines reserved for the structured address format are now optional and should be left empty (new line).
Why is this important? InvoiceNinja does not split the street into structured fields, which can be seen in the Company Details Settings:
For this reason, the combined (K) address format needs to be used in SPC data.
In InvoiceNinja's settings, the Invoice Design can be customized. When "Customize Design" tool is opened, the left side shows the backend code while the right side shows live changes on the final PDF design.
As I mentioned before, we're used to show our payment information in the invoice's footer. We wanted to put the QR code right next to this payment information. The trick however is to find the correct variables to use inside the code. InvoiceNinja's core developer Hillel Coren mentioned some of the variables can be found in the code's transformers. This certainly helps to find most of the needed variables but for certain a workaround is needed (more on that later).
With the following code snipped, almost all of the needed data can be dynamically inserted into the QR code:
"qr": "SPC\n0200\n1\nHard-Coded-IBAN\nK\n$account.name\n$account.address1\n$account.postal_code $account.city\n\n\nCH\n\n\n\n\n\n\n\n$balance\nCHF\n\n\n\n\n\n\nNON\n\n$invoice_number\nEPD\n",
Although there is a $client.currency_id available according to the source code, it never showed any value. And even if it would show a value, it is not certain that the "ID" would actually show the international known currency string, such as USD, EUR or CHF.
To circumvent this, a custom field can be created. InvoiceNinja supports two custom fields per category (products, clients, invoices, etc) which can then be used in the template. Under Settings -> Advanced Settings -> Invoice Settings, Custom Fields can be defined. Here a custom field called "Currency" is defined under the "Clients" category:
When a Client is now edited (or added), this new custom field shows up in the form:
Here the value "CHF" was added into this custom field.
The QR code was adjusted accordingly to retrieve the invoices currency dynamically from this custom field (using $client.custom_value1):
"qr": "SPC\n0200\n1\nCH240025625610422101T\nK\n$account.name\n$account.address1\n$account.postal_code $account.city\n\n\nCH\n\n\n\n\n\n\n\n$balance\n$client.custom_value1\n\n\n\n\n\n\n\nNON\n\n$invoice_number\nEPD\n",
This solution was also shared in the official InvoiceNinja community forums.
Now that everything is in place, a new invoice can be created and its QR code tested.
And in the PDF view of the invoice, the QR code shows up:
With a simple QR Code App this can now be read and the SPC data should be shown:
An official Swiss QR bill code validator exists and a generated invoice can be uploaded to the validator. If no errors show up, the code is validated and can be used.
Voilà! The validator scanned the QR code from the uploaded PDF invoice and could not detect any errors. Mission accomplished!
InvoiceNinja has once again proven to us, why we decided for it in the first place!
Since July 2020 Infiniroot offers dedicated InvoiceNinja servers in Switzerland. This allows you to run your own billing application using InvoiceNinja in a secure server environment and data in Switzerland, even with a low budget!
No comments yet.
AWS Android Ansible Apache Apple Atlassian BSD Backup Bash Bluecoat CMS Chef Cloud Coding Consul Container Containers CouchDB DB DNS Database Databases Docker ELK ElasticSearch Elasticsearch Filebeat FreeBSD GlusterFS Grafana Graphics HAProxy HTML Hacks Hardware Icinga Icingaweb2 InfluxDB Internet Java KVM Kibana Kubernetes LXC Linux Logstash Mac Macintosh Mail MariaDB Minio MongoDB Monitoring Multimedia MySQL NFS Nagios Network Nginx OSSEC OTRS PGSQL PHP Perl Personal PostgreSQL Postgres PowerDNS Proxmox Proxy Python Rancher SSL Security Shell SmartOS Solaris Surveillance SystemD TLS Tomcat Ubuntu Unix VMWare VMware Varnish Virtualization Windows Wireless Wordpress Wyse ZFS Zoneminder