diff --git a/partner_programs/services.py b/partner_programs/services.py index 1aac24fc..7a6ea0fb 100644 --- a/partner_programs/services.py +++ b/partner_programs/services.py @@ -132,6 +132,7 @@ def get_project_scores_info(self) -> dict[str, str]: ("project_region", "Регион проекта"), ("project_presentation", "Ссылка на презентацию"), ("team_size", "Количество человек в команде"), + ("team_members", "Состав команды"), ("leader_full_name", "Имя фамилия лидера"), ] EXCEL_CELL_MAX = 32767 # лимит символов в ячейке Excel @@ -174,6 +175,10 @@ def _leader_full_name(user): def _calc_team_size(project): + prefetched_collaborators = getattr(project, "_prefetched_collaborators", None) + if prefetched_collaborators is not None: + return 1 + len(prefetched_collaborators) + try: if hasattr(project, "get_collaborators_user_list"): return 1 + len(project.get_collaborators_user_list()) @@ -184,6 +189,41 @@ def _calc_team_size(project): return 1 +def _team_members(project) -> str: + members: list[str] = [] + seen_ids: set[int | None] = set() + + leader = getattr(project, "leader", None) + if leader: + leader_name = _leader_full_name(leader) + if leader_name: + members.append(leader_name) + seen_ids.add(getattr(leader, "id", None)) + + collaborators = getattr(project, "_prefetched_collaborators", None) + if collaborators is None: + collaborators = ( + project.collaborator_set.select_related("user").all() + if hasattr(project, "collaborator_set") + else [] + ) + + for collaborator in collaborators: + user = getattr(collaborator, "user", None) + if not user: + continue + user_id = getattr(user, "id", None) + if user_id in seen_ids: + continue + name = _leader_full_name(user) + if not name: + continue + members.append(name) + seen_ids.add(user_id) + + return "\n".join(members) + + def build_program_field_columns(program) -> list[tuple[str, str]]: program_fields = program.fields.all().order_by("pk") return [ @@ -212,6 +252,7 @@ def row_dict_for_link( row["project_region"] = project.region or "" row["project_presentation"] = project.presentation_address or "" row["team_size"] = _calc_team_size(project) + row["team_members"] = _team_members(project) row["leader_full_name"] = _leader_full_name(getattr(project, "leader", None)) values_map: dict[str, str] = {} diff --git a/partner_programs/views.py b/partner_programs/views.py index 101d0eb7..8fa8dd43 100644 --- a/partner_programs/views.py +++ b/partner_programs/views.py @@ -48,7 +48,7 @@ sanitize_excel_value, ) from partner_programs.utils import filter_program_projects_by_field_name -from projects.models import Project +from projects.models import Collaborator, Project from projects.serializers import ( PartnerProgramFieldValueUpdateSerializer, ProjectListSerializer, @@ -525,7 +525,12 @@ def get(self, request, pk: int): links_qs = program.program_projects.select_related( "project", "project__leader" ).prefetch_related( - Prefetch("field_values", queryset=fv_qs, to_attr="_prefetched_field_values") + Prefetch("field_values", queryset=fv_qs, to_attr="_prefetched_field_values"), + Prefetch( + "project__collaborator_set", + queryset=Collaborator.objects.select_related("user"), + to_attr="_prefetched_collaborators", + ), ) if only_submitted: links_qs = links_qs.filter(submitted=True)