Inheriting and modifying QWeb reports

Hi guys,

In this tutorial you will learn how to inherit already existing QWeb reports in a custom module. After this tutorial you will be able to inherit and modify any already existing QWeb report in Odoo!
In this example I will modify the default Quotation / order report through inheritance and I will remove a few elements from the report.

1. Creating a new module

The first step is to create a new module. The correct behaviour in Odoo is to always inherit, don’t ever modify existing files. Start by creating yourself a new module.
Tip: use the scaffold command from Odoo!
Odoo scaffold command
This will create a new module from scratch and the default structure of your module is already there.

2. Creating your XML file

The next step is to open up your XML file (in my example templates.xml) and to create a new record to inherit the report. To inherit a report you have to know in which module it is and what the original XML id of the report is. So, how do you find this?
The easiest way is to go to ‘Settings’ > ‘Reports’ > ‘Reports’ and to search the report you want to modify. In this tutorial this will be the quotation/order report so I’ll search for ‘Order’:
Quotation / Order report
Now that you’ve found your report click on it. This will open a new view where you will find all the technical information you need! For example with the quotation report:
Report details
At the right you will see a clickable link named ‘Search associated QWeb views’. Click on it. This will show you a list of all records that are associated to this specific report. In the example of the quotation report:
QWeb XML views
So this usually shows you two XML records. How do you know which one you need? The one that ends with _document is the correct XML record that you need to inherit. Under the column ‘External ID’ you will see there is an unique name, in this example sale.report_saleorder_document. The first part of this text (sale) is the module where the report is from, the second part (report_saleorder_document) is the name of the report that you want to inherit and modify.

Remember this value and now open up your XML file. To inherit a QWeb report you need two things: an unique template id and the inherit_id. The template id can be chosen by yourself, just make sure its unique. The inherit_id should contain the value you’ve just found on your report (sale.report_saleorder_document).

That is it! You’re now already on the correct report and are inheriting it. So, how do you now add or remove elements? To do this you will need Xpath expressions to find, modify, replace or add elements. Tip: Don’t know how Xpath expressions work? Follow my tutorial here!
For this example I will remove the columns that show the amount, the tax and the price per item. The first step is to modify the table header:

After modifying the table header the table content should also be modified.

This code will remove the fourth, third and second td element and all its content but only for the tbody with class ‘sale_tbody’ and inside the tr.
So this will replace the header and the table content from this report. Have a look at the full code to inherit and modify your QWeb report:

If you would now print out the report you would get this as a result:
Result modified quotation report

3. Adding the dependency for the external QWeb report

The next, and final step, is to add a dependency. Because this QWeb report is inside another module Odoo has to know about this module and its content so you should add a dependency. Without this your module will not work and you will get errors.
Open up your file in your custom module and find the line with depends.
Now take back that ‘External ID’ from the QWeb report and take the first part of the external id (before the dot). This tells you which module you should add as a dependency:
External ID Qweb report
In this example my QWeb comes from the sale module, so I will add it as a dependency.

4. Conclusion

Thats it! You’re done with inheriting and modifying the QWeb report. When you now install this module in your Odoo you will see the modified report.
Do you want to try a demo module and see the source code of this tutorial? You can view on my Github account.
Has this tutorial helped you, do you have any feedback or questions? Post away!
Tutorial sponsored by Oocademy

