Home Audience Developers Simplify Invoicing by Creating a Template with Python

Simplify Invoicing by Creating a Template with Python

python invoicing

Businesses require customised templates to reduce the time and effort spent on each document. This article talks about reclaiming the hours spent in creating invoices by designing a template in Python.

All businesses raise invoices to generate funds. I run a consultancy service that raises bills every week, so that my clients don’t need to get approval for larger monthly or annual invoices from their finance department. However, a major constraint here is that a lot of time is spent in designing the invoices. There are lots of services like Zoho books that allow you to make templates, but for a few specific cases like mine, the constraint is the time spent in typing out the actual items for the invoices.

The workflow that is generally used for creating such invoices is as follows.

  1. Create a copy of a Google Drive doc file that serves as a template.
  2. Read GitLab issues for the project, and create a list of items to be added in the invoice.
  3. Download the doc as a PDF file and email it to the client.

Though this workflow is fine for 1-4 projects at a time, when 8-10 projects are handled, this process starts consuming an hour every week. A lot of time can be saved by using the following steps.

The template
Figure 1: The template

The template
First, a template in docx format is needed. It is preferable to have a Google Drive doc as a template and use words as placeholders for actual information; for example : ‘BILL_TO’, ‘INVOICE_DATE’, ‘ITEM_LIST’, and ‘TOTAL_AMOUNT’.

The good thing about the docx format is that it’s actually a zip file. Since Python has a zipfile module (https://docs.python.org/3/library/zipfile.html), it’s easy to work with docx in it for this particular case.

This step simply requires that you download this docx template file onto your computer.

GitLab can be used to manage projects. The CI/CD pipelines have to be set up to ensure that all merge request titles follow a certain pattern. I used ‘#<issue number>: Brief description of task’ as the template. This template, along with squash commits, makes sure that the main branch only has commits that link to issues and a brief description of what is achieved. All the intermediate commits of ‘why is this not working?`, `tests are passing`, `making it faster` get collapsed within the merge request, and the main branch remains clean thanks to squash commits.

In my case, to generate items for the invoice, I picked up the latest commits since the last invoice was raised. This produced a draft to edit and was a lot faster than typing all the information manually. ‘git log –oneline origin/{target}..{sha}’ can be used to show commits since the sha commit. This is a very useful command, indeed!

With a draft ready for the items that have to be put in the invoice, many invoices can be produced quickly. Proofreading and entering the amounts that the client has to pay is all that’s left.

Filing the template
Since docx is zip readable and the invoice items are available to use in Python as a data structure, the next step is to combine the two. When we open the docx file using the zipfile library, we need to look for the ‘word/document.xml’ file within the zip. This is what we need to edit. The rest can be written back to the new file exactly the same as before. For the ‘word/document.xml’ file we have to replace the placeholders that we put in the template with actual values.

I initially started with trying Jinja templates (https://jinja.palletsprojects.com/en/3.0.x/templates/). That felt like overkill though, so I tried the re library (https://docs.python.org/3/library/re.html) in Python. It still felt like overkill.

So the final code I used is ‘string.replace(‘a’, ‘b’)’ and it worked well enough for this use case. I just replaced placeholders in the template with actual values. For example, string.replace(‘BILL_TO’, ‘ABC Pvt Ltd’).

This final replaced docx is written back to the file system. The new docx has been created like a charm.

Making a PDF
A PDF is still needed. Docx can look very different if it is opened in Windows, LibreOffice, or Google Drive. A PDF, though, always looks exactly the same. I used LibreOffice to convert the docx to a PDF.

libreoffice --headless \
  --convert-to pdf {fname}.docx \
  --outdir invoices

This PDF can be created in roughly 5 seconds, reducing the time spent in creating invoices from 1-1.5 hours to just 5 minutes of proofreading.

All the code for this tutorial is available at (a gist on GitHub) https://gist.github.com/theSage21/29261e071efd92f701b69ddd56374fa6.



Please enter your comment!
Please enter your name here