ljm 修改备份

This commit is contained in:
李鹏宇
2024-12-23 11:01:59 +08:00
parent 52f0c91a23
commit e75e23f3e7
40 changed files with 1326 additions and 1 deletions
+8
View File
@@ -0,0 +1,8 @@
# -*- coding: utf-8 -*-
from . import models
from . import controllers
from . import wizard
from .hooks import pre_init_hook
from .hooks import post_init_hook
from .hooks import uninstall_hook
+97
View File
@@ -0,0 +1,97 @@
# -*- coding: utf-8 -*-
# Copyright 2014 ABF OSIELL <http://osiell.com>
# Created on 2022-09-01
# author: 欧度智能,https://www.odooai.cn
# email: 300883@qq.com
# resource of odooai
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
# Odoo16在线用户手册(长期更新)
# https://www.odooai.cn/documentation/16.0/zh_CN/index.html
# Odoo16在线开发者手册(长期更新)
# https://www.odooai.cn/documentation/16.0/zh_CN/developer.html
# Odoo13在线用户手册(长期更新)
# https://www.odooai.cn/documentation/user/13.0/zh_CN/index.html
# Odoo13在线开发者手册(长期更新)
# https://www.odooai.cn/documentation/13.0/index.html
# Odoo10在线中文用户手册(长期更新)
# https://www.odooai.cn/documentation/user/10.0/zh_CN/index.html
# Odoo10离线中文用户手册下载
# https://www.odooai.cn/odoo10_user_manual_document_offline/
# Odoo10离线开发手册下载-含python教程,jquery参考,Jinja2模板,PostgresSQL参考(odoo开发必备)
# https://www.odooai.cn/odoo10_developer_document_offline/
##############################################################################
# Copyright (C) 2009-TODAY odooAi.cn Ltd. https://www.odooai.cn
# Author: Ivan Deng,300883@qq.com
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
# See <http://www.gnu.org/licenses/>.
#
# It is forbidden to publish, distribute, sublicense, or sell copies
# of the Software or modified copies of the Software.
##############################################################################
# todo: 这个有点复杂了,只处理成角色有哪些用户即可
{
'name': "Easy User Admin,User Role manager. 用户角色/用户权限快速管理",
'version': '17.0.24.12.23',
'author': 'odooai.cn',
'category': 'Base',
'website': 'https://www.odooai.cn',
'live_test_url': 'https://demo.odooapp.cn',
'license': 'OPL-1',
'sequence': 2,
'price': 38.00,
'currency': 'EUR',
'images': ['static/description/banner.png'],
'depends': [
'web',
],
'summary': '''
Easy setup user role base on multi security groups.
User role packed with access rule, Validity time period.
Quick assign access right to every user.Mass setup user access right.
Quick set role access.
''',
'description': '''
Base on oca base_user_role. author,ABF OSIELL, Odoo Community Association (OCA)
1. Easy setup user role base on multi security groups.
2. User role packed with access rule, Validity time period.
3. Quick assign access right to every user.Mass setup user access right.
4. The Roles is the base rule of user. Also you can set detail in Access Rights page
5. Easy import groups access from user to roles.
11. Multi-language Support. Multi-Company Support.
12. Support Odoo 18,17,16,15,14,13,12, Enterprise and Community and odoo.sh Edition.
13. Full Open Source.
==========
1.
2.
11. 多语言支持,多公司支持
12. Odoo 18,17,16,15,14,13,12, 企业版,社区版,在线SaaS.sh版,等全版本支持
13. 代码完全开源
''',
'data': [
"security/ir.model.access.csv",
"data/ir_cron_data.xml",
"data/ir_module_category_data.xml",
"wizard/wizard_user2role_views.xml",
"views/res_users_role_views.xml",
"views/res_users_views.xml",
"views/res_groups_views.xml",
],
'demo': [],
# 'pre_init_hook': 'pre_init_hook',
# 'post_init_hook': 'post_init_hook',
# 'uninstall_hook': 'uninstall_hook',
'installable': True,
'application': True,
'auto_install': False,
}
+2
View File
@@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
# from . import main
+25
View File
@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
from odoo import http
from odoo.http import request
from odoo.exceptions import AccessDenied, UserError
from odoo.tools.translate import _
from odoo.addons.portal.controllers.portal import CustomerPortal
# class appCustomerPortal(CustomerPortal):
# @http.route('/my/webclient/locale/<string:lang>', type='http', auth="none")
# def index(self, **kw):
# return "Hello, world"
# @http.route('/default/default/objects/', auth='public')
# def list(self, **kw):
# return http.request.render('default.listing', {
# 'root': '/default/default',
# 'objects': http.request.env['default.default'].search([]),
# })
# @http.route('/default/default/objects/<model("default.default"):obj>/', auth='public')
# def object(self, obj, **kw):
# return http.request.render('default.object', {
# 'object': obj
# })
+15
View File
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2016 ABF OSIELL <http://osiell.com>
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-->
<odoo noupdate="1">
<record model="ir.cron" id="cron_update_users">
<field name='name'>Update user roles</field>
<field name='interval_number'>3</field>
<field name='interval_type'>hours</field>
<field name="active">True</field>
<field name="model_id" ref="app_user_admin.model_res_users_role" />
<field name="state">code</field>
<field name="code">model.cron_update_users()</field>
</record>
</odoo>
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2016 ABF OSIELL <http://osiell.com>
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-->
<odoo>
<!--
This module category aims to be linked to role/group you create in your own
module (field 'res.groups.category_id').
By doing this you'll have the section 'User roles' in the "Access rights" tab
on the user form which will regroup all roles/groups for a better visibility.
-->
<record model="ir.module.category" id="ir_module_category_role">
<field name='name'>User roles</field>
</record>
</odoo>
+28
View File
@@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
# Created on 2018-10-12
# author: 欧度智能,https://www.odooai.cn
# email: 300883@qq.com
# resource of odooai
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
# Odoo在线中文用户手册(长期更新)
# https://www.odooai.cn/documentation/user/10.0/zh_CN/index.html
# Odoo10离线中文用户手册下载
# https://www.odooai.cn/odoo10_user_manual_document_offline/
# Odoo10离线开发手册下载-含python教程,jquery参考,Jinja2模板,PostgresSQL参考(odoo开发必备)
# https://www.odooai.cn/odoo10_developer_document_offline/
# description:
from odoo import api, SUPERUSER_ID, _
def pre_init_hook(env):
pass
def post_init_hook(env):
pass
def uninstall_hook(env):
pass
+2
View File
@@ -0,0 +1,2 @@
Please follow this tutorial for more guides:
https://www.odoo.com/documentation/master/developer/misc/i18n/translations.html
+379
View File
@@ -0,0 +1,379 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * app_user_admin
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0+e-20230721\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-09-04 16:44+0000\n"
"PO-Revision-Date: 2023-09-04 16:44+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_groups__role_count
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__role_count
msgid "# Roles"
msgstr "# 角色"
#. module: app_user_admin
#: model_terms:ir.ui.view,arch_db:app_user_admin.view_res_users_form_inherit
msgid ""
"<strong>The Roles is the base rule of user. Also you can set detail in "
"Access Rights page</strong>"
msgstr "<strong>角色是用户的基本规则。您也可以在访问权限页面中设置详细信息</strong>"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__model_access
msgid "Access Controls"
msgstr "访问控制"
#. module: app_user_admin
#: model:ir.model,name:app_user_admin.model_res_groups
msgid "Access Groups"
msgstr "用户权限组"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__menu_access
msgid "Access Menu"
msgstr "访问菜单"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__model_access_ids
#: model_terms:ir.ui.view,arch_db:app_user_admin.view_res_users_role_form
msgid "Access Rights"
msgstr "访问权限"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role_line__active
msgid "Active"
msgstr "积极"
#. module: app_user_admin
#: model_terms:ir.ui.view,arch_db:app_user_admin.view_res_users_role_form
msgid "Add a line"
msgstr "添加一行"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__category_id
msgid "Application"
msgstr "应用"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__group_category_id
msgid "Associated category"
msgstr "关联类别"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__group_id
msgid "Associated group"
msgstr "关联组"
#. module: app_user_admin
#: model:ir.model.fields,help:app_user_admin.field_res_users_role__group_category_id
msgid "Associated group's category"
msgstr "关联权限组的类别"
#. module: app_user_admin
#: model_terms:ir.ui.view,arch_db:app_user_admin.app_wizard_user2role_form_view
msgid "Cancel"
msgstr "取消"
#. module: app_user_admin
#: model:ir.model,name:app_user_admin.model_wizard_user2role
msgid "Clone User Group to Role Wizard"
msgstr "克隆用户权限组至角色"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__color
msgid "Color Index"
msgstr "颜色索引指数"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__comment
msgid "Comment"
msgstr "评论"
#. module: app_user_admin
#: model_terms:ir.ui.view,arch_db:app_user_admin.app_wizard_user2role_form_view
msgid "Confirm"
msgstr "确定"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__create_uid
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role_line__create_uid
#: model:ir.model.fields,field_description:app_user_admin.field_wizard_user2role__create_uid
msgid "Created by"
msgstr "创建者"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__create_date
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role_line__create_date
#: model:ir.model.fields,field_description:app_user_admin.field_wizard_user2role__create_date
msgid "Created on"
msgstr "创建于"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__display_name
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role_line__display_name
#: model:ir.model.fields,field_description:app_user_admin.field_wizard_user2role__display_name
msgid "Display Name"
msgstr "显示名称"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role_line__is_enabled
msgid "Enabled"
msgstr "启用"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role_line__date_from
msgid "From"
msgstr "从"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__full_name
msgid "Group Name"
msgstr "权限组名称"
#. module: app_user_admin
#: model:ir.model.fields,help:app_user_admin.field_res_users_role__share
msgid "Group created to set access rights for sharing data with some users."
msgstr "为设置与某些用户共享数据的访问权限而创建的组。"
#. module: app_user_admin
#: model_terms:ir.ui.view,arch_db:app_user_admin.view_res_users_role_form
msgid "Groups Setup"
msgstr "权限组设置"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__id
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role_line__id
#: model:ir.model.fields,field_description:app_user_admin.field_wizard_user2role__id
msgid "ID"
msgstr ""
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_wizard_user2role__user_id
msgid "Import From User"
msgstr "从用户导入"
#. module: app_user_admin
#: model_terms:ir.ui.view,arch_db:app_user_admin.view_res_users_role_form
msgid "Import Groups"
msgstr "导入权限组"
#. module: app_user_admin
#: model:ir.actions.act_window,name:app_user_admin.action_wizard_user2role
msgid "Import User Groups to Role"
msgstr "导入用户权限组至角色"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__implied_ids
msgid "Inherits"
msgstr "继承"
#. module: app_user_admin
#: model_terms:ir.ui.view,arch_db:app_user_admin.view_res_users_role_form
msgid "Internal Notes"
msgstr "内部说明"
#. module: app_user_admin
#: model:ir.model.fields,help:app_user_admin.field_res_groups__parent_ids
#: model:ir.model.fields,help:app_user_admin.field_res_users_role__parent_ids
msgid ""
"Inverse relation for the Inherits field. The groups from which this group is"
" inheriting"
msgstr "“继承”字段的反比关系。此组从中继承的组"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role____last_update
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role_line____last_update
#: model:ir.model.fields,field_description:app_user_admin.field_wizard_user2role____last_update
msgid "Last Modified on"
msgstr "上次修改时间"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__write_uid
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role_line__write_uid
#: model:ir.model.fields,field_description:app_user_admin.field_wizard_user2role__write_uid
msgid "Last Updated by"
msgstr "最后更新者"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__write_date
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role_line__write_date
#: model:ir.model.fields,field_description:app_user_admin.field_wizard_user2role__write_date
msgid "Last Updated on"
msgstr "最后更新于"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__model_access_count
msgid "Model Access Count"
msgstr "模型访问计数"
#. module: app_user_admin
#: model_terms:ir.ui.view,arch_db:app_user_admin.view_res_users_role_form
msgid "Multi Add line"
msgstr "批量添加"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__name
msgid "Name"
msgstr "名字"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_groups__trans_parent_ids
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__trans_parent_ids
msgid "Parent Groups"
msgstr "上级组"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_groups__parent_ids
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__parent_ids
msgid "Parents"
msgstr "上级"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__rule_ids
#: model_terms:ir.ui.view,arch_db:app_user_admin.view_res_users_role_form
msgid "Record Rules"
msgstr "记录规则"
#. module: app_user_admin
#: model:ir.model.fields,help:app_user_admin.field_res_groups__role_id
#: model:ir.model.fields,help:app_user_admin.field_res_users_role__role_id
msgid "Relation for the groups that represents a role"
msgstr "表示角色与权限组的关系"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_groups__role_id
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__role_id
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role_line__role_id
msgid "Role"
msgstr "角色"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_users__role_line_ids
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__line_ids
msgid "Role lines"
msgstr "角色明细"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_groups__role_ids
#: model:ir.model.fields,field_description:app_user_admin.field_res_users__role_ids
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__role_ids
#: model_terms:ir.ui.view,arch_db:app_user_admin.res_groups_view_form
#: model_terms:ir.ui.view,arch_db:app_user_admin.view_res_users_form_inherit
#: model_terms:ir.ui.view,arch_db:app_user_admin.view_res_users_role_search
msgid "Roles"
msgstr "角色"
#. module: app_user_admin
#: model:ir.actions.act_window,name:app_user_admin.action_res_users_role_tree
#: model:ir.ui.menu,name:app_user_admin.menu_action_res_users_role_tree
msgid "Roles Management"
msgstr "角色管理"
#. module: app_user_admin
#: model:ir.model.constraint,message:app_user_admin.constraint_res_users_role_line_user_role_uniq
msgid "Roles can be assigned to a user only once at a time"
msgstr "一次只能为用户分配一次角色"
#. module: app_user_admin
#: model:ir.model.fields,help:app_user_admin.field_res_groups__role_ids
#: model:ir.model.fields,help:app_user_admin.field_res_users_role__role_ids
msgid "Roles in which the group is involved"
msgstr "权限组所在的角色"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__rule_groups
msgid "Rules"
msgstr "规则"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__rules_count
msgid "Rules Count"
msgstr "规则计数"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__share
msgid "Share Group"
msgstr "共享组"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role_line__date_to
msgid "To"
msgstr "至"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_wizard_user2role__role_id
msgid "To Role"
msgstr ""
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__trans_implied_ids
msgid "Transitively inherits"
msgstr "可传递继承"
#. module: app_user_admin
#: model:ir.actions.server,name:app_user_admin.cron_update_users_ir_actions_server
#: model:ir.cron,cron_name:app_user_admin.cron_update_users
msgid "Update user roles"
msgstr "更新用户角色"
#. module: app_user_admin
#: model:ir.model,name:app_user_admin.model_res_users
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role_line__user_id
msgid "User"
msgstr "用户"
#. module: app_user_admin
#: model:ir.model,name:app_user_admin.model_res_users_role
msgid "User role"
msgstr "用户角色"
#. module: app_user_admin
#: model:ir.module.category,name:app_user_admin.ir_module_category_role
msgid "User roles"
msgstr "用户角色"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__users
msgid "Users"
msgstr "用户"
#. module: app_user_admin
#: model_terms:ir.ui.view,arch_db:app_user_admin.view_res_users_role_form
msgid "Users Add to Role"
msgstr "用户添加到角色"
#. module: app_user_admin
#: model:ir.model,name:app_user_admin.model_res_users_role_line
msgid "Users associated to a role"
msgstr "与角色关联的用户"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__user_ids
msgid "Users list"
msgstr "用户列表"
#. module: app_user_admin
#: model:ir.model.fields,help:app_user_admin.field_res_users_role__implied_ids
msgid "Users of this group automatically inherit those groups"
msgstr "此组的用户会自动继承这些组"
#. module: app_user_admin
#: model:ir.model.fields,field_description:app_user_admin.field_res_groups__view_access
#: model:ir.model.fields,field_description:app_user_admin.field_res_users_role__view_access
msgid "Views"
msgstr "视图"
#. module: app_user_admin
#: model_terms:ir.ui.view,arch_db:app_user_admin.view_res_users_form_inherit
msgid "You can set multi user role in Roles Management"
msgstr "您可以在角色管理中设置多用户角色"
+6
View File
@@ -0,0 +1,6 @@
# -*- coding: utf-8 -*-
from . import res_users_role
from . import res_users_role_line
from . import res_users
from . import res_groups
+89
View File
@@ -0,0 +1,89 @@
# -*- coding: utf-8 -*-
from odoo import api, fields, models
class ResGroups(models.Model):
_inherit = "res.groups"
view_access = fields.Many2many(
groups="base.group_system",
)
# The inverse field of the field group_id on the res.users.role model
# This field should be used a One2one relation as a role can only be
# represented by one group. It's declared as a One2many field as the
# inverse field on the res.users.role it's declared as a Many2one
role_id = fields.One2many(
comodel_name="res.users.role",
inverse_name="group_id",
help="Relation for the groups that represents a role",
)
role_ids = fields.Many2many(
comodel_name="res.users.role",
relation="res_groups_implied_roles_rel",
string="Roles",
compute="_compute_role_ids",
help="Roles in which the group is involved",
)
parent_ids = fields.Many2many(
"res.groups",
"res_groups_implied_rel",
"hid",
"gid",
string="Parents",
help="Inverse relation for the Inherits field. "
"The groups from which this group is inheriting",
)
trans_parent_ids = fields.Many2many(
comodel_name="res.groups",
string="Parent Groups",
compute="_compute_trans_parent_ids",
recursive=True,
)
role_count = fields.Integer("# Roles", compute="_compute_role_count")
def _compute_role_count(self):
for group in self:
group.role_count = len(group.role_ids)
@api.depends("parent_ids.trans_parent_ids")
def _compute_trans_parent_ids(self):
for group in self:
group.trans_parent_ids = (
group.parent_ids | group.parent_ids.trans_parent_ids
)
def _compute_role_ids(self):
for group in self:
if group.trans_parent_ids:
group.role_ids = group.trans_parent_ids.role_id
else:
group.role_ids = group.role_id
def action_view_roles(self):
self.ensure_one()
action = self.env["ir.actions.act_window"]._for_xml_id(
"app_user_admin.action_res_users_role_tree"
)
action["context"] = {}
if len(self.role_ids) > 1:
action["domain"] = [("id", "in", self.role_ids.ids)]
elif self.role_ids:
form_view = [
(self.env.ref("app_user_admin.view_res_users_role_form").id, "form")
]
if "views" in action:
action["views"] = form_view + [
(state, view) for state, view in action["views"] if view != "form"
]
else:
action["views"] = form_view
action["res_id"] = self.role_ids.id
else:
action = {"type": "ir.actions.act_window_close"}
return action
+89
View File
@@ -0,0 +1,89 @@
# -*- coding: utf-8 -*-
from odoo import api, fields, models
class ResUsers(models.Model):
_inherit = "res.users"
role_line_ids = fields.One2many(
comodel_name="res.users.role.line",
inverse_name="user_id",
string="Role lines",
default=lambda self: self._default_role_lines(),
)
role_ids = fields.One2many(
comodel_name="res.users.role",
string="Roles",
compute="_compute_role_ids",
compute_sudo=True,
)
@api.model
def _default_role_lines(self):
default_user = self.env.ref("base.default_user", raise_if_not_found=False)
default_values = []
if default_user:
for role_line in default_user.with_context(active_test=False).role_line_ids:
default_values.append(
{
"role_id": role_line.role_id.id,
"date_from": role_line.date_from,
"date_to": role_line.date_to,
"is_enabled": role_line.is_enabled,
}
)
return default_values
@api.depends("role_line_ids.role_id")
def _compute_role_ids(self):
for user in self:
user.role_ids = user.role_line_ids.mapped("role_id")
@api.model_create_multi
def create(self, vals_list):
new_records = super(ResUsers, self).create(vals_list)
new_records.set_groups_from_roles()
return new_records
def write(self, vals):
res = super(ResUsers, self).write(vals)
self.sudo().set_groups_from_roles()
return res
def _get_enabled_roles(self):
return self.role_line_ids.filtered(lambda rec: rec.is_enabled)
def set_groups_from_roles(self, force=False):
"""Set (replace) the groups following the roles defined on users.
If no role is defined on the user, its groups are let untouched unless
the `force` parameter is `True`.
"""
role_groups = {}
# We obtain all the groups associated to each role first, so that
# it is faster to compare later with each user's groups.
for role in self.mapped("role_line_ids.role_id"):
role_groups[role] = list(
set(
role.group_id.ids
+ role.implied_ids.ids
+ role.trans_implied_ids.ids
)
)
for user in self:
if not user.role_line_ids and not force:
continue
group_ids = []
for role_line in user._get_enabled_roles():
role = role_line.role_id
group_ids += role_groups[role]
group_ids = list(set(group_ids)) # Remove duplicates IDs
groups_to_add = list(set(group_ids) - set(user.groups_id.ids))
groups_to_remove = list(set(user.groups_id.ids) - set(group_ids))
to_add = [(4, gr) for gr in groups_to_add]
to_remove = [(3, gr) for gr in groups_to_remove]
groups = to_remove + to_add
if groups:
vals = {"groups_id": groups}
super(ResUsers, user).write(vals)
return True
+124
View File
@@ -0,0 +1,124 @@
# -*- coding: utf-8 -*-
import logging
from odoo import SUPERUSER_ID, api, fields, models
_logger = logging.getLogger(__name__)
class ResUsersRole(models.Model):
_name = "res.users.role"
_inherits = {"res.groups": "group_id"}
_description = "User role"
group_id = fields.Many2one(
comodel_name="res.groups",
required=True,
ondelete="cascade",
readonly=True,
string="Associated group",
)
line_ids = fields.One2many(
comodel_name="res.users.role.line", inverse_name="role_id", string="Role lines"
)
user_ids = fields.One2many(
comodel_name="res.users", string="Users list", compute="_compute_user_ids"
)
rule_ids = fields.Many2many(
comodel_name="ir.rule",
compute="_compute_rule_ids",
string="Record Rules",
required=False,
)
rules_count = fields.Integer(compute="_compute_rule_ids")
model_access_ids = fields.Many2many(
comodel_name="ir.model.access",
compute="_compute_model_access_ids",
string="Access Rights",
required=False,
)
model_access_count = fields.Integer(compute="_compute_model_access_ids")
group_category_id = fields.Many2one(
related="group_id.category_id",
default=lambda cls: cls.env.ref("app_user_admin.ir_module_category_role").id,
string="Associated category",
help="Associated group's category",
readonly=False,
)
@api.depends("line_ids.user_id")
def _compute_user_ids(self):
for role in self.sudo() if self._bypass_rules() else self:
role.user_ids = role.line_ids.mapped("user_id")
@api.depends("implied_ids", "implied_ids.model_access")
def _compute_model_access_ids(self):
for rec in self:
rec.model_access_ids = rec.implied_ids.model_access.ids
rec.model_access_count = len(rec.model_access_ids)
@api.depends("implied_ids", "implied_ids.rule_groups")
def _compute_rule_ids(self):
for rec in self:
rec.rule_ids = rec.implied_ids.rule_groups.ids
rec.rules_count = len(rec.rule_ids)
@api.model
def _bypass_rules(self):
# Run methods as super user to avoid problems by "Administrator/Access Right"
return self._name == "res.users.role" and self.env.user.has_group(
"base.group_erp_manager"
)
@api.model_create_multi
def create(self, vals_list):
model = (self.sudo() if self._bypass_rules() else self).browse()
new_records = super(ResUsersRole, model).create(vals_list)
new_records.update_users()
return new_records
def read(self, fields=None, load="_classic_read"):
recs = self.sudo() if self._bypass_rules() else self
return super(ResUsersRole, recs).read(fields, load)
def write(self, vals):
recs = self.sudo() if self._bypass_rules() else self
# Workaround to solve issue with broken code in odoo that clear the
# cache during the write: see odoo/addons/base/models/res_users.py#L226
groups_vals = {}
for field in recs.group_id._fields:
if field in vals:
groups_vals[field] = vals.pop(field)
if groups_vals:
recs.group_id.write(groups_vals)
res = super(ResUsersRole, recs).write(vals)
recs.update_users()
return res
def unlink(self):
users = self.mapped("user_ids")
res = super(ResUsersRole, self).unlink()
users.set_groups_from_roles(force=True)
return res
def update_users(self):
"""Update all the users concerned by the roles identified by `ids`."""
users = self.mapped("user_ids")
users.set_groups_from_roles()
return True
@api.model
def cron_update_users(self):
logging.info("Update user roles")
self.search([]).update_users()
def show_rule_ids(self):
action = self.env["ir.actions.actions"]._for_xml_id("base.action_rule")
action["domain"] = [("id", "in", self.rule_ids.ids)]
return action
def show_model_access_ids(self):
action = self.env["ir.actions.actions"]._for_xml_id("base.ir_access_act")
action["domain"] = [("id", "in", self.model_access_ids.ids)]
return action
@@ -0,0 +1,55 @@
# -*- coding: utf-8 -*-
import datetime
import logging
from odoo import SUPERUSER_ID, api, fields, models
_logger = logging.getLogger(__name__)
class ResUsersRoleLine(models.Model):
_name = "res.users.role.line"
_description = "Users associated to a role"
active = fields.Boolean(related="user_id.active")
role_id = fields.Many2one(
comodel_name="res.users.role", required=True, string="Role", ondelete="cascade"
)
user_id = fields.Many2one(
comodel_name="res.users",
required=True,
string="User",
domain=[("id", "!=", SUPERUSER_ID)],
ondelete="cascade",
)
date_from = fields.Date("From")
date_to = fields.Date("To")
is_enabled = fields.Boolean("Enabled", compute="_compute_is_enabled")
_sql_constraints = [
(
"user_role_uniq",
"unique (user_id,role_id)",
"Roles can be assigned to a user only once at a time",
)
]
@api.depends("date_from", "date_to")
def _compute_is_enabled(self):
today = datetime.date.today()
for role_line in self:
role_line.is_enabled = True
if role_line.date_from:
date_from = role_line.date_from
if date_from > today:
role_line.is_enabled = False
if role_line.date_to:
date_to = role_line.date_to
if today > date_to:
role_line.is_enabled = False
def unlink(self):
users = self.mapped("user_id")
res = super(ResUsersRoleLine, self).unlink()
users.set_groups_from_roles(force=True)
return res
+2
View File
@@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
@@ -0,0 +1,4 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_res_users_role,access_res_users_role,model_res_users_role,"base.group_erp_manager",1,1,1,1
access_res_users_role_line,access_res_users_role_line,model_res_users_role_line,"base.group_erp_manager",1,1,1,1
access_wizard_user2role,access_wizard_user2role,model_wizard_user2role,"base.group_erp_manager",1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_res_users_role access_res_users_role model_res_users_role base.group_erp_manager 1 1 1 1
3 access_res_users_role_line access_res_users_role_line model_res_users_role_line base.group_erp_manager 1 1 1 1
4 access_wizard_user2role access_wizard_user2role model_wizard_user2role base.group_erp_manager 1 1 1 1
Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

