summaryrefslogtreecommitdiff
path: root/odoo
diff options
context:
space:
mode:
authorXavier Morel <xmo@odoo.com>2018-05-14 15:04:19 +0000
committerXavier Morel <xmo@odoo.com>2019-05-27 12:00:39 +0000
commit10f1a1a0c451a3538ac77c6c06cd26fb5898fa9c (patch)
treea2fddfc82cf8a5f0525f877ad22c3f906981b96c /odoo
parent0679d0d54269ffe0664845e8e0bd1238110fd514 (diff)
[REM] multi from ir.actions.act_window
Task 1843603 * src_model is redundant with binding_model_id * multi -> binding_view_types (if empty => all views) (maybe should be empty by default yo?) * in convert, type => rec.get(type) but no @type possible on <act_window>... * removed deprecated auto_refresh & auto_search (not used anywhere (?)) closes odoo/odoo#24738 Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
Diffstat (limited to 'odoo')
-rw-r--r--odoo/addons/base/models/ir_actions.py12
-rw-r--r--odoo/addons/base/tests/test_ir_actions.py48
-rw-r--r--odoo/addons/base/views/ir_actions_views.xml4
-rw-r--r--odoo/addons/base/views/ir_ui_view_views.xml2
-rw-r--r--odoo/addons/base/views/res_users_views.xml5
-rw-r--r--odoo/addons/base/wizard/base_partner_merge_views.xml5
-rw-r--r--odoo/addons/test_action_bindings/__init__.py2
-rw-r--r--odoo/addons/test_action_bindings/__manifest__.py7
-rw-r--r--odoo/addons/test_action_bindings/ir.model.access.csv3
-rw-r--r--odoo/addons/test_action_bindings/models.py9
-rw-r--r--odoo/addons/test_action_bindings/test_data.xml40
-rw-r--r--odoo/addons/test_action_bindings/tests/__init__.py1
-rw-r--r--odoo/addons/test_action_bindings/tests/test_bindings.py93
-rw-r--r--odoo/import_xml.rng28
-rw-r--r--odoo/models.py12
-rw-r--r--odoo/tools/convert.py27
-rw-r--r--odoo/tools/test_reports.py2
17 files changed, 202 insertions, 98 deletions
diff --git a/odoo/addons/base/models/ir_actions.py b/odoo/addons/base/models/ir_actions.py
index bbb93dd99c9..f6d10146e66 100644
--- a/odoo/addons/base/models/ir_actions.py
+++ b/odoo/addons/base/models/ir_actions.py
@@ -45,9 +45,9 @@ class IrActions(models.Model):
binding_model_id = fields.Many2one('ir.model', ondelete='cascade',
help="Setting a value makes this action available in the sidebar for the given model.")
binding_type = fields.Selection([('action', 'Action'),
- ('action_form_only', "Form-only"),
('report', 'Report')],
required=True, default='action')
+ binding_view_types = fields.Char(default='list,form')
def _compute_xml_id(self):
res = self.get_external_id()
@@ -134,13 +134,13 @@ class IrActionsActWindow(models.Model):
_sequence = 'ir_actions_id_seq'
_order = 'name'
- @api.constrains('res_model', 'src_model')
+ @api.constrains('res_model', 'binding_model_id')
def _check_model(self):
for action in self:
if action.res_model not in self.env:
raise ValidationError(_('Invalid model name %r in action definition.') % action.res_model)
- if action.src_model and action.src_model not in self.env:
- raise ValidationError(_('Invalid model name %r in action definition.') % action.src_model)
+ if action.binding_model_id and action.binding_model_id.model not in self.env:
+ raise ValidationError(_('Invalid model name %r in action definition.') % action.binding_model_id.model)
@api.depends('view_ids.view_mode', 'view_mode', 'view_id.type')
def _compute_views(self):
@@ -180,8 +180,6 @@ class IrActionsActWindow(models.Model):
res_id = fields.Integer(string='Record ID', help="Database ID of record to open in form view, when ``view_mode`` is set to 'form' only")
res_model = fields.Char(string='Destination Model', required=True,
help="Model name of the object to open in the view window")
- src_model = fields.Char(string='Source Model',
- help="Optional model name of the objects on which this action should be visible")
target = fields.Selection([('current', 'Current Window'), ('new', 'New Window'), ('inline', 'Inline Edit'), ('fullscreen', 'Full Screen'), ('main', 'Main action of Current Window')], default="current", string='Target Window')
view_mode = fields.Char(required=True, default='tree,form',
help="Comma-separated list of allowed view modes, such as 'form', 'tree', 'calendar', etc. (Default: tree,form)")
@@ -199,9 +197,7 @@ class IrActionsActWindow(models.Model):
'act_id', 'gid', string='Groups')
search_view_id = fields.Many2one('ir.ui.view', string='Search View Ref.')
filter = fields.Boolean()
- auto_search = fields.Boolean(default=True)
search_view = fields.Text(compute='_compute_search_view')
- multi = fields.Boolean(string='Restrict to lists', help="If checked and the action is bound to a model, it will only appear in the More menu on list views")
@api.multi
def read(self, fields=None, load='_classic_read'):
diff --git a/odoo/addons/base/tests/test_ir_actions.py b/odoo/addons/base/tests/test_ir_actions.py
index cfd05fc540a..cfabee877f1 100644
--- a/odoo/addons/base/tests/test_ir_actions.py
+++ b/odoo/addons/base/tests/test_ir_actions.py
@@ -253,54 +253,6 @@ class TestServerActions(TestServerActionsBase):
self.assertEqual(self.test_country.vat_label, 'VatFromTest', 'vat label should be changed to VatFromTest')
-class TestActionBindings(common.TransactionCase):
-
- def test_bindings(self):
- """ check the action bindings on models """
- Actions = self.env['ir.actions.actions']
-
- # first make sure there is no bound action
- self.env.ref('base.action_partner_merge').unlink()
- bindings = Actions.get_bindings('res.partner')
- self.assertFalse(bindings['action'])
- self.assertFalse(bindings['report'])
-
- # create action bindings, and check the returned bindings
- action1 = self.env.ref('base.action_attachment')
- action2 = self.env.ref('base.ir_default_menu_action')
- action3 = self.env['ir.actions.report'].search([('groups_id', '=', False)], limit=1)
- action1.binding_model_id = action2.binding_model_id \
- = action3.binding_model_id \
- = self.env['ir.model']._get('res.partner')
-
- bindings = Actions.get_bindings('res.partner')
- self.assertItemsEqual(
- bindings['action'],
- (action1 + action2).read(),
- "Wrong action bindings",
- )
- self.assertItemsEqual(
- bindings['report'],
- action3.read(),
- "Wrong action bindings",
- )
-
- # add a group on an action, and check that it is not returned
- group = self.env.ref('base.group_user')
- action2.groups_id += group
- self.env.user.groups_id -= group
-
- bindings = Actions.get_bindings('res.partner')
- self.assertItemsEqual(
- bindings['action'],
- action1.read(),
- "Wrong action bindings",
- )
- self.assertItemsEqual(
- bindings['report'],
- action3.read(),
- "Wrong action bindings",
- )
class TestCustomFields(common.TransactionCase):
diff --git a/odoo/addons/base/views/ir_actions_views.xml b/odoo/addons/base/views/ir_actions_views.xml
index 6c64fdf6d90..2a30f9e894d 100644
--- a/odoo/addons/base/views/ir_actions_views.xml
+++ b/odoo/addons/base/views/ir_actions_views.xml
@@ -86,7 +86,6 @@
</page>
<page name='advanced' string="Advanced Properties">
<group>
- <field name="multi"/>
<field name="attachment_use"/>
<field name="attachment"/>
</group>
@@ -163,7 +162,6 @@
<field name="name"/>
<field name="xml_id" string="External ID"/>
<field name="res_model" string="Object"/>
- <field name="src_model" string="Source Object"/>
</group>
<group name="action_details">
<field name="usage"/>
@@ -183,9 +181,7 @@
<field name="domain"/>
<field name="context"/>
<field name="limit"/>
- <field name="auto_search"/>
<field name="filter"/>
- <field name="multi"/>
</group>
</group>
<group name="help" string="Help">
diff --git a/odoo/addons/base/views/ir_ui_view_views.xml b/odoo/addons/base/views/ir_ui_view_views.xml
index 05f51b477ae..f185931eb7d 100644
--- a/odoo/addons/base/views/ir_ui_view_views.xml
+++ b/odoo/addons/base/views/ir_ui_view_views.xml
@@ -121,7 +121,7 @@
</record>
<act_window id="reset_view_arch_wizard_action"
name="Reset View Architecture"
- src_model="ir.ui.view"
+ binding_model="ir.ui.view" binding_views="form"
res_model="reset.view.arch.wizard"
view_type="form"
view_mode="form"
diff --git a/odoo/addons/base/views/res_users_views.xml b/odoo/addons/base/views/res_users_views.xml
index d77cee157ba..68b63a9423f 100644
--- a/odoo/addons/base/views/res_users_views.xml
+++ b/odoo/addons/base/views/res_users_views.xml
@@ -29,10 +29,9 @@
</record>
<act_window id="change_password_wizard_action"
name="Change Password"
- src_model="res.users"
+ binding_model="res.users"
res_model="change.password.wizard"
- view_type="form" view_mode="form"
- key2="client_action_multi" target="new"
+ view_type="form" view_mode="form" target="new"
groups="base.group_erp_manager"/>
<!-- res.groups -->
diff --git a/odoo/addons/base/wizard/base_partner_merge_views.xml b/odoo/addons/base/wizard/base_partner_merge_views.xml
index 18e19fc6a3a..2c130f16212 100644
--- a/odoo/addons/base/wizard/base_partner_merge_views.xml
+++ b/odoo/addons/base/wizard/base_partner_merge_views.xml
@@ -102,10 +102,9 @@
<act_window
id="action_partner_merge"
res_model="base.partner.merge.automatic.wizard"
- src_model="res.partner"
+ binding_model="res.partner"
+ binding_views="list"
target="new"
- multi="True"
- key2="client_action_multi"
view_mode="form"
name="Merge Contacts"/>
</odoo>
diff --git a/odoo/addons/test_action_bindings/__init__.py b/odoo/addons/test_action_bindings/__init__.py
new file mode 100644
index 00000000000..a0fdc10fe11
--- /dev/null
+++ b/odoo/addons/test_action_bindings/__init__.py
@@ -0,0 +1,2 @@
+# -*- coding: utf-8 -*-
+from . import models
diff --git a/odoo/addons/test_action_bindings/__manifest__.py b/odoo/addons/test_action_bindings/__manifest__.py
new file mode 100644
index 00000000000..2486286196a
--- /dev/null
+++ b/odoo/addons/test_action_bindings/__manifest__.py
@@ -0,0 +1,7 @@
+{
+ 'name': "Test Action Bindings",
+ 'data': [
+ 'ir.model.access.csv',
+ 'test_data.xml',
+ ],
+}
diff --git a/odoo/addons/test_action_bindings/ir.model.access.csv b/odoo/addons/test_action_bindings/ir.model.access.csv
new file mode 100644
index 00000000000..a37ae0a59fd
--- /dev/null
+++ b/odoo/addons/test_action_bindings/ir.model.access.csv
@@ -0,0 +1,3 @@
+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+access_tab_a,access_tab_a,model_tab_a,,1,1,1,1
+access_tab_b,access_tab_b,model_tab_b,,1,1,1,1
diff --git a/odoo/addons/test_action_bindings/models.py b/odoo/addons/test_action_bindings/models.py
new file mode 100644
index 00000000000..0a1f6cfff5c
--- /dev/null
+++ b/odoo/addons/test_action_bindings/models.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+from odoo import models
+
+class A(models.Model):
+ _name = _description = 'tab.a'
+
+
+class B(models.Model):
+ _name = _description = 'tab.b'
diff --git a/odoo/addons/test_action_bindings/test_data.xml b/odoo/addons/test_action_bindings/test_data.xml
new file mode 100644
index 00000000000..65670f7a33c
--- /dev/null
+++ b/odoo/addons/test_action_bindings/test_data.xml
@@ -0,0 +1,40 @@
+<odoo>
+ <!-- bind to all views -->
+ <act_window
+ id="act1"
+ name="Action 1"
+ res_model="tab.a"
+ binding_model="tab.a"
+ binding_views=""/>
+ <!-- bind to form views -->
+ <act_window
+ id="act2"
+ name="Action 2"
+ res_model="tab.a"
+ binding_model="tab.a"
+ binding_views="form"/>
+ <!-- bind to default views (list, form) -->
+ <act_window
+ id="act3"
+ name="Action 3"
+ res_model="tab.a"
+ binding_model="tab.a"/>
+
+ <record id="r1" model="ir.actions.act_window">
+ <field name="name">Record 1</field>
+ <field name="res_model">tab.b</field>
+ <field name="binding_model_id" ref="model_tab_b"/>
+ <field name="binding_view_types"/>
+ </record>
+ <record id="r2" model="ir.actions.act_window">
+ <field name="name">Record 2</field>
+ <field name="res_model">tab.b</field>
+ <field name="binding_model_id" ref="model_tab_b"/>
+ <field name="binding_view_types">form</field>
+ </record>
+ <record id="r3" model="ir.actions.act_window">
+ <field name="name">Record 3</field>
+ <field name="res_model">tab.b</field>
+ <field name="binding_model_id" ref="model_tab_b"/>
+ </record>
+</odoo>
diff --git a/odoo/addons/test_action_bindings/tests/__init__.py b/odoo/addons/test_action_bindings/tests/__init__.py
new file mode 100644
index 00000000000..202218ee086
--- /dev/null
+++ b/odoo/addons/test_action_bindings/tests/__init__.py
@@ -0,0 +1 @@
+from . import test_bindings
diff --git a/odoo/addons/test_action_bindings/tests/test_bindings.py b/odoo/addons/test_action_bindings/tests/test_bindings.py
new file mode 100644
index 00000000000..7dc58b9cca3
--- /dev/null
+++ b/odoo/addons/test_action_bindings/tests/test_bindings.py
@@ -0,0 +1,93 @@
+from odoo.tests import common
+
+class TestActionBindings(common.TransactionCase):
+
+ def test_bindings(self):
+ """ check the action bindings on models """
+ Actions = self.env['ir.actions.actions']
+
+ # first make sure there is no bound action
+ self.env.ref('base.action_partner_merge').unlink()
+ bindings = Actions.get_bindings('res.partner')
+ self.assertFalse(bindings['action'])
+ self.assertFalse(bindings['report'])
+
+ # create action bindings, and check the returned bindings
+ action1 = self.env.ref('base.action_attachment')
+ action2 = self.env.ref('base.ir_default_menu_action')
+ action3 = self.env['ir.actions.report'].search([('groups_id', '=', False)], limit=1)
+ action1.binding_model_id = action2.binding_model_id \
+ = action3.binding_model_id \
+ = self.env['ir.model']._get('res.partner')
+
+ bindings = Actions.get_bindings('res.partner')
+ self.assertItemsEqual(
+ bindings['action'],
+ (action1 + action2).read(),
+ "Wrong action bindings",
+ )
+ self.assertItemsEqual(
+ bindings['report'],
+ action3.read(),
+ "Wrong action bindings",
+ )
+
+ # add a group on an action, and check that it is not returned
+ group = self.env.ref('base.group_user')
+ action2.groups_id += group
+ self.env.user.groups_id -= group
+
+ bindings = Actions.get_bindings('res.partner')
+ self.assertItemsEqual(
+ bindings['action'],
+ action1.read(),
+ "Wrong action bindings",
+ )
+ self.assertItemsEqual(
+ bindings['report'],
+ action3.read(),
+ "Wrong action bindings",
+ )
+
+class TestBindingViewFilters(common.TransactionCase):
+ def test_act_window(self):
+ A = self.env['tab.a']
+
+ form_act = A.fields_view_get(toolbar=True)['toolbar']['action']
+ self.assertEqual(
+ [a['name'] for a in form_act],
+ ['Action 1', 'Action 2', 'Action 3'],
+ "forms should have all actions")
+
+ list_act = A.fields_view_get(view_type='tree', toolbar=True)['toolbar']['action']
+ self.assertEqual(
+ [a['name'] for a in list_act],
+ ['Action 1', 'Action 3'],
+ "lists should not have the form-only action")
+
+ kanban_act = A.fields_view_get(view_type='kanban', toolbar=True)['toolbar']['action']
+ self.assertEqual(
+ [a['name'] for a in kanban_act],
+ ['Action 1'],
+ "kanban should only have the universal action")
+
+ def test_act_record(self):
+ B = self.env['tab.b']
+
+ form_act = B.fields_view_get(toolbar=True)['toolbar']['action']
+ self.assertEqual(
+ [a['name'] for a in form_act],
+ ['Record 1', 'Record 2', 'Record 3'],
+ "forms should have all actions")
+
+ list_act = B.fields_view_get(view_type='tree', toolbar=True)['toolbar']['action']
+ self.assertEqual(
+ [a['name'] for a in list_act],
+ ['Record 1', 'Record 3'],
+ "lists should not have the form-only action")
+
+ kanban_act = B.fields_view_get(view_type='kanban', toolbar=True)['toolbar']['action']
+ self.assertEqual(
+ [a['name'] for a in kanban_act],
+ ['Record 1'],
+ "kanban should only have the universal action")
diff --git a/odoo/import_xml.rng b/odoo/import_xml.rng
index 83324f379a9..1603459ed52 100644
--- a/odoo/import_xml.rng
+++ b/odoo/import_xml.rng
@@ -6,6 +6,12 @@
<rng:optional><rng:attribute name="context" /></rng:optional>
</rng:define>
+ <rng:define name="views">
+ <rng:data type="string">
+ <rng:param name="pattern">([a-z]+(,[a-z]+)*)?</rng:param>
+ </rng:data>
+ </rng:define>
+
<rng:define name="any">
<rng:element>
<rng:anyName/>
@@ -243,18 +249,30 @@
<rng:attribute name="name" />
<rng:attribute name="res_model" />
<rng:optional><rng:attribute name="domain" /> </rng:optional>
- <rng:optional><rng:attribute name="src_model" /></rng:optional>
<rng:optional><rng:attribute name="context" /></rng:optional>
<rng:optional> <rng:attribute name="view_id"/> </rng:optional>
- <rng:optional> <rng:attribute name="view_type"/> </rng:optional>
+ <rng:optional><rng:attribute name="view_type"><rng:ref name="views"/></rng:attribute></rng:optional>
<rng:optional> <rng:attribute name="view_mode"/> </rng:optional>
- <rng:optional> <rng:attribute name="multi"/> </rng:optional>
<rng:optional> <rng:attribute name="target"/> </rng:optional>
- <rng:optional> <rng:attribute name="key2"/> </rng:optional>
<rng:optional> <rng:attribute name="groups"/> </rng:optional>
<rng:optional> <rng:attribute name="limit"/> </rng:optional>
<rng:optional> <rng:attribute name="usage"/> </rng:optional>
- <rng:optional> <rng:attribute name="auto_refresh"/> </rng:optional>
+ <rng:optional>
+ <rng:attribute name="binding_model"/>
+ <rng:optional>
+ <rng:attribute name="binding_type">
+ <rng:choice>
+ <rng:value>action</rng:value>
+ <rng:value>report</rng:value>
+ </rng:choice>
+ </rng:attribute>
+ </rng:optional>
+ <rng:optional>
+ <rng:attribute name="binding_views">
+ <rng:ref name="views"/>
+ </rng:attribute>
+ </rng:optional>
+ </rng:optional>
<rng:empty />
</rng:element>
</rng:define>
diff --git a/odoo/models.py b/odoo/models.py
index f8e96406a13..aabc365d03b 100644
--- a/odoo/models.py
+++ b/odoo/models.py
@@ -1484,24 +1484,18 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})):
# Add related action information if aksed
if toolbar:
+ vt = 'list' if view_type == 'tree' else view_type
bindings = self.env['ir.actions.actions'].get_bindings(self._name)
resreport = [action
for action in bindings['report']
- if view_type == 'tree' or not action.get('multi')]
+ if vt in (action.get('binding_view_types') or vt).split(',')]
resaction = [action
for action in bindings['action']
- if view_type == 'tree' or not action.get('multi')]
- resrelate = []
- if view_type == 'form':
- resrelate = bindings['action_form_only']
-
- for res in itertools.chain(resreport, resaction):
- res['string'] = res['name']
+ if vt in (action.get('binding_view_types') or vt).split(',')]
result['toolbar'] = {
'print': resreport,
'action': resaction,
- 'relate': resrelate,
}
return result
diff --git a/odoo/tools/convert.py b/odoo/tools/convert.py
index 7a3ff444cce..599fb3a6e47 100644
--- a/odoo/tools/convert.py
+++ b/odoo/tools/convert.py
@@ -328,13 +328,12 @@ form: module.record_id""" % (xml_id,)
name = rec.get('name')
xml_id = rec.get('id','')
self._test_xml_id(xml_id)
- type = rec.get('type') or 'ir.actions.act_window'
view_id = False
if rec.get('view_id'):
view_id = self.id_get(rec.get('view_id'))
domain = rec.get('domain') or '[]'
res_model = rec.get('res_model')
- src_model = rec.get('src_model')
+ binding_model = rec.get('binding_model')
view_type = rec.get('view_type') or 'form'
view_mode = rec.get('view_mode') or 'tree,form'
usage = rec.get('usage')
@@ -359,16 +358,16 @@ form: module.record_id""" % (xml_id,)
eval_context = {
'name': name,
'xml_id': xml_id,
- 'type': type,
+ 'type': 'ir.actions.act_window',
'view_id': view_id,
'domain': domain,
'res_model': res_model,
- 'src_model': src_model,
+ 'src_model': binding_model,
'view_type': view_type,
'view_mode': view_mode,
'usage': usage,
'limit': limit,
- 'uid' : uid,
+ 'uid': uid,
'active_id': active_id,
'active_ids': active_ids,
'active_model': active_model,
@@ -386,12 +385,11 @@ form: module.record_id""" % (xml_id,)
domain, xml_id or 'n/a', exc_info=True)
res = {
'name': name,
- 'type': type,
+ 'type': 'ir.actions.act_window',
'view_id': view_id,
'domain': domain,
'context': context,
'res_model': res_model,
- 'src_model': src_model,
'view_type': view_type,
'view_mode': view_mode,
'usage': usage,
@@ -412,15 +410,12 @@ form: module.record_id""" % (xml_id,)
if rec.get('target'):
res['target'] = rec.get('target','')
- if rec.get('multi'):
- res['multi'] = safe_eval(rec.get('multi', 'False'))
- if src_model:
- res['binding_model_id'] = self.env['ir.model']._get(src_model).id
- res['binding_type'] = 'report' if rec.get('key2') == 'client_print_multi' else 'action'
- if rec.get('key2') in (None, 'client_action_relate'):
- if not res.get('multi'):
- res['binding_type'] = 'action_form_only'
-
+ if binding_model:
+ res['binding_model_id'] = self.env['ir.model']._get(binding_model).id
+ res['binding_type'] = rec.get('binding_type') or 'action'
+ views = rec.get('binding_views')
+ if views is not None:
+ res['binding_view_types'] = views
xid = self.make_xml_id(xml_id)
data = dict(xml_id=xid, values=res, noupdate=self.noupdate)
self.env['ir.actions.act_window']._load_records([data], self.mode == 'update')
diff --git a/odoo/tools/test_reports.py b/odoo/tools/test_reports.py
index ef3e61ecb42..3e745990dd3 100644
--- a/odoo/tools/test_reports.py
+++ b/odoo/tools/test_reports.py
@@ -140,7 +140,7 @@ def try_report_action(cr, uid, action_id, active_model=None, active_ids=None,
env = env(context=context)
if action['type'] in ['ir.actions.act_window', 'ir.actions.submenu']:
for key in ('res_id', 'res_model', 'view_type', 'view_mode',
- 'limit', 'search_view', 'auto_search', 'search_view_id'):
+ 'limit', 'search_view', 'search_view_id'):
datas[key] = action.get(key, datas.get(key, None))
view_id = False