If you want to call a python function from the QWeb report you will need to create a custom parser for the report. In the parser, you will need to add the function as an argument in the render method.
For Example, if you need to add custom function that will return split text in the Sale Order report the code for the parser should look like following:
from openerp import api, models def split_text(txt): return txt.split(';') class SaleOrderReport(models.AbstractModel): _name = 'report.sale.report_saleorder' @api.multi def render_html(self, data=None): report = self.env['report']._get_report_from_name('sale.report_saleorder') docargs = { 'doc_ids': self._ids, 'doc_model': report.model, 'docs': self.env['sale.order'].browse(self._ids), 'split_text': split_text } return self.env['report'].render('sale.report_saleorder', docargs)
Now when you have the method split_text in the list of arguments you can access it in the report like:
<xpath expr="//p[@t-field='doc.note']" position="replace"> <t t-foreach="split_text(doc.note)" t-as="text_line"> <p t-esc="text_line.strip()"/> </t> </xpath>
Additionally, you can find an example of the code as simple module here
Hello could you tell me a bit more about your code. Where do you put the main code? in sale_report.py? or can you install as module? i have tried to make custom module, then i have added inside the report, but it gives me an error.
Hi Ged,
Yeah, you should create a custom module in which you need to add a custom parser for the report. What that means is in your odoo module create new python module where you will add the code from the example. I have changed the name of the report in the example to match the name of the default Sales Order Report. After that, you can override the XML part of the report and use the method split_test in it.
If you still getting an error let me know the error message and I will try to help you.
Hello there, here is my code(took an example directly from odoo page):
class buh_aps_report(models.AbstractModel):
_name = ‘report.l10n_lt_buh_aps_forma.report_buh_aps_forma_lt’
def some_math(txt):
return txt * 5
def get_format(self):
return ‘its working’
@api.multi
def render_html(self, data=None):
report_obj = self.env[‘report’]
report = report_obj._get_report_from_name(‘l10n_lt_buh_aps_forma.report_buh_aps_forma_lt’)
docargs = {
‘doc_ids’: self._ids,
‘doc_model’: report.model,
‘docs’: self,
‘some_math’: self.some_math,
‘get_format’: self.get_format,
}
return report_obj.render(‘l10n_lt_buh_aps_forma.report_buh_aps_forma_lt’, docargs)
After i add this code to my module i cant access all object attributes, actually i can but only from report.l10n_lt_buh_aps_forma.report_buh_aps_forma_lt model ,which are: id, display_name, __last_update.
And im getting error like this:
“‘report.l10n_lt_buh_aps_forma.report_buh_aps_forma_’ object has no attribute ‘line_ids'” while evaluating ‘o.line_ids’
If you need i can post my report code as well. Thank you
Try as ‘docs’ instead of self to return queryset of the actual report.model. It should works.
Example: https://github.com/odoo/odoo/blob/9.0/addons/account/report/account_report_financial.py#L148
Thank you for your time, will try it on Monday and will report back results, thanks
from odoo import api, models
import logging
_logger = logging.getLogger(__name__)
class pet_report(models.AbstractModel):
_name = ‘report.pet.report_pet_qweb’
_template = ‘pet.report_pet_qweb’
def get_pet_price(self, petname):
price = 87.77 #hardcording for testing only
return price
@api.model
def render_html(self, docids, data=None):
pet_obj = self.env[‘tbl.pets’].browse(docids)
docargs = {
‘doc_ids’: docids,
‘doc_model’: ‘tbl.pets’,
‘data’: data,
‘docs’: pet_obj,
‘get_pet_price’:get_pet_price,
}
return self.env[‘report’].render(‘pet.report_pet_qweb’, docargs)
with the above code in Odoo 10 I am getting runtime error
“QWebException: ‘NoneType’ object is not callable
Traceback (most recent call last):
.
.
Node: ”
If I comment out my report runs
Node: get_pet_price(‘dog’)
Hi Bil,
As I can see “get_pet_price” is part of the class “pet_report” and should be called with “self”, but in the docargs it is defined as ‘get_pet_price’:get_pet_price,.
Correct version should look like:
docargs = {
‘doc_ids’: docids,
‘doc_model’: ‘tbl.pets’,
‘data’: data,
‘docs’: pet_obj,
‘get_pet_price’:self.get_pet_price,
}
Could you post your code as a ready made module? because i have tried your code today, and it doesn’t work. Tried example from Odoo documentation, it brings me empty pdf. Working example code would be very nice. Thank you
Hi Ged,
I just update the post with a simple module as an example. I hope this will help you.
Thank you, will test it later today!
Tried on Odoo v10 community, im getting an error. Did you try it on v10?
You can not install this module on v10 because it is for v9. Will migrate it today. But in any case, the way of calling python method in the QWeb reports is the same.