@@ -0,0 +1,151 @@
<section class="oe_container container">
<div class="oe_row oe_spaced" >
<div class="row">
<h2 class="oe_slogan">Easy User Admin, User Role manager. </h2>
<h3 class="oe_slogan"> Quick assign access right to every user.Mass setup user access right. </h3>
<div class="oe_row">
<h3>Latest update: v17.24.12.23</h3>
<div class="oe_span12 oe_spaced">
<div class="alert alert-info" style="padding:8px;font-weight: 300; font-size: 20px;">
<i class="fa fa-hand-o-right"></i><b> Key features: </b>
<ul class="list-unstyled">
<li>
<i class="fa fa-check-square-o text-primary"></i>
1. Easy setup user role base on multi security groups.
</li>
<li>
<i class="fa fa-check-square-o text-primary"></i>
2. User role packed with access rule, Validity time period.
</li>
<li>
<i class="fa fa-check-square-o text-primary"></i>
3. Quick assign access right to every user.Mass setup user access right.
</li>
<li>
<i class="fa fa-check-square-o text-primary"></i>
4. The Roles is the base rule of user. Also you can set detail in Access Rights page
</li>
<li>
<i class="fa fa-check-square-o text-primary"></i>
5. Easy import groups access from user to roles.
</li>
<li>
<i class="fa fa-check-square-o text-primary"></i>
11. Multi-language Support. Multi-Company Support.
</li>
<li>
<i class="fa fa-check-square-o text-primary"></i>
12. Support Odoo 18,17,16,15,14,13,12, Enterprise and Community and odoo.sh Edition.
</li>
<li>
<i class="fa fa-check-square-o text-primary"></i>
13. Full Open Source.
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</section>
<section class="oe_container container">
<div class="oe_row oe_spaced">
<h2 class="bg-warning text-center pt8 pb8 mt16 mb16">1. Easy setup user role base on multi security groups.</h2>
<h4 class="oe_slogan"> </h4>
<div class="oe_demo oe_screenshot img img-fluid">
<img src="demo1.jpg"/>
</div>
</div>
</section>
<section class="oe_container container">
<div class="oe_row oe_spaced">
<h2 class="bg-warning text-center pt8 pb8 mt16 mb16">2. User role packed with access rule, Validity time period.</h2>
<h4 class="oe_slogan"> </h4>
<div class="oe_demo oe_screenshot img img-fluid">
<img src="demo2.jpg"/>
</div>
</div>
</section>
<section class="oe_container container">
<div class="oe_row oe_spaced">
<h2 class="bg-warning text-center pt8 pb8 mt16 mb16">3. Quick assign access right to every user.Mass setup user access right.</h2>
<h4 class="oe_slogan"> </h4>
<div class="oe_demo oe_screenshot img img-fluid">
<img src="demo3.jpg"/>
</div>
</div>
</section>
<section class="oe_container container">
<div class="oe_row oe_spaced">
<h2 class="bg-warning text-center pt8 pb8 mt16 mb16">4. The Roles is the base rule of user. Also you can set detail in Access Rights page</h2>
<h4 class="oe_slogan"> </h4>
<div class="oe_demo oe_screenshot img img-fluid">
<img src="demo4.jpg"/>
</div>
<div class="oe_demo oe_screenshot img img-fluid">
<img src="demo41.jpg"/>
</div>
</div>
</section>
<section class="oe_container container">
<div class="oe_row oe_spaced">
<h2 class="bg-warning text-center pt8 pb8 mt16 mb16">5. Easy import groups access from user to roles.</h2>
<h4 class="oe_slogan"> </h4>
<div class="oe_demo oe_screenshot img img-fluid">
<img src="demo5.jpg"/>
</div>
</div>
</section>
<section class="oe_container container">
<div class="oe_row oe_spaced">
<h2 class="bg-warning text-center pt8 pb8 mt16 mb16">Multi-language Support..</h2>
<h4 class="oe_slogan"> </h4>
<div class="oe_demo oe_screenshot img img-fluid">
<img src="cnreadme.png"/>
</div>
</div>
</section>
<section class="container oe_dark">
<div class="oe_row oe_spaced text-center">
<div class="row">
<h2 class="oe_slogan">Technical Help & Support</h2>
</div>
<div class="col-md-12 pad0">
<div class="oe_mt16">
<p><h4>
For any type of technical help & support requests, Feel free to contact us</h4></p>
<a style="background: #002e5a none repeat scroll 0% 0%; color: rgb(255, 255, 255);position: relative; overflow: hidden;"
class="btn btn-warning btn-lg" rel="nofollow" href="mailto:odoo@china.com"><span
style="height: 354px; width: 354px; top: -147.433px; left: -6.93335px;" class="o_ripple"></span>
<i class="fa fa-envelope"></i> odoo@china.com</a>
<p><h4>
Via QQ: 300883 (App user would not get QQ or any other IM support. Only for odoo project customize.)</h4></p>
<a style="background: #002e5a none repeat scroll 0% 0%; color: rgb(255, 255, 255);position: relative; overflow: hidden;"
class="btn btn-warning btn-lg" rel="nofollow" href="mailto:300883@qq.com"><span
style="height: 354px; width: 354px; top: -147.433px; left: -6.93335px;" class="o_ripple"></span>
<i class="fa fa-envelope"></i> 300883@qq.com</a>
</div>
<div class="oe_mt16">
<p><h4>
Visit our website for more support.</h4></p>
<a style="background: #002e5a none repeat scroll 0% 0%; color: rgb(255, 255, 255);position: relative; overflow: hidden;"
class="btn btn-warning btn-lg" rel="nofollow" href="https://www.odooai.cn" target="_blank"><span
style="height: 354px; width: 354px; top: -147.433px; left: -6.93335px;" class="o_ripple"></span>
<i class="fa fa-web"></i>https://www.odooai.cn</a>
</div>
</div>
</div>
<div class="oe_row oe_spaced text-center">
<h2>More Powerful addons, Make your odoo very easy to use, easy customize:
<a class="btn btn-primary mb16" href="http://www.odoo.com/apps/modules/browse?author=odooAi.cn">odooAi.cn Odoo Addons</a>
</h2>
</div>
</section>
Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