19 thoughts on “Inheriting and modifying QWeb reports

  1. Derek Strong says:

    Great tutorial! As I am relatively new with Odoo, I’ve found that the documentation that Odoo/OpenERP provides is a little dated, and in some cases, vague. You’ve proven to be extremely valuable.

    In this tutorial, you’ve removed information from the report, but in my case, I must add the ‘internal category’ (from product.template) into a column between the Description and Taxes.

    I’ve tried creating a custom module, inheriting the sale.order and product.template modules into a class in that new module, used the xpath expressions to replace the sale_order_line information with the combined sale/product information, but, FAIL…

    Any ideas? This seems like it’s close.

    • Yenthe666 says:

      Hi Derek,

      Great to hear that my tutorials helpen you! Just create a field that links from your sale order to product template (there are already some links) and through this link you can het all values from the product. The rest is just a simple xpath expression to the right place in the report and then add the fields you’d like to have printed.

  2. Els Guns says:

    Hi Yenthe,

    I was looking for a way to make inhereted reports, just to have duplicates that will not be sent to the printer when printing. So, we can choose between PDF preview and printing for every document. Maybe there is a better solution to this problem than duplicating the reports, but if it is the right way to do it, can I create a new report but also inherit so no duplicate code has to be maintained?


    • Yenthe666 says:

      Hi Els,

      You’ll have to create a new report for every new report, so you’ll have to duplicate them pretty much. There is no way to bypass this.


  3. I don’t know. Can not selection of nth element to work.

    Have a qweb report (stock.report_picking) where I want to replace the second div with class = ‘row’.

    I would like to think I can select this div with:

    But no….

    Tried variants like:

    But I get the impression that selecting anything except the first element (which I did for other reports) does not work.

    • Yenthe666 says:

      Hi Ronald,

      The editor tends to filter it out sometimes. Just to be sure, you know that the xpath index starts counting from 0 and not 1? So if you do [1] you’ll have the second element.

    • Yenthe666 says:

      Hi Danial,

      You can configure this under Settings > Technical > Reports > Paper format. If you wish to change the paper format for a specific report you can do this under Settings > Technical > Reports > Reports.

  4. yut says:

    First I would like to thank you for your posting which explain concept of inherit and modify
    Secondly, I have question related to inheriting. Currently I inherit with modification of both header and footer. My question is any guideline / recommends document for having difference footer in difference report ? Appreciate your help on this.

    • Yenthe666 says:

      Hi Yut,

      You’re welcome! If you want to use different headers and footers on different reports you’ll need to make more XML records that create your different headers or footers. In every single report you’ll need to change it so it doesn’t take the default header/footer template then.

  5. Dax1900 says:

    Yeah! Got my first module working!!! Thanks a lot for this great introduction.

    My Odoo v10 CE is running within a docker container and then these steps above are not always trivial. So let me contribute my 2 cents and share my cmd listing below:

    root@AvunetStation:~# docker exec prod_odoo_1 /usr/bin/odoo scaffold my_so_report /mnt/extra-addons

    root@AvunetStation:~# docker exec -u 0 -it prod_odoo_1 bash

    root@9d64c947c7e9:/# cd mnt/extra-addons/
    root@9d64c947c7e9:/mnt/extra-addons# ls -al
    total 0
    drwxr-xr-x 1 odoo root 614 Oct 24 19:59 .
    drwxr-xr-x 1 root root 24 Feb 7 2017 ..
    drwxr-xr-x 1 odoo odoo 120 Oct 24 19:59 my_so_report

    root@9d64c947c7e9:/mnt/extra-addons# chown -R odoo my_so_report
    root@9d64c947c7e9:/mnt/extra-addons# chmod -R 755 my_so_report

    root@9d64c947c7e9:/mnt/extra-addons# cd my_so_report/views
    root@9d64c947c7e9:/mnt/extra-addons/my_so_report/views# cat templates.xml


    root@9d64c947c7e9:/usr/lib/python2.7/dist-packages/odoo/addons# cp -r /mnt/extra-addons/my_so_report /usr/lib/python2.7/dist-packages/odoo/addons

    I have one question: Now I have to install/uninstall the module everytime I want to print the SO report with/without these columns. In Odoo 10 it is possible to choose or create a quotation template. Is it not possible to extend this template with our new module from this great post?

    • Yenthe666 says:

      Hi Dan,

      Thanks for sharing! You could also choose to make two reports and choose the report depending on your requirements. ๐Ÿ™‚ Or you can add a configurable field in the SO which defines if a part should be shown on the report or not (with a t-if statement)

  6. Great tutorial!! This helped me so much. Just a request.. It would be very helpful if you add the steps to inherit the report class in python so that we can do some modifications to the content before rendering the html. I am getting mad to find the way to do it.

Leave a Reply