1474 lines
88 KiB
Python
1474 lines
88 KiB
Python
# -*- coding: utf-8 -*-
|
||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||
from email.policy import default
|
||
|
||
from odoo import fields, models, api
|
||
from odoo.exceptions import UserError, ValidationError
|
||
from datetime import datetime, date, time, timedelta
|
||
import logging
|
||
_logger = logging.getLogger(__name__)
|
||
|
||
|
||
class SoongWorkflowCommentWizard(models.TransientModel):
|
||
_name = "soong.workflow.comment.wizard"
|
||
_description = "Soong Workflow Comment Wizard"
|
||
_inherit = ['mail.thread.main.attachment', 'mail.activity.mixin']
|
||
_transient_max_count = 0
|
||
|
||
name = fields.Char(string="name")
|
||
res_model = fields.Char()
|
||
res_id = fields.Integer()
|
||
code = fields.Char()
|
||
|
||
log_ids = fields.Many2many(comodel_name="soong.workflow.log")
|
||
node_btn_id = fields.Many2one(comodel_name="soong.workflow.node.button")
|
||
node_btn_name = fields.Char(string="动作名称", related='node_btn_id.name')
|
||
user_id = fields.Many2one('res.users', string='用户', default=lambda self: self.env.user)
|
||
user_role_ids = fields.Many2many('soong.user.role', string="角色", compute='_compute_user_role_ids', store=True)
|
||
node_link_len = fields.Char(string="转交2")
|
||
is_supervising = fields.Boolean(string="是否督办")
|
||
comment_note_id = fields.Many2one('soong.note', string="常用意见")
|
||
comment_note = fields.Text(string="意见")
|
||
illustrate = fields.Text(string="说明")
|
||
comment = fields.Char(compute='_compute_comment', store=True)
|
||
state_list = fields.Char(string="状态列表")
|
||
record_id = fields.Integer()
|
||
workflow_record_id = fields.Many2one('soong.workflow.record', string="流程")
|
||
is_selection = fields.Boolean(string="是否自动选择")
|
||
trans_link_id = fields.Many2one('trans.link', string='转交节点', ondelete='set null')
|
||
document_ids = fields.Many2many('ir.attachment', string="附件")
|
||
return_link_id = fields.Many2one('trans.link', string='退回节点', ondelete='set null')
|
||
invalid_link_ids = fields.Many2many(
|
||
'trans.link',
|
||
string='跳过相同人员',
|
||
help='跳过相同人员的节点'
|
||
)
|
||
|
||
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)
|
||
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_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='并:任何人均给意见,最后一个完成的人转交到下一节点.'
|
||
'串:都会收到消息,但任意一个人转交后,即到下一节点,其他人将不再显示,相当于收回.')
|
||
is_automatic = fields.Boolean('是否自动匹配')
|
||
company_id = fields.Many2one('res.company', '公司', default=lambda self: self.env.user.company_id)
|
||
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', 'scope_type')
|
||
def _onchange_is_selection(self):
|
||
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('scope_type', 'department_id', 'company_id', 'employee_ids1')
|
||
def _onchange_employee_ids1(self):
|
||
if self.is_selection:
|
||
return
|
||
if not self.employee_ids1:
|
||
self.employee_ids = False
|
||
return
|
||
filtered_employees = self.employee_ids1
|
||
# 范围过滤
|
||
if self.scope_type == 'company':
|
||
filtered_employees = self.employee_ids1.filtered(
|
||
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
|
||
|
||
@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)
|
||
|
||
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:
|
||
comment_parts = []
|
||
if record.comment_note_id:
|
||
comment_parts.append(record.comment_note_id.name)
|
||
if record.comment_note:
|
||
comment_parts.append(record.comment_note)
|
||
record.comment = " ".join(comment_parts) if comment_parts else ""
|
||
|
||
@api.depends('user_id.employee_ids.user_role_ids', 'user_id.employee_ids.user_role_id')
|
||
def _compute_user_role_ids(self):
|
||
for record in self:
|
||
if record.user_id and record.user_id.employee_ids:
|
||
role_ids_from_employee = record.user_id.employee_ids.user_role_ids
|
||
role_id_from_field = record.user_id.employee_ids.user_role_id
|
||
if role_id_from_field:
|
||
record.user_role_ids = role_ids_from_employee | role_id_from_field
|
||
else:
|
||
record.user_role_ids = role_ids_from_employee
|
||
else:
|
||
record.user_role_ids = False
|
||
|
||
@api.onchange('record_id')
|
||
def _onchange_record_id(self):
|
||
record_id = self.env[self.res_model].search([('id', '=', self.res_id)])
|
||
self.record_id = record_id
|
||
|
||
@api.onchange('return_link_id')
|
||
def onchange_employee_ids(self):
|
||
record_id = self.env[self.res_model].search([('id', '=', self.res_id)])
|
||
for ret in self.return_link_id:
|
||
if ret.name in ['拟办', '申请人']:
|
||
if hasattr(record_id, 'user_id') and record_id.user_id:
|
||
employee_ids1 = self.env['hr.employee'].search([('user_id', '=', record_id.user_id.id)])
|
||
elif hasattr(record_id, 'users_id') and record_id.users_id:
|
||
employee_ids1 = self.env['hr.employee'].search([('user_id', '=', record_id.users_id.id)])
|
||
self.employee_ids1 = employee_ids1
|
||
elif self.node_btn_name == '退回':
|
||
target_log = record_id.log_ids.filtered(lambda l: l.name == ret.name)
|
||
if target_log and target_log.done_by:
|
||
if target_log.done_by:
|
||
employee = self.env['hr.employee'].sudo().search([('user_id', '=', target_log.done_by.id)], limit=1)
|
||
self.employee_ids1 = employee
|
||
else:
|
||
self.employee_ids1 = self.env['hr.employee']
|
||
|
||
# next_list = []
|
||
# workflow_id = self.return_link_id.node_button_id.workflow_id
|
||
# state_list = [i.node_name for i in workflow_id.node_ids]
|
||
# if ret.name == '询价':
|
||
# name = 'draft'
|
||
# else:
|
||
# name = ret.name
|
||
# self_state = state_list.index(name)
|
||
# button_ids = workflow_id.node_ids[self_state].button_ids
|
||
# for btn in button_ids:
|
||
# next_list.append(btn.name)
|
||
# if '转交' not in next_list:
|
||
# raise UserError('配置错误,请配置当前{}的转交按钮'.format(btn.name))
|
||
# else:
|
||
# if btn.is_automatic:
|
||
# employee_user_role_id = self.env['hr.employee'].search(
|
||
# ['|', ('user_role_id', '=', btn.users_role_id.id),
|
||
# ('user_role_id', 'in', btn.users_role_group_ids.user_role_ids.ids),
|
||
# ('department_id', '=', record_id.department_id.id)])
|
||
# self.employee_ids1 = employee_user_role_id
|
||
# else:
|
||
# employee_user_role_ids = self.env['hr.employee'].search(
|
||
# ['|', ('user_role_id', '=', btn.users_role_id.id),
|
||
# ('user_role_id', 'in', btn.users_role_group_ids.user_role_ids.ids),
|
||
# ])
|
||
# self.employee_ids1 = employee_user_role_ids
|
||
|
||
def _get_entrust_substitution(self, model_name):
|
||
"""返回 {委托人 user_id: 被委托人 hr.employee} 映射。
|
||
仅包含对当前模型(或在"全部流程"中)生效且在有效期内的流程委托(soong.workflow.entrust)。
|
||
"""
|
||
today = fields.Date.today()
|
||
substitution = {}
|
||
entrust_all = self.env['ir.model'].sudo().search([('model', '=', 'entrust.all')], limit=1)
|
||
model = self.env['ir.model'].sudo().search([('model', '=', model_name)], limit=1)
|
||
if not model and not entrust_all:
|
||
return substitution
|
||
entrusts = self.env['soong.workflow.entrust'].sudo().search([
|
||
('is_enable', '=', True),
|
||
('start_date', '<=', today),
|
||
'|',
|
||
('end_date', '>', today),
|
||
('end_date', '=', False)
|
||
])
|
||
for ent in entrusts:
|
||
model_ids = ent.model_ids.ids
|
||
# 命中"全部流程"(entrust.all) 或 当前业务模型
|
||
in_scope = (entrust_all and entrust_all.id in model_ids) or (model and model.id in model_ids)
|
||
if in_scope and ent.entrust_user_id and ent.entrust_user_id2:
|
||
delegatee = self.env['hr.employee'].sudo().search(
|
||
[('user_id', '=', ent.entrust_user_id2.id)], limit=1)
|
||
if delegatee:
|
||
substitution[ent.entrust_user_id.id] = delegatee
|
||
return substitution
|
||
|
||
@api.onchange('trans_link_id')
|
||
def onchange_trans_employee_ids(self):
|
||
for record in self:
|
||
# 先清空
|
||
record_id = self.env[record.res_model].browse(record.res_id) if record.res_model and record.res_id else None
|
||
ctx_links = self.env.context.get('all_workflow_links', [])
|
||
valid_links = self.env['trans.link'].browse(ctx_links) if isinstance(ctx_links, (list, tuple)) else ctx_links
|
||
|
||
record.is_selection = False
|
||
if self.node_btn_name == '退回':
|
||
record.scope_type = 'group'
|
||
else:
|
||
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
|
||
|
||
if not record.trans_link_id:
|
||
continue
|
||
|
||
# 排除规则:流程退回 不限制
|
||
if record_id and record_id.workflow_id:
|
||
has_exclude_log = record_id.log_ids.filtered(lambda l: l.node_btn_name == '1')
|
||
if not has_exclude_log:
|
||
# 1. 从 valid_links 里 匹配出 当前流程会经过的【必经节点】
|
||
current_mandatory_nodes = self.env['soong.workflow.node']
|
||
for link in valid_links:
|
||
link_node = record_id.workflow_id.node_ids.search([
|
||
('name', '=', link.name),
|
||
('workflow_id', '=', record_id.workflow_id.id)
|
||
], limit=1)
|
||
if link_node and link_node.is_mandatory_node:
|
||
current_mandatory_nodes |= link_node
|
||
|
||
if current_mandatory_nodes:
|
||
# 2. 取第一个必经节点
|
||
first_mandatory = current_mandatory_nodes.sorted('sequence')[0]
|
||
# 3. 只允许选择 <= 第一个必经节点 的链接
|
||
allow_links = self.env['trans.link']
|
||
for link in valid_links:
|
||
link_node = record_id.workflow_id.node_ids.search([
|
||
('name', '=', link.name),
|
||
('workflow_id', '=', record_id.workflow_id.id)
|
||
], limit=1)
|
||
if link_node and link_node.sequence <= first_mandatory.sequence:
|
||
allow_links |= link
|
||
|
||
# 4. 校验:选了必经节点之后的 → 报错
|
||
if record.trans_link_id not in allow_links:
|
||
record.trans_link_id = False
|
||
raise UserError(f"节点【{first_mandatory.name}】是必经节点,不可跳过!")
|
||
|
||
for link in record.trans_link_id:
|
||
employee_user_role_ids = self.env['hr.employee']
|
||
if link.name == '印章管理员':
|
||
if hasattr(record_id, 'type_stamp_ids'):
|
||
stamp_types = record_id.type_stamp_ids
|
||
if stamp_types:
|
||
user_ids = self.env['res.users']
|
||
for stamp in stamp_types:
|
||
user_ids |= stamp.user_ids
|
||
if user_ids:
|
||
employee_user_role_ids = self.env['hr.employee'].sudo().search([
|
||
('user_id', 'in', user_ids.ids)
|
||
])
|
||
else:
|
||
employee_user_role_ids = record_id._get_approvers_for_link(link, record_id)
|
||
workflow_id = link.node_button_id.workflow_id
|
||
node = workflow_id.node_ids.search([
|
||
('name', '=', link.name),
|
||
('workflow_id', '=', workflow_id.id)
|
||
], limit=1)
|
||
if node:
|
||
record.approval_concatenation = node.approval_concatenation
|
||
record.employee_trans_domain_ids = employee_user_role_ids
|
||
record.employee_ids1 = employee_user_role_ids
|
||
workflow_id = link.node_button_id.workflow_id
|
||
node = workflow_id.node_ids.search([
|
||
('name', '=', link.name),
|
||
('workflow_id', '=', workflow_id.id)
|
||
])
|
||
button_priority_list = ["分发", "下发", "转交", "结束"]
|
||
button = False
|
||
if node.button_ids:
|
||
for btn_name in button_priority_list:
|
||
for btn in node.button_ids:
|
||
if btn.name == btn_name: # 匹配优先级按钮名称
|
||
is_in_scope = True
|
||
if not btn.is_review_invisible:
|
||
button = btn
|
||
break
|
||
if btn.is_review_invisible:
|
||
domain = eval(btn.invisible_expression)
|
||
model = record_id.env[record_id._name]
|
||
matched = model.search(domain + [('id', '=', record_id.id)])
|
||
is_in_scope = bool(matched)
|
||
if is_in_scope:
|
||
target_btn = btn
|
||
button = target_btn
|
||
break
|
||
if button:
|
||
if button.is_node_automatic:
|
||
record.is_selection = True
|
||
else:
|
||
record.is_selection = False
|
||
record._onchange_is_selection()
|
||
|
||
def _send_workflow_notifications(self, partners=None):
|
||
""" 通知前端刷新红点、播放音频
|
||
:param partners: 需要通知的用户(res.partner),未传则通知所有
|
||
"""
|
||
bus_message = {'type': 'wkf_notify'}
|
||
notifications = [[partner, 'sun_badge_menu.reload_menu_data', [bus_message]] for partner in partners]
|
||
self.env["bus.bus"]._sendmany(notifications) # 浏览器叮咚
|
||
|
||
def add_comment(self):
|
||
self.ensure_one()
|
||
partners = self._get_all_employee_partners()
|
||
self._send_workflow_notifications(partners)
|
||
# 如果选择了常用意见,将使用信息追加到 soong.note 记录
|
||
if self.comment_note_id:
|
||
import pytz
|
||
from datetime import datetime
|
||
tz = pytz.timezone('Asia/Shanghai')
|
||
today = datetime.now(pytz.utc).astimezone(tz).strftime('%Y-%m-%d')
|
||
user_name = self.env.user.name
|
||
code = self.code or ''
|
||
note_name = self.comment_note_id.name or ''
|
||
new_line = f"{today} {code} {user_name} {note_name}"
|
||
old_info = self.comment_note_id.use_info or ''
|
||
updated_info = (old_info + '\n' + new_line) if old_info else new_line
|
||
self.comment_note_id.sudo().write({'use_info': updated_info})
|
||
cx = self.env.context.copy() or {}
|
||
record_id = self.env[self.res_model].search([('id', '=', self.res_id)])
|
||
is_admin = self.env.user.has_group('soong_workflow.group_soong_workflow_manager')
|
||
log_done_by_ids = [log.done_by.id for log in record_id.log_ids if log.done_by]
|
||
|
||
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),
|
||
("approval_state", 'in', ['0','1']),
|
||
],
|
||
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()
|
||
})
|
||
if hasattr(record_id, 'user_id') and record_id.user_id:
|
||
query_user_id = record_id.user_id
|
||
elif hasattr(record_id, 'users_id') and record_id.users_id:
|
||
query_user_id = record_id.users_id
|
||
description = f"标题:{record_id.name}\n申请人:{query_user_id.name}"
|
||
action_id = self.env['ir.actions.act_window'].search([('res_model', '=', self.res_model)])[0]
|
||
for employee_id in self.add_employee_ids:
|
||
next_node_log_records = 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,
|
||
"add_sign_by": self.env.user.id,
|
||
"is_return" : self.is_return,
|
||
"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'
|
||
result_data = self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa',
|
||
user_id=employee_id.wecom_userid,
|
||
title=record_id._description + "加签",
|
||
description=description, url=url,
|
||
btntxt="查看详情")
|
||
if result_data and 'msgid' in result_data[-1]:
|
||
msg_id = result_data[-1]['msgid']
|
||
target_logs = next_node_log_records.filtered(lambda l: l.done_by.id == employee_id.user_id.id)
|
||
if target_logs:
|
||
target_logs.msg_id = msg_id
|
||
|
||
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 == '转交' or (self.node_btn_name == '加签' and not self.is_return):
|
||
if self.res_model == 'issue.approval':
|
||
if self.trans_link_id.name != '申请人':
|
||
if record_id.issue_approval_ids:
|
||
for issue_library in record_id.issue_approval_ids:
|
||
issue_library.issue_library_id.issue_state = 'to_draft'
|
||
has_comment_note = bool(self.comment_note_id)
|
||
has_comment = bool(self.comment and self.comment.strip())
|
||
if not has_comment_note and not has_comment:
|
||
raise UserError('请填写备注')
|
||
if not self.employee_ids and self.trans_link_id:
|
||
raise UserError("必须有转交人员")
|
||
self_node_id = record_id.workflow_id.node_ids.search(
|
||
[('name', '=', record_id.state), ('workflow_id', '=', record_id.workflow_id.id)])
|
||
log = self.env['soong.workflow.log'].search([("model", "=", self.res_model),
|
||
("res_id", "=", self.res_id)])
|
||
query_user_id = self.env.user.id
|
||
if is_admin and record_id:
|
||
if hasattr(record_id, 'user_id') and record_id.user_id:
|
||
query_user_id = record_id.user_id.id
|
||
elif hasattr(record_id, 'users_id') and record_id.users_id:
|
||
query_user_id = record_id.users_id.id
|
||
if len(log) > 1 and is_admin:
|
||
current_node_log = self.sudo().env["soong.workflow.log"].search(
|
||
[("model", "=", self.res_model),
|
||
("res_id", "=", self.res_id),
|
||
("node_id", "=", self.node_btn_id.node_id.id)
|
||
],
|
||
order="lase_click_date DESC",
|
||
limit=1
|
||
)
|
||
else:
|
||
current_node_log = self.sudo().env["soong.workflow.log"].search(
|
||
[
|
||
("model", "=", self.res_model),
|
||
("res_id", "=", self.res_id),
|
||
("done_by", "=", query_user_id),
|
||
("node_id", "=", self.node_btn_id.node_id.id),
|
||
],
|
||
order="create_date DESC",
|
||
limit=1
|
||
)
|
||
# 创建或更新当前用户的审批记录
|
||
if not current_node_log:
|
||
self.sudo().env["soong.workflow.log"].create({
|
||
"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": query_user_id,
|
||
"node_btn_name": "0",
|
||
"node_btn_id": self.node_btn_id.id,
|
||
"approval_state": "2", # 已完成
|
||
"lase_click_date": fields.Datetime.now(),
|
||
"comment": self.comment,
|
||
})
|
||
else:
|
||
current_node_log.write({
|
||
"comment": self.comment,
|
||
"approval_state": "2", # 已完成
|
||
'document_ids': [(6, 0, self.document_ids.ids)],
|
||
"lase_click_date": fields.Datetime.now()
|
||
})
|
||
if current_node_log.node_btn_name == '3':
|
||
other_node_logs = self.sudo().env["soong.workflow.log"].search(
|
||
[("model", "=", self.res_model),
|
||
("res_id", "=", self.res_id),
|
||
("id", "!=", current_node_log.id),
|
||
("node_id", "=", self.node_btn_id.node_id.id)
|
||
])
|
||
for other_node_log in other_node_logs:
|
||
if getattr(other_node_log, 'msg_id', False):
|
||
self.sudo().env["wecom.apps"].back_message(other_node_log.msg_id, category='approval')
|
||
other_node_log.unlink()
|
||
|
||
if getattr(current_node_log, 'stamp_id', False):
|
||
same_stamp_logs = self.sudo().env["soong.workflow.log"].search(
|
||
[("model", "=", self.res_model),
|
||
("res_id", "=", self.res_id),
|
||
("id", "!=", current_node_log.id),
|
||
("node_id", "=", self.node_btn_id.node_id.id),
|
||
("stamp_id", "=", current_node_log.stamp_id.id),
|
||
("approval_state", "in", ['0', '1']),
|
||
])
|
||
for log_delete in same_stamp_logs:
|
||
if getattr(log_delete, 'msg_id', False):
|
||
self.sudo().env["wecom.apps"].back_message(log_delete.msg_id, category='approval')
|
||
same_stamp_logs.unlink()
|
||
|
||
# 印章分组审批:模型有 type_stamp_ids 字段且转交目标是「印章管理员」节点
|
||
record_has_stamps = hasattr(record_id, 'type_stamp_ids') and bool(record_id.type_stamp_ids)
|
||
is_transfer_to_stamp = self.trans_link_id and self.trans_link_id.name == '印章管理员'
|
||
is_stamp_reviewer = bool(current_node_log and getattr(current_node_log, 'stamp_id', False))
|
||
# 流程委托:当前模型(或"全部流程")且在有效期内的 {委托人 user_id: 被委托人 hr.employee}
|
||
entrust_substitution = self._get_entrust_substitution(self.res_model) if self.node_btn_name == '转交' else {}
|
||
|
||
if is_transfer_to_stamp and record_has_stamps:
|
||
# 场景1:转交到印章管理员节点,按章分组建待办(章间并审、章内串审)
|
||
next_node_id = record_id.workflow_id.node_ids.search([
|
||
('name', '=', self.trans_link_id.name),
|
||
('workflow_id', '=', record_id.workflow_id.id)
|
||
], limit=1)
|
||
# 同一人可能兼任多枚章,先按 user 去重(只保留第一枚章),避免重复待办
|
||
user_stamp_map = {}
|
||
for stamp in record_id.type_stamp_ids:
|
||
for user in stamp.user_ids:
|
||
if user.id not in user_stamp_map:
|
||
user_stamp_map[user.id] = stamp
|
||
all_user_ids = []
|
||
all_employee_ids = []
|
||
for user, stamp in user_stamp_map.items():
|
||
employee = self.env['hr.employee'].sudo().search([('user_id', '=', user)], limit=1)
|
||
if employee and employee.id not in all_employee_ids:
|
||
all_employee_ids.append(employee.id)
|
||
all_user_ids.append(user)
|
||
self.sudo().env["soong.workflow.log"].create({
|
||
"code": self.code,
|
||
"model": self.res_model,
|
||
"res_id": self.res_id,
|
||
"node_id": next_node_id.id,
|
||
"workflow_id": self.node_btn_id.workflow_id.id,
|
||
"done_by": user,
|
||
"node_btn_name": "4",
|
||
"stamp_id": stamp.id,
|
||
"approval_state": "0",
|
||
})
|
||
related_record = self.env[self.res_model].browse(self.res_id)
|
||
if hasattr(related_record, 'self_users_ids'):
|
||
related_record.self_users_ids = [(6, 0, all_user_ids)] if all_user_ids else [(5,)]
|
||
record_id.write({'state': self.trans_link_id.name})
|
||
workflow_record_id = self.env['soong.workflow.record'].sudo().search([('res_id', '=', record_id.id),
|
||
('res_model', '=', record_id._name)])
|
||
workflow_record_id.users_ids = [(4, uid) for uid in all_user_ids]
|
||
workflow_record_id.employee_ids = all_employee_ids
|
||
workflow_record_id.approve_state = "pending"
|
||
action_id = self.env['ir.actions.act_window'].search([('res_model', '=', self.res_model)])[0]
|
||
description = "标题: {}\n".format(record_id.name) + self.env.user.name + ' ' + str(fields.Datetime.now() + timedelta(hours=8))
|
||
for uid in all_user_ids:
|
||
employee = self.env['hr.employee'].sudo().search([('user_id', '=', uid)], limit=1)
|
||
if not employee:
|
||
continue
|
||
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.wecom_userid,
|
||
title=record_id._description + "印章审批",
|
||
description=description, url=url,
|
||
btntxt="查看详情")
|
||
|
||
# 检查是否为并审模式(印章节点的人提交时也走并审,实现章间并审)
|
||
elif is_stamp_reviewer or self.approval_concatenation == 'bing': # 并审模式
|
||
expected_employees = self.employee_ids
|
||
# 流程委托:把选中的委托人解析为实际审批人(被委托人)
|
||
delegation_targets = []
|
||
for selected_employee in expected_employees:
|
||
actual_employee = selected_employee
|
||
is_delegated = False
|
||
if selected_employee.user_id and selected_employee.user_id.id in entrust_substitution:
|
||
actual_employee = entrust_substitution[selected_employee.user_id.id]
|
||
is_delegated = True
|
||
delegation_targets.append((selected_employee, actual_employee, is_delegated))
|
||
effective_employees = self.env['hr.employee']
|
||
for selected_employee, actual_employee, is_delegated in delegation_targets:
|
||
if actual_employee:
|
||
effective_employees |= actual_employee
|
||
if record_id.log_ids2:
|
||
log_employee_ids = record_id.log_ids2.mapped('done_by.employee_id.id')
|
||
effective_employees = effective_employees.filtered(lambda emp: emp.id not in log_employee_ids)
|
||
|
||
# 查找下一个节点
|
||
if self.trans_link_id:
|
||
next_node_id = record_id.workflow_id.node_ids.search([
|
||
('name', '=', self.trans_link_id.name),
|
||
('workflow_id', '=', record_id.workflow_id.id)
|
||
])
|
||
|
||
completed_logs = self.sudo().env["soong.workflow.log"].search([
|
||
("model", "=", self.res_model),
|
||
("res_id", "=", self.res_id),
|
||
("node_id", "=", self.node_btn_id.node_id.id),
|
||
("node_btn_name", "=", "4"),
|
||
("approval_state", "!=", "2")
|
||
])
|
||
all_completed = len(completed_logs) == 0
|
||
next_node_log_records = self.env["soong.workflow.log"]
|
||
if all_completed:
|
||
for employee in effective_employees:
|
||
is_delegated = any(employee.id == actual_employee.id
|
||
for selected_employee, actual_employee, is_delegated in delegation_targets
|
||
if is_delegated)
|
||
# 检查该员工在下一节点是否已有记录
|
||
next_node_employee_log = self.sudo().env["soong.workflow.log"].search([
|
||
("model", "=", self.res_model),
|
||
("res_id", "=", self.res_id),
|
||
("node_id", "=", next_node_id.id),
|
||
('node_btn_name', '!=', '1'),
|
||
('approval_state', '!=', '2'),
|
||
("done_by", "=", employee.user_id.id)
|
||
])
|
||
if not next_node_employee_log:
|
||
# 创建初步记录,状态为"待审批"
|
||
next_node_employee_log = self.sudo().env["soong.workflow.log"].create({
|
||
"code": self.code,
|
||
"model": self.res_model,
|
||
"res_id": self.res_id,
|
||
"node_id": next_node_id.id,
|
||
"workflow_id": self.node_btn_id.workflow_id.id,
|
||
"done_by": employee.user_id.id,
|
||
"done_by_display": f"{employee.name}(委托人)" if is_delegated else False,
|
||
"node_btn_name": "4",
|
||
"approval_state": "0", # 待审批
|
||
})
|
||
next_node_log_records += next_node_employee_log
|
||
workflow_record_id = self.env['soong.workflow.record'].sudo().search([('res_id', '=', record_id.id),
|
||
('res_model', '=', record_id._name)
|
||
])
|
||
# 被委托人(实际经办) + 委托人(原选中人) 都可见
|
||
visible_uids = [emp.user_id.id for emp in effective_employees if emp.user_id]
|
||
for selected_employee, actual_employee, is_delegated in delegation_targets:
|
||
if is_delegated and selected_employee.user_id and selected_employee.user_id.id not in visible_uids:
|
||
visible_uids.append(selected_employee.user_id.id)
|
||
workflow_record_id.users_ids = [(4, uid) for uid in visible_uids]
|
||
workflow_record_id.employee_ids = effective_employees.ids
|
||
workflow_record_id.approve_state = "pending" # 待审批
|
||
related_record = self.env[self.res_model].browse(self.res_id)
|
||
if hasattr(related_record, 'self_users_ids'):
|
||
user_ids = [emp.user_id.id for emp in effective_employees if emp.user_id]
|
||
related_record.self_users_ids = [(6, 0, user_ids)] if user_ids else [(5,)]
|
||
if not self.trans_link_id.name:
|
||
raise UserError('无转交节点')
|
||
record_id.write({'state': self.trans_link_id.name})
|
||
for employee in effective_employees:
|
||
action_id = self.env['ir.actions.act_window'].search([('res_model', '=', self.res_model)])[0]
|
||
target_url = f'https://oa.thtzjt.com/web#id={record_id.id}&cids=2&active_id={action_id.id}&model={record_id._name}&view_type=form'
|
||
url = self.sudo().env["wecom.apps"].generate_oauth_login_url(target_url, employee.user_id.id)
|
||
_logger.info(f"===================当前的url为{url}=============================")
|
||
title = record_id._description
|
||
if 'Purchase Order' == record_id._description:
|
||
title = '采购订单'
|
||
if 'Room Booking' == record_id._description:
|
||
title = '会议通知'
|
||
result_data = self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa', user_id=employee.wecom_userid, title=title,
|
||
description="标题: {}\n".format(record_id.name) + self.env.user.name + ' ' + str(
|
||
fields.Datetime.now() + timedelta(hours=8)),
|
||
url=url, btntxt="查看详情")
|
||
if result_data and 'msgid' in result_data[-1]:
|
||
msg_id = result_data[-1]['msgid']
|
||
target_logs = next_node_log_records.filtered(lambda l: l.done_by.id == employee.user_id.id)
|
||
if target_logs:
|
||
target_logs.msg_id = msg_id
|
||
|
||
else: # 串审模式 (沿用原有逻辑)
|
||
# 查找下一个节点
|
||
if self.trans_link_id:
|
||
next_node_id = record_id.workflow_id.node_ids.search([
|
||
('name', 'ilike', self.trans_link_id.name),
|
||
('workflow_id', '=', record_id.workflow_id.id)
|
||
])
|
||
# 流程委托:把选中的委托人解析为实际审批人(被委托人),双方都可见
|
||
delegation_targets = []
|
||
for selected_employee in self.employee_ids:
|
||
actual_employee = selected_employee
|
||
is_delegated = False
|
||
if selected_employee.user_id and selected_employee.user_id.id in entrust_substitution:
|
||
actual_employee = entrust_substitution[selected_employee.user_id.id]
|
||
is_delegated = True
|
||
delegation_targets.append((selected_employee, actual_employee, is_delegated))
|
||
for selected_employee, actual_employee, is_delegated in delegation_targets:
|
||
# 创建下一节点的审批记录(done_by 落库为被委托人)
|
||
self.sudo().env["soong.workflow.log"].create({
|
||
"code": self.code,
|
||
"model": self.res_model,
|
||
"res_id": self.res_id,
|
||
"node_id": next_node_id.id,
|
||
"workflow_id": self.node_btn_id.workflow_id.id,
|
||
"done_by": actual_employee.user_id.id if actual_employee.user_id else query_user_id,
|
||
"done_by_display": f"{actual_employee.name}(委托人)" if is_delegated else False,
|
||
"node_btn_name": "3",
|
||
"approval_state": "1", # 待审批
|
||
})
|
||
|
||
# 更新业务记录状态
|
||
related_record = self.env[self.res_model].browse(self.res_id)
|
||
if hasattr(related_record, 'self_users_ids'):
|
||
user_ids = [actual_employee.user_id.id for selected_employee, actual_employee, is_delegated in delegation_targets if actual_employee.user_id]
|
||
related_record.self_users_ids = [(6, 0, user_ids)] if user_ids else [(5,)]
|
||
record_id.write({'state': self.trans_link_id.name})
|
||
workflow_record_id = self.env['soong.workflow.record'].sudo().search([('res_id', '=', record_id.id),
|
||
('res_model', '=', record_id._name)
|
||
])
|
||
# 被委托人(实际经办) + 委托人(原选中人) 都可见
|
||
visible_uids = [actual_employee.user_id.id for selected_employee, actual_employee, is_delegated in delegation_targets if actual_employee.user_id]
|
||
for selected_employee, actual_employee, is_delegated in delegation_targets:
|
||
if is_delegated and selected_employee.user_id and selected_employee.user_id.id not in visible_uids:
|
||
visible_uids.append(selected_employee.user_id.id)
|
||
|
||
workflow_record_id.users_ids = [(4, uid) for uid in visible_uids]
|
||
workflow_record_id.employee_ids = [actual_employee.id for selected_employee, actual_employee, is_delegated in delegation_targets if actual_employee]
|
||
workflow_record_id.approve_state = "pending" # 待审批
|
||
|
||
for employee in self.circulated_employee_ids:
|
||
record_id = self.env[self.res_model].search([('id', '=', self.res_id)])
|
||
self.sudo().env["soong.workflow.record.copy"].create({
|
||
"code": record_id.code,
|
||
"name": record_id.name,
|
||
"res_model": self.res_model,
|
||
"workflow_id": self.node_btn_id.workflow_id.id,
|
||
"res_id": self.res_id,
|
||
"done_by": employee.user_id.id,
|
||
"approval_state_copy": "0",
|
||
})
|
||
if employee.user_id.id not in log_done_by_ids:
|
||
self.sudo().env["soong.workflow.log2"].create({
|
||
"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.user_id.id,
|
||
"node_btn_id": self.node_btn_id.id,
|
||
"approval_state": "0",
|
||
})
|
||
|
||
if self.circulated_employee_ids:
|
||
action_id = self.env['ir.actions.act_window'].search([('res_model', '=', self.res_model)])[0]
|
||
workflow_record_id = self.env['soong.workflow.record'].sudo().search([('res_id', '=', record_id.id),
|
||
('res_model', '=', record_id._name)
|
||
])
|
||
workflow_record_id.is_log2 = True
|
||
description = "标题: {}\n".format(record_id.name) + self.env.user.name + ' ' + str(fields.Datetime.now() + timedelta(hours=8))
|
||
workflow_record_id.employee2_ids = [(6, 0, self.circulated_employee_ids.ids)]
|
||
|
||
title = record_id._description
|
||
if 'Room Booking' == title:
|
||
title = '会议通知'
|
||
for employee in self.circulated_employee_ids:
|
||
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.wecom_userid,
|
||
title=title + "传阅/抄送",
|
||
description=description, url=url,
|
||
btntxt="查看详情")
|
||
self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa',
|
||
user_id='18562027762',
|
||
title=title + '传阅/抄送,测试提醒',
|
||
description=description, url=url,
|
||
btntxt="查看详情")
|
||
self._handle_avoidance()
|
||
if self.node_btn_name == '退回':
|
||
if not self.return_link_id:
|
||
raise UserError('请选择退回节点')
|
||
record_id.write({'state': self.return_link_id.name})
|
||
next_node_id = record_id.workflow_id.node_ids.search([('name', '=', self.return_link_id.name), ('workflow_id', '=', record_id.workflow_id.id)])
|
||
for next_link in record_id.workflow_id.link_ids:
|
||
if next_link.name.split('-> ')[0].strip() == self.return_link_id.name.strip():
|
||
next_node_id = next_link.node_from
|
||
|
||
user_log = record_id.log_ids.filtered(
|
||
lambda log: log.done_by == self.env.user and log.approval_state in ['0', '1'])
|
||
user_log.write({'approval_state': '2',
|
||
"lase_click_date": fields.Datetime.now(),
|
||
"comment": self.comment,
|
||
"node_btn_name": "1"})
|
||
target_names = user_log.mapped('name')
|
||
logs_to_delete = record_id.log_ids.filtered(
|
||
lambda log: (log.name in target_names) and
|
||
not log.comment and
|
||
log not in user_log
|
||
)
|
||
if logs_to_delete:
|
||
logs_to_delete.unlink()
|
||
self.sudo().env["soong.workflow.log"].create({
|
||
"code": self.code,
|
||
"model": self.res_model,
|
||
"res_id": self.res_id,
|
||
"node_id": next_node_id.id,
|
||
"workflow_id": self.node_btn_id.workflow_id.id,
|
||
"done_by": self.employee_ids[0].user_id.id,
|
||
"approval_state": "0",
|
||
"node_btn_id": self.node_btn_id.id,
|
||
})
|
||
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.employee_ids
|
||
action_id = self.env['ir.actions.act_window'].search([('res_model', '=', self.res_model)])[0]
|
||
related_record = self.env[self.res_model].browse(self.res_id)
|
||
user_ids = [employee.user_id.id for employee in self.employee_ids if employee.user_id]
|
||
if hasattr(related_record, 'self_users_ids'):
|
||
related_record.self_users_ids = [(6, 0, user_ids)] if user_ids else [(5,)]
|
||
node_name = self.node_btn_id.node_id.name
|
||
description = f"您的{record_id.name}, 于当前{node_name}退回"
|
||
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'
|
||
for employee in self.employee_ids:
|
||
self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa',
|
||
user_id=employee.wecom_userid,
|
||
title=record_id._description + "退回",
|
||
description=description, url=url, btntxt="查看详情")
|
||
|
||
if self.node_btn_name == '加签确认':
|
||
if hasattr(record_id, 'user_id') and record_id.user_id:
|
||
query_user_id = record_id.user_id
|
||
elif hasattr(record_id, 'users_id') and record_id.users_id:
|
||
query_user_id = record_id.users_id
|
||
description = f"标题:{record_id.name}\n申请人:{query_user_id.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 不存在的话 说明他加签是不返回 证明已经走了下一个节点 如果返回的话 节点是不会动的
|
||
if not current_node_log:
|
||
current_node_log1 = self.sudo().env["soong.workflow.log"].search(
|
||
[
|
||
("model", "=", self.res_model),
|
||
("res_id", "=", self.res_id),
|
||
("done_by", "=", self.env.user.id),
|
||
("name", "=", "加签"),
|
||
("approval_state", "=", '1')
|
||
],
|
||
order="create_date DESC",
|
||
limit=1
|
||
)
|
||
current_node_log1.write({
|
||
"comment": self.comment,
|
||
"approval_state": "2", # 已完成
|
||
'document_ids': [(6, 0, self.document_ids.ids)],
|
||
"lase_click_date": fields.Datetime.now()
|
||
})
|
||
|
||
if current_node_log:
|
||
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
|
||
# 从当前加签 log 上读取加签发起人
|
||
add_sign_user = current_node_log.add_sign_by
|
||
if not add_sign_user:
|
||
# 兼容旧数据:没有 add_sign_by 的,走原来的排序逻辑
|
||
last_sign_log = log_obj.search([
|
||
("model", "=", self.res_model),
|
||
("res_id", "=", self.res_id),
|
||
("name", "=", "归档"),
|
||
], order="create_date DESC", limit=1)
|
||
if not last_sign_log:
|
||
last_sign_log = log_obj.search([
|
||
("model", "=", self.res_model),
|
||
("res_id", "=", self.res_id),
|
||
('approval_state', "=", '2'),
|
||
("name", "!=", "加签"),
|
||
], order="lase_click_date DESC")[0]
|
||
if not last_sign_log:
|
||
return
|
||
add_sign_user = last_sign_log.done_by
|
||
|
||
# 查找发起人在该节点上的原始 log(非加签),确定返回的 name(如"归档")
|
||
origin_log = log_obj.search([
|
||
("model", "=", self.res_model),
|
||
("res_id", "=", self.res_id),
|
||
("node_id", "=", node_id),
|
||
("done_by", "=", add_sign_user.id),
|
||
("name", "!=", "加签"),
|
||
("approval_state", "=", "2"),
|
||
], order="create_date DESC", limit=1)
|
||
log_name = origin_log.name if origin_log and origin_log.name == '归档' else False
|
||
|
||
# 查找同一批次的加签 log(同一个发起人、同一个节点)
|
||
batch_logs = log_obj.search([
|
||
("model", "=", self.res_model),
|
||
("res_id", "=", self.res_id),
|
||
("node_id", "=", node_id),
|
||
("name", "=", "加签"),
|
||
("add_sign_by", "=", add_sign_user.id),
|
||
])
|
||
# 是否都完成了
|
||
all_done = all(log.approval_state == "2" for log in batch_logs)
|
||
if all_done :
|
||
log_vals = {
|
||
"model": self.res_model,
|
||
"res_id": self.res_id,
|
||
"workflow_id": self.node_btn_id.workflow_id.id,
|
||
"node_id": node_id,
|
||
"done_by": add_sign_user.id,
|
||
"approval_state": "0",
|
||
"create_date": fields.Datetime.now(),
|
||
}
|
||
if log_name:
|
||
log_vals["name"] = log_name
|
||
log_obj.create(log_vals)
|
||
workflow_record_id = self.env['soong.workflow.record'].sudo().search([('res_id', '=', record_id.id),
|
||
(
|
||
'res_model', '=', record_id._name)
|
||
])
|
||
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=add_sign_user.employee_ids.wecom_userid,
|
||
title=record_id._description + '加签返回',
|
||
description=description, url=url,
|
||
btntxt="查看详情")
|
||
|
||
if self.node_btn_name in ['结束', '确认']:
|
||
title = record_id._description
|
||
current_comment = self.comment or ''
|
||
if 'Room Booking' == record_id._description:
|
||
title = '会议通知'
|
||
is_work_remind = False
|
||
current_user = self.env.user
|
||
query_user_id = self.env.user.id
|
||
current_datetime = fields.Datetime.now()
|
||
is_admin = current_user.has_group('base.group_system')
|
||
current_node_log = self.sudo().env["soong.workflow.log"].search(
|
||
[
|
||
("model", "=", self.res_model),
|
||
("res_id", "=", self.res_id),
|
||
("done_by", "=", query_user_id),
|
||
("node_id", "=", self.node_btn_id.node_id.id),
|
||
],
|
||
order="create_date DESC",
|
||
limit=1
|
||
)
|
||
# 印章分组审批:章内串审,删除同章其他人的待办
|
||
if getattr(current_node_log, 'stamp_id', False):
|
||
same_stamp_logs = self.sudo().env["soong.workflow.log"].search(
|
||
[("model", "=", self.res_model),
|
||
("res_id", "=", self.res_id),
|
||
("id", "!=", current_node_log.id),
|
||
("node_id", "=", self.node_btn_id.node_id.id),
|
||
("stamp_id", "=", current_node_log.stamp_id.id),
|
||
("approval_state", "in", ['0', '1']),
|
||
])
|
||
for log_delete in same_stamp_logs:
|
||
if getattr(log_delete, 'msg_id', False):
|
||
self.sudo().env["wecom.apps"].back_message(log_delete.msg_id, category='approval')
|
||
same_stamp_logs.unlink()
|
||
# 归档判断
|
||
last_log = record_id.log_ids.sorted(
|
||
key=lambda r: (not r.lase_click_date, r.lase_click_date or False, r.id)
|
||
)[-1] if record_id.log_ids else None
|
||
all_user = True if last_log and last_log.done_by == current_user else False
|
||
|
||
if last_log:
|
||
same_name_logs = record_id.log_ids.filtered(
|
||
lambda log: log.name == last_log.name and log.node_btn_name == '4' and log.id != last_log.id
|
||
)
|
||
all_approved = all(log.approval_state in ['2', '3'] for log in same_name_logs) or not same_name_logs
|
||
if all_approved and all_user:
|
||
workflow_record = self.env['soong.workflow.record'].sudo().search([('res_id', '=', record_id.id),
|
||
('res_model', '=',record_id._name),
|
||
('reclaim_state', '=', False),
|
||
])
|
||
has_archive_btn = any(btn_name.name == '归档' for btn_name in self.node_btn_id.node_id.button_ids)
|
||
if has_archive_btn:
|
||
log_id = record_id.log_ids.filtered(lambda l: l.name == '归档')
|
||
employee_id = self.env['hr.employee'].sudo().search(
|
||
[('user_id', '=', record_id.log_ids[0].done_by.id)], limit=1)
|
||
if workflow_record:
|
||
workflow_record.write({
|
||
'approve_state': 'end',
|
||
'employee_ids': [(6, 0, [employee_id.id])],
|
||
'soong_state': 'to_active',
|
||
'node_id': False,
|
||
})
|
||
if not log_id:
|
||
self.env["soong.workflow.log"].create({
|
||
'name': '归档',
|
||
"code": self.code,
|
||
"model": self.res_model,
|
||
"res_id": self.res_id,
|
||
"workflow_id": self.node_btn_id.workflow_id.id,
|
||
"done_by": record_id.log_ids[0].done_by.id,
|
||
"approval_state": "0",
|
||
"node_btn_id": self.node_btn_id.id,
|
||
})
|
||
is_work_remind = True
|
||
else:
|
||
log_id.write({
|
||
'document_ids': [(6, 0, self.document_ids.ids)],
|
||
"approval_state": "2",
|
||
'lase_click_date': fields.Datetime.now(),
|
||
})
|
||
workflow_record.write({
|
||
'approve_state': 'end',
|
||
'soong_state': 'active',
|
||
'employee_ids': False,
|
||
})
|
||
else:
|
||
if workflow_record and self.node_btn_name == '结束':
|
||
workflow_record.sudo().write({
|
||
'approve_state': 'end',
|
||
'employee_ids': False,
|
||
'node_id': False,
|
||
'soong_state': 'done',
|
||
})
|
||
record_id.work_end = True
|
||
# 自动设置审批结果为 不通过
|
||
if any(keyword in current_comment for keyword in ['不同意', '不批准', '不通过']):
|
||
if hasattr(record_id, 'approval_result'):
|
||
record_id.approval_result = 'fail'
|
||
else:
|
||
if hasattr(record_id, 'approval_result'):
|
||
record_id.approval_result = 'pass'
|
||
self.node_btn_id.with_context(cx).run()
|
||
|
||
if is_admin:
|
||
user_log = record_id.log_ids.filtered(
|
||
lambda log: log.done_by == current_user and log.node_btn_name != '1' and log.approval_state == '0'
|
||
)
|
||
if user_log:
|
||
user_log.write({
|
||
'comment': self.comment,
|
||
'approval_state': "2",
|
||
'lase_click_date': current_datetime,
|
||
'document_ids': [(6, 0, self.document_ids.ids)]
|
||
})
|
||
else:
|
||
last_log = record_id.log_ids[-1] if record_id.log_ids else None
|
||
if last_log and last_log.approval_state not in ['2', '3']:
|
||
last_log.sudo().write({
|
||
'comment': self.comment,
|
||
'approval_state': "2",
|
||
'lase_click_date': fields.Datetime.now() - timedelta(hours=8),
|
||
'document_ids': [(6, 0, self.document_ids.ids)]
|
||
})
|
||
self.env['soong.workflow.record'].search([('code', '=', record_id.code)]).write({'approve_state': 'end',
|
||
"employee_ids": False,
|
||
"node_id": False, })
|
||
record_id.work_end = True
|
||
else:
|
||
if record_id.log_ids:
|
||
user_log = record_id.log_ids.filtered(
|
||
lambda log: log.done_by == current_user and log.node_btn_name != '1' and log.approval_state in ['0', '1']
|
||
)
|
||
if user_log:
|
||
user_log.write({
|
||
'comment': self.comment,
|
||
'approval_state': "2",
|
||
'lase_click_date': current_datetime,
|
||
'document_ids': [(6, 0, self.document_ids.ids)]
|
||
})
|
||
if any(log.node_btn_name == '3' for log in user_log):
|
||
other_node_logs = self.sudo().env["soong.workflow.log"].search(
|
||
[("model", "=", self.res_model),
|
||
("res_id", "=", self.res_id),
|
||
("id", "not in", user_log.ids),
|
||
("node_id", "=", self.node_btn_id.node_id.id)
|
||
])
|
||
for other_node_log in other_node_logs:
|
||
other_node_log.unlink()
|
||
|
||
if (record_id.log_ids2 or record_id.log_ids.filtered(lambda log: log.name == '承办')) and self.node_btn_name == '确认':
|
||
user_log2 = record_id.log_ids2.filtered(lambda log: log.done_by == current_user)
|
||
user_log1 = record_id.log_ids.filtered(lambda log: log.done_by == current_user)
|
||
if user_log2:
|
||
user_log2.write({
|
||
'commit': self.comment,
|
||
'approval_state': "2",
|
||
'lase_click_date': current_datetime,
|
||
})
|
||
if user_log1:
|
||
user_log1.write({
|
||
'comment': self.comment,
|
||
'approval_state': "2",
|
||
'lase_click_date': current_datetime,
|
||
})
|
||
for employee in self.circulated_employee_ids:
|
||
action_id = self.env['ir.actions.act_window'].search([('res_model', '=', self.res_model)])[0]
|
||
url = f'https://oa.thtzjt.com/web#id={record_id.id}&cids=2&action={action_id.id}&model={self.res_model}&view_type=from&menu_id={record_id.id}'
|
||
description = "标题: {}\n".format(record_id.name) + self.env.user.name + ' ' + str(fields.Datetime.now() + timedelta(hours=8))
|
||
workflow_record_id = self.env['soong.workflow.record'].sudo().search([('res_id', '=', record_id.id),
|
||
('res_model', '=', record_id._name)
|
||
])
|
||
workflow_record_id.users_ids = [(4, employee.user_id.id) for employee in self.circulated_employee_ids if employee.user_id]
|
||
workflow_record_id.employee_ids = [(4, employee.id)]
|
||
record_id = self.env[self.res_model].search([('id', '=', self.res_id)])
|
||
self.sudo().env["soong.workflow.record.copy"].create({
|
||
"code": record_id.code,
|
||
"name": record_id.name,
|
||
"res_model": self.res_model,
|
||
"workflow_id": self.node_btn_id.workflow_id.id,
|
||
"res_id": self.res_id,
|
||
"done_by": employee.user_id.id,
|
||
"approval_state_copy": "0",
|
||
})
|
||
if employee.user_id.id not in log_done_by_ids:
|
||
self.sudo().env["soong.workflow.log2"].create({
|
||
"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.user_id.id,
|
||
"node_btn_id": self.node_btn_id.id,
|
||
"approval_state": "0",
|
||
})
|
||
self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa', user_id=employee.wecom_userid,
|
||
title=record_id._description + "传阅/抄送",
|
||
description=description, url=url,
|
||
btntxt="查看详情")
|
||
|
||
# 给申请人发消息
|
||
if is_work_remind:
|
||
biz_record = self.env[self.res_model].browse(self.res_id)
|
||
if hasattr(biz_record, 'user_id') and biz_record.user_id:
|
||
employee = biz_record.user_id.employee_ids
|
||
elif hasattr(biz_record, 'users_id') and biz_record.users_id:
|
||
employee = biz_record.users_id.employee_ids
|
||
action_id = self.env['ir.actions.act_window'].search([('res_model', '=', self.res_model)])[0]
|
||
recipients = []
|
||
if self.node_btn_id.workflow_id.archive_type == 'applicant':
|
||
biz_record = self.env[self.res_model].browse(self.res_id)
|
||
if hasattr(biz_record, 'user_id') and biz_record.user_id:
|
||
employee = biz_record.user_id.employee_ids
|
||
elif hasattr(biz_record, 'users_id') and biz_record.users_id:
|
||
employee = biz_record.users_id.employee_ids
|
||
recipients.append(employee)
|
||
elif self.node_btn_id.workflow_id.archive_type == 'role':
|
||
role_ids = self.node_btn_id.workflow_id.role_ids
|
||
employees = self.env['hr.employee'].search([
|
||
'|',
|
||
('user_role_id', 'in', role_ids.ids),
|
||
('user_role_ids', 'in', role_ids.ids)
|
||
])
|
||
recipients = [emp for emp in employees]
|
||
else:
|
||
employees = self.node_btn_id.workflow_id.employee_ids
|
||
recipients = [emp for emp in employees]
|
||
for employee in recipients:
|
||
target_url = f'https://oa.thtzjt.com/web#id={record_id.id}&cids=2&active_id={action_id.id}&model={record_id._name}&view_type=form'
|
||
url = self.sudo().env["wecom.apps"].generate_oauth_login_url(target_url, employee.user_id.id)
|
||
if self.res_model == 'purchase.order':
|
||
self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa',
|
||
user_id=employee.wecom_userid,
|
||
title='采购审批单',
|
||
description=f"{record_id.name}审批结束,可采购入库",
|
||
url=url, btntxt="查看详情")
|
||
else:
|
||
self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa',
|
||
user_id=employee.wecom_userid,
|
||
title=title,
|
||
description=f"标题为{record_id.name}的{title}已结束,请归档",
|
||
url=url, btntxt="查看详情")
|
||
self._handle_avoidance()
|
||
if self.node_btn_name == "分发":
|
||
record_id.is_send = True
|
||
menu_id = self.env['ir.ui.menu'].search([('name', '=', '行政收文')], limit=1)
|
||
workflow_record_id = self.env['soong.workflow.record'].sudo().search([('res_id', '=', record_id.id),
|
||
('res_model', '=', record_id._name)
|
||
])
|
||
action_id = self.env['ir.actions.act_window'].search([('res_model', '=', self.res_model)])[0]
|
||
target_url = f'https://oa.thtzjt.com/web#id={record_id.id}&cids=2&menu_id={menu_id.id}&active_id={action_id.id}&model={record_id._name}&view_type=form'
|
||
description = "标题: {}\n".format(record_id.name) + self.env.user.name + ' ' + str(fields.Datetime.now() + timedelta(hours=8))
|
||
if self.employee_ids:
|
||
workflow_record_id.users_ids = [(4, employee.user_id.id) for employee in self.employee_ids if employee.user_id]
|
||
next_node_id = record_id.workflow_id.node_ids.search([('name', '=', '董事长'), ('workflow_id', '=', record_id.workflow_id.id)])
|
||
if record_id.log_ids:
|
||
record_id.log_ids[-1].write({"comment": self.comment, "approval_state": "2", "lase_click_date": fields.Datetime.now()})
|
||
log_id = self.sudo().env["soong.workflow.log"].create({
|
||
"code": self.code,
|
||
"model": self.res_model,
|
||
"res_id": self.res_id,
|
||
"node_id": next_node_id.id,
|
||
"workflow_id": self.node_btn_id.workflow_id.id,
|
||
"done_by": self.employee_ids.user_id.id,
|
||
"node_btn_name": "0",
|
||
})
|
||
url = self.sudo().env["wecom.apps"].generate_oauth_login_url(target_url, self.employee_ids.user_id.id)
|
||
result_data = self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa', user_id=self.employee_ids.wecom_userid, title=record_id._description, description=description, url=url, btntxt="查看详情")
|
||
if result_data and 'msgid' in result_data[-1]:
|
||
msg_id = result_data[-1]['msgid']
|
||
log_id.msg_id = msg_id
|
||
for emp in self.dep_manager_employee_ids:
|
||
workflow_record_id.users_ids = [(4, employee.user_id.id) for employee in self.dep_manager_employee_ids if employee.user_id]
|
||
next_node_id = record_id.workflow_id.node_ids.search([('name', '=', '承办'), ('workflow_id', '=', record_id.workflow_id.id)])
|
||
log_id = self.sudo().env["soong.workflow.log"].create({
|
||
"code": self.code,
|
||
"model": self.res_model,
|
||
"res_id": self.res_id,
|
||
"node_id": next_node_id.id,
|
||
"workflow_id": self.node_btn_id.workflow_id.id,
|
||
"done_by": emp.user_id.id,
|
||
"node_btn_name": "4",
|
||
})
|
||
url = self.sudo().env["wecom.apps"].generate_oauth_login_url(target_url, emp.user_id.id)
|
||
result_data = self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa', user_id=emp.wecom_userid, title=record_id._description + "承办", description=description, url=url, btntxt="查看详情")
|
||
if result_data and 'msgid' in result_data[-1]:
|
||
msg_id = result_data[-1]['msgid']
|
||
log_id.msg_id = msg_id
|
||
for employee in self.circulated_employee_ids:
|
||
workflow_record_id.users_ids = [(4, employee.user_id.id) for employee in self.circulated_employee_ids if employee.user_id]
|
||
record_id = self.env[self.res_model].search([('id', '=', self.res_id)])
|
||
self.sudo().env["soong.workflow.record.copy"].create({
|
||
"code": record_id.code,
|
||
"name": record_id.name,
|
||
"res_model": self.res_model,
|
||
"workflow_id": self.node_btn_id.workflow_id.id,
|
||
"res_id": self.res_id,
|
||
"done_by": employee.user_id.id,
|
||
"approval_state_copy": "0",
|
||
})
|
||
if employee.user_id.id not in log_done_by_ids:
|
||
log2_domain = [
|
||
('model', '=', self.res_model),
|
||
('res_id', '=', self.res_id),
|
||
('node_id', '=', self.node_btn_id.node_id.id),
|
||
('done_by', '=', employee.user_id.id),
|
||
]
|
||
log2_id = self.sudo().env["soong.workflow.log2"].search(log2_domain, limit=1)
|
||
if not log2_id:
|
||
log2_id = self.sudo().env["soong.workflow.log2"].create({
|
||
"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.user_id.id,
|
||
"node_btn_id": self.node_btn_id.id,
|
||
"approval_state": "0",
|
||
})
|
||
url = self.sudo().env["wecom.apps"].generate_oauth_login_url(target_url, employee.user_id.id)
|
||
result_data = self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa', user_id=employee.wecom_userid, title=record_id._description + "传阅/抄送",description=description, url=url, btntxt="查看详情")
|
||
if result_data and 'msgid' in result_data[-1]:
|
||
msg_id = result_data[-1]['msgid']
|
||
log2_id.msg_id = msg_id
|
||
workflow_record_id.employee_ids = self.dep_manager_employee_ids + self.employee_ids + self.circulated_employee_ids
|
||
if record_id.log_ids:
|
||
record_id.log_ids[-1].write({"comment": self.comment, "approval_state": "2", "lase_click_date": fields.Datetime.now()})
|
||
if self.node_btn_name == "收回":
|
||
current_user = self.env.user
|
||
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')
|
||
last_normal_log = log_ids.filtered(lambda l: l.name != '加签').sorted('create_date')[-1:]
|
||
# 2. 如果有最后正常节点,只取【这个时间之后】的加签
|
||
if last_normal_log:
|
||
last_create_date = last_normal_log.create_date
|
||
has_sign_log = log_ids.filtered(lambda log:
|
||
log.name == '加签'
|
||
and log.node_id.name == record.state
|
||
and log.create_date > last_create_date # 关键:只取最后正常节点之后的加签
|
||
)
|
||
else:
|
||
has_sign_log = log_ids.filtered(lambda log: log.name == '加签' and log.node_id.name == record.state)
|
||
# 3. 判断这些加签是否已处理
|
||
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 and log.node_btn_name != '1')
|
||
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)
|
||
|
||
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)] 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'})
|
||
|
||
# 回退状态
|
||
if prev_log.name != '归档':
|
||
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]
|
||
target_url = f'https://oa.thtzjt.com/web#id={record_id.id}&cids=2&menu_id={menu_id.id}&active_id={action_id.id}&model={record_id._name}&view_type=form'
|
||
description = "标题: {}\n".format(record_id.name) + self.env.user.name + ' ' + str(fields.Datetime.now() + timedelta(hours=8))
|
||
record = self.env[self.res_model].search([('id', '=', self.res_id)])
|
||
if self.res_model == 'purchase.order':
|
||
record.write({'purchase_state': 'done'})
|
||
if record.log_ids:
|
||
_last_log = record.log_ids[-1]
|
||
_last_log.write({'is_active_operate': True,
|
||
'lase_click_date': fields.Datetime.now(),
|
||
'approval_state': '1'
|
||
})
|
||
workflow_record_id = self.env['soong.workflow.record'].sudo().search([('res_id', '=', record_id.id),
|
||
('res_model', '=', record_id._name)
|
||
])
|
||
if record.log_ids:
|
||
_last_log = record.log_ids[-1]
|
||
_last_log.write({'approval_state': '2'})
|
||
if self.document_ids:
|
||
_last_log.write({'document_ids': [(6, 0, self.document_ids.ids)]})
|
||
_last_log.write({"comment": self.comment})
|
||
workflow_record_id.write({'soong_state': 'active',
|
||
'employee_ids':False
|
||
})
|
||
if self.circulated_employee_ids:
|
||
for employee in self.circulated_employee_ids:
|
||
if employee.user_id.id not in log_done_by_ids:
|
||
log2_domain = [
|
||
('model', '=', self.res_model),
|
||
('res_id', '=', self.res_id),
|
||
('node_id', '=', self.node_btn_id.node_id.id),
|
||
('done_by', '=', employee.user_id.id),
|
||
]
|
||
log2_id = self.sudo().env["soong.workflow.log2"].search(log2_domain, limit=1)
|
||
if not log2_id:
|
||
workflow_record_id.users_ids = [(4, employee.user_id.id) for employee in self.circulated_employee_ids if employee.user_id]
|
||
log2_id = self.sudo().env["soong.workflow.log2"].create({
|
||
"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.user_id.id,
|
||
"node_btn_id": self.node_btn_id.id,
|
||
"approval_state": "0",
|
||
})
|
||
url = self.sudo().env["wecom.apps"].generate_oauth_login_url(target_url, employee.user_id.id)
|
||
result_data = self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa',
|
||
user_id=employee.wecom_userid,
|
||
title=record_id._description + "传阅/抄送",
|
||
description=description,
|
||
url=url,
|
||
btntxt="查看详情")
|
||
if result_data and 'msgid' in result_data[-1]:
|
||
msg_id = result_data[-1]['msgid']
|
||
log2_id.msg_id = msg_id
|
||
if self.node_btn_name != "收回":
|
||
tree_id = self.env.ref("soong_workflow.soong_workflow_record_my_tree").id
|
||
kanban_id = self.env.ref("soong_workflow.soong_workflow_record_kanban").id
|
||
# self.red_reload()
|
||
return {
|
||
'type': 'ir.actions.client',
|
||
'tag': 'flush_badge_wkf',
|
||
'params': {
|
||
'tree_id': tree_id,
|
||
'kanban_id': kanban_id,
|
||
'uid': self.env.uid,
|
||
}
|
||
}
|
||
|
||
def _get_all_employee_partners(self):
|
||
all_employees = self.env['hr.employee']
|
||
all_employees |= self.employee_trans_domain_ids
|
||
all_employees |= self.employee_ids
|
||
all_employees |= self.circulated_employee_ids
|
||
all_employees |= self.dep_manager_employee_ids
|
||
all_employees |= self.add_employee_ids
|
||
all_employees |= self.supervising_employee_ids
|
||
all_employees |= self.employee_ids1
|
||
partners = all_employees.filtered(lambda e: e.user_id and e.user_id.partner_id).mapped('user_id.partner_id')
|
||
return partners
|
||
|
||
|
||
def update_self_users_ids(self):
|
||
related_record = self.env[self.res_model].browse(self.res_id)
|
||
if hasattr(related_record, 'self_users_ids'):
|
||
user_ids = [employee.user_id.id for employee in self.employee_ids if employee.user_id]
|
||
related_record.self_users_ids = [(6, 0, user_ids)] if user_ids else [(5,)]
|