Files
gzth/soong_workflow/wizard/soong_workflow_comment_wizard.py
T
李鹏宇 0ea7f49f96 !8072 添加功能
Merge pull request !8072 from 李鹏宇/dev_zhou
2026-01-18 10:56:29 +00:00

922 lines
54 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- 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="意见")
comment = fields.Char(compute='_compute_comment', store=True)
state_list = fields.Char(string="状态列表")
record_id = fields.Integer()
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='审批人节点,跳过节点',
compute='_compute_invalid_link_ids',
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)
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)
is_this_company = fields.Boolean('本公司', default=True)
employee_ids1 = fields.Many2many('hr.employee', 'employee_ids1_rel', 'custom_id1', 'employee_id1', string="转交人员", store=True)
@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:
self.employee_ids = False
@api.onchange('employee_ids1')
def _onchange_employee_ids1(self):
filtered_employees = self.employee_ids1.filtered(
lambda emp: emp.company_id.id == self.company_id.id
)
if len(filtered_employees) == 1:
self.employee_ids = filtered_employees
else:
self.employee_ids = False
@api.constrains('employee_ids')
def _check_employee_ids(self):
if not self.employee_ids and self.node_btn_name == '转交':
raise ValidationError("必须有转交人员")
@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 = record_id.user_id.employee_ids
elif hasattr(record_id, 'users_id') and record_id.users_id:
employee_ids1 = record_id.users_id.employee_ids
self.employee_ids1 = employee_ids1
elif self.node_btn_name == '退回':
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
@api.depends('trans_link_id')
def _compute_invalid_link_ids(self):
for record in self:
invalid_links = self.env['trans.link']
ctx_links = self.env.context.get('all_workflow_links', [])
all_links = self.env['trans.link'].browse(ctx_links) if isinstance(ctx_links, (list, tuple)) else ctx_links
record_id = self.env[record.res_model].browse(record.res_id) if record.res_model and record.res_id else None
current_link = record.trans_link_id
if current_link and all_links:
sorted_all_links = all_links.sorted('sequence')
for idx, link in enumerate(sorted_all_links):
if link.id == current_link.id and link.sequence == current_link.sequence:
approvers = self._get_approvers_for_link(link, record_id)
# if not approvers:
# invalid_links |= link
log_records = record_id.log_ids
approved_users = log_records.filtered(lambda log: log.node_btn_name != '1' and log.done_by).mapped('done_by.employee_ids')
approved_employee_ids = approved_users.ids
employee_ids = approvers.ids
if len(approvers) > 1:
is_all_included = all(emp_id in approved_employee_ids for emp_id in employee_ids)
if is_all_included:
if idx + 1 < len(sorted_all_links):
self.trans_link_id = sorted_all_links[idx + 1]
invalid_links |= current_link
break
record.invalid_link_ids = invalid_links
@api.onchange('trans_link_id')
def onchange_trans_employee_ids(self):
for record in self:
if not record.trans_link_id:
continue
record_id = self.env[record.res_model].browse(record.res_id) if record.res_model and record.res_id else None
for link in record.trans_link_id:
employee_user_role_ids = self._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)
])
record.approval_concatenation = node.approval_concatenation
record.employee_trans_domain_ids = employee_user_role_ids
record.employee_ids1 = employee_user_role_ids
def _get_approvers_for_link(self, link, record_id=None):
"""
参数:
link: trans.link 记录对象
record_id: 关联的业务记录对象
返回:
hr.employee 记录集(可能为空)
"""
if not link or isinstance(link, int):
return self.env['hr.employee']
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:
target_btn = next((btn for btn in node.button_ids if btn.name == btn_name), None)
if target_btn:
button = target_btn
break
if not button:
return self.env['hr.employee']
link_users_id = button.users_role_id
link_users_group_ids = button.users_role_group_ids
is_automatic = button.is_automatic
is_automatic_company = button.is_automatic_company
is_automatic_group = button.is_automatic_group
is_logged_by = button.is_logged_by
is_logged_company = button.is_logged_company
is_logged_group = button.is_logged_group
is_dep = button.is_dep
is_field = button.specify_field_id
if button.reviewer_id:
employee = self.env['hr.employee'].search([
('user_id', '=', button.reviewer_id.id),
], limit=1)
return employee
# 部门和公司筛选条件
department_domain = []
company_domain = []
user_role_domain = []
if record_id:
# 获取当前用户和申请人的相关信息
current_user = self.env.user
applicant = None
# 获取申请人的用户对象
for field_name in ['user_id', 'users_id']:
if hasattr(record_id, field_name):
applicant = getattr(record_id, field_name)
if applicant:
break
# 根据勾选的条件设置域条件(只勾选一个)
if is_automatic and record_id.department_id:
# 按当前申请人自动匹配-本部门(保留部门和公司条件)
department_domain = ['|', ('department_id', '=', record_id.department_id.id),
('department_ids', 'in', record_id.department_id.id)]
company_domain = [('company_id', '=', applicant.company_id.id)]
elif is_automatic_company and applicant and hasattr(applicant, 'company_id'):
# 按当前申请人自动匹配-本公司(仅保留公司条件)
company_id = applicant.company_id.id
company_domain = [('company_id', '=', company_id)]
elif is_automatic_group and applicant and hasattr(applicant, 'company_id'):
# 按当前申请人自动匹配-本集团(仅保留公司条件)
parent_company = applicant.company_id.parent_id
if parent_company:
group_company_ids = self.env['res.company'].search([('id', 'child_of', parent_company.id)]).ids
company_domain = [('company_id', 'in', group_company_ids)]
elif is_dep and hasattr(record_id, 'department_id1') and record_id.department_id1:
department_id1 = record_id.department_id1.id
department_domain = ['|', ('department_id', '=', department_id1),
('department_ids', 'in', department_id1)]
user_role_domain = ['|', ('user_role_id', '=', button.role_id.user_role_ids.ids),
('user_role_ids', 'in', button.role_id.user_role_ids.ids)]
elif is_logged_by and current_user.department_id:
# 按当前登录人自动匹配-本部门(保留部门和公司条件)
department_domain = ['|', ('department_id', '=', current_user.department_id.id),
('department_ids', 'in', current_user.department_id.id)]
company_domain = [('company_id', '=', current_user.company_id.id)]
elif is_logged_company:
# 按当前登录人自动匹配-本公司(仅保留公司条件)
company_id = current_user.company_id.id
company_domain = [('company_id', '=', company_id)]
elif is_logged_group:
# 按当前登录人自动匹配-本集团(仅保留公司条件)
parent_company = current_user.company_id.parent_id
if parent_company:
group_company_ids = self.env['res.company'].search([('id', 'child_of', parent_company.id)]).ids
company_domain = [('company_id', 'in', group_company_ids)]
elif is_field:
field_name = button.specify_field_id.name
field_value = record_id[field_name]
if field_value:
if button.specify_field_id.relation == 'res.users':
employee = self.env['hr.employee'].sudo().search(
[('user_id', '=', field_value.id)],
limit=1
)
if employee:
return employee
else:
department_domain = ['|', ('department_id', '=', field_value.id),
('department_ids', 'in', field_value.id)]
if link_users_id:
role_domain = ['|', ('user_role_id', '=', link_users_id.id), ('user_role_ids', 'in', link_users_id.id)]
if user_role_domain:
role_domain = ['|'] + role_domain + user_role_domain
domain = role_domain + company_domain + department_domain
return self.env['hr.employee'].sudo().search(domain)
elif link_users_group_ids:
role_domain = ['|', ('user_role_id', 'in', link_users_group_ids.user_role_ids.ids),
('user_role_ids', 'in', link_users_group_ids.user_role_ids.ids)]
if user_role_domain:
role_domain = ['|'] + role_domain + user_role_domain
domain = role_domain + company_domain + department_domain
return self.env['hr.employee'].sudo().search(domain)
# 特殊分发按钮
if '分发' in link.name and record_id and hasattr(record_id, 'users_id'):
return record_id.users_id.employee_id
return self.env['hr.employee'] # 默认返回空记录集
def add_comment(self):
self.ensure_one()
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 == '转交':
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('请填写备注')
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
# 查询审批记录(使用确定的用户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)])
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)])
# 创建或更新当前用户的审批记录
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,
"lase_click_date": fields.Datetime.now(),
"approval_state": "2", # 已完成
"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 self.approval_concatenation == 'bing': # 并审模式
# 获取当前节点应该审批的所有员工
expected_employees = self.employee_ids
# 查找下一个节点
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 expected_employees:
# 检查该员工在下一节点是否已有记录
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'),
("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,
"node_btn_name": "4",
"approval_state": "0", # 待审批
})
next_node_log_records += next_node_employee_log
workflow_record_id = self.env['soong.workflow.record'].search([('code', '=', record_id.code)])
if self.employee_ids:
workflow_record_id.users_ids = [(4, employee.user_id.id) for employee in self.employee_ids if employee.user_id]
workflow_record_id.employee_ids = self.employee_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 = [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,)]
record_id.write({'state': self.trans_link_id.name})
if self.circulated_employee_ids:
workflow_record_id.is_log2 = True
workflow_record_id.employee2_ids = [(6, 0, self.circulated_employee_ids.ids)]
for employee in self.employee_ids:
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}=============================")
result_data = self.sudo().env["wecom.apps"].sync_send_message_textcard(category='oa',
user_id='18562027762',
title= record_id._description if 'Purchase Order' != record_id._description else '采购订单',
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: # 串审模式 (沿用原有逻辑)
# 查找下一个节点
next_node_id = record_id.workflow_id.node_ids.search([
('name', 'ilike', self.trans_link_id.name),
('workflow_id', '=', record_id.workflow_id.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 if self.employee_ids else query_user_id,
"node_btn_name": "0",
"lase_click_date": fields.Datetime.now(),
"approval_state": "1", # 待审批
})
# 更新业务记录状态
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,)]
record_id.write({'state': self.trans_link_id.name})
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",
})
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))
# 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 == '退回':
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
record_id.log_ids[-1].write({'approval_state': '2',
"lase_click_date": fields.Datetime.now(),
"comment": self.comment,
"node_btn_name": "1"})
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'].search([('code', '=', record_id.code)])
workflow_record_id.employee_ids = self.employee_ids
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,)]
workflow_record_id.users_ids = [(6, 0, user_ids)]
if self.node_btn_name in ['结束', '确认']:
current_user = self.env.user
current_datetime = fields.Datetime.now()
is_admin = current_user.has_group('soong_workflow.group_soong_workflow_manager')
if is_admin:
record_id.log_ids[-1].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
if record_id.log_ids:
user_log = record_id.log_ids.filtered(lambda log: log.done_by == current_user)
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 (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 + timedelta(hours=8),
})
if user_log1:
user_log1.write({
'comment': self.comment,
'approval_state': "2",
'lase_click_date': current_datetime + timedelta(hours=8),
})
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'].search([('code', '=', record_id.code)])
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 not record_id.log_ids2.search([('approval_state', '=', '0')]) or record_id.log_ids2:
last_log = record_id.log_ids[-1] if record_id.log_ids else None
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
log2_ids_all_qualified = True
if record_id.log_ids2:
log2_ids_all_qualified = all(log2.approval_state in ['2', '3'] for log2 in record_id.log_ids2)
if all_approved and log2_ids_all_qualified and not self.circulated_employee_ids:
workflow_record = self.env['soong.workflow.record'].search([('code', '=', record_id.code)],
limit=1)
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 == '归档')
if workflow_record:
workflow_record.write({
'approve_state': 'end',
'employee_ids': [(6, 0, [record_id.log_ids[0].done_by.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,
"lase_click_date": fields.Datetime.now(),
"done_by": record_id.log_ids[0].done_by.id,
"approval_state": "0",
"node_btn_id": self.node_btn_id.id,
})
else:
log_id.write({
"approval_state": "2",
})
workflow_record.write({
'soong_state': 'active',
'employee_ids': False,
})
else:
if workflow_record:
workflow_record.write({
'approve_state': 'end',
'employee_ids': False,
'node_id': False,
'soong_state': 'done',
})
record_id.work_end = True
# 给申请人发消息
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)
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=record_id._description,
description=f"标题为{record_id.name}的{record_id._description}已结束,请归档",
url=url, btntxt="查看详情")
self.node_btn_id.with_context(cx).run()
if self.node_btn_name == "分发":
record_id.is_send = True
menu_id = self.env['ir.ui.menu'].search([('name', '=', '行政收文')])
workflow_record_id = self.env['soong.workflow.record'].search([('code', '=', record_id.code)])
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'
url = self.sudo().env["wecom.apps"].generate_oauth_login_url(target_url)
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)])
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",
})
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",
})
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",
})
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
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')
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']
)
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]
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'
})
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,
})
self.node_btn_id.with_context(cx).run()
if self.node_btn_name == '归档':
menu_id = self.env['ir.ui.menu'].search([('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'
url = self.sudo().env["wecom.apps"].generate_oauth_login_url(target_url)
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)])
record.log_ids[-1].write({'is_active_operate': True,
'approval_state': '1'
})
workflow_record_id = self.env['soong.workflow.record'].search([('code', '=', record_id.code)])
if not self.circulated_employee_ids:
record.log_ids[-1].write({'approval_state': '2'})
if self.document_ids:
record.log_ids[-1].write({'document_ids': [(6, 0, self.document_ids.ids)]})
record.log_ids[-1].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",
})
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
# self.red_reload()
return {
'type': 'ir.actions.client',
'tag': 'flush_badge_wkf',
'params': {
'tree_id': tree_id,
'uid': self.env.uid,
}
}
# return {
# 'name': '流程待办',
# 'view_mode': 'tree',
# 'res_model': 'soong.workflow.record',
# 'type': 'ir.actions.act_window',
# 'views': [[tree_id, 'tree']],
# 'domain': [('users_ids', 'in', self.env.uid), ('reclaim_state', '=', False), ('soong_state', '=', 'to_do')],
# 'context': {
# 'header_search_default_approve_state': 1,
# 'header_search_default_to_do': 1,
# 'check_employee': 1
# }
# }
# def red_reload(self):
# return {
# 'type': 'ir.actions.client',
# 'tag': 'flush_badge',
# }
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,)]