11import logging
2+ from collections import OrderedDict
23
34from partner_programs .models import PartnerProgramUserProfile
45from project_rates .models import Criteria , ProjectScore
56
6-
77logger = logging .getLogger ()
88
99
@@ -23,16 +23,14 @@ class ProjectScoreDataPreparer:
2323 "Класс_курс" : "ОШИБКА" ,
2424 }
2525
26- EXPERT_ERROR_FIELDS = {
27- "Фамилия эксперта" : "ОШИБКА"
28- }
26+ EXPERT_ERROR_FIELDS = {"Фамилия эксперта" : "ОШИБКА" }
2927
3028 def __init__ (
3129 self ,
3230 user_profiles : dict [int , PartnerProgramUserProfile ],
3331 scores : dict [int , list [ProjectScore ]],
3432 project_id : int ,
35- program_id : int
33+ program_id : int ,
3634 ):
3735 self ._project_id = project_id
3836 self ._user_profiles = user_profiles
@@ -41,35 +39,54 @@ def __init__(
4139
4240 def get_project_user_info (self ) -> dict [str , str ]:
4341 try :
44- user_program_profile : PartnerProgramUserProfile = self ._user_profiles .get (self ._project_id )
45- user_program_profile_json : dict = user_program_profile .partner_program_data if user_program_profile else {}
42+ user_program_profile : PartnerProgramUserProfile = self ._user_profiles .get (
43+ self ._project_id
44+ )
45+ user_program_profile_json : dict = (
46+ user_program_profile .partner_program_data if user_program_profile else {}
47+ )
4648
4749 user_info : dict [str , str ] = {
48- "Фамилия" : user_program_profile .user .last_name if user_program_profile else '' ,
49- "Имя" : user_program_profile .user .first_name if user_program_profile else '' ,
50- "Отчество" : user_program_profile .user .patronymic if user_program_profile else '' ,
50+ "Фамилия" : (
51+ user_program_profile .user .last_name if user_program_profile else ""
52+ ),
53+ "Имя" : (
54+ user_program_profile .user .first_name if user_program_profile else ""
55+ ),
56+ "Отчество" : (
57+ user_program_profile .user .patronymic if user_program_profile else ""
58+ ),
5159 "Email" : (
52- user_program_profile_json .get ('email' ) if user_program_profile_json .get ('email' )
60+ user_program_profile_json .get ("email" )
61+ if user_program_profile_json .get ("email" )
5362 else user_program_profile .user .email
5463 ),
55- "Регион_РФ" : user_program_profile_json .get ('region' , '' ),
56- "Учебное_заведение" : user_program_profile_json .get ('education_type' , '' ),
57- "Название_учебного_заведения" : user_program_profile_json .get ('institution_name' , '' ),
58- "Класс_курс" : user_program_profile_json .get ('class_course' , '' ),
64+ "Регион_РФ" : user_program_profile_json .get ("region" , "" ),
65+ "Учебное_заведение" : user_program_profile_json .get ("education_type" , "" ),
66+ "Название_учебного_заведения" : user_program_profile_json .get (
67+ "institution_name" , ""
68+ ),
69+ "Класс_курс" : user_program_profile_json .get ("class_course" , "" ),
5970 }
6071 return user_info
6172 except Exception as e :
62- logger .error (f"Prepare export rates data about user error: { str (e )} " , exc_info = True )
73+ logger .error (
74+ f"Prepare export rates data about user error: { str (e )} " , exc_info = True
75+ )
6376 return self .USER_ERROR_FIELDS
6477
6578 def get_project_expert_info (self ) -> dict [str , str ]:
6679 try :
6780 project_scores : list [ProjectScore ] = self ._scores .get (self ._project_id , [])
6881 first_score = project_scores [0 ] if project_scores else None
69- expert_last_name : dict [str , str ] = {"Фамилия эксперта" : first_score .user .last_name if first_score else '' }
82+ expert_last_name : dict [str , str ] = {
83+ "Фамилия эксперта" : first_score .user .last_name if first_score else ""
84+ }
7085 return expert_last_name
7186 except Exception as e :
72- logger .error (f"Prepare export rates data about expert error: { str (e )} " , exc_info = True )
87+ logger .error (
88+ f"Prepare export rates data about expert error: { str (e )} " , exc_info = True
89+ )
7390 return self .EXPERT_ERROR_FIELDS
7491
7592 def get_project_scores_info (self ) -> dict [str , str ]:
@@ -78,16 +95,114 @@ def get_project_scores_info(self) -> dict[str, str]:
7895 project_scores : list [ProjectScore ] = self ._scores .get (self ._project_id , [])
7996 score_info_with_out_comment : dict [str , str ] = {
8097 score .criteria .name : score .value
81- for score in project_scores if score .criteria .name != "Комментарий"
98+ for score in project_scores
99+ if score .criteria .name != "Комментарий"
82100 }
83101 project_scores_dict .update (score_info_with_out_comment )
84- comment = next ((score for score in project_scores if score .criteria .name == "Комментарий" ), None )
102+ comment = next (
103+ (
104+ score
105+ for score in project_scores
106+ if score .criteria .name == "Комментарий"
107+ ),
108+ None ,
109+ )
85110 if comment is not None :
86111 project_scores_dict ["Комментарий" ] = comment .value
87112 return project_scores_dict
88113 except Exception as e :
89- logger .error (f"Prepare export rates data about project_scores error: { str (e )} " , exc_info = True )
114+ logger .error (
115+ f"Prepare export rates data about project_scores error: { str (e )} " ,
116+ exc_info = True ,
117+ )
90118 return {
91119 criteria .name : "ОШИБКА"
92- for criteria in Criteria .objects .filter (partner_program__id = self ._program_id )
120+ for criteria in Criteria .objects .filter (
121+ partner_program__id = self ._program_id
122+ )
93123 }
124+
125+
126+ BASE_COLUMNS = [
127+ ("row_number" , "№ п/п" ),
128+ ("project_name" , "Название проекта" ),
129+ ("project_description" , "Описание проекта" ),
130+ ("project_region" , "Регион проекта" ),
131+ ("project_presentation" , "Ссылка на презентацию" ),
132+ ("team_size" , "Количество человек в команде" ),
133+ ("leader_full_name" , "Имя фамилия лидера" ),
134+ ]
135+
136+
137+ def _leader_full_name (user ):
138+ if not user :
139+ return ""
140+ if hasattr (user , "get_full_name" ) and callable (user .get_full_name ):
141+ full = user .get_full_name ()
142+ if full :
143+ return full
144+ first = getattr (user , "first_name" , "" ) or ""
145+ last = getattr (user , "last_name" , "" ) or ""
146+ return (first + " " + last ).strip () or getattr (user , "username" , "" ) or str (user .pk )
147+
148+
149+ def _calc_team_size (project ):
150+ try :
151+ if hasattr (project , "get_collaborators_user_list" ):
152+ return 1 + len (project .get_collaborators_user_list ())
153+ if hasattr (project , "collaborator_set" ):
154+ return 1 + project .collaborator_set .count ()
155+ except Exception :
156+ pass
157+ return 1
158+
159+
160+ def build_program_field_columns (program ) -> list [tuple [str , str ]]:
161+ program_fields = program .fields .all ().order_by ("pk" )
162+ return [
163+ (f"name:{ program_field .name } " , program_field .label )
164+ for program_field in program_fields
165+ ]
166+
167+
168+ def row_dict_for_link (
169+ program_project_link ,
170+ extra_field_keys_order : list [str ],
171+ row_number : int ,
172+ ) -> OrderedDict :
173+ """
174+ program_project_link: PartnerProgramProject
175+ extra_field_keys_order: список псевдоключей "name:<field.name>" в нужном порядке
176+ row_number: порядковый номер строки в Excel (начиная с 1)
177+ """
178+ project = program_project_link .project
179+ row = OrderedDict ()
180+
181+ row ["row_number" ] = row_number
182+
183+ row ["project_name" ] = project .name or ""
184+ row ["project_description" ] = project .description or ""
185+ row ["project_region" ] = project .region or ""
186+ row ["project_presentation" ] = project .presentation_address or ""
187+ row ["team_size" ] = _calc_team_size (project )
188+ row ["leader_full_name" ] = _leader_full_name (getattr (project , "leader" , None ))
189+
190+ values_map : dict [str , str ] = {}
191+ prefetched_values = getattr (program_project_link , "_prefetched_field_values" , None )
192+ field_values_iterable = (
193+ prefetched_values
194+ if prefetched_values is not None
195+ else program_project_link .field_values .all ()
196+ )
197+
198+ for field_value in field_values_iterable :
199+ if (
200+ field_value .field .partner_program_id
201+ == program_project_link .partner_program_id
202+ ):
203+ values_map [f"name:{ field_value .field .name } " ] = field_value .get_value ()
204+
205+ for field_key in extra_field_keys_order :
206+ row [field_key ] = values_map .get (field_key , "" )
207+
208+ return row
0 commit comments