mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-05-17 18:09:25 +02:00
Refactor
This commit is contained in:
parent
f9e60ac237
commit
61b1ceeb9c
16 changed files with 435 additions and 138 deletions
|
@ -21,7 +21,12 @@ from epplibwrapper.errors import ErrorCode, RegistryError
|
|||
from registrar.models.user_domain_role import UserDomainRole
|
||||
from waffle.admin import FlagAdmin
|
||||
from waffle.models import Sample, Switch
|
||||
from registrar.utility.admin_helpers import get_all_action_needed_reason_emails, get_action_needed_reason_default_email
|
||||
from registrar.utility.admin_helpers import (
|
||||
get_all_action_needed_reason_emails,
|
||||
get_action_needed_reason_default_email,
|
||||
get_all_rejection_reason_emails,
|
||||
get_rejection_reason_default_email,
|
||||
)
|
||||
from registrar.models import Contact, Domain, DomainRequest, DraftDomain, User, Website, SeniorOfficial
|
||||
from registrar.utility.constants import BranchChoices
|
||||
from registrar.utility.errors import FSMDomainRequestError, FSMErrorCodes
|
||||
|
@ -234,6 +239,7 @@ class DomainRequestAdminForm(forms.ModelForm):
|
|||
}
|
||||
labels = {
|
||||
"action_needed_reason_email": "Email",
|
||||
"rejection_reason_email": "Email",
|
||||
}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
@ -1755,6 +1761,7 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin):
|
|||
"status_history",
|
||||
"status",
|
||||
"rejection_reason",
|
||||
"rejection_reason_email",
|
||||
"action_needed_reason",
|
||||
"action_needed_reason_email",
|
||||
"investigator",
|
||||
|
@ -1938,24 +1945,16 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin):
|
|||
original_obj = models.DomainRequest.objects.get(pk=obj.pk)
|
||||
|
||||
# == Handle action_needed_reason == #
|
||||
action_needed_reason_changed = obj.action_needed_reason != original_obj.action_needed_reason
|
||||
if action_needed_reason_changed:
|
||||
obj = self._handle_action_needed_reason(request, obj, original_obj)
|
||||
|
||||
reason_changed = obj.action_needed_reason != original_obj.action_needed_reason
|
||||
if reason_changed:
|
||||
# Track the fact that we sent out an email
|
||||
request.session["action_needed_email_sent"] = True
|
||||
|
||||
# Set the action_needed_reason_email to the default if nothing exists.
|
||||
# Since this check occurs after save, if the user enters a value then we won't update.
|
||||
|
||||
default_email = get_action_needed_reason_default_email(request, obj, obj.action_needed_reason)
|
||||
if obj.action_needed_reason_email:
|
||||
emails = get_all_action_needed_reason_emails(request, obj)
|
||||
is_custom_email = obj.action_needed_reason_email not in emails.values()
|
||||
if not is_custom_email:
|
||||
obj.action_needed_reason_email = default_email
|
||||
else:
|
||||
obj.action_needed_reason_email = default_email
|
||||
# == Handle rejection_reason == #
|
||||
rejection_reason_changed = obj.rejection_reason != original_obj.rejection_reason
|
||||
if rejection_reason_changed:
|
||||
obj = self._handle_rejection_reason(request, obj, original_obj)
|
||||
|
||||
# == Handle allowed emails == #
|
||||
if obj.status in DomainRequest.get_statuses_that_send_emails() and not settings.IS_PRODUCTION:
|
||||
self._check_for_valid_email(request, obj)
|
||||
|
||||
|
@ -1971,6 +1970,40 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin):
|
|||
if should_save:
|
||||
return super().save_model(request, obj, form, change)
|
||||
|
||||
def _handle_action_needed_reason(self, request, obj, original_obj):
|
||||
# Track the fact that we sent out an email
|
||||
request.session["action_needed_email_sent"] = True
|
||||
|
||||
# Set the action_needed_reason_email to the default if nothing exists.
|
||||
# Since this check occurs after save, if the user enters a value then we won't update.
|
||||
|
||||
default_email = get_action_needed_reason_default_email(obj, obj.action_needed_reason)
|
||||
if obj.action_needed_reason_email:
|
||||
emails = get_all_action_needed_reason_emails(obj)
|
||||
is_custom_email = obj.action_needed_reason_email not in emails.values()
|
||||
if not is_custom_email:
|
||||
obj.action_needed_reason_email = default_email
|
||||
else:
|
||||
obj.action_needed_reason_email = default_email
|
||||
return obj
|
||||
|
||||
def _handle_rejection_reason(self, request, obj, original_obj):
|
||||
# Track the fact that we sent out an email
|
||||
request.session["rejection_reason_email_sent"] = True
|
||||
|
||||
# Set the rejection_reason_email to the default if nothing exists.
|
||||
# Since this check occurs after save, if the user enters a value then we won't update.
|
||||
|
||||
default_email = get_rejection_reason_default_email(obj, obj.action_needed_reason)
|
||||
if obj.rejection_reason_email:
|
||||
emails = get_all_rejection_reason_emails(obj)
|
||||
is_custom_email = obj.rejection_reason_email not in emails.values()
|
||||
if not is_custom_email:
|
||||
obj.rejection_reason_email = default_email
|
||||
else:
|
||||
obj.rejection_reason_email = default_email
|
||||
return obj
|
||||
|
||||
def _check_for_valid_email(self, request, obj):
|
||||
"""Certain emails are whitelisted in non-production environments,
|
||||
so we should display that information using this function.
|
||||
|
|
|
@ -500,83 +500,41 @@ function initializeWidgetOnList(list, parentId) {
|
|||
}
|
||||
})();
|
||||
|
||||
class CustomizableEmailBase {
|
||||
constructor(dropdown, textarea, textareaPlaceholder, directEditButton, modalTrigger, modalConfirm, formLabel, lastSentEmailContent, apiUrl) {
|
||||
this.dropdown = dropdown;
|
||||
this.textarea = textarea;
|
||||
this.textareaPlaceholder = textareaPlaceholder;
|
||||
this.directEditButton = directEditButton;
|
||||
this.modalTrigger = modalTrigger;
|
||||
this.modalConfirm = modalConfirm;
|
||||
this.formLabel = formLabel;
|
||||
this.lastSentEmailContent = lastSentEmailContent;
|
||||
this.apiUrl = apiUrl;
|
||||
|
||||
/** An IIFE that hooks to the show/hide button underneath action needed reason.
|
||||
* This shows the auto generated email on action needed reason.
|
||||
*/
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const dropdown = document.getElementById("id_action_needed_reason");
|
||||
const textarea = document.getElementById("id_action_needed_reason_email")
|
||||
const domainRequestId = dropdown ? document.getElementById("domain_request_id").value : null
|
||||
const textareaPlaceholder = document.querySelector(".field-action_needed_reason_email__placeholder");
|
||||
const directEditButton = document.querySelector('.field-action_needed_reason_email__edit');
|
||||
const modalTrigger = document.querySelector('.field-action_needed_reason_email__modal-trigger');
|
||||
const modalConfirm = document.getElementById('confirm-edit-email');
|
||||
const formLabel = document.querySelector('label[for="id_action_needed_reason_email"]');
|
||||
let lastSentEmailContent = document.getElementById("last-sent-email-content");
|
||||
const initialDropdownValue = dropdown ? dropdown.value : null;
|
||||
const initialEmailValue = textarea.value;
|
||||
this.domainRequestId = this.dropdown ? document.getElementById("domain_request_id").value : null
|
||||
this.initialDropdownValue = this.dropdown ? this.dropdown.value : null;
|
||||
this.initialEmailValue = this.textarea ? this.textarea.value : null;
|
||||
|
||||
// We will use the const to control the modal
|
||||
let isEmailAlreadySentConst = lastSentEmailContent.value.replace(/\s+/g, '') === textarea.value.replace(/\s+/g, '');
|
||||
// We will use the function to control the label and help
|
||||
function isEmailAlreadySent() {
|
||||
return lastSentEmailContent.value.replace(/\s+/g, '') === textarea.value.replace(/\s+/g, '');
|
||||
}
|
||||
|
||||
if (!dropdown || !textarea || !domainRequestId || !formLabel || !modalConfirm) return;
|
||||
const apiUrl = document.getElementById("get-action-needed-email-for-user-json").value;
|
||||
|
||||
function updateUserInterface(reason) {
|
||||
if (!reason) {
|
||||
// No reason selected, we will set the label to "Email", show the "Make a selection" placeholder, hide the trigger, textarea, hide the help text
|
||||
formLabel.innerHTML = "Email:";
|
||||
textareaPlaceholder.innerHTML = "Select an action needed reason to see email";
|
||||
showElement(textareaPlaceholder);
|
||||
hideElement(directEditButton);
|
||||
hideElement(modalTrigger);
|
||||
hideElement(textarea);
|
||||
} else if (reason === 'other') {
|
||||
// 'Other' selected, we will set the label to "Email", show the "No email will be sent" placeholder, hide the trigger, textarea, hide the help text
|
||||
formLabel.innerHTML = "Email:";
|
||||
textareaPlaceholder.innerHTML = "No email will be sent";
|
||||
showElement(textareaPlaceholder);
|
||||
hideElement(directEditButton);
|
||||
hideElement(modalTrigger);
|
||||
hideElement(textarea);
|
||||
} else {
|
||||
// A triggering selection is selected, all hands on board:
|
||||
textarea.setAttribute('readonly', true);
|
||||
showElement(textarea);
|
||||
hideElement(textareaPlaceholder);
|
||||
|
||||
if (isEmailAlreadySentConst) {
|
||||
hideElement(directEditButton);
|
||||
showElement(modalTrigger);
|
||||
} else {
|
||||
showElement(directEditButton);
|
||||
hideElement(modalTrigger);
|
||||
}
|
||||
if (isEmailAlreadySent()) {
|
||||
formLabel.innerHTML = "Email sent to creator:";
|
||||
} else {
|
||||
formLabel.innerHTML = "Email:";
|
||||
this.isEmailAlreadySentConst;
|
||||
if (lastSentEmailContent && textarea) {
|
||||
this.isEmailAlreadySentConst = lastSentEmailContent.value.replace(/\s+/g, '') === textarea.value.replace(/\s+/g, '');
|
||||
}
|
||||
}
|
||||
|
||||
initializeDropdown(errorMessage) {
|
||||
this.dropdown.addEventListener("change", () => {
|
||||
console.log(this.dropdown)
|
||||
let reason = this.dropdown.value;
|
||||
if (this.initialDropdownValue !== this.dropdown.value || this.initialEmailValue !== this.textarea.value) {
|
||||
let searchParams = new URLSearchParams(
|
||||
{
|
||||
"reason": reason,
|
||||
"domain_request_id": this.domainRequestId,
|
||||
}
|
||||
|
||||
// Initialize UI
|
||||
updateUserInterface(dropdown.value);
|
||||
|
||||
dropdown.addEventListener("change", function() {
|
||||
const reason = dropdown.value;
|
||||
// Update the UI
|
||||
updateUserInterface(reason);
|
||||
if (reason && reason !== "other") {
|
||||
// If it's not the initial value
|
||||
if (initialDropdownValue !== dropdown.value || initialEmailValue !== textarea.value) {
|
||||
);
|
||||
// Replace the email content
|
||||
fetch(`${apiUrl}?reason=${reason}&domain_request_id=${domainRequestId}`)
|
||||
fetch(`${this.apiUrl}?${searchParams.toString()}`)
|
||||
.then(response => {
|
||||
return response.json().then(data => data);
|
||||
})
|
||||
|
@ -584,30 +542,174 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||
if (data.error) {
|
||||
console.error("Error in AJAX call: " + data.error);
|
||||
}else {
|
||||
textarea.value = data.action_needed_email;
|
||||
this.textarea.value = data.action_needed_email;
|
||||
}
|
||||
updateUserInterface(reason);
|
||||
this.updateUserInterface(reason);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error("Error action needed email: ", error)
|
||||
console.error(errorMessage, error)
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
initializeModalConfirm() {
|
||||
this.modalConfirm.addEventListener("click", () => {
|
||||
this.textarea.removeAttribute('readonly');
|
||||
this.textarea.focus();
|
||||
hideElement(this.directEditButton);
|
||||
hideElement(this.modalTrigger);
|
||||
});
|
||||
}
|
||||
|
||||
initializeDirectEditButton() {
|
||||
this.directEditButton.addEventListener("click", () => {
|
||||
this.textarea.removeAttribute('readonly');
|
||||
this.textarea.focus();
|
||||
hideElement(this.directEditButton);
|
||||
hideElement(this.modalTrigger);
|
||||
});
|
||||
}
|
||||
|
||||
isEmailAlreadySent() {
|
||||
return this.lastSentEmailContent.value.replace(/\s+/g, '') === this.textarea.value.replace(/\s+/g, '');
|
||||
}
|
||||
|
||||
updateUserInterface(reason) {
|
||||
if (!reason) {
|
||||
// No reason selected, we will set the label to "Email", show the "Make a selection" placeholder, hide the trigger, textarea, hide the help text
|
||||
this.showPlaceholder("Email:", "Select an action needed reason to see email");
|
||||
} else if (reason === 'other') {
|
||||
// 'Other' selected, we will set the label to "Email", show the "No email will be sent" placeholder, hide the trigger, textarea, hide the help text
|
||||
this.showPlaceholder("Email:", "No email will be sent");
|
||||
} else {
|
||||
// A triggering selection is selected, all hands on board:
|
||||
this.textarea.setAttribute('readonly', true);
|
||||
showElement(this.textarea);
|
||||
hideElement(this.textareaPlaceholder);
|
||||
|
||||
if (this.isEmailAlreadySentConst) {
|
||||
hideElement(this.directEditButton);
|
||||
showElement(this.modalTrigger);
|
||||
} else {
|
||||
showElement(this.directEditButton);
|
||||
hideElement(this.modalTrigger);
|
||||
}
|
||||
|
||||
if (this.isEmailAlreadySent()) {
|
||||
this.formLabel.innerHTML = "Email sent to creator:";
|
||||
} else {
|
||||
this.formLabel.innerHTML = "Email:";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
showPlaceholder(formLabelText, placeholderText) {
|
||||
this.formLabel.innerHTML = formLabelText;
|
||||
this.textareaPlaceholder.innerHTML = placeholderText;
|
||||
showElement(this.textareaPlaceholder);
|
||||
hideElement(this.directEditButton);
|
||||
hideElement(this.modalTrigger);
|
||||
hideElement(this.textarea);
|
||||
}
|
||||
}
|
||||
|
||||
modalConfirm.addEventListener("click", () => {
|
||||
textarea.removeAttribute('readonly');
|
||||
textarea.focus();
|
||||
hideElement(directEditButton);
|
||||
hideElement(modalTrigger);
|
||||
});
|
||||
directEditButton.addEventListener("click", () => {
|
||||
textarea.removeAttribute('readonly');
|
||||
textarea.focus();
|
||||
hideElement(directEditButton);
|
||||
hideElement(modalTrigger);
|
||||
});
|
||||
|
||||
|
||||
class customActionNeededEmail extends CustomizableEmailBase {
|
||||
constructor() {
|
||||
const dropdown = document.getElementById("id_action_needed_reason");
|
||||
const textarea = document.getElementById("id_action_needed_reason_email")
|
||||
const textareaPlaceholder = document.querySelector(".field-action_needed_reason_email__placeholder");
|
||||
const directEditButton = document.querySelector('.field-action_needed_reason_email__edit');
|
||||
const modalTrigger = document.querySelector('.field-action_needed_reason_email__modal-trigger');
|
||||
const modalConfirm = document.getElementById('confirm-edit-email');
|
||||
const formLabel = document.querySelector('label[for="id_action_needed_reason_email"]');
|
||||
const lastSentEmailContent = document.getElementById("last-sent-email-content");
|
||||
|
||||
let apiContainer = document.getElementById("get-action-needed-email-for-user-json")
|
||||
const apiUrl = apiContainer ? apiContainer.value : null;
|
||||
super(
|
||||
dropdown,
|
||||
textarea,
|
||||
textareaPlaceholder,
|
||||
directEditButton,
|
||||
modalTrigger,
|
||||
modalConfirm,
|
||||
formLabel,
|
||||
lastSentEmailContent,
|
||||
apiUrl
|
||||
);
|
||||
}
|
||||
|
||||
loadActionNeededEmail() {
|
||||
this.updateUserInterface(this.dropdown.value);
|
||||
this.initializeDropdown("Error when attempting to grab action needed email: ")
|
||||
this.initializeModalConfirm()
|
||||
this.initializeDirectEditButton()
|
||||
}
|
||||
}
|
||||
|
||||
/** An IIFE that hooks to the show/hide button underneath action needed reason.
|
||||
* This shows the auto generated email on action needed reason.
|
||||
*/
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const customEmail = new customActionNeededEmail();
|
||||
if (!customEmail.dropdown || !customEmail.textarea || !customEmail.domainRequestId || !customEmail.formLabel || !customEmail.modalConfirm){
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize UI
|
||||
customEmail.loadActionNeededEmail()
|
||||
});
|
||||
|
||||
|
||||
class customRejectedEmail extends CustomizableEmailBase {
|
||||
constructor() {
|
||||
const dropdown = document.getElementById("id_rejection_reason");
|
||||
const textarea = document.getElementById("id_rejection_reason_email")
|
||||
const textareaPlaceholder = document.querySelector(".field-rejection_reason_email__placeholder");
|
||||
const directEditButton = document.querySelector('.field-rejection_reason_email__edit');
|
||||
const modalTrigger = document.querySelector('.field-rejection_reason_email__modal-trigger');
|
||||
const modalConfirm = document.getElementById('confirm-edit-email');
|
||||
const formLabel = document.querySelector('label[for="id_rejection_reason_email"]');
|
||||
const lastSentEmailContent = document.getElementById("last-sent-email-content");
|
||||
|
||||
let apiContainer = document.getElementById("get-rejection-reason-email-for-user-json")
|
||||
const apiUrl = apiContainer ? apiContainer.value : null;
|
||||
super(
|
||||
dropdown,
|
||||
textarea,
|
||||
textareaPlaceholder,
|
||||
directEditButton,
|
||||
modalTrigger,
|
||||
modalConfirm,
|
||||
formLabel,
|
||||
lastSentEmailContent,
|
||||
apiUrl
|
||||
);
|
||||
}
|
||||
|
||||
loadRejectedEmail() {
|
||||
this.updateUserInterface(this.dropdown.value);
|
||||
this.initializeDropdown("Error when attempting to grab rejected email: ")
|
||||
this.initializeModalConfirm()
|
||||
this.initializeDirectEditButton()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** An IIFE that hooks to the show/hide button underneath rejected reason.
|
||||
* This shows the auto generated email on action needed reason.
|
||||
*/
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const customEmail = new customRejectedEmail();
|
||||
if (!customEmail.dropdown || !customEmail.textarea || !customEmail.domainRequestId || !customEmail.formLabel || !customEmail.modalConfirm){
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize UI
|
||||
customEmail.loadRejectedEmail()
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -300,6 +300,11 @@ class DomainRequest(TimeStampedModel):
|
|||
blank=True,
|
||||
)
|
||||
|
||||
rejection_reason_email = models.TextField(
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
|
||||
action_needed_reason = models.TextField(
|
||||
choices=ActionNeededReasons.choices,
|
||||
null=True,
|
||||
|
@ -798,6 +803,21 @@ class DomainRequest(TimeStampedModel):
|
|||
except EmailSendingError:
|
||||
logger.warning("Failed to send confirmation email", exc_info=True)
|
||||
|
||||
def _send_custom_status_update_email(self, email_content):
|
||||
"""Wrapper for `_send_status_update_email` that bcc's help@get.gov
|
||||
and sends an email equivalent to the 'email_content' variable."""
|
||||
if settings.IS_PRODUCTION:
|
||||
bcc_address = settings.DEFAULT_FROM_EMAIL
|
||||
|
||||
self._send_status_update_email(
|
||||
new_status="action needed",
|
||||
email_template=f"emails/includes/custom_email.txt",
|
||||
email_template_subject=f"emails/status_change_subject.txt",
|
||||
bcc_address=bcc_address,
|
||||
custom_email_content=email_content,
|
||||
wrap_email=True,
|
||||
)
|
||||
|
||||
def investigator_exists_and_is_staff(self):
|
||||
"""Checks if the current investigator is in a valid state for a state transition"""
|
||||
is_valid = True
|
||||
|
@ -901,7 +921,7 @@ class DomainRequest(TimeStampedModel):
|
|||
target=DomainRequestStatus.ACTION_NEEDED,
|
||||
conditions=[domain_is_not_active, investigator_exists_and_is_staff],
|
||||
)
|
||||
def action_needed(self, send_email=True):
|
||||
def action_needed(self):
|
||||
"""Send back an domain request that is under investigation or rejected.
|
||||
|
||||
This action is logged.
|
||||
|
@ -924,27 +944,7 @@ class DomainRequest(TimeStampedModel):
|
|||
# Send out an email if an action needed reason exists
|
||||
if self.action_needed_reason and self.action_needed_reason != self.ActionNeededReasons.OTHER:
|
||||
email_content = self.action_needed_reason_email
|
||||
self._send_action_needed_reason_email(send_email, email_content)
|
||||
|
||||
def _send_action_needed_reason_email(self, send_email=True, email_content=None):
|
||||
"""Sends out an automatic email for each valid action needed reason provided"""
|
||||
|
||||
email_template_name = "custom_email.txt"
|
||||
email_template_subject_name = f"{self.action_needed_reason}_subject.txt"
|
||||
|
||||
bcc_address = ""
|
||||
if settings.IS_PRODUCTION:
|
||||
bcc_address = settings.DEFAULT_FROM_EMAIL
|
||||
|
||||
self._send_status_update_email(
|
||||
new_status="action needed",
|
||||
email_template=f"emails/action_needed_reasons/{email_template_name}",
|
||||
email_template_subject=f"emails/action_needed_reasons/{email_template_subject_name}",
|
||||
send_email=send_email,
|
||||
bcc_address=bcc_address,
|
||||
custom_email_content=email_content,
|
||||
wrap_email=True,
|
||||
)
|
||||
self._send_custom_status_update_email(email_content)
|
||||
|
||||
@transition(
|
||||
field="status",
|
||||
|
@ -1051,6 +1051,11 @@ class DomainRequest(TimeStampedModel):
|
|||
"emails/status_change_rejected_subject.txt",
|
||||
)
|
||||
|
||||
# Send out an email if a rejection reason exists
|
||||
if self.rejection_reason:
|
||||
email_content = self.rejection_reason_email
|
||||
self._send_custom_status_update_email(email_content)
|
||||
|
||||
@transition(
|
||||
field="status",
|
||||
source=[
|
||||
|
|
10
src/registrar/templates/emails/includes/email_footer.txt
Normal file
10
src/registrar/templates/emails/includes/email_footer.txt
Normal file
|
@ -0,0 +1,10 @@
|
|||
THANK YOU
|
||||
.Gov helps the public identify official, trusted information. Thank you for requesting a .gov domain.
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
||||
The .gov team
|
||||
Contact us: <https://get.gov/contact/>
|
||||
Learn about .gov <https://get.gov>
|
||||
|
||||
The .gov registry is a part of the Cybersecurity and Infrastructure Security Agency (CISA) <https://cisa.gov/>
|
|
@ -0,0 +1,8 @@
|
|||
Hi, {{ recipient.first_name }}.
|
||||
|
||||
Your .gov domain request has been rejected.
|
||||
|
||||
DOMAIN REQUESTED: {{ domain_request.requested_domain.name }}
|
||||
REQUEST RECEIVED ON: {{ domain_request.last_submitted_date|date }}
|
||||
STATUS: Rejected
|
||||
----------------------------------------------------------------
|
|
@ -0,0 +1,8 @@
|
|||
{% autoescape off %}{# In a text file, we don't want to have HTML entities escaped #}
|
||||
{% include "emails/includes/status_change_rejected_header.html" %}
|
||||
REJECTION REASON
|
||||
Your domain request was rejected because we could not verify the organizational
|
||||
contacts you provided. If you have questions or comments, reply to this email.
|
||||
|
||||
{% include "emails/includes/email_footer.html" %}
|
||||
{% endautoescape %}
|
|
@ -0,0 +1,15 @@
|
|||
{% autoescape off %}{# In a text file, we don't want to have HTML entities escaped #}
|
||||
{% include "emails/includes/status_change_rejected_header.html" %}
|
||||
REJECTION REASON
|
||||
Your domain request was rejected because it does not meet our naming requirements.
|
||||
Domains should uniquely identify a government organization and be clear to the
|
||||
general public. Learn more about naming requirements for your type of organization
|
||||
<https://get.gov/domains/choosing/>.
|
||||
|
||||
|
||||
YOU CAN SUBMIT A NEW REQUEST
|
||||
We encourage you to request a domain that meets our requirements. If you have
|
||||
questions or want to discuss potential domain names, reply to this email.
|
||||
|
||||
{% include "emails/includes/email_footer.html" %}
|
||||
{% endautoescape %}
|
|
@ -0,0 +1,15 @@
|
|||
{% autoescape off %}{# In a text file, we don't want to have HTML entities escaped #}
|
||||
{% include "emails/includes/status_change_rejected_header.html" %}
|
||||
REJECTION REASON
|
||||
Your domain request was rejected because {{ domain_request.organization_name }} has a .gov domain. Our
|
||||
practice is to approve one domain per online service per government organization. We
|
||||
evaluate additional requests on a case-by-case basis. You did not provide sufficient
|
||||
justification for an additional domain.
|
||||
|
||||
Read more about our practice of approving one domain per online service
|
||||
<https://get.gov/domains/before/#one-domain-per-service>.
|
||||
|
||||
If you have questions or comments, reply to this email.
|
||||
|
||||
{% include "emails/includes/email_footer.html" %}
|
||||
{% endautoescape %}
|
|
@ -0,0 +1,14 @@
|
|||
{% autoescape off %}{# In a text file, we don't want to have HTML entities escaped #}
|
||||
{% include "emails/includes/status_change_rejected_header.html" %}
|
||||
REJECTION REASON
|
||||
Your domain request was rejected because we determined that {{ domain_request.organization_name }} is not
|
||||
eligible for a .gov domain. .Gov domains are only available to official U.S.-based
|
||||
government organizations.
|
||||
|
||||
Learn more about eligibility for .gov domains
|
||||
<https://get.gov/domains/eligibility/>.
|
||||
|
||||
If you have questions or comments, reply to this email.
|
||||
|
||||
{% include "emails/includes/email_footer.html" %}
|
||||
{% endautoescape %}
|
15
src/registrar/templates/emails/rejection_reasons/other.txt
Normal file
15
src/registrar/templates/emails/rejection_reasons/other.txt
Normal file
|
@ -0,0 +1,15 @@
|
|||
{% autoescape off %}{# In a text file, we don't want to have HTML entities escaped #}
|
||||
{% include "emails/includes/status_change_rejected_header.html" %}
|
||||
YOU CAN SUBMIT A NEW REQUEST
|
||||
If your organization is eligible for a .gov domain and you meet our other requirements, you can submit a new request.
|
||||
|
||||
Learn more about:
|
||||
- Eligibility for a .gov domain <https://get.gov/domains/eligibility>
|
||||
- Choosing a .gov domain name <https://get.gov/domains/choosing>
|
||||
|
||||
|
||||
NEED ASSISTANCE?
|
||||
If you have questions about this domain request or need help choosing a new domain name, reply to this email.
|
||||
|
||||
{% include "emails/includes/email_footer.html" %}
|
||||
{% endautoescape %}
|
|
@ -0,0 +1,15 @@
|
|||
{% autoescape off %}{# In a text file, we don't want to have HTML entities escaped #}
|
||||
{% include "emails/includes/status_change_rejected_header.html" %}
|
||||
REJECTION REASON
|
||||
Your domain request was rejected because the purpose you provided did not meet our
|
||||
requirements. You didn’t provide enough information about how you intend to use the
|
||||
domain.
|
||||
|
||||
Learn more about:
|
||||
- Eligibility for a .gov domain <https://get.gov/domains/eligibility>
|
||||
- What you can and can’t do with .gov domains <https://get.gov/domains/requirements/>
|
||||
|
||||
If you have questions or comments, reply to this email.
|
||||
|
||||
{% include "emails/includes/email_footer.html" %}
|
||||
{% endautoescape %}
|
|
@ -0,0 +1,14 @@
|
|||
{% autoescape off %}{# In a text file, we don't want to have HTML entities escaped #}
|
||||
{% include "emails/includes/status_change_rejected_header.html" %}
|
||||
REJECTION REASON
|
||||
Your domain request was rejected because we don’t believe you’re eligible to request a
|
||||
.gov domain on behalf of {{ domain_request.organization_name }}. You must be a government employee, or be
|
||||
working on behalf of a government organization, to request a .gov domain.
|
||||
|
||||
|
||||
DEMONSTRATE ELIGIBILITY
|
||||
If you can provide more information that demonstrates your eligibility, or you want to
|
||||
discuss further, reply to this email.
|
||||
|
||||
{% include "emails/includes/email_footer.html" %}
|
||||
{% endautoescape %}
|
|
@ -2,23 +2,66 @@ from registrar.models.domain_request import DomainRequest
|
|||
from django.template.loader import get_template
|
||||
|
||||
|
||||
def get_all_action_needed_reason_emails(request, domain_request):
|
||||
def get_all_action_needed_reason_emails(domain_request):
|
||||
"""Returns a dictionary of every action needed reason and its associated email
|
||||
for this particular domain request."""
|
||||
|
||||
emails = {}
|
||||
for action_needed_reason in domain_request.ActionNeededReasons:
|
||||
# Map the action_needed_reason to its default email
|
||||
emails[action_needed_reason.value] = get_action_needed_reason_default_email(
|
||||
request, domain_request, action_needed_reason.value
|
||||
return _get_all_default_emails(
|
||||
reasons=DomainRequest.ActionNeededReasons,
|
||||
# Where the emails are stored. This assumes that it contains a list of .txt files with the reason.
|
||||
path_root="emails/action_needed_reasons",
|
||||
# What reasons don't send out emails (none is handled automagically)
|
||||
excluded_reasons=[DomainRequest.ActionNeededReasons.OTHER],
|
||||
# Who to send it to, and from what domain request to reference
|
||||
domain_request=domain_request
|
||||
)
|
||||
|
||||
return emails
|
||||
|
||||
|
||||
def get_action_needed_reason_default_email(request, domain_request, action_needed_reason):
|
||||
def get_action_needed_reason_default_email(domain_request, action_needed_reason):
|
||||
"""Returns the default email associated with the given action needed reason"""
|
||||
if not action_needed_reason or action_needed_reason == DomainRequest.ActionNeededReasons.OTHER:
|
||||
return _get_default_email(
|
||||
domain_request,
|
||||
path_root="emails/rejection_reasons",
|
||||
reason=action_needed_reason,
|
||||
excluded_reasons=[DomainRequest.ActionNeededReasons.OTHER]
|
||||
)
|
||||
|
||||
|
||||
def get_all_rejection_reason_emails(domain_request):
|
||||
"""Returns a dictionary of every rejection reason and its associated email
|
||||
for this particular domain request."""
|
||||
return _get_all_default_emails(
|
||||
reasons=DomainRequest.RejectionReasons,
|
||||
# Where the emails are stored. This assumes that it contains a list of .txt files with the reason.
|
||||
path_root="emails/rejection_reasons",
|
||||
# What reasons don't send out emails (none is handled automagically)
|
||||
excluded_reasons=[DomainRequest.RejectionReasons.OTHER],
|
||||
# Who to send it to, and from what domain request to reference
|
||||
domain_request=domain_request
|
||||
)
|
||||
|
||||
|
||||
def get_rejection_reason_default_email(domain_request, action_needed_reason):
|
||||
"""Returns the default email associated with the given rejection reason"""
|
||||
return _get_default_email(
|
||||
domain_request,
|
||||
path_root="emails/rejection_reasons",
|
||||
reason=action_needed_reason,
|
||||
excluded_reasons=[DomainRequest.RejectionReasons.OTHER]
|
||||
)
|
||||
|
||||
def _get_all_default_emails(reasons, path_root, excluded_reasons, domain_request):
|
||||
emails = {}
|
||||
for reason in reasons:
|
||||
# Map the reason to its default email
|
||||
emails[reason.value] = _get_default_email(
|
||||
domain_request, path_root, reason, excluded_reasons
|
||||
)
|
||||
|
||||
def _get_default_email(domain_request, path_root, reason, excluded_reasons=None):
|
||||
if not reason:
|
||||
return None
|
||||
|
||||
if excluded_reasons and reason in excluded_reasons:
|
||||
return None
|
||||
|
||||
recipient = domain_request.creator
|
||||
|
@ -26,7 +69,7 @@ def get_action_needed_reason_default_email(request, domain_request, action_neede
|
|||
context = {"domain_request": domain_request, "recipient": recipient}
|
||||
|
||||
# Get the email body
|
||||
template_path = f"emails/action_needed_reasons/{action_needed_reason}.txt"
|
||||
template_path = f"{path_root}/{reason}.txt"
|
||||
|
||||
email_body_text = get_template(template_path).render(context=context)
|
||||
email_body_text_cleaned = None
|
||||
|
|
|
@ -90,5 +90,5 @@ def get_action_needed_email_for_user_json(request):
|
|||
return JsonResponse({"error": "No domain_request_id specified"}, status=404)
|
||||
|
||||
domain_request = DomainRequest.objects.filter(id=domain_request_id).first()
|
||||
emails = get_all_action_needed_reason_emails(request, domain_request)
|
||||
emails = get_all_action_needed_reason_emails(domain_request)
|
||||
return JsonResponse({"action_needed_email": emails.get(reason)}, status=200)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue