@@ -69,6 +69,18 @@ class SoongWorkflowRecord(models.Model):
|
||||
soong_state = fields.Selection([('to_do', '待办'), ('done', '已办'),('to_active', '待归档'), ('active', '已归档')], string="流程状态", default="to_do")
|
||||
member_of_department = fields.Boolean("是否是本部门数据", compute='_compute_part_of_department',
|
||||
search='_search_part_of_department')
|
||||
special_member_visible = fields.Boolean(
|
||||
"特殊权限可见(人事/考勤)",
|
||||
compute='_compute_special_member_visible',
|
||||
search='_search_special_member_visible',
|
||||
help="当前用户属于『本部-角色-人事专员』或『考勤-用户』用户组时,可查看对应的(仅本公司的)人事/考勤流程",
|
||||
)
|
||||
dept_query_visible = fields.Boolean(
|
||||
"部门查询可见(排除考勤/人事)",
|
||||
compute='_compute_dept_query_visible',
|
||||
search='_search_dept_query_visible',
|
||||
help="本部门可见,但排除审批分组为考勤/人事的流程(二者仅对特殊权限组可见)",
|
||||
)
|
||||
|
||||
# 人力资源流程的发生日期
|
||||
workflow_happen_date = fields.Date(string="发生日期")
|
||||
@@ -613,6 +625,78 @@ class SoongWorkflowRecord(models.Model):
|
||||
domain = ['!'] + domain
|
||||
return domain
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 特殊权限可见:人事专员 / 考勤-用户 用户组可查看对应(仅本公司)流程
|
||||
# ------------------------------------------------------------------
|
||||
@api.depends_context('uid', 'company')
|
||||
@api.depends('approvals_group_id', 'company_id')
|
||||
def _compute_special_member_visible(self):
|
||||
user = self.env.user
|
||||
hr_group = self.env['res.groups'].sudo().search([('name', '=', '本部-角色-人事专员')], limit=1)
|
||||
kq_group = self.env['res.groups'].sudo().search([('name', '=', '考勤-用户')], limit=1)
|
||||
is_hr_user = bool(hr_group and user in hr_group.users)
|
||||
is_kq_user = bool(kq_group and user in kq_group.users)
|
||||
active_company_ids = self.env.companies.ids
|
||||
for record in self:
|
||||
visible = False
|
||||
if record.approvals_group_id and record.company_id.id in active_company_ids:
|
||||
group_name = record.approvals_group_id.name
|
||||
if group_name == '人事' and is_hr_user:
|
||||
visible = True
|
||||
elif group_name == '考勤' and is_kq_user:
|
||||
visible = True
|
||||
record.special_member_visible = visible
|
||||
|
||||
def _search_special_member_visible(self, operator, value):
|
||||
user = self.env.user
|
||||
hr_group = self.env['res.groups'].sudo().search([('name', '=', '本部-角色-人事专员')], limit=1)
|
||||
kq_group = self.env['res.groups'].sudo().search([('name', '=', '集团-角色-考勤')], limit=1)
|
||||
is_hr_user = bool(hr_group and user in hr_group.users)
|
||||
is_kq_user = bool(kq_group and user in kq_group.users)
|
||||
company_ids = self.env.companies.ids
|
||||
|
||||
# 注意:必须用扁平前缀形式(&/| 放在 domain 顶层),
|
||||
# 不能把 ['&', ...] 作为子列表元素,否则 Odoo 会把它当叶子、把 & 当成字段名报错。
|
||||
parts = []
|
||||
if is_hr_user:
|
||||
parts.append(['&', ('approvals_group_id.name', '=', '人事'), ('company_id', 'in', company_ids)])
|
||||
if is_kq_user:
|
||||
parts.append(['&', ('approvals_group_id.name', '=', '考勤'), ('company_id', 'in', company_ids)])
|
||||
|
||||
if not parts:
|
||||
# 当前用户不属于任何特殊权限组,恒不满足
|
||||
domain = [('id', '=', False)]
|
||||
else:
|
||||
domain = ['|'] * (len(parts) - 1)
|
||||
for grp in parts:
|
||||
domain += grp
|
||||
|
||||
if (operator == '=' and not value) or (operator == '!=' and value):
|
||||
domain = ['!'] + domain
|
||||
return domain
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 部门查询可见(排除考勤/人事):本部门数据 且 审批分组不是考勤/人事
|
||||
# ------------------------------------------------------------------
|
||||
@api.depends_context('uid', 'company')
|
||||
@api.depends('member_of_department', 'approvals_group_id')
|
||||
def _compute_dept_query_visible(self):
|
||||
for record in self:
|
||||
record.dept_query_visible = bool(
|
||||
record.member_of_department
|
||||
and record.approvals_group_id
|
||||
and record.approvals_group_id.name not in ('考勤', '人事')
|
||||
)
|
||||
|
||||
def _search_dept_query_visible(self, operator, value):
|
||||
# 本部门数据 且 审批分组不是考勤/人事(member_of_department 由 search 方法内联展开,无嵌套)
|
||||
domain = ['&',
|
||||
('approvals_group_id.name', 'not in', ['考勤', '人事']),
|
||||
('member_of_department', '=', True)]
|
||||
if (operator == '=' and not value) or (operator == '!=' and value):
|
||||
domain = ['!'] + domain
|
||||
return domain
|
||||
|
||||
@api.model
|
||||
def create(self, vals_list):
|
||||
res = super().create(vals_list)
|
||||
|
||||
@@ -459,9 +459,15 @@
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">soong.workflow.record</field>
|
||||
<field name="view_mode">tree,kanban,search</field>
|
||||
<!-- 部门流程查询:只看"自己发起的(create_uid=uid)"或"自己作为审批人/经办人参与的(users_ids包含uid)" -->
|
||||
<!-- 删除原 member_of_department 分支,避免普通用户看到同部门其他同事发起的流程 -->
|
||||
<field name="domain">[('reclaim_state', '=', False), ('approve_state','!=','start'), '|', ('create_uid', '=', uid), ('users_ids', 'in', [uid])]</field>
|
||||
<field name="domain">[
|
||||
('reclaim_state', '=', False),
|
||||
('approve_state', '!=', 'start'),
|
||||
'|',
|
||||
'|',
|
||||
('users_ids', 'in', [uid]),
|
||||
('dept_query_visible', '=', True),
|
||||
('special_member_visible', '=', True)
|
||||
]</field>
|
||||
<field name="context">{'search_default_my_department_shifts': True, 'default_order': 'display_end_time desc'}</field>
|
||||
<field name="search_view_id" ref="soong_workflow_record_search1"/>
|
||||
<field name="view_id" ref="soong_workflow_record_department_tree"/>
|
||||
|
||||
@@ -48,7 +48,11 @@ class SoongWorkflowCommentWizard(models.TransientModel):
|
||||
employee_ids = fields.Many2many('hr.employee', 'employee_ids_rel', 'custom_id', 'employee_id', string="转交人员", store=True)
|
||||
circulated_employee_ids = fields.Many2many('hr.employee', 'circulated_employee_rel', 'custom_id', 'employee_id', help='只可以看不可以评论,看过以后状态自动变为已阅', string="传阅人员", store=True)
|
||||
dep_manager_employee_ids = fields.Many2many('hr.employee', 'dep_manager_employee_rel', 'custom_id', 'employee_id', string="承办", store=True)
|
||||
add_employee_ids = fields.Many2many('hr.employee', 'add_employee_rel', 'custom_id', 'employee_id', string="加签人员", help='点击确认以后评论的人员', store=True)
|
||||
add_employee_ids = fields.Many2many('hr.employee', 'add_employee_rel', 'custom_id', 'employee_id', string="加签人员", help='点击确认以后评论的人员', store=True, domain="[('id', 'in', add_employee_filter_ids)]")
|
||||
add_employee_filter_ids = fields.Many2many('hr.employee', 'add_employee_filter_rel', 'custom_id', 'employee_id', string="加签过滤人员",
|
||||
default=lambda self: self._default_add_employee_filter_ids(),
|
||||
help='当前登录人所在部门及子部门(递归)的员工,用于过滤加签人员可选范围')
|
||||
is_return = fields.Boolean('是否返回', help='勾选之后,加签返回自己')
|
||||
supervising_employee_ids = fields.Many2many('hr.employee', 'supervising_employee_rel', 'custom_id', 'employee_id', string="督办人员", store=True)
|
||||
approval_concatenation = fields.Selection([('chuan', '串申'), ('bing', '并申')], string="审批形式",
|
||||
help='并:任何人均给意见,最后一个完成的人转交到下一节点.'
|
||||
@@ -133,6 +137,35 @@ class SoongWorkflowCommentWizard(models.TransientModel):
|
||||
])
|
||||
self.employee_ids2 = self.env['hr.employee'].search(domain)
|
||||
|
||||
def _default_add_employee_filter_ids(self):
|
||||
"""获取当前登录人所在部门及子部门(递归)的员工,作为加签人员的可选范围。
|
||||
|
||||
参考 yuthon_notice._constrains_employee_related_fields 中的
|
||||
get_department_employees(department_id),递归获取部门及其所有子部门下的员工。
|
||||
"""
|
||||
department = self.env.user.department_id
|
||||
if not department:
|
||||
return self.env['hr.employee']
|
||||
|
||||
result = self.env['hr.employee']
|
||||
|
||||
def collect(dept):
|
||||
nonlocal result
|
||||
# 当前部门(含多部门字段 department_ids)下的员工
|
||||
emps = self.env['hr.employee'].search([
|
||||
('company_id', '=', self.env.user.company_id.id),
|
||||
'|',
|
||||
('department_id', '=', dept.id),
|
||||
('department_ids', 'in', dept.ids),
|
||||
])
|
||||
result |= emps
|
||||
# 递归处理子部门(部门及以下)
|
||||
for child in dept.child_ids:
|
||||
collect(child)
|
||||
|
||||
collect(department)
|
||||
return result
|
||||
|
||||
@api.depends('comment_note_id', 'comment_note')
|
||||
def _compute_comment(self):
|
||||
for record in self:
|
||||
@@ -754,7 +787,7 @@ class SoongWorkflowCommentWizard(models.TransientModel):
|
||||
# 是否都完成了
|
||||
all_done = all(log.approval_state == "2" for log in batch_logs)
|
||||
# 如果都完成 → 创建一条新日志给加签发起人
|
||||
if all_done:
|
||||
if all_done and self.is_return:
|
||||
log_vals = {
|
||||
"model": self.res_model,
|
||||
"res_id": self.res_id,
|
||||
|
||||
@@ -72,9 +72,10 @@
|
||||
<label for="scope_type" string="范围"/>
|
||||
<field name="scope_type" nolabel="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="is_return"/>
|
||||
<field name="add_employee_ids" invisible="node_btn_name == '退回'"
|
||||
widget="many2many_tags" options="{'no_create': True}"
|
||||
domain="[('id', 'in', employee_ids2)]"/>
|
||||
domain="[('id', 'in', add_employee_filter_ids)]"/>
|
||||
</group>
|
||||
</group>
|
||||
<group invisible="node_btn_name != '结束'">
|
||||
@@ -152,6 +153,7 @@
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="employee_ids1" widget="many2many_tags" string="人员" invisible="1"/>
|
||||
<field name="employee_ids2" widget="many2many_tags" invisible="1"/>
|
||||
<field name="add_employee_filter_ids" widget="many2many_tags" invisible="1"/>
|
||||
<field name="employee_ids" widget="many2many_tags" string="人员"
|
||||
domain="[('id', 'in', employee_ids1)]"
|
||||
options="{'no_create': True}"
|
||||
|
||||
Reference in New Issue
Block a user