Merge branch 'main' into sspj/domain-model

This commit is contained in:
Seamus Johnston 2022-11-28 11:53:22 -06:00
commit 758c645943
No known key found for this signature in database
GPG key ID: 2F21225985069105
37 changed files with 1339 additions and 232 deletions

View file

@ -1,9 +1,11 @@
"""Forms Wizard for creating a new domain application."""
from __future__ import annotations # allows forward references in annotations
import logging
from django import forms
from django.shortcuts import redirect
from django.shortcuts import render
from django.contrib.auth.mixins import LoginRequiredMixin
@ -15,7 +17,14 @@ from registrar.models import DomainApplication, Domain
logger = logging.getLogger(__name__)
class OrganizationForm(forms.Form):
# Subclass used to remove the default colon suffix from all fields
class RegistrarForm(forms.Form):
def __init__(self, *args, **kwargs):
kwargs.setdefault("label_suffix", "")
super(RegistrarForm, self).__init__(*args, **kwargs)
class OrganizationTypeForm(RegistrarForm):
organization_type = forms.ChoiceField(
required=True,
choices=[
@ -45,49 +54,244 @@ class OrganizationForm(forms.Form):
],
widget=forms.RadioSelect,
)
class OrganizationFederalForm(RegistrarForm):
federal_type = forms.ChoiceField(
required=False,
choices=[
("Executive", "Executive"),
("Judicial", "Judicial"),
("Legislative", "Legislative"),
],
choices=DomainApplication.BRANCH_CHOICES,
widget=forms.RadioSelect,
)
is_election_board = forms.ChoiceField(
class OrganizationElectionForm(RegistrarForm):
is_election_board = forms.BooleanField(
widget=forms.RadioSelect(
choices=[
(True, "Yes"),
(False, "No"),
],
),
required=False,
choices=[
("Yes", "Yes"),
("No", "No"),
],
widget=forms.RadioSelect,
)
class ContactForm(forms.Form):
class OrganizationContactForm(RegistrarForm):
organization_name = forms.CharField(label="Organization Name")
street_address = forms.CharField(label="Street address")
address_line1 = forms.CharField(label="Address line 1")
address_line2 = forms.CharField(
required=False,
label="Address line 2",
)
us_state = forms.ChoiceField(
label="State",
choices=[
("AL", "Alabama"),
("AK", "Alaska"),
("AZ", "Arizona"),
("AR", "Arkansas"),
("CA", "California"),
("CO", "Colorado"),
("CT", "Connecticut"),
("DE", "Delaware"),
("DC", "District of Columbia"),
("FL", "Florida"),
("GA", "Georgia"),
("HI", "Hawaii"),
("ID", "Idaho"),
("IL", "Illinois"),
("IN", "Indiana"),
("IA", "Iowa"),
("KS", "Kansas"),
("KY", "Kentucky"),
("LA", "Louisiana"),
("ME", "Maine"),
("MD", "Maryland"),
("MA", "Massachusetts"),
("MI", "Michigan"),
("MN", "Minnesota"),
("MS", "Mississippi"),
("MO", "Missouri"),
("MT", "Montana"),
("NE", "Nebraska"),
("NV", "Nevada"),
("NH", "New Hampshire"),
("NJ", "New Jersey"),
("NM", "New Mexico"),
("NY", "New York"),
("NC", "North Carolina"),
("ND", "North Dakota"),
("OH", "Ohio"),
("OK", "Oklahoma"),
("OR", "Oregon"),
("PA", "Pennsylvania"),
("RI", "Rhode Island"),
("SC", "South Carolina"),
("SD", "South Dakota"),
("TN", "Tennessee"),
("TX", "Texas"),
("UT", "Utah"),
("VT", "Vermont"),
("VA", "Virginia"),
("WA", "Washington"),
("WV", "West Virginia"),
("WI", "Wisconsin"),
("WY", "Wyoming"),
("AS", "American Samoa"),
("GU", "Guam"),
("MP", "Northern Mariana Islands"),
("PR", "Puerto Rico"),
("VI", "Virgin Islands"),
],
)
zipcode = forms.CharField(label="ZIP code")
class AuthorizingOfficialForm(RegistrarForm):
first_name = forms.CharField(label="First name/given name")
middle_name = forms.CharField(
required=False,
label="Middle name (optional)",
)
last_name = forms.CharField(label="Last name/family name")
title = forms.CharField(label="Title or role in your organization")
email = forms.EmailField(label="Email")
phone = forms.CharField(label="Phone")
class CurrentSitesForm(RegistrarForm):
current_site = forms.CharField(
required=False,
label="Enter your organizations public website, if you have one. For example, "
"www.city.com.",
)
class DotGovDomainForm(RegistrarForm):
dotgov_domain = forms.CharField(label="What .gov domain do you want?")
alternative_domain = forms.CharField(
required=False,
label="Are there other domains youd like if we cant give you your first "
"choice? Entering alternative domains is optional.",
)
class PurposeForm(RegistrarForm):
purpose_field = forms.CharField(label="Purpose", widget=forms.Textarea())
class YourContactForm(RegistrarForm):
first_name = forms.CharField(label="First name/given name")
middle_name = forms.CharField(
required=False,
label="Middle name (optional)",
)
last_name = forms.CharField(label="Last name/family name")
title = forms.CharField(label="Title or role in your organization")
email = forms.EmailField(label="Email")
phone = forms.CharField(label="Phone")
class OtherContactsForm(RegistrarForm):
first_name = forms.CharField(label="First name/given name")
middle_name = forms.CharField(
required=False,
label="Middle name (optional)",
)
last_name = forms.CharField(label="Last name/family name")
title = forms.CharField(label="Title or role in your organization")
email = forms.EmailField(label="Email")
phone = forms.CharField(label="Phone")
class SecurityEmailForm(RegistrarForm):
email = forms.EmailField(
required=False,
label="Security email",
)
class AnythingElseForm(RegistrarForm):
anything_else = forms.CharField(
required=False, label="Anything else we should know", widget=forms.Textarea()
)
class RequirementsForm(RegistrarForm):
agree_check = forms.BooleanField(
label="I read and agree to the .gov domain requirements."
)
# Empty class for the review page which gets included as part of the form, but does not
# have any form fields itself
class ReviewForm(RegistrarForm):
pass
# List of forms in our wizard. Each entry is a tuple of a name and a form
# subclass
FORMS = [
("organization", OrganizationForm),
("contact", ContactForm),
("organization_type", OrganizationTypeForm),
("organization_federal", OrganizationFederalForm),
("organization_election", OrganizationElectionForm),
("organization_contact", OrganizationContactForm),
("authorizing_official", AuthorizingOfficialForm),
("current_sites", CurrentSitesForm),
("dotgov_domain", DotGovDomainForm),
("purpose", PurposeForm),
("your_contact", YourContactForm),
("other_contacts", OtherContactsForm),
("security_email", SecurityEmailForm),
("anything_else", AnythingElseForm),
("requirements", RequirementsForm),
("review", ReviewForm),
]
# Dict to match up the right template with the right step. Keys here must
# match the first elements of the tuples in FORMS
TEMPLATES = {
"organization": "application_organization.html",
"contact": "application_contact.html",
"organization_type": "application_org_type.html",
"organization_federal": "application_org_federal.html",
"organization_election": "application_org_election.html",
"organization_contact": "application_org_contact.html",
"authorizing_official": "application_authorizing_official.html",
"current_sites": "application_current_sites.html",
"dotgov_domain": "application_dotgov_domain.html",
"purpose": "application_purpose.html",
"your_contact": "application_your_contact.html",
"other_contacts": "application_other_contacts.html",
"security_email": "application_security_email.html",
"anything_else": "application_anything_else.html",
"requirements": "application_requirements.html",
"review": "application_review.html",
}
# We need to pass our page titles as context to the templates, indexed
# by the step names
TITLES = {
"organization": "About your organization",
"contact": "Your organization's contact information",
"organization_type": "Type of organization",
"organization_federal": "Type of organization — Federal",
"organization_election": "Type of organization — Election board",
"organization_contact": "Organization name and mailing address",
"authorizing_official": "Authorizing official",
"current_sites": "Organization website",
"dotgov_domain": ".gov domain",
"purpose": "Purpose of your domain",
"your_contact": "Your contact information",
"other_contacts": "Other contacts for your domain",
"security_email": "Security email for public use",
"anything_else": "Anything else we should know?",
"requirements": "Requirements for registration and operation of .gov domains",
"review": "Review and submit your domain request",
}
# We can use a dictionary with step names and callables that return booleans
# to show or hide particular steps based on the state of the process.
WIZARD_CONDITIONS = {
"organization_federal": DomainApplication.show_organization_federal,
"organization_election": DomainApplication.show_organization_election,
}
@ -120,16 +324,26 @@ class ApplicationWizard(LoginRequiredMixin, NamedUrlSessionWizardView):
"""Unpack the form responses onto the model object properties."""
application = DomainApplication.objects.create(creator=self.request.user)
# organization information
organization_data = form_dict["organization"].cleaned_data
application.organization_type = organization_data["organization_type"]
application.federal_branch = organization_data["federal_type"]
application.is_election_office = organization_data["is_election_board"]
# organization type information
organization_type_data = form_dict["organization_type"].cleaned_data
application.organization_type = organization_type_data["organization_type"]
# federal branch information may not exist
federal_branch_data = form_dict.get("organization_federal")
if federal_branch_data is not None:
federal_branch_data = federal_branch_data.cleaned_data
application.federal_branch = federal_branch_data["federal_type"]
# election board information may not exist.
election_board_data = form_dict.get("organization_election")
if election_board_data is not None:
election_board_data = election_board_data.cleaned_data
application.is_election_office = election_board_data["is_election_board"]
# contact information
contact_data = form_dict["contact"].cleaned_data
contact_data = form_dict["organization_contact"].cleaned_data
application.organization_name = contact_data["organization_name"]
application.street_address = contact_data["street_address"]
application.street_address = contact_data["address_line1"]
# TODO: add the rest of these fields when they are created in the forms
# This isn't really the requested_domain field
@ -144,5 +358,7 @@ class ApplicationWizard(LoginRequiredMixin, NamedUrlSessionWizardView):
application = self.forms_to_object(form_dict)
application.submit() # change the status to submitted
application.save()
logger.debug("Application object saved:", application.id)
return redirect("home")
logger.debug("Application object saved: %s", application.id)
return render(
self.request, "application_done.html", {"application_id": application.id}
)