I am facing problem while showing the data from database into Qweb Template of odoo v8.
The codes follows:
The controller gives me object from database : like stock.quant(), the object is from stock_quant table. In this scenario the object is empty. Now i have to check if the object is empty in template. so i tried following :
My Controller: quant.py
quant = { get value from table }
return request.render('test', {'quant':quant})
in my template i have to check if quant is empty or not, so i tried :
<t t-if="quant is Empty" /> # doesn't work
<t t-if="quant is False" /> # doesn't work
also checked other way around
<t t-if="quant is not Empty" /> # doesn't work
<t t-if="quant is not False" /> # doesn't work
Can someone help me in determining how to check object is empty in Qweb Template.
Thanks,
Just try simply,
<t t-if="not quant">
<!-- your code -->
</t>
And suppose you want to check any other relational fields of that object then you should check like that,
<t t-if="not quant or not 'relational_field_name' in quant">
<!-- your code -->
</t>
You using the wrong comparison operator.
In python is compares identity, hence if the value is {} or None your check will fail even if these values are always boolean falses.
Simply use not quant and whatever value will be ok.
Related
I want to create a custom button in the odoo employee model, which creates and downloads a pdf with the working contract of this employee. I tried to reverse engineer the given buttons in odoo, but every approach of mine failed. Does someone have a tip on where to start? Thanks a lot!
I usually return an URL action with the download button, and write a controller for the URL. The result is clicking the button actually downloading a file.
First step is to write your Qweb report. I'll write a sample one here. Note that the report ID is action_report_test_contract which is used later in the controller.
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<report string="Test Contract" id="action_report_test_contract" model="hr.contract" name="your_module_folder_name.test_contract_report" file="your_module_folder_name.test_contract_report" report_type="qweb-pdf" print_report_name="'%s - Contract' % (object.name)" />
<template id="test_contract_report">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="doc">
<t t-call="web.internal_layout">
<div class="page">
<h1><t t-esc="doc.name"/></h1>
<h2>Employee: <t t-esc="doc.employee_id.name"/></h2>
<h2>Start Date: <t t-esc="doc.date_start"/></h2>
</div>
</t>
</t>
</t>
</template>
</odoo>
Don't forget to add the report file path to your manufest. Test print the report from a contract, yes the sample works. Now inherit the hr.employee module to add the download method.
class HrEmployee(models.Model):
_inherit = "hr.employee"
def button_download_contract(self):
if not self.contract_id:
return
return {
'type' : 'ir.actions.act_url',
'url': '/web/download/test-contract-report?contract_id=%s'%(self.contract_id.id),
'target': 'self',
}
Also, inherit the view to add the download button:
<button name="button_download_contract" type="object" string="Download Contract" icon="fa-download"/>
Finally, finish the controller:
from odoo import http
from odoo.http import request, content_disposition, route
class testDownload(http.Controller):
#route(['/web/download/test-contract-report'], type='http', auth="user")
def download_pdf(self, contract_id, **kw):
employee_contract = request.env['hr.contract'].sudo().search([('id','=',contract_id)], limit=1)
if not employee_contract:
return None
pdf, _ = request.env.ref('your_module_folder_name.action_report_test_contract').sudo().render_qweb_pdf([int(contract_id)])
pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(pdf)),('Content-Disposition', content_disposition('%s - Contract.PDF' % (employee_contract.name)))]
return request.make_response(pdf, headers=pdfhttpheaders)
Note that the method render_qweb_pdf relies on the report object. So action_report_test_contract is used, not test_contract_report.
I have developed a new report for account.invoice in odoo 12 but when i suppose to print this, it gives me a warning like this in 12.0 branch :
The report's template 'Template name' is wrong, please contact your administrator.
Can not separate file to save as attachment because the report's template does not contains the attributes 'data-oe-model' and 'data-oe-id' on the div with 'article' classname.
In master branch it says data-model instead of data-oe-model, data-id instead of data-oe-id and 'page' classname instead of 'article' classname
If anyone has faced the same issue and find a solution then please let me know.
Thanks
I solved it with a help from a friend:
In your external_layout you have to define 't-att-data-oe-model' and 't-att-data-oe-id' . Add this:
<div class="article o_report_layout_standard" t-att-data-oe-model="o and o._name" t-att-data-oe-id="o and o.id">
<t t-call="web.address_layout"/>
<t t-raw="0"/>
</div>
Previously this piece of code (v11) was like this:
<div class="article o_report_layout_standard">
<t t-raw="0" />
</div>
Hope it solves your problem. This change is because the report is now editable in v12 with the studio app.
Yes, you need to modify the external_layout, In my case it was custom layout and i solved it using below XML
<template id="custom_layout">
<!-- Multicompany -->
<div class="article o_report_layout_standard" t-att-data-oe-model="doc and doc._name" t-att-data-oe-id="doc and doc.id">
<t t-if ="doc and 'company_id' in doc" >
<t t-set="company" t-value="doc.company_id"/>
<t t-set="customer" t-value="doc.partner_id"/>
</t>
<t t-call="custom_sale_report_v12.custom_layout_header"/>
<t t-raw="0"/>
<t t-call="ce_sale_report_v12.custom_layout_footer"/>
</div>
</template>
I had faced same issue.
The reason was there is a t-if condition before the <t t-call="web.external_layout"> . The error is coming when ever its value is False.
This error could happen if there is no report_type="qweb-html" for the report_type="qweb-pdf".
To solve this issue just had both... something like this :
<report
id="report_invoice_html"
model="MY_MODEL_NAME"
string="Invoice HTML"
name="MODULE.report_invoice_view"
file="MODULE.report_invoice"
report_type="qweb-html" />
<report
id="report_invoice_pdf"
model="MY_MODEL_NAME"
string="Invoice PDF"
name="MODULE.report_invoice_view"
file="MODULE.report_invoice"
report_type="qweb-pdf" />
If you look at the Odoo code source at ir_actions_report.py, you will see a statement comparing set(res_ids) != set(html_ids), if HTML template doesn't exist it return True, and then raise the Error
I am new to odoo and learning a bit related to reporting. i was looking around stock picking report. i noticed that it has an object called "docs" and the values are stored inside this object.
as i am from PHP background there are possibilities to print the object received for debugging purpose as follows:
<?php print_r("object"); ?>
So i tried to print the same thing in odoo using QWeb template using below codes :
1. <t t-esc="docs" />
2. <t t-foreach="docs" t-as="o">
<t t-esc="o" />
3. <t t-foreach="docs" t-as="o">
<t t-esc="o_all" />
4. <t t-foreach="docs" t-as="o">
<t t-esc="o_value" />
5. <t t-foreach="docs" t-as="o">
<t t-esc="o_all" />
But i was unable to print the whole object, i only get stock.picking(1,)
Can someone help me how can i see the whole object with keys and values in qweb template. Moreover can someone guide me where this object "docs" is defined.
I will really appreciate.
Thanks,
Based on #Diderh answer, see how to display each attributes of an object with their related values:
<table>
<t t-foreach="product._fields" t-as="field">
<tr>
<td>
<t t-esc="field" />
</td>
<td>
<t t-esc="product[field]" />
</td>
</tr>
</t>
</table>
stock.picking(1,) is a single object so it doesn't have key and values which dictionaries have. so i guess what you want to see are the attributes the object has like the id, name and so on
you can do that by using the dir function, that's the equivalent of print_r on an object in php (not really),
<t t-foreach="docs" t-as="o">
<t t-esc="dir(o)" />
That will print out all the attribute that the object has, if you want to see a specific attribute like the id you can do this
<t t-foreach="docs" t-as="o">
<t t-esc="o.id" />
dir gives a lot more information, but you can still get the same behaviour as php's print_r with some little modifications. for example
class Example:
whatever = 'whatever attribute'
something = 'something attribute'
ex = Example()
print({attribute: getattr(ex, attribute) for attribute in dir(ex) if not attribute.startswith('__')})
Here i used a dictionary comprehension to loop through all the attributes of the object returned by dir before then i used an if statement to strip out all the extra information about the object that dir gives us which usually start with two underscores (__).
Hence the output is a dictionary with the object attributes as keys and the values are the contents of those attributes
{'whatever': 'whatever attribute', 'something': 'something attribute'}
Untested by me. but this should work in QWeb also
<t t-foreach="docs" t-as="o">
<t t-esc="{attribute: getattr(o, attribute) for attribute in dir(o) if not attribute.startswith('__')}" />
Sometime we are a little lost how to print the fields for an particular object in website Odoo v12, you can use a simple code to show wholes fields. Here how i did it for Object Forum:
<t t-foreach="forums.sorted(reverse=True)" t-as="forum">
<t t-esc="forum._fields" />
</t>
I have a custom module test and created pages called test_1, test_2, test_3.
I have inherited calendar view and wrote a condition in js like all the calendar changes should be reflected to test_1. And that is working fine.
Now i need to remove Day and Month button from test_1 page -> Calendar view.
So i am trying to write t-if condition. I dont have idea how to call model. i tried below code but it is not working.
<template>
<tr t-extend="CalendarView.quick_create">
<t t-if="widget.model=='test_1'">
<t t-jquery=".form-group" t-operation="after">
<div class="form-group">
<h3>Example - put fields here </h3>
</div>
</t>
</t>
</tr>
</template>
It is not working throws an TypeError: Cannot read property 'model' of undefined
How to access model in t-if condition?
I do not know why it's not recognizing the fields which I have created in python file.I am getiing error as QWebException: "amt_inv" while evaluating
"line['amt_inv']"
This is my python file,
class account_move_line(models.Model):
_inherit = "account.move.line"
amt_inv=fields.Char('Invoice')
amt_reinv=fields.Char('Refunded Invoice')
This is a small part of my xml file,
<tr t-foreach="lines(partner)" t-as="line">
<td>
<t t-if="line['credit']==0">
<span t-esc="line['amt_inv']"/></t>
<t t-if="line['credit']>0">
<span t-esc="line['amt_reinv']"/></t>
</td>
Basically in your case your function lines(partner) will not returned the values properly.so your line instance of lines function is not part of the key so that you are facing that problem.
First it much and more important things is that you have to check the proper logic which you were returned from your lines() function.
For Example :
I have mentioned over hear what the actually you are returned from the dictionary and how we are iterate over the loop using our Qweb View file.
def lines(o.partner_id):
Your logic mentioned over hear for make a new the dictionary
res={
'amt_inv':2022,
'amt-reinv':5244.20,
'credit':0,
}
return list(res)
<tr t-foreach="lines(partner)" t-as="line">
<td>
<t t-if="line['credit']==0">
<span t-esc="line['amt_inv']"/></t>
<t t-if="line['credit']>0">
<span t-esc="line['amt_reinv']"/></t>
</td>
hear you can access as line instance form the key of that value as amt_inv key.
please try to check again your lines function logic It will return the proper list of dictionary or not
I hope my answer may helpful for your :)