看不懂可以看这个链接:https://alanhou.org/odoo-14-creating-odoo-add-on-modules/
场景:每一个用户登陆后都只可以查看销售员=用户本身的联系人,不能查看别人的联系人,并可以通过添加关注者来实现查看其他用户的联系人,admin可以查看全部的联系人
类似于下图
自己查看自己的联系人
WechatIMG400.jpeg超级管理员可查看所有的
WechatIMG401.jpeg大概有两种方法可实现:
1、通过记录规则来实现
2、在源代码中添加一个插件模块,在插件模块中写domain权限应用到hr模块中
插件模块实现
1、进入到工作目录即你要操作并放置新建的自定义模块的插件目录中:
$ cd ~/odoo14
$ mkdir odoo_ext
2、为新模块选择一个技术名称并使用该名称作为模块名创建目录。本例中,我们使用hr_ext:
$ mkdir odoo_ext/hr_ext
ℹ️模块的技术名称必须是有效的Python标识符,需以字母开头,仅包含字母、数字和下划线。建议在模块名称中只使用小写字母。
3、通过添加init.py文件来让Python模块可导入:
$ touch local-addons/my_library/__init__.py
4、在init.py中导入models(在这个文件中改domain)、controllers(逻辑层 与外部交互的)
# -*- coding: utf-8 -*-
from . import controllers
from . import models
5、为Odoo添加一个最小化的模块声明来让其成为一个插件模块。我们在odoo_ext文件夹中创建manifest.py(声明文件的模块)并添加如下行:
# -*- coding: utf-8 -*-
{
'name': "hr_ext",
'summary': "权限相关插件",
'author': "My Company",
'website': "", # 网站地址
'category': 'Uncategorized', # 类别
'version': '0.1', # 版本
# any module necessary for this one to work correctly
'depends': ['hr', 'hr_timesheet'],
# always loaded
'data': [
'security/ir.model.access.csv',
# 'views/res_partner.xml',
# 'views/templates.xml',
],
# only loaded in demonstration mode
'demo': [
'demo/demo.xml',
],
}
注意这里是根目录哦
6、将我们的插件目录路径追加到odoo.conf中:
addons_path = /Users/applw/dev/odoo14/odoo/addons,/Users/applw/dev/odoo14/addons,./odoo_ext
注意这里是追加哟,直接在addons_path的最后,./odoo_ext(添加插件文件路径就可以了)
7、在添加models文件夹和models.py文件:
image.png
models.py中写
# -*- coding: utf-8 -*-
from odoo import api, models, _, fields
class PartnerInherit(models.Model):
"""
联系人
"""
_inherit = ['res.partner'] # 继承 res.partner
@api.model
def search_read(self, domain=None, fields=None, offset=0, limit=None, order=None):
user = self.env.user
print(user)
domain = domain or []
if user.id == 2:
pass
else:
domain += ['|', '|', '|', '|',
('message_partner_ids', 'child_of', [user.partner_id.id]),
('user_id', '=', user.id),
'&',
('user_id', '=', False),
('parent_id.user_id', '=', user.id),
'&',
('user_id', '=', False),
('parent_id.user_id', '=', False),
'&',
('user_id', '=', False),
('parent_id', '=', False)
]
return super(PartnerInherit, self).search_read(
domain=domain, fields=fields, offset=offset, limit=limit, order=order)
class ProjectInherit(models.Model):
"""
项目
"""
_inherit = ['project.project'] # 继承 project.project
task_count = fields.Integer(compute='_compute_task_count', string='# Tasks')
# def _compute_task_count(self):
# user = self.env.user
# domain = []
# if user.id == 2:
# pass
# else:
# domain += ['|', '|', # '|', '|',
# ('message_partner_ids', 'child_of', [user.partner_id.id]),
# ('user_id', '=', user.id),
# # '&',
# ('user_id', '=', False),
# # ('parent_id.user_id', '=', user.id),
# # '&',
# # ('user_id', '=', False),
# # ('parent_id.user_id', '=', False),
# # '&',
# # ('user_id', '=', False),
# # ('parent_id', '=', False)
# ]
# fetch_data = self.env['project.task'].read_group(domain, ['partner_id'],
# ['partner_id'])
# result = dict((data['partner_id'][0], data['partner_id_count']) for data in fetch_data)
# for partner in self:
# partner.task_count = result.get(partner.id, 0) + sum(c.task_count for c in partner.child_ids)
# 方法 重写 模块查询接口
@api.model
def search_read(self, domain=None, fields=None, offset=0, limit=None, order=None):
"""
:param domain: 过滤条件
:param fields: 字段
:param offset:
:param limit:
:param order: 排序
:return:
"""
user = self.env.user
domain = domain or []
if user.id == 2:
pass
else:
domain += ['|', '|',# '|', '|',
('message_partner_ids', 'child_of', [user.partner_id.id]),
('user_id', '=', user.id),
# '&',
('user_id', '=', False),
# ('parent_id.user_id', '=', user.id),
# '&',
# ('user_id', '=', False),
# ('parent_id.user_id', '=', False),
# '&',
# ('user_id', '=', False),
# ('parent_id', '=', False)
]
return super(ProjectInherit, self).search_read(
domain=domain, fields=fields, offset=offset, limit=limit, order=order)
class ProjectTaskInherit(models.Model):
"""
项目任务
"""
_inherit = ['project.task'] # 继承 project.task
@api.model
def search_count(self, args):
""" search_count(args) -> int
Returns the number of records in the current model matching :ref:`the
provided domain <reference/orm/domains>`.
"""
user = self.env.user
args = args or []
if user.id == 2:
pass
else:
args += ['|', '|', # '|', '|',
('message_partner_ids', 'child_of', [user.partner_id.id]),
('user_id', '=', user.id),
# '&',
('user_id', '=', False),
# ('parent_id.user_id', '=', user.id),
# '&',
# ('user_id', '=', False),
# ('parent_id.user_id', '=', False),
# '&',
# ('user_id', '=', False),
# ('parent_id', '=', False)
]
print(args)
res = self.search(args, count=True)
return res if isinstance(res, int) else len(res)
# 方法 重写 模块查询接口
@api.model
def search_read(self, domain=None, fields=None, offset=0, limit=None, order=None):
"""
:param domain: 过滤条件
:param fields: 字段
:param offset:
:param limit:
:param order: 排序
:return:
"""
user = self.env.user
domain = domain or []
if user.id == 2:
pass
else:
domain += ['|', '|',# '|', '|',
('message_partner_ids', 'child_of', [user.partner_id.id]),
('user_id', '=', user.id),
# '&',
('user_id', '=', False),
# ('parent_id.user_id', '=', user.id),
# '&',
# ('user_id', '=', False),
# ('parent_id.user_id', '=', False),
# '&',
# ('user_id', '=', False),
# ('parent_id', '=', False)
]
return super(ProjectTaskInherit, self).search_read(
domain=domain, fields=fields, offset=offset, limit=limit, order=order)
8、为了这个新模块在Odoo中可用;使用管理员登录Odoo,启动开发者模式,然后打开应用模块,点击刷新本地模块列表:
image.png
然后点击更新:
image.png
然后搜索hr_ext然后点击安装,如下图:
image.png
这里需要注意的是hr_ext还不属于应用 所以需要只搜索hr_ext,上图是因为我已经安装了 所以没有安装按钮
在安装后只这个插件就已经可以使用了
运行原理…
Odoo模块是一个包含代码文件及其它资源的目录。所使用的目录名为模块的技术名称。模块声明中的 name 键对应其标题。
manifest.py是模块的声明文件。它包含一个带有模块元数据的Python字典,有分类、版本、所依赖的模块以及一系列它要加载的数据文件。在这一节中,我们使用了最简化的声明文件,但在真实的模块中,我们需要使用其它的重要键名。这将在下一节完成插件模块的声明是进行讨论。
模块目录必须是Python可导入的,因此即便内容为空也要添加一个init.py 文件。要载入模块,Odoo服务要导入它。这会导致init.py文件中的代码被执行,它作为运行该模块Python代码的一个入口。因此,它通常会包含加载模块Python文件及子模块的一些导入语句。
已识别模块可通过命令行使用–init或-i选项直接安装。例如,如果希望安装crm和website应用,可使用-i crm,website。这一模块列表在提供插件路径新建数据库时获取到的模块进行初始化设置。可通过Update Module List菜单更新已有数据库。
这个文件夹我传百度云了 自己可下载看看
链接:https://pan.baidu.com/s/1PBYan3ose_oPJaIhXMvaeg 密码:rz67
网友评论