diff options
| author | Xavier Morel <xmo@odoo.com> | 2018-06-22 15:33:25 +0200 |
|---|---|---|
| committer | Xavier Morel <xmo@odoo.com> | 2018-07-16 11:44:33 +0200 |
| commit | e89131381015e0ca155f64500d077a7a7bfff9c8 (patch) | |
| tree | ab71505096477a4cfb7023bd193332e75c33319a /odoo | |
| parent | 93c0d7e811da0e64d03bfea0f131c6ace1fbde05 (diff) | |
[IMP] base: disable demo data if they can't install
Task 1856935
Currently, if installing a module's demo data fails (because the
module was uninstalled and some were left over and can't be
reinstalled, or because they're broken, or…) the installation of the
module fails and further installations are skipped (?).
Since demo data are non-essential (though required to run tests),
rather than fail everything if they fail just roll them back and
notify the user.
This change generates a warning log *and* shows a notification popup
to the end user.
Diffstat (limited to 'odoo')
| -rw-r--r-- | odoo/addons/base/__manifest__.py | 1 | ||||
| -rw-r--r-- | odoo/addons/base/data/ir_demo_failure_data.xml | 51 | ||||
| -rw-r--r-- | odoo/addons/base/models/__init__.py | 1 | ||||
| -rw-r--r-- | odoo/addons/base/models/ir_actions.py | 7 | ||||
| -rw-r--r-- | odoo/addons/base/models/ir_demo_failure.py | 29 | ||||
| -rw-r--r-- | odoo/addons/base/models/ir_module.py | 2 | ||||
| -rw-r--r-- | odoo/modules/graph.py | 14 | ||||
| -rw-r--r-- | odoo/modules/loading.py | 32 |
8 files changed, 125 insertions, 12 deletions
diff --git a/odoo/addons/base/__manifest__.py b/odoo/addons/base/__manifest__.py index 99f634350e2..27844454c0c 100644 --- a/odoo/addons/base/__manifest__.py +++ b/odoo/addons/base/__manifest__.py @@ -57,6 +57,7 @@ The kernel of Odoo, needed for all installation. 'wizard/base_update_translations_views.xml', 'wizard/base_partner_merge_views.xml', 'data/ir_actions_data.xml', + 'data/ir_demo_failure_data.xml', 'views/res_company_views.xml', 'views/res_lang_views.xml', 'views/res_partner_views.xml', diff --git a/odoo/addons/base/data/ir_demo_failure_data.xml b/odoo/addons/base/data/ir_demo_failure_data.xml new file mode 100644 index 00000000000..c3afb3f1f9a --- /dev/null +++ b/odoo/addons/base/data/ir_demo_failure_data.xml @@ -0,0 +1,51 @@ +<odoo> + <record model="ir.actions.server" id="demo_failure_action"> + <field name="name">Failed to install demo data for some modules, demo disabled</field> + <field name="model_id" ref="base.model_ir_demo_failure_wizard"/> + <field name="state">code</field> + <field name="code"> +failures = env['ir.demo_failure'].search([ + ('wizard_id', '=', False), +]) +record = model.create({ + 'failure_ids': [(6, 0, failures.ids)], +}) +action = { + 'type': 'ir.actions.act_window', + 'res_id': record.id, + 'res_model': 'ir.demo_failure.wizard', + 'target': 'new', + 'views': [(env.ref('base.demo_failures_dialog').id, 'form')], +} + </field> + </record> + + <record model="ir.ui.view" id="demo_failures_dialog"> + <field name="name">Demo Failure Dialog</field> + <field name="model">ir.demo_failure.wizard</field> + <field name="arch" type="xml"> + <form> + <h3> + The demonstration data of <field name="failures_count"/> + module(s) failed to install and were disabled + </h3> + <field name="failure_ids"> + <tree> + <field name="module_id"/> + <field name="error"/> + </tree> + </field> + <footer> + <button string="Ok" class="oe_highlight" type="object" name="done"/> + </footer> + </form> + </field> + </record> + + <record model="ir.actions.todo" id="demo_failure_todo"> + <field name="name">Demo Failure Notification</field> + <field name="sequence">1</field> + <field name="state">done</field> + <field name="action_id" ref="base.demo_failure_action"/> + </record> +</odoo> diff --git a/odoo/addons/base/models/__init__.py b/odoo/addons/base/models/__init__.py index 4506929a5c5..e29a0938007 100644 --- a/odoo/addons/base/models/__init__.py +++ b/odoo/addons/base/models/__init__.py @@ -28,6 +28,7 @@ from . import ir_logging from . import ir_property from . import ir_module from . import ir_demo +from . import ir_demo_failure from . import report_paperformat from . import res_country from . import res_lang diff --git a/odoo/addons/base/models/ir_actions.py b/odoo/addons/base/models/ir_actions.py index f770b667c27..5403990ea24 100644 --- a/odoo/addons/base/models/ir_actions.py +++ b/odoo/addons/base/models/ir_actions.py @@ -661,17 +661,18 @@ class IrActionsTodo(models.Model): return super(IrActionsTodo, self)._name_search(name, args=args, operator=operator, limit=limit, name_get_uid=name_get_uid) @api.multi - def action_launch(self, context=None): + def action_launch(self): """ Launch Action of Wizard""" self.ensure_one() self.write({'state': 'done'}) # Load action - action = self.env[self.action_id.type].browse(self.action_id.id) + action_type = self.action_id.type + action = self.env[action_type].browse(self.action_id.id) result = action.read()[0] - if action._name != 'ir.actions.act_window': + if action_type != 'ir.actions.act_window': return result result.setdefault('context', '{}') diff --git a/odoo/addons/base/models/ir_demo_failure.py b/odoo/addons/base/models/ir_demo_failure.py new file mode 100644 index 00000000000..8a7396fa99d --- /dev/null +++ b/odoo/addons/base/models/ir_demo_failure.py @@ -0,0 +1,29 @@ +from odoo import api, fields, models + + +class DemoFailure(models.TransientModel): + """ Stores modules for which we could not install demo data + """ + _name = 'ir.demo_failure' + + module_id = fields.Many2one('ir.module.module', required=True, string="Module") + error = fields.Char(string="Error") + wizard_id = fields.Many2one('ir.demo_failure.wizard') + +class DemoFailureWizard(models.TransientModel): + _name = 'ir.demo_failure.wizard' + + failure_ids = fields.One2many( + 'ir.demo_failure', 'wizard_id', readonly=True, + string="Demo Installation Failures" + ) + failures_count = fields.Integer(compute='_compute_failures_count') + + @api.depends('failure_ids') + def _compute_failures_count(self): + for r in self: + r.failures_count = len(r.failure_ids) + + def done(self): + # pylint: disable=next-method-called + return self.env['ir.module.module'].next() diff --git a/odoo/addons/base/models/ir_module.py b/odoo/addons/base/models/ir_module.py index d61d7321912..4c2afe54876 100644 --- a/odoo/addons/base/models/ir_module.py +++ b/odoo/addons/base/models/ir_module.py @@ -516,7 +516,7 @@ class Module(models.Model): _logger.info('getting next %s', Todos) active_todo = Todos.search([('state', '=', 'open')], limit=1) if active_todo: - _logger.info('next action is %s', active_todo) + _logger.info('next action is "%s"', active_todo.name) return active_todo.action_launch() return { 'type': 'ir.actions.act_url', diff --git a/odoo/modules/graph.py b/odoo/modules/graph.py index 0f2e329fab9..33846fbd1ec 100644 --- a/odoo/modules/graph.py +++ b/odoo/modules/graph.py @@ -176,3 +176,17 @@ class Node(object): for c in self.children: s += '%s`-> %s' % (' ' * depth, c._pprint(depth+1)) return s + + def should_have_demo(self): + return (hasattr(self, 'demo') or (self.dbdemo and self.state != 'installed')) and all(p.dbdemo for p in self.parents) + + @property + def parents(self): + if self.depth == 0: + return [] + + return ( + node for node in self.graph.values() + if node.depth < self.depth + if self in node.children + ) diff --git a/odoo/modules/loading.py b/odoo/modules/loading.py index f9a41c9161b..af4ed28ca59 100644 --- a/odoo/modules/loading.py +++ b/odoo/modules/loading.py @@ -75,10 +75,27 @@ def load_demo(cr, package, idref, mode, report=None): """ Loads demo data for the specified package. """ - has_demo = hasattr(package, 'demo') or (package.dbdemo and package.state != 'installed') - if has_demo: - load_data(cr, idref, mode, kind='demo', package=package, report=report) - return has_demo + if not package.should_have_demo(): + return False + + try: + _logger.info("Module %s: loading demo", package.name) + with cr.savepoint(): + load_data(cr, idref, mode, kind='demo', package=package, report=report) + return True + except Exception as e: + # If we could not install demo data for this module + _logger.warning( + "Module %s demo data failed to install, installed without demo data", + package.name, exc_info=True) + + env = api.Environment(cr, SUPERUSER_ID, {}) + todo = env.ref('base.demo_failure_todo', raise_if_not_found=False) + Failure = env.get('ir.demo_failure') + if todo and Failure is not None: + todo.state = 'open' + Failure.create({'module_id': package.id, 'error': str(e)}) + return False def force_demo(cr): @@ -205,10 +222,9 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, # upgrading the module information module.write(module.get_values_from_terp(package.data)) load_data(cr, idref, mode, kind='data', package=package, report=report) - demo_loaded = load_demo(cr, package, idref, mode, report) - if demo_loaded: - cr.execute('update ir_module_module set demo=%s where id=%s', (True, module_id)) - module.invalidate_cache(['demo']) + demo_loaded = package.dbdemo = load_demo(cr, package, idref, mode, report) + cr.execute('update ir_module_module set demo=%s where id=%s', (demo_loaded, module_id)) + module.invalidate_cache(['demo']) migrations.migrate_module(package, 'post') |
