Browse Source

[MIG] report_py3o, report_py3o_fusion_server: Migration to 12.0

14.0-report-py3o-pr-506
Laurent Mignon (ACSONE) 6 years ago
committed by default
parent
commit
b781f4f099
  1. 7
      report_py3o/__manifest__.py
  2. 21
      report_py3o/controllers/main.py
  3. 16
      report_py3o/demo/report_py3o.xml
  4. 2
      report_py3o/i18n/am.po
  5. 2
      report_py3o/i18n/ar.po
  6. 2
      report_py3o/i18n/bg.po
  7. 2
      report_py3o/i18n/bs.po
  8. 2
      report_py3o/i18n/ca.po
  9. 2
      report_py3o/i18n/cs.po
  10. 2
      report_py3o/i18n/da.po
  11. 2
      report_py3o/i18n/de.po
  12. 2
      report_py3o/i18n/el_GR.po
  13. 2
      report_py3o/i18n/en_GB.po
  14. 2
      report_py3o/i18n/es.po
  15. 2
      report_py3o/i18n/es_AR.po
  16. 2
      report_py3o/i18n/es_CL.po
  17. 2
      report_py3o/i18n/es_CO.po
  18. 2
      report_py3o/i18n/es_CR.po
  19. 2
      report_py3o/i18n/es_DO.po
  20. 2
      report_py3o/i18n/es_EC.po
  21. 2
      report_py3o/i18n/es_ES.po
  22. 2
      report_py3o/i18n/es_MX.po
  23. 2
      report_py3o/i18n/es_PE.po
  24. 2
      report_py3o/i18n/es_PY.po
  25. 2
      report_py3o/i18n/es_VE.po
  26. 2
      report_py3o/i18n/et.po
  27. 2
      report_py3o/i18n/eu.po
  28. 2
      report_py3o/i18n/fa.po
  29. 2
      report_py3o/i18n/fi.po
  30. 2
      report_py3o/i18n/fr.po
  31. 2
      report_py3o/i18n/fr_CA.po
  32. 2
      report_py3o/i18n/fr_CH.po
  33. 2
      report_py3o/i18n/gl.po
  34. 2
      report_py3o/i18n/gl_ES.po
  35. 2
      report_py3o/i18n/he.po
  36. 2
      report_py3o/i18n/hr.po
  37. 2
      report_py3o/i18n/hr_HR.po
  38. 2
      report_py3o/i18n/hu.po
  39. 2
      report_py3o/i18n/id.po
  40. 2
      report_py3o/i18n/it.po
  41. 2
      report_py3o/i18n/ja.po
  42. 2
      report_py3o/i18n/ko.po
  43. 2
      report_py3o/i18n/lt.po
  44. 2
      report_py3o/i18n/lt_LT.po
  45. 2
      report_py3o/i18n/lv.po
  46. 2
      report_py3o/i18n/mk.po
  47. 2
      report_py3o/i18n/mn.po
  48. 2
      report_py3o/i18n/nb.po
  49. 2
      report_py3o/i18n/nb_NO.po
  50. 2
      report_py3o/i18n/nl.po
  51. 2
      report_py3o/i18n/nl_BE.po
  52. 2
      report_py3o/i18n/nl_NL.po
  53. 2
      report_py3o/i18n/pl.po
  54. 2
      report_py3o/i18n/pt.po
  55. 2
      report_py3o/i18n/pt_BR.po
  56. 2
      report_py3o/i18n/pt_PT.po
  57. 2
      report_py3o/i18n/report_py3o.pot
  58. 2
      report_py3o/i18n/ro.po
  59. 2
      report_py3o/i18n/ru.po
  60. 2
      report_py3o/i18n/sk.po
  61. 2
      report_py3o/i18n/sl.po
  62. 2
      report_py3o/i18n/sr.po
  63. 2
      report_py3o/i18n/sr@latin.po
  64. 2
      report_py3o/i18n/sv.po
  65. 2
      report_py3o/i18n/th.po
  66. 2
      report_py3o/i18n/tr.po
  67. 2
      report_py3o/i18n/tr_TR.po
  68. 2
      report_py3o/i18n/uk.po
  69. 2
      report_py3o/i18n/vi.po
  70. 2
      report_py3o/i18n/vi_VN.po
  71. 2
      report_py3o/i18n/zh_CN.po
  72. 2
      report_py3o/i18n/zh_TW.po
  73. 1
      report_py3o/migrations/10.0.2.0.0/pre-migration.py
  74. 3
      report_py3o/models/__init__.py
  75. 57
      report_py3o/models/ir_actions_report.py
  76. 118
      report_py3o/models/py3o_report.py
  77. 2
      report_py3o/models/py3o_template.py
  78. 25
      report_py3o/models/report.py
  79. 43
      report_py3o/static/src/js/py3oactionmanager.js
  80. 25
      report_py3o/tests/test_report_py3o.py
  81. 4
      report_py3o/views/ir_actions_report.xml
  82. 2
      report_py3o/views/menu.xml

7
report_py3o/__manifest__.py

