Merge pull request !11487 from 李鹏宇/dev
This commit is contained in:
李鹏宇
2026-05-14 06:59:17 +00:00
committed by Gitee
6 changed files with 406 additions and 134 deletions
+5 -9
View File
@@ -91,15 +91,11 @@ class SoongWorkflow(models.Model):
soong_ids = self.env["soong.workflow"].browse(
self._context.get('active_ids', self._context.get('active_id'))
)
for node in soong_ids.node_ids:
confirm_buttons = node.button_ids.filtered(lambda btn: btn.name == '确认')
if not confirm_buttons:
self.env['soong.workflow.node.button'].create({
'node_id': node.id,
'name': '确认',
'action_type': 'code',
"has_comment": True
})
for workflow in soong_ids:
nodes = workflow.node_ids.sorted('sequence')
for node in nodes[1:]:
node.is_apostille = True
node.onchange_is_apostille()
def change_opinions_wizard(self):
soong_ids = self.env["soong.workflow"].browse(
@@ -47,6 +47,8 @@ class SoongWorkflowLog(models.Model):
for rec in self:
if rec.name == '归档':
rec.name = '归档'
elif rec.name == '加签':
rec.name = '加签'
elif rec.node_id:
rec.name = "%(node_id_name)s" % {"node_id_name": rec.node_id.name}
else:
+108 -52
View File
@@ -90,6 +90,46 @@ class SoongWorkflowMixin(models.AbstractModel):
is_end = fields.Boolean(string="未结束", compute='_compute_is_confirm', store=False,)
is_done = fields.Boolean(string="已办", compute='_compute_is_done', store=False,)
is_send = fields.Boolean(string="是否分发", compute='_compute_is_send', store=False,)
is_show_add_sign = fields.Boolean(string="显示加签按钮", compute='_compute_is_show_add_sign')
is_show_transfer = fields.Boolean(string="显示加签确认按钮", compute='_compute_is_show_transfer')
def _compute_is_show_add_sign(self):
for record in self:
record.is_show_add_sign = True
domain_hide_01 = [
('workflow_id', '=', record.workflow_id.id),
('res_id', '=', record.id),
('name', '=', '加签'),
('approval_state', 'in', ['0', '1']),
]
has_01 = record.log_ids.search(domain_hide_01)
domain_hide_done = [
('workflow_id', '=', record.workflow_id.id),
('res_id', '=', record.id),
('name', '=', '加签'),
('approval_state', '=', '2'),
('done_by', '=', self.env.user.id),
]
has_done = record.log_ids.search(domain_hide_done)
if has_01 or has_done:
record.is_show_add_sign = False
def _compute_is_show_transfer(self):
for record in self:
record.is_show_transfer = False
domain_has_sign = [
('workflow_id', '=', record.workflow_id.id),
('res_id', '=', record.id),
('name', '=', '加签'),
('approval_state', 'in', ['0', '1']),
('done_by', '=', self.env.user.id),
]
has_sign_ok = record.log_ids.search(domain_has_sign)
if has_sign_ok:
record.is_show_transfer = True
def _compute_is_send(self):
for record in self:
@@ -365,60 +405,60 @@ class SoongWorkflowMixin(models.AbstractModel):
cx.update({"active_id": self.id, "active_ids": self.ids})
wkf_btn_obj = self.env["soong.workflow.node.button"]
btn_rec = wkf_btn_obj.search([("btn_key", "=", cx.get("btn_key", False))])
# 优化弹窗
# # 优化弹窗
if btn_rec:
log_obj = self._create_update_logs(btn_rec)
# 判断加签
if btn_rec.name in ["加签"]:
# 弹窗 进行填写 人员
wizard = self.env.ref("soong_workflow.view_soong_workflow_apostille_wizard")
return {
"name": _("添加加签人员"),
"type": "ir.actions.act_window",
"view_mode": "form",
"res_model": "soong.workflow.apostille.wizard",
"views": [(wizard.id, "form")],
"view_id": wizard.id,
"target": "new",
"context": {
"default_res_id": self.id,
"default_res_model": self._name,
"default_log_ids": log_obj.ids,
"default_node_btn_id": btn_rec.id,
},
}
if btn_rec.name in ["加签确认"]:
# 弹窗 进行填写 人员
wizard = self.env.ref("soong_workflow.view_soong_workflow_apostille_ok_wizard")
return {
"name": _("添加加签人员"),
"type": "ir.actions.act_window",
"view_mode": "form",
"res_model": "soong.workflow.apostille.ok.wizard",
"views": [(wizard.id, "form")],
"view_id": wizard.id,
"target": "new",
"context": {
"default_res_id": self.id,
"default_res_model": self._name,
"default_log_ids": log_obj.ids,
"default_node_btn_id": btn_rec.id,
},
}
if btn_rec.name not in ["加签", "加签确认"]:
# 判断当前是否所有加签都已经结束
apostille_log_obj = self.sudo().env["soong.workflow.log"].search(
[
("model", "=", self._name),
("res_id", "=", self.id),
("node_id", "=", btn_rec.node_id.id),
("workflow_id", "=", btn_rec.workflow_id.id),
("node_btn_name", "=", "2"),
("approval_state", "!=", "2")
]
)
if apostille_log_obj:
raise UserError("当前加签人员还有没有审批完成的!")
# # 判断加签
# if btn_rec.name in ["加签"]:
# # 弹窗 进行填写 人员
# wizard = self.env.ref("soong_workflow.view_soong_workflow_apostille_wizard")
# return {
# "name": _("添加加签人员"),
# "type": "ir.actions.act_window",
# "view_mode": "form",
# "res_model": "soong.workflow.apostille.wizard",
# "views": [(wizard.id, "form")],
# "view_id": wizard.id,
# "target": "new",
# "context": {
# "default_res_id": self.id,
# "default_res_model": self._name,
# "default_log_ids": log_obj.ids,
# "default_node_btn_id": btn_rec.id,
# },
# }
# if btn_rec.name in ["加签确认"]:
# # 弹窗 进行填写 人员
# wizard = self.env.ref("soong_workflow.view_soong_workflow_apostille_ok_wizard")
# return {
# "name": _("添加加签人员"),
# "type": "ir.actions.act_window",
# "view_mode": "form",
# "res_model": "soong.workflow.apostille.ok.wizard",
# "views": [(wizard.id, "form")],
# "view_id": wizard.id,
# "target": "new",
# "context": {
# "default_res_id": self.id,
# "default_res_model": self._name,
# "default_log_ids": log_obj.ids,
# "default_node_btn_id": btn_rec.id,
# },
# }
# if btn_rec.name not in ["加签", "加签确认"]:
# # 判断当前是否所有加签都已经结束
# apostille_log_obj = self.sudo().env["soong.workflow.log"].search(
# [
# ("model", "=", self._name),
# ("res_id", "=", self.id),
# ("node_id", "=", btn_rec.node_id.id),
# ("workflow_id", "=", btn_rec.workflow_id.id),
# ("node_btn_name", "=", "2"),
# ("approval_state", "!=", "2")
# ]
# )
# if apostille_log_obj:
# raise UserError("当前加签人员还有没有审批完成的!")
# 继续正常流程
# if btn_rec.has_comment:
return self.with_context(cx)._add_comment(log_obj, btn_rec)
@@ -1206,12 +1246,17 @@ class SoongWorkflowMixin(models.AbstractModel):
if button.name == "转交":
btn_exec_action_el.set("class", "btn btn-transfer")
invisible += " or is_done"
if button.name == "加签确认":
invisible += "or not is_show_transfer"
if button.name == "收回":
btn_exec_action_el.set("class", "btn btn-recall")
id_el = etree.Element("field")
id_el.set("name", "log_ids")
id_el.set("invisible", "1")
invisible += " or not log_ids or not is_back"
if button.name == "加签":
btn_exec_action_el.set("class", "btn btn-recall")
invisible += "or not is_show_add_sign"
if button.name == '归档':
btn_exec_action_el.set("class", "btn btn-archive")
invisible += "or not is_active"
@@ -1308,6 +1353,17 @@ class SoongWorkflowMixin(models.AbstractModel):
send_el.set("invisible", "1")
header_el.append(send_el)
sign_el = etree.Element("field")
sign_el.set("name", "is_show_add_sign")
sign_el.set("invisible", "1")
header_el.append(sign_el)
is_transfer_el = etree.Element("field")
is_transfer_el.set("name", "is_show_transfer")
is_transfer_el.set("invisible", "1")
header_el.append(is_transfer_el)
done_el = etree.Element("field")
done_el.set("name", "is_done")
done_el.set("invisible", "1")
@@ -45,7 +45,7 @@ class SoongWorkflowCommentWizard(models.TransientModel):
employee_trans_domain_ids = fields.Many2many('hr.employee', 'employee_trans_domain_ids_rel', string="传阅人员", store=True)
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)
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)
supervising_employee_ids = fields.Many2many('hr.employee', 'supervising_employee_rel', 'custom_id', 'employee_id', string="督办人员", store=True)
@@ -54,38 +54,81 @@ class SoongWorkflowCommentWizard(models.TransientModel):
'串:都会收到消息,但任意一个人转交后,即到下一节点,其他人将不再显示,相当于收回.')
is_automatic = fields.Boolean('是否自动匹配')
company_id = fields.Many2one('res.company', '公司', default=lambda self: self.env.user.company_id)
is_this_company = fields.Boolean('本公司', default=True)
scope_type = fields.Selection(
[
('company', '本公司'),
('group', '本集团'),
('department', '本部门'),
],
string='范围类型',
default='company',
required=True,
)
employee_ids1 = fields.Many2many('hr.employee', 'employee_ids1_rel', 'custom_id1', 'employee_id1', string="人员范围", store=True)
employee_ids2 = fields.Many2many('hr.employee', 'employee_ids2_rel', 'custom_id2', 'employee_id2', string="加签传阅人员过滤")
@api.onchange('is_selection')
def _onchange_is_selection(self):
domain = [('id', 'in', self.employee_ids1.ids)]
if self.is_selection:
if self.is_this_company:
domain.append(('company_id', '=', self.company_id.id))
all_employees = self.env['hr.employee'].search(domain)
self.employee_ids = all_employees
else:
if not self.employee_ids1:
self.employee_ids = False
return
domain = [('id', 'in', self.employee_ids1.ids)]
if self.scope_type == 'company':
domain.append(('company_id', '=', self.company_id.id))
elif self.scope_type == 'group':
pass
elif self.scope_type == 'department':
department = self.env.user.department_id
if department:
all_depts = department.child_ids | department
domain.extend([
('company_id', '=', self.company_id.id),
'|',
('department_id', 'in', all_depts.ids),
('department_ids', 'in', all_depts.ids),
])
all_employees = self.env['hr.employee'].search(domain)
self.employee_ids = all_employees if self.is_selection else False
@api.onchange('employee_ids1')
@api.onchange('scope_type', 'employee_ids1', 'department_id', 'company_id')
def _onchange_employee_ids1(self):
if not self.employee_ids1:
self.employee_ids = False
return
filtered_employees = self.employee_ids1
if self.is_this_company:
# 范围过滤
if self.scope_type == 'company':
filtered_employees = self.employee_ids1.filtered(
lambda emp: emp.company_id.id == self.company_id.id
lambda e: e.company_id == self.company_id
)
elif self.scope_type == 'department':
department = self.env.user.department_id
if department:
all_depts = department.child_ids | department
filtered_employees = self.employee_ids1.filtered(
lambda e: e.department_id in all_depts or any(d in all_depts for d in e.department_ids)
)
if len(filtered_employees) == 1:
self.employee_ids = filtered_employees
else:
domain = [('id', 'in', self.employee_ids1.ids)]
if self.is_selection:
if self.is_this_company:
domain.append(('company_id', '=', self.company_id.id))
all_employees = self.env['hr.employee'].search(domain)
self.employee_ids = all_employees
else:
self.employee_ids = False
return
@api.onchange('scope_type', 'department_id', 'company_id')
def _onchange_employee_ids2(self):
domain = []
if self.scope_type == 'company':
domain.append(('company_id', '=', self.company_id.id))
elif self.scope_type == 'department':
department = self.env.user.department_id
if department:
all_depts = department.child_ids | department
domain.extend([
('company_id', '=', self.company_id.id),
'|',
('department_id', 'in', all_depts.ids),
('department_ids', 'in', all_depts.ids),
])
self.employee_ids2 = self.env['hr.employee'].search(domain)
@api.depends('comment_note_id', 'comment_note')
def _compute_comment(self):
@@ -170,9 +213,9 @@ class SoongWorkflowCommentWizard(models.TransientModel):
record.is_selection = False
if self.node_btn_name == '退回':
record.is_this_company = False
record.scope_type = 'group'
else:
record.is_this_company = True
record.scope_type = 'company'
if record.node_btn_id.employee_ids and record.node_btn_id.is_carbon_copy:
record.circulated_employee_ids = record.node_btn_id.employee_ids
@@ -259,8 +302,6 @@ class SoongWorkflowCommentWizard(models.TransientModel):
button = target_btn
break
if button:
if button.is_automatic_group:
record.is_this_company = False
if button.is_node_automatic:
record.is_selection = True
record._onchange_is_selection()
@@ -577,6 +618,123 @@ class SoongWorkflowCommentWizard(models.TransientModel):
user_id=employee.wecom_userid,
title=record_id._description + "退回",
description=description, url=url, btntxt="查看详情")
if self.node_btn_name == '加签':
current_node_log = self.sudo().env["soong.workflow.log"].search(
[
("model", "=", self.res_model),
("res_id", "=", self.res_id),
("done_by", "=", self.env.user.id),
("node_id", "=", self.node_btn_id.node_id.id),
],
order="create_date DESC",
limit=1
)
current_node_log.write({
"comment": self.comment,
"approval_state": "2", # 已完成
'document_ids': [(6, 0, self.document_ids.ids)],
"lase_click_date": fields.Datetime.now()
})
title = record_id._description
action_id = self.env['ir.actions.act_window'].search([('res_model', '=', self.res_model)])[0]
for employee_id in self.add_employee_ids:
self.sudo().env["soong.workflow.log"].create({
'name': '加签',
"code": self.code,
"model": self.res_model,
"res_id": self.res_id,
"node_id": self.node_btn_id.node_id.id,
"workflow_id": self.node_btn_id.workflow_id.id,
"done_by": employee_id.user_id.id,
"node_btn_id": self.node_btn_id.id,
"approval_state": "0",
})
url = f'https://oa.thtzjt.com/web#id={record_id.id}&cids=2&menu_id={record_id.id}&action={action_id.id}&model={self.res_model}&view_type=form'
self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa',
user_id=employee_id.wecom_userid,
title=record_id._description + "加签",
description=title, url=url,
btntxt="查看详情")
workflow_record_id = self.env['soong.workflow.record'].sudo().search([('res_id', '=', record_id.id),
('res_model', '=', record_id._name)
])
workflow_record_id.employee_ids = self.add_employee_ids
workflow_record_id.users_ids = [(4, employee.user_id.id) for employee in self.add_employee_ids if
employee.user_id]
if self.node_btn_name == '加签确认':
action_id = self.env['ir.actions.act_window'].search([('res_model', '=', self.res_model)])[0]
user_log = record_id.log_ids.filtered(
lambda log: log.done_by == self.env.user.id and log.node_btn_name != '1' and log.approval_state in ['0',
'1']
)
current_node_log = self.sudo().env["soong.workflow.log"].search(
[
("model", "=", self.res_model),
("res_id", "=", self.res_id),
("done_by", "=", self.env.user.id),
("node_id", "=", self.node_btn_id.node_id.id),
],
order="create_date DESC",
limit=1
)
current_node_log.write({
"comment": self.comment,
"approval_state": "2", # 已完成
'document_ids': [(6, 0, self.document_ids.ids)],
"lase_click_date": fields.Datetime.now()
})
log_obj = self.sudo().env["soong.workflow.log"]
node_id = self.node_btn_id.node_id.id
last_sign_log = log_obj.search([
("model", "=", self.res_model),
("res_id", "=", self.res_id),
("node_id", "=", node_id),
("name", "!=", "加签"),
], order="create_date DESC", limit=1)
# 如果没有加签日志,直接跳过
if not last_sign_log:
return
# 最新加签的经办人
last_sign_user = last_sign_log.done_by
# 2. 找到当前节点所有日志(排除最新加签那条)
all_logs = log_obj.search([
("model", "=", self.res_model),
("res_id", "=", self.res_id),
("node_id", "=", node_id),
("name", "=", "加签"),
("id", "!=", user_log.id),
])
# 其他人是否都完成了
all_other_done = all(log.approval_state == "2" for log in all_logs)
# 4. 如果满足 → 创建一条新日志给【最新加签的经办人】
if all_other_done:
log_obj.create({
"model": self.res_model,
"res_id": self.res_id,
"workflow_id": self.node_btn_id.workflow_id.id,
"node_id": node_id,
"done_by": last_sign_user.id, # 最新加签的经办人
"approval_state": "0",
"create_date": fields.Datetime.now(),
})
workflow_record_id = self.env['soong.workflow.record'].sudo().search([('res_id', '=', record_id.id),
(
'res_model', '=', record_id._name)
])
workflow_record_id.employee_ids = [(6, 0, [last_sign_user.employee_id.id])]
url = f'https://oa.thtzjt.com/web#id={record_id.id}&cids=2&menu_id={record_id.id}&action={action_id.id}&model={self.res_model}&view_type=form'
self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa',
user_id=last_sign_user.wecom_userid,
title=record_id._description,
description=record_id._description, url=url,
btntxt="查看详情")
if self.node_btn_name in ['结束', '确认']:
title = record_id._description
if 'Room Booking' == record_id._description:
@@ -863,47 +1021,75 @@ class SoongWorkflowCommentWizard(models.TransientModel):
record = self.env[self.res_model].search([('id', '=', self.res_id)])
is_admin = current_user.has_group('base.group_system') or current_user.has_group('base.group_admin')
log_ids = record.log_ids.sorted('sequence')
log_to_delete = log_ids.filtered(lambda log: log.name == record.state)
if self.res_model == 'yuthon.official.incoming.normal':
director_logs = log_ids.filtered(lambda log: '董事长' in (log.name or ''))
if len(director_logs) == 2:
log_to_delete = log_ids[-1:]
if not is_admin:
invalid_logs = log_to_delete.filtered(
lambda log: log.approval_state in ['1', '2'] and log.node_btn_name != '1'
)
if invalid_logs:
raise UserError('当前状态不可以收回')
total_log_count = len(log_ids)
deleted_log_count = len(log_to_delete)
prev_log_index = (total_log_count - deleted_log_count) - 1
other_log_index = total_log_count - deleted_log_count
if prev_log_index < 0 or prev_log_index >= len(log_ids):
raise UserError('无有效的上一级审批明细行,无法执行收回操作')
prev_log = log_ids[prev_log_index]
has_sign_log = log_ids.filtered(lambda log: log.name == '加签' and log.node_id.name == record.state)
if has_sign_log:
# 加签日志
for log in has_sign_log:
if log.approval_state != '0':
raise UserError('加签流程已处理,不可收回!')
log_to_delete = has_sign_log
# 3. 删除后剩下的最后一条日志(取最后一个)
remaining_logs = log_ids - log_to_delete
if not remaining_logs:
raise UserError('无上级审批节点,无法收回')
prev_log = remaining_logs[-1] # 删除后的最后一条
# 4. 要删除的经办人 ID 列表
done_by_list = [log.done_by.id for log in log_to_delete]
else:
# 无加签日志
log_to_delete = log_ids.filtered(lambda log: log.name == record.state)
if self.res_model == 'yuthon.official.incoming.normal':
director_logs = log_ids.filtered(lambda log: '董事长' in (log.name or ''))
if len(director_logs) == 2:
log_to_delete = log_ids[-1:]
if not is_admin:
invalid_logs = log_to_delete.filtered(
lambda log: log.approval_state in ['1', '2'] and log.node_btn_name != '1'
)
if invalid_logs:
pass
total_log_count = len(log_ids)
deleted_log_count = len(log_to_delete)
prev_log_index = (total_log_count - deleted_log_count) - 1
other_log_index = total_log_count - deleted_log_count
if prev_log_index < 0 or prev_log_index >= len(log_ids):
raise UserError('无有效的上一级审批明细行,无法执行收回操作')
prev_log = log_ids[prev_log_index]
done_by_list = []
for index in range(other_log_index):
done_by_list.append(log_ids[index].done_by.id)
related_record = self.env[self.res_model].browse(self.res_id)
done_by_list = []
for index in range(other_log_index):
done_by_list.append(log_ids[index].done_by.id)
if hasattr(related_record, 'self_users_ids'):
related_record.self_users_ids = [(6, 0, [prev_log.done_by.id])]
self.env['soong.workflow.record'].search([('code', '=', record.code)]).write(
{"employee_ids": [(6, 0, [prev_log.done_by.employee_ids.id])],
"users_ids": [(6, 0, done_by_list)],
'soong_state': 'to_do'
})
# 核心写入:使用删除后的最后一条经办人
self.env['soong.workflow.record'].search([('code', '=', record.code)]).write({
"employee_ids": [(6, 0, [prev_log.done_by.employee_id.id])],
"users_ids": [(6, 0, done_by_list)] if not has_sign_log else [(3, user_id) for user_id in done_by_list],
'soong_state': 'to_do'
})
# 消息回退 + 删除日志
for log_delete in log_to_delete:
self.sudo().env["wecom.apps"].back_message(log_delete.msg_id, category='approval')
log_to_delete.unlink()
if record.log_ids2:
for log_id2 in record.log_ids2:
self.sudo().env["wecom.apps"].back_message(log_id2.msg_id, category='approval')
record.log_ids2.unlink()
# 把最后一条日志置为处理中
prev_log.write({'approval_state': '1'})
record.write({'state': prev_log.name,
'work_end': False,
})
# 回退状态
record.write({
'state': prev_log.name,
'work_end': False,
})
if self.node_btn_name == '归档':
menu_id = self.env['ir.ui.menu'].search([('name', '=', '行政收文')], limit=1)
action_id = self.env['ir.actions.act_window'].search([('res_model', '=', self.res_model)])[0]
@@ -14,7 +14,7 @@
<field name="user_role_ids"/>
<field name="comment"/>
</group>
<group invisible="node_btn_name in ['分发', '结束', '收回', '确认', '归档']">
<group invisible="node_btn_name in ['分发', '结束', '收回', '确认', '归档', '加签', '加签确认']">
<div class="oe_comment_block"
style=" width:1200%; border: 1px solid #dee2e6; border-radius: 4px; padding: 12px; margin-bottom: 16px;">
<label for="comment_note_id" string="常用意见"
@@ -43,9 +43,39 @@
<field name="document_ids" widget="preview_many2many" force_save="1"/>
</group>
<group>
<field name="is_this_company"/>
<field name="scope_type"/>
<field name="circulated_employee_ids" widget="many2many_tags" options="{'no_create': True}"
domain="[('company_id', '=', company_id)] if is_this_company else []"/>
domain="[('id', 'in', employee_ids2)]"/>
</group>
</group>
<group invisible="node_btn_name != '加签确认'">
<div class="oe_comment_block"
style=" width:1200%; border: 1px solid #dee2e6; border-radius: 4px; padding: 12px; margin-bottom: 16px;">
<label for="comment_note_id" string="加签意见"
style="font-weight: bold; margin-bottom: 8px; display: block;"/>
<field name="comment_note_id" class="mb-3" style="width: 100%;" options="{'no_create': True}"
domain="[('note_setting_id.users_role_ids', 'in', user_role_ids)]"/>
<field name="comment_note" placeholder="请输入意见内容..." style="width: 100%;"/>
</div>
</group>
<group invisible="node_btn_name != '加签'">
<div class="oe_comment_block"
style=" width:1200%; border: 1px solid #dee2e6; border-radius: 4px; padding: 12px; margin-bottom: 16px;">
<label for="comment_note_id" string="意见"
style="font-weight: bold; margin-bottom: 8px; display: block;"/>
<field name="comment_note_id" class="mb-3" style="width: 100%;" options="{'no_create': True}"
domain="[('note_setting_id.users_role_ids', 'in', user_role_ids)]"/>
<field name="comment_note" placeholder="请输入意见内容..." style="width: 100%;"/>
</div>
<group>
<label for="scope_type" string="范围"/>
<field name="scope_type" nolabel="1"/>
<label for="is_selection" string="是否自动选择"/>
<field name="is_selection" nolabel="1"/>
<field name="company_id" invisible="1"/>
<field name="add_employee_ids" invisible="node_btn_name == '退回'"
widget="many2many_tags" options="{'no_create': True}"
domain="[('id', 'in', employee_ids2)]"/>
</group>
</group>
<group invisible="node_btn_name != '结束'">
@@ -63,7 +93,7 @@
<group>
<field name="document_ids" widget="preview_many2many"/>
<field name="circulated_employee_ids" widget="many2many_tags" options="{'no_create': True}"
domain="[('company_id', '=', company_id)] if is_this_company else []"/>
domain="[('id', 'in', employee_ids2)]"/>
</group>
</group>
<group invisible="node_btn_name != '确认'">
@@ -77,7 +107,7 @@
</div>
<group>
<field name="circulated_employee_ids" widget="many2many_tags" options="{'no_create': True}"
domain="[('company_id', '=', company_id)] if is_this_company else []"/>
domain="[('id', 'in', employee_ids2)]"/>
</group>
</group>
<group invisible="node_btn_name != '分发'">
@@ -90,7 +120,7 @@
<field name="comment_note" placeholder="请输入意见内容..." style="width: 100%;"/>
</div>
</group>
<group invisible="node_btn_name in ['分发', '结束', '收回', '确认', '归档']">
<group invisible="node_btn_name in ['分发', '结束', '收回', '确认', '归档', '加签', '加签确认']">
<field name="user_id" invisible="1"/>
<field name="user_role_ids" widget="many2many_tags" invisible="1"/>
<field name="node_btn_id" invisible="1"/>
@@ -100,7 +130,7 @@
<field name="is_automatic" invisible="1"/>
<field name="is_supervising" invisible="1"/>
</group>
<group col="2" invisible="node_btn_name in ['分发', '结束', '收回', '确认', '归档']">
<group col="2" invisible="node_btn_name in ['分发', '结束', '收回', '确认', '归档', '加签', '加签确认']">
<group>
<!-- 转交人员 -->
<field name="workflow_record_id" string="测试流程record" invisible="1"/>
@@ -115,19 +145,20 @@
options="{'no_open': True, 'fg_color': 'red'}" widget="radio" force_save="1"/>
</group>
<group>
<label for="is_this_company" string="本公司"/>
<field name="is_this_company" nolabel="1"/>
<label for="scope_type" string="范围"/>
<field name="scope_type" nolabel="1"/>
<label for="is_selection" string="是否自动选择"/>
<field name="is_selection" nolabel="1"/>
<field name="company_id" invisible="1"/>
<field name="employee_ids1" widget="many2many_tags" string="人员范围" invisible="1"/>
<field name="employee_ids" widget="many2many_tags" string="人员范围"
domain="[('company_id', '=', company_id), ('id', 'in', employee_ids1)] if is_this_company else [('id', 'in', employee_ids1)]"
<field name="employee_ids1" widget="many2many_tags" string="人员" invisible="1"/>
<field name="employee_ids2" widget="many2many_tags"/>
<field name="employee_ids" widget="many2many_tags" string="人员"
domain="[('id', 'in', employee_ids1)]"
options="{'no_create': True}"
context="{'tree_view_ref':'yuthon_hr_employee.view_employee_phone_tree'}"/>
<field name="circulated_employee_ids" invisible="node_btn_name == '退回'"
widget="many2many_tags" options="{'no_create': True}"
domain="[('company_id', '=', company_id)] if is_this_company else []"/>
domain="[('id', 'in', employee_ids2)]"/>
</group>
</group>
<div invisible="node_btn_name != '收回'">
@@ -140,17 +171,17 @@
groups="yuthon_salary.group_jtbb_user"/>
</group>
<group>
<!-- 分发弹窗:本公司开关控制人员筛选范围 -->
<field name="is_this_company"/>
<!-- 分发弹窗:范围开关控制人员筛选范围 -->
<field name="scope_type"/>
</group>
<group>
<field name="dep_manager_employee_ids" widget="many2many_tags" string="承办"
options="{'no_create': True}"
domain="[('company_id', '=', company_id)] if is_this_company else []"/>
domain="[('id', 'in', employee_ids2)]"/>
</group>
<group>
<field name="circulated_employee_ids" widget="many2many_tags" options="{'no_create': True}"
domain="[('company_id', '=', company_id)] if is_this_company else []"/>
domain="[('id', 'in', employee_ids2)]"/>
</group>
<group>
<field name="supervising_employee_ids" widget="many2many_tags" invisible="not is_supervising"
+3 -2
View File
@@ -1069,8 +1069,9 @@ class HolidaysRequestBatch(models.Model):
record.holiday_allowance2 = record.holiday_allowance
if total_annual_leave_days > self.remaining_annual_leave:
raise UserError('年假天数额度不足,无法请假')
if total_compensatory_leave_days > self.remaining_compensatory_leave / 8:
raise UserError('补休天数额度不足,无法请假')
if total_compensatory_leave_days:
if total_compensatory_leave_days > self.remaining_compensatory_leave / 8:
raise UserError('补休天数额度不足,无法请假')
@api.onchange('leave_ids', 'hour_leave_ids', 'employee_id')