@@ -169,153 +169,142 @@ class SoongWorkflowRecord(models.Model):
_logger . warning ( f " Failed to get urgency_level from { record . res_model } : { e } " )
record . urgency_level = ' normal '
@api.depends ( ' employee_ids ' , ' res_model ' , ' res_id ' , ' soong_state ' , ' reclaim_state ' , ' approve_state ' )
@api.depends ( ' employee_ids ' , ' res_model ' , ' res_id ' , ' soong_state ' , ' reclaim_state ' , ' approve_state ' ,
' employee2_ids ' )
def _compute_is_to_do ( self ) :
""" 保留原有计算逻辑(已优化批量查询,参考之前的版本) """
current_uid = self . env . user . id
current_employees = self . env [ ' hr.employee ' ] . search ( [ ( ' user_id ' , ' = ' , current_uid ) ] )
active_employee_ids = current_employees . ids if current_employees else [ ]
if not active_employee_ids :
self . is_to_do = False
# 关键修改:不再查users_ids,改为查当前用户对应的hr.employee记录
current_employee = self . env [ ' hr.employee ' ] . search ( [ ( ' user_id ' , ' = ' , current_uid ) ] , limit = 1 )
if not current_employee :
# 若当前用户无对应员工记录,所有记录均为非待办
for rec in self :
rec . is_to_do = False
return
all_employees = self . env [ ' hr.employee ' ] . search ( [ ( ' user_state ' , ' = ' , ' in ' ) ] )
emp_to_user = { emp . id : emp . user_id . id for emp in all_employees if emp . user_id }
# 第一步:批量处理条件1( approve_state=start)
condition1_records = self . filtered (
lambda r : not r . reclaim_state and r . approve_state == ' start ' and
set ( active_employee_ids ) & set ( r . employee_ids . ids + r . employee2_ids . ids )
# 初始化所有记录为非待办(上下文流畅,保留原有初始化逻辑)
self . is_to_do = False
valid_records = self . filtered (
lambda r : ( current_employee . id in r . employee_ids . ids or current_employee . id in r . employee2_ids . ids )
and not r . reclaim_state
)
condition1_records . is_to_do = True
if not valid_records :
return
# 以下逻辑完全不变,和你原来一致
start_records = valid_records . filtered ( lambda r : r . approve_state == ' start ' )
start_records . is_to_do = True
remaining_records = valid_records - start_records
if not remaining_records :
return
# 第二步:批量处理条件2( log_ids/log_ids2)
remaining_records = self - condition1_records
remaining_records . is_to_do = False
target_records = remaining_records . filtered (
lambda r : r . res_model and r . res_id and r . approve_state not in [ ' draft ' , ' start ' ]
)
if not target_records :
return
# 按res_model分组批量查询log(核心优化 )
model_res_ids = defaultdict ( list )
rec_model_res_map = { }
for rec in remaining_records . filtered ( lambda r : not r . reclaim_state and r . res_model and r . res_id ) :
model_res_ids [ rec . res_model ] . append ( rec . res_id )
rec_model_res_map [ rec . id ] = ( rec . res_model , rec . res_id )
# 批量查询日志(性能优化保留,逻辑不变 )
model_res_id_pairs = [ ( rec . res_model , rec . res_id ) for rec in target_records ]
log1_domain = [
( ' model ' , ' in ' , list ( { m for m , _ in model_res_id_pairs } ) ) ,
( ' res_id ' , ' in ' , list ( { r for _ , r in model_res_id_pairs } ) ) ,
( ' done_by ' , ' = ' , current_uid ) ,
( ' approval_state ' , ' in ' , [ ' 0 ' , ' 1 ' ] )
]
log2_domain = log1_domain . copy ( )
# 批量查log满足条件的记录ID
valid_rec_ids = [ ]
for model_name , res_ids in model_res_ids . items ( ) :
if not res_ids :
continue
TargetModel = self . env [ model_name ] . sudo ( )
log_domain = [
( ' res_id ' , ' in ' , res_ids ) ,
( ' done_by ' , ' in ' , list ( emp_to_user . values ( ) ) ) ,
( ' approval_state ' , ' in ' , [ ' 0 ' , ' 1 ' ] )
]
# 批量查log_ids
log1_valid_res_ids = TargetModel . log_ids . search ( log_domain ) . mapped ( ' res_id ' )
# 批量查log_ids2
log2_valid_res_ids = TargetModel . log_ids2 . search ( log_domain ) . mapped ( ' res_id ' )
valid_log1_pairs = set ( )
log1_records = self . env [ ' soong.workflow.log ' ] . search ( log1_domain )
for log in log1_records :
valid_log1_pairs . add ( ( log . model , log . res_id ) )
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 :
valid_rec_ids . append ( rec_id )
self . browse ( valid_rec_ids ) . is_to_do = True
valid_log2_pairs = set ( )
log2_records = self . env [ ' soong.workflow.log2 ' ] . search ( log2_domain )
for log in log2_records :
valid_log2_pairs . add ( ( log . model , log . res_id ) )
valid_pairs = valid_log1_pairs | valid_log2_pairs
for rec in target_records :
if ( rec . res_model , rec . res_id ) in valid_pairs :
rec . is_to_do = True
def _search_is_to_do ( self , operator , value ) :
""" 搜索待办状态:仅打印总耗时 """
current_uid = self . env . user . id
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 :
current_employee = self . env [ ' hr.employee ' ] . search ( [ ( ' user_id ' , ' = ' , current_uid ) ] , limit = 1 )
if not current_employee :
return [ ( ' id ' , ' = ' , False ) ]
base_domain = [
' | ' ,
( ' employee_ids ' , ' in ' , [ current_employee . id ] ) ,
( ' employee2_ids ' , ' in ' , [ current_employee . id ] ) ,
( ' reclaim_state ' , ' = ' , False )
]
candidate_records = self . search ( base_domain )
if not candidate_records :
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 )
if not candidate_records :
return [ ( ' id ' , ' = ' , False ) ]
condition1_ids = candidate_records . filtered (
lambda r : r . approve_state == ' start ' and not r . reclaim_state
lambda r : r . approve_state == ' start '
) . 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 :
model_res_ids [ rec . res_model ] . append ( rec . res_id )
rec_model_res_map [ rec . id ] = ( rec . res_model , rec . res_id )
remaining_records = candidate_records - self . browse ( condition1_ids )
target_records = remaining_records . filtered (
lambda r : r . res_model and r . res_id and r . approve_state not in [ ' draft ' , ' start ' ]
)
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 ) ,
if target_records :
model_res_id_pairs = [ ( rec . res_model , rec . res_id ) for rec in target_records ]
log_domain = [
( ' model ' , ' in ' , list ( { m for m , _ in model_res_id_pairs } ) ) ,
( ' res_id ' , ' in ' , list ( { r for _ , r in model_res_id_pairs } ) ) ,
( ' 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 ' )
log1_valid_pairs = set (
( log . model , log . res_id ) for log in self . env [ ' soong.workflow.log ' ] . search ( log_domain ) )
log2_valid_pairs = set (
( log . model , log . res_id ) for log in self . env [ ' soong.workflow.log2 ' ] . search ( log_domain ) )
valid_pairs = log1_valid_pairs | log2_valid_pairs
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 )
for rec in target_records :
if ( rec . res_model , rec . res_id ) in valid_pairs :
condition2_rec_ids . append ( rec . id )
valid_ids = list ( set ( condition1_ids + condition2_rec_ids ) )
domain = [ ( ' id ' , ' in ' , valid_ids ) ]
domain = [ ( ' id ' , ' in ' , valid_ids ) ] if valid_ids else [ ( ' id ' , ' = ' , False ) ]
elif ( operator == ' = ' and not value ) or ( operator == ' != ' and value ) :
candidate_records = self . search ( base_domain )
if not candidate_records :
return [ ( ' id ' , ' = ' , False ) ]
condition1_todo_ids = candidate_records . filtered ( lambda r : r . approve_state == ' start ' ) . ids
condition1_invalid_ids = candidate_records . filtered (
lambda r : r . approve_state == ' start ' and not r . reclaim_state
) . ids
remaining_records = candidate_records - self . browse ( condition1_todo_ids )
target_records = remaining_records . filtered (
lambda r : r . res_model and r . res_id and r . approve_state not in [ ' draft ' , ' start ' ]
)
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 :
model_res_ids [ rec . res_model ] . append ( rec . res_id )
rec_model_res_map [ rec . id ] = ( rec . res_model , rec . res_id )
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 ) ,
condition2_todo_ids = [ ]
if target_records :
model_res_id_pairs = [ ( rec . res_model , rec . res_id ) for rec in target_records ]
log_domain = [
( ' model ' , ' in ' , list ( { m for m , _ in model_res_id_pairs } ) ) ,
( ' res_id ' , ' in ' , list ( { r for _ , r in model_res_id_pairs } ) ) ,
( ' 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 ' )
log1_valid_pairs = set (
( log . model , log . res_id ) for log in self . env [ ' soong.workflow.log ' ] . search ( log_domain ) )
log2_valid_pairs = set (
( log . model , log . res_id ) for log in self . env [ ' soong.workflow.log2 ' ] . search ( log_domain ) )
valid_pairs = log1_valid_pairs | log2_valid_pairs
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 )
for rec in target_records :
if ( rec . res_model , rec . res_id ) in valid_pairs :
condition2_todo_ids . append ( rec . id )
invalid_ids = list ( set ( condition1_invalid_ids + condition2_invalid_ids ) )
domain = [ ( ' id ' , ' not in ' , invalid_ids ) ]
todo_ids = list ( set ( condition1_todo_ids + condition2_todo_ids ) )
all_candidate_ids = candidate_records . ids
non_todo_ids = [ rec_id for rec_id in all_candidate_ids if rec_id not in todo_ids ]
domain = [ ( ' id ' , ' in ' , non_todo_ids ) ] if non_todo_ids else [ ( ' id ' , ' = ' , False ) ]
else :
domain = [ ( ' id ' , ' = ' , False ) ]
@@ -669,15 +658,21 @@ class SoongWorkflowRecord(models.Model):
@api.model
def get_view ( self , view_id = None , view_type = ' form ' , * * options ) :
current_user_id = self . env . user . id
all_records = self . search ( [
( ' users_ids ' , ' in ' , current_user_id ) ,
( ' soong_state ' , ' != ' , ' active ' ) ,
] )
if not all_records :
return super ( ) . get_view ( view_id , view_type , * * options )
all_records . _compute_is_done ( )
all_records . _compute_is_to_do ( )
return super ( ) . get_view ( view_id , view_type , * * options )
current_employee = self . env [ ' hr.employee ' ] . search ( [ ( ' user_id ' , ' = ' , current_user_id ) ] , limit = 1 )
view = super ( ) . get_view ( view_id , view_type , * * options )
if not current_employee :
return view
if view_type == ' list ' :
all_records = self . search ( [
' | ' ,
( ' employee_ids ' , ' in ' , [ current_employee . id ] ) ,
( ' employee2_ids ' , ' in ' , [ current_employee . id ] ) ,
( ' reclaim_state ' , ' = ' , False ) # 补回丢失的过滤条件
] ) # 限制最大记录数,避免性能问题
if all_records :
all_records . _compute_is_done ( )
all_records . _compute_is_to_do ( )
return view
def to_do_process_reminders ( self ) :
workflow_records = self . env [ ' soong.workflow.record ' ] . search ( [