diff --git a/addons/base_import_module/i18n/base_import_module.pot b/addons/base_import_module/i18n/base_import_module.pot index 30880dfaf92..b0927451436 100644 --- a/addons/base_import_module/i18n/base_import_module.pot +++ b/addons/base_import_module/i18n/base_import_module.pot @@ -15,6 +15,16 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: \n" +#. module: base_import_module +#. odoo-python +#: code:addons/base_import_module/models/ir_module.py:0 +#, python-format +msgid "" +"\n" +"You may need the Enterprise version to install the data module. Please visit https://www.odoo.com/pricing-plan for more information.\n" +"If you need Website themes, it can be downloaded from https://github.com/odoo/design-themes.\n" +msgstr "" + #. module: base_import_module #: model_terms:ir.ui.view,arch_db:base_import_module.module_view_kanban_apps_inherit msgid "Activate" @@ -229,7 +239,16 @@ msgstr "" #. odoo-python #: code:addons/base_import_module/models/ir_module.py:0 #, python-format -msgid "The following modules will be also installed:\n" +msgid "The following modules will also be installed:\n" +msgstr "" + +#. module: base_import_module +#. odoo-python +#: code:addons/base_import_module/models/ir_module.py:0 +#, python-format +msgid "" +"The installation of the data module would fail as the following dependencies" +" can't be found in the addons-path:\n" msgstr "" #. module: base_import_module diff --git a/addons/base_import_module/models/base_import_module.py b/addons/base_import_module/models/base_import_module.py index 0035c9eb8fd..734ce94ccc4 100644 --- a/addons/base_import_module/models/base_import_module.py +++ b/addons/base_import_module/models/base_import_module.py @@ -30,7 +30,7 @@ class BaseImportModule(models.TransientModel): } def get_dependencies_to_install_names(self): - module_ids = self.env['ir.module.module']._get_missing_dependencies_modules(base64.decodebytes(self.module_file)) + module_ids, _not_found = self.env['ir.module.module']._get_missing_dependencies_modules(base64.decodebytes(self.module_file)) return module_ids.mapped('name') def action_module_open(self): diff --git a/addons/base_import_module/models/ir_module.py b/addons/base_import_module/models/ir_module.py index 1c4610623e5..cef792ff631 100644 --- a/addons/base_import_module/models/ir_module.py +++ b/addons/base_import_module/models/ir_module.py @@ -381,10 +381,13 @@ class IrModule(models.Model): timeout=5.0, ) resp.raise_for_status() + missing_dependencies_description, unavailable_modules = self._get_missing_dependencies(resp.content) + if unavailable_modules: + raise UserError(missing_dependencies_description) import_module = self.env['base.import.module'].create({ 'module_file': base64.b64encode(resp.content), 'state': 'init', - 'modules_dependencies': self._get_missing_dependencies(resp.content) + 'modules_dependencies': missing_dependencies_description, }) return { 'name': 'Install an App', @@ -402,18 +405,31 @@ class IrModule(models.Model): @api.model def _get_missing_dependencies(self, zip_data): - modules = self._get_missing_dependencies_modules(zip_data) + modules, unavailable_modules = self._get_missing_dependencies_modules(zip_data) description = '' - if modules: - description = _('The following modules will be also installed:\n') + if unavailable_modules: + description = _( + "The installation of the data module would fail as the following dependencies can't" + " be found in the addons-path:\n" + ) + for module in unavailable_modules: + description += "- " + module + "\n" + description += _( + "\nYou may need the Enterprise version to install the data module. Please visit " + "https://www.odoo.com/pricing-plan for more information.\n" + "If you need Website themes, it can be downloaded from https://github.com/odoo/design-themes.\n" + ) + elif modules: + description = _("The following modules will also be installed:\n") for mod in modules: description += "- " + mod.shortdesc + "\n" - return description + return description, unavailable_modules def _get_missing_dependencies_modules(self, zip_data): dependencies_to_install = self.env['ir.module.module'] - known_mods = self.search([]) + known_mods = self.search([('to_buy', '=', False)]) installed_mods = [m.name for m in known_mods if m.state == 'installed'] + not_found_modules = set() with zipfile.ZipFile(BytesIO(zip_data), "r") as z: manifest_files = [ file @@ -431,7 +447,10 @@ class IrModule(models.Model): continue unmet_dependencies = set(terp.get('depends', [])).difference(installed_mods) dependencies_to_install |= known_mods.filtered(lambda m: m.name in unmet_dependencies) - return dependencies_to_install + not_found_modules |= set( + mod for mod in unmet_dependencies if mod not in dependencies_to_install.mapped('name') + ) + return dependencies_to_install, not_found_modules @api.model def search_panel_select_range(self, field_name, **kwargs): diff --git a/addons/base_import_module/tests/test_import_module.py b/addons/base_import_module/tests/test_import_module.py index 7f5d6c78b06..a52627d6991 100644 --- a/addons/base_import_module/tests/test_import_module.py +++ b/addons/base_import_module/tests/test_import_module.py @@ -351,10 +351,11 @@ class TestImportModuleHttp(TestImportModule, odoo.tests.HttpCase): with ZipFile(archive, 'w') as zipf: for path, data in files: zipf.writestr(path, data) + modules_dependencies, _not_found = self.env['ir.module.module']._get_missing_dependencies(archive.getvalue()) import_module = self.env['base.import.module'].create({ 'module_file': base64.b64encode(archive.getvalue()), 'state': 'init', - 'modules_dependencies': self.env['ir.module.module']._get_missing_dependencies(archive.getvalue()) + 'modules_dependencies': modules_dependencies, }) dependencies_names = import_module.get_dependencies_to_install_names() self.assertEqual(dependencies_names, [])