diff --git a/report_py3o_fusion_server/models/ir_actions_report.py b/report_py3o_fusion_server/models/ir_actions_report.py index f95a1b098..6c8927d85 100644 --- a/report_py3o_fusion_server/models/ir_actions_report.py +++ b/report_py3o_fusion_server/models/ir_actions_report.py @@ -7,26 +7,19 @@ from odoo.exceptions import ValidationError logger = logging.getLogger(__name__) -try: - from py3o.formats import Formats -except ImportError: - logger.debug('Cannot import py3o.formats') - class IrActionsReport(models.Model): _inherit = 'ir.actions.report' @api.multi - @api.constrains("py3o_is_local_fusion", "py3o_server_id", "py3o_filetype") + @api.constrains("py3o_is_local_fusion", "py3o_server_id") def _check_py3o_server_id(self): for report in self: if report.report_type != "py3o": continue - is_native = Formats().get_format(report.py3o_filetype).native - if ((not is_native or not report.py3o_is_local_fusion) and - not report.py3o_server_id): + if (not report.py3o_is_local_fusion and not report.py3o_server_id): raise ValidationError(_( - "Can not use not native format in local fusion. " + "You can not use remote fusion without Fusion server. " "Please specify a Fusion Server")) py3o_is_local_fusion = fields.Boolean( @@ -42,3 +35,22 @@ class IrActionsReport(models.Model): 'py3o.pdf.options', string='PDF Options', ondelete='restrict', help="PDF options can be set per report, but also per Py3o Server. " "If both are defined, the options on the report are used.") + + @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": + continue + if (not rec.is_py3o_native_format and + not rec.lo_bin_path and not rec.py3o_server_id): + rec.is_py3o_report_not_available = True + rec.msg_py3o_report_not_available = _( + "A fusion server or a libreoffice runtime are required " + "to genereate the py3o report '%s'. If the libreoffice" + "runtime is already installed and is not found by " + "Odoo, you can provide the full path to the runtime by " + "setting the key 'py3o.conversion_command' into the " + "configuration parameters." + ) % rec.name diff --git a/report_py3o_fusion_server/tests/test_report_py3o_fusion_server.py b/report_py3o_fusion_server/tests/test_report_py3o_fusion_server.py index 773aae5f7..bf9debd07 100644 --- a/report_py3o_fusion_server/tests/test_report_py3o_fusion_server.py +++ b/report_py3o_fusion_server/tests/test_report_py3o_fusion_server.py @@ -2,6 +2,8 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). import mock from odoo.exceptions import ValidationError +from odoo.addons.report_py3o.models.ir_actions_report import \ + PY3O_CONVERSION_COMMAND_PARAMETER from odoo.addons.report_py3o.tests import test_report_py3o @@ -22,14 +24,31 @@ class TestReportPy3oFusionServer(test_report_py3o.TestReportPy3o): "py3o_server_id": py3o_server.id, "py3o_filetype": 'pdf', }) + self.py3o_server = py3o_server def test_no_local_fusion_without_fusion_server(self): self.assertTrue(self.report.py3o_is_local_fusion) + # Fusion server is only required if not local... + self.report.write({ + "py3o_server_id": None, + "py3o_is_local_fusion": True, + }) + self.report.write({ + "py3o_server_id": self.py3o_server.id, + "py3o_is_local_fusion": True, + }) + self.report.write({ + "py3o_server_id": self.py3o_server.id, + "py3o_is_local_fusion": False, + }) with self.assertRaises(ValidationError) as e: - self.report.write({"py3o_server_id": None}) + self.report.write({ + "py3o_server_id": None, + "py3o_is_local_fusion": False, + }) self.assertEqual( e.exception.name, - "Can not use not native format in local fusion. " + "You can not use remote fusion without Fusion server. " "Please specify a Fusion Server") def test_reports_no_local_fusion(self): @@ -40,3 +59,41 @@ class TestReportPy3oFusionServer(test_report_py3o.TestReportPy3o): for options in self.env['py3o.pdf.options'].search([]): options_dict = options.odoo2libreoffice_options() self.assertIsInstance(options_dict, dict) + + def test_py3o_report_availability(self): + # if the report is not into a native format, we must have at least + # a libreoffice runtime or a fusion server. Otherwise the report is + # not usable and will fail at rutime. + # This test could fails if libreoffice is not available on the server + self.report.py3o_filetype = "odt" + self.assertTrue(self.report.lo_bin_path) + self.assertTrue(self.report.py3o_server_id) + self.assertTrue(self.report.is_py3o_native_format) + self.assertFalse(self.report.is_py3o_report_not_available) + self.assertFalse(self.report.msg_py3o_report_not_available) + + # specify a wrong lo bin path and a non native format. + self.env['ir.config_parameter'].set_param( + PY3O_CONVERSION_COMMAND_PARAMETER, "/wrong_path") + self.report.py3o_filetype = "pdf" + self.report.refresh() + # no native and no bin path, everything is still OK since a fusion + # server is specified. + self.assertFalse(self.report.lo_bin_path) + self.assertTrue(self.report.py3o_server_id) + self.assertFalse(self.report.is_py3o_native_format) + self.assertFalse(self.report.is_py3o_report_not_available) + self.assertFalse(self.report.msg_py3o_report_not_available) + + # if we remove the fusion server, the report becomes unavailable + self.report.py3o_server_id = False + self.assertTrue(self.report.is_py3o_report_not_available) + self.assertTrue(self.report.msg_py3o_report_not_available) + + # if we set a libreffice runtime, the report is available again + self.env['ir.config_parameter'].set_param( + PY3O_CONVERSION_COMMAND_PARAMETER, "libreoffice") + self.report.refresh() + self.assertTrue(self.report.lo_bin_path) + self.assertFalse(self.report.is_py3o_report_not_available) + self.assertFalse(self.report.msg_py3o_report_not_available)