[FIX] report: page numbering rml reports
authorMartin Trigaux <mat@odoo.com>
Tue, 21 Oct 2014 08:54:23 +0000 (10:54 +0200)
committerMartin Trigaux <mat@odoo.com>
Tue, 21 Oct 2014 13:36:01 +0000 (15:36 +0200)
Save the NumberedCanvas state before doing a page reset.
The order of execution when rendering an rml report is the following:
1. init canevas (_pageNumber = 1)
2. render the page element
3. if still pages to render, afterPage method
4. if still pages to render, showPage method (_pageNumber += 1)
5. back to step 2 for each page
6. draw the ResetPage element (setting flag _doPageReset=True)
7. end the document build with afterPage & showPage method

The PageReset element should be executed at the end of the rendering of a story (subdocument) to reinitialize the page numbers to 0 (for new story) and insert the pageCount element for that story with the total number of pages (needed if want to use tag <pageCount/> in rml).

In case of NumberedCanvas (e.g. used in Trial Balance report), the numbering is generated at the end of the build using the _saved_page_states dict in the canevas.
To have an accurate _saved_page_states content, it needs to be saved before the pageReset.

Fixes #2225

openerp/report/render/rml2pdf/trml2pdf.py

index 75bc30d..3b36c3e 100644 (file)
@@ -88,7 +88,6 @@ class NumberedCanvas(canvas.Canvas):
         self._saved_page_states = []
 
     def showPage(self):
-        self._saved_page_states.append(dict(self.__dict__))
         self._startPage()
 
     def save(self):
@@ -123,6 +122,8 @@ class PageCount(platypus.Flowable):
 
 class PageReset(platypus.Flowable):
     def draw(self):
+        """Flag to close current story page numbering and prepare for the next
+        should be executed after the rendering of the full story"""
         self.canv._doPageReset = True
 
 class _rml_styles(object,):
@@ -930,6 +931,9 @@ class TinyDocTemplate(platypus.BaseDocTemplate):
         self.handle_frameBegin()
 
     def afterPage(self):
+        if isinstance(self.canv, NumberedCanvas):
+            # save current page states before eventual reset
+            self.canv._saved_page_states.append(dict(self.canv.__dict__))
         if self.canv._doPageReset:
             # Following a <pageReset/> tag:
             # - we reset page number to 0
@@ -1003,10 +1007,10 @@ class _rml_template(object):
         story_cnt = 0
         for node_story in node_stories:
             if story_cnt > 0:
-                # Reset Page Number with new story tag
-                fis.append(PageReset())
                 fis.append(platypus.PageBreak())
             fis += r.render(node_story)
+            # end of story numbering computation
+            fis.append(PageReset())
             story_cnt += 1
         try:
             if self.localcontext and self.localcontext.get('internal_header',False):