odoo教程---在odoo8中创建自定义的reports
目录(?)[+]
Hi guys
In this tutorial you will learn how to create a new QWeb report from scratch.
During this tutorial I will create a second invoice report, but this time without prices. Some companies do not want to show prices per record for example, so I’ll take this as a sample.
1. Creating a new XML file
The first step to create your own new report is to make a new XML file. This file should be placed under yourModuleName/views and you can name it as you wish. In this tutorial I will create a new invoice that is made in the module account.
I’ve named the file report_without_prices.xml as you can see here:
In this file you will define the template id’s and names, which will later on be used by your Odoo to find the correct report.
The minimal code looks like this:
<? xml version = "1.0" encoding = "utf-8" ?>
< ! -- Custom report . -- >
< openerp >
< data >
< template id = "report_without_prices_document" >
< t t - call = "report.external_layout" >
< div class = "page" >
< div class = "row" >
< h3 > Title < / h3 >
< / div >
< / div >
< / t >
< / template >
< template id = "report_without_prices" >
< t t - call = "report.html_container" >
< t t - foreach = "doc_ids" t - as = "doc_id" >
< t t - raw = "translate_doc(doc_id, doc_model, 'partner_id.lang', 'account.report_without_prices_document')" / >
< / t >
< / t >
< / template >
< / data >
< / openerp >
So, what is important about this? The name of the template id (from the first record) should be the same as the name for the t-raw that handles translations. In the t-raw you need to add the module name before this name with a dot. Here’s an image to make things more clear:
The second template_id then needs to be identical to the name that you will set in the next file. So let us continue.
2.Add the report to the XML file responsible for reports
This brings us to part 2. Every module has a file that makes a reference to every single report in the module. This is done by a item, which can be found in the XML file.
This file always has the same name structure. It starts with the name of your module, an underscore and then report.xml. Its found in the first level of the directory of your module, as you can see here:
The filename is always yourModuleName_report.xml. Now open up this file and you will see a tag for every report that exists in this module.
The next step for us is to add a new tag for our own report. The code looks like this:
< report
id = "custom_report_without_prices"
model = "account.invoice"
string = "Invoice without prices"
report_type = "qweb-pdf"
name = "account.report_without_prices"
attachment_use = "False"
file = "account.report_without_prices"
/ >
Now that you’ve added this code you’re almost there! The last step is to notify Odoo of the new report.
3. Notify Odoo from the new report
So how do we tell Odoo there is a new report? In every module is a file named __openerp__.py. This file is used to import (include) all files in a module.
As all files are loaded in here we should also add our new XML file in this list. Without this Odoo will not find or use the XML file which will result in a not working report and errors.
Add a new line to the __openerp__.py file, right under ‘data’:[
#Lots of code above this that is not relevant
""" ,
'website' : 'https://www.odoo.com/page/billing' ,
'images' : [ 'images/accounts.jpeg' , 'images/bank_statement.jpeg' , 'images/cash_register.jpeg' , 'images/chart_of_accounts.jpeg' , 'images/customer_invoice.jpeg' , 'images/journal_entries.jpeg' ] ,
'depends' : [ 'base_setup' , 'product' , 'analytic' , 'board' , 'edi' , 'report' ] ,
'data' : [
'views/report_without_prices.xml' ,
#All other files are loaded under this
4. Wrapping things up
Now that you’ve made a new report (a new XML file),added the template id to the moduleName_report.xml file and added your XML file to __openerp__.py you’re done!
The last thing you need to do is reload your module (by command or by a module update) and you’ll see the new report showing up.
If you then look under accounting > Customer Invoices and make a new invoice you will see your new print option:
And, finally, if you print it out you’ll get your custom report!
NOTE:If you want a more advanced code, which shows a full report without the prices just paste this code in reports_without_prices.xml
<? xml version = "1.0" encoding = "utf-8" ?>
< ! -- Custom report -- >
< openerp >
< data >
< template id = "report_without_prices_document" >
< t t - call = "report.external_layout" >
< div class = "page" >
< h2 >
< span t - if = "o.type == 'out_invoice' and (o.state == 'open' or o.state == 'paid')" > Invoice < / span >
< span t - if = "o.type == 'out_invoice' and o.state == 'proforma2'" > PRO - FORMA < / span >
< span t - if = "o.type == 'out_invoice' and o.state == 'draft'" > Draft Invoice < / span >
< span t - if = "o.type == 'out_invoice' and o.state == 'cancel'" > Cancelled Invoice < / span >
< span t - if = "o.type == 'out_refund'" > Refund < / span >
< span t - if = "o.type == 'in_refund'" > Supplier Refund < / span >
< span t - if = "o.type == 'in_invoice'" > Supplier Invoice < / span >
< span t - field = "o.number" / >
< / h2 >
< div class = "row mt32 mb32" >
< div class = "col-xs-3" t - if = "o.name" >
< strong > Description : < / strong >
< p t - field = "o.name" / >
< / div >
< div class = "col-xs-3" t - if = "o.date_invoice" >
< strong > Invoice Date : < / strong >
< p t - field = "o.date_invoice" / >
< / div >
< div class = "col-xs-3" t - if = "o.origin" >
< strong > Source : < / strong >
< p t - field = "o.origin" / >
< / div >
< div class = "col-xs-3" t - if = "o.partner_id.ref" >
< strong > Customer Code : < / strong >
< p t - field = "o.partner_id.ref" / >
< / div >
< / div >
< table class = "table table-condensed" >
< thead >
< tr >
< th style = "width:35%;" > Description < / th >
< th style = "width:15%;" > Quantity < / th >
< ! -- < th class = "text-right" style = "width:15%;" > Unit Price < / th >
< th class = "text-right" groups = "sale.group_discount_per_so_line" > Discount ( % ) < / th >
< th class = "text-right" style = "width:20%;" > Taxes < / th >
< th class = "text-right" style = "width:15%;" > Amount < / th > -- >
< / tr >
< / thead >
< tbody class = "invoice_tbody" >
< tr t - foreach = "o.invoice_line" t - as = "l" >
< td style = "width:25%;" > < span t - field = "l.name" / > < / td >
< td style = "width:15%;" >
< span t - field = "l.quantity" / >
< span t - field = "l.uos_id" groups = "product.group_uom" / >
< / td >
< ! -- < td class = "text-right" style = "width:15%;" >
< span t - field = "l.price_unit" / >
< / td >
< td groups = "sale.group_discount_per_so_line" > < span t - field = "l.discount" / > < / td >
< td class = "text-right" style = "width:20%;" >
< span t - esc = "', '.join(map(lambda x: x.name, l.invoice_line_tax_id))" / >
< / td >
< td class = "text-right" style = "width:15%;" >
< span t - field = "l.price_subtotal"
t - field - options = '{"widget": "monetary", "display_currency": "o.currency_id"}' / >
< / td > -- >
< / tr >
< / tbody >
< / table >
< div class = "row" >
< div class = "col-xs-4 pull-right" >
< table class = "table table-condensed" >
< tr class = "border-black" >
< td > < strong > Total Without Taxes < / strong > < / td >
< td class = "text-right" >
< span t - field = "o.amount_untaxed" t - field - options = '{"widget": "monetary", "display_currency": "o.currency_id"}' / >
< / td >
< / tr >
< tr >
< td > Taxes < / td >
< td class = "text-right" >
< span t - field = "o.amount_tax" t - field - options = '{"widget": "monetary", "display_currency": "o.currency_id"}' / >
< / td >
< / tr >
< tr class = "border-black" >
< td > < strong > Total < / strong > < / td >
< td class = "text-right" >
< span t - field = "o.amount_total" t - field - options = '{"widget": "monetary", "display_currency": "o.currency_id"}' / >
< / td >
< / tr >
< / table >
< / div >
< / div >
< div class = "row" t - if = "o.tax_line" >
< div class = "col-xs-6" >
< table class = "table table-condensed" >
< thead >
< tr >
< th > Tax < / th >
< th class = "text-right" > Base < / th >
< th class = "text-right" > Amount < / th >
< / tr >
< / thead >
< tbody >
< tr t - foreach = "o.tax_line" t - as = "t" >
< td > < span t - field = "t.name" / > < / td >
< td class = "text-right" >
< span t - field = "t.base"
t - field - options = '{"widget": "monetary", "display_currency": "o.currency_id"}' / >
< / td >
< td class = "text-right" >
< span t - field = "t.amount"
t - field - options = '{"widget": "monetary", "display_currency": "o.currency_id"}' / >
< / td >
< / tr >
< / tbody >
< / table >
< / div >
< / div >
< p t - if = "o.comment" >
< strong > Comment : < / strong >
< span t - field = "o.comment" / >
< / p >
< p t - if = "o.payment_term" >
< strong > Payment Term : < / strong >
< span t - field = "o.payment_term" / >
< / p >
< p t - if = "o.fiscal_position" >
< strong > Fiscal Position : < / strong >
< span t - field = "o.fiscal_position" / >
< / p >
< / div >
< / t >
< / template >
< template id = "report_without_prices" >
< t t - call = "report.html_container" >
< t t - foreach = "doc_ids" t - as = "doc_id" >
< t t - raw = "translate_doc(doc_id, doc_model, 'partner_id.lang', 'account.report_without_prices_document')" / >
< / t >
< / t >
< / template >
< / data >
< / openerp >
Looking for more information about reports?
Check out the official documentation
Hi guys
In this tutorial you will learn how to create a new QWeb report from scratch.
During this tutorial I will create a second invoice report, but this time without prices. Some companies do not want to show prices per record for example, so I’ll take this as a sample.
1. Creating a new XML file
The first step to create your own new report is to make a new XML file. This file should be placed under yourModuleName/views and you can name it as you wish. In this tutorial I will create a new invoice that is made in the module account.
I’ve named the file report_without_prices.xml as you can see here:
In this file you will define the template id’s and names, which will later on be used by your Odoo to find the correct report.
The minimal code looks like this:
<? xml version = "1.0" encoding = "utf-8" ?>
< ! -- Custom report . -- >
< openerp >
< data >
< template id = "report_without_prices_document" >
< t t - call = "report.external_layout" >
< div class = "page" >
< div class = "row" >
< h3 > Title < / h3 >
< / div >
< / div >
< / t >
< / template >
< template id = "report_without_prices" >
< t t - call = "report.html_container" >
< t t - foreach = "doc_ids" t - as = "doc_id" >
< t t - raw = "translate_doc(doc_id, doc_model, 'partner_id.lang', 'account.report_without_prices_document')" / >
< / t >
< / t >
< / template >
< / data >
< / openerp >
So, what is important about this? The name of the template id (from the first record) should be the same as the name for the t-raw that handles translations. In the t-raw you need to add the module name before this name with a dot. Here’s an image to make things more clear:
The second template_id then needs to be identical to the name that you will set in the next file. So let us continue.
2.Add the report to the XML file responsible for reports
This brings us to part 2. Every module has a file that makes a reference to every single report in the module. This is done by a item, which can be found in the XML file.
This file always has the same name structure. It starts with the name of your module, an underscore and then report.xml. Its found in the first level of the directory of your module, as you can see here:
The filename is always yourModuleName_report.xml. Now open up this file and you will see a tag for every report that exists in this module.
The next step for us is to add a new tag for our own report. The code looks like this:
< report
id = "custom_report_without_prices"
model = "account.invoice"
string = "Invoice without prices"
report_type = "qweb-pdf"
name = "account.report_without_prices"
attachment_use = "False"
file = "account.report_without_prices"
/ >
Now that you’ve added this code you’re almost there! The last step is to notify Odoo of the new report.
3. Notify Odoo from the new report
So how do we tell Odoo there is a new report? In every module is a file named __openerp__.py. This file is used to import (include) all files in a module.
As all files are loaded in here we should also add our new XML file in this list. Without this Odoo will not find or use the XML file which will result in a not working report and errors.
Add a new line to the __openerp__.py file, right under ‘data’:[
#Lots of code above this that is not relevant
""" ,
'website' : 'https://www.odoo.com/page/billing' ,
'images' : [ 'images/accounts.jpeg' , 'images/bank_statement.jpeg' , 'images/cash_register.jpeg' , 'images/chart_of_accounts.jpeg' , 'images/customer_invoice.jpeg' , 'images/journal_entries.jpeg' ] ,
'depends' : [ 'base_setup' , 'product' , 'analytic' , 'board' , 'edi' , 'report' ] ,
'data' : [
'views/report_without_prices.xml' ,
#All other files are loaded under this
4. Wrapping things up
Now that you’ve made a new report (a new XML file),added the template id to the moduleName_report.xml file and added your XML file to __openerp__.py you’re done!
The last thing you need to do is reload your module (by command or by a module update) and you’ll see the new report showing up.
If you then look under accounting > Customer Invoices and make a new invoice you will see your new print option:
And, finally, if you print it out you’ll get your custom report!
NOTE:If you want a more advanced code, which shows a full report without the prices just paste this code in reports_without_prices.xml
<? xml version = "1.0" encoding = "utf-8" ?>
< ! -- Custom report -- >
< openerp >
< data >
< template id = "report_without_prices_document" >
< t t - call = "report.external_layout" >
< div class = "page" >
< h2 >
< span t - if = "o.type == 'out_invoice' and (o.state == 'open' or o.state == 'paid')" > Invoice < / span >
< span t - if = "o.type == 'out_invoice' and o.state == 'proforma2'" > PRO - FORMA < / span >
< span t - if = "o.type == 'out_invoice' and o.state == 'draft'" > Draft Invoice < / span >
< span t - if = "o.type == 'out_invoice' and o.state == 'cancel'" > Cancelled Invoice < / span >
< span t - if = "o.type == 'out_refund'" > Refund < / span >
< span t - if = "o.type == 'in_refund'" > Supplier Refund < / span >
< span t - if = "o.type == 'in_invoice'" > Supplier Invoice < / span >
< span t - field = "o.number" / >
< / h2 >
< div class = "row mt32 mb32" >
< div class = "col-xs-3" t - if = "o.name" >
< strong > Description : < / strong >
< p t - field = "o.name" / >
< / div >
< div class = "col-xs-3" t - if = "o.date_invoice" >
< strong > Invoice Date : < / strong >
< p t - field = "o.date_invoice" / >
< / div >
< div class = "col-xs-3" t - if = "o.origin" >
< strong > Source : < / strong >
< p t - field = "o.origin" / >
< / div >
< div class = "col-xs-3" t - if = "o.partner_id.ref" >
< strong > Customer Code : < / strong >
< p t - field = "o.partner_id.ref" / >
< / div >
< / div >
< table class = "table table-condensed" >
< thead >
< tr >
< th style = "width:35%;" > Description < / th >
< th style = "width:15%;" > Quantity < / th >
< ! -- < th class = "text-right" style = "width:15%;" > Unit Price < / th >
< th class = "text-right" groups = "sale.group_discount_per_so_line" > Discount ( % ) < / th >
< th class = "text-right" style = "width:20%;" > Taxes < / th >
< th class = "text-right" style = "width:15%;" > Amount < / th > -- >
< / tr >
< / thead >
< tbody class = "invoice_tbody" >
< tr t - foreach = "o.invoice_line" t - as = "l" >
< td style = "width:25%;" > < span t - field = "l.name" / > < / td >
< td style = "width:15%;" >
< span t - field = "l.quantity" / >
< span t - field = "l.uos_id" groups = "product.group_uom" / >
< / td >
< ! -- < td class = "text-right" style = "width:15%;" >
< span t - field = "l.price_unit" / >
< / td >
< td groups = "sale.group_discount_per_so_line" > < span t - field = "l.discount" / > < / td >
< td class = "text-right" style = "width:20%;" >
< span t - esc = "', '.join(map(lambda x: x.name, l.invoice_line_tax_id))" / >
< / td >
< td class = "text-right" style = "width:15%;" >
< span t - field = "l.price_subtotal"
t - field - options = '{"widget": "monetary", "display_currency": "o.currency_id"}' / >
< / td > -- >
< / tr >
< / tbody >
< / table >
< div class = "row" >
< div class = "col-xs-4 pull-right" >
< table class = "table table-condensed" >
< tr class = "border-black" >
< td > < strong > Total Without Taxes < / strong > < / td >
< td class = "text-right" >
< span t - field = "o.amount_untaxed" t - field - options = '{"widget": "monetary", "display_currency": "o.currency_id"}' / >
< / td >
< / tr >
< tr >
< td > Taxes < / td >
< td class = "text-right" >
< span t - field = "o.amount_tax" t - field - options = '{"widget": "monetary", "display_currency": "o.currency_id"}' / >
< / td >
< / tr >
< tr class = "border-black" >
< td > < strong > Total < / strong > < / td >
< td class = "text-right" >
< span t - field = "o.amount_total" t - field - options = '{"widget": "monetary", "display_currency": "o.currency_id"}' / >
< / td >
< / tr >
< / table >
< / div >
< / div >
< div class = "row" t - if = "o.tax_line" >
< div class = "col-xs-6" >
< table class = "table table-condensed" >
< thead >
< tr >
< th > Tax < / th >
< th class = "text-right" > Base < / th >
< th class = "text-right" > Amount < / th >
< / tr >
< / thead >
< tbody >
< tr t - foreach = "o.tax_line" t - as = "t" >
< td > < span t - field = "t.name" / > < / td >
< td class = "text-right" >
< span t - field = "t.base"
t - field - options = '{"widget": "monetary", "display_currency": "o.currency_id"}' / >
< / td >
< td class = "text-right" >
< span t - field = "t.amount"
t - field - options = '{"widget": "monetary", "display_currency": "o.currency_id"}' / >
< / td >
< / tr >
< / tbody >
< / table >
< / div >
< / div >
< p t - if = "o.comment" >
< strong > Comment : < / strong >
< span t - field = "o.comment" / >
< / p >
< p t - if = "o.payment_term" >
< strong > Payment Term : < / strong >
< span t - field = "o.payment_term" / >
< / p >
< p t - if = "o.fiscal_position" >
< strong > Fiscal Position : < / strong >
< span t - field = "o.fiscal_position" / >
< / p >
< / div >
< / t >
< / template >
< template id = "report_without_prices" >
< t t - call = "report.html_container" >
< t t - foreach = "doc_ids" t - as = "doc_id" >
< t t - raw = "translate_doc(doc_id, doc_model, 'partner_id.lang', 'account.report_without_prices_document')" / >
< / t >
< / t >
< / template >
< / data >
< / openerp >
Looking for more information about reports?
Check out the official documentation