I want to achieve the below scenario. Have tried in many ways but no luck.
<t t-if="q1_percent > 75">
<td style="background-color:#52be80"><field name="q1_percent" nolabel="1"/></td>
</t>
<t t-elif="'q1_percent' > 50 and 'q1_percent' < 75">
<td class="td_act" style="background-color:#f4d03f"><field name="q1_percent" nolabel="1"/></td>
</t>
<t t-elif="'q1_percent' < 50">
<td class="td_act" style="background-color:#e74c3c"><field name="q1_percent" nolabel="1"/></td>
</t>
I am using odoo 10. And the above code is for form view.
How can I achieve this? Any ideas any help is most appreciated. Thanks!
Until Odoo 12 There is a difference between a regular view(tree, form, etc) and a QWeb view meaning that regular views cannot be mixed with QWeb content to be evaluated as for Reports and Website Pages.
You still could be able to acquire what you are looking for by simply defining a computed HTML Field that will contains the HTML result of evaluate that QWeb code or directly build the HTML without using QWeb at all. Or without QWeb just generating the HTML by yourself.
For example:
from lxml import etree
q1_percent_html = fields.HTML("Q1 Percent HTML", compute='_compute_q1_percent_html')
#api.depends('q1_percent')
def _compute_q1_percent_html(self):
for elem in self:
# QWeb version
t = etree.fromstring("""
<div>
<t t-if="q1_percent > 75">
<td style="background-color:#52be80"><t t-esc="q1_percent"/></td>
</t>
<t t-elif="'q1_percent' > 50 and 'q1_percent' < 75">
<td class="td_act" style="background-color:#f4d03f"><t t-esc="q1_percent"/></td>
</t>
<t t-elif="'q1_percent' < 50">
<td class="td_act" style="background-color:#e74c3c"><t t-esc="q1_percent"/></td>
</t>
<div>
""")
elem.q1_percent_html = self.env['ir.qweb'].render(t, {'q1_percent': elem.q1_percent})
# Python direct version
if elem.q1_percent >= 75:
background_color = "#52be80"
elif elem.q1_percent >= 50 and elem.q1_percent <= 75:
background_color = "#f4d03f"
elif elem.q1_percent <= 50:
background_color = "#e74c3c"
elem.q1_percent_html = """<div><td style="background-color:%s">%s</td></div>"""% (background_color, elem.q1_percent)
Use that field in your form view like:
<field name="q1_percent_html" nolabel="1" readonly="1"/>
Related
For creating a dict, i used the following code:
<t t-set="count" t-value="dict()"/>
<t t-foreach="count_obj" t-as="ob">
<t t-set="count" t-esc="count.update({ob.id: ob.name})"/>
</t>
But i am getting a none value.Why?
Can anyone help me?Thanks in advance..
shahinsha ummer
You have to specify the value in dict form when you try setting the value
[<t t-set="variable" t-value=""/>].
In your example, there is no need to set the variable before the loop with dictionary form it will do nothing.
<t t-foreach="count_obj" t-as="ob">
<t t-set="count" t-value="{ob.id: ob.name}"/> <!-- Set the Value in form of dictionar -->
<span t-esc="count"/>
</t>
I'm a beginner on Odoo and I want to customize the report that already exists in sale and so I made an inherit of sale But my code shows me an error that is:
Error while validating the constraint .... cannot be located in the parent view
In addition to that if I execute just the first part it works but it directly modifies the report of dirty but the report in my module is remain empty.
Here is the code:
<template id="report_real_estate_rental_in" inherit_id="sale.report_saleorder_document">
<xpath expr="//span[#t-field='doc.name']" position="after">
<p>JE SUIS LA</p>
</xpath>
</template>
<template id="report_real_estate_rental">
<t t-call = "web.html_container" >
<t t-foreach = "docs" t-as = "o" >
<t t-call = "web.external_layout" >
<div class = "page" >
<t t-call="report_real_estate_rental_in"/>
</div>
</t>
</t>
</t>
</template>
This error usually occurs when xpath expression cannot be located in parent view. Please make sure the xpath expression is correct and template id you're inheriting is correct. Check out this link for inheriting and modifying existing report in Odoo.
If i got the question as you meant , when you use t-call you have to include the module name also , so it will be module_name.template_id.
In your case , change it as <t t-call="your_module_name.report_real_estate_rental_in"/>
I have faced some of the issue page break in Qweb report in last few days.
I am trying to print my Qweb report for Cheque format and single Qweb page divided into 3 different sections
Section 1 : Displaying invoice list details
Section 2 : Bank details and amount which we will pay to our owner/tenant in MICR FONT 13B FONT
Section 3 : Displaying invoice list details
section 1 & 3 are the common and displaying the same invoices details into both of the sections and about the section2 will change as per the
different amount which we will pay to owner/tenant.
Expected Result :
I have 23 invoice details are attached it into single cheque then I want to bifurcate my invoice details into different slot
sloat 1 : Display first 10 invoice details into first page
sloat 2 : Display next 10 invoice details into second page
sloat 3 : Display remaning 3 invoice details into third page
I want to bifurcate my invoice details into different sloat wise page if the total number of invoices are more than 10 lines
What I have tried from my side ?
Attempt 1 : Using counter variable and update the counter through iterating the loop and break it when 10 is reach divide by 0
Applied this code inside into loping
<t t-set="count" t-value="count+1" />
<t t-if="count%10== 0">
<div style="page-break-after:auto;"/>
</t>
</t>
Attempt 2:
<span t-esc="line_index+1"/>
<t t-if="line_index+1%10 ==0">
<div style="page-break-inside:auto !important;">
</t>
I think you need to provide a little bit more of the context and info, perhaps the problem is other than that one are you exposing.
have you tried using a custom python report?
class IncrementReports(models.AbstractModel):
_name = 'report.your_model.your_report_name'
#api.model
def render_html(self, docids, data=None):
report_obj = self.env['report']
report = report_obj._get_report_from_name(
'your_model.your_report_name')
docs = []
objects = self.env[report.model].browse(docids)
for o in objects:
docs.append({...})
docargs = {
'doc_ids': docids,
'doc_model': report.model,
'docs': objects,
'custom_docs': docs,
'datetime': datetime.datetime,
}
return report_obj.render('your_model.your_report_name', docargs)
Using a custom report you can create a function to divide the 3 blocks of information, sending this in different variable inside de docargs and iterating over them without check the condition in the XML report.
I don't know if I'm clear, my English is not good enough.
I have also fixed the issue from my end after tried a lot more attempts.
If any one will face the same issue in your future development
so that they can also able to fix it quickly.
Create a method into specific model : (cheque.cheque model)
def get_invoice_details(self, invoice_ids,cheque):
vals,container,result,val=[],[],[],1
invoice_no=''
for line in invoice_ids:
desc=''
if line.is_vendor:
invoice_no=line.vendor_reference
else:
invoice_no=line.number
pay_amt=line.payment_ids.filtered(lambda m: m.cheque_issued_id.id ==cheque.id).amount or 0.00
for l in line.invoice_line_ids:
desc+=str(l.product_id.default_code)+',' or ''
vals.append({
'date':str(line.date_invoice),
'invoice_no':invoice_no,
'inv_amt':str(line.amount_total),
'description':desc,
'pay_amt':float(pay_amt)
})
invoice_no=''
for l in vals:
if val<=len(vals):
container.append(l)
if val % 9 == 0:
result.append({'section':9,'vals':container})
container=[]
val+=1
if container:
result.append({'section':4,'vals':container})
return result
In this method I have set section key with its value into result of list for dictionary
where we are using the same section to making the page break perfectly
Call the same method and iterate it into Qweb Template
<t t-foreach="o.get_invoice_details(o.invoice_ids,o)" t-as="line" >
<div class="page">
<div class="col-xs-12">
<table style="width:100%">
<thead>
<tr>
<th>Invoice Date</th>
<th>Invoice # </th>
<th>Invoice Amt</th>
<th>Description </th>
<th style="text-align:right">Payment Amt</th>
</tr>
</thead>
<t t-foreach="line.get('vals')" t-as="inv">
<tbody class="sale_tbody">
<tr>
<td>
<span t-esc="inv.get('date')" />
</td>
<td>
<span t-esc="inv.get('invoice_no')" />
</td>
<td>
<span t-esc="o.decimal_formated_amount(float(inv.get('inv_amt',0.00)))" />
</td>
<td>
<span t-esc="inv.get('description')" />
</td>
<td style="text-align:right">
<span t-esc="o.decimal_formated_amount2(float(inv.get('pay_amt',0.00)))" />
</td>
</tr>
</tbody>
</t>
</table>
</div>
<span t-if="line.get('section') % 9 == 0" style="page-break-after: always;">
</span>
</div>
As per the business logic of get_invoice_details() method
which is return the data in list form and then we can user the same and render it into the XML template.
Odoo will manage the page break automatically when the condition will satisfy over the XML template
system will automatically bifurcate the page according to source code
I hope my answer may helpful for you :)
I have a table, where I want to declare ngClass (first row)
<table [ngClass]="{'before_forth': pageNumber < 4, 'forth': pageNumber = 4}">
<tr id="words" *ngFor="let item of itemsSource3; let i = index;">
<td *ngFor="let item2 of helper[i]; let j = index;">
<input class="resizedTextbox" name="{{i}}{{j}}"
[(ngModel)]="helper[i][j].value" (ngModelChange)="onValueChange(f,i)"/>
</td>
{{item}}
</tr>
</table>
And my CSS is
table.forth.td:nth-child(2){background-color: green}
table.forth.td:nth-child(5){background-color: green}
table.before_forth.td:nth-child(2){background-color: red}
table.before_forth.td:nth-child(5){background-color: red}
So, what I would like to do is to set the colour, which depends on the number of page (in my component I use this method
this.pageNumber = this.activatedRoute.snapshot.queryParams['page'];
and it worked fine in other cases ( I use it oft)
I guess the problem is in css, in this piece of code table.forth.td:nth-child, could you please tell me what would be the right way to access class within the table?
You should use pageNumber === 4 and not pageNumber = 4, because then you are just assigning the variable:
<table [ngClass]="{'before_forth': pageNumber < 4, 'forth': pageNumber === 4}">
The second problem is the css rule, you are using a .td class in there, even though it's nowhere used in the html. My guess is that you want to target the <td> element inside the table:
table.forth td:nth-child(2){background-color: green}
table.forth td:nth-child(5){background-color: green}
table.before_forth td:nth-child(2){background-color: red}
table.before_forth td:nth-child(5){background-color: red}
The third problem is the usage of {{item}} outside the <td> tag. This is invalid html and will result in unwanted behaviour, you should move this inside the td
Also, don't use id inside in combination with *ngFor. An element with an id is supposed to be unique throughout the entire page. Actually, it's better not to use id at all if you have no special use for it:
<table [class.before_forth]="pageNumber < 4" [class.forth]="pageNumber === 4">
<tr *ngFor="let item of itemsSource3; let i = index;">
<td *ngFor="let item2 of helper[i]; let j = index;">
<input class="resizedTextbox" name="{{i}}{{j}}" [(ngModel)]="helper[i}[j].value" (ngModelChange)="onValueChange(f,i)">
{{item}}
</td>
</tr>
</table>
The last point is, the proper spelling of 4th is fourth and not forth, but that's just an fyi ;)
I met Odoo for first time a little less than a month ago, and, a DOS Systems Analyst from the 90's, am helping to implement it for a small but fast growing local manufacturer. Largely out of the industry the last 15 years, I'm not pro, but fast learning Python, HTML (some past exper) and Java...
I've been through the Developer Docs, as well as the Developer's Cookbook & Essentials, and a variety of online tutorials (just about everything Google could come up with from several search word combinations).
I read the closed post asking about this and get that there's apparently no actual Odoo reference...
Can someone please tell me where I might find 'date/time' parse and conversion functions that I can access from a report that is using the 'canned' 'hr.employee' model?
<?xml version="1.0"?>
<t t-name="hr_attendance.report_attendancelog">
<t t-call="report.html_container">
<t t-call="report.external_layout">
<div class="page">
<div class="oe_structure"/>
<div class="row">
<div class="col-xs-6">
<h2><br/>Attendance Log: </h2>
</div>
</div>
<table class="table table-condensed mt32">
<thead>
<th><strong>Date / Time</strong></th>
<th><strong> Operation</strong></th>
</thead>
<tbody>
<t t-foreach="docs" t-as="o">
<t t-set="DspDate" t-value="o.name"/>
<t t-set="DspTime" t-value="o.name"/>
<!-- I want to parse 'o.name', which is 'date time' format (from
Attendance record) to separate 'Date' and 'Time' fields... -->
<!-- t t-set="DspDate" t-value="FUNC?(o.name)"/ -->
<!-- t t-set="DspTime" t-value="FUNC?(o.name)"/ -->
<!-- and do calcs with date & time...) -->
<!-- t t-set="ClcDt1" t-value="FUNC?('PrvDt')"/ -->
<!-- t t-set="ClcDt2" t-value="FUNC?(DspDate)"/ -->
<!-- t t-set="ClcTm1" t-value="FUNC?('PrvTm')"/ -->
<!-- t t-set="ClcTm2" t-value="FUNC?(DspTime)"/ -->
<tr>
<t t-if="ClcDt1 == ClcDt2">
<td><span t-esc="DspDate"/></td>
<td><span t-esc="DspTime"/></td>
<td><span t-esc="o.action"/></td>
</t
</tr>
</t>
<tr class="border-black">
<td colspan="3"><strong>Total period</strong></td>
<td><strong t-esc="o.worked_hours"/></td -->
</tr>
</tbody>
</table>
</div>
</t>
</t>
</t>
I prefixed 'br/' to H2 to keep the it properly positioned (only shows on the first page), but subsequent pages obscure the col headers behind the layout header... this is probably obvious and I'm oblivious, but how can I adjust the 'H2' position to be below the 'header' setup by 'report.external_layout'??
On QWeb rendering you can use the python libs time, datetime and relativedelta. They are included in the so called QWeb context which is used for the evaluation (python eval) of the code in reports. You can see this in Odoo code here.
That means you do something like this:
<t t-set="DspDate" t-value="datetime.datetime.strptime(o.name, '%Y-%m-%d %H:%M:%S').strftime('%d/%m/%Y')" />
I prefer parser classes for reports to define some common functions. For example: you can define the function getDate doing your parsing or transforming stuff. The report code will be much better with parser functions:
<t t-set="DspDate" t-value="getDate(o.name)" />