@ -1,18 +1,17 @@
# -*- coding: utf-8 -*-
# Copyright 2013 XCG Consulting (http://odoo.consulting) # Copyright 2013 XCG Consulting (http://odoo.consulting)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{ {
'name': 'Py3o Report Engine', 'name': 'Py3o Report Engine',
'summary': 'Reporting engine based on Libreoffice (ODT -> ODT, ' 'summary': 'Reporting engine based on Libreoffice (ODT -> ODT, '
'ODT -> PDF, ODT -> DOC, ODT -> DOCX, ODS -> ODS, etc.)', 'ODT -> PDF, ODT -> DOC, ODT -> DOCX, ODS -> ODS, etc.)',
'version': '10.0.2.0.2',
'version': '12.0.2.0.2',
'category': 'Reporting', 'category': 'Reporting',
'license': 'AGPL-3', 'license': 'AGPL-3',
'author': 'XCG Consulting,' 'author': 'XCG Consulting,'
'ACSONE SA/NV,' 'ACSONE SA/NV,'
'Odoo Community Association (OCA)', 'Odoo Community Association (OCA)',
'website': 'http://odoo.consulting/', 'website': 'http://odoo.consulting/',
'depends': ['report'],
'depends': ['web'],
'external_dependencies': { 'external_dependencies': {
'python': ['py3o.template', 'python': ['py3o.template',
'py3o.formats'] 'py3o.formats']
@ -21,7 +20,7 @@
'security/ir.model.access.csv', 'security/ir.model.access.csv',
'views/menu.xml', 'views/menu.xml',
'views/py3o_template.xml', 'views/py3o_template.xml',
'views/ir_report.xml',
'views/ir_actions_report.xml',
'views/report_py3o.xml', 'views/report_py3o.xml',
'demo/report_py3o.xml', 'demo/report_py3o.xml',
], ],

