Page: 1 of 1

Page: 1 of 1

Autor: Kerrim Abd El Hamed

It’s been a while since my last blog post but sadly I didn’t have much time to write the last few months. MuK IT is doing well and a lot of people reach us with their problems regarding Odoo. One of our customers was annoyed about something that we also noticed a while back. Invoices, sales orders and all other documents generated in Odoo (they call them reports) are always showing the page number, even if they only have one page. So everytime you print a one paged document you have “Page: 1 of 1” printed in the footer.

I wanted to fix this and thought it would be a simple change of the report template. So I went to the General Settings in debug mode and clicked on Edit headers. The last part of the footer looked like this:

<div t-if="report_type == 'pdf'" class="text-muted">
  Page:
  <span class="page"/>
  of
  <span class="topage"/>
</div>

This told me that the pagenumbers are getting injected by javascript into the span tags. I also knew that Odoo uses wkhtmltopdf to print the pdf reports. So this had to be done there. I started reading about people having the same issue with wkhtmltopdf and found a javascript solution that worked when I tested it directly in my command line.

I couldn’t get it to work on Odoo. I think it was because the header and footer are splitted in different html files, but I’m not sure about that. Odoo does this in ir.actions.report in _prepare_html(self, html). Thats probably needed for wkhtmltopdf to build the page.

The biggest issue was getting useful error messages. We, by now I had asked Mathias for his javascript expertise, seperated the footer and tried to achieve our wished result in the browser first and then sending it directly to wkhtmltopdf. After some tweaks in the code we were able to get it to work in Odoo. The first working version looked like this:

<div t-if="report_type == 'pdf'" class="text-muted" id="pagenumbers">
  Page: <span class="page" /> of <span class="topage" />
</div>
<script>
  var prev_onload = window.onload;
  function check_pagenumbers() {
    prev_onload();
    topage = parseInt(document.getElementsByClassName("topage")[0].innerHTML)
    if(topage == 1) { document.getElementById('pagenumbers').style.display = 'none'; }
  }
  window.onload = check_pagenumbers;
</script>

We tried it on some more reports, but when printing multiple invoices at once the footer got destroyed. So I thought this was because the javascript was processed multiple times.

<div t-if="report_type == 'pdf'" class="text-muted pagenumbers">
  Page: <span class="page" /> of <span class="topage" />
</div>
<script>
  if (typeof prev_onload === 'undefined') {
    var prev_onload = window.onload;
    function check_pagenumbers() {
      prev_onload();
      pagenumbers = document.getElementsByClassName("pagenumbers");
      Array.prototype.forEach.call(pagenumbers, function(pagenumber) {
        topage = parseInt(pagenumber.getElementsByClassName("topage")[0].innerHTML);
        if(topage == 1) { pagenumber.style.display = "none"; }
      });
    }
    window.onload = check_pagenumbers;
  }
</script>

This works now for every report and when printing multiple reports in the list view. I don’t know if thats the best solution for this. But it does the job and doesn’t need a module to be installed. Meaning that anyone with access to the report template can change this.

We will probably pack this in a module soon. Mathias wanted it to look less like a hack before releasing. For everyone who can’t wait feel free to copy the lines of code printed above.

Download Link: MuK IT App: Page Numbers