summaryrefslogtreecommitdiff
path: root/odoo
diff options
context:
space:
mode:
authorXavier Morel <xmo@odoo.com>2018-06-22 15:33:25 +0200
committerXavier Morel <xmo@odoo.com>2018-07-16 11:44:33 +0200
commite89131381015e0ca155f64500d077a7a7bfff9c8 (patch)
treeab71505096477a4cfb7023bd193332e75c33319a /odoo
parent93c0d7e811da0e64d03bfea0f131c6ace1fbde05 (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__.py1
-rw-r--r--odoo/addons/base/data/ir_demo_failure_data.xml51
-rw-r--r--odoo/addons/base/models/__init__.py1
-rw-r--r--odoo/addons/base/models/ir_actions.py7
-rw-r--r--odoo/addons/base/models/ir_demo_failure.py29
-rw-r--r--odoo/addons/base/models/ir_module.py2
-rw-r--r--odoo/modules/graph.py14
-rw-r--r--odoo/modules/loading.py32
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')