diff --git a/src/registrar/forms/portfolio.py b/src/registrar/forms/portfolio.py index 5aef09389..b83e718cb 100644 --- a/src/registrar/forms/portfolio.py +++ b/src/registrar/forms/portfolio.py @@ -445,3 +445,28 @@ class PortfolioNewMemberForm(BasePortfolioMemberForm): class Meta: model = PortfolioInvitation fields = ["portfolio", "email", "roles", "additional_permissions"] + + def _post_clean(self): + """ + Override _post_clean to customize model validation errors. + This runs after form clean is complete, but before the errors are displayed. + """ + try: + super()._post_clean() + self.instance.clean() + except forms.ValidationError as e: + override_error = False + if hasattr(e, "code"): + field = "email" if "email" in self.fields else None + if e.code == "has_existing_permissions": + self.add_error(field, f"{self.instance.email} is already a member of another .gov organization.") + override_error = True + elif e.code == "has_existing_invitations": + self.add_error( + field, f"{self.instance.email} has already been invited to another .gov organization." + ) + override_error = True + + # Errors denoted as "__all__" are special error types reserved for the model level clean function + if override_error and "__all__" in self._errors: + del self._errors["__all__"] diff --git a/src/registrar/models/utility/portfolio_helper.py b/src/registrar/models/utility/portfolio_helper.py index 03dca897f..009ea3c26 100644 --- a/src/registrar/models/utility/portfolio_helper.py +++ b/src/registrar/models/utility/portfolio_helper.py @@ -292,7 +292,8 @@ def validate_user_portfolio_permission(user_portfolio_permission): if existing_permissions.exists(): raise ValidationError( "This user is already assigned to a portfolio. " - "Based on current waffle flag settings, users cannot be assigned to multiple portfolios." + "Based on current waffle flag settings, users cannot be assigned to multiple portfolios.", + code="has_existing_permissions", ) existing_invitations = PortfolioInvitation.objects.filter(email=user_portfolio_permission.user.email).exclude( @@ -302,7 +303,8 @@ def validate_user_portfolio_permission(user_portfolio_permission): if existing_invitations.exists(): raise ValidationError( "This user is already assigned to a portfolio invitation. " - "Based on current waffle flag settings, users cannot be assigned to multiple portfolios." + "Based on current waffle flag settings, users cannot be assigned to multiple portfolios.", + code="has_existing_invitations", ) @@ -350,6 +352,7 @@ def validate_portfolio_invitation(portfolio_invitation): # == Validate the multiple_porfolios flag. == # user = User.objects.filter(email=portfolio_invitation.email).first() + # If user returns None, then we check for global assignment of multiple_portfolios. # Otherwise we just check on the user. if not flag_is_active_for_user(user, "multiple_portfolios"): @@ -362,13 +365,15 @@ def validate_portfolio_invitation(portfolio_invitation): if existing_permissions.exists(): raise ValidationError( "This user is already assigned to a portfolio. " - "Based on current waffle flag settings, users cannot be assigned to multiple portfolios." + "Based on current waffle flag settings, users cannot be assigned to multiple portfolios.", + code="has_existing_permissions", ) if existing_invitations.exists(): raise ValidationError( "This user is already assigned to a portfolio invitation. " - "Based on current waffle flag settings, users cannot be assigned to multiple portfolios." + "Based on current waffle flag settings, users cannot be assigned to multiple portfolios.", + code="has_existing_invitations", ) diff --git a/src/registrar/tests/test_views_portfolio.py b/src/registrar/tests/test_views_portfolio.py index 64bcb50a8..92e053576 100644 --- a/src/registrar/tests/test_views_portfolio.py +++ b/src/registrar/tests/test_views_portfolio.py @@ -3873,11 +3873,7 @@ class TestPortfolioInviteNewMemberView(MockEppLib, WebTest): # verify messages self.assertContains( response, - ( - "This user is already assigned to a portfolio invitation. " - "Based on current waffle flag settings, users cannot be assigned " - "to multiple portfolios." - ), + f"{self.invited_member_email} has already been invited to another .gov organization.", ) # Validate Database has not changed @@ -3915,11 +3911,7 @@ class TestPortfolioInviteNewMemberView(MockEppLib, WebTest): # Verify messages self.assertContains( response, - ( - "This user is already assigned to a portfolio. " - "Based on current waffle flag settings, users cannot be " - "assigned to multiple portfolios." - ), + f"{self.user.email} is already a member of another .gov organization.", ) # Validate Database has not changed