diff --git a/src/registrar/tests/test_reports.py b/src/registrar/tests/test_reports.py index 82942603a..1289c2467 100644 --- a/src/registrar/tests/test_reports.py +++ b/src/registrar/tests/test_reports.py @@ -889,7 +889,8 @@ class MemberExportTest(MockDbForIndividualTests, MockEppLib): "nonexistentmember_1@igorville.gov,False,help@get.gov,Unretrieved,Invited,None,Manager,False,0,\n" "nonexistentmember_2@igorville.gov,False,help@get.gov,Unretrieved,Invited,None,Viewer,False,0,\n" "nonexistentmember_3@igorville.gov,False,help@get.gov,Unretrieved,Invited,Viewer,None,False,0,\n" - "nonexistentmember_4@igorville.gov,True,help@get.gov,Unretrieved,Invited,Viewer Requester,Manager,False,0,\n" + "nonexistentmember_4@igorville.gov,True,help@get.gov,Unretrieved," + "Invited,Viewer Requester,Manager,False,0,\n" "nonexistentmember_5@igorville.gov,True,help@get.gov,Unretrieved,Invited,Viewer Requester,None,False,0,\n" ) # Normalize line endings and remove commas, diff --git a/src/registrar/utility/csv_export.py b/src/registrar/utility/csv_export.py index bd666923c..db5eb1657 100644 --- a/src/registrar/utility/csv_export.py +++ b/src/registrar/utility/csv_export.py @@ -146,6 +146,8 @@ class BaseExport(BaseModelAnnotation): class MemberExport(BaseExport): + """CSV export for the MembersTable. The members table combines the content + of three tables: PortfolioInvitation, UserPortfolioPermission, and DomainInvitation.""" @classmethod def model(self): @@ -185,8 +187,7 @@ class MemberExport(BaseExport): invitations = PortfolioInvitationModelAnnotation.get_annotated_queryset(portfolio, csv_report=True).values( *shared_columns ) - queryset_dict = convert_queryset_to_dict(permissions.union(invitations), is_model=False) - return queryset_dict + return convert_queryset_to_dict(permissions.union(invitations), is_model=False) @classmethod def get_columns(cls): @@ -213,30 +214,23 @@ class MemberExport(BaseExport): Given a set of columns and a model dictionary, generate a new row from cleaned column data. Must be implemented by subclasses """ - roles = model.get("roles") - additional_permissions = model.get("additional_permissions_display") - is_admin = UserPortfolioRoleChoices.ORGANIZATION_ADMIN in (roles or []) - domain_request_display = UserPortfolioPermission.get_domain_request_permission_display( - roles, additional_permissions - ) - member_perm_display = UserPortfolioPermission.get_member_permission_display(roles, additional_permissions) + roles = model.get("roles", []) + permissions = model.get("additional_permissions_display") user_managed_domains = model.get("domain_info", []) - managed_domains_as_csv = ",".join(user_managed_domains) + length_user_managed_domains = len(user_managed_domains) FIELDS = { "Email": model.get("email_display"), - "Organization admin": is_admin, + "Organization admin": bool(UserPortfolioRoleChoices.ORGANIZATION_ADMIN in roles), "Invited by": model.get("invited_by"), "Joined date": model.get("joined_date"), "Last active": model.get("last_active"), - "Domain requests": domain_request_display, - "Member management": member_perm_display, - "Domain management": len(user_managed_domains) > 0, - "Number of domains": len(user_managed_domains), - "Domains": managed_domains_as_csv, + "Domain requests": UserPortfolioPermission.get_domain_request_permission_display(roles, permissions), + "Member management": UserPortfolioPermission.get_member_permission_display(roles, permissions), + "Domain management": bool(length_user_managed_domains > 0), + "Number of domains": length_user_managed_domains, + "Domains": ",".join(user_managed_domains), } - - row = [FIELDS.get(column, "") for column in columns] - return row + return [FIELDS.get(column, "") for column in columns] class DomainExport(BaseExport): diff --git a/src/registrar/utility/model_annotations.py b/src/registrar/utility/model_annotations.py index f0ef70396..0fc430f4f 100644 --- a/src/registrar/utility/model_annotations.py +++ b/src/registrar/utility/model_annotations.py @@ -256,7 +256,7 @@ class UserPortfolioPermissionModelAnnotation(BaseModelAnnotation): portfolio=OuterRef(OuterRef("portfolio")), ).values("id")[:1] ), - output_field=TextField(), + output_field=CharField(), ) @classmethod @@ -297,7 +297,7 @@ class UserPortfolioPermissionModelAnnotation(BaseModelAnnotation): "last_active": Coalesce( last_active_query, Value("Invalid date"), - output_field=TextField(), + output_field=CharField(), ), "additional_permissions_display": F("additional_permissions"), "member_display": Case( @@ -324,7 +324,7 @@ class UserPortfolioPermissionModelAnnotation(BaseModelAnnotation): & Q(user__permissions__domain__domain_info__portfolio=portfolio), ), "type": Value("member", output_field=CharField()), - "joined_date": Func(F("created_at"), Value("YYYY-MM-DD"), function="to_char", output_field=TextField()), + "joined_date": Func(F("created_at"), Value("YYYY-MM-DD"), function="to_char", output_field=CharField()), "invited_by": PortfolioInvitationModelAnnotation.get_invited_by_query( object_id_query=cls.get_portfolio_invitation_id_query() ), @@ -426,7 +426,7 @@ class PortfolioInvitationModelAnnotation(BaseModelAnnotation): "first_name": Value(None, output_field=CharField()), "last_name": Value(None, output_field=CharField()), "email_display": F("email"), - "last_active": Value("Invited", output_field=TextField()), + "last_active": Value("Invited", output_field=CharField()), "additional_permissions_display": F("additional_permissions"), "member_display": F("email"), # Use ArrayRemove to return an empty list when no domain invitations are found @@ -438,7 +438,7 @@ class PortfolioInvitationModelAnnotation(BaseModelAnnotation): ), "type": Value("invitedmember", output_field=CharField()), "joined_date": Value("Unretrieved", output_field=CharField()), - "invited_by": cls.get_invited_by_query(object_id_query=Cast(OuterRef("id"), output_field=TextField())), + "invited_by": cls.get_invited_by_query(object_id_query=Cast(OuterRef("id"), output_field=CharField())), } @classmethod