Browse Source

[MIG] report_py3o, report_py3o_fusion_server: Migration to 13.0

pull/347/head
Laurent Mignon (ACSONE) 5 years ago
parent
commit
f584d505a0
  1. 2
      .isort.cfg
  2. 1
      .travis.yml
  3. 2
      report_py3o/__manifest__.py
  4. BIN
      report_py3o/demo/res_user.odt
  5. 11
      report_py3o/migrations/10.0.2.0.0/pre-migration.py
  6. 7
      report_py3o/models/ir_actions_report.py
  7. 15
      report_py3o/models/py3o_report.py
  8. 55
      report_py3o/static/src/js/py3oactionmanager.js
  9. 6
      report_py3o/views/report_py3o.xml
  10. 2
      report_py3o_fusion_server/__manifest__.py
  11. 5
      report_py3o_fusion_server/models/ir_actions_report.py
  12. 6
      report_py3o_fusion_server/models/py3o_report.py
  13. 3
      requirements.txt

2
.isort.cfg

@ -9,4 +9,4 @@ line_length=88
known_odoo=odoo
known_odoo_addons=odoo.addons
sections=FUTURE,STDLIB,THIRDPARTY,ODOO,ODOO_ADDONS,FIRSTPARTY,LOCALFOLDER
known_third_party=PyPDF2,mock,openerp,pkg_resources,requests,werkzeug
known_third_party=PyPDF2,mock,pkg_resources,requests,werkzeug

1
.travis.yml

@ -12,6 +12,7 @@ addons:
apt:
packages:
- expect-dev # provides unbuffer utility
- libreoffice
stages:
- linting

2
report_py3o/__manifest__.py

@ -4,7 +4,7 @@
"name": "Py3o Report Engine",
"summary": "Reporting engine based on Libreoffice (ODT -> ODT, "
"ODT -> PDF, ODT -> DOC, ODT -> DOCX, ODS -> ODS, etc.)",
"version": "12.0.2.0.2",
"version": "13.0.1.0.0",
"category": "Reporting",
"license": "AGPL-3",
"author": "XCG Consulting," "ACSONE SA/NV," "Odoo Community Association (OCA)",

BIN
report_py3o/demo/res_user.odt

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

@ -1,11 +0,0 @@
# © 2018 Therp BV <http://therp.nl>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
def migrate(cr, version=None):
# when migrating from a pre-split version of the module, pull the fusion
# server module too to have no loss of features
cr.execute(
"update ir_module_module set state='to install' "
"where name='report_py3o_fusion_server' and state='uninstalled'"
)

7
report_py3o/models/ir_actions_report.py

@ -27,7 +27,6 @@ class IrActionsReport(models.Model):
_inherit = "ir.actions.report"
@api.multi
@api.constrains("py3o_filetype", "report_type")
def _check_py3o_filetype(self):
for report in self:
@ -114,7 +113,6 @@ class IrActionsReport(models.Model):
return lo_bin
@api.depends("report_type", "py3o_filetype")
@api.multi
def _compute_is_py3o_native_format(self):
fmt = Formats()
for rec in self:
@ -123,14 +121,12 @@ class IrActionsReport(models.Model):
filetype = rec.py3o_filetype
rec.is_py3o_native_format = fmt.get_format(filetype).native
@api.multi
def _compute_lo_bin_path(self):
lo_bin = self._get_lo_bin()
for rec in self:
rec.lo_bin_path = lo_bin
@api.depends("lo_bin_path", "is_py3o_native_format", "report_type")
@api.multi
def _compute_py3o_report_not_available(self):
for rec in self:
if not rec.report_type == "py3o":
@ -156,7 +152,6 @@ class IrActionsReport(models.Model):
[("report_name", "=", report_name), ("report_type", "=", report_type)]
)
@api.multi
def render_py3o(self, res_ids, data):
self.ensure_one()
if self.report_type != "py3o":
@ -170,7 +165,6 @@ class IrActionsReport(models.Model):
.create_report(res_ids, data)
)
@api.multi
def gen_report_download_filename(self, res_ids, data):
"""Override this function to change the name of the downloaded report
"""
@ -181,7 +175,6 @@ class IrActionsReport(models.Model):
return safe_eval(report.print_report_name, {"object": obj, "time": time})
return "{}.{}".format(self.name, self.py3o_filetype)
@api.multi
def _get_attachments(self, res_ids):
""" Return the report already generated for the given res_ids
"""

