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.

146 lines
4.9 KiB

  1. from base64 import b64decode
  2. from tempfile import NamedTemporaryFile as tempfile
  3. from openerp import pooler
  4. from openerp.report.report_sxw import *
  5. from openerp.tools.translate import _
  6. from openerp.osv.osv import except_osv
  7. from py3o.template import Template
  8. from oe_json_serializer import OESerializer
  9. import json
  10. import requests
  11. import os
  12. class py3o_report(report_sxw):
  13. # def __init__(self, name, table):
  14. # super(py3o_report, self).__init__(name, table)
  15. def get_values(self, cr, uid, ids, data, context):
  16. ''' Override this function to customize the dictionary given to the
  17. py3o.template renderer. '''
  18. return {
  19. 'lang': self.get_lang(cr, uid, context),
  20. 'objects': self.getObjects(cr, uid, ids, context),
  21. }
  22. def get_lang(self, cr, uid, context):
  23. pool = pooler.get_pool(cr.dbname)
  24. lang_obj = pool.get('res.lang')
  25. user_obj = pool.get('res.users')
  26. lang_code = user_obj.browse(cr, uid, uid, context=context).lang
  27. lang = lang_obj.search(cr, uid,
  28. [('code', '=', lang_code)],
  29. context=context)[0]
  30. return lang_obj.browse(cr, uid, lang, context=context)
  31. def format_date(self, date, values):
  32. ''' Return a date formatted according to the language extracted from
  33. the "values" argument (which should be the result of get_values). '''
  34. return date.strftime(values['lang'].date_format)
  35. def create(self, cr, uid, ids, data, context=None):
  36. # Find the report definition to get its settings.
  37. pool = pooler.get_pool(cr.dbname)
  38. report_xml_obj = pool.get('ir.actions.report.xml')
  39. report_xml_ids = report_xml_obj.search(cr, uid,
  40. [('report_name', '=', self.name[7:])], # Ignore "report."
  41. context=context)
  42. if not report_xml_ids:
  43. return super(py3o_report, self).create(cr, uid, ids, data,
  44. context=context)
  45. report_xml = report_xml_obj.browse(cr, uid,
  46. report_xml_ids[0],
  47. context=context)
  48. template = report_xml.py3o_template_id
  49. filetype = report_xml.py3o_fusion_filetype
  50. #Try to request fusion server:
  51. fusion_server_obj = pool['py3o.server']
  52. #TODO: Raise a message if no config found
  53. fusion_server_id = fusion_server_obj.search(
  54. cr, uid, [], context=context
  55. )[0]
  56. fusion_server = fusion_server_obj.browse(cr, uid, fusion_server_id)
  57. # py3o.template operates on filenames so create temporary files.
  58. in_temp = tempfile(suffix='.odt', prefix='py3o-template-')
  59. in_temp.write(b64decode(template.py3o_template_data))
  60. in_temp.seek(0)
  61. out_temp = tempfile(suffix='.odt', prefix='py3o-report-')
  62. # We need to get the variables used in the template
  63. #TODO: Find a way to avoid calling Template
  64. t = Template(in_temp.name, out_temp.name)
  65. # Remove 'py3o.'
  66. user_variable = [x[5:] for x in t.get_all_user_python_expression()]
  67. print user_variable
  68. values = self.get_values(cr, uid, ids, data, context)
  69. t.render(values)
  70. print values
  71. #WARNING: We rely on the fact that there is a for loop on the report
  72. # on objects (for object in objects) due to lack of time
  73. val_dict = {}
  74. for val in values:
  75. if val == 'objects':
  76. o = []
  77. for obj in values[val]:
  78. x = OESerializer.serialize(
  79. obj,
  80. [
  81. v[len('object') + 1:]
  82. for v in user_variable
  83. if v.startswith('object')
  84. ]
  85. )
  86. o.append(x)
  87. val_dict.update({val: o})
  88. continue
  89. x = OESerializer.serialize(
  90. values[val],
  91. [
  92. v[len(val) + 1:]
  93. for v in user_variable
  94. if v.startswith(val)
  95. ]
  96. )
  97. val_dict.update({val: x})
  98. import pprint
  99. pprint.pprint(val_dict)
  100. val_json = json.dumps(val_dict)
  101. fields = {
  102. 'targetformat': filetype.fusion_ext,
  103. 'datadict': val_json,
  104. 'image_mapping': '{}',
  105. }
  106. print fields
  107. r = requests.post(
  108. fusion_server.url, data=fields, files={'tmpl_file': in_temp}
  109. )
  110. in_temp.close()
  111. if r.status_code == 400:
  112. raise Exception("Problem with fusion server: %s" % r.json())
  113. chunk_size = 1024
  114. ext = filetype.human_ext
  115. for chunk in r.iter_content(chunk_size):
  116. out_temp.write(chunk)
  117. out_temp.seek(0)
  118. return out_temp.read(), ext