Add logic in admin to catch no reason error, add JS to manage UI

This commit is contained in:
Rachid Mrad 2024-02-16 15:16:42 -05:00
parent 1530d77ad8
commit ba53e74e26
No known key found for this signature in database
4 changed files with 60 additions and 3 deletions

View file

@ -793,7 +793,7 @@ class DomainApplicationAdmin(ListHeaderAdmin):
# Detail view
form = DomainApplicationAdminForm
fieldsets = [
(None, {"fields": ["status", "investigator", "creator", "approved_domain", "notes"]}),
(None, {"fields": ["status", "rejection_reason", "investigator", "creator", "approved_domain", "notes"]}),
(
"Type of organization",
{
@ -901,6 +901,24 @@ class DomainApplicationAdmin(ListHeaderAdmin):
"This action is not permitted. The domain is already active.",
)
elif (
obj
and obj.status == models.DomainApplication.ApplicationStatus.REJECTED
and not obj.rejection_reason
):
# This condition should never be triggered.
# The opposite of this condition is acceptable (rejected -> other status and rejection_reason)
# because we clean up the rejection reason in the transition in the model.
# Clear the success message
messages.set_level(request, messages.ERROR)
messages.error(
request,
"A rejection reason is required.",
)
else:
if obj.status != original_obj.status:
status_method_mapping = {

View file

@ -312,3 +312,27 @@ function enableRelatedWidgetButtons(changeLink, deleteLink, viewLink, elementPk,
}
})();
/** An IIFE for admin in DjangoAdmin to listen to changes on the domain request
* status select amd to show/hide the rejection reason
*/
(function (){
// Get the rejection reason form row
let rejectionReasonFormGroup = document.querySelector('.field-rejection_reason')
if (rejectionReasonFormGroup) {
// Get the status select
let statusSelect = document.getElementById('id_status')
// If status is rejected, hide the rejection reason on load
if (statusSelect.value != 'rejected')
rejectionReasonFormGroup.style.display = 'none';
// Listen to status changes and toggle rejection reason
statusSelect.addEventListener('change', function() {
rejectionReasonFormGroup.style.display = statusSelect.value !== 'rejected' ? 'none' : 'block';
});
}
})();

View file

@ -26,7 +26,7 @@ class Migration(migrations.Migration):
"Research could not corroborate legitimacy of contacts or organization",
),
("organization_eligibility", "Organization isn't eligible for a .gov"),
("naming_requirements", "naming requirements not met"),
("naming_requirements", "Naming requirements not met"),
],
null=True,
),

View file

@ -356,7 +356,7 @@ class DomainApplication(TimeStampedModel):
SECOND_DOMAIN_REASONING = "second_domain_reasoning", "Organization already has a domain and does not provide sufficient reasoning for a second domain"
CONTACTS_OR_ORGANIZATION_LEGITIMACY = "contacts_or_organization_legitimacy", "Research could not corroborate legitimacy of contacts or organization"
ORGANIZATION_ELIGIBILITY = "organization_eligibility", "Organization isn't eligible for a .gov"
NAMING_REQUIREMENTS = "naming_requirements", "naming requirements not met"
NAMING_REQUIREMENTS = "naming_requirements", "Naming requirements not met"
# #### Internal fields about the application #####
status = FSMField(
@ -694,12 +694,17 @@ class DomainApplication(TimeStampedModel):
This action is logged.
This action cleans up the rejection status if moving away from rejected.
As side effects this will delete the domain and domain_information
(will cascade) when they exist."""
if self.status == self.ApplicationStatus.APPROVED:
self.delete_and_clean_up_domain("in_review")
if self.status == self.ApplicationStatus.REJECTED:
self.rejection_reason = None
literal = DomainApplication.ApplicationStatus.IN_REVIEW
# Check if the tuple exists, then grab its value
in_review = literal if literal is not None else "In Review"
@ -721,12 +726,17 @@ class DomainApplication(TimeStampedModel):
This action is logged.
This action cleans up the rejection status if moving away from rejected.
As side effects this will delete the domain and domain_information
(will cascade) when they exist."""
if self.status == self.ApplicationStatus.APPROVED:
self.delete_and_clean_up_domain("reject_with_prejudice")
if self.status == self.ApplicationStatus.REJECTED:
self.rejection_reason = None
literal = DomainApplication.ApplicationStatus.ACTION_NEEDED
# Check if the tuple is setup correctly, then grab its value
action_needed = literal if literal is not None else "Action Needed"
@ -745,6 +755,8 @@ class DomainApplication(TimeStampedModel):
def approve(self, send_email=True):
"""Approve an application that has been submitted.
This action cleans up the rejection status if moving away from rejected.
This has substantial side-effects because it creates another database
object for the approved Domain and makes the user who created the
application into an admin on that domain. It also triggers an email
@ -767,6 +779,9 @@ class DomainApplication(TimeStampedModel):
user=self.creator, domain=created_domain, role=UserDomainRole.Roles.MANAGER
)
if self.status == self.ApplicationStatus.REJECTED:
self.rejection_reason = None
self._send_status_update_email(
"application approved",
"emails/status_change_approved.txt",