PURPOSE ======= I've seen this new improvement regarding the naming of the printed reports: https://www.odoo.com/web?#id=10870&view_type=form&model=project.task&menu_id=3942&action=327 This makes the report have the pdf name being the name instead of the report_name of the ir.actions.report.xml, which is already an improvement. But why don't we allow the users to have their own naming conventions? I mean, we could allow our client to create and name their pdf the way they want, as they do regarding the attachment. Not only when it's about saving it as an attachment on the record, but also when downloading directly the pdf, such that the modification in the previous screenshot, would give the following result when downloaded: People need to have their pdf named automatically according to a convention. When you print 10 sales order during an hour, you don't want to get lost in having the following: Devis / Commande.pdf Devis / Commande(1).pdf Devis / Commande(2).pdf Devis / Commande(3).pdf Devis / Commande(4).pdf Devis / Commande(5).pdf Devis / Commande(6).pdf Devis / Commande(7).pdf especially when those are for different partners.
133 lines
6.2 KiB
Python
133 lines
6.2 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
from openerp.addons.web.http import Controller, route, request
|
|
from openerp.addons.web.controllers.main import _serialize_exception, content_disposition
|
|
from openerp.tools import html_escape
|
|
from openerp.tools.safe_eval import safe_eval as eval
|
|
|
|
import json
|
|
import time
|
|
from werkzeug import exceptions, url_decode
|
|
from werkzeug.test import Client
|
|
from werkzeug.wrappers import BaseResponse
|
|
from werkzeug.datastructures import Headers
|
|
from reportlab.graphics.barcode import createBarcodeDrawing
|
|
|
|
|
|
class ReportController(Controller):
|
|
|
|
#------------------------------------------------------
|
|
# Report controllers
|
|
#------------------------------------------------------
|
|
@route([
|
|
'/report/<path:converter>/<reportname>',
|
|
'/report/<path:converter>/<reportname>/<docids>',
|
|
], type='http', auth='user', website=True)
|
|
def report_routes(self, reportname, docids=None, converter=None, **data):
|
|
report_obj = request.registry['report']
|
|
cr, uid, context = request.cr, request.uid, request.context
|
|
|
|
if docids:
|
|
docids = [int(i) for i in docids.split(',')]
|
|
if data.get('options'):
|
|
data.update(json.loads(data.pop('options')))
|
|
if data.get('context'):
|
|
# Ignore 'lang' here, because the context in data is the one from the webclient *but* if
|
|
# the user explicitely wants to change the lang, this mechanism overwrites it.
|
|
data['context'] = json.loads(data['context'])
|
|
if data['context'].get('lang'):
|
|
del data['context']['lang']
|
|
context.update(data['context'])
|
|
|
|
if converter == 'html':
|
|
html = report_obj.get_html(cr, uid, docids, reportname, data=data, context=context)
|
|
return request.make_response(html)
|
|
elif converter == 'pdf':
|
|
pdf = report_obj.get_pdf(cr, uid, docids, reportname, data=data, context=context)
|
|
pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(pdf))]
|
|
return request.make_response(pdf, headers=pdfhttpheaders)
|
|
else:
|
|
raise exceptions.HTTPException(description='Converter %s not implemented.' % converter)
|
|
|
|
#------------------------------------------------------
|
|
# Misc. route utils
|
|
#------------------------------------------------------
|
|
@route(['/report/barcode', '/report/barcode/<type>/<path:value>'], type='http', auth="user")
|
|
def report_barcode(self, type, value, width=600, height=100, humanreadable=0):
|
|
"""Contoller able to render barcode images thanks to reportlab.
|
|
Samples:
|
|
<img t-att-src="'/report/barcode/QR/%s' % o.name"/>
|
|
<img t-att-src="'/report/barcode/?type=%s&value=%s&width=%s&height=%s' %
|
|
('QR', o.name, 200, 200)"/>
|
|
|
|
:param type: Accepted types: 'Codabar', 'Code11', 'Code128', 'EAN13', 'EAN8', 'Extended39',
|
|
'Extended93', 'FIM', 'I2of5', 'MSI', 'POSTNET', 'QR', 'Standard39', 'Standard93',
|
|
'UPCA', 'USPS_4State'
|
|
:param humanreadable: Accepted values: 0 (default) or 1. 1 will insert the readable value
|
|
at the bottom of the output image
|
|
"""
|
|
try:
|
|
barcode = request.registry['report'].barcode(type, value, width=width, height=height, humanreadable=humanreadable)
|
|
except (ValueError, AttributeError):
|
|
raise exceptions.HTTPException(description='Cannot convert into barcode.')
|
|
|
|
return request.make_response(barcode, headers=[('Content-Type', 'image/png')])
|
|
|
|
@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 = json.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')
|
|
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))
|
|
|
|
cr, uid = request.cr, request.uid
|
|
report = request.registry['report']._get_report_from_name(cr, uid, reportname)
|
|
filename = "%s.%s" % (report.name, "pdf")
|
|
ids = [int(x) for x in docids.split(",")]
|
|
obj = request.env[report.model].browse(ids)
|
|
if report.print_report_name and not len(obj) > 1:
|
|
filename = eval(report.print_report_name, {'object': obj, 'time': time})
|
|
response.headers.add('Content-Disposition', content_disposition(filename))
|
|
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(json.dumps(error)))
|
|
|
|
@route(['/report/check_wkhtmltopdf'], type='json', auth="user")
|
|
def check_wkhtmltopdf(self):
|
|
return request.registry['report']._check_wkhtmltopdf()
|