21
report_py3o/controllers/main.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright 2017 ACSONE SA/NV # Copyright 2017 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
import json import json
@ -7,7 +6,7 @@ from werkzeug import exceptions, url_decode
from odoo.http import route, request from odoo.http import route, request
from odoo.addons.report.controllers import main
from odoo.addons.web.controllers import main
from odoo.addons.web.controllers.main import ( from odoo.addons.web.controllers.main import (
_serialize_exception, _serialize_exception,
content_disposition content_disposition
@ -38,20 +37,18 @@ class ReportController(main.ReportController):
del data['context']['lang'] del data['context']['lang']
context.update(data['context']) context.update(data['context'])
ir_action = request.env['ir.actions.report.xml']
ir_action = request.env['ir.actions.report']
action_py3o_report = ir_action.get_from_report_name( action_py3o_report = ir_action.get_from_report_name(
reportname, "py3o").with_context(context) reportname, "py3o").with_context(context)
if not action_py3o_report: if not action_py3o_report:
raise exceptions.HTTPException( raise exceptions.HTTPException(
description='Py3o action report not found for report_name ' description='Py3o action report not found for report_name '
'%s' % reportname) '%s' % reportname)
context['report_name'] = reportname
py3o_report = request.env['py3o.report'].create({
'ir_actions_report_xml_id': action_py3o_report.id
}).with_context(context)
res, filetype = py3o_report.create_report(docids, data)
res, filetype = action_py3o_report._render_py3o(docids, data)
filename = action_py3o_report.gen_report_download_filename( filename = action_py3o_report.gen_report_download_filename(
docids, data) docids, data)
if not filename.endswith(filetype):
filename = "{}.{}".format(filename, filetype)
content_type = mimetypes.guess_type("x." + filetype)[0] content_type = mimetypes.guess_type("x." + filetype)[0]
http_headers = [('Content-Type', content_type), http_headers = [('Content-Type', content_type),
('Content-Length', len(res)), ('Content-Length', len(res)),
@ -69,8 +66,8 @@ class ReportController(main.ReportController):
:returns: Response with a filetoken cookie and an attachment header :returns: Response with a filetoken cookie and an attachment header
""" """
requestcontent = json.loads(data) requestcontent = json.loads(data)
url, type = requestcontent[0], requestcontent[1]
if type != 'py3o':
url, report_type = requestcontent[0], requestcontent[1]
if 'py3o' not in report_type:
return super(ReportController, self).report_download(data, token) return super(ReportController, self).report_download(data, token)
try: try:
reportname = url.split('/report/py3o/')[1].split('?')[0] reportname = url.split('/report/py3o/')[1].split('?')[0]
@ -85,12 +82,12 @@ class ReportController(main.ReportController):
else: else:
# Particular report: # Particular report:
# decoding the args represented in JSON # decoding the args represented in JSON
data = url_decode(url.split('?')[1]).items()
data = list(url_decode(url.split('?')[1]).items())
response = self.report_routes( response = self.report_routes(
reportname, converter='py3o', **dict(data)) reportname, converter='py3o', **dict(data))
response.set_cookie('fileToken', token) response.set_cookie('fileToken', token)
return response return response
except Exception, e:
except Exception as e:
se = _serialize_exception(e) se = _serialize_exception(e)
error = { error = {
'code': 200, 'code': 200,

16
report_py3o/demo/report_py3o.xml

@ -4,23 +4,17 @@
<odoo> <odoo>
<record id="res_users_report_py3o" model="ir.actions.report.xml">
<record id="res_users_report_py3o" model="ir.actions.report">
<field name="name">Py3o Demo Report</field> <field name="name">Py3o Demo Report</field>
<field name="type">ir.actions.report.xml</field>
<field name="type">ir.actions.report</field>
<field name="model">res.users</field> <field name="model">res.users</field>
<field name="report_name">py3o_user_info</field> <field name="report_name">py3o_user_info</field>
<field name="report_type">py3o</field> <field name="report_type">py3o</field>
<field name="py3o_filetype">odt</field> <field name="py3o_filetype">odt</field>
<field name="module">report_py3o</field> <field name="module">report_py3o</field>
<field name="py3o_template_fallback">demo/res_user.odt</field> <field name="py3o_template_fallback">demo/res_user.odt</field>
<field name="binding_model_id" ref="base.model_res_users" />
<field name="binding_type">report</field>
</record> </record>
<record id="res_users_report_py3o_print_action" model="ir.values">
<field eval="'action'" name="key" />
<field eval="'client_print_multi'" name="key2" />
<field name="model">res.users</field>
<field name="name">Py3o Demo Report</field>
<field eval="'ir.actions.report.xml,'+str(res_users_report_py3o)" name="value" />
</record>
</odoo>
</odoo>

2
report_py3o/i18n/am.po

@ -85,7 +85,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/ar.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/bg.po

@ -85,7 +85,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/bs.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/ca.po

@ -85,7 +85,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/cs.po

@ -85,7 +85,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/da.po

@ -85,7 +85,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/de.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/el_GR.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/en_GB.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/es.po

@ -89,7 +89,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "Ir a los informes de acciones xml id" msgstr "Ir a los informes de acciones xml id"

2
report_py3o/i18n/es_AR.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/es_CL.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/es_CO.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/es_CR.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/es_DO.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/es_EC.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/es_ES.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/es_MX.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/es_PE.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/es_PY.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/es_VE.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/et.po

@ -85,7 +85,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/eu.po

@ -85,7 +85,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/fa.po

@ -85,7 +85,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/fi.po

@ -85,7 +85,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/fr.po

@ -94,7 +94,7 @@ msgstr ""
"rapport pour les enregistrements sélectionnés." "rapport pour les enregistrements sélectionnés."
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "Ir actions report xml id" msgstr "Ir actions report xml id"

2
report_py3o/i18n/fr_CA.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/fr_CH.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/gl.po

@ -85,7 +85,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/gl_ES.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/he.po

@ -85,7 +85,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/hr.po

@ -87,7 +87,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/hr_HR.po

@ -88,7 +88,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/hu.po

@ -85,7 +85,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/id.po

@ -85,7 +85,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/it.po

@ -85,7 +85,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/ja.po

@ -85,7 +85,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/ko.po

@ -85,7 +85,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/lt.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/lt_LT.po

@ -87,7 +87,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/lv.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/mk.po

@ -85,7 +85,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/mn.po

@ -85,7 +85,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/nb.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/nb_NO.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/nl.po

@ -85,7 +85,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/nl_BE.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/nl_NL.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/pl.po

@ -87,7 +87,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/pt.po

@ -85,7 +85,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/pt_BR.po

@ -87,7 +87,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/pt_PT.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/report_py3o.pot

@ -75,7 +75,7 @@ msgid "If you execute a report on several records, by default Odoo will generate
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/ro.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/ru.po

@ -87,7 +87,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/sk.po

@ -85,7 +85,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/sl.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/sr.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/sr@latin.po

@ -87,7 +87,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/sv.po

@ -85,7 +85,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/th.po

@ -85,7 +85,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/tr.po

@ -85,7 +85,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/tr_TR.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/uk.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/vi.po

@ -85,7 +85,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/vi_VN.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/zh_CN.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

2
report_py3o/i18n/zh_TW.po

@ -86,7 +86,7 @@ msgid ""
msgstr "" msgstr ""
#. module: report_py3o #. module: report_py3o
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_xml_id
#: model:ir.model.fields,field_description:report_py3o.field_py3o_report_ir_actions_report_id
msgid "Ir actions report xml id" msgid "Ir actions report xml id"
msgstr "" msgstr ""

1
report_py3o/migrations/10.0.2.0.0/pre-migration.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# © 2018 Therp BV <http://therp.nl> # © 2018 Therp BV <http://therp.nl>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

3
report_py3o/models/__init__.py

@ -1,4 +1,3 @@
from . import ir_actions_report_xml
from . import py3o_template from . import py3o_template
from . import report
from . import ir_actions_report
from . import py3o_report from . import py3o_report

57
report_py3o/models/ir_actions_report_xml.py → report_py3o/models/ir_actions_report.py

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright 2013 XCG Consulting (http://odoo.consulting) # Copyright 2013 XCG Consulting (http://odoo.consulting)
# Copyright 2018 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import logging import logging
import time import time
@ -15,13 +15,13 @@ except ImportError:
logger.debug('Cannot import py3o.formats') logger.debug('Cannot import py3o.formats')
class IrActionsReportXml(models.Model):
""" Inherit from ir.actions.report.xml to allow customizing the template
class IrActionsReport(models.Model):
""" Inherit from ir.actions.report to allow customizing the template
file. The user cam chose a template from a list. file. The user cam chose a template from a list.
The list is configurable in the configuration tab, see py3o_template.py The list is configurable in the configuration tab, see py3o_template.py
""" """
_inherit = 'ir.actions.report.xml'
_inherit = 'ir.actions.report'
@api.multi @api.multi
@api.constrains("py3o_filetype", "report_type") @api.constrains("py3o_filetype", "report_type")
@ -43,6 +43,9 @@ class IrActionsReportXml(models.Model):
selections.append((name, description)) selections.append((name, description))
return selections return selections
report_type = fields.Selection(
selection_add=[("py3o", "py3o")]
)
py3o_filetype = fields.Selection( py3o_filetype = fields.Selection(
selection="_get_py3o_filetypes", selection="_get_py3o_filetypes",
string="Output Format") string="Output Format")
@ -78,11 +81,20 @@ class IrActionsReportXml(models.Model):
def render_report(self, res_ids, name, data): def render_report(self, res_ids, name, data):
action_py3o_report = self.get_from_report_name(name, "py3o") action_py3o_report = self.get_from_report_name(name, "py3o")
if action_py3o_report: if action_py3o_report:
return action_py3o_report._render_py3o(res_ids, data)
return super(IrActionsReport, self).render_report(
res_ids, name, data)
@api.multi
def _render_py3o(self, res_ids, data):
self.ensure_one()
if self.report_type != "py3o":
raise RuntimeError(
"py3o rendition is only available on py3o report.\n"
"(current: '{}', expected 'py3o'".format(self.report_type))
return self.env['py3o.report'].create({ return self.env['py3o.report'].create({
'ir_actions_report_xml_id': action_py3o_report.id
'ir_actions_report_id': self.id
}).create_report(res_ids, data) }).create_report(res_ids, data)
return super(IrActionsReportXml, self).render_report(
res_ids, name, data)
@api.multi @api.multi
def gen_report_download_filename(self, res_ids, data): def gen_report_download_filename(self, res_ids, data):
@ -95,3 +107,34 @@ class IrActionsReportXml(models.Model):
return safe_eval(report.print_report_name, return safe_eval(report.print_report_name,
{'object': obj, 'time': time}) {'object': obj, 'time': time})
return "%s.%s" % (self.name, self.py3o_filetype) return "%s.%s" % (self.name, self.py3o_filetype)
@api.model
def _get_report_from_name(self, report_name):
"""Get the first record of ir.actions.report having the
``report_name`` as value for the field report_name.
"""
res = super(IrActionsReport, self)._get_report_from_name(report_name)
if res:
return res
# maybe a py3o report
context = self.env['res.users'].context_get()
return self.with_context(context).search(
[('report_type', '=', 'py3o'),
('report_name', '=', report_name)], limit=1)
@api.multi
def _get_attachments(self, res_ids):
""" Return the report already generated for the given res_ids
"""
self.ensure_one()
save_in_attachment = {}
if res_ids:
# Dispatch the records by ones having an attachment
Model = self.env[self.model]
record_ids = Model.browse(res_ids)
if self.attachment:
for record_id in record_ids:
attachment_id = self.retrieve_attachment(record_id)
if attachment_id:
save_in_attachment[record_id.id] = attachment_id
return save_in_attachment

118
report_py3o/models/py3o_report.py

@ -1,10 +1,9 @@
# -*- coding: utf-8 -*-
# Copyright 2013 XCG Consulting (http://odoo.consulting) # Copyright 2013 XCG Consulting (http://odoo.consulting)
# Copyright 2016 ACSONE SA/NV # Copyright 2016 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
import base64 import base64
from base64 import b64decode from base64 import b64decode
from cStringIO import StringIO
from io import BytesIO
import logging import logging
import os import os
import cgi import cgi
@ -16,8 +15,6 @@ import sys
import tempfile import tempfile
from zipfile import ZipFile, ZIP_DEFLATED from zipfile import ZipFile, ZIP_DEFLATED
from odoo.exceptions import AccessError
from odoo.report.report_sxw import rml_parse
from odoo import api, fields, models, tools, _ from odoo import api, fields, models, tools, _
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -71,7 +68,7 @@ def format_multiline_value(value):
@py3o_report_extender() @py3o_report_extender()
def defautl_extend(report_xml, localcontext):
def default_extend(report_xml, localcontext):
# add the base64decode function to be able do decode binary fields into # add the base64decode function to be able do decode binary fields into
# the template # the template
localcontext['b64decode'] = b64decode localcontext['b64decode'] = b64decode
@ -82,11 +79,10 @@ def defautl_extend(report_xml, localcontext):
class Py3oReport(models.TransientModel): class Py3oReport(models.TransientModel):
_name = "py3o.report" _name = "py3o.report"
_inherit = 'report'
_description = "Report Py30" _description = "Report Py30"
ir_actions_report_xml_id = fields.Many2one(
comodel_name="ir.actions.report.xml",
ir_actions_report_id = fields.Many2one(
comodel_name="ir.actions.report",
required=True required=True
) )
@ -134,7 +130,7 @@ class Py3oReport(models.TransientModel):
""" """
if not tmpl_name: if not tmpl_name:
return None return None
report_xml = self.ir_actions_report_xml_id
report_xml = self.ir_actions_report_id
flbk_filename = None flbk_filename = None
if report_xml.module: if report_xml.module:
# if the default is defined # if the default is defined
@ -145,7 +141,7 @@ class Py3oReport(models.TransientModel):
elif self._is_valid_template_path(tmpl_name): elif self._is_valid_template_path(tmpl_name):
flbk_filename = os.path.realpath(tmpl_name) flbk_filename = os.path.realpath(tmpl_name)
if self._is_valid_template_filename(flbk_filename): if self._is_valid_template_filename(flbk_filename):
with open(flbk_filename, 'r') as tmpl:
with open(flbk_filename, 'rb') as tmpl:
return tmpl.read() return tmpl.read()
return None return None
@ -156,7 +152,7 @@ class Py3oReport(models.TransientModel):
:return: :return:
""" """
self.ensure_one() self.ensure_one()
report_xml = self.ir_actions_report_xml_id
report_xml = self.ir_actions_report_id
return self._get_template_from_path(report_xml.py3o_template_fallback) return self._get_template_from_path(report_xml.py3o_template_fallback)
@api.multi @api.multi
@ -174,7 +170,7 @@ class Py3oReport(models.TransientModel):
odoo.exceptions.DeferredException odoo.exceptions.DeferredException
""" """
self.ensure_one() self.ensure_one()
report_xml = self.ir_actions_report_xml_id
report_xml = self.ir_actions_report_id
if report_xml.py3o_template_id.py3o_template_data: if report_xml.py3o_template_id.py3o_template_data:
# if a user gave a report template # if a user gave a report template
tmpl_data = b64decode( tmpl_data = b64decode(
@ -187,7 +183,7 @@ class Py3oReport(models.TransientModel):
if tmpl_data is None: if tmpl_data is None:
# if for any reason the template is not found # if for any reason the template is not found
raise TemplateNotFound( raise TemplateNotFound(
_(u'No template found. Aborting.'),
_('No template found. Aborting.'),
sys.exc_info(), sys.exc_info(),
) )
@ -197,47 +193,35 @@ class Py3oReport(models.TransientModel):
def _extend_parser_context(self, context_instance, report_xml): def _extend_parser_context(self, context_instance, report_xml):
# add default extenders # add default extenders
for fct in _extender_functions.get(None, []): for fct in _extender_functions.get(None, []):
fct(report_xml, context_instance.localcontext)
fct(report_xml, context_instance)
# add extenders for registered on the template # add extenders for registered on the template
xml_id = report_xml.get_external_id().get(report_xml.id) xml_id = report_xml.get_external_id().get(report_xml.id)
if xml_id in _extender_functions: if xml_id in _extender_functions:
for fct in _extender_functions[xml_id]: for fct in _extender_functions[xml_id]:
fct(report_xml, context_instance.localcontext)
fct(report_xml, context_instance)
@api.multi @api.multi
def _get_parser_context(self, model_instance, data): def _get_parser_context(self, model_instance, data):
report_xml = self.ir_actions_report_xml_id
context_instance = rml_parse(self.env.cr, self.env.uid,
report_xml.name,
context=self.env.context)
context_instance.set_context(model_instance, data, model_instance.ids,
report_xml.report_type)
self._extend_parser_context(context_instance, report_xml)
return context_instance.localcontext
report_xml = self.ir_actions_report_id
context = report_xml._get_rendering_context(model_instance.ids, data)
context['objects'] = model_instance
self._extend_parser_context(context, report_xml)
return context
@api.model
def _postprocess_report(self, report_path, res_id, save_in_attachment):
if save_in_attachment.get(res_id):
with open(report_path, 'rb') as pdfreport:
attachment = {
'name': save_in_attachment.get(res_id),
'datas': base64.encodestring(pdfreport.read()),
'datas_fname': save_in_attachment.get(res_id),
'res_model': save_in_attachment.get('model'),
'res_id': res_id,
}
try:
self.env['ir.attachment'].create(attachment)
except AccessError:
logger.info("Cannot save PDF report %r as attachment",
attachment['name'])
else:
logger.info(
'The PDF document %s is now saved in the database',
attachment['name'])
@api.multi
def _postprocess_report(self, model_instance, result_path):
if len(model_instance) == 1 and self.ir_actions_report_id.attachment:
with open(result_path, 'rb') as f:
# we do all the generation process using files to avoid memory
# consumption...
# ... but odoo wants the whole data in memory anyways :)
buffer = BytesIO(f.read())
self.ir_actions_report_id.postprocess_pdf_report(
model_instance, buffer)
return result_path
@api.multi @api.multi
def _create_single_report(self, model_instance, data, save_in_attachment):
def _create_single_report(self, model_instance, data):
""" This function to generate our py3o report """ This function to generate our py3o report
""" """
self.ensure_one() self.ensure_one()
@ -245,8 +229,8 @@ class Py3oReport(models.TransientModel):
suffix='.ods', prefix='p3o.report.tmp.') suffix='.ods', prefix='p3o.report.tmp.')
tmpl_data = self.get_template(model_instance) tmpl_data = self.get_template(model_instance)
in_stream = StringIO(tmpl_data)
with closing(os.fdopen(result_fd, 'w+')) as out_stream:
in_stream = BytesIO(tmpl_data)
with closing(os.fdopen(result_fd, 'wb+')) as out_stream:
template = Template(in_stream, out_stream, escape_false=True) template = Template(in_stream, out_stream, escape_false=True)
localcontext = self._get_parser_context(model_instance, data) localcontext = self._get_parser_context(model_instance, data)
template.render(localcontext) template.render(localcontext)
@ -260,16 +244,12 @@ class Py3oReport(models.TransientModel):
result_path, model_instance, data result_path, model_instance, data
) )
if len(model_instance) == 1:
self._postprocess_report(
result_path, model_instance.id, save_in_attachment)
return result_path
return self._postprocess_report(model_instance, result_path)
@api.multi @api.multi
def _convert_single_report(self, result_path, model_instance, data): def _convert_single_report(self, result_path, model_instance, data):
"""Run a command to convert to our target format""" """Run a command to convert to our target format"""
filetype = self.ir_actions_report_xml_id.py3o_filetype
filetype = self.ir_actions_report_id.py3o_filetype
if not Formats().get_format(filetype).native: if not Formats().get_format(filetype).native:
command = self._convert_single_report_cmd( command = self._convert_single_report_cmd(
result_path, model_instance, data, result_path, model_instance, data,
@ -297,30 +277,30 @@ class Py3oReport(models.TransientModel):
), ),
'--headless', '--headless',
'--convert-to', '--convert-to',
self.ir_actions_report_xml_id.py3o_filetype,
self.ir_actions_report_id.py3o_filetype,
result_path, result_path,
] ]
@api.multi @api.multi
def _get_or_create_single_report(self, model_instance, data, def _get_or_create_single_report(self, model_instance, data,
save_in_attachment):
existing_reports_attachment):
self.ensure_one() self.ensure_one()
if save_in_attachment and save_in_attachment[
'loaded_documents'].get(model_instance.id):
d = save_in_attachment[
'loaded_documents'].get(model_instance.id)
attachment = existing_reports_attachment.get(
model_instance.id)
if attachment and self.ir_actions_report_id.attachment_use:
content = base64.decodestring(attachment.datas)
report_file = tempfile.mktemp( report_file = tempfile.mktemp(
"." + self.ir_actions_report_xml_id.py3o_filetype)
"." + self.ir_actions_report_id.py3o_filetype)
with open(report_file, "wb") as f: with open(report_file, "wb") as f:
f.write(d)
f.write(content)
return report_file return report_file
return self._create_single_report( return self._create_single_report(
model_instance, data, save_in_attachment)
model_instance, data)
@api.multi @api.multi
def _zip_results(self, reports_path): def _zip_results(self, reports_path):
self.ensure_one() self.ensure_one()
zfname_prefix = self.ir_actions_report_xml_id.name
zfname_prefix = self.ir_actions_report_id.name
result_path = tempfile.mktemp(suffix="zip", prefix='py3o-zip-result') result_path = tempfile.mktemp(suffix="zip", prefix='py3o-zip-result')
with ZipFile(result_path, 'w', ZIP_DEFLATED) as zf: with ZipFile(result_path, 'w', ZIP_DEFLATED) as zf:
cpt = 0 cpt = 0
@ -335,7 +315,7 @@ class Py3oReport(models.TransientModel):
@api.multi @api.multi
def _merge_results(self, reports_path): def _merge_results(self, reports_path):
self.ensure_one() self.ensure_one()
filetype = self.ir_actions_report_xml_id.py3o_filetype
filetype = self.ir_actions_report_id.py3o_filetype
if not reports_path: if not reports_path:
return False, False return False, False
if len(reports_path) == 1: if len(reports_path) == 1:
@ -359,22 +339,22 @@ class Py3oReport(models.TransientModel):
def create_report(self, res_ids, data): def create_report(self, res_ids, data):
""" Override this function to handle our py3o report """ Override this function to handle our py3o report
""" """
model_instances = self.env[self.ir_actions_report_xml_id.model].browse(
model_instances = self.env[self.ir_actions_report_id.model].browse(
res_ids) res_ids)
save_in_attachment = self._check_attachment_use(
res_ids, self.ir_actions_report_xml_id) or {}
reports_path = [] reports_path = []
if ( if (
len(res_ids) > 1 and len(res_ids) > 1 and
self.ir_actions_report_xml_id.py3o_multi_in_one):
self.ir_actions_report_id.py3o_multi_in_one):
reports_path.append( reports_path.append(
self._create_single_report( self._create_single_report(
model_instances, data, save_in_attachment))
model_instances, data))
else: else:
existing_reports_attachment = \
self.ir_actions_report_id._get_attachments(res_ids)
for model_instance in model_instances: for model_instance in model_instances:
reports_path.append( reports_path.append(
self._get_or_create_single_report( self._get_or_create_single_report(
model_instance, data, save_in_attachment))
model_instance, data, existing_reports_attachment))
result_path, filetype = self._merge_results(reports_path) result_path, filetype = self._merge_results(reports_path)
reports_path.append(result_path) reports_path.append(result_path)

2
report_py3o/models/py3o_template.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright 2013 XCG Consulting (http://odoo.consulting) # Copyright 2013 XCG Consulting (http://odoo.consulting)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import fields, models from odoo import fields, models
@ -6,6 +5,7 @@ from odoo import fields, models
class Py3oTemplate(models.Model): class Py3oTemplate(models.Model):
_name = 'py3o.template' _name = 'py3o.template'
_description = 'Py3o template'
name = fields.Char(required=True) name = fields.Char(required=True)
py3o_template_data = fields.Binary("LibreOffice Template") py3o_template_data = fields.Binary("LibreOffice Template")

25
report_py3o/models/report.py

@ -1,25 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2017 Akretion (http://www.akretion.com/)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, models
class Report(models.Model):
_inherit = 'report'
@api.model
def _get_report_from_name(self, report_name):
"""Get the first record of ir.actions.report.xml having the
``report_name`` as value for the field report_name.
"""
res = super(Report, self)._get_report_from_name(report_name)
if res:
return res
# maybe a py3o report
report_obj = self.env['ir.actions.report.xml']
context = self.env['res.users'].context_get()
return report_obj.with_context(context).search(
[('report_type', '=', 'py3o'),
('report_name', '=', report_name)], limit=1)

43
report_py3o/static/src/js/py3oactionmanager.js

@ -25,34 +25,33 @@ var trigger_download = function(session, response, c, action, options) {
}; };
ActionManager.include({ ActionManager.include({
ir_actions_report_xml: function(action, options) {
var self = this;
_executeReportAction: function (action, options) {
// Py3o reports // Py3o reports
if ('report_type' in action && action.report_type == 'py3o' ) {
framework.blockUI();
action = _.clone(action);
_t = core._t;
var report_url = '/report/py3o/' + action.report_name;;
// generic report: no query string
// particular: query string of action.data.form and context
if (!('data' in action) || !(action.data)) {
if ('active_ids' in action.context) {
report_url += "/" + action.context.active_ids.join(',');
}
if ('report_type' in action && action.report_type === 'py3o' ) {
return this._triggerDownload(action, options, 'py3o');
} else { } else {
report_url += "&options=" + encodeURIComponent(JSON.stringify(action.data));
report_url += "&context=" + encodeURIComponent(JSON.stringify(action.context));
return this._super.apply(this, arguments);
} }
},
var response = new Array();
response[0] = report_url;
response[1] = action.report_type;
var c = crash_manager;
return trigger_download(self.session, response, c, action, options);
_makeReportUrls: function(action) {
var reportUrls = this._super.apply(this, arguments);
reportUrls.py3o = '/report/py3o/' + action.report_name;
// We may have to build a query string with `action.data`. It's the place
// were report's using a wizard to customize the output traditionally put
// their options.
if (_.isUndefined(action.data) || _.isNull(action.data) ||
(_.isObject(action.data) && _.isEmpty(action.data))) {
if (action.context.active_ids) {
var activeIDsPath = '/' + action.context.active_ids.join(',');
reportUrls.py3o += activeIDsPath;;
}
} else { } else {
return self._super(action, options);
var serializedOptionsPath = '?options=' + encodeURIComponent(JSON.stringify(action.data));
serializedOptionsPath += '&context=' + encodeURIComponent(JSON.stringify(action.context));
reportUrls.py3o += serializedOptionsPath;
} }
return reportUrls;
} }
}); });

25
report_py3o/tests/test_report_py3o.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright 2016 ACSONE SA/NV # Copyright 2016 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).).
@ -14,6 +13,7 @@ from contextlib import contextmanager
from odoo import tools from odoo import tools
from odoo.tests.common import TransactionCase from odoo.tests.common import TransactionCase
from odoo.exceptions import ValidationError from odoo.exceptions import ValidationError
from odoo.addons.base.tests.test_mimetypes import PNG
from ..models.py3o_report import TemplateNotFound, format_multiline_value from ..models.py3o_report import TemplateNotFound, format_multiline_value
from base64 import b64encode from base64 import b64encode
@ -42,9 +42,10 @@ class TestReportPy3o(TransactionCase):
def setUp(self): def setUp(self):
super(TestReportPy3o, self).setUp() super(TestReportPy3o, self).setUp()
self.env.user.image = PNG
self.report = self.env.ref("report_py3o.res_users_report_py3o") self.report = self.env.ref("report_py3o.res_users_report_py3o")
self.py3o_report = self.env['py3o.report'].create({ self.py3o_report = self.env['py3o.report'].create({
'ir_actions_report_xml_id': self.report.id})
'ir_actions_report_id': self.report.id})
def test_required_py3_filetype(self): def test_required_py3_filetype(self):
self.assertEqual(self.report.report_type, "py3o") self.assertEqual(self.report.report_type, "py3o")
@ -56,15 +57,17 @@ class TestReportPy3o(TransactionCase):
def _render_patched(self, result_text='test result', call_count=1): def _render_patched(self, result_text='test result', call_count=1):
py3o_report = self.env['py3o.report'] py3o_report = self.env['py3o.report']
py3o_report_obj = py3o_report.create({
"ir_actions_report_id": self.report.id
})
with mock.patch.object( with mock.patch.object(
py3o_report.__class__, '_create_single_report') as patched_pdf: py3o_report.__class__, '_create_single_report') as patched_pdf:
result = tempfile.mktemp('.txt') result = tempfile.mktemp('.txt')
with open(result, 'w') as fp: with open(result, 'w') as fp:
fp.write(result_text) fp.write(result_text)
patched_pdf.return_value = result
patched_pdf.side_effect = lambda record, data, save_attachments:\
py3o_report._postprocess_report(
result, record.id, save_attachments,
patched_pdf.side_effect = lambda record, data:\
py3o_report_obj._postprocess_report(
record, result
) or result ) or result
# test the call the the create method inside our custom parser # test the call the the create method inside our custom parser
self.report.render_report(self.env.user.ids, self.report.render_report(self.env.user.ids,
@ -92,14 +95,14 @@ class TestReportPy3o(TransactionCase):
created_attachement = new_attachments - attachments created_attachement = new_attachments - attachments
self.assertEqual(1, len(created_attachement)) self.assertEqual(1, len(created_attachement))
content = b64decode(created_attachement.datas) content = b64decode(created_attachement.datas)
self.assertEqual("test result", content)
self.assertEqual(b"test result", content)
# put a new content into tha attachement and check that the next # put a new content into tha attachement and check that the next
# time we ask the report we received the saved attachment not a newly # time we ask the report we received the saved attachment not a newly
# generated document # generated document
created_attachement.datas = base64.encodestring("new content")
created_attachement.datas = base64.encodestring(b"new content")
res = self.report.render_report( res = self.report.render_report(
self.env.user.ids, self.report.report_name, {}) self.env.user.ids, self.report.report_name, {})
self.assertEqual(('new content', self.report.py3o_filetype), res)
self.assertEqual((b'new content', self.report.py3o_filetype), res)
def test_report_post_process(self): def test_report_post_process(self):
""" """
@ -115,7 +118,7 @@ class TestReportPy3o(TransactionCase):
self.assertEqual(self.env.user.name + '.txt', attachements.name) self.assertEqual(self.env.user.name + '.txt', attachements.name)
self.assertEqual(self.env.user._name, attachements.res_model) self.assertEqual(self.env.user._name, attachements.res_model)
self.assertEqual(self.env.user.id, attachements.res_id) self.assertEqual(self.env.user.id, attachements.res_id)
self.assertEqual('test result', b64decode(attachements.datas))
self.assertEqual(b'test result', b64decode(attachements.datas))
@tools.misc.mute_logger('odoo.addons.report_py3o.models.py3o_report') @tools.misc.mute_logger('odoo.addons.report_py3o.models.py3o_report')
def test_report_template_configs(self): def test_report_template_configs(self):
@ -152,7 +155,7 @@ class TestReportPy3o(TransactionCase):
# the tempalte can also be provided as a binary field # the tempalte can also be provided as a binary field
self.report.py3o_template_fallback = False self.report.py3o_template_fallback = False
with open(flbk_filename) as tmpl_file:
with open(flbk_filename, 'rb') as tmpl_file:
tmpl_data = b64encode(tmpl_file.read()) tmpl_data = b64encode(tmpl_file.read())
py3o_template = self.env['py3o.template'].create({ py3o_template = self.env['py3o.template'].create({
'name': 'test_template', 'name': 'test_template',

4
report_py3o/views/ir_report.xml → report_py3o/views/ir_actions_report.xml

@ -5,7 +5,7 @@
<record id="py3o_report_view" model="ir.ui.view"> <record id="py3o_report_view" model="ir.ui.view">
<field name="name">py3o_report_view</field> <field name="name">py3o_report_view</field>
<field name="model">ir.actions.report.xml</field>
<field name="model">ir.actions.report</field>
<field name="inherit_id" ref="base.act_report_xml_view" /> <field name="inherit_id" ref="base.act_report_xml_view" />
<field name="arch" type="xml"> <field name="arch" type="xml">
@ -29,7 +29,7 @@
<record id="act_report_xml_search_view" model="ir.ui.view"> <record id="act_report_xml_search_view" model="ir.ui.view">
<field name="name">py3o_report_search_view</field> <field name="name">py3o_report_search_view</field>
<field name="model">ir.actions.report.xml</field>
<field name="model">ir.actions.report</field>
<field name="inherit_id" ref="base.act_report_xml_search_view"/> <field name="inherit_id" ref="base.act_report_xml_search_view"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<field name="model" position="after"> <field name="model" position="after">

2
report_py3o/views/menu.xml

@ -3,6 +3,6 @@
<menuitem id="py3o_config_menu" <menuitem id="py3o_config_menu"
name="Py3o" name="Py3o"
parent="report.reporting_menuitem" />
parent="base.reporting_menuitem" />
</odoo> </odoo>
Loading…
Cancel
Save