How to set PDF name in qWeb report, Odoo?
Solution 1
In Odoo 8 you can patch the method report_download of addons/report/controllers/main.py like below (between FIX START and END). It will then use the code for the attachment attribute in the report action definition. As the system will then always also save the file as an attachment in the database you can change the behaviour further to only save in the database when attachment_use is set to True. In this way no extra fields need to be added and views changed.
@route(['/report/download'], type='http', auth="user")
def report_download(self, data, token):
"""This function is used by 'qwebactionmanager.js' in order to trigger the download of
a pdf/controller report.
:param data: a javascript array JSON.stringified containg report internal url ([0]) and
type [1]
:returns: Response with a filetoken cookie and an attachment header
"""
requestcontent = simplejson.loads(data)
url, type = requestcontent[0], requestcontent[1]
try:
if type == 'qweb-pdf':
reportname = url.split('/report/pdf/')[1].split('?')[0]
docids = None
if '/' in reportname:
reportname, docids = reportname.split('/')
if docids:
# Generic report:
response = self.report_routes(reportname, docids=docids, converter='pdf')
##### FIX START: switch reportname with the evaluated attachment attribute of the action if available
docids = [int(i) for i in docids.split(',')]
report_obj = request.registry['report']
cr, uid, context = request.cr, request.uid, request.context
report = report_obj._get_report_from_name(cr, uid, reportname)
if report.attachment:
obj = report_obj.pool[report.model].browse(cr, uid, docids[0])
reportname=eval(report.attachment, {'object': obj, 'time': time}).split('.pdf')[0]
##### FIX END
else:
# Particular report:
data = url_decode(url.split('?')[1]).items() # decoding the args represented in JSON
response = self.report_routes(reportname, converter='pdf', **dict(data))
response.headers.add('Content-Disposition', 'attachment; filename=%s.pdf;' % reportname)
response.set_cookie('fileToken', token)
return response
elif type =='controller':
reqheaders = Headers(request.httprequest.headers)
response = Client(request.httprequest.app, BaseResponse).get(url, headers=reqheaders, follow_redirects=True)
response.set_cookie('fileToken', token)
return response
else:
return
except Exception, e:
se = _serialize_exception(e)
error = {
'code': 200,
'message': "Odoo Server Error",
'data': se
}
return request.make_response(html_escape(simplejson.dumps(error)))
You can set the attachment attribute of a report action for example in this way:
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<!-- rename the file names of the standard rfq report -->
<record id="purchase.report_purchase_quotation" model="ir.actions.report.xml">
<field name="attachment">'RFQ_'+object.name+'.pdf'</field>
</record>
</data>
</openerp>
This is the patch of _check_attachment of the Report object in addons/report/report.py to modify the attachment_use behaviour:
@api.v7
def _check_attachment_use(self, cr, uid, ids, report):
""" Check attachment_use field. If set to true and an existing pdf is already saved, load
this one now. Else, mark save it.
"""
save_in_attachment = {}
save_in_attachment['model'] = report.model
save_in_attachment['loaded_documents'] = {}
if report.attachment:
for record_id in ids:
obj = self.pool[report.model].browse(cr, uid, record_id)
filename = eval(report.attachment, {'object': obj, 'time': time})
# If the user has checked 'Reload from Attachment'
if report.attachment_use:
alreadyindb = [('datas_fname', '=', filename),
('res_model', '=', report.model),
('res_id', '=', record_id)]
attach_ids = self.pool['ir.attachment'].search(cr, uid, alreadyindb)
if attach_ids:
# Add the loaded pdf in the loaded_documents list
pdf = self.pool['ir.attachment'].browse(cr, uid, attach_ids[0]).datas
pdf = base64.decodestring(pdf)
save_in_attachment['loaded_documents'][record_id] = pdf
_logger.info('The PDF document %s was loaded from the database' % filename)
continue # Do not save this document as we already ignore it
# FIX START (commenting out below lines and indenting the else clause one level down)
# If the user has checked 'Save as Attachment Prefix'
#~ if filename is False:
#~ # May be false if, for instance, the 'attachment' field contains a condition
#~ # preventing to save the file.
#~ continue
else:
save_in_attachment[record_id] = filename # Mark current document to be saved
# FIX END
return save_in_attachment
Solution 2
you can use 'custom file name' module
- Download module
- https://www.odoo.com/apps/modules/8.0/report_custom_filename/
- Change name in setting - > action -> report
select your report and change the name ..
Solution 3
You can give dynamic report name using configuration, but it will apply when you print one report.
Below is the example to Print custom name in report.Create one field in ir.actions.report.xml, in which user can configure report name.
from openerp import models, fields
class IrActionsReportXml(models.Model):
_inherit = 'ir.actions.report.xml'
download_filename = fields.Char(
'Download filename')
Now you need to create two files.
-
Report Controller
from openerp import http from openerp.addons.mail.models import mail_template from openerp.addons.report.controllers.main import ReportController from openerp.addons.web.controllers.main import content_disposition class ReportController(ReportController): @http.route([ '/report/<path:converter>/<reportname>', '/report/<path:converter>/<reportname>/<docids>', ]) def report_routes(self, reportname, docids=None, converter=None, **data): response = super(ReportController, self).report_routes( reportname, docids=docids, converter=converter, **data) if docids: docids = [int(i) for i in docids.split(',')] report_xml = http.request.session.model('ir.actions.report.xml') report_ids = report_xml.search( [('report_name', '=', reportname)]) for report in report_xml.browse(report_ids): if not report.download_filename: continue objects = http.request.session.model(report.model)\ .browse(docids or []) generated_filename = mail_template.mako_template_env\ .from_string(report.download_filename)\ .render({ 'objects': objects, 'o': objects[:1], 'object': objects[:1], 'ext': report.report_type.replace('qweb-', ''), }) response.headers['Content-Disposition'] = content_disposition( generated_filename) return response @http.route(['/report/download']) def report_download(self, data, token): response = super(ReportController, self).report_download(data, token) # if we got another content disposition before, ditch the one added # by super() last_index = None for i in range(len(response.headers) - 1, -1, -1): if response.headers[i][0] == 'Content-Disposition': if last_index: response.headers.pop(last_index) last_index = i return response
2.Report.py
import json
from openerp import http
from openerp.addons.web.controllers import main
from openerp.addons.mail.models import mail_template
class Reports(main.Reports):
@http.route('/web/report', type='http', auth="user")
@main.serialize_exception
def index(self, action, token):
result = super(Reports, self).index(action, token)
action = json.loads(action)
context = dict(http.request.context)
context.update(action["context"])
report_xml = http.request.env['ir.actions.report.xml']
reports = report_xml.search([
('report_name', '=', action['report_name']),
('download_filename', '!=', False)])
for report in reports:
objects = http.request.session.model(context['active_model'])\
.browse(context['active_ids'])
generated_filename = mail_template.mako_template_env\
.from_string(report.download_filename)\
.render({
'objects': objects,
'o': objects[0],
'object': objects[0],
})
result.headers['Content-Disposition'] = main.content_disposition(
generated_filename)
return result
Odoo community Providing us a default module for report custom name. you can directly install this module and set report name like : ${o.name}
Here o means your record.
Below is a link of odoo community module for V8 and V9.
https://www.odoo.com/apps/modules/9.0/report_custom_filename/
https://www.odoo.com/apps/modules/8.0/report_custom_filename/ This may help you.
Solution 4
I think this was a bug which was fixed in version 9. Simply replace the contents of addons\report\controllers\main.py with this https://github.com/odoo/odoo/blob/9.0/addons/report/controllers/main.py and then restart the odoo server
Solution 5
<report
id="report_sale_order"
string="Quotation / Order"
model="sale.order"
report_type="qweb-pdf"
file="sale.report_saleorder"
name="sale.report_saleorder"
/>
is correct for string name is a print PDF name done
Breba
Updated on June 14, 2022Comments
-
Breba about 2 years
I'm making reports using qWeb in Odoo 8. Those generated PDF files are saved with a "default" name. I would like to set a specific name to every generated file (not after file was saved, but in "generation" time).
Is that possible? If it is, how to do it?
Thanks in advance.