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.

91 lines
3.9 KiB

  1. # Copyright (C) 2014-2015 Grupo ESOC <www.grupoesoc.es>
  2. # License AGPL-3.0 or later (https://www.gnuorg/licenses/agpl.html).
  3. import json
  4. import time
  5. from odoo.addons.web.controllers import main as report
  6. from odoo.http import content_disposition, request, route, serialize_exception
  7. from odoo.tools import safe_eval, html_escape
  8. from werkzeug.urls import url_decode
  9. class ReportController(report.ReportController):
  10. @route()
  11. def report_routes(self, reportname, docids=None, converter=None, **data):
  12. if converter == 'xml':
  13. report = request.env['ir.actions.report']._get_report_from_name(
  14. reportname)
  15. context = dict(request.env.context)
  16. if docids:
  17. docids = [int(i) for i in docids.split(',')]
  18. if data.get('options'):
  19. data.update(json.loads(data.pop('options')))
  20. if data.get('context'):
  21. # Ignore 'lang' here, because the context in data is the one
  22. # from the webclient *but* if the user explicitely wants to
  23. # change the lang, this mechanism overwrites it.
  24. data['context'] = json.loads(data['context'])
  25. if data['context'].get('lang'):
  26. del data['context']['lang']
  27. context.update(data['context'])
  28. xml = report.with_context(context).render_qweb_xml(docids,
  29. data=data)[0]
  30. xmlhttpheaders = [('Content-Type', 'text/xml'),
  31. ('Content-Length', len(xml))]
  32. return request.make_response(xml, headers=xmlhttpheaders)
  33. else:
  34. return super(ReportController, self).report_routes(
  35. reportname, docids, converter, **data)
  36. @route()
  37. def report_download(self, data, token):
  38. requestcontent = json.loads(data)
  39. url, report_type = requestcontent[0], requestcontent[1]
  40. if report_type == 'qweb-xml':
  41. try:
  42. reportname = url.split('/report/xml/')[1].split('?')[0]
  43. docids = None
  44. if '/' in reportname:
  45. reportname, docids = reportname.split('/')
  46. if docids:
  47. # Generic report:
  48. response = self.report_routes(
  49. reportname, docids=docids, converter='xml')
  50. else:
  51. # Particular report:
  52. # decoding the args represented in JSON
  53. data = url_decode(url.split('?')[1]).items()
  54. response = self.report_routes(
  55. reportname, converter='xml', **dict(data))
  56. report_obj = request.env['ir.actions.report']
  57. report = report_obj._get_report_from_name(reportname)
  58. filename = "%s.xml" % (report.name)
  59. if docids:
  60. ids = [int(x) for x in docids.split(",")]
  61. records = request.env[report.model].browse(ids)
  62. if report.print_report_name and not len(records) > 1:
  63. report_name = safe_eval(report.print_report_name,
  64. {'object': records,
  65. 'time': time})
  66. filename = "%s.xml" % (report_name)
  67. response.headers.add('Content-Disposition',
  68. content_disposition(filename))
  69. response.set_cookie('fileToken', token)
  70. return response
  71. except Exception as e:
  72. se = serialize_exception(e)
  73. error = {
  74. 'code': 200,
  75. 'message': "Odoo Server Error",
  76. 'data': se
  77. }
  78. return request.make_response(html_escape(json.dumps(error)))
  79. else:
  80. return super(ReportController, self).report_download(data, token)