OCA reporting engine fork for dev and update.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

100 lines
4.0 KiB

  1. # -*- coding: utf-8 -*-
  2. # Copyright 2017 ACSONE SA/NV
  3. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
  4. import json
  5. import mimetypes
  6. from werkzeug import exceptions, url_decode
  7. from odoo.http import route, request
  8. from odoo.addons.report.controllers import main
  9. from odoo.addons.web.controllers.main import (
  10. _serialize_exception,
  11. content_disposition
  12. )
  13. from odoo.tools import html_escape
  14. class ReportController(main.ReportController):
  15. @route()
  16. def report_routes(self, reportname, docids=None, converter=None, **data):
  17. if converter != 'py3o':
  18. return super(ReportController, self).report_routes(
  19. reportname=reportname, docids=docids, converter=converter,
  20. **data)
  21. context = dict(request.env.context)
  22. if docids:
  23. docids = [int(i) for i in docids.split(',')]
  24. if data.get('options'):
  25. data.update(json.loads(data.pop('options')))
  26. if data.get('context'):
  27. # Ignore 'lang' here, because the context in data is the
  28. # one from the webclient *but* if the user explicitely wants to
  29. # change the lang, this mechanism overwrites it.
  30. data['context'] = json.loads(data['context'])
  31. if data['context'].get('lang'):
  32. del data['context']['lang']
  33. context.update(data['context'])
  34. ir_action = request.env['ir.actions.report.xml']
  35. action_py3o_report = ir_action.get_from_report_name(
  36. reportname, "py3o").with_context(context)
  37. if not action_py3o_report:
  38. raise exceptions.HTTPException(
  39. description='Py3o action report not found for report_name '
  40. '%s' % reportname)
  41. context['report_name'] = reportname
  42. py3o_report = request.env['py3o.report'].create({
  43. 'ir_actions_report_xml_id': action_py3o_report.id
  44. }).with_context(context)
  45. res, filetype = py3o_report.create_report(docids, data)
  46. filename = action_py3o_report.gen_report_download_filename(
  47. docids, data)
  48. content_type = mimetypes.guess_type("x." + filetype)[0]
  49. http_headers = [('Content-Type', content_type),
  50. ('Content-Length', len(res)),
  51. ('Content-Disposition', content_disposition(filename))
  52. ]
  53. return request.make_response(res, headers=http_headers)
  54. @route()
  55. def report_download(self, data, token):
  56. """This function is used by 'qwebactionmanager.js' in order to trigger
  57. the download of a py3o/controller report.
  58. :param data: a javascript array JSON.stringified containg report
  59. internal url ([0]) and type [1]
  60. :returns: Response with a filetoken cookie and an attachment header
  61. """
  62. requestcontent = json.loads(data)
  63. url, type = requestcontent[0], requestcontent[1]
  64. if type != 'py3o':
  65. return super(ReportController, self).report_download(data, token)
  66. try:
  67. reportname = url.split('/report/py3o/')[1].split('?')[0]
  68. docids = None
  69. if '/' in reportname:
  70. reportname, docids = reportname.split('/')
  71. if docids:
  72. # Generic report:
  73. response = self.report_routes(
  74. reportname, docids=docids, converter='py3o')
  75. else:
  76. # Particular report:
  77. # decoding the args represented in JSON
  78. data = url_decode(url.split('?')[1]).items()
  79. response = self.report_routes(
  80. reportname, converter='py3o', **dict(data))
  81. response.set_cookie('fileToken', token)
  82. return response
  83. except Exception, e:
  84. se = _serialize_exception(e)
  85. error = {
  86. 'code': 200,
  87. 'message': "Odoo Server Error",
  88. 'data': se
  89. }
  90. return request.make_response(html_escape(json.dumps(error)))