diff --git a/src/registrar/forms/application_wizard.py b/src/registrar/forms/application_wizard.py index 2d151a08e..d731c3965 100644 --- a/src/registrar/forms/application_wizard.py +++ b/src/registrar/forms/application_wizard.py @@ -511,7 +511,10 @@ class DotGovDomainForm(RegistrarForm): values = {} requested_domain = getattr(obj, "requested_domain", None) if requested_domain is not None: - values["requested_domain"] = Domain.sld(requested_domain.name) + is_incomplete = requested_domain.is_incomplete + # Only display a preexisting name if the application was completed + domain_name = requested_domain.name if not is_incomplete else "" + values["requested_domain"] = Domain.sld(domain_name) return values def clean_requested_domain(self): diff --git a/src/registrar/migrations/0063_draftdomain_is_incomplete_alter_draftdomain_name.py b/src/registrar/migrations/0063_draftdomain_draft_number_draftdomain_is_incomplete.py similarity index 63% rename from src/registrar/migrations/0063_draftdomain_is_incomplete_alter_draftdomain_name.py rename to src/registrar/migrations/0063_draftdomain_draft_number_draftdomain_is_incomplete.py index fcb462e22..1ea545c70 100644 --- a/src/registrar/migrations/0063_draftdomain_is_incomplete_alter_draftdomain_name.py +++ b/src/registrar/migrations/0063_draftdomain_draft_number_draftdomain_is_incomplete.py @@ -1,4 +1,4 @@ -# Generated by Django 4.2.7 on 2024-01-11 19:40 +# Generated by Django 4.2.7 on 2024-01-12 16:17 from django.db import migrations, models @@ -9,14 +9,16 @@ class Migration(migrations.Migration): ] operations = [ + migrations.AddField( + model_name="draftdomain", + name="draft_number", + field=models.IntegerField( + help_text="The draft number in the event a user doesn't save at this stage", null=True + ), + ), migrations.AddField( model_name="draftdomain", name="is_incomplete", field=models.BooleanField(default=False, help_text="Determines if this Draft is complete or not"), ), - migrations.AlterField( - model_name="draftdomain", - name="name", - field=models.CharField(help_text="Fully qualified domain name", max_length=253), - ), ] diff --git a/src/registrar/models/domain_application.py b/src/registrar/models/domain_application.py index 196449bfa..d93c429f9 100644 --- a/src/registrar/models/domain_application.py +++ b/src/registrar/models/domain_application.py @@ -631,6 +631,11 @@ class DomainApplication(TimeStampedModel): # Update submission_date to today self.submission_date = timezone.now().date() + + # Mark the draft domain as complete + if self.requested_domain.is_incomplete: + self.requested_domain.is_incomplete = False + self.save() self._send_status_update_email( diff --git a/src/registrar/models/draft_domain.py b/src/registrar/models/draft_domain.py index 4d79494f5..8a2ced775 100644 --- a/src/registrar/models/draft_domain.py +++ b/src/registrar/models/draft_domain.py @@ -17,10 +17,21 @@ class DraftDomain(TimeStampedModel, DomainHelper): name = models.CharField( max_length=253, blank=False, + default=None, # prevent saving without a value help_text="Fully qualified domain name", ) + draft_number = models.IntegerField( + null=True, + help_text="The draft number in the event a user doesn't save at this stage", + ) + is_incomplete = models.BooleanField( default=False, help_text="Determines if this Draft is complete or not" - ) \ No newline at end of file + ) + + def get_default_request_name(self): + """Returns the draft name that would be used for applications if no name exists""" + return f"New domain request {self.draft_number}" + \ No newline at end of file diff --git a/src/registrar/views/application.py b/src/registrar/views/application.py index deda6d0d2..b03de7774 100644 --- a/src/registrar/views/application.py +++ b/src/registrar/views/application.py @@ -1,5 +1,6 @@ import logging import re +from typing import List from django.db.models import Q from django.http import Http404, HttpResponse, HttpResponseRedirect @@ -172,7 +173,7 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView): incomplete_draft_names = incomplete_drafts.values_list(name_field, flat=True) proposed_draft_number = incomplete_drafts.count() + 1 - draft_name = f"New domain request {proposed_draft_number}" + draft_number = 1 for application in existing_applications: if application.requested_domain is not None and application.requested_domain.name is not None: name = application.requested_domain.name @@ -183,26 +184,26 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView): # and 2 is deleted - meaning we would get two duplicate "3"s if we added another if name in incomplete_draft_names: # Get the last numbered draft - last_draft = incomplete_draft_names.last() - last_draft_number = self._parse_first_number_from_string(last_draft) + last_draft = incomplete_drafts.last() + last_draft_number = last_draft.draft_number - smallest_number = self._find_smallest_missing_number(incomplete_draft_names) + smallest_number = self._find_smallest_missing_number(incomplete_drafts) smallest_name = f"New domain request {smallest_number}" if smallest_name not in incomplete_draft_names: - draft_name = smallest_name + draft_number = smallest_number elif proposed_draft_number == last_draft_number: # If the draft number we are trying to create matches the last draft number, # simply add one to that number - draft_name = f"New domain request {last_draft_number + 1}" - - # Handle edge case if the user has an obscene number of domain drafts - if len(draft_name) > 253: - draft_name = default_draft_text + draft_number = last_draft_number + 1 draft_domain = DraftDomain( - name=draft_name, + # Save a blank string rather then None due to DB requirements + name="", + draft_number=draft_number, is_incomplete=True, ) + # Generate a default name based off of a draft_number + draft_domain.name = draft_domain.get_default_request_name() draft_domain.save() return draft_domain @@ -211,7 +212,7 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView): draft_numbers = [] for draft in incomplete_drafts: # Parse the number out of the text - number = self._parse_first_number_from_string(draft) + number = draft.draft_number if number is not None: draft_numbers.append(number) @@ -224,15 +225,6 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView): break return smallest_missing - def _parse_first_number_from_string(self, string_to_parse: str) -> int | None: - """Given a `string_to_parse`, try to find any number in it and return that. - Returns None if no match is found""" - - # Parse the number out of the text - match = re.search("\d+", string_to_parse) - - number = int(match.group()) if match else None - return number @property def storage(self): # marking session as modified on every access