15
report_py3o/models/py3o_report.py

@ -77,7 +77,6 @@ class Py3oReport(models.TransientModel):
comodel_name="ir.actions.report", required=True
)
@api.multi
def _is_valid_template_path(self, path):
""" Check if the path is a trusted path for py3o templates.
"""
@ -100,7 +99,6 @@ class Py3oReport(models.TransientModel):
)
return is_valid
@api.multi
def _is_valid_template_filename(self, filename):
""" Check if the filename can be used as py3o template
"""
@ -116,7 +114,6 @@ class Py3oReport(models.TransientModel):
logger.warning("%s is not a valid Py3o template filename", filename)
return False
@api.multi
def _get_template_from_path(self, tmpl_name):
""" Return the template from the path to root of the module if specied
or an absolute path on your server
@ -137,7 +134,6 @@ class Py3oReport(models.TransientModel):
return tmpl.read()
return None
@api.multi
def _get_template_fallback(self, model_instance):
"""
Return the template referenced in the report definition
@ -147,7 +143,6 @@ class Py3oReport(models.TransientModel):
report_xml = self.ir_actions_report_id
return self._get_template_from_path(report_xml.py3o_template_fallback)
@api.multi
def get_template(self, model_instance):
"""private helper to fetch the template data either from the database
or from the default template file provided by the implementer.
@ -176,7 +171,6 @@ class Py3oReport(models.TransientModel):
return tmpl_data
@api.multi
def _extend_parser_context(self, context, report_xml):
# add default extenders
for fct in _extender_functions.get(None, []):
@ -187,7 +181,6 @@ class Py3oReport(models.TransientModel):
for fct in _extender_functions[xml_id]:
fct(report_xml, context)
@api.multi
def _get_parser_context(self, model_instance, data):
report_xml = self.ir_actions_report_id
context = Py3oParserContext(self.env).localcontext
@ -196,7 +189,6 @@ class Py3oReport(models.TransientModel):
self._extend_parser_context(context, report_xml)
return context
@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:
@ -207,7 +199,6 @@ class Py3oReport(models.TransientModel):
self.ir_actions_report_id.postprocess_pdf_report(model_instance, buffer)
return result_path
@api.multi
def _create_single_report(self, model_instance, data):
""" This function to generate our py3o report
"""
@ -232,7 +223,6 @@ class Py3oReport(models.TransientModel):
return self._postprocess_report(model_instance, result_path)
@api.multi
def _convert_single_report(self, result_path, model_instance, data):
"""Run a command to convert to our target format"""
if not self.ir_actions_report_id.is_py3o_native_format:
@ -252,7 +242,6 @@ class Py3oReport(models.TransientModel):
)
return result_path
@api.multi
def _convert_single_report_cmd(self, result_path, model_instance, data):
"""Return a command list suitable for use in subprocess.call"""
lo_bin = self.ir_actions_report_id.lo_bin_path
@ -271,7 +260,6 @@ class Py3oReport(models.TransientModel):
result_path,
]
@api.multi
def _get_or_create_single_report(
self, model_instance, data, existing_reports_attachment
):
@ -285,7 +273,6 @@ class Py3oReport(models.TransientModel):
return report_file
return self._create_single_report(model_instance, data)
@api.multi
def _zip_results(self, reports_path):
self.ensure_one()
zfname_prefix = self.ir_actions_report_id.name
@ -317,7 +304,6 @@ class Py3oReport(models.TransientModel):
writer.write(merged_file)
return merged_file_path
@api.multi
def _merge_results(self, reports_path):
self.ensure_one()
filetype = self.ir_actions_report_id.py3o_filetype
@ -339,7 +325,6 @@ class Py3oReport(models.TransientModel):
except (OSError, IOError):
logger.error("Error when trying to remove file %s" % temporary_file)
@api.multi
def create_report(self, res_ids, data):
""" Override this function to handle our py3o report
"""

55
report_py3o/static/src/js/py3oactionmanager.js

@ -1,38 +1,39 @@
/* Copyright 2017-2018 ACSONE SA/NV
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */
odoo.define('report_py3o.report', function (require) {
"use strict";
var ActionManager = require('web.ActionManager');
var ActionManager = require('web.ActionManager');
ActionManager.include({
_executeReportAction: function (action, options) {
ActionManager.include({
_executeReportAction: function (action, options) {
// Py3o reports
if ('report_type' in action && action.report_type === 'py3o' ) {
return this._triggerDownload(action, options, 'py3o');
} else {
if ('report_type' in action && action.report_type === 'py3o' ) {
return this._triggerDownload(action, options, 'py3o');
}
return this._super.apply(this, arguments);
}
},
_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;;
},
_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 {
var serializedOptionsPath = '?options=' + encodeURIComponent(JSON.stringify(action.data));
serializedOptionsPath += '&context=' + encodeURIComponent(JSON.stringify(action.context));
reportUrls.py3o += serializedOptionsPath;
}
} else {
var serializedOptionsPath = '?options=' + encodeURIComponent(JSON.stringify(action.data));
serializedOptionsPath += '&context=' + encodeURIComponent(JSON.stringify(action.context));
reportUrls.py3o += serializedOptionsPath;
}
return reportUrls;
}
});
return reportUrls;
},
});
});

6
report_py3o/views/report_py3o.xml

@ -1,10 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<odoo>
<template id="assets_backend" name="report assets" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script type="text/javascript" src="/report_py3o/static/src/js/py3oactionmanager.js"></script>
</xpath>
</template>
</data>
</openerp>
</odoo>

2
report_py3o_fusion_server/__manifest__.py

@ -3,7 +3,7 @@
{
"name": "Py3o Report Engine - Fusion server support",
"summary": "Let the fusion server handle format conversion.",
"version": "12.0.1.0.0",
"version": "13.0.1.0.0",
"category": "Reporting",
"license": "AGPL-3",
"author": "XCG Consulting," "ACSONE SA/NV," "Odoo Community Association (OCA)",

5
report_py3o_fusion_server/models/ir_actions_report.py

@ -3,8 +3,7 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging
from openerp import _, api, fields, models
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
logger = logging.getLogger(__name__)
@ -13,7 +12,6 @@ logger = logging.getLogger(__name__)
class IrActionsReport(models.Model):
_inherit = "ir.actions.report"
@api.multi
@api.constrains("py3o_is_local_fusion", "py3o_server_id")
def _check_py3o_server_id(self):
for report in self:
@ -46,7 +44,6 @@ class IrActionsReport(models.Model):
@api.depends(
"lo_bin_path", "is_py3o_native_format", "report_type", "py3o_server_id"
)
@api.multi
def _compute_py3o_report_not_available(self):
for rec in self:
if not rec.report_type == "py3o":

6
report_py3o_fusion_server/models/py3o_report.py

@ -11,8 +11,9 @@ from datetime import datetime
from io import BytesIO
import requests
from openerp import _, api, models
from openerp.exceptions import UserError
from odoo import _, models
from odoo.exceptions import UserError
logger = logging.getLogger(__name__)
@ -26,7 +27,6 @@ except ImportError:
class Py3oReport(models.TransientModel):
_inherit = "py3o.report"
@api.multi
def _create_single_report(self, model_instance, data):
""" This function to generate our py3o report
"""

3
requirements.txt

@ -0,0 +1,3 @@
py3o.template
py3o.formats
genshi>=0.7
Loading…
Cancel
Save