From 547880284317b3a14bbbb48671a538c901fea97f Mon Sep 17 00:00:00 2001 From: len-odoo Date: Wed, 25 Apr 2018 15:12:06 +0200 Subject: [PATCH 1/6] [IMP] base: Regroup Public/Portal/Employee access rights under the same category These groups should be exclusive. It makes no sense to have an employee who's also a public user. --- odoo/addons/base/data/ir_module_category_data.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/odoo/addons/base/data/ir_module_category_data.xml b/odoo/addons/base/data/ir_module_category_data.xml index 9eb3c218280..2c5bfac3817 100644 --- a/odoo/addons/base/data/ir_module_category_data.xml +++ b/odoo/addons/base/data/ir_module_category_data.xml @@ -66,9 +66,9 @@ 8 - - Employees - Helps you manage your employees. + + User types + Helps you manage users. 9 @@ -185,7 +185,7 @@ - + @@ -201,11 +201,11 @@ - + - + From e67b61811bc01fad467545dc8896d754dc39506a Mon Sep 17 00:00:00 2001 From: len-odoo Date: Wed, 25 Apr 2018 15:14:33 +0200 Subject: [PATCH 2/6] [IMP] base: Rename "Employee" access right into "Internal User" This doesn't mean that the user is an employee. It means that the user can have access to internal resources on the company. --- odoo/addons/base/security/base_groups.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/odoo/addons/base/security/base_groups.xml b/odoo/addons/base/security/base_groups.xml index c2e13857358..863046f9c4e 100644 --- a/odoo/addons/base/security/base_groups.xml +++ b/odoo/addons/base/security/base_groups.xml @@ -18,7 +18,7 @@ - Employee + Internal User From ab179bb2d7b8f890e04ea79e70d7bc0898e7599f Mon Sep 17 00:00:00 2001 From: len-odoo Date: Wed, 25 Apr 2018 15:38:20 +0200 Subject: [PATCH 3/6] [IMP] base: Add compute/inverse methods to manage user groups Purpose ======= Allow to define users groups on a res.user with computed fields based on the 'groups_id' field. Specification ============= Add compute/inverse methods to manage specific groups on a res.users. These methods should be used on fields defined like one the following cases: 1. A boolean field with the compute/inverse method and an attribute group_xml_id. Example: has_group_discount_per_so_line = fields.Boolean( "Discount on lines", compute='_compute_groups_id', inverse='_inverse_groups_id', group_xml_id='sale.group_discount_per_so_line') 2. A selection field with the compute/inverse method, the selection got from '_get_group_selection' and an attribute 'category_xml_id' Example: group_sales_team_user = fields.Selection( selection=lambda self: self._get_group_selection('base.module_category_sales_management'), string="Sales", compute='_compute_groups_id', inverse='_inverse_groups_id', category_xml_id='base.module_category_sales_management') The fields will be set according to the groups defined in the 'groups_id' field, and the 'groups_id' field will be modified according to the modifications made on theses fields when saving the users's form. --- odoo/addons/base/models/res_users.py | 106 +++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/odoo/addons/base/models/res_users.py b/odoo/addons/base/models/res_users.py index efcf203edf0..05c154bc466 100644 --- a/odoo/addons/base/models/res_users.py +++ b/odoo/addons/base/models/res_users.py @@ -624,6 +624,112 @@ class Users(models.Model): def get_company_currency_id(self): return self.env.user.company_id.currency_id.id + def _add_missing_default_values(self, vals): + # Remove the default values of 'group_' and 'has_group' fields at the user creation if + # 'groups_id' is provided in vals and if the fields value is not explicitely given. + res = super(Users, self)._add_missing_default_values(vals) + return { + key: value for (key, value) in res.items() + if 'groups_id' not in vals or key in vals or (not is_boolean_group(key) or not is_selection_groups(key)) + } + + def _get_group_selection(self, category_xml_id): + """Returns the ordered selection for the given ir.module.category xmlid""" + category = self.env.ref(category_xml_id, raise_if_not_found=False) + selections = [] + if category: + groups = self.env['res.groups'].search([('category_id', '=', category.id)]) + order = {group: len(group.trans_implied_ids & groups) for group in groups} + groups = groups.sorted(key=order.get) + selections = [(group.id, group.name) for group in groups] + return selections + + @api.depends('groups_id') + def _compute_groups_id(self): + """Set the value for the group field (Selection of Boolean) + according to the user's groups, defined by the field 'groups_id'. + + These methods should be used on fields defined like one the + following cases: + 1. A boolean field with the compute/inverse method and an attribute + group_xml_id. + Example: + has_group_discount_per_so_line = fields.Boolean( + "Discount on lines", + compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='sale.group_discount_per_so_line') + 2. A selection field with the compute/inverse method, the selection + got from '_get_group_selection' and an attribute + 'category_xml_id' + Example: + group_sales_team_user = fields.Selection( + selection=lambda self: self._get_group_selection('base.module_category_sales_management'), + string="Sales", compute='_compute_groups_id', inverse='_inverse_groups_id', + category_xml_id='base.module_category_sales_management') + The fields will be set according to the groups defined in the 'groups_id' + field, and the 'groups_id' field will be modified according to the + modifications made on theses fields when saving the users's form. + """ + computed_group_fields = [field for field in self._field_computed.keys() if field.compute == '_compute_groups_id'] + all_groups = self.env['res.groups'].search([]) + category_data = {} + # Retrieve groups order for selection fields + for field in computed_group_fields: + if getattr(field, 'category_xml_id', None): + category = self.env.ref(getattr(field, 'category_xml_id')) + category_groups = all_groups.filtered(lambda group: group.category_id == category) + order = {group: len(group.trans_implied_ids & category_groups) for group in category_groups} + category_data[field] = category_groups.sorted(key=order.get, reverse=True) + # Set group fields values according to groups_id + for user in self: + for field in computed_group_fields: + # Checkbox group + if getattr(field, 'group_xml_id', None): + group = self.env.ref(getattr(field, 'group_xml_id')) + user[field.name] = group in user.groups_id + # Selection group + elif getattr(field, 'category_xml_id', None): + # Take the highest level group the user belongs to + user_groups = [group for group in category_data[field] if group in user.groups_id] + user[field.name] = user_groups[0].id if user_groups else False + else: + _logger.warning(_("No 'group_xml_id' or 'category_xml_id' is set on the computed field %s linked to the method _compute_groups_id") % (field.name)) + + def _inverse_groups_id(self): + """Update 'groups_id' according the group fields values in cache.""" + computed_group_fields = [field for field in self._field_computed.keys() if field.compute == '_compute_groups_id'] + all_groups = self.env['res.groups'].search([]) + for user in self: + # we need to read all values in cache before any prefetch + field_values = {field: user[field.name] for field in computed_group_fields if field.name in user._cache} + groups_id_vals = [] + for field, value in field_values.items(): + # Checkbox group + if getattr(field, 'group_xml_id', None): + selected_group = self.env.ref(getattr(field, 'group_xml_id')) + if value: + groups_id_vals.append((4, selected_group.id)) + else: + groups_id_vals.append((3, selected_group.id)) + for group in selected_group.trans_implied_ids: + groups_id_vals.append((4, group.id)) + # Selection group + elif getattr(field, 'category_xml_id', None): + category = self.env.ref(getattr(field, 'category_xml_id')) + category_groups = [group for group in all_groups if group.category_id == category] + selected_group = [group for group in all_groups if group.id == value] + selected_group = selected_group and selected_group[0] or self.env['res.groups'] + for group in category_groups: + if group in (selected_group.trans_implied_ids | selected_group): + groups_id_vals.append((4, group.id)) + else: + groups_id_vals.append((3, group.id)) + else: + _logger.warning(_("No 'group_xml_id' or 'category_xml_id' is set on the computed field %s linked to the method _compute_groups_id") % (field.name)) + if groups_id_vals: + user.write({'groups_id': groups_id_vals}) + + # # Implied groups # From 99f497b390e680629dce3a7e2e282ada74ee9884 Mon Sep 17 00:00:00 2001 From: Yannick Tivisse Date: Wed, 25 Apr 2018 15:21:02 +0200 Subject: [PATCH 4/6] [IMP] *: Define groups on res.users models The reified view on the res users will be dropped in the following commit. The previous commit adds support to define each group as a computed field on the res users. This commit defines: - A boolean field for each 'isolated' res.group, i.e. a group in the hidden category. - A selection field for each 'Application' res.group, i.e. a group in a application category. Example: - The group to manage pricelist in sales becomes a boolean field - The groups project user/manager become a selection field --- addons/account/__manifest__.py | 1 + addons/account/models/__init__.py | 1 + addons/account/models/res_users.py | 21 +++++++ addons/account/views/res_users_views.xml | 24 ++++++++ addons/analytic/__manifest__.py | 1 + addons/analytic/models/__init__.py | 1 + addons/analytic/models/res_users.py | 16 +++++ addons/analytic/views/res_users_views.xml | 20 +++++++ addons/auth_signup/views/res_users_views.xml | 2 +- addons/crm/__manifest__.py | 1 + addons/crm/models/res_users.py | 5 +- addons/crm/views/res_users_views.xml | 16 +++++ addons/event/__manifest__.py | 2 + addons/event/models/__init__.py | 1 + addons/event/models/res_partner.py | 3 +- addons/event/models/res_users.py | 13 +++++ addons/event/views/res_users_views.xml | 14 +++++ addons/fleet/__manifest__.py | 1 + addons/fleet/models/__init__.py | 1 + addons/fleet/models/res_users.py | 13 +++++ addons/fleet/views/res_users_views.xml | 14 +++++ addons/hr/__manifest__.py | 1 + addons/hr/models/res_users.py | 6 ++ addons/hr/security/hr_security.xml | 1 - addons/hr/views/res_users_views.xml | 14 +++++ addons/hr_attendance/__manifest__.py | 1 + addons/hr_attendance/models/__init__.py | 1 + addons/hr_attendance/models/res_users.py | 23 ++++++++ .../hr_attendance/views/res_users_views.xml | 24 ++++++++ addons/hr_expense/__manifest__.py | 1 + addons/hr_expense/models/__init__.py | 1 + addons/hr_expense/models/res_users.py | 13 +++++ addons/hr_expense/views/res_users_views.xml | 14 +++++ addons/hr_holidays/__manifest__.py | 1 + addons/hr_holidays/models/__init__.py | 1 + addons/hr_holidays/models/res_users.py | 13 +++++ addons/hr_holidays/views/res_users_views.xml | 14 +++++ addons/hr_payroll/__manifest__.py | 1 + addons/hr_payroll/models/__init__.py | 1 + addons/hr_payroll/models/res_users.py | 13 +++++ addons/hr_payroll/views/res_users_views.xml | 14 +++++ addons/hr_recruitment/__manifest__.py | 1 + addons/hr_recruitment/models/__init__.py | 1 + addons/hr_recruitment/models/res_users.py | 13 +++++ .../hr_recruitment/views/res_users_views.xml | 14 +++++ addons/hr_timesheet/__manifest__.py | 1 + addons/hr_timesheet/models/__init__.py | 1 + addons/hr_timesheet/models/res_users.py | 13 +++++ addons/hr_timesheet/views/res_users_views.xml | 14 +++++ addons/im_livechat/__manifest__.py | 1 + addons/im_livechat/models/__init__.py | 1 + addons/im_livechat/models/res_users.py | 14 +++++ addons/im_livechat/views/res_users_views.xml | 14 +++++ addons/l10n_be_intrastat/__manifest__.py | 1 + addons/l10n_be_intrastat/models/__init__.py | 1 + addons/l10n_be_intrastat/models/res_users.py | 12 ++++ .../views/res_users_views.xml | 16 +++++ addons/lunch/__manifest__.py | 1 + addons/lunch/models/__init__.py | 1 + addons/lunch/models/res_users.py | 13 +++++ addons/lunch/views/res_users_views.xml | 14 +++++ addons/maintenance/__manifest__.py | 1 + addons/maintenance/models/__init__.py | 1 + addons/maintenance/models/res_users.py | 13 +++++ addons/maintenance/views/res_users_views.xml | 16 +++++ addons/mass_mailing/__manifest__.py | 1 + addons/mass_mailing/models/__init__.py | 1 + addons/mass_mailing/models/res_users.py | 17 ++++++ addons/mass_mailing/views/res_users_views.xml | 20 +++++++ addons/mrp/__manifest__.py | 1 + addons/mrp/models/__init__.py | 1 + addons/mrp/models/res_users.py | 17 ++++++ addons/mrp/views/res_users_views.xml | 20 +++++++ addons/point_of_sale/__manifest__.py | 2 +- addons/point_of_sale/models/res_users.py | 5 ++ ...res_users_view.xml => res_users_views.xml} | 8 ++- addons/product/__manifest__.py | 1 + addons/product/models/__init__.py | 1 + addons/product/models/res_users.py | 28 +++++++++ addons/product/views/res_users_views.xml | 32 ++++++++++ addons/project/__manifest__.py | 1 + addons/project/models/__init__.py | 1 + addons/project/models/res_users.py | 21 +++++++ addons/project/views/res_users_views.xml | 24 ++++++++ addons/purchase/__manifest__.py | 1 + addons/purchase/models/__init__.py | 1 + addons/purchase/models/res_users.py | 22 +++++++ addons/purchase/views/res_users_views.xml | 24 ++++++++ .../tests/test_purchase_requisition.py | 4 +- addons/sale/__manifest__.py | 1 + addons/sale/models/__init__.py | 1 + addons/sale/models/res_users.py | 43 ++++++++++++++ addons/sale/security/sale_security.xml | 6 -- addons/sale/views/res_users_views.xml | 44 ++++++++++++++ addons/sale_stock/__manifest__.py | 1 + addons/sale_stock/models/__init__.py | 1 + addons/sale_stock/models/res_users.py | 18 ++++++ addons/sale_stock/views/res_users_views.xml | 20 +++++++ addons/sales_team/__manifest__.py | 1 + addons/sales_team/models/res_users.py | 6 ++ addons/sales_team/views/res_users_views.xml | 14 +++++ addons/stock/__manifest__.py | 1 + addons/stock/models/__init__.py | 1 + addons/stock/models/res_users.py | 48 +++++++++++++++ addons/stock/views/res_users_views.xml | 44 ++++++++++++++ addons/survey/__manifest__.py | 2 + addons/survey/models/__init__.py | 1 + addons/survey/models/res_users.py | 13 +++++ addons/survey/views/res_users_views.xml | 14 +++++ addons/uom/__manifest__.py | 1 + addons/uom/models/__init__.py | 1 + addons/uom/models/res_users.py | 12 ++++ addons/uom/views/res_users_views.xml | 16 +++++ addons/website/__manifest__.py | 1 + addons/website/models/__init__.py | 1 + addons/website/models/res_users.py | 13 +++++ addons/website/views/res_users_views.xml | 14 +++++ addons/website_forum/__manifest__.py | 2 +- .../{res_users.xml => res_users_views.xml} | 0 addons/website_mass_mailing/__manifest__.py | 1 + .../website_mass_mailing/models/__init__.py | 1 + .../website_mass_mailing/models/res_users.py | 13 +++++ .../views/res_users_views.xml | 16 +++++ .../base/data/ir_module_category_data.xml | 5 -- odoo/addons/base/data/res_users_demo.xml | 3 + odoo/addons/base/models/res_users.py | 28 +++++++++ odoo/addons/base/views/res_users_views.xml | 58 +++++++++++++------ 127 files changed, 1189 insertions(+), 38 deletions(-) create mode 100644 addons/account/models/res_users.py create mode 100644 addons/account/views/res_users_views.xml create mode 100644 addons/analytic/models/res_users.py create mode 100644 addons/analytic/views/res_users_views.xml create mode 100644 addons/crm/views/res_users_views.xml create mode 100644 addons/event/models/res_users.py create mode 100644 addons/event/views/res_users_views.xml create mode 100644 addons/fleet/models/res_users.py create mode 100644 addons/fleet/views/res_users_views.xml create mode 100644 addons/hr/views/res_users_views.xml create mode 100644 addons/hr_attendance/models/res_users.py create mode 100644 addons/hr_attendance/views/res_users_views.xml create mode 100644 addons/hr_expense/models/res_users.py create mode 100644 addons/hr_expense/views/res_users_views.xml create mode 100644 addons/hr_holidays/models/res_users.py create mode 100644 addons/hr_holidays/views/res_users_views.xml create mode 100644 addons/hr_payroll/models/res_users.py create mode 100644 addons/hr_payroll/views/res_users_views.xml create mode 100644 addons/hr_recruitment/models/res_users.py create mode 100644 addons/hr_recruitment/views/res_users_views.xml create mode 100644 addons/hr_timesheet/models/res_users.py create mode 100644 addons/hr_timesheet/views/res_users_views.xml create mode 100644 addons/im_livechat/models/res_users.py create mode 100644 addons/im_livechat/views/res_users_views.xml create mode 100644 addons/l10n_be_intrastat/models/res_users.py create mode 100644 addons/l10n_be_intrastat/views/res_users_views.xml create mode 100644 addons/lunch/models/res_users.py create mode 100644 addons/lunch/views/res_users_views.xml create mode 100644 addons/maintenance/models/res_users.py create mode 100644 addons/maintenance/views/res_users_views.xml create mode 100644 addons/mass_mailing/models/res_users.py create mode 100644 addons/mass_mailing/views/res_users_views.xml create mode 100644 addons/mrp/models/res_users.py create mode 100644 addons/mrp/views/res_users_views.xml rename addons/point_of_sale/views/{res_users_view.xml => res_users_views.xml} (63%) create mode 100644 addons/product/models/res_users.py create mode 100644 addons/product/views/res_users_views.xml create mode 100644 addons/project/models/res_users.py create mode 100644 addons/project/views/res_users_views.xml create mode 100644 addons/purchase/models/res_users.py create mode 100644 addons/purchase/views/res_users_views.xml create mode 100644 addons/sale/models/res_users.py create mode 100644 addons/sale/views/res_users_views.xml create mode 100644 addons/sale_stock/models/res_users.py create mode 100644 addons/sale_stock/views/res_users_views.xml create mode 100644 addons/sales_team/views/res_users_views.xml create mode 100644 addons/stock/models/res_users.py create mode 100644 addons/stock/views/res_users_views.xml create mode 100644 addons/survey/models/res_users.py create mode 100644 addons/survey/views/res_users_views.xml create mode 100644 addons/uom/models/res_users.py create mode 100644 addons/uom/views/res_users_views.xml create mode 100644 addons/website/models/res_users.py create mode 100644 addons/website/views/res_users_views.xml rename addons/website_forum/views/{res_users.xml => res_users_views.xml} (100%) create mode 100644 addons/website_mass_mailing/models/res_users.py create mode 100644 addons/website_mass_mailing/views/res_users_views.xml diff --git a/addons/account/__manifest__.py b/addons/account/__manifest__.py index 8ead6af8961..47f91fd2cd4 100644 --- a/addons/account/__manifest__.py +++ b/addons/account/__manifest__.py @@ -65,6 +65,7 @@ Core mechanisms for the accounting modules. To display the menuitems, install th 'views/account_dashboard_setup_bar.xml', 'wizard/account_report_tax_view.xml', 'views/report_tax.xml', + 'views/res_users_views.xml', 'data/service_cron_reverse.xml', ], 'demo': [ diff --git a/addons/account/models/__init__.py b/addons/account/models/__init__.py index 011c2076d0d..4eb991c1183 100644 --- a/addons/account/models/__init__.py +++ b/addons/account/models/__init__.py @@ -14,3 +14,4 @@ from . import company from . import res_config_settings from . import account_cash_rounding from . import reconciliation_widget +from . import res_users diff --git a/addons/account/models/res_users.py b/addons/account/models/res_users.py new file mode 100644 index 00000000000..53e9c3b5a4a --- /dev/null +++ b/addons/account/models/res_users.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = 'res.users' + + has_group_warning_account = fields.Boolean( + 'A warning can be set on a partner (Account)', compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='account.group_warning_account') + + has_group_cash_rounding = fields.Boolean( + 'Allow the cash rounding management', compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='account.group_cash_rounding') + + group_account_user = fields.Selection( + selection=lambda self: self._get_group_selection('base.module_category_accounting_and_finance'), + string='Accounting & Finance', compute='_compute_groups_id', inverse='_inverse_groups_id', + category_xml_id='base.module_category_accounting_and_finance') diff --git a/addons/account/views/res_users_views.xml b/addons/account/views/res_users_views.xml new file mode 100644 index 00000000000..b3a4a15d402 --- /dev/null +++ b/addons/account/views/res_users_views.xml @@ -0,0 +1,24 @@ + + + + res.users.form.account.inherit + res.users + + 40 + + + + + + + + + diff --git a/addons/analytic/__manifest__.py b/addons/analytic/__manifest__.py index 74499219a64..392600a5850 100644 --- a/addons/analytic/__manifest__.py +++ b/addons/analytic/__manifest__.py @@ -19,6 +19,7 @@ that have no counterpart in the general financial accounts. 'security/analytic_security.xml', 'security/ir.model.access.csv', 'views/analytic_account_views.xml', + 'views/res_users_views.xml', ], 'demo': [ 'data/analytic_demo.xml', diff --git a/addons/analytic/models/__init__.py b/addons/analytic/models/__init__.py index d1fd64b96f8..2e5e553c626 100644 --- a/addons/analytic/models/__init__.py +++ b/addons/analytic/models/__init__.py @@ -2,3 +2,4 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from . import analytic_account +from . import res_users diff --git a/addons/analytic/models/res_users.py b/addons/analytic/models/res_users.py new file mode 100644 index 00000000000..f1363c0d123 --- /dev/null +++ b/addons/analytic/models/res_users.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = 'res.users' + + has_group_analytic_accounting = fields.Boolean( + 'Analytic Accounting', compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='analytic.group_analytic_accounting') + + has_group_analytic_tags = fields.Boolean( + 'Analytic Accounting Tags', compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='analytic.group_analytic_tags') diff --git a/addons/analytic/views/res_users_views.xml b/addons/analytic/views/res_users_views.xml new file mode 100644 index 00000000000..0d4b070cdaf --- /dev/null +++ b/addons/analytic/views/res_users_views.xml @@ -0,0 +1,20 @@ + + + + res.users.form.analytic.inherit + res.users + + + + + + + diff --git a/addons/auth_signup/views/res_users_views.xml b/addons/auth_signup/views/res_users_views.xml index 0a5f43eb8a0..85be323f340 100644 --- a/addons/auth_signup/views/res_users_views.xml +++ b/addons/auth_signup/views/res_users_views.xml @@ -1,7 +1,7 @@ - + res.users.form.inherit res.users diff --git a/addons/crm/__manifest__.py b/addons/crm/__manifest__.py index 8e1a36c89ea..e224a6d8101 100644 --- a/addons/crm/__manifest__.py +++ b/addons/crm/__manifest__.py @@ -43,6 +43,7 @@ 'report/crm_activity_report_views.xml', 'report/crm_opportunity_report_views.xml', 'views/crm_team_views.xml', + 'views/res_users_views.xml', ], 'demo': [ 'data/crm_demo.xml', diff --git a/addons/crm/models/res_users.py b/addons/crm/models/res_users.py index 2c94f1c05ab..fbbe64501eb 100644 --- a/addons/crm/models/res_users.py +++ b/addons/crm/models/res_users.py @@ -5,8 +5,11 @@ from odoo import fields, models class Users(models.Model): - _inherit = 'res.users' target_sales_won = fields.Integer('Won in Opportunities Target') target_sales_done = fields.Integer('Activities Done Target') + + has_group_use_lead = fields.Boolean( + 'Show Lead Menu', compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='crm.group_use_lead') diff --git a/addons/crm/views/res_users_views.xml b/addons/crm/views/res_users_views.xml new file mode 100644 index 00000000000..27c2bf286fa --- /dev/null +++ b/addons/crm/views/res_users_views.xml @@ -0,0 +1,16 @@ + + + + res.users.form.crm.inherit + res.users + + + + + + + diff --git a/addons/event/__manifest__.py b/addons/event/__manifest__.py index e9f22c0f53d..b3662b2f003 100644 --- a/addons/event/__manifest__.py +++ b/addons/event/__manifest__.py @@ -30,6 +30,8 @@ Key Features 'views/res_config_settings_views.xml', 'views/event_templates.xml', 'views/res_partner_views.xml', + 'views/res_users_views.xml', + ], 'demo': [ 'data/event_demo.xml', diff --git a/addons/event/models/__init__.py b/addons/event/models/__init__.py index eed59489b26..695ce7e13e4 100644 --- a/addons/event/models/__init__.py +++ b/addons/event/models/__init__.py @@ -5,3 +5,4 @@ from . import event from . import event_mail from . import res_config_settings from . import res_partner +from . import res_users diff --git a/addons/event/models/res_partner.py b/addons/event/models/res_partner.py index d534f3749f2..e91773c8fee 100644 --- a/addons/event/models/res_partner.py +++ b/addons/event/models/res_partner.py @@ -3,10 +3,11 @@ from odoo import api, fields, models + class ResPartner(models.Model): _inherit = 'res.partner' - event_count = fields.Integer("Events", compute='_compute_event_count', help="Number of events the partner has participated.") + event_count = fields.Integer("Events Count", compute='_compute_event_count', help="Number of events the partner has participated.") def _compute_event_count(self): for partner in self: diff --git a/addons/event/models/res_users.py b/addons/event/models/res_users.py new file mode 100644 index 00000000000..024677bcfe4 --- /dev/null +++ b/addons/event/models/res_users.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = 'res.users' + + group_event_user = fields.Selection( + selection=lambda self: self._get_group_selection('base.module_category_event_management'), + string='Events', compute='_compute_groups_id', inverse='_inverse_groups_id', + category_xml_id='base.module_category_event_management') diff --git a/addons/event/views/res_users_views.xml b/addons/event/views/res_users_views.xml new file mode 100644 index 00000000000..20b722bf76a --- /dev/null +++ b/addons/event/views/res_users_views.xml @@ -0,0 +1,14 @@ + + + + res.users.form.event.inherit + res.users + + 105 + + + + + + + diff --git a/addons/fleet/__manifest__.py b/addons/fleet/__manifest__.py index 646e28b1294..b3a33837130 100644 --- a/addons/fleet/__manifest__.py +++ b/addons/fleet/__manifest__.py @@ -36,6 +36,7 @@ Main Features 'views/fleet_vehicle_cost_views.xml', 'views/fleet_board_view.xml', 'views/mail_activity_views.xml', + 'views/res_users_views.xml', 'data/fleet_cars_data.xml', 'data/fleet_data.xml', 'data/mail_data.xml', diff --git a/addons/fleet/models/__init__.py b/addons/fleet/models/__init__.py index 781603220f3..0421e909283 100644 --- a/addons/fleet/models/__init__.py +++ b/addons/fleet/models/__init__.py @@ -4,3 +4,4 @@ from . import fleet_vehicle from . import fleet_vehicle_cost from . import fleet_vehicle_model +from . import res_users diff --git a/addons/fleet/models/res_users.py b/addons/fleet/models/res_users.py new file mode 100644 index 00000000000..0f031278fb5 --- /dev/null +++ b/addons/fleet/models/res_users.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = 'res.users' + + group_fleet_user = fields.Selection( + selection=lambda self: self._get_group_selection('fleet.module_fleet_category'), + string='Fleet', compute='_compute_groups_id', inverse='_inverse_groups_id', + category_xml_id='fleet.module_fleet_category') diff --git a/addons/fleet/views/res_users_views.xml b/addons/fleet/views/res_users_views.xml new file mode 100644 index 00000000000..3cd5e04b63a --- /dev/null +++ b/addons/fleet/views/res_users_views.xml @@ -0,0 +1,14 @@ + + + + res.users.form.fleet.inherit + res.users + + 100 + + + + + + + diff --git a/addons/hr/__manifest__.py b/addons/hr/__manifest__.py index fd9e76106fb..6bed1af89a1 100644 --- a/addons/hr/__manifest__.py +++ b/addons/hr/__manifest__.py @@ -27,6 +27,7 @@ 'views/hr_views.xml', 'views/hr_templates.xml', 'views/res_config_settings_views.xml', + 'views/res_users_views.xml', 'data/hr_data.xml', ], 'demo': [ diff --git a/addons/hr/models/res_users.py b/addons/hr/models/res_users.py index 8f371ba3b13..08c3d4f6d14 100644 --- a/addons/hr/models/res_users.py +++ b/addons/hr/models/res_users.py @@ -11,6 +11,12 @@ class User(models.Model): employee_ids = fields.One2many('hr.employee', 'user_id', string='Related employees') + group_hr_user = fields.Selection( + selection=lambda self: self._get_group_selection('base.module_category_human_resources'), + string="Human Resources", compute='_compute_groups_id', inverse='_inverse_groups_id', + category_xml_id='base.module_category_human_resources', + help='Officer: The user will be able to approve document created by employees.\nManager: The user will have an access to the human resources configuration as well as statistic reports.') + @api.multi def write(self, vals): """ When renaming admin user, we want its new name propagated to its related employees """ diff --git a/addons/hr/security/hr_security.xml b/addons/hr/security/hr_security.xml index b0e971e5491..0d4f310aa72 100644 --- a/addons/hr/security/hr_security.xml +++ b/addons/hr/security/hr_security.xml @@ -4,7 +4,6 @@ Officer - The user will be able to approve document created by employees. diff --git a/addons/hr/views/res_users_views.xml b/addons/hr/views/res_users_views.xml new file mode 100644 index 00000000000..d68aac97bd2 --- /dev/null +++ b/addons/hr/views/res_users_views.xml @@ -0,0 +1,14 @@ + + + + res.users.form.hr.inherit + res.users + + 50 + + + + + + + diff --git a/addons/hr_attendance/__manifest__.py b/addons/hr_attendance/__manifest__.py index 4637cc7bb61..fe15c194c92 100644 --- a/addons/hr_attendance/__manifest__.py +++ b/addons/hr_attendance/__manifest__.py @@ -26,6 +26,7 @@ actions(Check in/Check out) performed by them. 'views/hr_department_view.xml', 'views/hr_employee_view.xml', 'views/res_config_settings_views.xml', + 'views/res_users_views.xml', ], 'demo': [ 'data/hr_attendance_demo.xml' diff --git a/addons/hr_attendance/models/__init__.py b/addons/hr_attendance/models/__init__.py index fd62623b92b..724d7ee23aa 100644 --- a/addons/hr_attendance/models/__init__.py +++ b/addons/hr_attendance/models/__init__.py @@ -3,3 +3,4 @@ from . import res_config_settings from . import hr_attendance from . import hr_employee +from . import res_users diff --git a/addons/hr_attendance/models/res_users.py b/addons/hr_attendance/models/res_users.py new file mode 100644 index 00000000000..34b2450964d --- /dev/null +++ b/addons/hr_attendance/models/res_users.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = 'res.users' + + has_group_hr_attendance = fields.Boolean( + 'Manual Attendance', compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='hr_attendance.group_hr_attendance', + help='The user will gain access to the human resources attendance menu, enabling him to manage his own attendance.') + + has_group_hr_attendance_use_pin = fields.Boolean( + 'Enable PIN use', compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='hr_attendance.group_hr_attendance_use_pin', + help='The user will have to enter his PIN to check in and out manually at the company screen.') + + group_hr_attendance_user = fields.Selection( + selection=lambda self: self._get_group_selection('base.module_category_hr_attendance'), + string='Attendance', compute='_compute_groups_id', inverse='_inverse_groups_id', + category_xml_id='base.module_category_hr_attendance') diff --git a/addons/hr_attendance/views/res_users_views.xml b/addons/hr_attendance/views/res_users_views.xml new file mode 100644 index 00000000000..eb8115fbcf9 --- /dev/null +++ b/addons/hr_attendance/views/res_users_views.xml @@ -0,0 +1,24 @@ + + + + res.users.form.hr_attendance.inherit + res.users + + 80 + + + + + + + + + diff --git a/addons/hr_expense/__manifest__.py b/addons/hr_expense/__manifest__.py index 11ae6223152..c9a4184c302 100644 --- a/addons/hr_expense/__manifest__.py +++ b/addons/hr_expense/__manifest__.py @@ -43,6 +43,7 @@ This module also uses analytic accounting and is compatible with the invoice on 'views/assets.xml', 'views/res_config_settings_views.xml', 'views/account_journal_dashboard.xml', + 'views/res_users_views.xml', ], 'demo': ['data/hr_expense_demo.xml'], 'installable': True, diff --git a/addons/hr_expense/models/__init__.py b/addons/hr_expense/models/__init__.py index af1e04d2dd2..5a1b4fcd975 100644 --- a/addons/hr_expense/models/__init__.py +++ b/addons/hr_expense/models/__init__.py @@ -7,3 +7,4 @@ from . import hr_expense from . import product_template from . import res_config_settings from . import account_journal_dashboard +from . import res_users diff --git a/addons/hr_expense/models/res_users.py b/addons/hr_expense/models/res_users.py new file mode 100644 index 00000000000..84324e182f1 --- /dev/null +++ b/addons/hr_expense/models/res_users.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = 'res.users' + + group_hr_expense_user = fields.Selection( + selection=lambda self: self._get_group_selection('base.module_category_hr_expense'), + string='Expenses', compute='_compute_groups_id', inverse='_inverse_groups_id', + category_xml_id='base.module_category_hr_expense') diff --git a/addons/hr_expense/views/res_users_views.xml b/addons/hr_expense/views/res_users_views.xml new file mode 100644 index 00000000000..4225955c135 --- /dev/null +++ b/addons/hr_expense/views/res_users_views.xml @@ -0,0 +1,14 @@ + + + + res.users.form.hr_expense.inherit + res.users + + 65 + + + + + + + diff --git a/addons/hr_holidays/__manifest__.py b/addons/hr_holidays/__manifest__.py index da9238ad82a..9bf1da4a2ed 100644 --- a/addons/hr_holidays/__manifest__.py +++ b/addons/hr_holidays/__manifest__.py @@ -39,6 +39,7 @@ A synchronization with an internal agenda (Meetings of the CRM module) is also p 'views/hr_leave_allocation_views.xml', 'views/hr_views.xml', 'views/mail_activity_views.xml', + 'views/res_users_views.xml', 'wizard/hr_holidays_summary_department_views.xml', 'wizard/hr_holidays_summary_employees_views.xml', diff --git a/addons/hr_holidays/models/__init__.py b/addons/hr_holidays/models/__init__.py index 621aeccd08b..0465a571c55 100644 --- a/addons/hr_holidays/models/__init__.py +++ b/addons/hr_holidays/models/__init__.py @@ -6,3 +6,4 @@ from . import hr from . import hr_leave from . import hr_leave_allocation from . import hr_leave_type +from . import res_users diff --git a/addons/hr_holidays/models/res_users.py b/addons/hr_holidays/models/res_users.py new file mode 100644 index 00000000000..d38d6c63d82 --- /dev/null +++ b/addons/hr_holidays/models/res_users.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = 'res.users' + + group_hr_holidays_user = fields.Selection( + selection=lambda self: self._get_group_selection('base.module_category_hr_holidays'), + string='Leaves', compute='_compute_groups_id', inverse='_inverse_groups_id', + category_xml_id='base.module_category_hr_holidays') diff --git a/addons/hr_holidays/views/res_users_views.xml b/addons/hr_holidays/views/res_users_views.xml new file mode 100644 index 00000000000..354a681e7c4 --- /dev/null +++ b/addons/hr_holidays/views/res_users_views.xml @@ -0,0 +1,14 @@ + + + + res.users.form.hr_holidays.inherit + res.users + + 55 + + + + + + + diff --git a/addons/hr_payroll/__manifest__.py b/addons/hr_payroll/__manifest__.py index f0584b9474b..7225b046dc3 100644 --- a/addons/hr_payroll/__manifest__.py +++ b/addons/hr_payroll/__manifest__.py @@ -29,6 +29,7 @@ 'views/report_contributionregister_templates.xml', 'views/report_payslip_templates.xml', 'views/report_payslipdetails_templates.xml', + 'views/res_users_views.xml', ], 'demo': ['data/hr_payroll_demo.xml'], } diff --git a/addons/hr_payroll/models/__init__.py b/addons/hr_payroll/models/__init__.py index 99a241743cf..5c4f1a7008e 100644 --- a/addons/hr_payroll/models/__init__.py +++ b/addons/hr_payroll/models/__init__.py @@ -6,3 +6,4 @@ from . import hr_employee from . import res_config_settings from . import hr_salary_rule from . import hr_payslip +from . import res_users diff --git a/addons/hr_payroll/models/res_users.py b/addons/hr_payroll/models/res_users.py new file mode 100644 index 00000000000..3c2fe5c78d4 --- /dev/null +++ b/addons/hr_payroll/models/res_users.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = 'res.users' + + group_hr_payroll_user = fields.Selection( + selection=lambda self: self._get_group_selection('base.module_category_hr_payroll'), + string='Payroll', compute='_compute_groups_id', inverse='_inverse_groups_id', + category_xml_id='base.module_category_hr_payroll') diff --git a/addons/hr_payroll/views/res_users_views.xml b/addons/hr_payroll/views/res_users_views.xml new file mode 100644 index 00000000000..5d5fd491325 --- /dev/null +++ b/addons/hr_payroll/views/res_users_views.xml @@ -0,0 +1,14 @@ + + + + res.users.form.hr_payroll.inherit + res.users + + 95 + + + + + + + diff --git a/addons/hr_recruitment/__manifest__.py b/addons/hr_recruitment/__manifest__.py index ea329b7ba54..27664fcd4ad 100644 --- a/addons/hr_recruitment/__manifest__.py +++ b/addons/hr_recruitment/__manifest__.py @@ -27,6 +27,7 @@ 'views/hr_department_views.xml', 'views/hr_job_views.xml', 'views/mail_activity_views.xml', + 'views/res_users_views.xml', ], 'demo': [ 'data/hr_recruitment_demo.xml', diff --git a/addons/hr_recruitment/models/__init__.py b/addons/hr_recruitment/models/__init__.py index 078e032e222..d1bf3c8234b 100644 --- a/addons/hr_recruitment/models/__init__.py +++ b/addons/hr_recruitment/models/__init__.py @@ -4,3 +4,4 @@ from . import hr_employee from . import hr_job from . import res_config_settings from . import calendar +from . import res_users diff --git a/addons/hr_recruitment/models/res_users.py b/addons/hr_recruitment/models/res_users.py new file mode 100644 index 00000000000..a251cbcdcad --- /dev/null +++ b/addons/hr_recruitment/models/res_users.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = 'res.users' + + group_hr_recruitment_user = fields.Selection( + selection=lambda self: self._get_group_selection('base.module_category_hr_recruitment'), + string='Recruitment', compute='_compute_groups_id', inverse='_inverse_groups_id', + category_xml_id='base.module_category_hr_recruitment') diff --git a/addons/hr_recruitment/views/res_users_views.xml b/addons/hr_recruitment/views/res_users_views.xml new file mode 100644 index 00000000000..ea5eb7cef39 --- /dev/null +++ b/addons/hr_recruitment/views/res_users_views.xml @@ -0,0 +1,14 @@ + + + + res.users.form.hr_recruitment.inherit + res.users + + 60 + + + + + + + diff --git a/addons/hr_timesheet/__manifest__.py b/addons/hr_timesheet/__manifest__.py index 1b35f5f5c35..6c0a654f5f1 100644 --- a/addons/hr_timesheet/__manifest__.py +++ b/addons/hr_timesheet/__manifest__.py @@ -31,6 +31,7 @@ up a management by affair. 'report/hr_timesheet_report_view.xml', 'report/report_timesheet_templates.xml', 'views/hr_views.xml', + 'views/res_users_views.xml', 'data/hr_timesheet_data.xml', ], 'demo': [ diff --git a/addons/hr_timesheet/models/__init__.py b/addons/hr_timesheet/models/__init__.py index 11998476ce2..b8bfb2333b9 100644 --- a/addons/hr_timesheet/models/__init__.py +++ b/addons/hr_timesheet/models/__init__.py @@ -6,3 +6,4 @@ from . import hr from . import hr_timesheet from . import res_config_settings from . import project +from . import res_users diff --git a/addons/hr_timesheet/models/res_users.py b/addons/hr_timesheet/models/res_users.py new file mode 100644 index 00000000000..f5eb9addcb3 --- /dev/null +++ b/addons/hr_timesheet/models/res_users.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = 'res.users' + + group_hr_timesheet_user = fields.Selection( + selection=lambda self: self._get_group_selection('base.module_category_hr_timesheet'), + string='Timesheets', compute='_compute_groups_id', inverse='_inverse_groups_id', + category_xml_id='base.module_category_hr_timesheet') diff --git a/addons/hr_timesheet/views/res_users_views.xml b/addons/hr_timesheet/views/res_users_views.xml new file mode 100644 index 00000000000..c44ab31980d --- /dev/null +++ b/addons/hr_timesheet/views/res_users_views.xml @@ -0,0 +1,14 @@ + + + + res.users.form.hr_timesheet.inherit + res.users + + 70 + + + + + + + diff --git a/addons/im_livechat/__manifest__.py b/addons/im_livechat/__manifest__.py index c85b2ac330c..352f18c36b4 100644 --- a/addons/im_livechat/__manifest__.py +++ b/addons/im_livechat/__manifest__.py @@ -25,6 +25,7 @@ Help your customers with this chat, and analyse their feedback. "views/mail_channel_views.xml", "views/im_livechat_channel_views.xml", "views/im_livechat_channel_templates.xml", + "views/res_users_views.xml", "report/im_livechat_report_channel_views.xml", "report/im_livechat_report_operator_views.xml" ], diff --git a/addons/im_livechat/models/__init__.py b/addons/im_livechat/models/__init__.py index 7ed0b5e53f9..380ebfbfc00 100644 --- a/addons/im_livechat/models/__init__.py +++ b/addons/im_livechat/models/__init__.py @@ -3,3 +3,4 @@ from . import im_livechat_channel from . import ir_autovacuum from . import mail_channel from . import rating +from . import res_users diff --git a/addons/im_livechat/models/res_users.py b/addons/im_livechat/models/res_users.py new file mode 100644 index 00000000000..af9f066dbc7 --- /dev/null +++ b/addons/im_livechat/models/res_users.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = 'res.users' + + group_im_livechat_user = fields.Selection( + selection=lambda self: self._get_group_selection('im_livechat.module_category_im_livechat'), + string='Live Support', compute='_compute_groups_id', inverse='_inverse_groups_id', + category_xml_id='im_livechat.module_category_im_livechat', + help='User: The user will be able to join support channels.\nManager: The user will be able to delete support channels.') diff --git a/addons/im_livechat/views/res_users_views.xml b/addons/im_livechat/views/res_users_views.xml new file mode 100644 index 00000000000..57209008b8e --- /dev/null +++ b/addons/im_livechat/views/res_users_views.xml @@ -0,0 +1,14 @@ + + + + res.users.form.im_livechat.inherit + res.users + + 125 + + + + + + + diff --git a/addons/l10n_be_intrastat/__manifest__.py b/addons/l10n_be_intrastat/__manifest__.py index cc276b059a3..0e472995ea4 100644 --- a/addons/l10n_be_intrastat/__manifest__.py +++ b/addons/l10n_be_intrastat/__manifest__.py @@ -17,6 +17,7 @@ Based on invoices. 'security/l10n_be_intrastat_security.xml', 'security/ir.model.access.csv', 'views/l10n_be_intrastat_view.xml', + 'views/res_users_views.xml', 'wizard/l10n_be_intrastat_declaration_view.xml', ], } diff --git a/addons/l10n_be_intrastat/models/__init__.py b/addons/l10n_be_intrastat/models/__init__.py index fd6e09f945e..2fdf02ead4f 100644 --- a/addons/l10n_be_intrastat/models/__init__.py +++ b/addons/l10n_be_intrastat/models/__init__.py @@ -2,3 +2,4 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from . import l10n_be_intrastat +from . import res_users diff --git a/addons/l10n_be_intrastat/models/res_users.py b/addons/l10n_be_intrastat/models/res_users.py new file mode 100644 index 00000000000..15f52877bea --- /dev/null +++ b/addons/l10n_be_intrastat/models/res_users.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = 'res.users' + + has_group_intrastat_extended = fields.Boolean( + 'Intrastat extended', compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='l10n_be_intrastat.intrastat_extended') diff --git a/addons/l10n_be_intrastat/views/res_users_views.xml b/addons/l10n_be_intrastat/views/res_users_views.xml new file mode 100644 index 00000000000..043d6b8b8c0 --- /dev/null +++ b/addons/l10n_be_intrastat/views/res_users_views.xml @@ -0,0 +1,16 @@ + + + + res.users.form.l10n_be_intrastat.inherit + res.users + + + + + + + diff --git a/addons/lunch/__manifest__.py b/addons/lunch/__manifest__.py index 34499700cc6..1c593ffa772 100644 --- a/addons/lunch/__manifest__.py +++ b/addons/lunch/__manifest__.py @@ -29,6 +29,7 @@ If you want to save your employees' time and avoid them to always have coins in 'views/lunch_templates.xml', 'wizard/lucky_order_view.xml', 'views/lunch_views.xml', + 'views/res_users_views.xml', 'data/lunch_data.xml', ], 'demo': ['data/lunch_demo.xml'], diff --git a/addons/lunch/models/__init__.py b/addons/lunch/models/__init__.py index 9824b4ad3b0..e16f6c755b9 100644 --- a/addons/lunch/models/__init__.py +++ b/addons/lunch/models/__init__.py @@ -1,3 +1,4 @@ # -*- coding: utf-8 -*- from . import lunch +from . import res_users diff --git a/addons/lunch/models/res_users.py b/addons/lunch/models/res_users.py new file mode 100644 index 00000000000..9d3a39d8974 --- /dev/null +++ b/addons/lunch/models/res_users.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = 'res.users' + + group_lunch_user = fields.Selection( + selection=lambda self: self._get_group_selection('lunch.module_lunch_category'), + string='Lunch', compute='_compute_groups_id', inverse='_inverse_groups_id', + category_xml_id='lunch.module_lunch_category') diff --git a/addons/lunch/views/res_users_views.xml b/addons/lunch/views/res_users_views.xml new file mode 100644 index 00000000000..c414ba40d57 --- /dev/null +++ b/addons/lunch/views/res_users_views.xml @@ -0,0 +1,14 @@ + + + + res.users.form.lunch.inherit + res.users + + 90 + + + + + + + diff --git a/addons/maintenance/__manifest__.py b/addons/maintenance/__manifest__.py index d40bdbe3d9e..df1be15dfad 100644 --- a/addons/maintenance/__manifest__.py +++ b/addons/maintenance/__manifest__.py @@ -17,6 +17,7 @@ 'views/maintenance_views.xml', 'views/maintenance_templates.xml', 'views/mail_activity_views.xml', + 'views/res_users_views.xml', 'data/maintenance_cron.xml', ], 'demo': ['data/maintenance_demo.xml'], diff --git a/addons/maintenance/models/__init__.py b/addons/maintenance/models/__init__.py index fb9363f4230..155a108ce15 100644 --- a/addons/maintenance/models/__init__.py +++ b/addons/maintenance/models/__init__.py @@ -1,3 +1,4 @@ # -*- coding: utf-8 -*- from . import maintenance +from . import res_users diff --git a/addons/maintenance/models/res_users.py b/addons/maintenance/models/res_users.py new file mode 100644 index 00000000000..cac599eda08 --- /dev/null +++ b/addons/maintenance/models/res_users.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = 'res.users' + + has_group_equipment_manager = fields.Boolean( + 'Equipment Manager', compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='maintenance.group_equipment_manager', + help='The user will be able to manage equipments.') diff --git a/addons/maintenance/views/res_users_views.xml b/addons/maintenance/views/res_users_views.xml new file mode 100644 index 00000000000..f606d3ad869 --- /dev/null +++ b/addons/maintenance/views/res_users_views.xml @@ -0,0 +1,16 @@ + + + + res.users.form.maintenance.inherit + res.users + + + + + + + diff --git a/addons/mass_mailing/__manifest__.py b/addons/mass_mailing/__manifest__.py index 0a9a4851e6e..0478ca3a8c6 100644 --- a/addons/mass_mailing/__manifest__.py +++ b/addons/mass_mailing/__manifest__.py @@ -34,6 +34,7 @@ 'views/themes_templates.xml', 'views/snippets_themes.xml', 'views/snippets_themes_options.xml', + 'views/res_users_views.xml', ], 'demo': [ 'data/mass_mailing_demo.xml', diff --git a/addons/mass_mailing/models/__init__.py b/addons/mass_mailing/models/__init__.py index 5eaeb678539..ee8bfe34058 100644 --- a/addons/mass_mailing/models/__init__.py +++ b/addons/mass_mailing/models/__init__.py @@ -9,3 +9,4 @@ from . import res_config_settings from . import mass_mailing_report from . import link_tracker from . import ir_model_fields +from . import res_users diff --git a/addons/mass_mailing/models/res_users.py b/addons/mass_mailing/models/res_users.py new file mode 100644 index 00000000000..9b9a111c310 --- /dev/null +++ b/addons/mass_mailing/models/res_users.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = 'res.users' + + group_mass_mailing_user = fields.Selection( + selection=lambda self: self._get_group_selection('base.module_category_mass_mailing'), + string='Mass Mailing', compute='_compute_groups_id', inverse='_inverse_groups_id', + category_xml_id='base.module_category_mass_mailing') + + has_group_mass_mailing_campaign = fields.Boolean( + 'Manage Mass Mailing Campaigns', compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='mass_mailing.group_mass_mailing_campaign') diff --git a/addons/mass_mailing/views/res_users_views.xml b/addons/mass_mailing/views/res_users_views.xml new file mode 100644 index 00000000000..b4bd171931d --- /dev/null +++ b/addons/mass_mailing/views/res_users_views.xml @@ -0,0 +1,20 @@ + + + + res.users.form.mass_mailing.inherit + res.users + + 110 + + + + + + + + + diff --git a/addons/mrp/__manifest__.py b/addons/mrp/__manifest__.py index 3141d3a6372..d65c56ac813 100644 --- a/addons/mrp/__manifest__.py +++ b/addons/mrp/__manifest__.py @@ -36,6 +36,7 @@ 'views/res_config_settings_views.xml', 'views/mrp_templates.xml', 'views/stock_scrap_views.xml', + 'views/res_users_views.xml', 'report/mrp_report_views_main.xml', 'report/mrp_report_bom_structure.xml', 'report/mrp_production_templates.xml', diff --git a/addons/mrp/models/__init__.py b/addons/mrp/models/__init__.py index 35239e53b1c..8a5125a85fe 100644 --- a/addons/mrp/models/__init__.py +++ b/addons/mrp/models/__init__.py @@ -19,3 +19,4 @@ from . import stock_picking from . import stock_production_lot from . import stock_scrap from . import stock_warehouse +from . import res_users diff --git a/addons/mrp/models/res_users.py b/addons/mrp/models/res_users.py new file mode 100644 index 00000000000..28ab5647155 --- /dev/null +++ b/addons/mrp/models/res_users.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = 'res.users' + + has_group_mrp_routings = fields.Boolean( + 'Manage Work Order Operations', compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='mrp.group_mrp_routings') + + group_mrp_user = fields.Selection( + selection=lambda self: self._get_group_selection('base.module_category_manufacturing'), + string='Manufacturing', compute='_compute_groups_id', inverse='_inverse_groups_id', + category_xml_id='base.module_category_manufacturing') diff --git a/addons/mrp/views/res_users_views.xml b/addons/mrp/views/res_users_views.xml new file mode 100644 index 00000000000..b3bec2a27e8 --- /dev/null +++ b/addons/mrp/views/res_users_views.xml @@ -0,0 +1,20 @@ + + + + res.users.form.mrp.inherit + res.users + + 25 + + + + + + + + + diff --git a/addons/point_of_sale/__manifest__.py b/addons/point_of_sale/__manifest__.py index 7689d082fc7..2e3b7cb29fa 100644 --- a/addons/point_of_sale/__manifest__.py +++ b/addons/point_of_sale/__manifest__.py @@ -34,7 +34,7 @@ 'views/pos_order_report_view.xml', 'views/account_statement_view.xml', 'views/account_statement_report.xml', - 'views/res_users_view.xml', + 'views/res_users_views.xml', 'views/res_partner_view.xml', 'views/report_statement.xml', 'views/report_userlabel.xml', diff --git a/addons/point_of_sale/models/res_users.py b/addons/point_of_sale/models/res_users.py index 6fb09e8a44e..05adba44a5d 100644 --- a/addons/point_of_sale/models/res_users.py +++ b/addons/point_of_sale/models/res_users.py @@ -9,6 +9,11 @@ class ResUsers(models.Model): pos_security_pin = fields.Char(string='Security PIN', size=32, help='A Security PIN used to protect sensible functionality in the Point of Sale') + group_point_of_sale_user = fields.Selection( + selection=lambda self: self._get_group_selection('base.module_category_point_of_sale'), + string='Point of Sale', compute='_compute_groups_id', inverse='_inverse_groups_id', + category_xml_id='base.module_category_point_of_sale') + @api.constrains('pos_security_pin') def _check_pin(self): if self.pos_security_pin and not self.pos_security_pin.isdigit(): diff --git a/addons/point_of_sale/views/res_users_view.xml b/addons/point_of_sale/views/res_users_views.xml similarity index 63% rename from addons/point_of_sale/views/res_users_view.xml rename to addons/point_of_sale/views/res_users_views.xml index 84df0988d24..61a504fae59 100644 --- a/addons/point_of_sale/views/res_users_view.xml +++ b/addons/point_of_sale/views/res_users_views.xml @@ -1,10 +1,14 @@ - + res.users.form.view res.users - + + 130 + + + diff --git a/addons/product/__manifest__.py b/addons/product/__manifest__.py index 92637cd5a07..c62c9826f46 100644 --- a/addons/product/__manifest__.py +++ b/addons/product/__manifest__.py @@ -38,6 +38,7 @@ Print product labels with barcode. 'views/product_pricelist_views.xml', 'views/res_partner_views.xml', 'views/product_template_import_templates.xml', + 'views/res_users_views.xml', 'report/product_reports.xml', 'report/product_pricelist_templates.xml', 'report/product_product_templates.xml', diff --git a/addons/product/models/__init__.py b/addons/product/models/__init__.py index 57917450de3..d92be9dfb05 100644 --- a/addons/product/models/__init__.py +++ b/addons/product/models/__init__.py @@ -15,3 +15,4 @@ from . import product_attribute from . import product_pricelist from . import res_company from . import res_partner +from . import res_users diff --git a/addons/product/models/res_users.py b/addons/product/models/res_users.py new file mode 100644 index 00000000000..ee0f0395725 --- /dev/null +++ b/addons/product/models/res_users.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = 'res.users' + + has_group_sale_pricelist = fields.Boolean( + 'Sales Pricelists', compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='product.group_sale_pricelist') + + has_group_pricelist_item = fields.Boolean( + 'Manage Pricelist Items', compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='product.group_pricelist_item') + + has_group_product_pricelist = fields.Boolean( + 'Pricelists On Product', compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='product.group_product_pricelist') + + has_group_stock_packaging = fields.Boolean( + 'Manage Product Packaging', compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='product.group_stock_packaging') + + has_group_product_variant = fields.Boolean( + 'Manage Product Variants', compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='product.group_product_variant') diff --git a/addons/product/views/res_users_views.xml b/addons/product/views/res_users_views.xml new file mode 100644 index 00000000000..a8c05f84437 --- /dev/null +++ b/addons/product/views/res_users_views.xml @@ -0,0 +1,32 @@ + + + + res.users.form.product.inherit + res.users + + + + + + + diff --git a/addons/project/__manifest__.py b/addons/project/__manifest__.py index 5da8fb35d0c..838fe9b832c 100644 --- a/addons/project/__manifest__.py +++ b/addons/project/__manifest__.py @@ -32,6 +32,7 @@ 'views/project_assets.xml', 'views/project_portal_templates.xml', 'views/project_rating_templates.xml', + 'views/res_users_views.xml', 'data/project_mail_template_data.xml', ], 'qweb': ['static/src/xml/project.xml'], diff --git a/addons/project/models/__init__.py b/addons/project/models/__init__.py index e202189a304..a37cedf22ab 100644 --- a/addons/project/models/__init__.py +++ b/addons/project/models/__init__.py @@ -5,3 +5,4 @@ from . import project from . import res_config_settings from . import res_company from . import res_partner +from . import res_users diff --git a/addons/project/models/res_users.py b/addons/project/models/res_users.py new file mode 100644 index 00000000000..f304dc2d826 --- /dev/null +++ b/addons/project/models/res_users.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = 'res.users' + + has_group_subtask_project = fields.Boolean( + 'Use Subtasks', compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='project.group_subtask_project') + + has_group_project_rating = fields.Boolean( + 'Use Rating on Project', compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='project.group_project_rating') + + group_project_user = fields.Selection( + selection=lambda self: self._get_group_selection('base.module_category_project_management'), + string='Project', compute='_compute_groups_id', inverse='_inverse_groups_id', + category_xml_id='base.module_category_project_management') diff --git a/addons/project/views/res_users_views.xml b/addons/project/views/res_users_views.xml new file mode 100644 index 00000000000..a31d5978ba6 --- /dev/null +++ b/addons/project/views/res_users_views.xml @@ -0,0 +1,24 @@ + + + + res.users.form.project.inherit + res.users + + 5 + + + + + + + + + diff --git a/addons/purchase/__manifest__.py b/addons/purchase/__manifest__.py index 7f1cb5e5474..8e4a43cc50e 100644 --- a/addons/purchase/__manifest__.py +++ b/addons/purchase/__manifest__.py @@ -24,6 +24,7 @@ 'report/purchase_report_views.xml', 'data/mail_template_data.xml', 'views/portal_templates.xml', + 'views/res_users_views.xml', 'report/purchase_order_templates.xml', 'report/purchase_quotation_templates.xml', ], diff --git a/addons/purchase/models/__init__.py b/addons/purchase/models/__init__.py index d0ec983e287..d402046cde0 100644 --- a/addons/purchase/models/__init__.py +++ b/addons/purchase/models/__init__.py @@ -8,3 +8,4 @@ from . import res_company from . import res_config_settings from . import res_partner from . import stock +from . import res_users diff --git a/addons/purchase/models/res_users.py b/addons/purchase/models/res_users.py new file mode 100644 index 00000000000..5264a6fd89e --- /dev/null +++ b/addons/purchase/models/res_users.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = 'res.users' + + has_group_manage_vendor_price = fields.Boolean( + 'Manage Vendor Price', compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='purchase.group_manage_vendor_price') + + has_group_warning_purchase = fields.Boolean( + 'A warning can be set on a product or a customer (Purchase)', + compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='purchase.group_warning_purchase') + + group_purchase_user = fields.Selection( + selection=lambda self: self._get_group_selection('base.module_category_purchase_management'), + string='Purchases', compute='_compute_groups_id', inverse='_inverse_groups_id', + category_xml_id='base.module_category_purchase_management') diff --git a/addons/purchase/views/res_users_views.xml b/addons/purchase/views/res_users_views.xml new file mode 100644 index 00000000000..54e0eb080f5 --- /dev/null +++ b/addons/purchase/views/res_users_views.xml @@ -0,0 +1,24 @@ + + + + res.users.form.purchase.inherit + res.users + + 45 + + + + + + + + + diff --git a/addons/purchase_requisition/tests/test_purchase_requisition.py b/addons/purchase_requisition/tests/test_purchase_requisition.py index 1b4ff7c1da0..e80f04ecb95 100644 --- a/addons/purchase_requisition/tests/test_purchase_requisition.py +++ b/addons/purchase_requisition/tests/test_purchase_requisition.py @@ -23,11 +23,11 @@ class TestPurchaseRequisition(common.TransactionCase): # Create a user as 'Purchase Requisition Manager' self.res_users_purchase_requisition_manager = self.ResUser.create({'company_id': self.res_company_id, 'name': 'Purchase requisition Manager', 'login': 'prm', 'email': 'requisition_manager@yourcompany.com'}) # Added groups for Purchase Requisition Manager. - self.res_users_purchase_requisition_manager.group_id = self.ref('purchase.group_purchase_manager') + self.res_users_purchase_requisition_manager.groups_id = [(4, self.ref('purchase.group_purchase_manager'), False)] # Create a user as 'Purchase Requisition User' self.res_users_purchase_requisition_user = self.ResUser.create({'company_id': self.res_company_id, 'name': 'Purchase requisition User', 'login': 'pru', 'email': 'requisition_user@yourcompany.com'}) # Added groups for Purchase Requisition User. - self.res_users_purchase_requisition_user.group_id = self.ref('purchase.group_purchase_user') + self.res_users_purchase_requisition_user.groups_id = [(4, self.ref('purchase.group_purchase_user'), False)] # In order to test process of the purchase requisition ,create requisition self.requisition1 = self.env['purchase.requisition'].create({'line_ids': [(0, 0, {'product_id': self.product_09_id, 'product_qty': 10.0, 'product_uom_id': self.product_09_uom_id})]}) diff --git a/addons/sale/__manifest__.py b/addons/sale/__manifest__.py index 17983579339..1e78334c26d 100644 --- a/addons/sale/__manifest__.py +++ b/addons/sale/__manifest__.py @@ -31,6 +31,7 @@ This module contains all the common features of Sales Management and eCommerce. 'views/sale_portal_templates.xml', 'views/sale_layout_category_view.xml', 'views/res_config_settings_views.xml', + 'views/res_users_views.xml', ], 'demo': [ 'data/sale_demo.xml', diff --git a/addons/sale/models/__init__.py b/addons/sale/models/__init__.py index 7a157566790..dcd51bccca5 100644 --- a/addons/sale/models/__init__.py +++ b/addons/sale/models/__init__.py @@ -13,3 +13,4 @@ from . import res_config_settings from . import sale_layout from . import sales_team from . import ir_model_fields +from . import res_users \ No newline at end of file diff --git a/addons/sale/models/res_users.py b/addons/sale/models/res_users.py new file mode 100644 index 00000000000..5ff6b06d878 --- /dev/null +++ b/addons/sale/models/res_users.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = 'res.users' + + has_group_warning_sale = fields.Boolean( + "A warning can be set on a product or a customer (Sale)", + compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='sale.group_warning_sale') + + has_group_sale_layout = fields.Boolean( + "Personalize sales order and invoice report", + compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='sale.group_sale_layout') + + has_group_delivery_invoice_address = fields.Boolean( + "Addresses in Sales Orders", + compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='sale.group_delivery_invoice_address') + + has_group_show_price_subtotal = fields.Boolean( + "Show line subtotals without taxes (B2B)", + compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='sale.group_show_price_subtotal') + + has_group_show_price_total = fields.Boolean( + "Show line subtotals with taxes included (B2C)", + compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='sale.group_show_price_total') + + has_group_discount_per_so_line = fields.Boolean( + "Discount on lines", + compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='sale.group_discount_per_so_line') + + has_group_proforma_sales = fields.Boolean( + "Pro-forma Invoices", + compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='sale.group_proforma_sales') diff --git a/addons/sale/security/sale_security.xml b/addons/sale/security/sale_security.xml index f753c3bed13..8936079df73 100644 --- a/addons/sale/security/sale_security.xml +++ b/addons/sale/security/sale_security.xml @@ -50,12 +50,6 @@ - - Analytic Accounting for Sales - - - - diff --git a/addons/sale/views/res_users_views.xml b/addons/sale/views/res_users_views.xml new file mode 100644 index 00000000000..a4eae27cc6c --- /dev/null +++ b/addons/sale/views/res_users_views.xml @@ -0,0 +1,44 @@ + + + + res.users.form.sale.inherit + res.users + + + + + + + diff --git a/addons/sale_stock/__manifest__.py b/addons/sale_stock/__manifest__.py index c4b41c4ca3b..77a181a7195 100644 --- a/addons/sale_stock/__manifest__.py +++ b/addons/sale_stock/__manifest__.py @@ -35,6 +35,7 @@ You can choose flexible invoicing methods: 'views/account_invoice_views.xml', 'views/sale_stock_portal_template.xml', 'views/product_template_views.xml', + 'views/res_users_views.xml', 'report/sale_order_report_templates.xml', 'report/stock_report_deliveryslip.xml', 'data/sale_stock_data.xml', diff --git a/addons/sale_stock/models/__init__.py b/addons/sale_stock/models/__init__.py index 1f11274e77a..9aa9277bfe8 100644 --- a/addons/sale_stock/models/__init__.py +++ b/addons/sale_stock/models/__init__.py @@ -7,3 +7,4 @@ from . import sale_order from . import res_config_settings from . import stock from . import product_template +from . import res_users diff --git a/addons/sale_stock/models/res_users.py b/addons/sale_stock/models/res_users.py new file mode 100644 index 00000000000..5a1cbd2e1e5 --- /dev/null +++ b/addons/sale_stock/models/res_users.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = 'res.users' + + has_group_route_so_lines = fields.Boolean( + 'Enable Route on Sales Order Line', + compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='sale_stock.group_route_so_lines') + + has_group_display_incoterm = fields.Boolean( + 'Display incoterms on Sales Order and related invoices', + compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='sale_stock.group_display_incoterm') diff --git a/addons/sale_stock/views/res_users_views.xml b/addons/sale_stock/views/res_users_views.xml new file mode 100644 index 00000000000..99d64a9f5a8 --- /dev/null +++ b/addons/sale_stock/views/res_users_views.xml @@ -0,0 +1,20 @@ + + + + res.users.form.sale_stock.inherit + res.users + + + + + + + diff --git a/addons/sales_team/__manifest__.py b/addons/sales_team/__manifest__.py index 199b34db0e8..fd8ce74a30c 100644 --- a/addons/sales_team/__manifest__.py +++ b/addons/sales_team/__manifest__.py @@ -16,6 +16,7 @@ Using this application you can manage Sales Channels with CRM and/or Sales 'data/sales_team_data.xml', 'views/crm_team_views.xml', 'views/sales_team_dashboard.xml', + 'views/res_users_views.xml', ], 'demo': ['data/sales_team_demo.xml'], 'installable': True, diff --git a/addons/sales_team/models/res_users.py b/addons/sales_team/models/res_users.py index d5e657f2ce5..50b7e5cd28c 100644 --- a/addons/sales_team/models/res_users.py +++ b/addons/sales_team/models/res_users.py @@ -11,6 +11,12 @@ class ResUsers(models.Model): 'crm.team', 'Sales Team', help='Sales Channel the user is member of. Used to compute the members of a sales channel through the inverse one2many') + group_sales_team_user = fields.Selection( + selection=lambda self: self._get_group_selection('base.module_category_sales_management'), + string="Sales", compute='_compute_groups_id', inverse='_inverse_groups_id', + category_xml_id='base.module_category_sales_management', + help='User: Own Documents Only: the user will have access to his own data in the sales application.\nUser: All Documents: the user will have access to all records of everyone in the sales application.\nManager: the user will have an access to the sales configuration as well as statistic reports.') + @api.model def create(self, vals): # Assign the new user in the sales team if there's only one sales team of type `Sales` diff --git a/addons/sales_team/views/res_users_views.xml b/addons/sales_team/views/res_users_views.xml new file mode 100644 index 00000000000..2bdb98fe0a7 --- /dev/null +++ b/addons/sales_team/views/res_users_views.xml @@ -0,0 +1,14 @@ + + + + res.users.form.sales_team.inherit + res.users + + 1 + + + + + + + diff --git a/addons/stock/__manifest__.py b/addons/stock/__manifest__.py index 59a2c23e6d0..ed7e5f2d9ef 100644 --- a/addons/stock/__manifest__.py +++ b/addons/stock/__manifest__.py @@ -63,6 +63,7 @@ 'views/report_stock_traceability.xml', 'views/stock_template.xml', 'views/procurement_views.xml', + 'views/res_users_views.xml', 'data/default_barcode_patterns.xml', 'data/stock_data.xml', diff --git a/addons/stock/models/__init__.py b/addons/stock/models/__init__.py index af1550378ab..9741628e950 100644 --- a/addons/stock/models/__init__.py +++ b/addons/stock/models/__init__.py @@ -19,3 +19,4 @@ from . import stock_traceability from . import stock_warehouse from . import stock_scrap from . import product +from . import res_users diff --git a/addons/stock/models/res_users.py b/addons/stock/models/res_users.py new file mode 100644 index 00000000000..e6d1ccd5262 --- /dev/null +++ b/addons/stock/models/res_users.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = 'res.users' + + has_group_stock_multi_locations = fields.Boolean( + 'Manage Multiple Stock Locations', + compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='stock.group_stock_multi_locations') + + has_group_stock_multi_warehouses = fields.Boolean( + 'Manage Multiple Warehouses', + compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='stock.group_stock_multi_warehouses') + + has_group_production_lot = fields.Boolean( + 'Manage Lots / Serial Numbers', + compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='stock.group_production_lot') + + has_group_tracking_lot = fields.Boolean( + 'Manage Packages', + compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='stock.group_tracking_lot') + + has_group_adv_location = fields.Boolean( + 'Manage Push and Pull inventory flows', + compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='stock.group_adv_location') + + has_group_tracking_owner = fields.Boolean( + 'Manage Different Stock Owners', + compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='stock.group_tracking_owner') + + has_group_warning_stock = fields.Boolean( + 'A warning can be set on a partner (Stock)', + compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='stock.group_warning_stock') + + group_stock_user = fields.Selection( + selection=lambda self: self._get_group_selection('base.module_category_warehouse_management'), + string='Inventory', compute='_compute_groups_id', inverse='_inverse_groups_id', + category_xml_id='base.module_category_warehouse_management') diff --git a/addons/stock/views/res_users_views.xml b/addons/stock/views/res_users_views.xml new file mode 100644 index 00000000000..7d736825fc0 --- /dev/null +++ b/addons/stock/views/res_users_views.xml @@ -0,0 +1,44 @@ + + + + res.users.form.stock.inherit + res.users + + 15 + + + + + + + + + diff --git a/addons/survey/__manifest__.py b/addons/survey/__manifest__.py index 38fa932d670..78290313cbf 100644 --- a/addons/survey/__manifest__.py +++ b/addons/survey/__manifest__.py @@ -1,3 +1,4 @@ + # -*- encoding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. { @@ -23,6 +24,7 @@ sent mails with personal token for the invitation of the survey. 'views/survey_views.xml', 'views/survey_templates.xml', 'views/survey_result.xml', + 'views/res_users_views.xml', 'wizard/survey_email_compose_message.xml', 'data/survey_stages.xml', ], diff --git a/addons/survey/models/__init__.py b/addons/survey/models/__init__.py index 26edfafe8ad..1acf09ab8d1 100644 --- a/addons/survey/models/__init__.py +++ b/addons/survey/models/__init__.py @@ -3,3 +3,4 @@ from . import survey from . import ir_autovacuum +from . import res_users diff --git a/addons/survey/models/res_users.py b/addons/survey/models/res_users.py new file mode 100644 index 00000000000..939db447151 --- /dev/null +++ b/addons/survey/models/res_users.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = 'res.users' + + group_survey_user = fields.Selection( + selection=lambda self: self._get_group_selection('base.module_category_survey'), + string='Survey', compute='_compute_groups_id', inverse='_inverse_groups_id', + category_xml_id='base.module_category_survey') diff --git a/addons/survey/views/res_users_views.xml b/addons/survey/views/res_users_views.xml new file mode 100644 index 00000000000..dd60ccd8fae --- /dev/null +++ b/addons/survey/views/res_users_views.xml @@ -0,0 +1,14 @@ + + + + res.users.form.survey.inherit + res.users + + 115 + + + + + + + diff --git a/addons/uom/__manifest__.py b/addons/uom/__manifest__.py index 390682370b9..0ecdf757599 100644 --- a/addons/uom/__manifest__.py +++ b/addons/uom/__manifest__.py @@ -15,6 +15,7 @@ This is the base module for managing Units of measure. 'security/uom_security.xml', 'security/ir.model.access.csv', 'views/uom_uom_views.xml', + 'views/res_users_views.xml', ], 'installable': True, 'auto_install': False, diff --git a/addons/uom/models/__init__.py b/addons/uom/models/__init__.py index 357b0410c00..4b4c458ea60 100644 --- a/addons/uom/models/__init__.py +++ b/addons/uom/models/__init__.py @@ -2,3 +2,4 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from . import uom_uom +from . import res_users diff --git a/addons/uom/models/res_users.py b/addons/uom/models/res_users.py new file mode 100644 index 00000000000..8281b78ef14 --- /dev/null +++ b/addons/uom/models/res_users.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = 'res.users' + + has_group_uom = fields.Boolean( + 'Manage Multiple Units of Measure', compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='uom.group_uom') diff --git a/addons/uom/views/res_users_views.xml b/addons/uom/views/res_users_views.xml new file mode 100644 index 00000000000..55240233a6a --- /dev/null +++ b/addons/uom/views/res_users_views.xml @@ -0,0 +1,16 @@ + + + + res.users.form.uom.inherit + res.users + + + + + + + diff --git a/addons/website/__manifest__.py b/addons/website/__manifest__.py index fbedd44425b..119732b0257 100644 --- a/addons/website/__manifest__.py +++ b/addons/website/__manifest__.py @@ -27,6 +27,7 @@ 'views/website_views.xml', 'views/res_config_settings_views.xml', 'views/ir_actions_views.xml', + 'views/res_users_views.xml', 'wizard/base_language_install_views.xml', ], 'demo': [ diff --git a/addons/website/models/__init__.py b/addons/website/models/__init__.py index 750744ce7d1..ae4613baff0 100644 --- a/addons/website/models/__init__.py +++ b/addons/website/models/__init__.py @@ -12,3 +12,4 @@ from . import res_partner from . import res_config_settings from . import ir_model_fields from . import ir_model +from . import res_users diff --git a/addons/website/models/res_users.py b/addons/website/models/res_users.py new file mode 100644 index 00000000000..bab898d24c8 --- /dev/null +++ b/addons/website/models/res_users.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = 'res.users' + + group_website_user = fields.Selection( + selection=lambda self: self._get_group_selection('base.module_category_website'), + string='Website Editor', compute='_compute_groups_id', inverse='_inverse_groups_id', + category_xml_id='base.module_category_website') diff --git a/addons/website/views/res_users_views.xml b/addons/website/views/res_users_views.xml new file mode 100644 index 00000000000..80dfc371994 --- /dev/null +++ b/addons/website/views/res_users_views.xml @@ -0,0 +1,14 @@ + + + + res.users.form.website.inherit + res.users + + 135 + + + + + + + diff --git a/addons/website_forum/__manifest__.py b/addons/website_forum/__manifest__.py index a34afed27f9..d27dd595bce 100644 --- a/addons/website_forum/__manifest__.py +++ b/addons/website_forum/__manifest__.py @@ -20,7 +20,7 @@ Ask questions, get answers, no distractions 'data': [ 'data/forum_data.xml', 'views/forum.xml', - 'views/res_users.xml', + 'views/res_users_views.xml', 'views/website_forum.xml', 'views/ir_qweb.xml', 'security/ir.model.access.csv', diff --git a/addons/website_forum/views/res_users.xml b/addons/website_forum/views/res_users_views.xml similarity index 100% rename from addons/website_forum/views/res_users.xml rename to addons/website_forum/views/res_users_views.xml diff --git a/addons/website_mass_mailing/__manifest__.py b/addons/website_mass_mailing/__manifest__.py index ac3d34c0e1c..2b8f63808ff 100644 --- a/addons/website_mass_mailing/__manifest__.py +++ b/addons/website_mass_mailing/__manifest__.py @@ -16,6 +16,7 @@ Add a snippet in the website builder to subscribe a mass_mailing list 'views/snippets_templates.xml', 'views/mass_mailing_view.xml', 'views/res_config_settings_views.xml', + 'views/res_users_views.xml', ], 'auto_install': True, } diff --git a/addons/website_mass_mailing/models/__init__.py b/addons/website_mass_mailing/models/__init__.py index c9e39e466ca..d70758fc817 100644 --- a/addons/website_mass_mailing/models/__init__.py +++ b/addons/website_mass_mailing/models/__init__.py @@ -3,3 +3,4 @@ from . import res_config_settings from . import mass_mailing_list +from . import res_users diff --git a/addons/website_mass_mailing/models/res_users.py b/addons/website_mass_mailing/models/res_users.py new file mode 100644 index 00000000000..6024234dfb9 --- /dev/null +++ b/addons/website_mass_mailing/models/res_users.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class ResUsers(models.Model): + _inherit = 'res.users' + + has_group_website_popup_on_exit = fields.Boolean( + 'Use subscription pop up on the website', + compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='website_mass_mailing.group_website_popup_on_exit') diff --git a/addons/website_mass_mailing/views/res_users_views.xml b/addons/website_mass_mailing/views/res_users_views.xml new file mode 100644 index 00000000000..dc0b20a84f0 --- /dev/null +++ b/addons/website_mass_mailing/views/res_users_views.xml @@ -0,0 +1,16 @@ + + + + res.users.form.website_mass_mailing.inherit + res.users + + + + + + + diff --git a/odoo/addons/base/data/ir_module_category_data.xml b/odoo/addons/base/data/ir_module_category_data.xml index 2c5bfac3817..f31b210143f 100644 --- a/odoo/addons/base/data/ir_module_category_data.xml +++ b/odoo/addons/base/data/ir_module_category_data.xml @@ -171,11 +171,6 @@ 101 - - Other Extra Rights - 102 - - diff --git a/odoo/addons/base/data/res_users_demo.xml b/odoo/addons/base/data/res_users_demo.xml index aa632b5bac8..d5977f63173 100644 --- a/odoo/addons/base/data/res_users_demo.xml +++ b/odoo/addons/base/data/res_users_demo.xml @@ -72,6 +72,9 @@ + + + diff --git a/odoo/addons/base/models/res_users.py b/odoo/addons/base/models/res_users.py index 05c154bc466..9f9a1fa3281 100644 --- a/odoo/addons/base/models/res_users.py +++ b/odoo/addons/base/models/res_users.py @@ -230,6 +230,32 @@ class Users(models.Model): name = fields.Char(related='partner_id.name', inherited=True) email = fields.Char(related='partner_id.email', inherited=True) + group_base_user = fields.Selection( + selection=lambda self: self._get_group_selection('base.module_category_user_type'), + string="User type", compute='_compute_groups_id', inverse='_inverse_groups_id', + category_xml_id='base.module_category_user_type') + + group_administration_user = fields.Selection( + selection=lambda self: self._get_group_selection('base.module_category_administration'), + string="Administration", compute='_compute_groups_id', inverse='_inverse_groups_id', + category_xml_id='base.module_category_administration') + + has_group_multi_company = fields.Boolean( + 'Multi Companies', compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='base.group_multi_company') + + has_group_multi_currency = fields.Boolean( + 'Multi Currencies', compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='base.group_multi_currency') + + has_group_no_one = fields.Boolean( + 'Technical Features', compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='base.group_no_one') + + has_group_partner_manager = fields.Boolean( + 'Contact Creation', compute='_compute_groups_id', inverse='_inverse_groups_id', + group_xml_id='base.group_partner_manager') + _sql_constraints = [ ('login_key', 'UNIQUE (login)', 'You can not have two users with the same login !') ] @@ -330,6 +356,7 @@ class Users(models.Model): @api.model def create(self, vals): + # import pudb; pudb.set_trace() user = super(Users, self).create(vals) user.partner_id.active = user.active if user.partner_id.company_id: @@ -766,6 +793,7 @@ class GroupsImplied(models.Model): @api.multi def write(self, values): res = super(GroupsImplied, self).write(values) + if values.get('users') or values.get('implied_ids'): # add all implied groups (to all users of each group) for group in self: diff --git a/odoo/addons/base/views/res_users_views.xml b/odoo/addons/base/views/res_users_views.xml index 7cd872c966d..db9181ac2bf 100644 --- a/odoo/addons/base/views/res_users_views.xml +++ b/odoo/addons/base/views/res_users_views.xml @@ -141,11 +141,6 @@ - @@ -181,12 +176,36 @@ + + + - + + + + + + @@ -203,12 +222,27 @@ + + + + + - + + res.users.view.form.administration + res.users + + 1000 + + + + + + res.users.tree res.users @@ -268,16 +302,6 @@ - - res.users.groups - res.users - - - - - - - Users From bd49f9fd17aa6661945a3eff212ceabedf20efb8 Mon Sep 17 00:00:00 2001 From: Yannick Tivisse Date: Wed, 25 Apr 2018 15:46:05 +0200 Subject: [PATCH 5/6] [IMP] base: Remove the reified view on 'groups_id' in res_users' form Now all the group fields are defined on the res.users model. No need to generate a reified view according to the groups definitions. --- odoo/addons/base/models/res_users.py | 296 +-------------------------- 1 file changed, 5 insertions(+), 291 deletions(-) diff --git a/odoo/addons/base/models/res_users.py b/odoo/addons/base/models/res_users.py index 9f9a1fa3281..8664e70c556 100644 --- a/odoo/addons/base/models/res_users.py +++ b/odoo/addons/base/models/res_users.py @@ -26,48 +26,23 @@ USER_PRIVATE_FIELDS = ['password'] concat = chain.from_iterable # -# Functions for manipulating boolean and selection pseudo-fields +# Functions for manipulating boolean and selection fields # -def name_boolean_group(id): - return 'in_group_' + str(id) -def name_selection_groups(ids): - return 'sel_groups_' + '_'.join(str(it) for it in ids) def is_boolean_group(name): - return name.startswith('in_group_') + return name.startswith('has_group_') + def is_selection_groups(name): - return name.startswith('sel_groups_') + return name.startswith('group_') -def is_reified_group(name): - return is_boolean_group(name) or is_selection_groups(name) - -def get_boolean_group(name): - return int(name[9:]) - -def get_selection_groups(name): - return [int(v) for v in name[11:].split('_')] - -def parse_m2m(commands): - "return a list of ids corresponding to a many2many value" - ids = [] - for command in commands: - if isinstance(command, (tuple, list)): - if command[0] in (1, 4): - ids.append(command[1]) - elif command[0] == 5: - ids = [] - elif command[0] == 6: - ids = list(command[2]) - else: - ids.append(command) - return ids #---------------------------------------------------------- # Basic res.groups and res.users #---------------------------------------------------------- + class Groups(models.Model): _name = "res.groups" _description = "Access Groups" @@ -825,267 +800,6 @@ class UsersImplied(models.Model): super(UsersImplied, self).write(vals) return res -# -# Virtual checkbox and selection for res.user form view -# -# Extension of res.groups and res.users for the special groups view in the users -# form. This extension presents groups with selection and boolean widgets: -# - Groups are shown by application, with boolean and/or selection fields. -# Selection fields typically defines a role "Name" for the given application. -# - Uncategorized groups are presented as boolean fields and grouped in a -# section "Others". -# -# The user form view is modified by an inherited view (base.user_groups_view); -# the inherited view replaces the field 'groups_id' by a set of reified group -# fields (boolean or selection fields). The arch of that view is regenerated -# each time groups are changed. -# -# Naming conventions for reified groups fields: -# - boolean field 'in_group_ID' is True iff -# ID is in 'groups_id' -# - selection field 'sel_groups_ID1_..._IDk' is ID iff -# ID is in 'groups_id' and ID is maximal in the set {ID1, ..., IDk} -# - -class GroupsView(models.Model): - _inherit = 'res.groups' - - @api.model - def create(self, values): - user = super(GroupsView, self).create(values) - self._update_user_groups_view() - # actions.get_bindings() depends on action records - self.env['ir.actions.actions'].clear_caches() - return user - - @api.multi - def write(self, values): - res = super(GroupsView, self).write(values) - self._update_user_groups_view() - # actions.get_bindings() depends on action records - self.env['ir.actions.actions'].clear_caches() - return res - - @api.multi - def unlink(self): - res = super(GroupsView, self).unlink() - self._update_user_groups_view() - # actions.get_bindings() depends on action records - self.env['ir.actions.actions'].clear_caches() - return res - - @api.model - def _update_user_groups_view(self): - """ Modify the view with xmlid ``base.user_groups_view``, which inherits - the user form view, and introduces the reified group fields. - """ - if self._context.get('install_mode'): - # use installation/admin language for translatable names in the view - user_context = self.env['res.users'].context_get() - self = self.with_context(**user_context) - - # We have to try-catch this, because at first init the view does not - # exist but we are already creating some basic groups. - view = self.env.ref('base.user_groups_view', raise_if_not_found=False) - if view and view.exists() and view._name == 'ir.ui.view': - group_no_one = view.env.ref('base.group_no_one') - xml1, xml2 = [], [] - xml1.append(E.separator(string=_('Application Accesses'), colspan="2")) - for app, kind, gs in self.get_groups_by_application(): - # hide groups in categories 'Hidden' and 'Extra' (except for group_no_one) - attrs = {} - if app.xml_id in ('base.module_category_hidden', 'base.module_category_extra', 'base.module_category_usability'): - attrs['groups'] = 'base.group_no_one' - - if kind == 'selection': - # application name with a selection field - field_name = name_selection_groups(gs.ids) - xml1.append(E.field(name=field_name, **attrs)) - xml1.append(E.newline()) - else: - # application separator with boolean fields - app_name = app.name or _('Other') - xml2.append(E.separator(string=app_name, colspan="4", **attrs)) - for g in gs: - field_name = name_boolean_group(g.id) - if g == group_no_one: - # make the group_no_one invisible in the form view - xml2.append(E.field(name=field_name, invisible="1", **attrs)) - else: - xml2.append(E.field(name=field_name, **attrs)) - - xml2.append({'class': "o_label_nowrap"}) - xml = E.field(E.group(*(xml1), col="2"), E.group(*(xml2), col="4"), name="groups_id", position="replace") - xml.addprevious(etree.Comment("GENERATED AUTOMATICALLY BY GROUPS")) - xml_content = etree.tostring(xml, pretty_print=True, encoding="unicode") - - new_context = dict(view._context) - new_context.pop('install_mode_data', None) # don't set arch_fs for this computed view - new_context['lang'] = None - view.with_context(new_context).write({'arch': xml_content}) - - def get_application_groups(self, domain): - """ Return the non-share groups that satisfy ``domain``. """ - return self.search(domain + [('share', '=', False)]) - - @api.model - def get_groups_by_application(self): - """ Return all groups classified by application (module category), as a list:: - - [(app, kind, groups), ...], - - where ``app`` and ``groups`` are recordsets, and ``kind`` is either - ``'boolean'`` or ``'selection'``. Applications are given in sequence - order. If ``kind`` is ``'selection'``, ``groups`` are given in - reverse implication order. - """ - def linearize(app, gs): - # determine sequence order: a group appears after its implied groups - order = {g: len(g.trans_implied_ids & gs) for g in gs} - # check whether order is total, i.e., sequence orders are distinct - if len(set(order.values())) == len(gs): - return (app, 'selection', gs.sorted(key=order.get)) - else: - return (app, 'boolean', gs) - - # classify all groups by application - by_app, others = defaultdict(self.browse), self.browse() - for g in self.get_application_groups([]): - if g.category_id: - by_app[g.category_id] += g - else: - others += g - # build the result - res = [] - for app, gs in sorted(by_app.items(), key=lambda it: it[0].sequence or 0): - res.append(linearize(app, gs)) - if others: - res.append((self.env['ir.module.category'], 'boolean', others)) - return res - - -class UsersView(models.Model): - _inherit = 'res.users' - - @api.model - def create(self, values): - values = self._remove_reified_groups(values) - user = super(UsersView, self).create(values) - group_multi_company = self.env.ref('base.group_multi_company', False) - if group_multi_company and 'company_ids' in values: - if len(user.company_ids) <= 1 and user.id in group_multi_company.users.ids: - group_multi_company.write({'users': [(3, user.id)]}) - elif len(user.company_ids) > 1 and user.id not in group_multi_company.users.ids: - group_multi_company.write({'users': [(4, user.id)]}) - return user - - @api.multi - def write(self, values): - values = self._remove_reified_groups(values) - res = super(UsersView, self).write(values) - group_multi_company = self.env.ref('base.group_multi_company', False) - if group_multi_company and 'company_ids' in values: - for user in self: - if len(user.company_ids) <= 1 and user.id in group_multi_company.users.ids: - group_multi_company.write({'users': [(3, user.id)]}) - elif len(user.company_ids) > 1 and user.id not in group_multi_company.users.ids: - group_multi_company.write({'users': [(4, user.id)]}) - return res - - def _remove_reified_groups(self, values): - """ return `values` without reified group fields """ - add, rem = [], [] - values1 = {} - - for key, val in values.items(): - if is_boolean_group(key): - (add if val else rem).append(get_boolean_group(key)) - elif is_selection_groups(key): - rem += get_selection_groups(key) - if val: - add.append(val) - else: - values1[key] = val - - if 'groups_id' not in values and (add or rem): - # remove group ids in `rem` and add group ids in `add` - values1['groups_id'] = list(itertools.chain( - pycompat.izip(repeat(3), rem), - pycompat.izip(repeat(4), add) - )) - - return values1 - - @api.model - def default_get(self, fields): - group_fields, fields = partition(is_reified_group, fields) - fields1 = (fields + ['groups_id']) if group_fields else fields - values = super(UsersView, self).default_get(fields1) - self._add_reified_groups(group_fields, values) - return values - - @api.multi - def read(self, fields=None, load='_classic_read'): - # determine whether reified groups fields are required, and which ones - fields1 = fields or list(self.fields_get()) - group_fields, other_fields = partition(is_reified_group, fields1) - - # read regular fields (other_fields); add 'groups_id' if necessary - drop_groups_id = False - if group_fields and fields: - if 'groups_id' not in other_fields: - other_fields.append('groups_id') - drop_groups_id = True - else: - other_fields = fields - - res = super(UsersView, self).read(other_fields, load=load) - - # post-process result to add reified group fields - if group_fields: - for values in res: - self._add_reified_groups(group_fields, values) - if drop_groups_id: - values.pop('groups_id', None) - return res - - def _add_reified_groups(self, fields, values): - """ add the given reified group fields into `values` """ - gids = set(parse_m2m(values.get('groups_id') or [])) - for f in fields: - if is_boolean_group(f): - values[f] = get_boolean_group(f) in gids - elif is_selection_groups(f): - selected = [gid for gid in get_selection_groups(f) if gid in gids] - values[f] = selected and selected[-1] or False - - @api.model - def fields_get(self, allfields=None, attributes=None): - res = super(UsersView, self).fields_get(allfields, attributes=attributes) - # add reified groups fields - for app, kind, gs in self.env['res.groups'].sudo().get_groups_by_application(): - if kind == 'selection': - # selection group field - tips = ['%s: %s' % (g.name, g.comment) for g in gs if g.comment] - res[name_selection_groups(gs.ids)] = { - 'type': 'selection', - 'string': app.name or _('Other'), - 'selection': [(False, '')] + [(g.id, g.name) for g in gs], - 'help': '\n'.join(tips), - 'exportable': False, - 'selectable': False, - } - else: - # boolean group fields - for g in gs: - res[name_boolean_group(g.id)] = { - 'type': 'boolean', - 'string': g.name, - 'help': g.comment, - 'exportable': False, - 'selectable': False, - } - return res #---------------------------------------------------------- # change password wizard From 382fbd35204ff947c16b795ca090c97d6741fb1d Mon Sep 17 00:00:00 2001 From: Yannick Tivisse Date: Wed, 25 Apr 2018 16:08:57 +0200 Subject: [PATCH 6/6] [IMP] base: Remove unused module categories The categories other extra rigths and hidden are not used now. --- addons/account/security/account_security.xml | 3 --- .../analytic/security/analytic_security.xml | 2 -- addons/crm/security/crm_security.xml | 1 - .../security/hr_attendance_security.xml | 1 - .../security/mass_mailing_security.xml | 1 - addons/mrp/security/mrp_security.xml | 1 - addons/product/security/product_security.xml | 5 ---- addons/project/security/project_security.xml | 2 -- .../purchase/security/purchase_security.xml | 2 -- addons/sale/security/sale_security.xml | 7 ----- .../security/sale_stock_security.xml | 6 ++--- addons/stock/security/stock_security.xml | 7 ----- addons/uom/security/uom_security.xml | 1 - .../security/mass_mailing_security.xml | 1 - .../models/ir_module_module.py | 3 +-- addons/website_theme_install/views/views.xml | 2 +- .../base/data/ir_module_category_data.xml | 27 ------------------- 17 files changed, 4 insertions(+), 68 deletions(-) diff --git a/addons/account/security/account_security.xml b/addons/account/security/account_security.xml index b0ca871d10c..6e6d9ce21ce 100644 --- a/addons/account/security/account_security.xml +++ b/addons/account/security/account_security.xml @@ -10,7 +10,6 @@ Show Full Accounting Features - @@ -29,12 +28,10 @@ A warning can be set on a partner (Account) - Allow the cash rounding management - diff --git a/addons/analytic/security/analytic_security.xml b/addons/analytic/security/analytic_security.xml index 5e66d317f5c..30f813f4a19 100644 --- a/addons/analytic/security/analytic_security.xml +++ b/addons/analytic/security/analytic_security.xml @@ -34,12 +34,10 @@ Analytic Accounting - Analytic Accounting Tags - diff --git a/addons/crm/security/crm_security.xml b/addons/crm/security/crm_security.xml index 83f3197a5b1..5a0fa127698 100644 --- a/addons/crm/security/crm_security.xml +++ b/addons/crm/security/crm_security.xml @@ -5,7 +5,6 @@ Show Lead Menu - diff --git a/addons/hr_attendance/security/hr_attendance_security.xml b/addons/hr_attendance/security/hr_attendance_security.xml index 2f39cd13d21..6b903e890f9 100644 --- a/addons/hr_attendance/security/hr_attendance_security.xml +++ b/addons/hr_attendance/security/hr_attendance_security.xml @@ -34,7 +34,6 @@ Enable PIN use - The user will have to enter his PIN to check in and out manually at the company screen. diff --git a/addons/mass_mailing/security/mass_mailing_security.xml b/addons/mass_mailing/security/mass_mailing_security.xml index 823a9a4f4b5..308e02956ef 100644 --- a/addons/mass_mailing/security/mass_mailing_security.xml +++ b/addons/mass_mailing/security/mass_mailing_security.xml @@ -10,7 +10,6 @@ Manage Mass Mailing Campaigns - diff --git a/addons/mrp/security/mrp_security.xml b/addons/mrp/security/mrp_security.xml index 35d843b9aeb..d203cfc73c1 100644 --- a/addons/mrp/security/mrp_security.xml +++ b/addons/mrp/security/mrp_security.xml @@ -17,7 +17,6 @@ Manage Work Order Operations - diff --git a/addons/product/security/product_security.xml b/addons/product/security/product_security.xml index 422d7ac75ec..08fec11f11c 100644 --- a/addons/product/security/product_security.xml +++ b/addons/product/security/product_security.xml @@ -4,27 +4,22 @@ Sales Pricelists - Manage Pricelist Items - Pricelists On Product - Manage Product Packaging - Manage Product Variants - diff --git a/addons/project/security/project_security.xml b/addons/project/security/project_security.xml index cfa175258f9..a34f32e7393 100644 --- a/addons/project/security/project_security.xml +++ b/addons/project/security/project_security.xml @@ -16,12 +16,10 @@ Use Subtasks - Use Rating on Project - diff --git a/addons/purchase/security/purchase_security.xml b/addons/purchase/security/purchase_security.xml index 75fbca272f6..b2d8e241ba7 100644 --- a/addons/purchase/security/purchase_security.xml +++ b/addons/purchase/security/purchase_security.xml @@ -17,12 +17,10 @@ Manage Vendor Price - A warning can be set on a product or a customer (Purchase) - diff --git a/addons/sale/security/sale_security.xml b/addons/sale/security/sale_security.xml index 8936079df73..881b462b14e 100644 --- a/addons/sale/security/sale_security.xml +++ b/addons/sale/security/sale_security.xml @@ -3,23 +3,19 @@ Personalize sales order and invoice report - Addresses in Sales Orders - Tax display B2B - Show line subtotals without taxes (B2B) Tax display B2C - Show line subtotals with taxes included (B2C) @@ -37,17 +33,14 @@ Discount on lines - A warning can be set on a product or a customer (Sale) - Pro-forma Invoices - diff --git a/addons/sale_stock/security/sale_stock_security.xml b/addons/sale_stock/security/sale_stock_security.xml index 630a6512b2d..72c18b01594 100644 --- a/addons/sale_stock/security/sale_stock_security.xml +++ b/addons/sale_stock/security/sale_stock_security.xml @@ -3,12 +3,10 @@ Enable Route on Sales Order Line - - + Display incoterms on Sales Order and related invoices - - + diff --git a/addons/stock/security/stock_security.xml b/addons/stock/security/stock_security.xml index 3301a5fbb8c..153b39dd9e4 100644 --- a/addons/stock/security/stock_security.xml +++ b/addons/stock/security/stock_security.xml @@ -4,12 +4,10 @@ Manage Multiple Stock Locations - Manage Multiple Warehouses - @@ -26,27 +24,22 @@ Manage Lots / Serial Numbers - Manage Packages - Manage Push and Pull inventory flows - Manage Different Stock Owners - A warning can be set on a partner (Stock) - diff --git a/addons/uom/security/uom_security.xml b/addons/uom/security/uom_security.xml index ebfe3e1178d..f7e0c0dd4d4 100644 --- a/addons/uom/security/uom_security.xml +++ b/addons/uom/security/uom_security.xml @@ -3,7 +3,6 @@ Manage Multiple Units of Measure - diff --git a/addons/website_mass_mailing/security/mass_mailing_security.xml b/addons/website_mass_mailing/security/mass_mailing_security.xml index 1f1438fcab3..95c9d4d56bb 100644 --- a/addons/website_mass_mailing/security/mass_mailing_security.xml +++ b/addons/website_mass_mailing/security/mass_mailing_security.xml @@ -2,6 +2,5 @@ Use subscription pop up on the website - diff --git a/addons/website_theme_install/models/ir_module_module.py b/addons/website_theme_install/models/ir_module_module.py index 0ceea66f159..5350abea437 100644 --- a/addons/website_theme_install/models/ir_module_module.py +++ b/addons/website_theme_install/models/ir_module_module.py @@ -43,11 +43,10 @@ class IrModuleModule(models.Model): @api.multi def button_choose_theme(self): theme_category = self.env.ref('base.module_category_theme', False) - hidden_category = self.env.ref('base.module_category_hidden', False) theme_hidden_category = self.env.ref('base.module_category_theme_hidden', False) theme_category_id = theme_category.id if theme_category else 0 - hidden_categories_ids = [hidden_category.id if hidden_category else 0, theme_hidden_category.id if theme_hidden_category else 0] + hidden_categories_ids = [theme_hidden_category.id if theme_hidden_category else 0] self.search([ # Uninstall the theme(s) which is (are) installed ('state', '=', 'installed'), diff --git a/addons/website_theme_install/views/views.xml b/addons/website_theme_install/views/views.xml index ed9b393ddf6..f080ee96005 100644 --- a/addons/website_theme_install/views/views.xml +++ b/addons/website_theme_install/views/views.xml @@ -67,7 +67,7 @@ diff --git a/odoo/addons/base/data/ir_module_category_data.xml b/odoo/addons/base/data/ir_module_category_data.xml index f31b210143f..aaf28c0bb86 100644 --- a/odoo/addons/base/data/ir_module_category_data.xml +++ b/odoo/addons/base/data/ir_module_category_data.xml @@ -1,12 +1,6 @@ - - Technical Settings - 0 - - - Localization @@ -166,11 +160,6 @@ 100 - - Extra Rights - 101 - - @@ -183,18 +172,6 @@ - - - - - - - - - - - - @@ -203,9 +180,5 @@ - - - -