mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-08-13 13:09:41 +02:00
Merge pull request #1326 from cisagov/za/1241-imported-ao-data
Ticket #1241: Import AO on domains
This commit is contained in:
commit
cbd36cac76
7 changed files with 198 additions and 11 deletions
|
@ -14,6 +14,7 @@ from registrar.management.commands.utility.terminal_helper import (
|
||||||
TerminalColors,
|
TerminalColors,
|
||||||
TerminalHelper,
|
TerminalHelper,
|
||||||
)
|
)
|
||||||
|
from registrar.models.contact import Contact
|
||||||
from registrar.models.domain_application import DomainApplication
|
from registrar.models.domain_application import DomainApplication
|
||||||
from registrar.models.domain_information import DomainInformation
|
from registrar.models.domain_information import DomainInformation
|
||||||
from registrar.models.user import User
|
from registrar.models.user import User
|
||||||
|
@ -344,8 +345,35 @@ class Command(BaseCommand):
|
||||||
|
|
||||||
return updated
|
return updated
|
||||||
|
|
||||||
def try_add_domain_information(self):
|
def update_contact_info(self, first_name, middle_name, last_name, email, phone):
|
||||||
pass
|
contact = None
|
||||||
|
contacts = Contact.objects.filter(email=email)
|
||||||
|
contact_count = contacts.count()
|
||||||
|
# Create a new one
|
||||||
|
if contact_count == 0:
|
||||||
|
contact = Contact(
|
||||||
|
first_name=first_name, middle_name=middle_name, last_name=last_name, email=email, phone=phone
|
||||||
|
)
|
||||||
|
contact.save()
|
||||||
|
elif contact_count == 1:
|
||||||
|
contact = contacts.get()
|
||||||
|
contact.first_name = first_name
|
||||||
|
contact.middle_name = middle_name
|
||||||
|
contact.last_name = last_name
|
||||||
|
contact.email = email
|
||||||
|
contact.phone = phone
|
||||||
|
contact.save()
|
||||||
|
else:
|
||||||
|
logger.warning(f"Duplicate contact found {contact}. Updating all relevant entries.")
|
||||||
|
for c in contact:
|
||||||
|
c.first_name = first_name
|
||||||
|
c.middle_name = middle_name
|
||||||
|
c.last_name = last_name
|
||||||
|
c.email = email
|
||||||
|
c.phone = phone
|
||||||
|
c.save()
|
||||||
|
contact = c.first()
|
||||||
|
return contact
|
||||||
|
|
||||||
def create_new_domain_info(
|
def create_new_domain_info(
|
||||||
self,
|
self,
|
||||||
|
@ -356,11 +384,23 @@ class Command(BaseCommand):
|
||||||
org_choices,
|
org_choices,
|
||||||
debug_on,
|
debug_on,
|
||||||
) -> DomainInformation:
|
) -> DomainInformation:
|
||||||
org_type_current = transition_domain.organization_type
|
org_type = ("", "")
|
||||||
fed_type = transition_domain.federal_type
|
fed_type = transition_domain.federal_type
|
||||||
fed_agency = transition_domain.federal_agency
|
fed_agency = transition_domain.federal_agency
|
||||||
|
|
||||||
org_type = ("", "")
|
# = AO Information = #
|
||||||
|
first_name = transition_domain.first_name
|
||||||
|
middle_name = transition_domain.middle_name
|
||||||
|
last_name = transition_domain.last_name
|
||||||
|
email = transition_domain.email
|
||||||
|
phone = transition_domain.phone
|
||||||
|
|
||||||
|
contact = self.update_contact_info(first_name, middle_name, last_name, email, phone)
|
||||||
|
|
||||||
|
if debug_on:
|
||||||
|
logger.info(f"Contact created: {contact}")
|
||||||
|
|
||||||
|
org_type_current = transition_domain.organization_type
|
||||||
match org_type_current:
|
match org_type_current:
|
||||||
case "Federal":
|
case "Federal":
|
||||||
org_type = ("federal", "Federal")
|
org_type = ("federal", "Federal")
|
||||||
|
@ -387,6 +427,7 @@ class Command(BaseCommand):
|
||||||
"domain": domain,
|
"domain": domain,
|
||||||
"organization_name": transition_domain.organization_name,
|
"organization_name": transition_domain.organization_name,
|
||||||
"creator": default_creator,
|
"creator": default_creator,
|
||||||
|
"authorizing_official": contact,
|
||||||
}
|
}
|
||||||
|
|
||||||
if valid_org_type:
|
if valid_org_type:
|
||||||
|
|
|
@ -170,7 +170,10 @@ class LoadExtraTransitionDomain:
|
||||||
# STEP 3: Parse agency data
|
# STEP 3: Parse agency data
|
||||||
updated_transition_domain = self.parse_agency_data(domain_name, transition_domain)
|
updated_transition_domain = self.parse_agency_data(domain_name, transition_domain)
|
||||||
|
|
||||||
# STEP 4: Parse creation and expiration data
|
# STEP 4: Parse ao data
|
||||||
|
updated_transition_domain = self.parse_authority_data(domain_name, transition_domain)
|
||||||
|
|
||||||
|
# STEP 5: Parse creation and expiration data
|
||||||
updated_transition_domain = self.parse_creation_expiration_data(domain_name, transition_domain)
|
updated_transition_domain = self.parse_creation_expiration_data(domain_name, transition_domain)
|
||||||
|
|
||||||
# Check if the instance has changed before saving
|
# Check if the instance has changed before saving
|
||||||
|
@ -282,6 +285,53 @@ class LoadExtraTransitionDomain:
|
||||||
|
|
||||||
return transition_domain
|
return transition_domain
|
||||||
|
|
||||||
|
def log_add_or_changed_values(self, file_type, values_to_check, domain_name):
|
||||||
|
for field_name, value in values_to_check:
|
||||||
|
str_exists = value is not None and value.strip() != ""
|
||||||
|
# Logs if we either added to this property,
|
||||||
|
# or modified it.
|
||||||
|
self._add_or_change_message(
|
||||||
|
file_type,
|
||||||
|
field_name,
|
||||||
|
value,
|
||||||
|
domain_name,
|
||||||
|
str_exists,
|
||||||
|
)
|
||||||
|
|
||||||
|
def parse_authority_data(self, domain_name, transition_domain) -> TransitionDomain:
|
||||||
|
"""Grabs authorizing_offical data from the parsed files and associates it
|
||||||
|
with a transition_domain object, then returns that object."""
|
||||||
|
if not isinstance(transition_domain, TransitionDomain):
|
||||||
|
raise ValueError("Not a valid object, must be TransitionDomain")
|
||||||
|
|
||||||
|
info = self.get_authority_info(domain_name)
|
||||||
|
if info is None:
|
||||||
|
self.parse_logs.create_log_item(
|
||||||
|
EnumFilenames.AGENCY_ADHOC,
|
||||||
|
LogCode.ERROR,
|
||||||
|
f"Could not add authorizing_official on {domain_name}, no data exists.",
|
||||||
|
domain_name,
|
||||||
|
not self.debug,
|
||||||
|
)
|
||||||
|
return transition_domain
|
||||||
|
|
||||||
|
transition_domain.first_name = info.firstname
|
||||||
|
transition_domain.middle_name = info.middlename
|
||||||
|
transition_domain.last_name = info.lastname
|
||||||
|
transition_domain.email = info.email
|
||||||
|
transition_domain.phone = info.phonenumber
|
||||||
|
|
||||||
|
changed_fields = [
|
||||||
|
("first_name", transition_domain.first_name),
|
||||||
|
("middle_name", transition_domain.middle_name),
|
||||||
|
("last_name", transition_domain.last_name),
|
||||||
|
("email", transition_domain.email),
|
||||||
|
("phone", transition_domain.phone),
|
||||||
|
]
|
||||||
|
self.log_add_or_changed_values(EnumFilenames.AUTHORITY_ADHOC, changed_fields, domain_name)
|
||||||
|
|
||||||
|
return transition_domain
|
||||||
|
|
||||||
def parse_agency_data(self, domain_name, transition_domain) -> TransitionDomain:
|
def parse_agency_data(self, domain_name, transition_domain) -> TransitionDomain:
|
||||||
"""Grabs federal_agency from the parsed files and associates it
|
"""Grabs federal_agency from the parsed files and associates it
|
||||||
with a transition_domain object, then returns that object."""
|
with a transition_domain object, then returns that object."""
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
# Generated by Django 4.2.7 on 2023-11-09 19:58
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("registrar", "0045_transitiondomain_federal_agency_and_more"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="transitiondomain",
|
||||||
|
name="email",
|
||||||
|
field=models.TextField(blank=True, help_text="Email", null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="transitiondomain",
|
||||||
|
name="first_name",
|
||||||
|
field=models.TextField(
|
||||||
|
blank=True,
|
||||||
|
db_index=True,
|
||||||
|
help_text="First name",
|
||||||
|
null=True,
|
||||||
|
verbose_name="first name / given name",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="transitiondomain",
|
||||||
|
name="last_name",
|
||||||
|
field=models.TextField(blank=True, help_text="Last name", null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="transitiondomain",
|
||||||
|
name="middle_name",
|
||||||
|
field=models.TextField(blank=True, help_text="Middle name", null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="transitiondomain",
|
||||||
|
name="phone",
|
||||||
|
field=models.TextField(blank=True, help_text="Phone", null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="transitiondomain",
|
||||||
|
name="title",
|
||||||
|
field=models.TextField(blank=True, help_text="Title", null=True),
|
||||||
|
),
|
||||||
|
]
|
|
@ -73,6 +73,38 @@ class TransitionDomain(TimeStampedModel):
|
||||||
null=True,
|
null=True,
|
||||||
help_text=("Duplication of registry's expiration " "date saved for ease of reporting"),
|
help_text=("Duplication of registry's expiration " "date saved for ease of reporting"),
|
||||||
)
|
)
|
||||||
|
first_name = models.TextField(
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
help_text="First name",
|
||||||
|
verbose_name="first name / given name",
|
||||||
|
db_index=True,
|
||||||
|
)
|
||||||
|
middle_name = models.TextField(
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
help_text="Middle name",
|
||||||
|
)
|
||||||
|
last_name = models.TextField(
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
help_text="Last name",
|
||||||
|
)
|
||||||
|
title = models.TextField(
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
help_text="Title",
|
||||||
|
)
|
||||||
|
email = models.TextField(
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
help_text="Email",
|
||||||
|
)
|
||||||
|
phone = models.TextField(
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
|
help_text="Phone",
|
||||||
|
)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.username}, {self.domain_name}"
|
return f"{self.username}, {self.domain_name}"
|
||||||
|
@ -91,4 +123,9 @@ class TransitionDomain(TimeStampedModel):
|
||||||
f"federal_agency: {self.federal_agency}, \n"
|
f"federal_agency: {self.federal_agency}, \n"
|
||||||
f"epp_creation_date: {self.epp_creation_date}, \n"
|
f"epp_creation_date: {self.epp_creation_date}, \n"
|
||||||
f"epp_expiration_date: {self.epp_expiration_date}, \n"
|
f"epp_expiration_date: {self.epp_expiration_date}, \n"
|
||||||
|
f"first_name: {self.first_name}, \n"
|
||||||
|
f"middle_name: {self.middle_name}, \n"
|
||||||
|
f"last_name: {self.last_name}, \n"
|
||||||
|
f"email: {self.email}, \n"
|
||||||
|
f"phone: {self.phone}, \n"
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,5 +2,5 @@ authorityid|firstname|middlename|lastname|email|phonenumber|agencyid|addlinfo
|
||||||
1|Gregoor|middle|Kalinke|gkalinke0@indiegogo.com|(773) 172-5515|1|Asparagus - Mexican
|
1|Gregoor|middle|Kalinke|gkalinke0@indiegogo.com|(773) 172-5515|1|Asparagus - Mexican
|
||||||
2|Fayre||Filippozzi|ffilippozzi1@hugedomains.com|(357) 487-4280|2|Steampan - Foil
|
2|Fayre||Filippozzi|ffilippozzi1@hugedomains.com|(357) 487-4280|2|Steampan - Foil
|
||||||
3|Gabey||Lightbody|glightbody2@fc2.com|(332) 816-5691|3|Soup - Campbells, Minestrone
|
3|Gabey||Lightbody|glightbody2@fc2.com|(332) 816-5691|3|Soup - Campbells, Minestrone
|
||||||
4|Seline||Tower|stower3@answers.com|(151) 539-6028|4|Kiwi Gold Zespri
|
4|Seline|testmiddle2|Tower|stower3@answers.com|151-539-6028|4|Kiwi Gold Zespri
|
||||||
5|Joe||Smoe|joe@smoe.gov|(111) 111-1111|5|Kiwi Gold Zespri
|
5|Joe|testmiddle|Smoe|joe@smoe.gov|(111) 111-1111|5|Kiwi Gold Zespri
|
|
@ -313,6 +313,14 @@ class TestMigrations(TestCase):
|
||||||
self.assertEqual(fakewebsite.federal_agency, "Department of Commerce")
|
self.assertEqual(fakewebsite.federal_agency, "Department of Commerce")
|
||||||
self.assertEqual(fakewebsite.federal_type, "executive")
|
self.assertEqual(fakewebsite.federal_type, "executive")
|
||||||
|
|
||||||
|
ao = fakewebsite.authorizing_official
|
||||||
|
|
||||||
|
self.assertEqual(ao.first_name, "Seline")
|
||||||
|
self.assertEqual(ao.middle_name, "testmiddle2")
|
||||||
|
self.assertEqual(ao.last_name, "Tower")
|
||||||
|
self.assertEqual(ao.email, "stower3@answers.com")
|
||||||
|
self.assertEqual(ao.phone, "151-539-6028")
|
||||||
|
|
||||||
# Check for the "system" creator user
|
# Check for the "system" creator user
|
||||||
Users = User.objects.filter(username="System")
|
Users = User.objects.filter(username="System")
|
||||||
self.assertEqual(Users.count(), 1)
|
self.assertEqual(Users.count(), 1)
|
||||||
|
|
|
@ -13,7 +13,12 @@ def export_domains_to_writer(writer, columns, sort_fields, filter_condition):
|
||||||
domainInfos = DomainInformation.objects.filter(**filter_condition).order_by(*sort_fields)
|
domainInfos = DomainInformation.objects.filter(**filter_condition).order_by(*sort_fields)
|
||||||
for domainInfo in domainInfos:
|
for domainInfo in domainInfos:
|
||||||
security_contacts = domainInfo.domain.contacts.filter(contact_type=PublicContact.ContactTypeChoices.SECURITY)
|
security_contacts = domainInfo.domain.contacts.filter(contact_type=PublicContact.ContactTypeChoices.SECURITY)
|
||||||
|
# For linter
|
||||||
|
ao = " "
|
||||||
|
if domainInfo.authorizing_official:
|
||||||
|
first_name = domainInfo.authorizing_official.first_name or ""
|
||||||
|
last_name = domainInfo.authorizing_official.last_name or ""
|
||||||
|
ao = first_name + " " + last_name
|
||||||
# create a dictionary of fields which can be included in output
|
# create a dictionary of fields which can be included in output
|
||||||
FIELDS = {
|
FIELDS = {
|
||||||
"Domain name": domainInfo.domain.name,
|
"Domain name": domainInfo.domain.name,
|
||||||
|
@ -24,9 +29,7 @@ def export_domains_to_writer(writer, columns, sort_fields, filter_condition):
|
||||||
"Organization name": domainInfo.organization_name,
|
"Organization name": domainInfo.organization_name,
|
||||||
"City": domainInfo.city,
|
"City": domainInfo.city,
|
||||||
"State": domainInfo.state_territory,
|
"State": domainInfo.state_territory,
|
||||||
"AO": domainInfo.authorizing_official.first_name + " " + domainInfo.authorizing_official.last_name
|
"AO": ao,
|
||||||
if domainInfo.authorizing_official
|
|
||||||
else " ",
|
|
||||||
"AO email": domainInfo.authorizing_official.email if domainInfo.authorizing_official else " ",
|
"AO email": domainInfo.authorizing_official.email if domainInfo.authorizing_official else " ",
|
||||||
"Security Contact Email": security_contacts[0].email if security_contacts else " ",
|
"Security Contact Email": security_contacts[0].email if security_contacts else " ",
|
||||||
"Status": domainInfo.domain.state,
|
"Status": domainInfo.domain.state,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue