Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

113 linhas
4.4KB

  1. # Copyright 2019 信莱德软件
  2. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
  3. import json
  4. from werkzeug import exceptions, url_decode
  5. from odoo.http import route, request
  6. from odoo.addons.web.controllers import main
  7. from odoo.addons.web.controllers.main import (
  8. _serialize_exception,
  9. content_disposition
  10. )
  11. from odoo.tools import html_escape
  12. import logging
  13. _logger = logging.getLogger(__name__)
  14. class ReportController(main.ReportController):
  15. TYPES_MAPPING = {
  16. 'doc': 'application/vnd.ms-word',
  17. 'html': 'text/html',
  18. 'odt': 'application/vnd.oasis.opendocument.text',
  19. 'pdf': 'application/pdf',
  20. 'sxw': 'application/vnd.sun.xml.writer',
  21. 'xls': 'application/vnd.ms-excel',
  22. 'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  23. 'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
  24. }
  25. @route()
  26. def report_routes(self, reportname, docids=None, converter=None, **data):
  27. if converter != 'docx':
  28. return super(ReportController, self).report_routes(
  29. reportname=reportname, docids=docids, converter=converter,
  30. **data)
  31. context = dict(request.env.context)
  32. if docids:
  33. docids = [int(i) for i in docids.split(',')]
  34. if data.get('options'):
  35. data.update(json.loads(data.pop('options')))
  36. if data.get('context'):
  37. # Ignore 'lang' here, because the context in data is the
  38. # one from the webclient *but* if the user explicitely wants to
  39. # change the lang, this mechanism overwrites it.
  40. data['context'] = json.loads(data['context'])
  41. if data['context'].get('lang'):
  42. del data['context']['lang']
  43. context.update(data['context'])
  44. ir_action = request.env['ir.actions.report']
  45. action_docx_report = ir_action.get_from_report_name(
  46. reportname, "docx").with_context(context)
  47. if not action_docx_report:
  48. raise exceptions.HTTPException(
  49. description='Docx action report not found for report_name '
  50. '%s' % reportname)
  51. res, filetype = action_docx_report.render(docids, data)
  52. filename = action_docx_report.gen_report_download_filename(
  53. docids, data)
  54. if not filename.endswith(filetype):
  55. filename = "{}.{}".format(filename, filetype)
  56. content_type = self.TYPES_MAPPING.get(
  57. filetype, 'octet-stream')
  58. http_headers = [('Content-Type', content_type),
  59. ('Content-Length', len(res)),
  60. ('Content-Disposition', content_disposition(filename))
  61. ]
  62. return request.make_response(res, headers=http_headers)
  63. @route()
  64. def report_download(self, data, token):
  65. """This function is used by 'qwebactionmanager.js' in order to trigger
  66. the download of a docx/controller report.
  67. :param data: a javascript array JSON.stringified containg report
  68. internal url ([0]) and type [1]
  69. :returns: Response with a filetoken cookie and an attachment header
  70. """
  71. requestcontent = json.loads(data)
  72. url, report_type = requestcontent[0], requestcontent[1]
  73. if 'docx' not in report_type:
  74. return super(ReportController, self).report_download(data, token)
  75. try:
  76. reportname = url.split('/report/docx/')[1].split('?')[0]
  77. docids = None
  78. if '/' in reportname:
  79. reportname, docids = reportname.split('/')
  80. if docids:
  81. # Generic report:
  82. response = self.report_routes(
  83. reportname, docids=docids, converter='docx')
  84. else:
  85. # Particular report:
  86. # decoding the args represented in JSON
  87. data = list(url_decode(url.split('?')[1]).items())
  88. response = self.report_routes(
  89. reportname, converter='docx', **dict(data))
  90. response.set_cookie('fileToken', token)
  91. return response
  92. except Exception as e:
  93. se = _serialize_exception(e)
  94. error = {
  95. 'code': 200,
  96. 'message': "Odoo Server Error",
  97. 'data': se
  98. }
  99. return request.make_response(html_escape(json.dumps(error)))
上海开阖软件有限公司 沪ICP备12045867号-1