This commit is contained in:
李鹏宇
2026-03-18 19:37:03 +08:00
2 changed files with 75 additions and 61 deletions
+73 -59
View File
@@ -1,11 +1,12 @@
# -*- coding: utf-8 -*-
import time
from odoo import models, fields, api, _
from odoo import models, exceptions
from odoo.exceptions import ValidationError, UserError
import logging
from datetime import datetime, date, time, timedelta
from datetime import datetime, date, timedelta
import re
from collections import defaultdict
_logger = logging.getLogger(__name__)
@@ -228,89 +229,103 @@ class SoongWorkflowRecord(models.Model):
record.is_to_do = is_todo
def _search_is_to_do(self, operator, value):
"""实现is_to_do字段的搜索逻辑:
兼容新增条件(approve_state=start + employee_ids包含当前用户)和原有逻辑
"""
"""搜索待办状态:仅打印总耗时"""
current_uid = self.env.user.id
# 1. 获取当前用户关联的员工ID
current_employees = self.env['hr.employee'].search([('user_id', '=', current_uid)])
current_employees = self.env['hr.employee'].sudo().search([('user_id', '=', current_uid)])
active_employee_ids = current_employees.ids if current_employees else []
if not active_employee_ids:
return [('id', '=', False)]
base_domain = [
('reclaim_state', '=', False),
'|',
('employee_ids', 'in', active_employee_ids),
('employee2_ids', 'in', active_employee_ids)
]
if (operator == '=' and value) or (operator == '!=' and not value):
candidate_records = self.search(base_domain)
valid_ids = []
for rec in candidate_records:
# 条件1:approve_state为start → 直接加入有效列表
if rec.approve_state == 'start' and not rec.reclaim_state:
valid_ids.append(rec.id)
continue
# 条件2:原有log_ids/log_ids2判断逻辑
if not candidate_records:
return [('id', '=', False)]
condition1_ids = candidate_records.filtered(
lambda r: r.approve_state == 'start' and not r.reclaim_state
).ids
model_res_ids = defaultdict(list)
rec_model_res_map = {}
for rec in candidate_records - self.browse(condition1_ids):
if rec.res_model and rec.res_id:
try:
target = self.env[rec.res_model].browse(rec.res_id).exists()
if not target:
continue
model_res_ids[rec.res_model].append(rec.res_id)
rec_model_res_map[rec.id] = (rec.res_model, rec.res_id)
log1_ok = any(
l.done_by.id == current_uid and l.approval_state in ['0', '1']
for l in target.log_ids
)
log2_ok = False
if not log1_ok:
log2_ok = any(
l.done_by.id == current_uid and l.approval_state in ['0', '1']
for l in target.log_ids2
)
condition2_rec_ids = []
for model_name, res_ids in model_res_ids.items():
if not res_ids:
continue
TargetModel = self.env[model_name].sudo()
log1_domain = [
('res_id', 'in', res_ids),
('done_by', '=', current_uid),
('approval_state', 'in', ['0', '1'])
]
log1_valid_res_ids = TargetModel.log_ids.search(log1_domain).mapped('res_id')
log2_domain = [
('res_id', 'in', res_ids),
('done_by', '=', current_uid),
('approval_state', 'in', ['0', '1'])
]
log2_valid_res_ids = TargetModel.log_ids2.search(log2_domain).mapped('res_id')
if log1_ok or log2_ok:
valid_ids.append(rec.id)
except (exceptions.MissingError, exceptions.AccessError):
continue
valid_res_ids = set(log1_valid_res_ids + log2_valid_res_ids)
for rec_id, (model, res_id) in rec_model_res_map.items():
if model == model_name and res_id in valid_res_ids:
condition2_rec_ids.append(rec_id)
valid_ids = list(set(condition1_ids + condition2_rec_ids))
domain = [('id', 'in', valid_ids)]
elif (operator == '=' and not value) or (operator == '!=' and value):
# 搜索待办=False的记录:排除满足条件1/2的记录
candidate_records = self.search(base_domain)
invalid_ids = []
if not candidate_records:
return [('id', '=', False)]
for rec in candidate_records:
# 标记满足条件1的记录
all_rec_emp_ids = rec.employee_ids.ids + rec.employee2_ids.ids
if rec.approve_state == 'start' and set(active_employee_ids) & set(all_rec_emp_ids) and not rec.reclaim_state:
invalid_ids.append(rec.id)
continue
condition1_invalid_ids = candidate_records.filtered(
lambda r: r.approve_state == 'start' and not r.reclaim_state
).ids
model_res_ids = defaultdict(list)
rec_model_res_map = {}
for rec in candidate_records - self.browse(condition1_invalid_ids):
if rec.res_model and rec.res_id:
try:
target = self.env[rec.res_model].browse(rec.res_id).exists()
if not target:
continue
model_res_ids[rec.res_model].append(rec.res_id)
rec_model_res_map[rec.id] = (rec.res_model, rec.res_id)
log1_ok = any(
l.done_by.id == current_uid and l.approval_state in ['0', '1']
for l in target.log_ids
)
log2_ok = False
if not log1_ok:
log2_ok = any(
l.done_by.id == current_uid and l.approval_state in ['0', '1']
for l in target.log_ids2
)
condition2_invalid_ids = []
for model_name, res_ids in model_res_ids.items():
if not res_ids:
continue
TargetModel = self.env[model_name].sudo()
log1_domain = [
('res_id', 'in', res_ids),
('done_by', '=', current_uid),
('approval_state', 'in', ['0', '1'])
]
log1_valid_res_ids = TargetModel.log_ids.search(log1_domain).mapped('res_id')
log2_domain = log1_domain.copy()
log2_valid_res_ids = TargetModel.log_ids2.search(log2_domain).mapped('res_id')
if log1_ok or log2_ok:
invalid_ids.append(rec.id)
except (exceptions.MissingError, exceptions.AccessError):
continue
valid_res_ids = set(log1_valid_res_ids + log2_valid_res_ids)
for rec_id, (model, res_id) in rec_model_res_map.items():
if model == model_name and res_id in valid_res_ids:
condition2_invalid_ids.append(rec_id)
invalid_ids = list(set(condition1_invalid_ids + condition2_invalid_ids))
domain = [('id', 'not in', invalid_ids)]
else:
domain = [('id', '=', False)]
return domain
@api.depends('employee_ids', 'soong_state', 'reclaim_state')
@@ -697,7 +712,6 @@ class SoongWorkflowRecord(models.Model):
elif log2.approval_state in ['0', '1']:
record.write({'soong_state': 'to_do'})
record._compute_is_done()
record._compute_is_to_do()
return super(SoongWorkflowRecord, self).get_view(view_id, view_type, **options)
def to_do_process_reminders(self):
@@ -453,7 +453,7 @@ class SoongWorkflowCommentWizard(models.TransientModel):
("model", "=", self.res_model),
("res_id", "=", self.res_id),
("done_by", "=", query_user_id),
("node_id", "=", self.node_btn_id.node_id.id)
("node_id", "=", self.node_btn_id.node_id.id),
],
order="lase_click_date DESC",
limit=1
@@ -522,9 +522,9 @@ class SoongWorkflowCommentWizard(models.TransientModel):
("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({