manage.get.gov/src/registrar/forms/application_wizard.py
2022-11-15 14:58:13 -06:00

150 lines
5 KiB
Python

"""Forms Wizard for creating a new domain application."""
import logging
from django import forms
from django.shortcuts import redirect, render
from django.contrib.auth.mixins import LoginRequiredMixin
from formtools.wizard.views import NamedUrlSessionWizardView # type: ignore
from registrar.models import DomainApplication, Website
logger = logging.getLogger(__name__)
class OrganizationForm(forms.Form):
organization_type = forms.ChoiceField(
required=True,
choices=[
("Federal", "Federal: a federal agency"),
("Interstate", "Interstate: an organization of two or more states"),
(
"State_or_Territory",
(
"State or Territory: One of the 50 U.S. states, the District of "
"Columbia, American Samoa, Guam, Northern Mariana Islands, "
"Puerto Rico, or the U.S. Virgin Islands"
),
),
(
"Tribal",
(
"Tribal: a tribal government recognized by the federal or "
"state government"
),
),
("County", "County: a county, parish, or borough"),
("City", "City: a city, town, township, village, etc."),
(
"Special_District",
"Special District: an independent organization within a single state",
),
],
widget=forms.RadioSelect,
)
federal_type = forms.ChoiceField(
required=False,
choices=[
("Executive", "Executive"),
("Judicial", "Judicial"),
("Legislative", "Legislative"),
],
widget=forms.RadioSelect,
)
is_election_board = forms.ChoiceField(
required=False,
choices=[
("Yes", "Yes"),
("No", "No"),
],
widget=forms.RadioSelect,
)
class ContactForm(forms.Form):
organization_name = forms.CharField(label="Organization Name")
street_address = forms.CharField(label="Street address")
# List of forms in our wizard. Each entry is a tuple of a name and a form
# subclass
FORMS = [
("organization", OrganizationForm),
("contact", ContactForm),
]
# 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",
}
# 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",
}
class ApplicationWizard(LoginRequiredMixin, NamedUrlSessionWizardView):
"""Multi-page form ("wizard") for new domain applications.
This sets up a sequence of forms that gather information for new
domain applications. Each form in the sequence has its own URL and
the progress through the form is stored in the Django session (thus
"NamedUrlSessionWizardView").
"""
form_list = FORMS
def get_template_names(self):
"""Template for the current step.
The return is a singleton list.
"""
return [TEMPLATES[self.steps.current]]
def get_context_data(self, form, **kwargs):
"""Add title information to the context for all steps."""
context = super().get_context_data(form=form, **kwargs)
context["form_titles"] = TITLES
return context
def forms_to_object(self, form_dict: dict) -> DomainApplication:
"""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"]
# contact information
contact_data = form_dict["contact"].cleaned_data
application.organization_name = contact_data["organization_name"]
application.street_address = contact_data["street_address"]
# TODO: add the rest of these fields when they are created in the forms
# This isn't really the requested_domain field
# but we need something in this field to make the form submittable
requested_site, _ = Website.objects.get_or_create(
website=contact_data["organization_name"] + ".gov"
)
application.requested_domain = requested_site
return application
def done(self, form_list, form_dict, **kwargs):
application = self.forms_to_object(form_dict)
application.submit() # change the status to submitted
application.save()
logger.debug("Application object saved: %s", application.id)
return render(
self.request, "application_done.html", {"application_id": application.id}
)