Search code examples
pythonxmlreportodoo-8odoo

How to create a paperformat record with dynamic height?


I did a new report for stock.picking model, which is always printed in a RJ-4040 Brother printer. So I had to create a new paper format with a width of 102mm and assign it to the report:

<record id="paperformat_stock_picking_rj4040brother" model="report.paperformat">
    <field name="name">RJ-4040 Brother</field>
    <field name="default" eval="True"/>
    <field name="format">custom</field>
    <field name="page_height">297</field>
    <field name="page_width">102</field>
    <field name="orientation">Portrait</field>
    <field name="margin_top">40</field>
    <field name="margin_bottom">23</field>
    <field name="margin_left">3</field>
    <field name="margin_right">3</field>
    <field name="header_line" eval="False"/>
    <field name="header_spacing">35</field>
    <field name="dpi">80</field>
</record>

It's working OK, but the problem is that I had to set a height for the paper format, and the paper of that printer is a paper roll, whose height is undefined. This is the same case of a point of sale ticket, so I went to see the paper format of the POS ticket and its height is 150mm, which I guess is not working well with long receipts. That report doesn't call the classic header layout but it has its own header, which I think is being repeated at the top of each page (if the ticket is longer than 150mm). So I guess a long ticket, of 20 lines for example, will be printed in a paper roll like this: 7 lines - header - 7 lines - header - 6 lines (supposing that only 7 lines fit in 150mm), when it should be printed like this: header - 20 lines.

I tried basic things like <field name="page_height">-1</field> (which gives an error) or <field name="page_height">0</field> (which ignores the height and the width set).

Then I read this post: How to Dynamic change paper format margins (Left, Right, Top, Bottom)?

So I inherit the get_pdf method, and now I have the paperformat recordset and the HTML code in a variable, but I don't know if I'm wasting my time trying to measure the height of the second one to modify the paperformat height afterwards.

Does anyone know which is the best way to achieve my purpose? Any help will be appreciated, thank you!


Solution

  • I had a problem like this when I didn't need the page header in other pages and I didn't want the margin between the top page and the first line in the second page. What I did is avoid using the external layout provided by Odoo and create a new paper format with no header nor footer:

        <!-- 0 mm header and 0mm bottom and less height -->
        <field name="page_height">150</field>
        <field name="margin_top">0</field>
        <field name="margin_bottom">0</field>
    

    And I wrote my report after the tag of <page>, defining my own header in order to be rendered once per record in the whole PDF.

       <page>
           <div class="new_header" style="margin-top: 1%;"> <!-- Margin-top here replaces the margin_top of the paper format -->
                 <!-- my header code here -->
                 <!-- don't user <header> element or class="header" because odoo will render it in the header section by default -->
           <div>
    

    I hope you get the idea, it requires some skills with xpath in order to remove the external layout, or, you can define a new report with this technique.

    Note that the only way to remove the space in the header and bottom is the margins of the page.