Browse Source
[IMP] report_py3o: Take into account print_report_name
[IMP] report_py3o: Take into account print_report_name
If a Printed Report Name is set on the action report, use it as downloaded filename refs #133pull/140/head
Laurent Mignon
8 years ago
committed by
Laurent Mignon (ACSONE)
7 changed files with 193 additions and 3 deletions
-
1report_py3o/__init__.py
-
1report_py3o/__manifest__.py
-
1report_py3o/controllers/__init__.py
-
100report_py3o/controllers/main.py
-
24report_py3o/models/ir_actions_report_xml.py
-
59report_py3o/static/src/js/py3oactionmanager.js
-
10report_py3o/views/report_py3o.xml
@ -1 +1,2 @@ |
|||||
from . import models |
from . import models |
||||
|
from . import controllers |
@ -0,0 +1 @@ |
|||||
|
from . import main |
@ -0,0 +1,100 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2017 ACSONE SA/NV |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) |
||||
|
import json |
||||
|
import mimetypes |
||||
|
from werkzeug import exceptions, url_decode |
||||
|
|
||||
|
from odoo.http import route, request |
||||
|
|
||||
|
from odoo.addons.report.controllers import main |
||||
|
from odoo.addons.web.controllers.main import ( |
||||
|
_serialize_exception, |
||||
|
content_disposition |
||||
|
) |
||||
|
from odoo.tools import html_escape |
||||
|
|
||||
|
|
||||
|
class ReportController(main.ReportController): |
||||
|
|
||||
|
@route() |
||||
|
def report_routes(self, reportname, docids=None, converter=None, **data): |
||||
|
if converter != 'py3o': |
||||
|
return super(ReportController, self).report_routes( |
||||
|
reportname=reportname, docids=docids, converter=converter, |
||||
|
**data) |
||||
|
context = dict(request.env.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']) |
||||
|
|
||||
|
ir_action = request.env['ir.actions.report.xml'] |
||||
|
action_py3o_report = ir_action.get_from_report_name( |
||||
|
reportname, "py3o").with_context(context) |
||||
|
if not action_py3o_report: |
||||
|
raise exceptions.HTTPException( |
||||
|
description='Py3o action report not found for report_name ' |
||||
|
'%s' % reportname) |
||||
|
context['report_name'] = reportname |
||||
|
py3o_report = request.env['py3o.report'].create({ |
||||
|
'ir_actions_report_xml_id': action_py3o_report.id |
||||
|
}).with_context(context) |
||||
|
res, filetype = py3o_report.create_report(docids, data) |
||||
|
filename = action_py3o_report.gen_report_download_filename( |
||||
|
docids, data) |
||||
|
content_type = mimetypes.guess_type("x." + filetype)[0] |
||||
|
http_headers = [('Content-Type', content_type), |
||||
|
('Content-Length', len(res)), |
||||
|
('Content-Disposition', content_disposition(filename)) |
||||
|
] |
||||
|
return request.make_response(res, headers=http_headers) |
||||
|
|
||||
|
@route() |
||||
|
def report_download(self, data, token): |
||||
|
"""This function is used by 'qwebactionmanager.js' in order to trigger |
||||
|
the download of a py3o/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] |
||||
|
if type != 'py3o': |
||||
|
return super(ReportController, self).report_download(data, token) |
||||
|
try: |
||||
|
reportname = url.split('/report/py3o/')[1].split('?')[0] |
||||
|
docids = None |
||||
|
if '/' in reportname: |
||||
|
reportname, docids = reportname.split('/') |
||||
|
|
||||
|
if docids: |
||||
|
# Generic report: |
||||
|
response = self.report_routes( |
||||
|
reportname, docids=docids, converter='py3o') |
||||
|
else: |
||||
|
# Particular report: |
||||
|
# decoding the args represented in JSON |
||||
|
data = url_decode(url.split('?')[1]).items() |
||||
|
response = self.report_routes( |
||||
|
reportname, converter='py3o', **dict(data)) |
||||
|
response.set_cookie('fileToken', token) |
||||
|
return response |
||||
|
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))) |
@ -0,0 +1,59 @@ |
|||||
|
/* Copyright 2017 ACSONE SA/NV |
||||
|
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */
|
||||
|
odoo.define('report_py3o.report', function (require) { |
||||
|
|
||||
|
var ActionManager = require('web.ActionManager'); |
||||
|
var core = require('web.core'); |
||||
|
var crash_manager = require('web.crash_manager'); |
||||
|
var framework = require('web.framework'); |
||||
|
var session = require('web.session'); |
||||
|
|
||||
|
var _t = core._t; |
||||
|
|
||||
|
var trigger_download = function(session, response, c, action, options) { |
||||
|
session.get_file({ |
||||
|
url: '/report/download', |
||||
|
data: {data: JSON.stringify(response)}, |
||||
|
complete: framework.unblockUI, |
||||
|
error: c.rpc_error.bind(c), |
||||
|
success: function(){ |
||||
|
if (action && options && !action.dialog) { |
||||
|
options.on_close(); |
||||
|
} |
||||
|
}, |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
ActionManager.include({ |
||||
|
ir_actions_report_xml: function(action, options) { |
||||
|
var self = this; |
||||
|
framework.blockUI(); |
||||
|
action = _.clone(action); |
||||
|
_t = core._t; |
||||
|
|
||||
|
// Py3o reports
|
||||
|
if ('report_type' in action && action.report_type == 'py3o' ) { |
||||
|
var report_url = '/report/py3o/' + action.report_name;; |
||||
|
// generic report: no query string
|
||||
|
// particular: query string of action.data.form and context
|
||||
|
if (!('data' in action) || !(action.data)) { |
||||
|
if ('active_ids' in action.context) { |
||||
|
report_url += "/" + action.context.active_ids.join(','); |
||||
|
} |
||||
|
} else { |
||||
|
report_url += "&options=" + encodeURIComponent(JSON.stringify(action.data)); |
||||
|
report_url += "&context=" + encodeURIComponent(JSON.stringify(action.context)); |
||||
|
} |
||||
|
|
||||
|
var response = new Array(); |
||||
|
response[0] = report_url; |
||||
|
response[1] = action.report_type; |
||||
|
var c = crash_manager; |
||||
|
return trigger_download(self.session, response, c, action, options); |
||||
|
} else { |
||||
|
return self._super(action, options); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
}); |
@ -0,0 +1,10 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<openerp> |
||||
|
<data> |
||||
|
<template id="assets_backend" name="report assets" inherit_id="web.assets_backend"> |
||||
|
<xpath expr="." position="inside"> |
||||
|
<script type="text/javascript" src="/report_py3o/static/src/js/py3oactionmanager.js"></script> |
||||
|
</xpath> |
||||
|
</template> |
||||
|
</data> |
||||
|
</openerp> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue