diff --git a/jikimo_hide_options/__init__.py b/jikimo_hide_options/__init__.py new file mode 100644 index 00000000..c5145b22 --- /dev/null +++ b/jikimo_hide_options/__init__.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +from . import models +from odoo import api, SUPERUSER_ID + + +def uninstall_hook(cr, registry): + # 使用cr来执行数据库操作 + with api.Environment.manage(): + env = api.Environment(cr, SUPERUSER_ID, {}) + # 执行数据清理操作 + access_rights = env['access.right'].search([]) + access_rights.unlink() + followers = env['mail.followers'].search([('res_model', '=', 'access.right')]) + followers.unlink() diff --git a/jikimo_hide_options/__manifest__.py b/jikimo_hide_options/__manifest__.py new file mode 100644 index 00000000..6a4c41a8 --- /dev/null +++ b/jikimo_hide_options/__manifest__.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +{ + 'name': '机企猫 隐藏项目', + 'version': '16.0.1.0.0', + 'category': 'Extra Tools, Productivity', + 'summary': """ Can hide options from user """, + 'description': """ By using this module we can hide the options like create, + delete,export,and archive/un archive in the model which we want. Here we + are also able to select the user groups except Administrator which we want + to apply the above hiding functionality """, + 'author': '机企猫-MGW', + 'company': '机企猫', + 'depends': ['base_setup', 'mail'], + 'data': [ + 'security/security.xml', + 'security/ir.model.access.csv', + 'views/model_access_rights_views.xml', + ], + 'assets': { + 'web.assets_backend': [ + 'jikimo_hide_options/static/src/js/form_controller.js', + 'jikimo_hide_options/static/src/js/list_controller.js', + 'jikimo_hide_options/static/src/js/kanban_controller.js' + ] + }, + 'images': ['static/description/banner.jpg'], + 'license': 'LGPL-3', + 'installable': True, + 'auto_install': False, + 'application': False, + 'uninstall_hook': 'uninstall_hook', +} diff --git a/jikimo_hide_options/models/__init__.py b/jikimo_hide_options/models/__init__.py new file mode 100644 index 00000000..0950faaf --- /dev/null +++ b/jikimo_hide_options/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +from . import model_access_rights +from . import models + diff --git a/jikimo_hide_options/models/model_access_rights.py b/jikimo_hide_options/models/model_access_rights.py new file mode 100644 index 00000000..ca808557 --- /dev/null +++ b/jikimo_hide_options/models/model_access_rights.py @@ -0,0 +1,107 @@ +# -*- coding: utf-8 -*- +from odoo import api, fields, models, _ + + +class ModelAccessRights(models.Model): + """This class is used to detect, which all options want to hide from the + specified group and model""" + _name = 'access.right' + _inherit = 'mail.thread' + _description = 'Manage Modules Access Control' + _rec_name = 'model_id' + + model_id = fields.Many2one('ir.model', ondelete='cascade', required=True, + help="select the model") + groups_id = fields.Many2one('res.groups', required=True, + help="select the group") + is_delete = fields.Boolean(string="Delete", help="hide the delete option") + is_export = fields.Boolean(string="Export", + help="hide the 'Export All'" + " option from list view") + is_create_or_update = fields.Boolean(string="Create/Update", + help="hide the create option from list" + " as well as form view") + is_archive = fields.Boolean(string="Archive/UnArchive", + help="hide the archive option") + + @api.model + def hide_buttons(self): + """This function contains a query that detects which all options want + to hide, in which model,and to which user groups""" + access_right_rec = self.sudo().search_read([], ['model_id', 'is_delete', + 'is_export', + 'is_create_or_update', + 'is_archive', + 'groups_id']) + for dic in access_right_rec: + model = self.env['ir.model'].sudo().browse(dic['model_id'][0]).model + group_name = self.env['ir.model.data'].sudo().search([ + ('model', '=', 'res.groups'), + ('res_id', '=', dic['groups_id'][0]) + ]).name + + module_name = self.env['ir.model.data'].sudo().search([ + ('model', '=', 'res.groups'), + ('res_id', '=', dic['groups_id'][0]) + ]).module + dic.update({ + 'model': model, + 'group_name': group_name, + 'module': module_name + }) + return access_right_rec + # @api.model + # def hide_buttons(self): + # """This function contains a query that detects which all options want + # to hide, in which model,and to which user groups""" + # access_right_rec = self.sudo().search_read([], ['model_id', 'is_delete', + # 'is_export', + # 'is_create_or_update', + # 'is_archive', + # 'groups_id']) + # for dic in access_right_rec: + # model = self.env['ir.model'].sudo().browse(dic['model_id']).model + # group_name = self.env['ir.model.data'].sudo().search([ + # ('model', '=', 'res.groups'), + # ('res_id', '=', dic['groups_id']) + # ]).name + # module_name = self.env['ir.model.data'].sudo().search([ + # ('model', '=', 'res.groups'), + # ('res_id', '=', dic['groups_id']) + # ]).module + # dic.update({ + # 'model': model, + # 'group_name': group_name, + # 'module': module_name + # }) + # return access_right_rec + + +# class AccessRightCleanup(models.Model): +# _name = 'access.right.cleanup' # 定义一个新的模型名 +# _description = 'Access Right Cleanup' + + + + # @api.model + # def _module_uninstall(self): + # """在模块卸载时执行清理操作""" + # super(AccessRightCleanup, self)._module_uninstall() + # # 这里执行你的清理逻辑 + # + # # 获取access.right模型的所有记录 + # access_rights = self.env['access.right'].search([]) + # for access_right in access_rights: + # # 删除access.right模型的所有记录 + # access_right.unlink() + # + # # 查找所有关联到access.right模型的关注者记录 + # followers = self.env['mail.followers'].search([('res_model', '=', 'access.right')]) + # for follower in followers: + # # 删除关注者记录 + # follower.unlink() + # + # # # 示例:删除自定义数据表(确保先检查外键约束等) + # # self.env.cr.execute('DROP TABLE IF EXISTS access_right CASCADE;') + # + # # 其他清理工作... diff --git a/jikimo_hide_options/models/models.py b/jikimo_hide_options/models/models.py new file mode 100644 index 00000000..72046dca --- /dev/null +++ b/jikimo_hide_options/models/models.py @@ -0,0 +1,353 @@ +# -*- coding: utf-8 -*- +from collections import defaultdict +from operator import attrgetter +from odoo import api, _ +from odoo.exceptions import UserError +from odoo.models import BaseModel, _unlink, LOG_ACCESS_COLUMNS, \ + INSERT_BATCH_SIZE, SQL_DEFAULT +# from odoo.tools import OrderedSet, split_every, attrgetter, clean_context +from odoo.tools import OrderedSet, split_every, clean_context + + +@api.model +def _create(self, data_list): + """ Create records from the stored field values in ``data_list``. """ + assert data_list + cr = self.env.cr + + # insert rows in batches of maximum INSERT_BATCH_SIZE + ids = [] # ids of created records + other_fields = OrderedSet() # non-column fields + + for data_sublist in split_every(INSERT_BATCH_SIZE, data_list): + stored_list = [data['stored'] for data in data_sublist] + fnames = sorted({name for stored in stored_list for name in stored}) + + columns = [] + rows = [[] for _ in stored_list] + for fname in fnames: + field = self._fields[fname] + if field.column_type: + columns.append(fname) + for stored, row in zip(stored_list, rows): + if fname in stored: + colval = field.convert_to_column(stored[fname], self, + stored) + if field.translate is True and colval: + if 'en_US' not in colval.adapted: + colval.adapted['en_US'] = next( + iter(colval.adapted.values())) + row.append(colval) + else: + row.append(SQL_DEFAULT) + else: + other_fields.add(field) + + if field.type == 'properties': + # force calling fields.create for properties field because + # we might want to update the parent definition + other_fields.add(field) + + if not columns: + # manage the case where we create empty records + columns = ['id'] + for row in rows: + row.append(SQL_DEFAULT) + + header = ", ".join(f'"{column}"' for column in columns) + template = ", ".join("%s" for _ in rows) + cr.execute( + f'INSERT INTO "{self._table}" ({header}) VALUES {template} RETURNING "id"', + [tuple(row) for row in rows], + ) + ids.extend(id_ for id_, in cr.fetchall()) + + # put the new records in cache, and update inverse fields, for many2one + # + # cachetoclear is an optimization to avoid modified()'s cost until other_fields are processed + cachetoclear = [] + records = self.browse(ids) + inverses_update = defaultdict(list) # {(field, value): ids} + common_set_vals = set( + LOG_ACCESS_COLUMNS + [self.CONCURRENCY_CHECK_FIELD, 'id', + 'parent_path']) + for data, record in zip(data_list, records): + data['record'] = record + # DLE P104: test_inherit.py, test_50_search_one2many + vals = dict( + {k: v for d in data['inherited'].values() for k, v in d.items()}, + **data['stored']) + set_vals = common_set_vals.union(vals) + for field in self._fields.values(): + if field.type in ('one2many', 'many2many'): + self.env.cache.set(record, field, ()) + elif field.related and not field.column_type: + self.env.cache.set(record, field, + field.convert_to_cache(None, record)) + # DLE P123: `test_adv_activity`, `test_message_assignation_inbox`, `test_message_log`, `test_create_mail_simple`, ... + # Set `mail.message.parent_id` to False in cache so it doesn't do the useless SELECT when computing the modified of `child_ids` + # in other words, if `parent_id` is not set, no other message `child_ids` are impacted. + # + avoid the fetch of fields which are False. e.g. if a boolean field is not passed in vals and as no default set in the field attributes, + # then we know it can be set to False in the cache in the case of a create. + elif field.name not in set_vals and not field.compute: + self.env.cache.set(record, field, + field.convert_to_cache(None, record)) + for fname, value in vals.items(): + field = self._fields[fname] + if field.type in ('one2many', 'many2many'): + cachetoclear.append((record, field)) + else: + cache_value = field.convert_to_cache(value, record) + self.env.cache.set(record, field, cache_value) + if field.type in ('many2one', 'many2one_reference') and \ + self.pool.field_inverses[field]: + inverses_update[(field, cache_value)].append(record.id) + + for (field, value), record_ids in inverses_update.items(): + field._update_inverses(self.browse(record_ids), value) + + # update parent_path + records._parent_store_create() + + # protect fields being written against recomputation + protected = [(data['protected'], data['record']) for data in data_list] + with self.env.protecting(protected): + # mark computed fields as todo + records.modified(self._fields, create=True) + + if other_fields: + # discard default values from context for other fields + others = records.with_context(clean_context(self._context)) + for field in sorted(other_fields, key=attrgetter('_sequence')): + field.create([ + (other, data['stored'][field.name]) + for other, data in zip(others, data_list) + if field.name in data['stored'] + ]) + + # mark fields to recompute + records.modified([field.name for field in other_fields], + create=True) + + # if value in cache has not been updated by other_fields, remove it + for record, field in cachetoclear: + if self.env.cache.contains(record, + field) and not self.env.cache.get( + record, field): + self.env.cache.remove(record, field) + + # check Python constraints for stored fields + records._validate_fields( + name for data in data_list for name in data['stored']) + records.check_access_rule('create') + # This is used to restrict the access right to create a record + current_model_id = self.env['ir.model'].sudo().search( + [('model', '=', self._name)]).id + # access_right_rec = self.env['access.right'].sudo().search_read( + # [('model_id', '=', current_model_id)], + # ['model_id', 'is_create_or_update', + # 'groups_id']) + # if access_right_rec and not self.env.is_admin(): + # for rec in access_right_rec: + # group_name = self.env['ir.model.data'].sudo().search([ + # ('model', '=', 'res.groups'), + # ('res_id', '=', rec['groups_id'][0]) + # ]).name + # module_name = self.env['ir.model.data'].sudo().search([ + # ('model', '=', 'res.groups'), + # ('res_id', '=', rec['groups_id'][0]) + # ]).module + # group = module_name + "." + group_name + # if self.env.user.has_group(group): + # if rec['is_create_or_update']: + # raise UserError('You are restricted from performing this' + # ' operation. Please contact the' + # ' administrator.') + # 检查 'access.right' 模型是否存在于环境中 + if 'access.right' in self.env: + access_right_rec = self.env['access.right'].sudo().search_read( + [('model_id', '=', current_model_id)], + ['model_id', 'is_create_or_update', 'groups_id'] + ) + + # 如果找到相关记录,并且当前用户不是管理员 + if access_right_rec and not self.env.is_admin(): + for rec in access_right_rec: + # 获取与权限相关的用户组信息 + group_data = self.env['ir.model.data'].sudo().search_read( + [('model', '=', 'res.groups'), ('res_id', '=', rec['groups_id'][0])], + ['name', 'module'] + ) + + # 如果找到了用户组数据 + if group_data: + group_name = group_data[0]['name'] + module_name = group_data[0]['module'] + group_xml_id = f"{module_name}.{group_name}" + + # 检查当前用户是否属于该组 + if self.env.user.has_group(group_xml_id): + # 如果该用户组被限制创建或更新操作 + if rec['is_create_or_update']: + raise UserError( + _("You are restricted from performing this operation. Please contact the administrator.")) + else: + # 如果 'access.right' 模型不存在,可以在这里定义备选逻辑 + # 例如,记录日志、发送通知或者简单地跳过这部分逻辑 + pass + + return records + + +@api.model +def unlink(self): + """ unlink() + + Deletes the records in ``self``. + + :raise AccessError: if the user is not allowed to delete all the given records + :raise UserError: if the record is default property for other records + """ + if not self: + return True + + self.check_access_rights('unlink') + self.check_access_rule('unlink') + + from odoo.addons.base.models.ir_model import MODULE_UNINSTALL_FLAG + for func in self._ondelete_methods: + # func._ondelete is True if it should be called during uninstallation + if func._ondelete or not self._context.get(MODULE_UNINSTALL_FLAG): + func(self) + + # TOFIX: this avoids an infinite loop when trying to recompute a + # field, which triggers the recomputation of another field using the + # same compute function, which then triggers again the computation + # of those two fields + for field in self._fields.values(): + self.env.remove_to_compute(field, self) + + self.env.flush_all() + + cr = self._cr + Data = self.env['ir.model.data'].sudo().with_context({}) + Defaults = self.env['ir.default'].sudo() + Property = self.env['ir.property'].sudo() + Attachment = self.env['ir.attachment'].sudo() + ir_property_unlink = Property + ir_model_data_unlink = Data + ir_attachment_unlink = Attachment + + # mark fields that depend on 'self' to recompute them after 'self' has + # been deleted (like updating a sum of lines after deleting one line) + with self.env.protecting(self._fields.values(), self): + self.modified(self._fields, before=True) + for sub_ids in cr.split_for_in_conditions(self.ids): + records = self.browse(sub_ids) + + # Check if the records are used as default properties. + refs = [f'{self._name},{id_}' for id_ in sub_ids] + if Property.search( + [('res_id', '=', False), ('value_reference', 'in', refs)], + limit=1): + raise UserError( + _('Unable to delete this document because it is used as a default property')) + + # Delete the records' properties. + ir_property_unlink |= Property.search([('res_id', 'in', refs)]) + + query = f'DELETE FROM "{self._table}" WHERE id IN %s' + cr.execute(query, (sub_ids,)) + + # Removing the ir_model_data reference if the record being deleted + # is a record created by xml/csv file, as these are not connected + # with real database foreign keys, and would be dangling references. + # + # Note: the following steps are performed as superuser to avoid + # access rights restrictions, and with no context to avoid possible + # side-effects during admin calls. + data = Data.search( + [('model', '=', self._name), ('res_id', 'in', sub_ids)]) + ir_model_data_unlink |= data + + # For the same reason, remove the defaults having some of the + # records as value + Defaults.discard_records(records) + + # For the same reason, remove the relevant records in ir_attachment + # (the search is performed with sql as the search method of + # ir_attachment is overridden to hide attachments of deleted + # records) + query = 'SELECT id FROM ir_attachment WHERE res_model=%s AND res_id IN %s' + cr.execute(query, (self._name, sub_ids)) + ir_attachment_unlink |= Attachment.browse( + row[0] for row in cr.fetchall()) + + # invalidate the *whole* cache, since the orm does not handle all + # changes made in the database, like cascading delete! + self.env.invalidate_all(flush=False) + if ir_property_unlink: + ir_property_unlink.unlink() + if ir_model_data_unlink: + ir_model_data_unlink.unlink() + if ir_attachment_unlink: + ir_attachment_unlink.unlink() + # DLE P93: flush after the unlink, for recompute fields depending on + # the modified of the unlink + self.env.flush_all() + # auditing: deletions are infrequent and leave no trace in the database + _unlink.info('User #%s deleted %s records with IDs: %r', self._uid, + self._name, self.ids) + # This is used to restrict the access right to unlink a record + current_model_id = self.env['ir.model'].sudo().search( + [('model', '=', self._name)]).id + # access_right_rec = self.env['access.right'].sudo().search_read( + # [('model_id', '=', current_model_id)], ['model_id', 'is_delete', + # 'groups_id']) + # if access_right_rec and not self.env.is_admin(): + # for rec in access_right_rec: + # group_name = self.env['ir.model.data'].sudo().search([ + # ('model', '=', 'res.groups'), + # ('res_id', '=', rec['groups_id'][0]) + # ]).name + # module_name = self.env['ir.model.data'].sudo().search([ + # ('model', '=', 'res.groups'), + # ('res_id', '=', rec['groups_id'][0]) + # ]).module + # group = module_name + "." + group_name + # if self.env.user.has_group(group): + # if rec['is_delete']: + # raise UserError(_('You are restricted from performing this' + # ' operation. Please contact the' + # ' administrator.')) + # 检查 'access.right' 模型是否存在于环境中 + if 'access.right' in self.env: + # current_model_id = self.env['ir.model'].sudo().search([('model', '=', self._name)]).id + access_right_rec = self.env['access.right'].sudo().search_read( + [('model_id', '=', current_model_id)], ['model_id', 'is_delete', 'groups_id'] + ) + + if access_right_rec and not self.env.is_admin(): + for rec in access_right_rec: + group_data = self.env['ir.model.data'].sudo().search_read( + [('model', '=', 'res.groups'), ('res_id', '=', rec['groups_id'][0])], + ['name', 'module'] + ) + + if group_data: + group_name = group_data[0]['name'] + module_name = group_data[0]['module'] + group_xml_id = f"{module_name}.{group_name}" + + if self.env.user.has_group(group_xml_id) and rec['is_delete']: + raise UserError( + _('You are restricted from performing this operation. Please contact the administrator.')) + else: + # 如果 'access.right' 模型不存在,可以在这里定义备选逻辑 + pass + + return True + + +BaseModel._create = _create +BaseModel.unlink = unlink diff --git a/jikimo_hide_options/security/ir.model.access.csv b/jikimo_hide_options/security/ir.model.access.csv new file mode 100644 index 00000000..ec0f6f88 --- /dev/null +++ b/jikimo_hide_options/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink +access_access_right,access.access.right,model_access_right,jikimo_hide_options.model_access_rights_groups_configure_model_access,1,1,1,1 diff --git a/jikimo_hide_options/security/security.xml b/jikimo_hide_options/security/security.xml new file mode 100644 index 00000000..23a2b818 --- /dev/null +++ b/jikimo_hide_options/security/security.xml @@ -0,0 +1,9 @@ + + + + + 配置隐藏项目 + + + + diff --git a/jikimo_hide_options/static/description/assets/icons/check.png b/jikimo_hide_options/static/description/assets/icons/check.png new file mode 100644 index 00000000..c8e85f51 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/check.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/chevron.png b/jikimo_hide_options/static/description/assets/icons/chevron.png new file mode 100644 index 00000000..2089293d Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/chevron.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/cogs.png b/jikimo_hide_options/static/description/assets/icons/cogs.png new file mode 100644 index 00000000..95d0bad6 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/cogs.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/consultation.png b/jikimo_hide_options/static/description/assets/icons/consultation.png new file mode 100644 index 00000000..8319d4ba Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/consultation.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/ecom-black.png b/jikimo_hide_options/static/description/assets/icons/ecom-black.png new file mode 100644 index 00000000..a9385ff1 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/ecom-black.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/education-black.png b/jikimo_hide_options/static/description/assets/icons/education-black.png new file mode 100644 index 00000000..3eb09b27 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/education-black.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/hotel-black.png b/jikimo_hide_options/static/description/assets/icons/hotel-black.png new file mode 100644 index 00000000..130f613b Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/hotel-black.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/license.png b/jikimo_hide_options/static/description/assets/icons/license.png new file mode 100644 index 00000000..a5869797 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/license.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/lifebuoy.png b/jikimo_hide_options/static/description/assets/icons/lifebuoy.png new file mode 100644 index 00000000..658d56cc Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/lifebuoy.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/manufacturing-black.png b/jikimo_hide_options/static/description/assets/icons/manufacturing-black.png new file mode 100644 index 00000000..697eb0e9 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/manufacturing-black.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/pos-black.png b/jikimo_hide_options/static/description/assets/icons/pos-black.png new file mode 100644 index 00000000..97c0f90c Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/pos-black.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/puzzle.png b/jikimo_hide_options/static/description/assets/icons/puzzle.png new file mode 100644 index 00000000..65cf854e Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/puzzle.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/restaurant-black.png b/jikimo_hide_options/static/description/assets/icons/restaurant-black.png new file mode 100644 index 00000000..4a35eb93 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/restaurant-black.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/service-black.png b/jikimo_hide_options/static/description/assets/icons/service-black.png new file mode 100644 index 00000000..301ab51c Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/service-black.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/trading-black.png b/jikimo_hide_options/static/description/assets/icons/trading-black.png new file mode 100644 index 00000000..9398ba2f Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/trading-black.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/training.png b/jikimo_hide_options/static/description/assets/icons/training.png new file mode 100644 index 00000000..884ca024 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/training.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/update.png b/jikimo_hide_options/static/description/assets/icons/update.png new file mode 100644 index 00000000..ecbc5a01 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/update.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/user.png b/jikimo_hide_options/static/description/assets/icons/user.png new file mode 100644 index 00000000..6ffb23d9 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/user.png differ diff --git a/jikimo_hide_options/static/description/assets/icons/wrench.png b/jikimo_hide_options/static/description/assets/icons/wrench.png new file mode 100644 index 00000000..6c04dea0 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/icons/wrench.png differ diff --git a/jikimo_hide_options/static/description/assets/misc/categories.png b/jikimo_hide_options/static/description/assets/misc/categories.png new file mode 100644 index 00000000..bedf1e0b Binary files /dev/null and b/jikimo_hide_options/static/description/assets/misc/categories.png differ diff --git a/jikimo_hide_options/static/description/assets/misc/check-box.png b/jikimo_hide_options/static/description/assets/misc/check-box.png new file mode 100644 index 00000000..42caf24b Binary files /dev/null and b/jikimo_hide_options/static/description/assets/misc/check-box.png differ diff --git a/jikimo_hide_options/static/description/assets/misc/compass.png b/jikimo_hide_options/static/description/assets/misc/compass.png new file mode 100644 index 00000000..d5fed8fa Binary files /dev/null and b/jikimo_hide_options/static/description/assets/misc/compass.png differ diff --git a/jikimo_hide_options/static/description/assets/misc/corporate.png b/jikimo_hide_options/static/description/assets/misc/corporate.png new file mode 100644 index 00000000..2eb13edb Binary files /dev/null and b/jikimo_hide_options/static/description/assets/misc/corporate.png differ diff --git a/jikimo_hide_options/static/description/assets/misc/customer-support.png b/jikimo_hide_options/static/description/assets/misc/customer-support.png new file mode 100644 index 00000000..79efc72e Binary files /dev/null and b/jikimo_hide_options/static/description/assets/misc/customer-support.png differ diff --git a/jikimo_hide_options/static/description/assets/misc/cybrosys-logo.png b/jikimo_hide_options/static/description/assets/misc/cybrosys-logo.png new file mode 100644 index 00000000..cc3cc0cc Binary files /dev/null and b/jikimo_hide_options/static/description/assets/misc/cybrosys-logo.png differ diff --git a/jikimo_hide_options/static/description/assets/misc/features.png b/jikimo_hide_options/static/description/assets/misc/features.png new file mode 100644 index 00000000..b41769f7 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/misc/features.png differ diff --git a/jikimo_hide_options/static/description/assets/misc/logo.png b/jikimo_hide_options/static/description/assets/misc/logo.png new file mode 100644 index 00000000..478462d3 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/misc/logo.png differ diff --git a/jikimo_hide_options/static/description/assets/misc/pictures.png b/jikimo_hide_options/static/description/assets/misc/pictures.png new file mode 100644 index 00000000..56d255fe Binary files /dev/null and b/jikimo_hide_options/static/description/assets/misc/pictures.png differ diff --git a/jikimo_hide_options/static/description/assets/misc/pie-chart.png b/jikimo_hide_options/static/description/assets/misc/pie-chart.png new file mode 100644 index 00000000..426e0524 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/misc/pie-chart.png differ diff --git a/jikimo_hide_options/static/description/assets/misc/right-arrow.png b/jikimo_hide_options/static/description/assets/misc/right-arrow.png new file mode 100644 index 00000000..730984a0 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/misc/right-arrow.png differ diff --git a/jikimo_hide_options/static/description/assets/misc/star.png b/jikimo_hide_options/static/description/assets/misc/star.png new file mode 100644 index 00000000..2eb9ab29 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/misc/star.png differ diff --git a/jikimo_hide_options/static/description/assets/misc/support.png b/jikimo_hide_options/static/description/assets/misc/support.png new file mode 100644 index 00000000..4f18b8b8 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/misc/support.png differ diff --git a/jikimo_hide_options/static/description/assets/misc/whatsapp.png b/jikimo_hide_options/static/description/assets/misc/whatsapp.png new file mode 100644 index 00000000..d513a535 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/misc/whatsapp.png differ diff --git a/jikimo_hide_options/static/description/assets/modules/1.png b/jikimo_hide_options/static/description/assets/modules/1.png new file mode 100644 index 00000000..d0f36b00 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/modules/1.png differ diff --git a/jikimo_hide_options/static/description/assets/modules/l2.png b/jikimo_hide_options/static/description/assets/modules/l2.png new file mode 100644 index 00000000..a3194264 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/modules/l2.png differ diff --git a/jikimo_hide_options/static/description/assets/modules/l3.png b/jikimo_hide_options/static/description/assets/modules/l3.png new file mode 100644 index 00000000..e894393e Binary files /dev/null and b/jikimo_hide_options/static/description/assets/modules/l3.png differ diff --git a/jikimo_hide_options/static/description/assets/modules/l4.png b/jikimo_hide_options/static/description/assets/modules/l4.png new file mode 100644 index 00000000..ed11bd81 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/modules/l4.png differ diff --git a/jikimo_hide_options/static/description/assets/modules/l5.png b/jikimo_hide_options/static/description/assets/modules/l5.png new file mode 100644 index 00000000..3415917c Binary files /dev/null and b/jikimo_hide_options/static/description/assets/modules/l5.png differ diff --git a/jikimo_hide_options/static/description/assets/modules/l6.png b/jikimo_hide_options/static/description/assets/modules/l6.png new file mode 100644 index 00000000..c7ea331e Binary files /dev/null and b/jikimo_hide_options/static/description/assets/modules/l6.png differ diff --git a/jikimo_hide_options/static/description/assets/screenshots/hero.gif b/jikimo_hide_options/static/description/assets/screenshots/hero.gif new file mode 100644 index 00000000..cb2f6b52 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/screenshots/hero.gif differ diff --git a/jikimo_hide_options/static/description/assets/screenshots/model_access_right_01.png b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_01.png new file mode 100644 index 00000000..2ca6bf0b Binary files /dev/null and b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_01.png differ diff --git a/jikimo_hide_options/static/description/assets/screenshots/model_access_right_02.png b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_02.png new file mode 100644 index 00000000..4d800214 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_02.png differ diff --git a/jikimo_hide_options/static/description/assets/screenshots/model_access_right_03.png b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_03.png new file mode 100644 index 00000000..ee165e8f Binary files /dev/null and b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_03.png differ diff --git a/jikimo_hide_options/static/description/assets/screenshots/model_access_right_04.png b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_04.png new file mode 100644 index 00000000..d3760944 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_04.png differ diff --git a/jikimo_hide_options/static/description/assets/screenshots/model_access_right_05.png b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_05.png new file mode 100644 index 00000000..7418fda6 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_05.png differ diff --git a/jikimo_hide_options/static/description/assets/screenshots/model_access_right_06.png b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_06.png new file mode 100644 index 00000000..738a4160 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_06.png differ diff --git a/jikimo_hide_options/static/description/assets/screenshots/model_access_right_07.png b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_07.png new file mode 100644 index 00000000..3bd2812d Binary files /dev/null and b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_07.png differ diff --git a/jikimo_hide_options/static/description/assets/screenshots/model_access_right_08.png b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_08.png new file mode 100644 index 00000000..fa3b0387 Binary files /dev/null and b/jikimo_hide_options/static/description/assets/screenshots/model_access_right_08.png differ diff --git a/jikimo_hide_options/static/description/banner.jpg b/jikimo_hide_options/static/description/banner.jpg new file mode 100644 index 00000000..cc970a2b Binary files /dev/null and b/jikimo_hide_options/static/description/banner.jpg differ diff --git a/jikimo_hide_options/static/description/icon.png b/jikimo_hide_options/static/description/icon.png new file mode 100644 index 00000000..7b22e2b9 Binary files /dev/null and b/jikimo_hide_options/static/description/icon.png differ diff --git a/jikimo_hide_options/static/description/index.html b/jikimo_hide_options/static/description/index.html new file mode 100644 index 00000000..0c64834d --- /dev/null +++ b/jikimo_hide_options/static/description/index.html @@ -0,0 +1,596 @@ +
+ +
+ +
+
+ Community +
+
+ Enterprise +
+
+ Odoo.sh +
+
+
+ +
+
+
+ +

+ Hide Create|Delete|Archive|Export Options - Model Wise

+

Hide Create, Delete, Archive, Export Options in Models

+ + +
+
+
+ + +
+ + +
+
+ +
+

Explore This + Module

+
+
+
+ +
+
+ Overview + Learn + more about this + module +
+ +
+
+
+
+ +
+
+ Features + View + features of this + module +
+ +
+
+
+
+ +
+
+ Screenshots + View + screenshots of this + module +
+ +
+
+
+
+ + + +
+
+ +
+

Overview +

+
+
+
+ By using this module we can hide the options like create,delete,export,and archive/un archive in the model + which we want. Here we are also able to select the user groups except Administrator which we want to apply the + above hiding functionality
+
+ + + +
+
+ +
+

Features +

+
+
+
+
+ + Easily hide the options like Create,Delete,Export and Archive/UnArchive +
+
+ + Can hide the options for specific model +
+
+ + Can hide the options for specific user group +
+
+ + No additional configuration needed +
+
+
+ + + +
+
+ +
+

Screenshots +

+
+
+
+ +
+

Go to Settings > Users and there you can see the Configure Model Access, by enabling that + option and refresh the page, you can see a new menu named 'Restrict Access Rights'

+ +
+ +
+

User in the Purchase module

+ +
+ +
+

Select the Model, Groups and the options which we want to hide

+ +
+
+

We can see Create option is hidden in purchase.order to those who are User + in purchase module

+ +
+ +
+

User in Project module

+ +
+
+

By default, we can see Export and Archive/UnArchive options

+ +
+
+

Select the options which we want to hide

+ +
+
+

Export and Archive/UnArchive functionality are hidden

+ +
+
+
+ + +
+
+ +
+

+ Related + Products +

+
+
+
+ +
+
+ + + + +
+
+ +
+

Our Services +

+
+ +
+
+
+
+ +
+
+ Odoo + Customization
+
+ +
+
+ +
+
+ Odoo + Implementation
+
+ +
+
+ +
+
+ Odoo + Support
+
+ + +
+
+ +
+
+ Hire + Odoo + Developer
+
+ +
+
+ +
+
+ Odoo + Integration
+
+ +
+
+ +
+
+ Odoo + Migration
+
+ + +
+
+ +
+
+ Odoo + Consultancy
+
+ +
+
+ +
+
+ Odoo + Implementation
+
+ +
+
+ +
+
+ Odoo + Licensing Consultancy
+
+
+ +
+ + + + + +
+
+ +
+

Our + Industries +

+
+ +
+
+
+
+ +
+ Trading +
+

+ Easily procure + and + sell your products

