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.

85 lines
3.0 KiB

  1. # -*- coding: utf-8 -*-
  2. # © 2013 XCG Consulting <http://odoo.consulting>
  3. # © 2016 ACSONE SA/NV
  4. # © 2017 Therp BV <http://therp.nl>
  5. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  6. import json
  7. import logging
  8. import os
  9. import requests
  10. import tempfile
  11. from contextlib import closing
  12. from openerp import _, api, models
  13. from openerp.exceptions import UserError
  14. from StringIO import StringIO
  15. logger = logging.getLogger(__name__)
  16. try:
  17. from py3o.template import Template
  18. from py3o.template.helpers import Py3oConvertor
  19. except ImportError:
  20. logger.debug('Cannot import py3o.template')
  21. class Py3oReport(models.TransientModel):
  22. _inherit = 'py3o.report'
  23. @api.multi
  24. def _create_single_report(self, model_instance, data, save_in_attachment):
  25. """ This function to generate our py3o report
  26. """
  27. self.ensure_one()
  28. report_xml = self.ir_actions_report_xml_id
  29. filetype = report_xml.py3o_filetype
  30. if report_xml.py3o_is_local_fusion:
  31. result_path = super(Py3oReport, self)._create_single_report(
  32. model_instance, data, save_in_attachment,
  33. )
  34. with closing(open(result_path, 'r')) as out_stream:
  35. tmpl_data = out_stream.read()
  36. datadict = {}
  37. else:
  38. result_fd, result_path = tempfile.mkstemp(
  39. suffix='.' + filetype, prefix='p3o.report.tmp.')
  40. tmpl_data = self.get_template(model_instance)
  41. in_stream = StringIO(tmpl_data)
  42. with closing(os.fdopen(result_fd, 'w+')) as out_stream:
  43. template = Template(in_stream, out_stream, escape_false=True)
  44. localcontext = self._get_parser_context(model_instance, data)
  45. expressions = template.get_all_user_python_expression()
  46. py_expression = template.convert_py3o_to_python_ast(
  47. expressions)
  48. convertor = Py3oConvertor()
  49. data_struct = convertor(py_expression)
  50. datadict = data_struct.render(localcontext)
  51. # Call py3o.server to render the template in the desired format
  52. files = {
  53. 'tmpl_file': tmpl_data,
  54. }
  55. fields = {
  56. "targetformat": filetype,
  57. "datadict": json.dumps(datadict),
  58. "image_mapping": "{}",
  59. "escape_false": "on",
  60. }
  61. if report_xml.py3o_is_local_fusion:
  62. fields['skipfusion'] = '1'
  63. r = requests.post(
  64. report_xml.py3o_server_id.url, data=fields, files=files)
  65. if r.status_code != 200:
  66. # server says we have an issue... let's tell that to enduser
  67. raise UserError(
  68. _('Fusion server error %s') % r.text,
  69. )
  70. chunk_size = 1024
  71. with open(result_path, 'w+') as fd:
  72. for chunk in r.iter_content(chunk_size):
  73. fd.write(chunk)
  74. if len(model_instance) == 1:
  75. self._postprocess_report(
  76. result_path, model_instance.id, save_in_attachment)
  77. return result_path