+23
View File
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="res_groups_view_form" model="ir.ui.view">
<field name="name">app.res.groups.form</field>
<field name="model">res.groups</field>
<field name="inherit_id" ref="base.view_groups_form" />
<field name="arch" type="xml">
<xpath expr="//sheet/group" position="before">
<div name="button_box" class="oe_button_box">
<button
class="oe_stat_button"
name="action_view_roles"
type="object"
icon="fa-gears"
invisible="role_count == 0"
>
<field string="Roles" name="role_count" widget="statinfo" />
</button>
</div>
</xpath>
</field>
</record>
</odoo>
@@ -0,0 +1,114 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="view_res_users_role_tree" model="ir.ui.view">
<field name="name">res.users.role.tree</field>
<field name="model">res.users.role</field>
<field name="arch" type="xml">
<tree>
<field name="name" />
<field name="user_ids" />
</tree>
</field>
</record>
<record id="view_res_users_role_search" model="ir.ui.view">
<field name="name">res.users.role.search</field>
<field name="model">res.users.role</field>
<field name="arch" type="xml">
<search string="Roles">
<field name="name" />
<field name="user_ids" />
<field name="implied_ids" />
</search>
</field>
</record>
<record id="view_res_users_role_form" model="ir.ui.view">
<field name="name">res.users.role.form</field>
<field name="model">res.users.role</field>
<field name="arch" type="xml">
<form>
<sheet>
<div class="oe_button_box" name="button_box">
<button
name="%(action_wizard_user2role)d"
string="Import Groups"
type="action"
context="{'default_role_id': id}"
class="oe_stat_button"
icon="fa-user"/>
<button
name="show_model_access_ids"
type="object"
class="oe_stat_button"
icon="fa-book"
>
<field
name="model_access_count"
widget="statinfo"
string="Access Rights"
/>
</button>
<button
name="show_rule_ids"
type="object"
class="oe_stat_button"
icon="fa-server"
>
<field
name="rules_count"
widget="statinfo"
string="Record Rules"
/>
</button>
</div>
<group>
<field name="id" invisible="1"/>
<field name="name" />
<field name="group_id" required="0" readonly="1" />
</group>
<notebook>
<page string="Users Add to Role">
<field name="line_ids" nolabel="1" context="{'active_test':0}">
<tree editable="bottom" decoration-muted="not is_enabled">
<control>
<create string="Add a line"/>
<create string="Multi Add line" context="{
'pro_multi_add': True,
'pro_res_model': 'res.users',
'pro_res_field': 'user_id',
}"/>
</control>
<field name="user_id"/>
<field name="date_from"/>
<field name="date_to"/>
<field name="is_enabled"/>
</tree>
</field>
</page>
<page string="Groups Setup">
<field name="implied_ids" nolabel="1"/>
</page>
<page name="page_internal_notes" string="Internal Notes">
<field name="comment" />
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<record model="ir.actions.act_window" id="action_res_users_role_tree">
<field name="name">Roles Management</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">res.users.role</field>
<field name="view_id" ref="view_res_users_role_tree" />
</record>
<menuitem
id="menu_action_res_users_role_tree"
parent="base.menu_users"
sequence="2"
action="action_res_users_role_tree"
/>
</odoo>
+43
View File
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2014 ABF OSIELL <http://osiell.com>
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
-->
<odoo>
<record id="view_res_users_form_inherit" model="ir.ui.view">
<field name="name">res.users.form.inherit</field>
<field name="model">res.users</field>
<field name="inherit_id" ref="base.view_users_form" />
<field name="arch" type="xml">
<xpath expr="//notebook/page[1]" position="before">
<page string="Roles">
<div class="alert alert-info text-left" role="alert">
<strong>The Roles is the base rule of user. Also you can set detail in Access Rights page</strong>
<p>You can set multi user role in Roles Management </p>
</div>
<field name="role_ids" invisible="1"/>
<field name="role_line_ids" nolabel="1" context="{'active_test':0}">
<tree editable="bottom" decoration-muted="not is_enabled">
<field
name="role_id"
domain="[('id', 'not in', parent.role_ids)]"
/>
<field name="date_from" />
<field name="date_to" />
<field name="is_enabled" />
</tree>
</field>
</page>
</xpath>
</field>
</record>
<record id="view_res_users_search_inherit" model="ir.ui.view">
<field name="name">res.users.search.inherit</field>
<field name="model">res.users</field>
<field name="inherit_id" ref="base.view_users_search" />
<field name="arch" type="xml">
<field name="company_ids" position="after">
<field name="role_ids" />
</field>
</field>
</record>
</odoo>
+3
View File
@@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import wizard_user2role
View File
+20
View File
@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
from odoo import api, fields, models, _
from odoo.exceptions import UserError
from odoo.osv import expression
from odoo.tools import float_is_zero, float_compare
class WizardUser2Role(models.TransientModel):
_name = 'wizard.user2role'
_description = 'Clone User Group to Role Wizard'
user_id = fields.Many2one('res.users', string='Import From User', required=True)
role_id = fields.Many2one('res.users.role', string='To Role', required=True)
def confirm(self):
self.ensure_one()
vals = []
self.role_id.write({
'implied_ids': self.user_id.groups_id.ids
})
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="app_wizard_user2role_form_view" model="ir.ui.view">
<field name="name">wizard.user2role.form</field>
<field name="model">wizard.user2role</field>
<field name="arch" type="xml">
<form>
<group>
<group>
<field name="user_id" context="{'active_test':0}"/>
<field name="role_id"/>
</group>
</group>
<footer>
<button type="object" name="confirm" string="Confirm" class="oe_highlight"/>
<button special="cancel" string="Cancel" class="btn-secondary"/>
</footer>
</form>
</field>
</record>
<record id="action_wizard_user2role" model="ir.actions.act_window">
<field name="name">Import User Groups to Role</field>
<field name="res_model">wizard.user2role</field>
<field name="view_mode">form</field>
<field name="view_id" ref="app_wizard_user2role_form_view"/>
<field name="target">new</field>
</record>
</odoo>
+2 -1
View File
@@ -691,6 +691,7 @@ class HrAttendanceDetail(models.Model):
"check_in": checkin_time, "check_in": checkin_time,
"is_late_card": checkin_time > will_datetime_start, "is_late_card": checkin_time > will_datetime_start,
"is_no_card": True, "is_no_card": True,
"is_abnormal": True,
}) })
return True return True
else: else:
@@ -708,10 +709,10 @@ class HrAttendanceDetail(models.Model):
"sch_check_in_time": will_datetime_start, "sch_check_in_time": will_datetime_start,
"check_in": min_time, "check_in": min_time,
"is_late_card": min_time > will_datetime_start, "is_late_card": min_time > will_datetime_start,
"sch_check_out_time": will_datetime_end, "sch_check_out_time": will_datetime_end,
"check_out": max_time, "check_out": max_time,
"is_early_card": will_datetime_end > max_time, "is_early_card": will_datetime_end > max_time,
"is_abnormal": min_time > will_datetime_start or will_datetime_end > max_time,
}) })
return True return True