handle removals

This commit is contained in:
David Kennedy 2025-01-30 16:30:18 -05:00
parent f786d13cdf
commit b1f528b9a2
No known key found for this signature in database
GPG key ID: 6528A5386E66B96B
2 changed files with 105 additions and 1 deletions

View file

@ -275,3 +275,54 @@ def _send_portfolio_admin_addition_emails_to_portfolio_admins(email: str, reques
)
all_emails_sent = False
return all_emails_sent
def send_portfolio_admin_removal_emails(email: str, requestor, portfolio: Portfolio):
"""
Notifies all portfolio admins of the provided portfolio of a removed portfolio admin
Returns:
Boolean indicating if all messages were sent successfully.
Raises:
MissingEmailError
"""
requestor_email = _get_requestor_email(requestor, portfolio=portfolio)
return _send_portfolio_admin_removal_emails_to_portfolio_admins(email, requestor_email, portfolio)
def _send_portfolio_admin_removal_emails_to_portfolio_admins(email: str, requestor_email, portfolio: Portfolio):
"""
Notifies all portfolio admins of the provided portfolio of a removed portfolio admin
Returns:
Boolean indicating if all messages were sent successfully.
"""
all_emails_sent = True
# Get each portfolio admin from list
user_portfolio_permissions = UserPortfolioPermission.objects.filter(
portfolio=portfolio, roles__contains=[UserPortfolioRoleChoices.ORGANIZATION_ADMIN]
).exclude(user__email=email)
for user_portfolio_permission in user_portfolio_permissions:
# Send email to each portfolio_admin
user = user_portfolio_permission.user
try:
send_templated_email(
"emails/portfolio_admin_removal_notification.txt",
"emails/portfolio_admin_removal_notification_subject.txt",
to_address=user.email,
context={
"portfolio": portfolio,
"requestor_email": requestor_email,
"removed_email_address": email,
"portfolio_admin": user,
"date": date.today(),
},
)
except EmailSendingError:
logger.warning(
f"Could not send email organization admin notification to {user.email} for portfolio: {portfolio.name}",
exc_info=True,
)
all_emails_sent = False
return all_emails_sent

View file

@ -148,6 +148,21 @@ class PortfolioMemberDeleteView(PortfolioMemberPermission, View):
messages.error(request, error_message)
return redirect(reverse("member", kwargs={"pk": pk}))
# if member being removed is an admin
if UserPortfolioRoleChoices.ORGANIZATION_ADMIN in portfolio_member_permission.roles:
try:
# attempt to send notification emails of the removal to other portfolio admins
if not send_portfolio_admin_removal_emails(
email=portfolio_member_permission.user.email,
requestor=request.user,
portfolio=portfolio_member_permission.portfolio
):
messages.warning(
self.request, "Could not send email notification to existing organization admins."
)
except Exception as e:
self._handle_exceptions(e)
# passed all error conditions
portfolio_member_permission.delete()
@ -159,6 +174,18 @@ class PortfolioMemberDeleteView(PortfolioMemberPermission, View):
messages.success(request, success_message)
return redirect(reverse("members"))
def _handle_exceptions(self, exception):
"""Handle exceptions raised during the process."""
if isinstance(exception, MissingEmailError):
messages.warning(self.request, "Could not send email notification to existing organization admins.")
logger.warning(
f"Could not send email notification to existing organization admins.",
exc_info=True,
)
else:
logger.warning("Could not send email notification to existing organization admins.", exc_info=True)
messages.warning(self.request, "Could not send email notification to existing organization admins.")
class PortfolioMemberEditView(PortfolioMemberEditPermissionView, View):
@ -182,7 +209,6 @@ class PortfolioMemberEditView(PortfolioMemberEditPermissionView, View):
def post(self, request, pk):
portfolio_permission = get_object_or_404(UserPortfolioPermission, pk=pk)
user_initially_is_admin = UserPortfolioRoleChoices.ORGANIZATION_ADMIN in portfolio_permission.roles
user = portfolio_permission.user
form = self.form_class(request.POST, instance=portfolio_permission)
if form.is_valid():
@ -415,6 +441,21 @@ class PortfolioInvitedMemberDeleteView(PortfolioMemberPermission, View):
"""
portfolio_invitation = get_object_or_404(PortfolioInvitation, pk=pk)
# if invitation being removed is an admin
if UserPortfolioRoleChoices.ORGANIZATION_ADMIN in portfolio_invitation.roles:
try:
# attempt to send notification emails of the removal to portfolio admins
if not send_portfolio_admin_removal_emails(
email=portfolio_invitation.email,
requestor=request.user,
portfolio=portfolio_invitation.portfolio
):
messages.warning(
self.request, "Could not send email notification to existing organization admins."
)
except Exception as e:
self._handle_exceptions(e)
portfolio_invitation.delete()
success_message = f"You've removed {portfolio_invitation.email} from the organization."
@ -425,6 +466,18 @@ class PortfolioInvitedMemberDeleteView(PortfolioMemberPermission, View):
messages.success(request, success_message)
return redirect(reverse("members"))
def _handle_exceptions(self, exception):
"""Handle exceptions raised during the process."""
if isinstance(exception, MissingEmailError):
messages.warning(self.request, "Could not send email notification to existing organization admins.")
logger.warning(
f"Could not send email notification to existing organization admins.",
exc_info=True,
)
else:
logger.warning("Could not send email notification to existing organization admins.", exc_info=True)
messages.warning(self.request, "Could not send email notification to existing organization admins.")
class PortfolioInvitedMemberEditView(PortfolioMemberEditPermissionView, View):