diff options
| author | Xavier Morel <xmo@odoo.com> | 2018-05-14 15:04:19 +0000 |
|---|---|---|
| committer | Xavier Morel <xmo@odoo.com> | 2019-05-27 12:00:39 +0000 |
| commit | 10f1a1a0c451a3538ac77c6c06cd26fb5898fa9c (patch) | |
| tree | a2fddfc82cf8a5f0525f877ad22c3f906981b96c /odoo | |
| parent | 0679d0d54269ffe0664845e8e0bd1238110fd514 (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.py | 12 | ||||
| -rw-r--r-- | odoo/addons/base/tests/test_ir_actions.py | 48 | ||||
| -rw-r--r-- | odoo/addons/base/views/ir_actions_views.xml | 4 | ||||
| -rw-r--r-- | odoo/addons/base/views/ir_ui_view_views.xml | 2 | ||||
| -rw-r--r-- | odoo/addons/base/views/res_users_views.xml | 5 | ||||
| -rw-r--r-- | odoo/addons/base/wizard/base_partner_merge_views.xml | 5 | ||||
| -rw-r--r-- | odoo/addons/test_action_bindings/__init__.py | 2 | ||||
| -rw-r--r-- | odoo/addons/test_action_bindings/__manifest__.py | 7 | ||||
| -rw-r--r-- | odoo/addons/test_action_bindings/ir.model.access.csv | 3 | ||||
| -rw-r--r-- | odoo/addons/test_action_bindings/models.py | 9 | ||||
| -rw-r--r-- | odoo/addons/test_action_bindings/test_data.xml | 40 | ||||
| -rw-r--r-- | odoo/addons/test_action_bindings/tests/__init__.py | 1 | ||||
| -rw-r--r-- | odoo/addons/test_action_bindings/tests/test_bindings.py | 93 | ||||
| -rw-r--r-- | odoo/import_xml.rng | 28 | ||||
| -rw-r--r-- | odoo/models.py | 12 | ||||
| -rw-r--r-- | odoo/tools/convert.py | 27 | ||||
| -rw-r--r-- | odoo/tools/test_reports.py | 2 |
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 |