+
+
+ +
+
+ +
+ POS +
+

+ Easy + configuration + and convivial experience

+
+
+ +
+
+ +
+ Education +
+

+ A platform for + educational management

+
+
+ +
+
+ +
+ Manufacturing +
+

+ Plan, track and + schedule your operations

+
+
+ +
+
+ +
+ E-commerce & Website +
+

+ Mobile + friendly, + awe-inspiring product pages

+
+
+ +
+
+ +
+ Service Management +
+

+ Keep track of + services and invoice

+
+
+ +
+
+ +
+ Restaurant +
+

+ Run your bar or + restaurant methodically

+
+
+ +
+
+ +
+ Hotel Management +
+

+ An + all-inclusive + hotel management application

+
+
+
+
+ + + + +
+
+ +
+

Support +

+
+
+
+
+
+
+ +
+
+

Need Help?

+

Got questions or need help? Get in touch.

+ +

+ odoo@cybrosys.com

+
+
+
+
+
+
+
+ +
+
+

WhatsApp

+

Say hi to us on WhatsApp!

+ +

+91 86068 + 27707

+
+
+
+
+
+
+
+ +
+
+
+ \ No newline at end of file diff --git a/jikimo_hide_options/static/src/js/form_controller.js b/jikimo_hide_options/static/src/js/form_controller.js new file mode 100644 index 00000000..f515a865 --- /dev/null +++ b/jikimo_hide_options/static/src/js/form_controller.js @@ -0,0 +1,46 @@ +/** @odoo-module */ +/** + * This file will used to hide the selected options from the form view + */ +import { FormController} from "@web/views/form/form_controller"; +import { patch} from "@web/core/utils/patch"; +var rpc = require('web.rpc'); +const { onWillStart} = owl; +patch(FormController.prototype, 'jikimo_hide_options/static/src/js/form_controller.js.FormController', { +/** + * This function will used to hide the selected options from the form view + */ + setup() { + this._super(); + onWillStart(async () => { + var self = this + var result; + await rpc.query({ + model: 'access.right', + method: 'hide_buttons', + }).then(function(data) { + result = data; + }); + for (var i = 0; i < result.length; i++) { + var group = result[i].module + "." + result[i].group_name + if (self.props.resModel == result[i].model) { + if (await self.user.hasGroup(group)) { + if (!this.user.isAdmin) { + if (result[i].is_create_or_update) { + self.canCreate = false + } + if (result[i].is_delete) { + this.archInfo.activeActions.delete = false + } + if (result[i].is_archive) { + self.archiveEnabled = false + } else { + self.archiveEnabled = true; + } + } + } + } + } + }); + } +}); diff --git a/jikimo_hide_options/static/src/js/kanban_controller.js b/jikimo_hide_options/static/src/js/kanban_controller.js new file mode 100644 index 00000000..3e7938cc --- /dev/null +++ b/jikimo_hide_options/static/src/js/kanban_controller.js @@ -0,0 +1,42 @@ +/** @odoo-module */ +/** + * This file will used to hide the selected options from the list view + */ +import { KanbanController } from '@web/views/kanban/kanban_controller'; +import { patch} from "@web/core/utils/patch"; +var rpc = require('web.rpc'); +const {onWillStart} = owl; +patch(KanbanController.prototype, 'jikimo_hide_options/static/src/js/list_controller.js.KanbanController', { +/** + * This function will used to hide the selected options from the Kanban view + */ + setup() { + this._super(); + onWillStart(async () => { + var self = this + var result; + await rpc.query({ + model: 'access.right', + method: 'hide_buttons', + }).then(function(data) { + result = data; + }); + for (var i = 0; i < result.length; i++) { + var group = result[i].module + "." + result[i].group_name + if (self.props.resModel == result[i].model) { + if (await self.model.user.hasGroup(group)) { + if (!self.model.user.isAdmin) { + if (result[i].is_create_or_update) { + self.props.archInfo.activeActions.create=false + self.props.archInfo.activeActions.edit=false + } + if (result[i].is_delete) { + self.props.archInfo.activeActions.delete=false + } + } + } + } + } + }); + } +}); diff --git a/jikimo_hide_options/static/src/js/list_controller.js b/jikimo_hide_options/static/src/js/list_controller.js new file mode 100644 index 00000000..f2e2de76 --- /dev/null +++ b/jikimo_hide_options/static/src/js/list_controller.js @@ -0,0 +1,50 @@ +/** @odoo-module */ +/** + * This file will used to hide the selected options from the list view + */ +import { ListController} from '@web/views/list/list_controller'; +import { patch} from "@web/core/utils/patch"; +var rpc = require('web.rpc'); +const {onWillStart} = owl; +patch(ListController.prototype, 'jikimo_hide_options/static/src/js/list_controller.js.ListController', { +/** + * This function will used to hide the selected options from the list view + */ + setup() { + this._super(); + onWillStart(async () => { + var self = this + var result; + await rpc.query({ + model: 'access.right', + method: 'hide_buttons', + }).then(function(data) { + result = data; + }); + for (var i = 0; i < result.length; i++) { + var group = result[i].module + "." + result[i].group_name + if (self.props.resModel == result[i].model) { + if (await self.userService.hasGroup(group)) { + if (!this.userService.isAdmin) { + if (result[i].is_create_or_update) { + self.activeActions.create = false; + } + if (result[i].is_export) { + self.isExportEnable = false + self.isExportEnable = false + } + if (result[i].is_delete) { + self.activeActions.delete = false; + } + if (result[i].is_archive) { + self.archiveEnabled = false; + } else { + self.archiveEnabled = true; + } + } + } + } + } + }); + } +}); diff --git a/jikimo_hide_options/views/model_access_rights_views.xml b/jikimo_hide_options/views/model_access_rights_views.xml new file mode 100644 index 00000000..ed4e89b1 --- /dev/null +++ b/jikimo_hide_options/views/model_access_rights_views.xml @@ -0,0 +1,58 @@ + + + + + 隐藏项目 + access.right + tree,form + + + + access.right.view.tree + access.right + + + + + + + + + + + + + + access.right.view.form + access.right + +
+ + + + + + + + + + + + + + +
+ + +
+
+
+
+ + +
diff --git a/spiffy_theme_backend/.idea/spiffy_theme_backend.iml b/spiffy_theme_backend/.idea/spiffy_theme_backend.iml deleted file mode 100644 index d0876a78..00000000 --- a/spiffy_theme_backend/.idea/spiffy_theme_backend.iml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file