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.

144 lines
4.9 KiB

10 years ago
  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_user_variable()]
  67. print user_variable
  68. values = self.get_values(cr, uid, ids, data, context)
  69. print values
  70. #WARNING: We rely on the fact that there is a for loop on the report
  71. # on objects (for object in objects) due to lack of time
  72. val_dict = {}
  73. for val in values:
  74. if val == 'objects':
  75. o = []
  76. for obj in values[val]:
  77. x = OESerializer.serialize(
  78. obj,
  79. [
  80. v[len('object') + 1:]
  81. for v in user_variable
  82. if v.startswith('object')
  83. ]
  84. )
  85. o.append(x)
  86. val_dict.update({val: o})
  87. continue
  88. x = OESerializer.serialize(
  89. values[val],
  90. [
  91. v[len(val) + 1:]
  92. for v in user_variable
  93. if v.startswith(val)
  94. ]
  95. )
  96. val_dict.update({val: x})
  97. import pprint
  98. pprint.pprint(val_dict)
  99. val_json = json.dumps(val_dict)
  100. fields = {
  101. 'targetformat': filetype.fusion_ext,
  102. 'datadict': val_json,
  103. 'image_mapping': '{}',
  104. }
  105. print fields
  106. r = requests.post(
  107. fusion_server.url, data=fields, files={'tmpl_file': in_temp}
  108. )
  109. in_temp.close()
  110. if r.status_code == 400:
  111. raise Exception("Problem with fusion server: %s" % r.json())
  112. chunk_size = 1024
  113. ext = filetype.human_ext
  114. for chunk in r.iter_content(chunk_size):
  115. out_temp.write(chunk)
  116. out_temp.seek(0)
  117. return out_temp.read(), ext