diff --git a/src/registrar/templates/domain_request_review.html b/src/registrar/templates/domain_request_review.html
index 6776dd2c0..ced20b6b7 100644
--- a/src/registrar/templates/domain_request_review.html
+++ b/src/registrar/templates/domain_request_review.html
@@ -130,8 +130,8 @@
{% if step == Step.YOUR_CONTACT %}
{% namespaced_url 'domain-request' step as domain_request_url %}
- {% if domain_request.submitter is not None %}
- {% with title=form_titles|get_item:step value=domain_request.submitter %}
+ {% if domain_request.creator is not None %}
+ {% with title=form_titles|get_item:step value=domain_request.creator %}
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=domain_request_url contact='true' %}
{% endwith %}
{% else %}
diff --git a/src/registrar/templates/domain_request_status.html b/src/registrar/templates/domain_request_status.html
index 183a8be81..c870f5ab1 100644
--- a/src/registrar/templates/domain_request_status.html
+++ b/src/registrar/templates/domain_request_status.html
@@ -109,8 +109,8 @@
{% include "includes/summary_item.html" with title='Purpose of your domain' value=DomainRequest.purpose heading_level=heading_level %}
{% endif %}
- {% if DomainRequest.submitter and not has_profile_feature_flag %}
- {% include "includes/summary_item.html" with title='Your contact information' value=DomainRequest.submitter contact='true' heading_level=heading_level %}
+ {% if DomainRequest.creator and not has_profile_feature_flag %}
+ {% include "includes/summary_item.html" with title='Your contact information' value=DomainRequest.creator contact='true' heading_level=heading_level %}
{% endif %}
{% if DomainRequest.other_contacts.all %}
diff --git a/src/registrar/views/domain_request.py b/src/registrar/views/domain_request.py
index b691549cd..45c0c3ddb 100644
--- a/src/registrar/views/domain_request.py
+++ b/src/registrar/views/domain_request.py
@@ -375,7 +375,7 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView):
),
"dotgov_domain": self.domain_request.requested_domain is not None,
"purpose": self.domain_request.purpose is not None,
- "your_contact": self.domain_request.submitter is not None,
+ "your_contact": self.domain_request.creator is not None,
"other_contacts": (
self.domain_request.other_contacts.exists()
or self.domain_request.no_other_contacts_rationale is not None
@@ -813,7 +813,7 @@ class DomainRequestDeleteView(DomainRequestPermissionDeleteView):
# After a delete occurs, do a second sweep on any returned duplicates.
# This determines if any of these three fields share a contact, which is used for
- # the edge case where the same user may be an SO, and a submitter, for example.
+ # the edge case where the same user may be an SO, and a creator, for example.
if len(duplicates) > 0:
duplicates_to_delete, _ = self._get_orphaned_contacts(domain_request, check_db=True)
Contact.objects.filter(id__in=duplicates_to_delete).delete()
@@ -826,7 +826,7 @@ class DomainRequestDeleteView(DomainRequestPermissionDeleteView):
Collects all orphaned contacts associated with a given DomainRequest object.
An orphaned contact is defined as a contact that is associated with the domain request,
- but not with any other domain_request. This includes the senior official, the submitter,
+ but not with any other domain_request. This includes the senior official, the creator,
and any other contacts linked to the domain_request.
Parameters:
@@ -842,18 +842,18 @@ class DomainRequestDeleteView(DomainRequestPermissionDeleteView):
# Get each contact object on the DomainRequest object
so = domain_request.senior_official
- submitter = domain_request.submitter
+ creator = domain_request.creator
other_contacts = list(domain_request.other_contacts.all())
other_contact_ids = domain_request.other_contacts.all().values_list("id", flat=True)
# Check if the desired item still exists in the DB
if check_db:
so = self._get_contacts_by_id([so.id]).first() if so is not None else None
- submitter = self._get_contacts_by_id([submitter.id]).first() if submitter is not None else None
+ creator = self._get_contacts_by_id([creator.id]).first() if creator is not None else None
other_contacts = self._get_contacts_by_id(other_contact_ids)
# Pair each contact with its db related name for use in checking if it has joins
- checked_contacts = [(so, "senior_official"), (submitter, "submitted_domain_requests")]
+ checked_contacts = [(so, "senior_official"), (creator, "submitted_domain_requests")]
checked_contacts.extend((contact, "contact_domain_requests") for contact in other_contacts)
for contact, related_name in checked_contacts:
From 2713e597956fdd729b0551a1b5a03caa57eb00b9 Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Mon, 26 Aug 2024 15:59:48 -0700
Subject: [PATCH 003/150] Remove submitter from model tests
---
src/registrar/models/domain_request.py | 7 +++-
src/registrar/tests/common.py | 20 +++++------
src/registrar/tests/test_admin.py | 44 ++++++++---------------
src/registrar/tests/test_admin_domain.py | 7 ----
src/registrar/tests/test_admin_request.py | 30 ++++------------
src/registrar/tests/test_models.py | 29 ++++++---------
src/registrar/tests/test_views.py | 6 ----
src/registrar/tests/test_views_request.py | 20 +++--------
src/registrar/views/utility/mixins.py | 12 +++----
9 files changed, 57 insertions(+), 118 deletions(-)
diff --git a/src/registrar/models/domain_request.py b/src/registrar/models/domain_request.py
index acd41053b..1c4cbb355 100644
--- a/src/registrar/models/domain_request.py
+++ b/src/registrar/models/domain_request.py
@@ -1137,6 +1137,10 @@ class DomainRequest(TimeStampedModel):
# Special District -> "Election office" and "About your organization" page can't be empty
return self.is_election_board is not None and self.about_your_organization is not None
+ # Do we still want to test this after creator is autogenerated? Currently it went back to being selectable
+ def _is_creator_complete(self):
+ return self.creator is not None
+
def _is_organization_name_and_address_complete(self):
return not (
self.organization_name is None
@@ -1205,7 +1209,8 @@ class DomainRequest(TimeStampedModel):
def _is_general_form_complete(self, request):
has_profile_feature_flag = flag_is_active(request, "profile_feature")
return (
- self._is_organization_name_and_address_complete()
+ self._is_creator_complete()
+ and self._is_organization_name_and_address_complete()
and self._is_senior_official_complete()
and self._is_requested_domain_complete()
and self._is_purpose_complete()
diff --git a/src/registrar/tests/common.py b/src/registrar/tests/common.py
index ceb3b6e92..40d5108f4 100644
--- a/src/registrar/tests/common.py
+++ b/src/registrar/tests/common.py
@@ -392,7 +392,6 @@ class AuditedAdminMockData:
about_your_organization: str = "e-Government",
anything_else: str = "There is more",
senior_official: Contact = self.dummy_contact(item_name, "senior_official"),
- submitter: Contact = self.dummy_contact(item_name, "submitter"),
creator: User = self.dummy_user(item_name, "creator"),
}
""" # noqa
@@ -410,7 +409,6 @@ class AuditedAdminMockData:
about_your_organization="e-Government",
anything_else="There is more",
senior_official=self.dummy_contact(item_name, "senior_official"),
- submitter=self.dummy_contact(item_name, "submitter"),
creator=creator,
)
return common_args
@@ -897,7 +895,6 @@ def completed_domain_request( # noqa
has_cisa_representative=True,
status=DomainRequest.DomainRequestStatus.STARTED,
user=False,
- submitter=False,
name="city.gov",
investigator=None,
generic_org_type="federal",
@@ -921,14 +918,14 @@ def completed_domain_request( # noqa
domain, _ = DraftDomain.objects.get_or_create(name=name)
alt, _ = Website.objects.get_or_create(website="city1.gov")
current, _ = Website.objects.get_or_create(website="city.com")
- if not submitter:
- submitter, _ = Contact.objects.get_or_create(
- first_name="Testy2",
- last_name="Tester2",
- title="Admin Tester",
- email="mayor@igorville.gov",
- phone="(555) 555 5556",
- )
+ # if not creator:
+ # creator, _ = Contact.objects.get_or_create(
+ # first_name="Testy2",
+ # last_name="Tester2",
+ # title="Admin Tester",
+ # email="mayor@igorville.gov",
+ # phone="(555) 555 5556",
+ # )
other, _ = Contact.objects.get_or_create(
first_name="Testy",
last_name="Tester",
@@ -957,7 +954,6 @@ def completed_domain_request( # noqa
zipcode="10002",
senior_official=so,
requested_domain=domain,
- submitter=submitter,
creator=user,
status=status,
investigator=investigator,
diff --git a/src/registrar/tests/test_admin.py b/src/registrar/tests/test_admin.py
index 827742ef1..b6c8e7c21 100644
--- a/src/registrar/tests/test_admin.py
+++ b/src/registrar/tests/test_admin.py
@@ -380,7 +380,7 @@ class TestDomainInformationAdmin(TestCase):
contact, _ = Contact.objects.get_or_create(first_name="Henry", last_name="McFakerson")
domain_request = completed_domain_request(
- submitter=contact, name="city1244.gov", status=DomainRequest.DomainRequestStatus.IN_REVIEW
+ name="city1244.gov", status=DomainRequest.DomainRequestStatus.IN_REVIEW
)
domain_request.approve()
@@ -505,7 +505,6 @@ class TestDomainInformationAdmin(TestCase):
# These should exist in the response
expected_values = [
("creator", "Person who submitted the domain request"),
- ("submitter", 'Person listed under "your contact information" in the request form'),
("domain_request", "Request associated with this domain"),
("no_other_contacts_rationale", "Required if creator does not list other employees"),
("urbanization", "Required for Puerto Rico only"),
@@ -629,16 +628,6 @@ class TestDomainInformationAdmin(TestCase):
# Check for the field itself
self.assertContains(response, "Meoward Jones")
- # == Check for the submitter == #
- self.assertContains(response, "mayor@igorville.gov", count=2)
- expected_submitter_fields = [
- # Field, expected value
- ("title", "Admin Tester"),
- ("phone", "(555) 555 5556"),
- ]
- self.test_helper.assert_response_contains_distinct_values(response, expected_submitter_fields)
- self.assertContains(response, "Testy2 Tester2")
-
# == Check for the senior_official == #
self.assertContains(response, "testy@town.com", count=2)
expected_so_fields = [
@@ -684,7 +673,6 @@ class TestDomainInformationAdmin(TestCase):
"more_organization_information",
"domain",
"domain_request",
- "submitter",
"no_other_contacts_rationale",
"anything_else",
"is_policy_acknowledged",
@@ -703,19 +691,19 @@ class TestDomainInformationAdmin(TestCase):
# Assert that sorting in reverse works correctly
self.test_helper.assert_table_sorted("-1", ("-domain__name",))
- def test_submitter_sortable(self):
- """Tests if DomainInformation sorts by submitter correctly"""
+ def test_creator_sortable(self):
+ """Tests if DomainInformation sorts by creator correctly"""
with less_console_noise():
self.client.force_login(self.superuser)
# Assert that our sort works correctly
self.test_helper.assert_table_sorted(
"4",
- ("submitter__first_name", "submitter__last_name"),
+ ("creator__first_name", "creator__last_name"),
)
# Assert that sorting in reverse works correctly
- self.test_helper.assert_table_sorted("-4", ("-submitter__first_name", "-submitter__last_name"))
+ self.test_helper.assert_table_sorted("-4", ("-creator__first_name", "-creator__last_name"))
class TestUserDomainRoleAdmin(TestCase):
@@ -1298,7 +1286,6 @@ class AuditedAdminTest(TestCase):
# Senior offical is commented out for now - this is alphabetized
# and this test does not accurately reflect that.
# DomainRequest.senior_official.field,
- DomainRequest.submitter.field,
# DomainRequest.investigator.field,
DomainRequest.creator.field,
DomainRequest.requested_domain.field,
@@ -1358,7 +1345,6 @@ class AuditedAdminTest(TestCase):
# Senior offical is commented out for now - this is alphabetized
# and this test does not accurately reflect that.
# DomainInformation.senior_official.field,
- DomainInformation.submitter.field,
# DomainInformation.creator.field,
(DomainInformation.domain.field, ["name"]),
(DomainInformation.domain_request.field, ["requested_domain__name"]),
@@ -1680,10 +1666,10 @@ class TestContactAdmin(TestCase):
)
# join it to 4 domain requests.
- domain_request1 = completed_domain_request(submitter=contact, name="city1.gov")
- domain_request2 = completed_domain_request(submitter=contact, name="city2.gov")
- domain_request3 = completed_domain_request(submitter=contact, name="city3.gov")
- domain_request4 = completed_domain_request(submitter=contact, name="city4.gov")
+ domain_request1 = completed_domain_request(name="city1.gov")
+ domain_request2 = completed_domain_request(name="city2.gov")
+ domain_request3 = completed_domain_request(name="city3.gov")
+ domain_request4 = completed_domain_request(name="city4.gov")
with patch("django.contrib.messages.warning") as mock_warning:
# Use the test client to simulate the request
@@ -1720,12 +1706,12 @@ class TestContactAdmin(TestCase):
first_name="Henry",
last_name="McFakerson",
)
- domain_request1 = completed_domain_request(submitter=contact, name="city1.gov")
- domain_request2 = completed_domain_request(submitter=contact, name="city2.gov")
- domain_request3 = completed_domain_request(submitter=contact, name="city3.gov")
- domain_request4 = completed_domain_request(submitter=contact, name="city4.gov")
- domain_request5 = completed_domain_request(submitter=contact, name="city5.gov")
- completed_domain_request(submitter=contact, name="city6.gov")
+ domain_request1 = completed_domain_request(name="city1.gov")
+ domain_request2 = completed_domain_request(name="city2.gov")
+ domain_request3 = completed_domain_request(name="city3.gov")
+ domain_request4 = completed_domain_request(name="city4.gov")
+ domain_request5 = completed_domain_request(name="city5.gov")
+ completed_domain_request(name="city6.gov")
with patch("django.contrib.messages.warning") as mock_warning:
# Use the test client to simulate the request
response = self.client.get(reverse("admin:registrar_contact_change", args=[contact.pk]))
diff --git a/src/registrar/tests/test_admin_domain.py b/src/registrar/tests/test_admin_domain.py
index e156dd377..43602d395 100644
--- a/src/registrar/tests/test_admin_domain.py
+++ b/src/registrar/tests/test_admin_domain.py
@@ -423,13 +423,6 @@ class TestDomainAdminWithClient(TestCase):
# Check for the field itself
self.assertContains(response, "Meoward Jones")
- # == Check for the submitter == #
- self.assertContains(response, "mayor@igorville.gov")
-
- self.assertContains(response, "Admin Tester")
- self.assertContains(response, "(555) 555 5556")
- self.assertContains(response, "Testy2 Tester2")
-
# == Check for the senior_official == #
self.assertContains(response, "testy@town.com")
self.assertContains(response, "Chief Tester")
diff --git a/src/registrar/tests/test_admin_request.py b/src/registrar/tests/test_admin_request.py
index c4fc8bcee..2bce7de7a 100644
--- a/src/registrar/tests/test_admin_request.py
+++ b/src/registrar/tests/test_admin_request.py
@@ -94,7 +94,7 @@ class TestDomainRequestAdmin(MockEppLib):
SeniorOfficial.objects.get_or_create(first_name="Zoup", last_name="Soup", title="title")
contact, _ = Contact.objects.get_or_create(first_name="Henry", last_name="McFakerson")
- domain_request = completed_domain_request(submitter=contact, name="city1.gov")
+ domain_request = completed_domain_request(name="city1.gov")
request = self.factory.post("/admin/registrar/domainrequest/{}/change/".format(domain_request.pk))
model_admin = AuditedAdmin(DomainRequest, self.site)
@@ -150,10 +150,6 @@ class TestDomainRequestAdmin(MockEppLib):
# These should exist in the response
expected_values = [
("creator", "Person who submitted the domain request; will not receive email updates"),
- (
- "submitter",
- 'Person listed under "your contact information" in the request form; will receive email updates',
- ),
("approved_domain", "Domain associated with this request; will be blank until request is approved"),
("no_other_contacts_rationale", "Required if creator does not list other employees"),
("alternative_domains", "Other domain names the creator provided for consideration"),
@@ -409,8 +405,8 @@ class TestDomainRequestAdmin(MockEppLib):
self.test_helper.assert_table_sorted("-1", ("-requested_domain__name",))
@less_console_noise_decorator
- def test_submitter_sortable(self):
- """Tests if the DomainRequest sorts by submitter correctly"""
+ def test_creator_sortable(self):
+ """Tests if the DomainRequest sorts by creator correctly"""
self.client.force_login(self.superuser)
multiple_unalphabetical_domain_objects("domain_request")
@@ -424,8 +420,8 @@ class TestDomainRequestAdmin(MockEppLib):
self.test_helper.assert_table_sorted(
"11",
(
- "submitter__first_name",
- "submitter__last_name",
+ "creator__first_name",
+ "creator__last_name",
),
)
@@ -433,8 +429,8 @@ class TestDomainRequestAdmin(MockEppLib):
self.test_helper.assert_table_sorted(
"-11",
(
- "-submitter__first_name",
- "-submitter__last_name",
+ "-creator__first_name",
+ "-creator__last_name",
),
)
@@ -1381,16 +1377,6 @@ class TestDomainRequestAdmin(MockEppLib):
# Check for the field itself
self.assertContains(response, "Meoward Jones")
- # == Check for the submitter == #
- self.assertContains(response, "mayor@igorville.gov", count=2)
- expected_submitter_fields = [
- # Field, expected value
- ("title", "Admin Tester"),
- ("phone", "(555) 555 5556"),
- ]
- self.test_helper.assert_response_contains_distinct_values(response, expected_submitter_fields)
- self.assertContains(response, "Testy2 Tester2")
-
# == Check for the senior_official == #
self.assertContains(response, "testy@town.com", count=2)
expected_so_fields = [
@@ -1546,7 +1532,6 @@ class TestDomainRequestAdmin(MockEppLib):
"senior_official",
"approved_domain",
"requested_domain",
- "submitter",
"purpose",
"no_other_contacts_rationale",
"anything_else",
@@ -1583,7 +1568,6 @@ class TestDomainRequestAdmin(MockEppLib):
"approved_domain",
"alternative_domains",
"purpose",
- "submitter",
"no_other_contacts_rationale",
"anything_else",
"is_policy_acknowledged",
diff --git a/src/registrar/tests/test_models.py b/src/registrar/tests/test_models.py
index f4e998fff..5e8dbc80b 100644
--- a/src/registrar/tests/test_models.py
+++ b/src/registrar/tests/test_models.py
@@ -168,7 +168,6 @@ class TestDomainRequest(TestCase):
zipcode="12345-6789",
senior_official=contact,
requested_domain=domain,
- submitter=contact,
purpose="Igorville rules!",
anything_else="All of Igorville loves the dotgov program.",
is_policy_acknowledged=True,
@@ -195,7 +194,6 @@ class TestDomainRequest(TestCase):
state_territory="CA",
zipcode="12345-6789",
senior_official=contact,
- submitter=contact,
purpose="Igorville rules!",
anything_else="All of Igorville loves the dotgov program.",
is_policy_acknowledged=True,
@@ -258,7 +256,7 @@ class TestDomainRequest(TestCase):
@less_console_noise_decorator
def test_submit_from_started_sends_email(self):
msg = "Create a domain request and submit it and see if email was sent."
- domain_request = completed_domain_request(submitter=self.dummy_user, user=self.dummy_user_2)
+ domain_request = completed_domain_request(user=self.dummy_user_2)
self.check_email_sent(domain_request, msg, "submit", 1, expected_content="Hello")
@override_flag("profile_feature", active=True)
@@ -266,7 +264,7 @@ class TestDomainRequest(TestCase):
def test_submit_from_started_sends_email_to_creator(self):
"""Tests if, when the profile feature flag is on, we send an email to the creator"""
msg = "Create a domain request and submit it and see if email was sent when the feature flag is on."
- domain_request = completed_domain_request(submitter=self.dummy_user, user=self.dummy_user_2)
+ domain_request = completed_domain_request(user=self.dummy_user_2)
self.check_email_sent(
domain_request, msg, "submit", 1, expected_content="Lava", expected_email="intern@igorville.com"
)
@@ -275,7 +273,7 @@ class TestDomainRequest(TestCase):
def test_submit_from_withdrawn_sends_email(self):
msg = "Create a withdrawn domain request and submit it and see if email was sent."
domain_request = completed_domain_request(
- status=DomainRequest.DomainRequestStatus.WITHDRAWN, submitter=self.dummy_user
+ status=DomainRequest.DomainRequestStatus.WITHDRAWN
)
self.check_email_sent(domain_request, msg, "submit", 1, expected_content="Hello")
@@ -294,25 +292,19 @@ class TestDomainRequest(TestCase):
@less_console_noise_decorator
def test_approve_sends_email(self):
msg = "Create a domain request and approve it and see if email was sent."
- domain_request = completed_domain_request(
- status=DomainRequest.DomainRequestStatus.IN_REVIEW, submitter=self.dummy_user
- )
+ domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
self.check_email_sent(domain_request, msg, "approve", 1, expected_content="Hello")
@less_console_noise_decorator
def test_withdraw_sends_email(self):
msg = "Create a domain request and withdraw it and see if email was sent."
- domain_request = completed_domain_request(
- status=DomainRequest.DomainRequestStatus.IN_REVIEW, submitter=self.dummy_user
- )
+ domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
self.check_email_sent(domain_request, msg, "withdraw", 1, expected_content="Hello")
@less_console_noise_decorator
def test_reject_sends_email(self):
msg = "Create a domain request and reject it and see if email was sent."
- domain_request = completed_domain_request(
- status=DomainRequest.DomainRequestStatus.APPROVED, submitter=self.dummy_user
- )
+ domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.APPROVED)
self.check_email_sent(domain_request, msg, "reject", 1, expected_content="Hello")
@less_console_noise_decorator
@@ -1877,7 +1869,6 @@ class TestDomainRequestIncomplete(TestCase):
senior_official=so,
requested_domain=draft_domain,
purpose="Some purpose",
- submitter=you,
no_other_contacts_rationale=None,
has_cisa_representative=True,
cisa_representative_email="somerep@cisa.com",
@@ -2007,11 +1998,11 @@ class TestDomainRequestIncomplete(TestCase):
self.assertFalse(self.domain_request._is_purpose_complete())
@less_console_noise_decorator
- def test_is_submitter_complete(self):
- self.assertTrue(self.domain_request._is_submitter_complete())
- self.domain_request.submitter = None
+ def test_is_creator_complete(self):
+ self.assertTrue(self.domain_request._is_creator_complete())
+ self.domain_request.creator = None
self.domain_request.save()
- self.assertFalse(self.domain_request._is_submitter_complete())
+ self.assertFalse(self.domain_request._is_creator_complete())
@less_console_noise_decorator
def test_is_other_contacts_complete_missing_one_field(self):
diff --git a/src/registrar/tests/test_views.py b/src/registrar/tests/test_views.py
index 6c2ad6b5e..890e6ebdd 100644
--- a/src/registrar/tests/test_views.py
+++ b/src/registrar/tests/test_views.py
@@ -381,7 +381,6 @@ class HomeTests(TestWithUser):
requested_domain=site,
status=DomainRequest.DomainRequestStatus.WITHDRAWN,
senior_official=contact,
- submitter=contact_user,
)
domain_request.other_contacts.set([contact_2])
@@ -392,7 +391,6 @@ class HomeTests(TestWithUser):
requested_domain=site_2,
status=DomainRequest.DomainRequestStatus.STARTED,
senior_official=contact_2,
- submitter=contact_shared,
)
domain_request_2.other_contacts.set([contact_shared])
@@ -455,7 +453,6 @@ class HomeTests(TestWithUser):
requested_domain=site,
status=DomainRequest.DomainRequestStatus.WITHDRAWN,
senior_official=contact,
- submitter=contact_user,
)
domain_request.other_contacts.set([contact_2])
@@ -466,7 +463,6 @@ class HomeTests(TestWithUser):
requested_domain=site_2,
status=DomainRequest.DomainRequestStatus.STARTED,
senior_official=contact_2,
- submitter=contact_shared,
)
domain_request_2.other_contacts.set([contact_shared])
@@ -1038,7 +1034,6 @@ class UserProfileTests(TestWithUser, WebTest):
requested_domain=site,
status=DomainRequest.DomainRequestStatus.SUBMITTED,
senior_official=contact_user,
- submitter=contact_user,
)
with override_flag("profile_feature", active=True):
response = self.client.get(f"/domain-request/{domain_request.id}", follow=True)
@@ -1060,7 +1055,6 @@ class UserProfileTests(TestWithUser, WebTest):
requested_domain=site,
status=DomainRequest.DomainRequestStatus.SUBMITTED,
senior_official=contact_user,
- submitter=contact_user,
)
with override_flag("profile_feature", active=False):
response = self.client.get(f"/domain-request/{domain_request.id}", follow=True)
diff --git a/src/registrar/tests/test_views_request.py b/src/registrar/tests/test_views_request.py
index 6642b6471..1f6b50ded 100644
--- a/src/registrar/tests/test_views_request.py
+++ b/src/registrar/tests/test_views_request.py
@@ -368,11 +368,11 @@ class DomainRequestTests(TestWithUser, WebTest):
your_contact_result = your_contact_form.submit()
# validate that data from this step are being saved
domain_request = DomainRequest.objects.get() # there's only one
- self.assertEqual(domain_request.submitter.first_name, "Testy you")
- self.assertEqual(domain_request.submitter.last_name, "Tester you")
- self.assertEqual(domain_request.submitter.title, "Admin Tester")
- self.assertEqual(domain_request.submitter.email, "testy-admin@town.com")
- self.assertEqual(domain_request.submitter.phone, "(201) 555 5556")
+ self.assertEqual(domain_request.creator.first_name, self.user.first_name)
+ self.assertEqual(domain_request.creator.last_name, self.user.last_name)
+ self.assertEqual(domain_request.creator.title, self.user.title)
+ self.assertEqual(domain_request.creator.email, self.user.email)
+ self.assertEqual(domain_request.creator.phone, self.user.phone)
# the post request should return a redirect to the next form in
# the domain request page
self.assertEqual(your_contact_result.status_code, 302)
@@ -1643,7 +1643,6 @@ class DomainRequestTests(TestWithUser, WebTest):
state_territory="NY",
zipcode="10002",
senior_official=so,
- submitter=you,
creator=self.user,
status="started",
)
@@ -1780,7 +1779,6 @@ class DomainRequestTests(TestWithUser, WebTest):
state_territory="NY",
zipcode="10002",
senior_official=so,
- submitter=you,
creator=self.user,
status="started",
)
@@ -1855,7 +1853,6 @@ class DomainRequestTests(TestWithUser, WebTest):
state_territory="NY",
zipcode="10002",
senior_official=so,
- submitter=you,
creator=self.user,
status="started",
)
@@ -1933,7 +1930,6 @@ class DomainRequestTests(TestWithUser, WebTest):
state_territory="NY",
zipcode="10002",
senior_official=so,
- submitter=you,
creator=self.user,
status="started",
)
@@ -2010,7 +2006,6 @@ class DomainRequestTests(TestWithUser, WebTest):
state_territory="NY",
zipcode="10002",
senior_official=so,
- submitter=you,
creator=self.user,
status="started",
)
@@ -2086,7 +2081,6 @@ class DomainRequestTests(TestWithUser, WebTest):
state_territory="NY",
zipcode="10002",
senior_official=so,
- submitter=you,
creator=self.user,
status="started",
)
@@ -2297,7 +2291,6 @@ class DomainRequestTests(TestWithUser, WebTest):
address_line1="address 1",
state_territory="NY",
zipcode="10002",
- submitter=you,
creator=self.user,
status="started",
)
@@ -2363,7 +2356,6 @@ class DomainRequestTests(TestWithUser, WebTest):
address_line1="address 1",
state_territory="NY",
zipcode="10002",
- submitter=submitter,
creator=self.user,
status="started",
)
@@ -2729,7 +2721,6 @@ class DomainRequestTests(TestWithUser, WebTest):
zipcode="10002",
senior_official=so,
requested_domain=domain,
- submitter=you,
creator=self.user,
)
domain_request.other_contacts.add(other)
@@ -3072,7 +3063,6 @@ class TestWizardUnlockingSteps(TestWithUser, WebTest):
requested_domain=site,
status=DomainRequest.DomainRequestStatus.WITHDRAWN,
senior_official=contact,
- submitter=contact_user,
)
domain_request.other_contacts.set([contact_2])
diff --git a/src/registrar/views/utility/mixins.py b/src/registrar/views/utility/mixins.py
index 16a896100..04d86593f 100644
--- a/src/registrar/views/utility/mixins.py
+++ b/src/registrar/views/utility/mixins.py
@@ -81,12 +81,12 @@ class OrderableFieldsMixin:
Or for fields with multiple order_fields:
```
- def get_sortable_submitter(self, obj):
- return obj.submitter
+ def get_sortable_creator(self, obj):
+ return obj.creator
# Allows column order sorting
- get_sortable_submitter.admin_order_field = ["submitter__first_name", "submitter__last_name"]
+ get_sortable_creator.admin_order_field = ["creator__first_name", "creaotr__last_name"]
# Sets column's header
- get_sortable_submitter.short_description = "submitter"
+ get_sortable_creator.short_description = "creator"
```
Parameters:
@@ -114,8 +114,8 @@ class OrderableFieldsMixin:
Returns (example):
```
- def get_submitter(self, obj):
- return obj.submitter
+ def get_creator(self, obj):
+ return obj.creator
```
"""
attr = getattr(obj, field)
From ff9e73def6f34708fd177eef2b5acae09e52ea63 Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Tue, 27 Aug 2024 15:52:23 -0700
Subject: [PATCH 004/150] Continued test cleanup
---
src/registrar/config/urls.py | 6 -
src/registrar/tests/test_admin.py | 2 +-
src/registrar/tests/test_admin_request.py | 4 +-
src/registrar/tests/test_views.py | 14 --
src/registrar/tests/test_views_domain.py | 6 -
src/registrar/tests/test_views_request.py | 180 +++-------------------
src/registrar/views/__init__.py | 1 -
src/registrar/views/domain.py | 32 ----
src/registrar/views/domain_request.py | 15 --
9 files changed, 22 insertions(+), 238 deletions(-)
diff --git a/src/registrar/config/urls.py b/src/registrar/config/urls.py
index 413449896..7e483dc92 100644
--- a/src/registrar/config/urls.py
+++ b/src/registrar/config/urls.py
@@ -49,7 +49,6 @@ for step, view in [
(Step.CURRENT_SITES, views.CurrentSites),
(Step.DOTGOV_DOMAIN, views.DotgovDomain),
(Step.PURPOSE, views.Purpose),
- (Step.YOUR_CONTACT, views.YourContact),
(Step.OTHER_CONTACTS, views.OtherContacts),
(Step.ADDITIONAL_DETAILS, views.AdditionalDetails),
(Step.REQUIREMENTS, views.Requirements),
@@ -198,11 +197,6 @@ urlpatterns = [
views.DomainDsDataView.as_view(),
name="domain-dns-dnssec-dsdata",
),
- path(
- "domain/
/your-contact-information",
- views.DomainYourContactInformationView.as_view(),
- name="domain-your-contact-information",
- ),
path(
"domain//org-name-address",
views.DomainOrgNameAddressView.as_view(),
diff --git a/src/registrar/tests/test_admin.py b/src/registrar/tests/test_admin.py
index b6c8e7c21..f69c37947 100644
--- a/src/registrar/tests/test_admin.py
+++ b/src/registrar/tests/test_admin.py
@@ -649,7 +649,7 @@ class TestDomainInformationAdmin(TestCase):
self.test_helper.assert_response_contains_distinct_values(response, expected_other_employees_fields)
# Test for the copy link
- self.assertContains(response, "button--clipboard", count=4)
+ self.assertContains(response, "button--clipboard", count=3)
# cleanup this test
domain_info.delete()
diff --git a/src/registrar/tests/test_admin_request.py b/src/registrar/tests/test_admin_request.py
index 2bce7de7a..5a1236d49 100644
--- a/src/registrar/tests/test_admin_request.py
+++ b/src/registrar/tests/test_admin_request.py
@@ -149,7 +149,7 @@ class TestDomainRequestAdmin(MockEppLib):
# These should exist in the response
expected_values = [
- ("creator", "Person who submitted the domain request; will not receive email updates"),
+ ("creator", "Person who submitted the domain request; will receive email updates"),
("approved_domain", "Domain associated with this request; will be blank until request is approved"),
("no_other_contacts_rationale", "Required if creator does not list other employees"),
("alternative_domains", "Other domain names the creator provided for consideration"),
@@ -1397,7 +1397,7 @@ class TestDomainRequestAdmin(MockEppLib):
self.test_helper.assert_response_contains_distinct_values(response, expected_other_employees_fields)
# Test for the copy link
- self.assertContains(response, "button--clipboard", count=5)
+ self.assertContains(response, "button--clipboard", count=4)
# Test that Creator counts display properly
self.assertNotContains(response, "Approved domains")
diff --git a/src/registrar/tests/test_views.py b/src/registrar/tests/test_views.py
index 890e6ebdd..f142fb966 100644
--- a/src/registrar/tests/test_views.py
+++ b/src/registrar/tests/test_views.py
@@ -1006,20 +1006,6 @@ class UserProfileTests(TestWithUser, WebTest):
self.assertContains(response, "Your profile")
self.assertNotContains(response, "Your contact information")
- @less_console_noise_decorator
- def test_domain_your_contact_information_when_profile_feature_off(self):
- """test that Your contact information is accessible when profile_feature is off"""
- with override_flag("profile_feature", active=False):
- response = self.client.get(f"/domain/{self.domain.id}/your-contact-information", follow=True)
- self.assertContains(response, "Your contact information")
-
- @less_console_noise_decorator
- def test_domain_your_contact_information_when_profile_feature_on(self):
- """test that Your contact information is not accessible when profile feature is on"""
- with override_flag("profile_feature", active=True):
- response = self.client.get(f"/domain/{self.domain.id}/your-contact-information", follow=True)
- self.assertEqual(response.status_code, 404)
-
@less_console_noise_decorator
def test_request_when_profile_feature_on(self):
"""test that Your profile is in request page when profile feature is on"""
diff --git a/src/registrar/tests/test_views_domain.py b/src/registrar/tests/test_views_domain.py
index 3a90543a2..980a1bf12 100644
--- a/src/registrar/tests/test_views_domain.py
+++ b/src/registrar/tests/test_views_domain.py
@@ -1602,12 +1602,6 @@ class TestDomainSuborganization(TestDomainOverview):
class TestDomainContactInformation(TestDomainOverview):
- @less_console_noise_decorator
- def test_domain_your_contact_information(self):
- """Can load domain's your contact information page."""
- page = self.client.get(reverse("domain-your-contact-information", kwargs={"pk": self.domain.id}))
- self.assertContains(page, "Your contact information")
-
@less_console_noise_decorator
def test_domain_your_contact_information_content(self):
"""Logged-in user's contact information appears on the page."""
diff --git a/src/registrar/tests/test_views_request.py b/src/registrar/tests/test_views_request.py
index 1f6b50ded..fab64180f 100644
--- a/src/registrar/tests/test_views_request.py
+++ b/src/registrar/tests/test_views_request.py
@@ -7,6 +7,7 @@ from api.tests.common import less_console_noise_decorator
from .common import MockSESClient, completed_domain_request # type: ignore
from django_webtest import WebTest # type: ignore
import boto3_mocking # type: ignore
+from waffle.testutils import override_flag
from registrar.models import (
DomainRequest,
@@ -348,41 +349,13 @@ class DomainRequestTests(TestWithUser, WebTest):
# the post request should return a redirect to the next form in
# the domain request page
self.assertEqual(purpose_result.status_code, 302)
- self.assertEqual(purpose_result["Location"], "/request/your_contact/")
- num_pages_tested += 1
-
- # ---- YOUR CONTACT INFO PAGE ----
- # Follow the redirect to the next form page
- self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
- your_contact_page = purpose_result.follow()
- your_contact_form = your_contact_page.forms[0]
-
- your_contact_form["your_contact-first_name"] = "Testy you"
- your_contact_form["your_contact-last_name"] = "Tester you"
- your_contact_form["your_contact-title"] = "Admin Tester"
- your_contact_form["your_contact-email"] = "testy-admin@town.com"
- your_contact_form["your_contact-phone"] = "(201) 555 5556"
-
- # test next button
- self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
- your_contact_result = your_contact_form.submit()
- # validate that data from this step are being saved
- domain_request = DomainRequest.objects.get() # there's only one
- self.assertEqual(domain_request.creator.first_name, self.user.first_name)
- self.assertEqual(domain_request.creator.last_name, self.user.last_name)
- self.assertEqual(domain_request.creator.title, self.user.title)
- self.assertEqual(domain_request.creator.email, self.user.email)
- self.assertEqual(domain_request.creator.phone, self.user.phone)
- # the post request should return a redirect to the next form in
- # the domain request page
- self.assertEqual(your_contact_result.status_code, 302)
- self.assertEqual(your_contact_result["Location"], "/request/other_contacts/")
+ self.assertEqual(purpose_result["Location"], "/request/other_contacts/")
num_pages_tested += 1
# ---- OTHER CONTACTS PAGE ----
# Follow the redirect to the next form page
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
- other_contacts_page = your_contact_result.follow()
+ other_contacts_page = purpose_result.follow()
# This page has 3 forms in 1.
# Let's set the yes/no radios to enable the other contacts fieldsets
@@ -492,11 +465,6 @@ class DomainRequestTests(TestWithUser, WebTest):
self.assertContains(review_page, "city.gov")
self.assertContains(review_page, "city1.gov")
self.assertContains(review_page, "For all kinds of things.")
- self.assertContains(review_page, "Testy you")
- self.assertContains(review_page, "Tester you")
- self.assertContains(review_page, "Admin Tester")
- self.assertContains(review_page, "testy-admin@town.com")
- self.assertContains(review_page, "(201) 555-5556")
self.assertContains(review_page, "Testy2")
self.assertContains(review_page, "Tester2")
self.assertContains(review_page, "Another Tester")
@@ -704,41 +672,13 @@ class DomainRequestTests(TestWithUser, WebTest):
# the post request should return a redirect to the next form in
# the domain request page
self.assertEqual(purpose_result.status_code, 302)
- self.assertEqual(purpose_result["Location"], "/request/your_contact/")
- num_pages_tested += 1
-
- # ---- YOUR CONTACT INFO PAGE ----
- # Follow the redirect to the next form page
- self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
- your_contact_page = purpose_result.follow()
- your_contact_form = your_contact_page.forms[0]
-
- your_contact_form["your_contact-first_name"] = "Testy you"
- your_contact_form["your_contact-last_name"] = "Tester you"
- your_contact_form["your_contact-title"] = "Admin Tester"
- your_contact_form["your_contact-email"] = "testy-admin@town.com"
- your_contact_form["your_contact-phone"] = "(201) 555 5556"
-
- # test next button
- self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
- your_contact_result = your_contact_form.submit()
- # validate that data from this step are being saved
- domain_request = DomainRequest.objects.get() # there's only one
- self.assertEqual(domain_request.submitter.first_name, "Testy you")
- self.assertEqual(domain_request.submitter.last_name, "Tester you")
- self.assertEqual(domain_request.submitter.title, "Admin Tester")
- self.assertEqual(domain_request.submitter.email, "testy-admin@town.com")
- self.assertEqual(domain_request.submitter.phone, "(201) 555 5556")
- # the post request should return a redirect to the next form in
- # the domain request page
- self.assertEqual(your_contact_result.status_code, 302)
- self.assertEqual(your_contact_result["Location"], "/request/other_contacts/")
+ self.assertEqual(purpose_result["Location"], "/request/other_contacts/")
num_pages_tested += 1
# ---- OTHER CONTACTS PAGE ----
# Follow the redirect to the next form page
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
- other_contacts_page = your_contact_result.follow()
+ other_contacts_page = purpose_result.follow()
# This page has 3 forms in 1.
# Let's set the yes/no radios to enable the other contacts fieldsets
@@ -2264,6 +2204,7 @@ class DomainRequestTests(TestWithUser, WebTest):
senior_official = domain_request.senior_official
self.assertEquals("Testy2", senior_official.first_name)
+ @override_flag("profile_feature", active=True)
@less_console_noise_decorator
def test_edit_submitter_in_place(self):
"""When you:
@@ -2274,13 +2215,6 @@ class DomainRequestTests(TestWithUser, WebTest):
# Populate the database with a domain request that
# has a submitter
# We'll do it from scratch
- you, _ = Contact.objects.get_or_create(
- first_name="Testy",
- last_name="Tester",
- title="Chief Tester",
- email="testy@town.com",
- phone="(201) 555 5555",
- )
domain_request, _ = DomainRequest.objects.get_or_create(
generic_org_type="federal",
federal_type="executive",
@@ -2297,7 +2231,7 @@ class DomainRequestTests(TestWithUser, WebTest):
# submitter_pk is the initial pk of the submitter. set it before update
# to be able to verify after update that the same contact object is in place
- submitter_pk = you.id
+ creator_pk = self.user.id
# prime the form by visiting /edit
self.app.get(reverse("edit-domain-request", kwargs={"id": domain_request.pk}))
@@ -2308,97 +2242,25 @@ class DomainRequestTests(TestWithUser, WebTest):
session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
- your_contact_page = self.app.get(reverse("domain-request:your_contact"))
+ profile_page = self.app.get(f"/user-profile")
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
- your_contact_form = your_contact_page.forms[0]
+ profile_form = profile_page.forms[0]
# Minimal check to ensure the form is loaded
- self.assertEqual(your_contact_form["your_contact-first_name"].value, "Testy")
+ self.assertEqual(profile_form["first_name"].value, self.user.first_name)
# update the first name of the contact
- your_contact_form["your_contact-first_name"] = "Testy2"
+ profile_form["first_name"] = "Testy2"
# Submit the updated form
- your_contact_form.submit()
+ profile_form.submit()
domain_request.refresh_from_db()
- updated_submitter = domain_request.submitter
- self.assertEquals(submitter_pk, updated_submitter.id)
- self.assertEquals("Testy2", updated_submitter.first_name)
-
- @less_console_noise_decorator
- def test_edit_submitter_creates_new(self):
- """When you:
- 1. edit an existing your contact which IS joined to another model,
- 2. then submit,
- the domain request is linked to a new Contact, and the new Contact is updated."""
-
- # Populate the database with a domain request that
- # has submitter assigned to it, the submitter is also
- # an other contact initially
- # We'll do it from scratch
- submitter, _ = Contact.objects.get_or_create(
- first_name="Testy",
- last_name="Tester",
- title="Chief Tester",
- email="testy@town.com",
- phone="(201) 555 5555",
- )
- domain_request, _ = DomainRequest.objects.get_or_create(
- generic_org_type="federal",
- federal_type="executive",
- purpose="Purpose of the site",
- anything_else="No",
- is_policy_acknowledged=True,
- organization_name="Testorg",
- address_line1="address 1",
- state_territory="NY",
- zipcode="10002",
- creator=self.user,
- status="started",
- )
- domain_request.other_contacts.add(submitter)
-
- # submitter_pk is the initial pk of the your contact. set it before update
- # to be able to verify after update that the other contact is still in place
- # and not updated, and that the new submitter has a new id
- submitter_pk = submitter.id
-
- # prime the form by visiting /edit
- self.app.get(reverse("edit-domain-request", kwargs={"id": domain_request.pk}))
- # django-webtest does not handle cookie-based sessions well because it keeps
- # resetting the session key on each new request, thus destroying the concept
- # of a "session". We are going to do it manually, saving the session ID here
- # and then setting the cookie on each request.
- session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
- self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
-
- your_contact_page = self.app.get(reverse("domain-request:your_contact"))
- self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
-
- your_contact_form = your_contact_page.forms[0]
-
- # Minimal check to ensure the form is loaded
- self.assertEqual(your_contact_form["your_contact-first_name"].value, "Testy")
-
- # update the first name of the contact
- your_contact_form["your_contact-first_name"] = "Testy2"
-
- # Submit the updated form
- your_contact_form.submit()
-
- domain_request.refresh_from_db()
-
- # assert that the other contact is not updated
- other_contacts = domain_request.other_contacts.all()
- other_contact = other_contacts[0]
- self.assertEquals(submitter_pk, other_contact.id)
- self.assertEquals("Testy", other_contact.first_name)
- # assert that the submitter is updated
- submitter = domain_request.submitter
- self.assertEquals("Testy2", submitter.first_name)
+ updated_creator = domain_request.creator
+ self.assertEquals(creator_pk, updated_creator.id)
+ self.assertEquals("Testy2", updated_creator.first_name)
@less_console_noise_decorator
def test_domain_request_about_your_organiztion_interstate(self):
@@ -2865,7 +2727,6 @@ class DomainRequestTestDifferentStatuses(TestWithUser, WebTest):
self.assertContains(detail_page, "city1.gov")
self.assertContains(detail_page, "Chief Tester")
self.assertContains(detail_page, "testy@town.com")
- self.assertContains(detail_page, "Admin Tester")
self.assertContains(detail_page, "Status:")
@less_console_noise_decorator
@@ -2882,7 +2743,6 @@ class DomainRequestTestDifferentStatuses(TestWithUser, WebTest):
self.assertContains(detail_page, "city.gov")
self.assertContains(detail_page, "Chief Tester")
self.assertContains(detail_page, "testy@town.com")
- self.assertContains(detail_page, "Admin Tester")
self.assertContains(detail_page, "Status:")
@less_console_noise_decorator
@@ -2896,7 +2756,6 @@ class DomainRequestTestDifferentStatuses(TestWithUser, WebTest):
self.assertContains(detail_page, "city1.gov")
self.assertContains(detail_page, "Chief Tester")
self.assertContains(detail_page, "testy@town.com")
- self.assertContains(detail_page, "Admin Tester")
self.assertContains(detail_page, "Status:")
# click the "Withdraw request" button
mock_client = MockSESClient()
@@ -2929,7 +2788,6 @@ class DomainRequestTestDifferentStatuses(TestWithUser, WebTest):
self.assertContains(detail_page, "city1.gov")
self.assertContains(detail_page, "Chief Tester")
self.assertContains(detail_page, "testy@town.com")
- self.assertContains(detail_page, "Admin Tester")
self.assertContains(detail_page, "Status:")
# Restricted user trying to withdraw results in 403 error
with less_console_noise():
@@ -3028,10 +2886,10 @@ class TestWizardUnlockingSteps(TestWithUser, WebTest):
self.assertEqual(detail_page.status_code, 200)
# 10 unlocked steps, one active step, the review step will have link_usa but not check_circle
- self.assertContains(detail_page, "#check_circle", count=10)
+ self.assertContains(detail_page, "#check_circle", count=9)
# Type of organization
self.assertContains(detail_page, "usa-current", count=1)
- self.assertContains(detail_page, "link_usa-checked", count=11)
+ self.assertContains(detail_page, "link_usa-checked", count=10)
else:
self.fail(f"Expected a redirect, but got a different response: {response}")
@@ -3090,10 +2948,10 @@ class TestWizardUnlockingSteps(TestWithUser, WebTest):
# 5 unlocked steps (so, domain, submitter, other contacts, and current sites
# which unlocks if domain exists), one active step, the review step is locked
- self.assertContains(detail_page, "#check_circle", count=5)
+ self.assertContains(detail_page, "#check_circle", count=4)
# Type of organization
self.assertContains(detail_page, "usa-current", count=1)
- self.assertContains(detail_page, "link_usa-checked", count=5)
+ self.assertContains(detail_page, "link_usa-checked", count=4)
else:
self.fail(f"Expected a redirect, but got a different response: {response}")
diff --git a/src/registrar/views/__init__.py b/src/registrar/views/__init__.py
index f6e87dd07..2c42263d3 100644
--- a/src/registrar/views/__init__.py
+++ b/src/registrar/views/__init__.py
@@ -8,7 +8,6 @@ from .domain import (
DomainNameserversView,
DomainDNSSECView,
DomainDsDataView,
- DomainYourContactInformationView,
DomainSecurityEmailView,
DomainUsersView,
DomainAddUserView,
diff --git a/src/registrar/views/domain.py b/src/registrar/views/domain.py
index 72f2fd27e..4de2ad31e 100644
--- a/src/registrar/views/domain.py
+++ b/src/registrar/views/domain.py
@@ -637,38 +637,6 @@ class DomainDsDataView(DomainFormBaseView):
return super().form_valid(formset)
-class DomainYourContactInformationView(DomainFormBaseView):
- """Domain your contact information editing view."""
-
- template_name = "domain_your_contact_information.html"
- form_class = UserForm
-
- @waffle_flag("!profile_feature") # type: ignore
- def dispatch(self, request, *args, **kwargs): # type: ignore
- return super().dispatch(request, *args, **kwargs)
-
- def get_form_kwargs(self, *args, **kwargs):
- """Add domain_info.submitter instance to make a bound form."""
- form_kwargs = super().get_form_kwargs(*args, **kwargs)
- form_kwargs["instance"] = self.request.user
- return form_kwargs
-
- def get_success_url(self):
- """Redirect to the your contact information for the domain."""
- return reverse("domain-your-contact-information", kwargs={"pk": self.object.pk})
-
- def form_valid(self, form):
- """The form is valid, call setter in model."""
-
- # Post to DB using values from the form
- form.save()
-
- messages.success(self.request, "Your contact information for all your domains has been updated.")
-
- # superclass has the redirect
- return super().form_valid(form)
-
-
class DomainSecurityEmailView(DomainFormBaseView):
"""Domain security email editing view."""
diff --git a/src/registrar/views/domain_request.py b/src/registrar/views/domain_request.py
index 45c0c3ddb..220cfcae1 100644
--- a/src/registrar/views/domain_request.py
+++ b/src/registrar/views/domain_request.py
@@ -45,7 +45,6 @@ class Step(StrEnum):
CURRENT_SITES = "current_sites"
DOTGOV_DOMAIN = "dotgov_domain"
PURPOSE = "purpose"
- YOUR_CONTACT = "your_contact"
OTHER_CONTACTS = "other_contacts"
ADDITIONAL_DETAILS = "additional_details"
REQUIREMENTS = "requirements"
@@ -91,7 +90,6 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView):
Step.CURRENT_SITES: _("Current websites"),
Step.DOTGOV_DOMAIN: _(".gov domain"),
Step.PURPOSE: _("Purpose of your domain"),
- Step.YOUR_CONTACT: _("Your contact information"),
Step.OTHER_CONTACTS: _("Other employees from your organization"),
Step.ADDITIONAL_DETAILS: _("Additional details"),
Step.REQUIREMENTS: _("Requirements for operating a .gov domain"),
@@ -375,7 +373,6 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView):
),
"dotgov_domain": self.domain_request.requested_domain is not None,
"purpose": self.domain_request.purpose is not None,
- "your_contact": self.domain_request.creator is not None,
"other_contacts": (
self.domain_request.other_contacts.exists()
or self.domain_request.no_other_contacts_rationale is not None
@@ -439,9 +436,6 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView):
if condition:
step_list.append(step)
- if flag_is_active(self.request, "profile_feature"):
- step_list.remove(Step.YOUR_CONTACT)
-
return step_list
def goto(self, step):
@@ -582,15 +576,6 @@ class Purpose(DomainRequestWizard):
forms = [forms.PurposeForm]
-class YourContact(DomainRequestWizard):
- template_name = "domain_request_your_contact.html"
- forms = [forms.YourContactForm]
-
- @waffle_flag("!profile_feature") # type: ignore
- def dispatch(self, request, *args, **kwargs): # type: ignore
- return super().dispatch(request, *args, **kwargs)
-
-
class OtherContacts(DomainRequestWizard):
template_name = "domain_request_other_contacts.html"
forms = [forms.OtherContactsYesNoForm, forms.OtherContactsFormSet, forms.NoOtherContactsForm]
From 11e44a326ab3ada8d58b0a51e822fa7a822ff3be Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Tue, 27 Aug 2024 16:04:15 -0700
Subject: [PATCH 005/150] Remove test_is_creator_complete test
---
src/registrar/tests/test_models.py | 7 -------
1 file changed, 7 deletions(-)
diff --git a/src/registrar/tests/test_models.py b/src/registrar/tests/test_models.py
index 5e8dbc80b..f4dd14ae0 100644
--- a/src/registrar/tests/test_models.py
+++ b/src/registrar/tests/test_models.py
@@ -1997,13 +1997,6 @@ class TestDomainRequestIncomplete(TestCase):
self.domain_request.save()
self.assertFalse(self.domain_request._is_purpose_complete())
- @less_console_noise_decorator
- def test_is_creator_complete(self):
- self.assertTrue(self.domain_request._is_creator_complete())
- self.domain_request.creator = None
- self.domain_request.save()
- self.assertFalse(self.domain_request._is_creator_complete())
-
@less_console_noise_decorator
def test_is_other_contacts_complete_missing_one_field(self):
self.assertTrue(self.domain_request._is_other_contacts_complete())
From 9a83287c6ecde9869cd5b38bf9e5114a82baba02 Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Tue, 27 Aug 2024 16:07:58 -0700
Subject: [PATCH 006/150] Remove test
test_home_deletes_domain_request_and_orphans
---
src/registrar/tests/test_views.py | 71 -------------------------------
1 file changed, 71 deletions(-)
diff --git a/src/registrar/tests/test_views.py b/src/registrar/tests/test_views.py
index f142fb966..cb340d444 100644
--- a/src/registrar/tests/test_views.py
+++ b/src/registrar/tests/test_views.py
@@ -349,77 +349,6 @@ class HomeTests(TestWithUser):
# clean up
domain_request.delete()
- @less_console_noise_decorator
- def test_home_deletes_domain_request_and_orphans(self):
- """Tests if delete for DomainRequest deletes orphaned Contact objects"""
-
- # Create the site and contacts to delete (orphaned)
- contact = Contact.objects.create(
- first_name="Henry",
- last_name="Mcfakerson",
- )
- contact_shared = Contact.objects.create(
- first_name="Relative",
- last_name="Aether",
- )
-
- # Create two non-orphaned contacts
- contact_2 = Contact.objects.create(
- first_name="Saturn",
- last_name="Mars",
- )
-
- # Attach a user object to a contact (should not be deleted)
- contact_user, _ = Contact.objects.get_or_create(
- first_name="Hank",
- last_name="McFakey",
- )
-
- site = DraftDomain.objects.create(name="igorville.gov")
- domain_request = DomainRequest.objects.create(
- creator=self.user,
- requested_domain=site,
- status=DomainRequest.DomainRequestStatus.WITHDRAWN,
- senior_official=contact,
- )
- domain_request.other_contacts.set([contact_2])
-
- # Create a second domain request to attach contacts to
- site_2 = DraftDomain.objects.create(name="teaville.gov")
- domain_request_2 = DomainRequest.objects.create(
- creator=self.user,
- requested_domain=site_2,
- status=DomainRequest.DomainRequestStatus.STARTED,
- senior_official=contact_2,
- )
- domain_request_2.other_contacts.set([contact_shared])
-
- igorville = DomainRequest.objects.filter(requested_domain__name="igorville.gov")
- self.assertTrue(igorville.exists())
-
- # Trigger the delete logic
- self.client.post(reverse("domain-request-delete", kwargs={"pk": domain_request.pk}))
-
- # igorville is now deleted
- igorville = DomainRequest.objects.filter(requested_domain__name="igorville.gov")
- self.assertFalse(igorville.exists())
-
- # Check if the orphaned contacts were deleted
- orphan = Contact.objects.filter(id=contact.id)
- self.assertFalse(orphan.exists())
- orphan = Contact.objects.filter(id=contact_user.id)
- self.assertFalse(orphan.exists())
-
- try:
- edge_case = Contact.objects.filter(id=contact_2.id).get()
- except Contact.DoesNotExist:
- self.fail("contact_2 (a non-orphaned contact) was deleted")
-
- self.assertEqual(edge_case, contact_2)
-
- DomainRequest.objects.all().delete()
- Contact.objects.all().delete()
-
@less_console_noise_decorator
def test_home_deletes_domain_request_and_shared_orphans(self):
"""Test the edge case for an object that will become orphaned after a delete
From d0b3dd7c4681a93b02aa22105d4d136e52ac3b42 Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Tue, 27 Aug 2024 16:09:57 -0700
Subject: [PATCH 007/150] Delete test_home_deletes_domain_request_and_orphans
---
src/registrar/tests/test_views.py | 62 -------------------------------
1 file changed, 62 deletions(-)
diff --git a/src/registrar/tests/test_views.py b/src/registrar/tests/test_views.py
index cb340d444..4e5553976 100644
--- a/src/registrar/tests/test_views.py
+++ b/src/registrar/tests/test_views.py
@@ -349,68 +349,6 @@ class HomeTests(TestWithUser):
# clean up
domain_request.delete()
- @less_console_noise_decorator
- def test_home_deletes_domain_request_and_shared_orphans(self):
- """Test the edge case for an object that will become orphaned after a delete
- (but is not an orphan at the time of deletion)"""
-
- # Create the site and contacts to delete (orphaned)
- contact = Contact.objects.create(
- first_name="Henry",
- last_name="Mcfakerson",
- )
- contact_shared = Contact.objects.create(
- first_name="Relative",
- last_name="Aether",
- )
-
- # Create two non-orphaned contacts
- contact_2 = Contact.objects.create(
- first_name="Saturn",
- last_name="Mars",
- )
-
- # Attach a user object to a contact (should not be deleted)
- contact_user, _ = Contact.objects.get_or_create(
- first_name="Hank",
- last_name="McFakey",
- )
-
- site = DraftDomain.objects.create(name="igorville.gov")
- domain_request = DomainRequest.objects.create(
- creator=self.user,
- requested_domain=site,
- status=DomainRequest.DomainRequestStatus.WITHDRAWN,
- senior_official=contact,
- )
- domain_request.other_contacts.set([contact_2])
-
- # Create a second domain request to attach contacts to
- site_2 = DraftDomain.objects.create(name="teaville.gov")
- domain_request_2 = DomainRequest.objects.create(
- creator=self.user,
- requested_domain=site_2,
- status=DomainRequest.DomainRequestStatus.STARTED,
- senior_official=contact_2,
- )
- domain_request_2.other_contacts.set([contact_shared])
-
- teaville = DomainRequest.objects.filter(requested_domain__name="teaville.gov")
- self.assertTrue(teaville.exists())
-
- # Trigger the delete logic
- self.client.post(reverse("domain-request-delete", kwargs={"pk": domain_request_2.pk}))
-
- teaville = DomainRequest.objects.filter(requested_domain__name="teaville.gov")
- self.assertFalse(teaville.exists())
-
- # Check if the orphaned contact was deleted
- orphan = Contact.objects.filter(id=contact_shared.id)
- self.assertFalse(orphan.exists())
-
- DomainRequest.objects.all().delete()
- Contact.objects.all().delete()
-
@less_console_noise_decorator
def test_domain_request_form_view(self):
response = self.client.get("/request/", follow=True)
From 2c43533441075088446cbe8b0108055d20e6462d Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Tue, 27 Aug 2024 16:46:30 -0700
Subject: [PATCH 008/150] Remove submitter from deleting orphaned contacts
---
src/registrar/tests/test_views.py | 133 +++++++++++++++++++++++
src/registrar/tests/test_views_domain.py | 13 ---
src/registrar/views/domain_request.py | 4 +-
3 files changed, 134 insertions(+), 16 deletions(-)
diff --git a/src/registrar/tests/test_views.py b/src/registrar/tests/test_views.py
index 4e5553976..f142fb966 100644
--- a/src/registrar/tests/test_views.py
+++ b/src/registrar/tests/test_views.py
@@ -349,6 +349,139 @@ class HomeTests(TestWithUser):
# clean up
domain_request.delete()
+ @less_console_noise_decorator
+ def test_home_deletes_domain_request_and_orphans(self):
+ """Tests if delete for DomainRequest deletes orphaned Contact objects"""
+
+ # Create the site and contacts to delete (orphaned)
+ contact = Contact.objects.create(
+ first_name="Henry",
+ last_name="Mcfakerson",
+ )
+ contact_shared = Contact.objects.create(
+ first_name="Relative",
+ last_name="Aether",
+ )
+
+ # Create two non-orphaned contacts
+ contact_2 = Contact.objects.create(
+ first_name="Saturn",
+ last_name="Mars",
+ )
+
+ # Attach a user object to a contact (should not be deleted)
+ contact_user, _ = Contact.objects.get_or_create(
+ first_name="Hank",
+ last_name="McFakey",
+ )
+
+ site = DraftDomain.objects.create(name="igorville.gov")
+ domain_request = DomainRequest.objects.create(
+ creator=self.user,
+ requested_domain=site,
+ status=DomainRequest.DomainRequestStatus.WITHDRAWN,
+ senior_official=contact,
+ )
+ domain_request.other_contacts.set([contact_2])
+
+ # Create a second domain request to attach contacts to
+ site_2 = DraftDomain.objects.create(name="teaville.gov")
+ domain_request_2 = DomainRequest.objects.create(
+ creator=self.user,
+ requested_domain=site_2,
+ status=DomainRequest.DomainRequestStatus.STARTED,
+ senior_official=contact_2,
+ )
+ domain_request_2.other_contacts.set([contact_shared])
+
+ igorville = DomainRequest.objects.filter(requested_domain__name="igorville.gov")
+ self.assertTrue(igorville.exists())
+
+ # Trigger the delete logic
+ self.client.post(reverse("domain-request-delete", kwargs={"pk": domain_request.pk}))
+
+ # igorville is now deleted
+ igorville = DomainRequest.objects.filter(requested_domain__name="igorville.gov")
+ self.assertFalse(igorville.exists())
+
+ # Check if the orphaned contacts were deleted
+ orphan = Contact.objects.filter(id=contact.id)
+ self.assertFalse(orphan.exists())
+ orphan = Contact.objects.filter(id=contact_user.id)
+ self.assertFalse(orphan.exists())
+
+ try:
+ edge_case = Contact.objects.filter(id=contact_2.id).get()
+ except Contact.DoesNotExist:
+ self.fail("contact_2 (a non-orphaned contact) was deleted")
+
+ self.assertEqual(edge_case, contact_2)
+
+ DomainRequest.objects.all().delete()
+ Contact.objects.all().delete()
+
+ @less_console_noise_decorator
+ def test_home_deletes_domain_request_and_shared_orphans(self):
+ """Test the edge case for an object that will become orphaned after a delete
+ (but is not an orphan at the time of deletion)"""
+
+ # Create the site and contacts to delete (orphaned)
+ contact = Contact.objects.create(
+ first_name="Henry",
+ last_name="Mcfakerson",
+ )
+ contact_shared = Contact.objects.create(
+ first_name="Relative",
+ last_name="Aether",
+ )
+
+ # Create two non-orphaned contacts
+ contact_2 = Contact.objects.create(
+ first_name="Saturn",
+ last_name="Mars",
+ )
+
+ # Attach a user object to a contact (should not be deleted)
+ contact_user, _ = Contact.objects.get_or_create(
+ first_name="Hank",
+ last_name="McFakey",
+ )
+
+ site = DraftDomain.objects.create(name="igorville.gov")
+ domain_request = DomainRequest.objects.create(
+ creator=self.user,
+ requested_domain=site,
+ status=DomainRequest.DomainRequestStatus.WITHDRAWN,
+ senior_official=contact,
+ )
+ domain_request.other_contacts.set([contact_2])
+
+ # Create a second domain request to attach contacts to
+ site_2 = DraftDomain.objects.create(name="teaville.gov")
+ domain_request_2 = DomainRequest.objects.create(
+ creator=self.user,
+ requested_domain=site_2,
+ status=DomainRequest.DomainRequestStatus.STARTED,
+ senior_official=contact_2,
+ )
+ domain_request_2.other_contacts.set([contact_shared])
+
+ teaville = DomainRequest.objects.filter(requested_domain__name="teaville.gov")
+ self.assertTrue(teaville.exists())
+
+ # Trigger the delete logic
+ self.client.post(reverse("domain-request-delete", kwargs={"pk": domain_request_2.pk}))
+
+ teaville = DomainRequest.objects.filter(requested_domain__name="teaville.gov")
+ self.assertFalse(teaville.exists())
+
+ # Check if the orphaned contact was deleted
+ orphan = Contact.objects.filter(id=contact_shared.id)
+ self.assertFalse(orphan.exists())
+
+ DomainRequest.objects.all().delete()
+ Contact.objects.all().delete()
+
@less_console_noise_decorator
def test_domain_request_form_view(self):
response = self.client.get("/request/", follow=True)
diff --git a/src/registrar/tests/test_views_domain.py b/src/registrar/tests/test_views_domain.py
index 980a1bf12..1da73087e 100644
--- a/src/registrar/tests/test_views_domain.py
+++ b/src/registrar/tests/test_views_domain.py
@@ -159,7 +159,6 @@ class TestDomainPermissions(TestWithDomainPermissions):
"domain-dns-nameservers",
"domain-org-name-address",
"domain-senior-official",
- "domain-your-contact-information",
"domain-security-email",
]:
with self.subTest(view_name=view_name):
@@ -179,7 +178,6 @@ class TestDomainPermissions(TestWithDomainPermissions):
"domain-dns-nameservers",
"domain-org-name-address",
"domain-senior-official",
- "domain-your-contact-information",
"domain-security-email",
]:
with self.subTest(view_name=view_name):
@@ -200,7 +198,6 @@ class TestDomainPermissions(TestWithDomainPermissions):
"domain-dns-dnssec-dsdata",
"domain-org-name-address",
"domain-senior-official",
- "domain-your-contact-information",
"domain-security-email",
]:
for domain in [
@@ -1601,16 +1598,6 @@ class TestDomainSuborganization(TestDomainOverview):
portfolio.delete()
-class TestDomainContactInformation(TestDomainOverview):
- @less_console_noise_decorator
- def test_domain_your_contact_information_content(self):
- """Logged-in user's contact information appears on the page."""
- self.user.first_name = "Testy"
- self.user.save()
- page = self.app.get(reverse("domain-your-contact-information", kwargs={"pk": self.domain.id}))
- self.assertContains(page, "Testy")
-
-
class TestDomainSecurityEmail(TestDomainOverview):
def test_domain_security_email_existing_security_contact(self):
"""Can load domain's security email page."""
diff --git a/src/registrar/views/domain_request.py b/src/registrar/views/domain_request.py
index 220cfcae1..05f4e38ff 100644
--- a/src/registrar/views/domain_request.py
+++ b/src/registrar/views/domain_request.py
@@ -827,18 +827,16 @@ class DomainRequestDeleteView(DomainRequestPermissionDeleteView):
# Get each contact object on the DomainRequest object
so = domain_request.senior_official
- creator = domain_request.creator
other_contacts = list(domain_request.other_contacts.all())
other_contact_ids = domain_request.other_contacts.all().values_list("id", flat=True)
# Check if the desired item still exists in the DB
if check_db:
so = self._get_contacts_by_id([so.id]).first() if so is not None else None
- creator = self._get_contacts_by_id([creator.id]).first() if creator is not None else None
other_contacts = self._get_contacts_by_id(other_contact_ids)
# Pair each contact with its db related name for use in checking if it has joins
- checked_contacts = [(so, "senior_official"), (creator, "submitted_domain_requests")]
+ checked_contacts = [(so, "senior_official")]
checked_contacts.extend((contact, "contact_domain_requests") for contact in other_contacts)
for contact, related_name in checked_contacts:
From 06ef54f0319d8f6f85f04cf0d43331e24b92dbef Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Tue, 27 Aug 2024 17:16:52 -0700
Subject: [PATCH 009/150] Delete outdated contact join tests
---
src/registrar/tests/common.py | 9 +---
src/registrar/tests/test_admin.py | 85 -------------------------------
2 files changed, 1 insertion(+), 93 deletions(-)
diff --git a/src/registrar/tests/common.py b/src/registrar/tests/common.py
index 40d5108f4..ea2462dfb 100644
--- a/src/registrar/tests/common.py
+++ b/src/registrar/tests/common.py
@@ -918,14 +918,7 @@ def completed_domain_request( # noqa
domain, _ = DraftDomain.objects.get_or_create(name=name)
alt, _ = Website.objects.get_or_create(website="city1.gov")
current, _ = Website.objects.get_or_create(website="city.com")
- # if not creator:
- # creator, _ = Contact.objects.get_or_create(
- # first_name="Testy2",
- # last_name="Tester2",
- # title="Admin Tester",
- # email="mayor@igorville.gov",
- # phone="(555) 555 5556",
- # )
+ creator = user
other, _ = Contact.objects.get_or_create(
first_name="Testy",
last_name="Tester",
diff --git a/src/registrar/tests/test_admin.py b/src/registrar/tests/test_admin.py
index f69c37947..4cce3ed14 100644
--- a/src/registrar/tests/test_admin.py
+++ b/src/registrar/tests/test_admin.py
@@ -1653,91 +1653,6 @@ class TestContactAdmin(TestCase):
self.assertEqual(readonly_fields, expected_fields)
- def test_change_view_for_joined_contact_five_or_less(self):
- """Create a contact, join it to 4 domain requests.
- Assert that the warning on the contact form lists 4 joins."""
- with less_console_noise():
- self.client.force_login(self.superuser)
-
- # Create an instance of the model
- contact, _ = Contact.objects.get_or_create(
- first_name="Henry",
- last_name="McFakerson",
- )
-
- # join it to 4 domain requests.
- domain_request1 = completed_domain_request(name="city1.gov")
- domain_request2 = completed_domain_request(name="city2.gov")
- domain_request3 = completed_domain_request(name="city3.gov")
- domain_request4 = completed_domain_request(name="city4.gov")
-
- with patch("django.contrib.messages.warning") as mock_warning:
- # Use the test client to simulate the request
- response = self.client.get(reverse("admin:registrar_contact_change", args=[contact.pk]))
-
- # Assert that the error message was called with the correct argument
- # Note: The 5th join will be a user.
- mock_warning.assert_called_once_with(
- response.wsgi_request,
- ""
- "Joined to DomainRequest: city1.gov "
- "Joined to DomainRequest: city2.gov "
- "Joined to DomainRequest: city3.gov "
- "Joined to DomainRequest: city4.gov "
- " ",
- )
-
- # cleanup this test
- DomainRequest.objects.all().delete()
- contact.delete()
-
- def test_change_view_for_joined_contact_five_or_more(self):
- """Create a contact, join it to 6 domain requests.
- Assert that the warning on the contact form lists 5 joins and a '1 more' ellispsis."""
- with less_console_noise():
- self.client.force_login(self.superuser)
- # Create an instance of the model
- # join it to 6 domain requests.
- contact, _ = Contact.objects.get_or_create(
- first_name="Henry",
- last_name="McFakerson",
- )
- domain_request1 = completed_domain_request(name="city1.gov")
- domain_request2 = completed_domain_request(name="city2.gov")
- domain_request3 = completed_domain_request(name="city3.gov")
- domain_request4 = completed_domain_request(name="city4.gov")
- domain_request5 = completed_domain_request(name="city5.gov")
- completed_domain_request(name="city6.gov")
- with patch("django.contrib.messages.warning") as mock_warning:
- # Use the test client to simulate the request
- response = self.client.get(reverse("admin:registrar_contact_change", args=[contact.pk]))
- logger.debug(mock_warning)
- # Assert that the error message was called with the correct argument
- # Note: The 6th join will be a user.
- mock_warning.assert_called_once_with(
- response.wsgi_request,
- ""
- "Joined to DomainRequest: city1.gov "
- "Joined to DomainRequest: city2.gov "
- "Joined to DomainRequest: city3.gov "
- "Joined to DomainRequest: city4.gov "
- "Joined to DomainRequest: city5.gov "
- " "
- "And 1 more...
",
- )
- # cleanup this test
- DomainRequest.objects.all().delete()
- contact.delete()
-
class TestVerifiedByStaffAdmin(TestCase):
From 804d19f30eb6c1be39f99e34dfe993b572d6dfef Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Tue, 27 Aug 2024 17:43:08 -0700
Subject: [PATCH 010/150] remove submitter from orphan tests
---
src/registrar/tests/test_admin_request.py | 4 +++-
src/registrar/tests/test_emails.py | 1 -
src/registrar/tests/test_views.py | 22 ----------------------
3 files changed, 3 insertions(+), 24 deletions(-)
diff --git a/src/registrar/tests/test_admin_request.py b/src/registrar/tests/test_admin_request.py
index 5a1236d49..5b688343a 100644
--- a/src/registrar/tests/test_admin_request.py
+++ b/src/registrar/tests/test_admin_request.py
@@ -35,6 +35,7 @@ from .common import (
GenericTestHelper,
)
from unittest.mock import patch
+from waffle.testutils import override_flag
from django.conf import settings
import boto3_mocking # type: ignore
@@ -149,7 +150,7 @@ class TestDomainRequestAdmin(MockEppLib):
# These should exist in the response
expected_values = [
- ("creator", "Person who submitted the domain request; will receive email updates"),
+ ("creator", "Person who submitted the domain request. Will receive email updates"),
("approved_domain", "Domain associated with this request; will be blank until request is approved"),
("no_other_contacts_rationale", "Required if creator does not list other employees"),
("alternative_domains", "Other domain names the creator provided for consideration"),
@@ -894,6 +895,7 @@ class TestDomainRequestAdmin(MockEppLib):
self.transition_state_and_send_email(domain_request, DomainRequest.DomainRequestStatus.SUBMITTED)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 3)
+ @override_flag("profile_feature", True)
@less_console_noise_decorator
def test_save_model_sends_approved_email(self):
"""When transitioning to approved on a domain request,
diff --git a/src/registrar/tests/test_emails.py b/src/registrar/tests/test_emails.py
index 8cf707004..cc8b0c4b1 100644
--- a/src/registrar/tests/test_emails.py
+++ b/src/registrar/tests/test_emails.py
@@ -69,7 +69,6 @@ class TestEmails(TestCase):
# check for optional things
self.assertIn("Other employees from your organization:", body)
- self.assertIn("Testy2 Tester2", body)
self.assertIn("Current websites:", body)
self.assertIn("city.com", body)
self.assertIn("About your organization:", body)
diff --git a/src/registrar/tests/test_views.py b/src/registrar/tests/test_views.py
index f142fb966..8b2743059 100644
--- a/src/registrar/tests/test_views.py
+++ b/src/registrar/tests/test_views.py
@@ -358,10 +358,6 @@ class HomeTests(TestWithUser):
first_name="Henry",
last_name="Mcfakerson",
)
- contact_shared = Contact.objects.create(
- first_name="Relative",
- last_name="Aether",
- )
# Create two non-orphaned contacts
contact_2 = Contact.objects.create(
@@ -369,12 +365,6 @@ class HomeTests(TestWithUser):
last_name="Mars",
)
- # Attach a user object to a contact (should not be deleted)
- contact_user, _ = Contact.objects.get_or_create(
- first_name="Hank",
- last_name="McFakey",
- )
-
site = DraftDomain.objects.create(name="igorville.gov")
domain_request = DomainRequest.objects.create(
creator=self.user,
@@ -407,8 +397,6 @@ class HomeTests(TestWithUser):
# Check if the orphaned contacts were deleted
orphan = Contact.objects.filter(id=contact.id)
self.assertFalse(orphan.exists())
- orphan = Contact.objects.filter(id=contact_user.id)
- self.assertFalse(orphan.exists())
try:
edge_case = Contact.objects.filter(id=contact_2.id).get()
@@ -430,10 +418,6 @@ class HomeTests(TestWithUser):
first_name="Henry",
last_name="Mcfakerson",
)
- contact_shared = Contact.objects.create(
- first_name="Relative",
- last_name="Aether",
- )
# Create two non-orphaned contacts
contact_2 = Contact.objects.create(
@@ -441,12 +425,6 @@ class HomeTests(TestWithUser):
last_name="Mars",
)
- # Attach a user object to a contact (should not be deleted)
- contact_user, _ = Contact.objects.get_or_create(
- first_name="Hank",
- last_name="McFakey",
- )
-
site = DraftDomain.objects.create(name="igorville.gov")
domain_request = DomainRequest.objects.create(
creator=self.user,
From 29de97d5321a5de823db6aecf04a04acf7f6e28a Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Tue, 27 Aug 2024 17:43:58 -0700
Subject: [PATCH 011/150] Revert deleted contact shared
---
src/registrar/tests/test_views.py | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/src/registrar/tests/test_views.py b/src/registrar/tests/test_views.py
index 8b2743059..ebe0abb59 100644
--- a/src/registrar/tests/test_views.py
+++ b/src/registrar/tests/test_views.py
@@ -358,6 +358,10 @@ class HomeTests(TestWithUser):
first_name="Henry",
last_name="Mcfakerson",
)
+ contact_shared = Contact.objects.create(
+ first_name="Relative",
+ last_name="Aether",
+ )
# Create two non-orphaned contacts
contact_2 = Contact.objects.create(
@@ -425,6 +429,12 @@ class HomeTests(TestWithUser):
last_name="Mars",
)
+ # Attach a user object to a contact (should not be deleted)
+ contact_user, _ = Contact.objects.get_or_create(
+ first_name="Hank",
+ last_name="McFakey",
+ )
+
site = DraftDomain.objects.create(name="igorville.gov")
domain_request = DomainRequest.objects.create(
creator=self.user,
From 5b3ae28b88c001cf8fbe289a40ff14012e0d6b72 Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Tue, 27 Aug 2024 17:49:04 -0700
Subject: [PATCH 012/150] Restore variable in orphan tests
---
src/registrar/tests/test_views.py | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/registrar/tests/test_views.py b/src/registrar/tests/test_views.py
index ebe0abb59..2ae582b0e 100644
--- a/src/registrar/tests/test_views.py
+++ b/src/registrar/tests/test_views.py
@@ -422,6 +422,10 @@ class HomeTests(TestWithUser):
first_name="Henry",
last_name="Mcfakerson",
)
+ contact_shared = Contact.objects.create(
+ first_name="Relative",
+ last_name="Aether",
+ )
# Create two non-orphaned contacts
contact_2 = Contact.objects.create(
From 2fcad733cd405d214b2a129eef201366fe04cbd5 Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Tue, 27 Aug 2024 18:16:40 -0700
Subject: [PATCH 013/150] Update email status tests
---
src/registrar/tests/test_admin_request.py | 229 ++++++++++++++--------
1 file changed, 150 insertions(+), 79 deletions(-)
diff --git a/src/registrar/tests/test_admin_request.py b/src/registrar/tests/test_admin_request.py
index 5b688343a..397de21db 100644
--- a/src/registrar/tests/test_admin_request.py
+++ b/src/registrar/tests/test_admin_request.py
@@ -627,28 +627,35 @@ class TestDomainRequestAdmin(MockEppLib):
def test_action_needed_sends_reason_email_prod_bcc(self):
"""When an action needed reason is set, an email is sent out and help@get.gov
is BCC'd in production"""
- # Ensure there is no user with this email
- EMAIL = "mayor@igorville.gov"
+ # Create fake creator
+ _creator = User.objects.create(
+ username="MrMeoward",
+ first_name="Meoward",
+ last_name="Jones",
+ email="meoward.jones@igorville.gov",
+ phone="(555) 123 12345",
+ title="Treat inspector",
+ )
+
BCC_EMAIL = settings.DEFAULT_FROM_EMAIL
- User.objects.filter(email=EMAIL).delete()
in_review = DomainRequest.DomainRequestStatus.IN_REVIEW
action_needed = DomainRequest.DomainRequestStatus.ACTION_NEEDED
# Create a sample domain request
- domain_request = completed_domain_request(status=in_review)
+ domain_request = completed_domain_request(status=in_review, user=_creator)
# Test the email sent out for already_has_domains
already_has_domains = DomainRequest.ActionNeededReasons.ALREADY_HAS_DOMAINS
self.transition_state_and_send_email(domain_request, action_needed, action_needed_reason=already_has_domains)
- self.assert_email_is_accurate("ORGANIZATION ALREADY HAS A .GOV DOMAIN", 0, EMAIL, bcc_email_address=BCC_EMAIL)
+ self.assert_email_is_accurate("ORGANIZATION ALREADY HAS A .GOV DOMAIN", 0, _creator.email, bcc_email_address=BCC_EMAIL)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 1)
# Test the email sent out for bad_name
bad_name = DomainRequest.ActionNeededReasons.BAD_NAME
self.transition_state_and_send_email(domain_request, action_needed, action_needed_reason=bad_name)
self.assert_email_is_accurate(
- "DOMAIN NAME DOES NOT MEET .GOV REQUIREMENTS", 1, EMAIL, bcc_email_address=BCC_EMAIL
+ "DOMAIN NAME DOES NOT MEET .GOV REQUIREMENTS", 1, _creator.email, bcc_email_address=BCC_EMAIL
)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
@@ -656,7 +663,7 @@ class TestDomainRequestAdmin(MockEppLib):
eligibility_unclear = DomainRequest.ActionNeededReasons.ELIGIBILITY_UNCLEAR
self.transition_state_and_send_email(domain_request, action_needed, action_needed_reason=eligibility_unclear)
self.assert_email_is_accurate(
- "ORGANIZATION MAY NOT MEET ELIGIBILITY REQUIREMENTS", 2, EMAIL, bcc_email_address=BCC_EMAIL
+ "ORGANIZATION MAY NOT MEET ELIGIBILITY REQUIREMENTS", 2, _creator.email, bcc_email_address=BCC_EMAIL
)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 3)
@@ -664,7 +671,7 @@ class TestDomainRequestAdmin(MockEppLib):
questionable_so = DomainRequest.ActionNeededReasons.QUESTIONABLE_SENIOR_OFFICIAL
self.transition_state_and_send_email(domain_request, action_needed, action_needed_reason=questionable_so)
self.assert_email_is_accurate(
- "SENIOR OFFICIAL DOES NOT MEET ELIGIBILITY REQUIREMENTS", 3, EMAIL, bcc_email_address=BCC_EMAIL
+ "SENIOR OFFICIAL DOES NOT MEET ELIGIBILITY REQUIREMENTS", 3, _creator.email, bcc_email_address=BCC_EMAIL
)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 4)
@@ -685,7 +692,7 @@ class TestDomainRequestAdmin(MockEppLib):
)
domain_request.refresh_from_db()
- self.assert_email_is_accurate("custom email content", 4, EMAIL, bcc_email_address=BCC_EMAIL)
+ self.assert_email_is_accurate("custom email content", 4, _creator.email, bcc_email_address=BCC_EMAIL)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 5)
# Tests if a new email gets sent when just the email is changed.
@@ -709,7 +716,7 @@ class TestDomainRequestAdmin(MockEppLib):
action_needed_reason=eligibility_unclear,
action_needed_reason_email="custom content when starting anew",
)
- self.assert_email_is_accurate("custom content when starting anew", 5, EMAIL, bcc_email_address=BCC_EMAIL)
+ self.assert_email_is_accurate("custom content when starting anew", 5, _creator.email, bcc_email_address=BCC_EMAIL)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 6)
# def test_action_needed_sends_reason_email_prod_bcc(self):
@@ -773,22 +780,28 @@ class TestDomainRequestAdmin(MockEppLib):
Also test that the default email set in settings is NOT BCCd on non-prod whenever
an email does go out."""
- # Ensure there is no user with this email
- EMAIL = "mayor@igorville.gov"
- User.objects.filter(email=EMAIL).delete()
+ # Create fake creator
+ _creator = User.objects.create(
+ username="MrMeoward",
+ first_name="Meoward",
+ last_name="Jones",
+ email="meoward.jones@igorville.gov",
+ phone="(555) 123 12345",
+ title="Treat inspector",
+ )
# Create a sample domain request
- domain_request = completed_domain_request()
+ domain_request = completed_domain_request(user=_creator)
# Test Submitted Status from started
self.transition_state_and_send_email(domain_request, DomainRequest.DomainRequestStatus.SUBMITTED)
- self.assert_email_is_accurate("We received your .gov domain request.", 0, EMAIL, True)
+ self.assert_email_is_accurate("We received your .gov domain request.", 0, _creator.email, True)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 1)
# Test Withdrawn Status
self.transition_state_and_send_email(domain_request, DomainRequest.DomainRequestStatus.WITHDRAWN)
self.assert_email_is_accurate(
- "Your .gov domain request has been withdrawn and will not be reviewed by our team.", 1, EMAIL, True
+ "Your .gov domain request has been withdrawn and will not be reviewed by our team.", 1, _creator.email, True
)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
@@ -847,30 +860,36 @@ class TestDomainRequestAdmin(MockEppLib):
Also test that the default email set in settings IS BCCd on prod whenever
an email does go out."""
- # Ensure there is no user with this email
- EMAIL = "mayor@igorville.gov"
- User.objects.filter(email=EMAIL).delete()
+ # Create fake creator
+ _creator = User.objects.create(
+ username="MrMeoward",
+ first_name="Meoward",
+ last_name="Jones",
+ email="meoward.jones@igorville.gov",
+ phone="(555) 123 12345",
+ title="Treat inspector",
+ )
BCC_EMAIL = settings.DEFAULT_FROM_EMAIL
# Create a sample domain request
- domain_request = completed_domain_request()
+ domain_request = completed_domain_request(user=_creator)
# Test Submitted Status from started
self.transition_state_and_send_email(domain_request, DomainRequest.DomainRequestStatus.SUBMITTED)
- self.assert_email_is_accurate("We received your .gov domain request.", 0, EMAIL, False, BCC_EMAIL)
+ self.assert_email_is_accurate("We received your .gov domain request.", 0, _creator.email, False, BCC_EMAIL)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 1)
# Test Withdrawn Status
self.transition_state_and_send_email(domain_request, DomainRequest.DomainRequestStatus.WITHDRAWN)
self.assert_email_is_accurate(
- "Your .gov domain request has been withdrawn and will not be reviewed by our team.", 1, EMAIL
+ "Your .gov domain request has been withdrawn and will not be reviewed by our team.", 1, _creator.email
)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
# Test Submitted Status Again (from withdrawn)
self.transition_state_and_send_email(domain_request, DomainRequest.DomainRequestStatus.SUBMITTED)
- self.assert_email_is_accurate("We received your .gov domain request.", 0, EMAIL, False, BCC_EMAIL)
+ self.assert_email_is_accurate("We received your .gov domain request.", 0, _creator.email, False, BCC_EMAIL)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 3)
# Move it to IN_REVIEW
@@ -901,16 +920,22 @@ class TestDomainRequestAdmin(MockEppLib):
"""When transitioning to approved on a domain request,
an email is sent out every time."""
- # Ensure there is no user with this email
- EMAIL = "mayor@igorville.gov"
- User.objects.filter(email=EMAIL).delete()
+ # Create fake creator
+ _creator = User.objects.create(
+ username="MrMeoward",
+ first_name="Meoward",
+ last_name="Jones",
+ email="meoward.jones@igorville.gov",
+ phone="(555) 123 12345",
+ title="Treat inspector",
+ )
# Create a sample domain request
- domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
+ domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW, user=_creator)
# Test Submitted Status
self.transition_state_and_send_email(domain_request, DomainRequest.DomainRequestStatus.APPROVED)
- self.assert_email_is_accurate("Congratulations! Your .gov domain request has been approved.", 0, EMAIL)
+ self.assert_email_is_accurate("Congratulations! Your .gov domain request has been approved.", 0, _creator.email)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 1)
# Test Withdrawn Status
@@ -919,7 +944,7 @@ class TestDomainRequestAdmin(MockEppLib):
DomainRequest.DomainRequestStatus.REJECTED,
DomainRequest.RejectionReasons.DOMAIN_PURPOSE,
)
- self.assert_email_is_accurate("Your .gov domain request has been rejected.", 1, EMAIL)
+ self.assert_email_is_accurate("Your .gov domain request has been rejected.", 1, _creator.email)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
# Test Submitted Status Again (No new email should be sent)
@@ -931,12 +956,18 @@ class TestDomainRequestAdmin(MockEppLib):
"""When transitioning to rejected on a domain request, an email is sent
explaining why when the reason is domain purpose."""
- # Ensure there is no user with this email
- EMAIL = "mayor@igorville.gov"
- User.objects.filter(email=EMAIL).delete()
+ # Create fake creator
+ _creator = User.objects.create(
+ username="MrMeoward",
+ first_name="Meoward",
+ last_name="Jones",
+ email="meoward.jones@igorville.gov",
+ phone="(555) 123 12345",
+ title="Treat inspector",
+ )
# Create a sample domain request
- domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
+ domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW, user=_creator)
# Reject for reason DOMAIN_PURPOSE and test email
self.transition_state_and_send_email(
@@ -947,13 +978,13 @@ class TestDomainRequestAdmin(MockEppLib):
self.assert_email_is_accurate(
"Your domain request was rejected because the purpose you provided did not meet our \nrequirements.",
0,
- EMAIL,
+ _creator.email,
)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 1)
# Approve
self.transition_state_and_send_email(domain_request, DomainRequest.DomainRequestStatus.APPROVED)
- self.assert_email_is_accurate("Congratulations! Your .gov domain request has been approved.", 1, EMAIL)
+ self.assert_email_is_accurate("Congratulations! Your .gov domain request has been approved.", 1, _creator.email)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
@less_console_noise_decorator
@@ -961,12 +992,18 @@ class TestDomainRequestAdmin(MockEppLib):
"""When transitioning to rejected on a domain request, an email is sent
explaining why when the reason is requestor."""
- # Ensure there is no user with this email
- EMAIL = "mayor@igorville.gov"
- User.objects.filter(email=EMAIL).delete()
+ # Create fake creator
+ _creator = User.objects.create(
+ username="MrMeoward",
+ first_name="Meoward",
+ last_name="Jones",
+ email="meoward.jones@igorville.gov",
+ phone="(555) 123 12345",
+ title="Treat inspector",
+ )
# Create a sample domain request
- domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
+ domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW, user=_creator)
# Reject for reason REQUESTOR and test email including dynamic organization name
self.transition_state_and_send_email(
@@ -976,13 +1013,13 @@ class TestDomainRequestAdmin(MockEppLib):
"Your domain request was rejected because we don’t believe you’re eligible to request a \n.gov "
"domain on behalf of Testorg",
0,
- EMAIL,
+ _creator.email,
)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 1)
# Approve
self.transition_state_and_send_email(domain_request, DomainRequest.DomainRequestStatus.APPROVED)
- self.assert_email_is_accurate("Congratulations! Your .gov domain request has been approved.", 1, EMAIL)
+ self.assert_email_is_accurate("Congratulations! Your .gov domain request has been approved.", 1, _creator.email)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
@less_console_noise_decorator
@@ -990,12 +1027,18 @@ class TestDomainRequestAdmin(MockEppLib):
"""When transitioning to rejected on a domain request, an email is sent
explaining why when the reason is second domain."""
- # Ensure there is no user with this email
- EMAIL = "mayor@igorville.gov"
- User.objects.filter(email=EMAIL).delete()
+ # Create fake creator
+ _creator = User.objects.create(
+ username="MrMeoward",
+ first_name="Meoward",
+ last_name="Jones",
+ email="meoward.jones@igorville.gov",
+ phone="(555) 123 12345",
+ title="Treat inspector",
+ )
# Create a sample domain request
- domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
+ domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW, user=_creator)
# Reject for reason SECOND_DOMAIN_REASONING and test email including dynamic organization name
self.transition_state_and_send_email(
@@ -1003,25 +1046,30 @@ class TestDomainRequestAdmin(MockEppLib):
DomainRequest.DomainRequestStatus.REJECTED,
DomainRequest.RejectionReasons.SECOND_DOMAIN_REASONING,
)
- self.assert_email_is_accurate("Your domain request was rejected because Testorg has a .gov domain.", 0, EMAIL)
+ self.assert_email_is_accurate("Your domain request was rejected because Testorg has a .gov domain.", 0, _creator.email)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 1)
# Approve
self.transition_state_and_send_email(domain_request, DomainRequest.DomainRequestStatus.APPROVED)
- self.assert_email_is_accurate("Congratulations! Your .gov domain request has been approved.", 1, EMAIL)
+ self.assert_email_is_accurate("Congratulations! Your .gov domain request has been approved.", 1, _creator.email)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
@less_console_noise_decorator
def test_save_model_sends_rejected_email_contacts_or_org_legitimacy(self):
"""When transitioning to rejected on a domain request, an email is sent
explaining why when the reason is contacts or org legitimacy."""
-
- # Ensure there is no user with this email
- EMAIL = "mayor@igorville.gov"
- User.objects.filter(email=EMAIL).delete()
+ # Create fake creator
+ _creator = User.objects.create(
+ username="MrMeoward",
+ first_name="Meoward",
+ last_name="Jones",
+ email="meoward.jones@igorville.gov",
+ phone="(555) 123 12345",
+ title="Treat inspector",
+ )
# Create a sample domain request
- domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
+ domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW, user=_creator)
# Reject for reason CONTACTS_OR_ORGANIZATION_LEGITIMACY and test email including dynamic organization name
self.transition_state_and_send_email(
@@ -1033,13 +1081,13 @@ class TestDomainRequestAdmin(MockEppLib):
"Your domain request was rejected because we could not verify the organizational \n"
"contacts you provided. If you have questions or comments, reply to this email.",
0,
- EMAIL,
+ _creator.email,
)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 1)
# Approve
self.transition_state_and_send_email(domain_request, DomainRequest.DomainRequestStatus.APPROVED)
- self.assert_email_is_accurate("Congratulations! Your .gov domain request has been approved.", 1, EMAIL)
+ self.assert_email_is_accurate("Congratulations! Your .gov domain request has been approved.", 1, _creator.email)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
@less_console_noise_decorator
@@ -1047,12 +1095,18 @@ class TestDomainRequestAdmin(MockEppLib):
"""When transitioning to rejected on a domain request, an email is sent
explaining why when the reason is org eligibility."""
- # Ensure there is no user with this email
- EMAIL = "mayor@igorville.gov"
- User.objects.filter(email=EMAIL).delete()
+ # Create fake creator
+ _creator = User.objects.create(
+ username="MrMeoward",
+ first_name="Meoward",
+ last_name="Jones",
+ email="meoward.jones@igorville.gov",
+ phone="(555) 123 12345",
+ title="Treat inspector",
+ )
# Create a sample domain request
- domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
+ domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW, user=_creator)
# Reject for reason ORGANIZATION_ELIGIBILITY and test email including dynamic organization name
self.transition_state_and_send_email(
@@ -1064,26 +1118,31 @@ class TestDomainRequestAdmin(MockEppLib):
"Your domain request was rejected because we determined that Testorg is not \neligible for "
"a .gov domain.",
0,
- EMAIL,
+ _creator.email,
)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 1)
# Approve
self.transition_state_and_send_email(domain_request, DomainRequest.DomainRequestStatus.APPROVED)
- self.assert_email_is_accurate("Congratulations! Your .gov domain request has been approved.", 1, EMAIL)
+ self.assert_email_is_accurate("Congratulations! Your .gov domain request has been approved.", 1, _creator.email)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
@less_console_noise_decorator
def test_save_model_sends_rejected_email_naming(self):
"""When transitioning to rejected on a domain request, an email is sent
explaining why when the reason is naming."""
-
- # Ensure there is no user with this email
- EMAIL = "mayor@igorville.gov"
- User.objects.filter(email=EMAIL).delete()
+ # Create fake creator
+ _creator = User.objects.create(
+ username="MrMeoward",
+ first_name="Meoward",
+ last_name="Jones",
+ email="meoward.jones@igorville.gov",
+ phone="(555) 123 12345",
+ title="Treat inspector",
+ )
# Create a sample domain request
- domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
+ domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW, user=_creator)
# Reject for reason NAMING_REQUIREMENTS and test email including dynamic organization name
self.transition_state_and_send_email(
@@ -1092,13 +1151,13 @@ class TestDomainRequestAdmin(MockEppLib):
DomainRequest.RejectionReasons.NAMING_REQUIREMENTS,
)
self.assert_email_is_accurate(
- "Your domain request was rejected because it does not meet our naming requirements.", 0, EMAIL
+ "Your domain request was rejected because it does not meet our naming requirements.", 0, _creator.email
)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 1)
# Approve
self.transition_state_and_send_email(domain_request, DomainRequest.DomainRequestStatus.APPROVED)
- self.assert_email_is_accurate("Congratulations! Your .gov domain request has been approved.", 1, EMAIL)
+ self.assert_email_is_accurate("Congratulations! Your .gov domain request has been approved.", 1, _creator.email)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
@less_console_noise_decorator
@@ -1106,12 +1165,18 @@ class TestDomainRequestAdmin(MockEppLib):
"""When transitioning to rejected on a domain request, an email is sent
explaining why when the reason is other."""
- # Ensure there is no user with this email
- EMAIL = "mayor@igorville.gov"
- User.objects.filter(email=EMAIL).delete()
+ # Create fake creator
+ _creator = User.objects.create(
+ username="MrMeoward",
+ first_name="Meoward",
+ last_name="Jones",
+ email="meoward.jones@igorville.gov",
+ phone="(555) 123 12345",
+ title="Treat inspector",
+ )
# Create a sample domain request
- domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
+ domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW, user=_creator)
# Reject for reason NAMING_REQUIREMENTS and test email including dynamic organization name
self.transition_state_and_send_email(
@@ -1119,12 +1184,12 @@ class TestDomainRequestAdmin(MockEppLib):
DomainRequest.DomainRequestStatus.REJECTED,
DomainRequest.RejectionReasons.OTHER,
)
- self.assert_email_is_accurate("Choosing a .gov domain name", 0, EMAIL)
+ self.assert_email_is_accurate("Choosing a .gov domain name", 0, _creator.email)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 1)
# Approve
self.transition_state_and_send_email(domain_request, DomainRequest.DomainRequestStatus.APPROVED)
- self.assert_email_is_accurate("Congratulations! Your .gov domain request has been approved.", 1, EMAIL)
+ self.assert_email_is_accurate("Congratulations! Your .gov domain request has been approved.", 1, _creator.email)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
@less_console_noise_decorator
@@ -1186,23 +1251,29 @@ class TestDomainRequestAdmin(MockEppLib):
"""When transitioning to withdrawn on a domain request,
an email is sent out every time."""
- # Ensure there is no user with this email
- EMAIL = "mayor@igorville.gov"
- User.objects.filter(email=EMAIL).delete()
+ # Create fake creator
+ _creator = User.objects.create(
+ username="MrMeoward",
+ first_name="Meoward",
+ last_name="Jones",
+ email="meoward.jones@igorville.gov",
+ phone="(555) 123 12345",
+ title="Treat inspector",
+ )
# Create a sample domain request
- domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
+ domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW, user=_creator)
# Test Submitted Status
self.transition_state_and_send_email(domain_request, DomainRequest.DomainRequestStatus.WITHDRAWN)
self.assert_email_is_accurate(
- "Your .gov domain request has been withdrawn and will not be reviewed by our team.", 0, EMAIL
+ "Your .gov domain request has been withdrawn and will not be reviewed by our team.", 0, _creator.email
)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 1)
# Test Withdrawn Status
self.transition_state_and_send_email(domain_request, DomainRequest.DomainRequestStatus.SUBMITTED)
- self.assert_email_is_accurate("We received your .gov domain request.", 1, EMAIL)
+ self.assert_email_is_accurate("We received your .gov domain request.", 1, _creator.email)
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
# Test Submitted Status Again (No new email should be sent)
From a9ab88286641d544cfa3bb6d414a335b7a69514b Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Tue, 27 Aug 2024 21:25:33 -0700
Subject: [PATCH 014/150] Refactor email tests to deprecate submitter
---
src/registrar/tests/test_admin_request.py | 12 +++++++---
src/registrar/tests/test_emails.py | 5 +---
src/registrar/tests/test_models.py | 28 ++++++++++++++---------
3 files changed, 27 insertions(+), 18 deletions(-)
diff --git a/src/registrar/tests/test_admin_request.py b/src/registrar/tests/test_admin_request.py
index 397de21db..d363e2aa7 100644
--- a/src/registrar/tests/test_admin_request.py
+++ b/src/registrar/tests/test_admin_request.py
@@ -648,7 +648,9 @@ class TestDomainRequestAdmin(MockEppLib):
already_has_domains = DomainRequest.ActionNeededReasons.ALREADY_HAS_DOMAINS
self.transition_state_and_send_email(domain_request, action_needed, action_needed_reason=already_has_domains)
- self.assert_email_is_accurate("ORGANIZATION ALREADY HAS A .GOV DOMAIN", 0, _creator.email, bcc_email_address=BCC_EMAIL)
+ self.assert_email_is_accurate(
+ "ORGANIZATION ALREADY HAS A .GOV DOMAIN", 0, _creator.email, bcc_email_address=BCC_EMAIL
+ )
self.assertEqual(len(self.mock_client.EMAILS_SENT), 1)
# Test the email sent out for bad_name
@@ -716,7 +718,9 @@ class TestDomainRequestAdmin(MockEppLib):
action_needed_reason=eligibility_unclear,
action_needed_reason_email="custom content when starting anew",
)
- self.assert_email_is_accurate("custom content when starting anew", 5, _creator.email, bcc_email_address=BCC_EMAIL)
+ self.assert_email_is_accurate(
+ "custom content when starting anew", 5, _creator.email, bcc_email_address=BCC_EMAIL
+ )
self.assertEqual(len(self.mock_client.EMAILS_SENT), 6)
# def test_action_needed_sends_reason_email_prod_bcc(self):
@@ -1046,7 +1050,9 @@ class TestDomainRequestAdmin(MockEppLib):
DomainRequest.DomainRequestStatus.REJECTED,
DomainRequest.RejectionReasons.SECOND_DOMAIN_REASONING,
)
- self.assert_email_is_accurate("Your domain request was rejected because Testorg has a .gov domain.", 0, _creator.email)
+ self.assert_email_is_accurate(
+ "Your domain request was rejected because Testorg has a .gov domain.", 0, _creator.email
+ )
self.assertEqual(len(self.mock_client.EMAILS_SENT), 1)
# Approve
diff --git a/src/registrar/tests/test_emails.py b/src/registrar/tests/test_emails.py
index cc8b0c4b1..0fda9baee 100644
--- a/src/registrar/tests/test_emails.py
+++ b/src/registrar/tests/test_emails.py
@@ -111,9 +111,7 @@ class TestEmails(TestCase):
_, kwargs = self.mock_client.send_email.call_args
body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"]
self.assertIn("Other employees from your organization:", body)
- # spacing should be right between adjacent elements
- self.assertRegex(body, r"5556\n\nOther employees")
- self.assertRegex(body, r"5557\n\nAnything else")
+ # spacing should be right between adjacent elements self.assertRegex(body, r"5557\n\nAnything else")
@boto3_mocking.patching
@less_console_noise_decorator
@@ -125,7 +123,6 @@ class TestEmails(TestCase):
_, kwargs = self.mock_client.send_email.call_args
body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"]
# spacing should be right between adjacent elements
- self.assertRegex(body, r"5556\n\nOther employees")
self.assertRegex(body, r"None\n\nAnything else")
@boto3_mocking.patching
diff --git a/src/registrar/tests/test_models.py b/src/registrar/tests/test_models.py
index f4dd14ae0..e0794dab4 100644
--- a/src/registrar/tests/test_models.py
+++ b/src/registrar/tests/test_models.py
@@ -257,7 +257,9 @@ class TestDomainRequest(TestCase):
def test_submit_from_started_sends_email(self):
msg = "Create a domain request and submit it and see if email was sent."
domain_request = completed_domain_request(user=self.dummy_user_2)
- self.check_email_sent(domain_request, msg, "submit", 1, expected_content="Hello")
+ self.check_email_sent(
+ domain_request, msg, "submit", 1, expected_content="Hi", expected_email=self.dummy_user_2.email
+ )
@override_flag("profile_feature", active=True)
@less_console_noise_decorator
@@ -272,10 +274,9 @@ class TestDomainRequest(TestCase):
@less_console_noise_decorator
def test_submit_from_withdrawn_sends_email(self):
msg = "Create a withdrawn domain request and submit it and see if email was sent."
- domain_request = completed_domain_request(
- status=DomainRequest.DomainRequestStatus.WITHDRAWN
- )
- self.check_email_sent(domain_request, msg, "submit", 1, expected_content="Hello")
+ user, _ = User.objects.get_or_create(username="testy")
+ domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.WITHDRAWN, user=user)
+ self.check_email_sent(domain_request, msg, "submit", 1, expected_content="Hi", expected_email=user.email)
@less_console_noise_decorator
def test_submit_from_action_needed_does_not_send_email(self):
@@ -292,20 +293,25 @@ class TestDomainRequest(TestCase):
@less_console_noise_decorator
def test_approve_sends_email(self):
msg = "Create a domain request and approve it and see if email was sent."
- domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
- self.check_email_sent(domain_request, msg, "approve", 1, expected_content="Hello")
+ user, _ = User.objects.get_or_create(username="testy")
+ domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW, user=user)
+ self.check_email_sent(domain_request, msg, "approve", 1, expected_content="approved", expected_email=user.email)
@less_console_noise_decorator
def test_withdraw_sends_email(self):
msg = "Create a domain request and withdraw it and see if email was sent."
- domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
- self.check_email_sent(domain_request, msg, "withdraw", 1, expected_content="Hello")
+ user, _ = User.objects.get_or_create(username="testy")
+ domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW, user=user)
+ self.check_email_sent(
+ domain_request, msg, "withdraw", 1, expected_content="withdrawn", expected_email=user.email
+ )
@less_console_noise_decorator
def test_reject_sends_email(self):
msg = "Create a domain request and reject it and see if email was sent."
- domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.APPROVED)
- self.check_email_sent(domain_request, msg, "reject", 1, expected_content="Hello")
+ user, _ = User.objects.get_or_create(username="testy")
+ domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.APPROVED, user=user)
+ self.check_email_sent(domain_request, msg, "reject", 1, expected_content="rejected", expected_email=user.email)
@less_console_noise_decorator
def test_reject_with_prejudice_does_not_send_email(self):
From a431b41e6e461d3326dee4af49bcf0babaa28d92 Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Tue, 27 Aug 2024 21:32:21 -0700
Subject: [PATCH 015/150] Fix linting
---
src/registrar/models/domain_request.py | 2 --
src/registrar/tests/common.py | 1 -
src/registrar/tests/test_admin.py | 2 +-
src/registrar/tests/test_views_request.py | 2 +-
src/registrar/views/domain.py | 2 --
src/registrar/views/domain_request.py | 2 --
6 files changed, 2 insertions(+), 9 deletions(-)
diff --git a/src/registrar/models/domain_request.py b/src/registrar/models/domain_request.py
index 1c4cbb355..c83af8ff0 100644
--- a/src/registrar/models/domain_request.py
+++ b/src/registrar/models/domain_request.py
@@ -6,7 +6,6 @@ from django.conf import settings
from django.db import models
from django_fsm import FSMField, transition # type: ignore
from django.utils import timezone
-from waffle import flag_is_active
from registrar.models.domain import Domain
from registrar.models.federal_agency import FederalAgency
from registrar.models.utility.generic_helper import CreateOrUpdateOrganizationTypeHelper
@@ -1207,7 +1206,6 @@ class DomainRequest(TimeStampedModel):
return self.is_policy_acknowledged is not None
def _is_general_form_complete(self, request):
- has_profile_feature_flag = flag_is_active(request, "profile_feature")
return (
self._is_creator_complete()
and self._is_organization_name_and_address_complete()
diff --git a/src/registrar/tests/common.py b/src/registrar/tests/common.py
index ea2462dfb..566f9b3cf 100644
--- a/src/registrar/tests/common.py
+++ b/src/registrar/tests/common.py
@@ -918,7 +918,6 @@ def completed_domain_request( # noqa
domain, _ = DraftDomain.objects.get_or_create(name=name)
alt, _ = Website.objects.get_or_create(website="city1.gov")
current, _ = Website.objects.get_or_create(website="city.com")
- creator = user
other, _ = Contact.objects.get_or_create(
first_name="Testy",
last_name="Tester",
diff --git a/src/registrar/tests/test_admin.py b/src/registrar/tests/test_admin.py
index 4cce3ed14..3add7a201 100644
--- a/src/registrar/tests/test_admin.py
+++ b/src/registrar/tests/test_admin.py
@@ -60,7 +60,7 @@ from .common import (
)
from django.contrib.sessions.backends.db import SessionStore
from django.contrib.auth import get_user_model
-from unittest.mock import patch, Mock
+from unittest.mock import Mock
import logging
diff --git a/src/registrar/tests/test_views_request.py b/src/registrar/tests/test_views_request.py
index fab64180f..56c7b838f 100644
--- a/src/registrar/tests/test_views_request.py
+++ b/src/registrar/tests/test_views_request.py
@@ -2242,7 +2242,7 @@ class DomainRequestTests(TestWithUser, WebTest):
session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
- profile_page = self.app.get(f"/user-profile")
+ profile_page = self.app.get("/user-profile")
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
profile_form = profile_page.forms[0]
diff --git a/src/registrar/views/domain.py b/src/registrar/views/domain.py
index 4de2ad31e..260d6c8f4 100644
--- a/src/registrar/views/domain.py
+++ b/src/registrar/views/domain.py
@@ -40,7 +40,6 @@ from registrar.models.utility.contact_error import ContactError
from registrar.views.utility.permission_views import UserDomainRolePermissionDeleteView
from ..forms import (
- UserForm,
SeniorOfficialContactForm,
DomainOrgNameAddressForm,
DomainAddUserForm,
@@ -59,7 +58,6 @@ from epplibwrapper import (
from ..utility.email import send_templated_email, EmailSendingError
from .utility import DomainPermissionView, DomainInvitationPermissionDeleteView
-from waffle.decorators import waffle_flag
logger = logging.getLogger(__name__)
diff --git a/src/registrar/views/domain_request.py b/src/registrar/views/domain_request.py
index 05f4e38ff..f1cd5fbbf 100644
--- a/src/registrar/views/domain_request.py
+++ b/src/registrar/views/domain_request.py
@@ -22,8 +22,6 @@ from .utility import (
DomainRequestWizardPermissionView,
)
-from waffle.decorators import flag_is_active, waffle_flag
-
logger = logging.getLogger(__name__)
From 061a0961fb6d019725d2d0ebc98f3532b47d783f Mon Sep 17 00:00:00 2001
From: zandercymatics <141044360+zandercymatics@users.noreply.github.com>
Date: Wed, 28 Aug 2024 14:10:21 -0600
Subject: [PATCH 016/150] Create skeleton
---
.../commands/create_federal_portfolio.py | 148 ++++++++++++++++++
.../transfer_transition_domains_to_domains.py | 2 +-
src/registrar/models/user.py | 6 +
3 files changed, 155 insertions(+), 1 deletion(-)
create mode 100644 src/registrar/management/commands/create_federal_portfolio.py
diff --git a/src/registrar/management/commands/create_federal_portfolio.py b/src/registrar/management/commands/create_federal_portfolio.py
new file mode 100644
index 000000000..562e468a3
--- /dev/null
+++ b/src/registrar/management/commands/create_federal_portfolio.py
@@ -0,0 +1,148 @@
+"""Loads files from /tmp into our sandboxes"""
+
+import argparse
+import logging
+from django.core.management import BaseCommand, CommandError
+from registrar.management.commands.utility.terminal_helper import TerminalColors, TerminalHelper
+from registrar.models import DomainInformation, DomainRequest, FederalAgency, Suborganization, Portfolio, User, SeniorOfficial
+from django.db.models import Q
+
+logger = logging.getLogger(__name__)
+
+
+class Command(BaseCommand):
+ help = "Creates a federal portfolio given a FederalAgency name"
+
+ def add_arguments(self, parser):
+ """Add our arguments."""
+ parser.add_argument(
+ "agency_name",
+ help="The name of the FederalAgency to add",
+ )
+ parser.add_argument(
+ "--parse_requests",
+ action=argparse.BooleanOptionalAction
+ help="Adds portfolio to DomainRequests",
+ )
+ parser.add_argument(
+ "--parse_domains",
+ action=argparse.BooleanOptionalAction
+ help="Adds portfolio to DomainInformation",
+ )
+
+ def handle(self, agency_name, **options):
+ parse_requests = options.get("parse_requests")
+ parse_domains = options.get("parse_domains")
+
+ if not parse_requests and not parse_domains:
+ raise CommandError("You must specify at least one of --parse_requests or --parse_domains.")
+
+ agencies = FederalAgency.objects.filter(agency__iexact=agency_name)
+
+ # TODO - maybe we can add an option here to add this if it doesn't exist?
+ if not agencies.exists():
+ raise ValueError(
+ f"Cannot find the federal agency '{agency_name}' in our database. "
+ "The value you enter for `agency_name` must be "
+ "prepopulated in the FederalAgency table before proceeding."
+ )
+
+ # There should be a one-to-one relationship between the name and the agency.
+ federal_agency = agencies.get()
+
+ portfolio = self.create_or_modify_portfolio(federal_agency)
+ self.create_suborganizations(portfolio, federal_agency)
+
+ if parse_requests:
+ self.handle_portfolio_requests(portfolio, federal_agency)
+
+ if parse_domains:
+ self.handle_portfolio_domains(portfolio, federal_agency)
+
+ def create_or_modify_portfolio(self, federal_agency):
+ # TODO - state_territory, city, etc fields???
+ portfolio_args = {
+ "organization_name": federal_agency.agency,
+ "organization_type": federal_agency.federal_type,
+ "senior_official": getattr(federal_agency, "so_federal_agency", None),
+ "creator": User.get_default_user(),
+ "notes": "Auto-generated record",
+ }
+
+ # Create the Portfolio value if it doesn't exist
+ existing_portfolio = Portfolio.objects.filter(organization_name=federal_agency.agency)
+ if not existing_portfolio.exists():
+ portfolio = Portfolio.objects.create(**portfolio_args)
+ message = f"Created portfolio '{federal_agency.agency}'"
+ TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
+ else:
+ if len(existing_portfolio) > 1:
+ raise ValueError(f"Could not update portfolio '{federal_agency.agency}': multiple records exist.")
+
+ # TODO a dialog to confirm / deny doing this
+ existing_portfolio.update(**portfolio_args)
+ message = f"Modified portfolio '{federal_agency.agency}'"
+ TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
+
+ return portfolio
+
+ def create_suborganizations(self, portfolio: Portfolio, federal_agency: FederalAgency):
+ non_federal_agency = FederalAgency.objects.get(agency="Non-Federal Agency")
+ valid_agencies = DomainInformation.objects.filter(federal_agency=federal_agency).exclude(
+ Q(federal_agency=non_federal_agency) | Q(federal_agency__isnull=True)
+ )
+
+ org_names = valid_agencies.values_list("organization_name", flat=True)
+ if len(org_names) < 1:
+ message =f"No suborganizations found for {federal_agency.agency}"
+ TerminalHelper.colorful_logger(logger.warning, TerminalColors.YELLOW, message)
+ return
+
+ # Check if we need to update any existing suborgs first.
+ # This step is optional.
+ existing_suborgs = Suborganization.objects.filter(name__in=org_names)
+ if len(existing_suborgs) > 1:
+ # TODO - we need a prompt here if any are found
+ for org in existing_suborgs:
+ org.portfolio = portfolio
+
+ Suborganization.objects.bulk_update(existing_suborgs, ["portfolio"])
+ message = f"Updated {len(existing_suborgs)} suborganizations"
+ TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
+
+ # Add any suborgs that don't presently exist
+ suborgs = []
+ for name in org_names:
+ if name not in existing_suborgs:
+ suborg = Suborganization(
+ name=name,
+ portfolio=portfolio,
+ )
+ suborgs.append(suborg)
+
+ Suborganization.objects.bulk_create(suborgs)
+
+ message = f"Added {len(org_names)} suborganizations..."
+ TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
+
+ def handle_portfolio_requests(self, portfolio: Portfolio, federal_agency: FederalAgency):
+ domain_requests = DomainInformation.objects.filter(federal_agency=federal_agency)
+
+ for domain_request in domain_requests:
+ domain_request.portfolio = portfolio
+
+ DomainRequest.objects.bulk_update(domain_request, ["portfolio"])
+
+ message = f"Added portfolio to {len(domain_requests)} domain requests"
+ TerminalHelper.colorful_logger(logger.info, TerminalColors.MAGENTA, message)
+
+ def handle_portfolio_domains(self, portfolio: Portfolio, federal_agency: FederalAgency):
+ domain_infos = DomainInformation.objects.filter(federal_agency=federal_agency)
+
+ for domain_info in domain_infos:
+ domain_info.portfolio = portfolio
+
+ DomainInformation.objects.bulk_update(domain_infos, ["portfolio"])
+
+ message = f"Added portfolio to {len(domain_infos)} domains"
+ TerminalHelper.colorful_logger(logger.info, TerminalColors.MAGENTA, message)
diff --git a/src/registrar/management/commands/transfer_transition_domains_to_domains.py b/src/registrar/management/commands/transfer_transition_domains_to_domains.py
index 615df50a5..acb886b92 100644
--- a/src/registrar/management/commands/transfer_transition_domains_to_domains.py
+++ b/src/registrar/management/commands/transfer_transition_domains_to_domains.py
@@ -423,7 +423,7 @@ class Command(BaseCommand):
valid_fed_type = fed_type in fed_choices
valid_fed_agency = fed_agency in agency_choices
- default_creator, _ = User.objects.get_or_create(username="System")
+ default_creator, _ = User.get_default_user()
new_domain_info_data = {
"domain": domain,
diff --git a/src/registrar/models/user.py b/src/registrar/models/user.py
index a7ea1e14a..88e49a9d9 100644
--- a/src/registrar/models/user.py
+++ b/src/registrar/models/user.py
@@ -157,6 +157,12 @@ class User(AbstractUser):
else:
return self.username
+ @classmethod
+ def get_default_user(cls):
+ """Returns the default "system" user"""
+ default_creator, _ = User.objects.get_or_create(username="System")
+ return default_creator
+
def restrict_user(self):
self.status = self.RESTRICTED
self.save()
From e5b1b5a87a53def67d28b324d0edbf368537038f Mon Sep 17 00:00:00 2001
From: zandercymatics <141044360+zandercymatics@users.noreply.github.com>
Date: Wed, 28 Aug 2024 14:28:23 -0600
Subject: [PATCH 017/150] Fix bugs
---
.../commands/create_federal_portfolio.py | 34 +++++++++++++------
1 file changed, 23 insertions(+), 11 deletions(-)
diff --git a/src/registrar/management/commands/create_federal_portfolio.py b/src/registrar/management/commands/create_federal_portfolio.py
index 562e468a3..5c9f96023 100644
--- a/src/registrar/management/commands/create_federal_portfolio.py
+++ b/src/registrar/management/commands/create_federal_portfolio.py
@@ -21,12 +21,12 @@ class Command(BaseCommand):
)
parser.add_argument(
"--parse_requests",
- action=argparse.BooleanOptionalAction
+ action=argparse.BooleanOptionalAction,
help="Adds portfolio to DomainRequests",
)
parser.add_argument(
"--parse_domains",
- action=argparse.BooleanOptionalAction
+ action=argparse.BooleanOptionalAction,
help="Adds portfolio to DomainInformation",
)
@@ -62,19 +62,24 @@ class Command(BaseCommand):
def create_or_modify_portfolio(self, federal_agency):
# TODO - state_territory, city, etc fields???
portfolio_args = {
+ "federal_agency": federal_agency,
"organization_name": federal_agency.agency,
- "organization_type": federal_agency.federal_type,
- "senior_official": getattr(federal_agency, "so_federal_agency", None),
+ "organization_type": DomainRequest.OrganizationChoices.FEDERAL,
"creator": User.get_default_user(),
"notes": "Auto-generated record",
}
+ senior_official = federal_agency.so_federal_agency
+ if senior_official.exists():
+ portfolio_args["senior_official"] = senior_official.first()
+
# Create the Portfolio value if it doesn't exist
existing_portfolio = Portfolio.objects.filter(organization_name=federal_agency.agency)
if not existing_portfolio.exists():
portfolio = Portfolio.objects.create(**portfolio_args)
message = f"Created portfolio '{federal_agency.agency}'"
TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
+ return portfolio
else:
if len(existing_portfolio) > 1:
raise ValueError(f"Could not update portfolio '{federal_agency.agency}': multiple records exist.")
@@ -82,9 +87,8 @@ class Command(BaseCommand):
# TODO a dialog to confirm / deny doing this
existing_portfolio.update(**portfolio_args)
message = f"Modified portfolio '{federal_agency.agency}'"
- TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
-
- return portfolio
+ TerminalHelper.colorful_logger(logger.info, TerminalColors.MAGENTA, message)
+ return existing_portfolio
def create_suborganizations(self, portfolio: Portfolio, federal_agency: FederalAgency):
non_federal_agency = FederalAgency.objects.get(agency="Non-Federal Agency")
@@ -127,22 +131,30 @@ class Command(BaseCommand):
def handle_portfolio_requests(self, portfolio: Portfolio, federal_agency: FederalAgency):
domain_requests = DomainInformation.objects.filter(federal_agency=federal_agency)
+ if len(domain_requests) < 1:
+ message = f"Portfolios not added to domain requests: no valid records found"
+ TerminalHelper.colorful_logger(logger.info, TerminalColors.YELLOW, message)
+ return
for domain_request in domain_requests:
domain_request.portfolio = portfolio
- DomainRequest.objects.bulk_update(domain_request, ["portfolio"])
-
+ DomainRequest.objects.bulk_update(domain_requests, ["portfolio"])
message = f"Added portfolio to {len(domain_requests)} domain requests"
- TerminalHelper.colorful_logger(logger.info, TerminalColors.MAGENTA, message)
+ TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
def handle_portfolio_domains(self, portfolio: Portfolio, federal_agency: FederalAgency):
domain_infos = DomainInformation.objects.filter(federal_agency=federal_agency)
+ if len(domain_infos) < 1:
+ message = f"Portfolios not added to domains: no valid records found"
+ TerminalHelper.colorful_logger(logger.info, TerminalColors.YELLOW, message)
+ return
+
for domain_info in domain_infos:
domain_info.portfolio = portfolio
DomainInformation.objects.bulk_update(domain_infos, ["portfolio"])
message = f"Added portfolio to {len(domain_infos)} domains"
- TerminalHelper.colorful_logger(logger.info, TerminalColors.MAGENTA, message)
+ TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
From d35acc8a306e52614c0e6a0c805e54924fcf4806 Mon Sep 17 00:00:00 2001
From: zandercymatics <141044360+zandercymatics@users.noreply.github.com>
Date: Wed, 28 Aug 2024 14:54:12 -0600
Subject: [PATCH 018/150] Update create_federal_portfolio.py
---
.../commands/create_federal_portfolio.py | 48 +++++++++++++++----
1 file changed, 39 insertions(+), 9 deletions(-)
diff --git a/src/registrar/management/commands/create_federal_portfolio.py b/src/registrar/management/commands/create_federal_portfolio.py
index 5c9f96023..68e625bc9 100644
--- a/src/registrar/management/commands/create_federal_portfolio.py
+++ b/src/registrar/management/commands/create_federal_portfolio.py
@@ -77,18 +77,18 @@ class Command(BaseCommand):
existing_portfolio = Portfolio.objects.filter(organization_name=federal_agency.agency)
if not existing_portfolio.exists():
portfolio = Portfolio.objects.create(**portfolio_args)
- message = f"Created portfolio '{federal_agency.agency}'"
+ message = f"Created portfolio '{portfolio}'"
TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
return portfolio
else:
if len(existing_portfolio) > 1:
- raise ValueError(f"Could not update portfolio '{federal_agency.agency}': multiple records exist.")
+ raise ValueError(f"Could not update portfolio '{portfolio}': multiple records exist.")
# TODO a dialog to confirm / deny doing this
existing_portfolio.update(**portfolio_args)
message = f"Modified portfolio '{federal_agency.agency}'"
TerminalHelper.colorful_logger(logger.info, TerminalColors.MAGENTA, message)
- return existing_portfolio
+ return existing_portfolio.get()
def create_suborganizations(self, portfolio: Portfolio, federal_agency: FederalAgency):
non_federal_agency = FederalAgency.objects.get(agency="Non-Federal Agency")
@@ -115,20 +115,50 @@ class Command(BaseCommand):
TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
# Add any suborgs that don't presently exist
+ excluded_org_names = existing_suborgs.values_list("name", flat=True)
suborgs = []
for name in org_names:
- if name not in existing_suborgs:
- suborg = Suborganization(
- name=name,
- portfolio=portfolio,
- )
- suborgs.append(suborg)
+ if name and name not in excluded_org_names:
+ if portfolio.organization_name and name.lower() == portfolio.organization_name.lower():
+ # If the suborg name is the name that currently exists,
+ # thats not a suborg - thats the portfolio itself!
+ # In this case, we can use this as an opportunity to update
+ # address information and the like
+ self._update_portfolio_location_details(portfolio, valid_agencies.get(organization_name=name))
+ else:
+ suborg = Suborganization(
+ name=name,
+ portfolio=portfolio,
+ )
+ suborgs.append(suborg)
Suborganization.objects.bulk_create(suborgs)
+ # TODO - this is inaccurate when the suborg name does not equal the org name - i.e. if the
+ # record exists already as well
message = f"Added {len(org_names)} suborganizations..."
TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
+ # TODO rename
+ def _update_portfolio_location_details(self, portfolio: Portfolio, domain_info: DomainInformation):
+ location_props = [
+ "address_line1",
+ "address_line2",
+ "city",
+ "state_territory",
+ "zipcode",
+ "urbanization",
+ ]
+
+ for prop_name in location_props:
+ # Copy the value from the domain info object to the portfolio object
+ value = getattr(domain_info, prop_name)
+ setattr(portfolio, prop_name, value)
+ portfolio.save()
+
+ message = f"Updated location details on portfolio '{portfolio}'"
+ TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
+
def handle_portfolio_requests(self, portfolio: Portfolio, federal_agency: FederalAgency):
domain_requests = DomainInformation.objects.filter(federal_agency=federal_agency)
if len(domain_requests) < 1:
From 71d44353d10c714a03a61dd0d21c55038903758f Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Wed, 28 Aug 2024 16:30:43 -0700
Subject: [PATCH 019/150] Remove submitter refs in docs
---
docs/architecture/diagrams/model_timeline.md | 3 +--
docs/architecture/diagrams/models_diagram.md | 2 --
docs/developer/generating-emails-guide.md | 8 ++++----
src/registrar/tests/test_models.py | 2 +-
src/registrar/tests/test_views_request.py | 14 +++++---------
5 files changed, 11 insertions(+), 18 deletions(-)
diff --git a/docs/architecture/diagrams/model_timeline.md b/docs/architecture/diagrams/model_timeline.md
index f05b9e056..eed2610eb 100644
--- a/docs/architecture/diagrams/model_timeline.md
+++ b/docs/architecture/diagrams/model_timeline.md
@@ -42,7 +42,6 @@ class DomainRequest {
creator (User)
investigator (User)
senior_official (Contact)
- submitter (Contact)
other_contacts (Contacts)
approved_domain (Domain)
requested_domain (DraftDomain)
@@ -80,7 +79,7 @@ class Contact {
--
}
-DomainRequest *-r-* Contact : senior_official, submitter, other_contacts
+DomainRequest *-r-* Contact : senior_official, other_contacts
class DraftDomain {
Requested domain
diff --git a/docs/architecture/diagrams/models_diagram.md b/docs/architecture/diagrams/models_diagram.md
index 455f8fb09..1e9d3089e 100644
--- a/docs/architecture/diagrams/models_diagram.md
+++ b/docs/architecture/diagrams/models_diagram.md
@@ -179,7 +179,6 @@ class "registrar.DomainRequest " as registrar.DomainRequest #d6f4e9 {
~ senior_official (ForeignKey)
~ approved_domain (OneToOneField)
~ requested_domain (OneToOneField)
- ~ submitter (ForeignKey)
+ purpose (TextField)
+ no_other_contacts_rationale (TextField)
+ anything_else (TextField)
@@ -236,7 +235,6 @@ class "registrar.DomainInformation " as registrar.DomainInformation #
+ about_your_organization (TextField)
~ senior_official (ForeignKey)
~ domain (OneToOneField)
- ~ submitter (ForeignKey)
+ purpose (TextField)
+ no_other_contacts_rationale (TextField)
+ anything_else (TextField)
diff --git a/docs/developer/generating-emails-guide.md b/docs/developer/generating-emails-guide.md
index dd0a55e64..cc5f9d41b 100644
--- a/docs/developer/generating-emails-guide.md
+++ b/docs/developer/generating-emails-guide.md
@@ -14,7 +14,7 @@
- Starting Location: Home page
- Workflow: (Domain requests Table) Manage domain
- Workflow Step: Click "Manage" -> Click "Withdraw request" -> (confirmation prompt) -> Click "Withdraw request" (inside prompt)
-- Notes: You can also do this through Django Admin by switching a domain of status "submitted" to "withdrawn", but you need to be the submitter (email listed on Your Contact Information).
+- Notes: You can also do this through Django Admin by switching a domain of status "submitted" to "withdrawn", but you need to be the creator.
- [Email Content](https://github.com/cisagov/manage.get.gov/blob/main/src/registrar/templates/emails/domain_request_withdrawn.txt)
### Domain Request Withdrawn Subject
@@ -25,7 +25,7 @@
- Starting Location: Django Admin
- Workflow: Analyst Admin
- Workflow Step: Click "domain requests" -> Click a domain request in a status of "submitted", "In review", "rejected", or "ineligible" -> Click status dropdown -> (select "approved") -> click "Save"
-- Notes: Note that this will send an email to the submitter (email listed on Your Contact Information). To test this with your own email, you need to create a domain request, then set the status to "approved". This will send you an email.
+- Notes: Note that this will send an email to the creator. To test this with your own email, you need to create a domain request, then set the status to "approved". This will send you an email.
- [Email Content](https://github.com/cisagov/manage.get.gov/blob/main/src/registrar/templates/emails/status_change_approved.txt)
### Status Change Approved Subject
@@ -36,7 +36,7 @@
- Starting Location: Django Admin
- Workflow: Analyst Admin
- Workflow Step: Click "domain requests" -> Click a domain request in a status of "In review", or "approved" -> Click status dropdown -> (select "rejected") -> click "Save"
-- Notes: Note that this will send an email to the submitter (email listed on Your Contact Information). To test this with your own email, you need to create a domain request, then set the status to "in review" (and click save). Then, go back to the same application and set the status to "rejected". This will send you an email.
+- Notes: Note that this will send an email to the creator. To test this with your own email, you need to create a domain request, then set the status to "in review" (and click save). Then, go back to the same application and set the status to "rejected". This will send you an email.
- [Email Content](https://github.com/cisagov/manage.get.gov/blob/main/src/registrar/templates/emails/status_change_rejected.txt)
### Status Change Rejected Subject
@@ -47,7 +47,7 @@
- Starting Location: Home Page
- Workflow: Start domain request
- Workflow Step: Click "Start a new domain request" -> (fill out the form) -> On the last step ("Review and submit your domain request "), click "Submit your domain request"
-- Notes: Note that this will send an email to the submitter (email listed on Your Contact Information)
+- Notes: Note that this will send an email to the creator.
- [Email Content](https://github.com/cisagov/manage.get.gov/blob/main/src/registrar/templates/emails/submission_confirmation.txt)
### Submission Confirmation Subject
diff --git a/src/registrar/tests/test_models.py b/src/registrar/tests/test_models.py
index e0794dab4..cdc7d2a00 100644
--- a/src/registrar/tests/test_models.py
+++ b/src/registrar/tests/test_models.py
@@ -221,7 +221,7 @@ class TestDomainRequest(TestCase):
site = DraftDomain.objects.create(name="igorville.gov")
domain_request = DomainRequest.objects.create(creator=user, requested_domain=site)
- # no submitter email so this emits a log warning
+ # no email sent to creator so this emits a log warning
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
with less_console_noise():
diff --git a/src/registrar/tests/test_views_request.py b/src/registrar/tests/test_views_request.py
index 56c7b838f..8718abda7 100644
--- a/src/registrar/tests/test_views_request.py
+++ b/src/registrar/tests/test_views_request.py
@@ -2206,15 +2206,13 @@ class DomainRequestTests(TestWithUser, WebTest):
@override_flag("profile_feature", active=True)
@less_console_noise_decorator
- def test_edit_submitter_in_place(self):
+ def test_edit_creator_in_place(self):
"""When you:
- 1. edit a submitter (your contact) which is not joined to another model,
+ 1. edit a your user profile information,
2. then submit,
- the domain request is linked to the existing submitter, and the submitter updated."""
+ the domain request also updates its creator data to reflect user profile changes."""
- # Populate the database with a domain request that
- # has a submitter
- # We'll do it from scratch
+ # Populate the database with a domain request
domain_request, _ = DomainRequest.objects.get_or_create(
generic_org_type="federal",
federal_type="executive",
@@ -2229,8 +2227,6 @@ class DomainRequestTests(TestWithUser, WebTest):
status="started",
)
- # submitter_pk is the initial pk of the submitter. set it before update
- # to be able to verify after update that the same contact object is in place
creator_pk = self.user.id
# prime the form by visiting /edit
@@ -2946,7 +2942,7 @@ class TestWizardUnlockingSteps(TestWithUser, WebTest):
# Now 'detail_page' contains the response after following the redirect
self.assertEqual(detail_page.status_code, 200)
- # 5 unlocked steps (so, domain, submitter, other contacts, and current sites
+ # 5 unlocked steps (so, domain, other contacts, and current sites
# which unlocks if domain exists), one active step, the review step is locked
self.assertContains(detail_page, "#check_circle", count=4)
# Type of organization
From 8e6115acf0fe294cf9a4abc06fd85dd4e4705914 Mon Sep 17 00:00:00 2001
From: zandercymatics <141044360+zandercymatics@users.noreply.github.com>
Date: Thu, 29 Aug 2024 10:00:10 -0600
Subject: [PATCH 020/150] Add some better logging and options
---
.../commands/create_federal_portfolio.py | 88 +++++++++++++------
1 file changed, 60 insertions(+), 28 deletions(-)
diff --git a/src/registrar/management/commands/create_federal_portfolio.py b/src/registrar/management/commands/create_federal_portfolio.py
index 68e625bc9..6d62a645b 100644
--- a/src/registrar/management/commands/create_federal_portfolio.py
+++ b/src/registrar/management/commands/create_federal_portfolio.py
@@ -60,7 +60,9 @@ class Command(BaseCommand):
self.handle_portfolio_domains(portfolio, federal_agency)
def create_or_modify_portfolio(self, federal_agency):
- # TODO - state_territory, city, etc fields???
+ """Tries to create a portfolio record based off of a federal agency.
+ If the record already exists, we prompt the user to proceed then
+ update the record."""
portfolio_args = {
"federal_agency": federal_agency,
"organization_name": federal_agency.agency,
@@ -81,38 +83,44 @@ class Command(BaseCommand):
TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
return portfolio
else:
- if len(existing_portfolio) > 1:
- raise ValueError(f"Could not update portfolio '{portfolio}': multiple records exist.")
+
+ proceed = TerminalHelper.prompt_for_execution(
+ system_exit_on_terminate=False,
+ info_to_inspect=f"""The given portfolio '{federal_agency.agency}' already exists in our DB.
+ If you cancel, the rest of the script will still execute but this record will not update.
+ """,
+ prompt_title="Do you wish to modify this record?",
+ )
+ if not proceed:
+ if len(existing_portfolio) > 1:
+ raise ValueError(f"Could not use portfolio '{federal_agency.agency}': multiple records exist.")
+ else:
+ # Just return the portfolio object without modifying it
+ return existing_portfolio.get()
+
+ if len(existing_portfolio) > 1:
+ raise ValueError(f"Could not update portfolio '{federal_agency.agency}': multiple records exist.")
- # TODO a dialog to confirm / deny doing this
existing_portfolio.update(**portfolio_args)
- message = f"Modified portfolio '{federal_agency.agency}'"
+ message = f"Modified portfolio '{existing_portfolio.first()}'"
TerminalHelper.colorful_logger(logger.info, TerminalColors.MAGENTA, message)
return existing_portfolio.get()
def create_suborganizations(self, portfolio: Portfolio, federal_agency: FederalAgency):
- non_federal_agency = FederalAgency.objects.get(agency="Non-Federal Agency")
- valid_agencies = DomainInformation.objects.filter(federal_agency=federal_agency).exclude(
- Q(federal_agency=non_federal_agency) | Q(federal_agency__isnull=True)
- )
-
+ """Given a list of organization_names on DomainInformation objects (filtered by agency),
+ create multiple Suborganizations tied to the given portfolio"""
+ valid_agencies = DomainInformation.objects.filter(federal_agency=federal_agency)
org_names = valid_agencies.values_list("organization_name", flat=True)
if len(org_names) < 1:
- message =f"No suborganizations found for {federal_agency.agency}"
+ message =f"No suborganizations found for {federal_agency}"
TerminalHelper.colorful_logger(logger.warning, TerminalColors.YELLOW, message)
return
# Check if we need to update any existing suborgs first.
# This step is optional.
existing_suborgs = Suborganization.objects.filter(name__in=org_names)
- if len(existing_suborgs) > 1:
- # TODO - we need a prompt here if any are found
- for org in existing_suborgs:
- org.portfolio = portfolio
-
- Suborganization.objects.bulk_update(existing_suborgs, ["portfolio"])
- message = f"Updated {len(existing_suborgs)} suborganizations"
- TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
+ if len(existing_suborgs) > 0:
+ self._update_existing_suborganizations(portfolio, existing_suborgs)
# Add any suborgs that don't presently exist
excluded_org_names = existing_suborgs.values_list("name", flat=True)
@@ -132,15 +140,39 @@ class Command(BaseCommand):
)
suborgs.append(suborg)
- Suborganization.objects.bulk_create(suborgs)
+ if len(org_names) > 1:
+ Suborganization.objects.bulk_create(suborgs)
+ message = f"Added {len(suborgs)} suborganizations"
+ TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
+ else:
+ message =f"No suborganizations added"
+ TerminalHelper.colorful_logger(logger.warning, TerminalColors.YELLOW, message)
+
+ def _update_existing_suborganizations(self, portfolio, orgs_to_update):
+ proceed = TerminalHelper.prompt_for_execution(
+ system_exit_on_terminate=False,
+ info_to_inspect=f"""Some suborganizations already exist in our DB.
+ If you cancel, the rest of the script will still execute but these records will not update.
+
+ ==Proposed Changes==
+ The following suborgs will be updated: {[org.name for org in orgs_to_update]}
+ """,
+ prompt_title="Do you wish to modify existing suborganizations?",
+ )
+ if not proceed:
+ return
+
+ for org in orgs_to_update:
+ org.portfolio = portfolio
+
+ Suborganization.objects.bulk_update(orgs_to_update, ["portfolio"])
+ message = f"Updated {len(orgs_to_update)} suborganizations"
+ TerminalHelper.colorful_logger(logger.info, TerminalColors.MAGENTA, message)
- # TODO - this is inaccurate when the suborg name does not equal the org name - i.e. if the
- # record exists already as well
- message = f"Added {len(org_names)} suborganizations..."
- TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
- # TODO rename
def _update_portfolio_location_details(self, portfolio: Portfolio, domain_info: DomainInformation):
+ """Adds location information to the given portfolio based off of the values in
+ DomainInformation"""
location_props = [
"address_line1",
"address_line2",
@@ -168,9 +200,9 @@ class Command(BaseCommand):
for domain_request in domain_requests:
domain_request.portfolio = portfolio
-
+
DomainRequest.objects.bulk_update(domain_requests, ["portfolio"])
- message = f"Added portfolio to {len(domain_requests)} domain requests"
+ message = f"Added portfolio '{portfolio}' to {len(domain_requests)} domain requests"
TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
def handle_portfolio_domains(self, portfolio: Portfolio, federal_agency: FederalAgency):
@@ -186,5 +218,5 @@ class Command(BaseCommand):
DomainInformation.objects.bulk_update(domain_infos, ["portfolio"])
- message = f"Added portfolio to {len(domain_infos)} domains"
+ message = f"Added portfolio '{portfolio}' to {len(domain_infos)} domains"
TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
From 2d52e02b59a8fd9987b1c433efbdef26fb8b41ed Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Thu, 29 Aug 2024 09:29:16 -0700
Subject: [PATCH 021/150] Save progress
---
src/.zshrc | 1 +
src/Pipfile.lock | 1367 ++++++++++++++----------------
src/models_diagram.puml | 463 ++++++++++
src/registrar/config/settings.py | 4 +-
src/requirements.txt | 67 +-
5 files changed, 1133 insertions(+), 769 deletions(-)
create mode 100644 src/.zshrc
create mode 100644 src/models_diagram.puml
diff --git a/src/.zshrc b/src/.zshrc
new file mode 100644
index 000000000..45a622a14
--- /dev/null
+++ b/src/.zshrc
@@ -0,0 +1 @@
+export DOCKER_DEFAULT_PLATFORM=linux/amd64
diff --git a/src/Pipfile.lock b/src/Pipfile.lock
index a42563c63..09ac4a934 100644
--- a/src/Pipfile.lock
+++ b/src/Pipfile.lock
@@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
- "sha256": "9095c4f98f58a9502444584067a63f329d5a5fc4b49454c4e129bda09552d19d"
+ "sha256": "2799ab9e493352740c6946e604ccc075c5c16359c809753296091bbe2b9fd837"
},
"pipfile-spec": 6,
"requires": {},
@@ -16,11 +16,11 @@
"default": {
"annotated-types": {
"hashes": [
- "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43",
- "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d"
+ "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53",
+ "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"
],
"markers": "python_version >= '3.8'",
- "version": "==0.6.0"
+ "version": "==0.7.0"
},
"asgiref": {
"hashes": [
@@ -32,37 +32,37 @@
},
"boto3": {
"hashes": [
- "sha256:decf52f8d5d8a1b10c9ff2a0e96ee207ed79e33d2e53fdf0880a5cbef70785e0",
- "sha256:e836b71d79671270fccac0a4d4c8ec239a6b82ea47c399b64675aa597d0ee63b"
+ "sha256:06eac4757de2a9c6020381205cb902f05964caad80b56e58c8931284a133b4cb",
+ "sha256:b9587131372a808bf6f99c5ed8b11be55cd113261cc3b437a917b4acc6c30bfe"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==1.34.95"
+ "version": "==1.35.8"
},
"botocore": {
"hashes": [
- "sha256:6bd76a2eadb42b91fa3528392e981ad5b4dfdee3968fa5b904278acf6cbf15ff",
- "sha256:ead5823e0dd6751ece5498cb979fd9abf190e691c8833bcac6876fd6ca261fa7"
+ "sha256:4b820cf680ab5d778bd2fe4feeef1ff8a2b96d5c535d4638ab30f703ade282f8",
+ "sha256:adf389eb8fd87775f193300e3431d1353f925807ad3a39958172cb644f0d60a1"
],
"markers": "python_version >= '3.8'",
- "version": "==1.34.95"
+ "version": "==1.35.8"
},
"cachetools": {
"hashes": [
- "sha256:0abad1021d3f8325b2fc1d2e9c8b9c9d57b04c3932657a72465447332c24d945",
- "sha256:ba29e2dfa0b8b556606f097407ed1aa62080ee108ab0dc5ec9d6a723a007d105"
+ "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292",
+ "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"
],
"index": "pypi",
"markers": "python_version >= '3.7'",
- "version": "==5.3.3"
+ "version": "==5.5.0"
},
"certifi": {
"hashes": [
- "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f",
- "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"
+ "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b",
+ "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"
],
"markers": "python_version >= '3.6'",
- "version": "==2024.2.2"
+ "version": "==2024.7.4"
},
"cfenv": {
"hashes": [
@@ -74,61 +74,76 @@
},
"cffi": {
"hashes": [
- "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc",
- "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a",
- "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417",
- "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab",
- "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520",
- "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36",
- "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743",
- "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8",
- "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed",
- "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684",
- "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56",
- "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324",
- "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d",
- "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235",
- "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e",
- "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088",
- "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000",
- "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7",
- "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e",
- "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673",
- "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c",
- "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe",
- "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2",
- "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098",
- "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8",
- "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a",
- "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0",
- "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b",
- "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896",
- "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e",
- "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9",
- "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2",
- "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b",
- "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6",
- "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404",
- "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f",
- "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0",
- "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4",
- "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc",
- "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936",
- "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba",
- "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872",
- "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb",
- "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614",
- "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1",
- "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d",
- "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969",
- "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b",
- "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4",
- "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627",
- "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956",
- "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"
+ "sha256:011aff3524d578a9412c8b3cfaa50f2c0bd78e03eb7af7aa5e0df59b158efb2f",
+ "sha256:0a048d4f6630113e54bb4b77e315e1ba32a5a31512c31a273807d0027a7e69ab",
+ "sha256:0bb15e7acf8ab35ca8b24b90af52c8b391690ef5c4aec3d31f38f0d37d2cc499",
+ "sha256:0d46ee4764b88b91f16661a8befc6bfb24806d885e27436fdc292ed7e6f6d058",
+ "sha256:0e60821d312f99d3e1569202518dddf10ae547e799d75aef3bca3a2d9e8ee693",
+ "sha256:0fdacad9e0d9fc23e519efd5ea24a70348305e8d7d85ecbb1a5fa66dc834e7fb",
+ "sha256:14b9cbc8f7ac98a739558eb86fabc283d4d564dafed50216e7f7ee62d0d25377",
+ "sha256:17c6d6d3260c7f2d94f657e6872591fe8733872a86ed1345bda872cfc8c74885",
+ "sha256:1a2ddbac59dc3716bc79f27906c010406155031a1c801410f1bafff17ea304d2",
+ "sha256:2404f3de742f47cb62d023f0ba7c5a916c9c653d5b368cc966382ae4e57da401",
+ "sha256:24658baf6224d8f280e827f0a50c46ad819ec8ba380a42448e24459daf809cf4",
+ "sha256:24aa705a5f5bd3a8bcfa4d123f03413de5d86e497435693b638cbffb7d5d8a1b",
+ "sha256:2770bb0d5e3cc0e31e7318db06efcbcdb7b31bcb1a70086d3177692a02256f59",
+ "sha256:331ad15c39c9fe9186ceaf87203a9ecf5ae0ba2538c9e898e3a6967e8ad3db6f",
+ "sha256:3aa9d43b02a0c681f0bfbc12d476d47b2b2b6a3f9287f11ee42989a268a1833c",
+ "sha256:41f4915e09218744d8bae14759f983e466ab69b178de38066f7579892ff2a555",
+ "sha256:4304d4416ff032ed50ad6bb87416d802e67139e31c0bde4628f36a47a3164bfa",
+ "sha256:435a22d00ec7d7ea533db494da8581b05977f9c37338c80bc86314bec2619424",
+ "sha256:45f7cd36186db767d803b1473b3c659d57a23b5fa491ad83c6d40f2af58e4dbb",
+ "sha256:48b389b1fd5144603d61d752afd7167dfd205973a43151ae5045b35793232aa2",
+ "sha256:4e67d26532bfd8b7f7c05d5a766d6f437b362c1bf203a3a5ce3593a645e870b8",
+ "sha256:516a405f174fd3b88829eabfe4bb296ac602d6a0f68e0d64d5ac9456194a5b7e",
+ "sha256:5ba5c243f4004c750836f81606a9fcb7841f8874ad8f3bf204ff5e56332b72b9",
+ "sha256:5bdc0f1f610d067c70aa3737ed06e2726fd9d6f7bfee4a351f4c40b6831f4e82",
+ "sha256:6107e445faf057c118d5050560695e46d272e5301feffda3c41849641222a828",
+ "sha256:6327b572f5770293fc062a7ec04160e89741e8552bf1c358d1a23eba68166759",
+ "sha256:669b29a9eca6146465cc574659058ed949748f0809a2582d1f1a324eb91054dc",
+ "sha256:6ce01337d23884b21c03869d2f68c5523d43174d4fc405490eb0091057943118",
+ "sha256:6d872186c1617d143969defeadac5a904e6e374183e07977eedef9c07c8953bf",
+ "sha256:6f76a90c345796c01d85e6332e81cab6d70de83b829cf1d9762d0a3da59c7932",
+ "sha256:70d2aa9fb00cf52034feac4b913181a6e10356019b18ef89bc7c12a283bf5f5a",
+ "sha256:7cbc78dc018596315d4e7841c8c3a7ae31cc4d638c9b627f87d52e8abaaf2d29",
+ "sha256:856bf0924d24e7f93b8aee12a3a1095c34085600aa805693fb7f5d1962393206",
+ "sha256:8a98748ed1a1df4ee1d6f927e151ed6c1a09d5ec21684de879c7ea6aa96f58f2",
+ "sha256:93a7350f6706b31f457c1457d3a3259ff9071a66f312ae64dc024f049055f72c",
+ "sha256:964823b2fc77b55355999ade496c54dde161c621cb1f6eac61dc30ed1b63cd4c",
+ "sha256:a003ac9edc22d99ae1286b0875c460351f4e101f8c9d9d2576e78d7e048f64e0",
+ "sha256:a0ce71725cacc9ebf839630772b07eeec220cbb5f03be1399e0457a1464f8e1a",
+ "sha256:a47eef975d2b8b721775a0fa286f50eab535b9d56c70a6e62842134cf7841195",
+ "sha256:a8b5b9712783415695663bd463990e2f00c6750562e6ad1d28e072a611c5f2a6",
+ "sha256:a9015f5b8af1bb6837a3fcb0cdf3b874fe3385ff6274e8b7925d81ccaec3c5c9",
+ "sha256:aec510255ce690d240f7cb23d7114f6b351c733a74c279a84def763660a2c3bc",
+ "sha256:b00e7bcd71caa0282cbe3c90966f738e2db91e64092a877c3ff7f19a1628fdcb",
+ "sha256:b50aaac7d05c2c26dfd50c3321199f019ba76bb650e346a6ef3616306eed67b0",
+ "sha256:b7b6ea9e36d32582cda3465f54c4b454f62f23cb083ebc7a94e2ca6ef011c3a7",
+ "sha256:bb9333f58fc3a2296fb1d54576138d4cf5d496a2cc118422bd77835e6ae0b9cb",
+ "sha256:c1c13185b90bbd3f8b5963cd8ce7ad4ff441924c31e23c975cb150e27c2bf67a",
+ "sha256:c3b8bd3133cd50f6b637bb4322822c94c5ce4bf0d724ed5ae70afce62187c492",
+ "sha256:c5d97162c196ce54af6700949ddf9409e9833ef1003b4741c2b39ef46f1d9720",
+ "sha256:c815270206f983309915a6844fe994b2fa47e5d05c4c4cef267c3b30e34dbe42",
+ "sha256:cab2eba3830bf4f6d91e2d6718e0e1c14a2f5ad1af68a89d24ace0c6b17cced7",
+ "sha256:d1df34588123fcc88c872f5acb6f74ae59e9d182a2707097f9e28275ec26a12d",
+ "sha256:d6bdcd415ba87846fd317bee0774e412e8792832e7805938987e4ede1d13046d",
+ "sha256:db9a30ec064129d605d0f1aedc93e00894b9334ec74ba9c6bdd08147434b33eb",
+ "sha256:dbc183e7bef690c9abe5ea67b7b60fdbca81aa8da43468287dae7b5c046107d4",
+ "sha256:dca802c8db0720ce1c49cce1149ff7b06e91ba15fa84b1d59144fef1a1bc7ac2",
+ "sha256:dec6b307ce928e8e112a6bb9921a1cb00a0e14979bf28b98e084a4b8a742bd9b",
+ "sha256:df8bb0010fdd0a743b7542589223a2816bdde4d94bb5ad67884348fa2c1c67e8",
+ "sha256:e4094c7b464cf0a858e75cd14b03509e84789abf7b79f8537e6a72152109c76e",
+ "sha256:e4760a68cab57bfaa628938e9c2971137e05ce48e762a9cb53b76c9b569f1204",
+ "sha256:eb09b82377233b902d4c3fbeeb7ad731cdab579c6c6fda1f763cd779139e47c3",
+ "sha256:eb862356ee9391dc5a0b3cbc00f416b48c1b9a52d252d898e5b7696a5f9fe150",
+ "sha256:ef9528915df81b8f4c7612b19b8628214c65c9b7f74db2e34a646a0a2a0da2d4",
+ "sha256:f3157624b7558b914cb039fd1af735e5e8049a87c817cc215109ad1c8779df76",
+ "sha256:f3e0992f23bbb0be00a921eae5363329253c3b86287db27092461c887b791e5e",
+ "sha256:f9338cc05451f1942d0d8203ec2c346c830f8e86469903d5126c1f0a13a2bcbb",
+ "sha256:ffef8fd58a36fb5f1196919638f73dd3ae0db1a878982b27a9a5a176ede4ba91"
],
"markers": "platform_python_implementation != 'PyPy'",
- "version": "==1.16.0"
+ "version": "==1.17.0"
},
"charset-normalizer": {
"hashes": [
@@ -228,41 +243,36 @@
},
"cryptography": {
"hashes": [
- "sha256:0270572b8bd2c833c3981724b8ee9747b3ec96f699a9665470018594301439ee",
- "sha256:111a0d8553afcf8eb02a4fea6ca4f59d48ddb34497aa8706a6cf536f1a5ec576",
- "sha256:16a48c23a62a2f4a285699dba2e4ff2d1cff3115b9df052cdd976a18856d8e3d",
- "sha256:1b95b98b0d2af784078fa69f637135e3c317091b615cd0905f8b8a087e86fa30",
- "sha256:1f71c10d1e88467126f0efd484bd44bca5e14c664ec2ede64c32f20875c0d413",
- "sha256:2424ff4c4ac7f6b8177b53c17ed5d8fa74ae5955656867f5a8affaca36a27abb",
- "sha256:2bce03af1ce5a5567ab89bd90d11e7bbdff56b8af3acbbec1faded8f44cb06da",
- "sha256:329906dcc7b20ff3cad13c069a78124ed8247adcac44b10bea1130e36caae0b4",
- "sha256:37dd623507659e08be98eec89323469e8c7b4c1407c85112634ae3dbdb926fdd",
- "sha256:3eaafe47ec0d0ffcc9349e1708be2aaea4c6dd4978d76bf6eb0cb2c13636c6fc",
- "sha256:5e6275c09d2badf57aea3afa80d975444f4be8d3bc58f7f80d2a484c6f9485c8",
- "sha256:6fe07eec95dfd477eb9530aef5bead34fec819b3aaf6c5bd6d20565da607bfe1",
- "sha256:7367d7b2eca6513681127ebad53b2582911d1736dc2ffc19f2c3ae49997496bc",
- "sha256:7cde5f38e614f55e28d831754e8a3bacf9ace5d1566235e39d91b35502d6936e",
- "sha256:9481ffe3cf013b71b2428b905c4f7a9a4f76ec03065b05ff499bb5682a8d9ad8",
- "sha256:98d8dc6d012b82287f2c3d26ce1d2dd130ec200c8679b6213b3c73c08b2b7940",
- "sha256:a011a644f6d7d03736214d38832e030d8268bcff4a41f728e6030325fea3e400",
- "sha256:a2913c5375154b6ef2e91c10b5720ea6e21007412f6437504ffea2109b5a33d7",
- "sha256:a30596bae9403a342c978fb47d9b0ee277699fa53bbafad14706af51fe543d16",
- "sha256:b03c2ae5d2f0fc05f9a2c0c997e1bc18c8229f392234e8a0194f202169ccd278",
- "sha256:b6cd2203306b63e41acdf39aa93b86fb566049aeb6dc489b70e34bcd07adca74",
- "sha256:b7ffe927ee6531c78f81aa17e684e2ff617daeba7f189f911065b2ea2d526dec",
- "sha256:b8cac287fafc4ad485b8a9b67d0ee80c66bf3574f655d3b97ef2e1082360faf1",
- "sha256:ba334e6e4b1d92442b75ddacc615c5476d4ad55cc29b15d590cc6b86efa487e2",
- "sha256:ba3e4a42397c25b7ff88cdec6e2a16c2be18720f317506ee25210f6d31925f9c",
- "sha256:c41fb5e6a5fe9ebcd58ca3abfeb51dffb5d83d6775405305bfa8715b76521922",
- "sha256:cd2030f6650c089aeb304cf093f3244d34745ce0cfcc39f20c6fbfe030102e2a",
- "sha256:cd65d75953847815962c84a4654a84850b2bb4aed3f26fadcc1c13892e1e29f6",
- "sha256:e4985a790f921508f36f81831817cbc03b102d643b5fcb81cd33df3fa291a1a1",
- "sha256:e807b3188f9eb0eaa7bbb579b462c5ace579f1cedb28107ce8b48a9f7ad3679e",
- "sha256:f12764b8fffc7a123f641d7d049d382b73f96a34117e0b637b80643169cec8ac",
- "sha256:f8837fe1d6ac4a8052a9a8ddab256bc006242696f03368a4009be7ee3075cdb7"
+ "sha256:0663585d02f76929792470451a5ba64424acc3cd5227b03921dab0e2f27b1709",
+ "sha256:08a24a7070b2b6804c1940ff0f910ff728932a9d0e80e7814234269f9d46d069",
+ "sha256:232ce02943a579095a339ac4b390fbbe97f5b5d5d107f8a08260ea2768be8cc2",
+ "sha256:2905ccf93a8a2a416f3ec01b1a7911c3fe4073ef35640e7ee5296754e30b762b",
+ "sha256:299d3da8e00b7e2b54bb02ef58d73cd5f55fb31f33ebbf33bd00d9aa6807df7e",
+ "sha256:2c6d112bf61c5ef44042c253e4859b3cbbb50df2f78fa8fae6747a7814484a70",
+ "sha256:31e44a986ceccec3d0498e16f3d27b2ee5fdf69ce2ab89b52eaad1d2f33d8778",
+ "sha256:3d9a1eca329405219b605fac09ecfc09ac09e595d6def650a437523fcd08dd22",
+ "sha256:3dcdedae5c7710b9f97ac6bba7e1052b95c7083c9d0e9df96e02a1932e777895",
+ "sha256:47ca71115e545954e6c1d207dd13461ab81f4eccfcb1345eac874828b5e3eaaf",
+ "sha256:4a997df8c1c2aae1e1e5ac49c2e4f610ad037fc5a3aadc7b64e39dea42249431",
+ "sha256:51956cf8730665e2bdf8ddb8da0056f699c1a5715648c1b0144670c1ba00b48f",
+ "sha256:5bcb8a5620008a8034d39bce21dc3e23735dfdb6a33a06974739bfa04f853947",
+ "sha256:64c3f16e2a4fc51c0d06af28441881f98c5d91009b8caaff40cf3548089e9c74",
+ "sha256:6e2b11c55d260d03a8cf29ac9b5e0608d35f08077d8c087be96287f43af3ccdc",
+ "sha256:7b3f5fe74a5ca32d4d0f302ffe6680fcc5c28f8ef0dc0ae8f40c0f3a1b4fca66",
+ "sha256:844b6d608374e7d08f4f6e6f9f7b951f9256db41421917dfb2d003dde4cd6b66",
+ "sha256:9a8d6802e0825767476f62aafed40532bd435e8a5f7d23bd8b4f5fd04cc80ecf",
+ "sha256:aae4d918f6b180a8ab8bf6511a419473d107df4dbb4225c7b48c5c9602c38c7f",
+ "sha256:ac1955ce000cb29ab40def14fd1bbfa7af2017cca696ee696925615cafd0dce5",
+ "sha256:b88075ada2d51aa9f18283532c9f60e72170041bba88d7f37e49cbb10275299e",
+ "sha256:cb013933d4c127349b3948aa8aaf2f12c0353ad0eccd715ca789c8a0f671646f",
+ "sha256:cc70b4b581f28d0a254d006f26949245e3657d40d8857066c2ae22a61222ef55",
+ "sha256:e9c5266c432a1e23738d178e51c2c7a5e2ddf790f248be939448c0ba2021f9d1",
+ "sha256:ea9e57f8ea880eeea38ab5abf9fbe39f923544d7884228ec67d666abd60f5a47",
+ "sha256:ee0c405832ade84d4de74b9029bedb7b31200600fa524d218fc29bfa371e97f5",
+ "sha256:fdcb265de28585de5b859ae13e3846a8e805268a823a12a4da2597f1f5afc9f0"
],
"markers": "python_version >= '3.7'",
- "version": "==42.0.5"
+ "version": "==43.0.0"
},
"defusedxml": {
"hashes": [
@@ -282,10 +292,10 @@
},
"dj-database-url": {
"hashes": [
- "sha256:04bc34b248d4c21aaa13e4ab419ae6575ef5f10f3df735ce7da97722caa356e0",
- "sha256:f2042cefe1086e539c9da39fad5ad7f61173bf79665e69bf7e4de55fa88b135f"
+ "sha256:3e792567b0aa9a4884860af05fe2aa4968071ad351e033b6db632f97ac6db9de",
+ "sha256:9f9b05058ddf888f1e6f840048b8d705ff9395e3b52a07165daa3d8b9360551b"
],
- "version": "==2.1.0"
+ "version": "==2.2.0"
},
"dj-email-url": {
"hashes": [
@@ -337,12 +347,12 @@
},
"django-cors-headers": {
"hashes": [
- "sha256:0b1fd19297e37417fc9f835d39e45c8c642938ddba1acce0c1753d3edef04f36",
- "sha256:0bf65ef45e606aff1994d35503e6b677c0b26cafff6506f8fd7187f3be840207"
+ "sha256:5c6e3b7fe870876a1efdfeb4f433782c3524078fa0dc9e0195f6706ce7a242f6",
+ "sha256:92cf4633e22af67a230a1456cb1b7a02bb213d6536d2dcb2a4a24092ea9cebc2"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==4.3.1"
+ "version": "==4.4.0"
},
"django-csp": {
"hashes": [
@@ -362,12 +372,12 @@
},
"django-import-export": {
"hashes": [
- "sha256:2eac09e8cec8670f36e24314760448011ad23c51e8fb930d55f50d0c3c926da0",
- "sha256:4deabc557801d368093608c86fd0f4831bc9540e2ea41ca2f023e2efb3eb6f48"
+ "sha256:16ecc5a9f0df46bde6eb278a3e65ebda0ee1db55656f36440e9fb83f40ab85a3",
+ "sha256:730ae2443a02b1ba27d8dba078a27ae9123adfcabb78161b4f130843607b3df9"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==3.3.8"
+ "version": "==4.1.1"
},
"django-login-required-middleware": {
"hashes": [
@@ -381,11 +391,11 @@
"phonenumberslite"
],
"hashes": [
- "sha256:bc6eaa49d1f9d870944f5280258db511e3a1ba5e2fbbed255488dceacae45d06",
- "sha256:f9cdb3de085f99c249328293a3b93d4e5fa440c0c8e3b99eb0d0f54748629797"
+ "sha256:196c917b70c01a98e327f482eb8a4a4a55a29891db551f99078585397370b3ba",
+ "sha256:8a560fe1b01b94c9de8cde22bc373b695f023cc6df4baba00264cb079da9f631"
],
"markers": "python_version >= '3.8'",
- "version": "==7.3.0"
+ "version": "==8.0.0"
},
"django-waffle": {
"hashes": [
@@ -416,22 +426,14 @@
"markers": "python_version >= '3.8'",
"version": "==11.0.0"
},
- "et-xmlfile": {
- "hashes": [
- "sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c",
- "sha256:a2ba85d1d6a74ef63837eed693bcb89c3f752169b0e3e7ae5b16ca5e1b3deada"
- ],
- "markers": "python_version >= '3.6'",
- "version": "==1.1.0"
- },
"faker": {
"hashes": [
- "sha256:87ef41e24b39a5be66ecd874af86f77eebd26782a2681200e86c5326340a95d3",
- "sha256:e23a2b74888885c3d23a9237bacb823041291c03d609a39acb9ebe6c123f3986"
+ "sha256:0d3c0399204aaf8205cc1750db443474ca0436f177126b2c27b798e8336cc74f",
+ "sha256:6a3a08be54c37e05f7943d7ba5211d252c1de737687a46ad6f29209d8d5db11f"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==25.0.0"
+ "version": "==28.0.0"
},
"fred-epplib": {
"git": "https://github.com/cisagov/epplib.git",
@@ -567,20 +569,20 @@
},
"gunicorn": {
"hashes": [
- "sha256:350679f91b24062c86e386e198a15438d53a7a8207235a78ba1b53df4c4378d9",
- "sha256:4a0b436239ff76fb33f11c07a16482c521a7e09c1ce3cc293c2330afe01bec63"
+ "sha256:ec400d38950de4dfd418cff8328b2c8faed0edb0d517d3394e457c317908ca4d",
+ "sha256:f014447a0101dc57e294f6c18ca6b40227a4c90e9bdb586042628030cba004ec"
],
"index": "pypi",
"markers": "python_version >= '3.7'",
- "version": "==22.0.0"
+ "version": "==23.0.0"
},
"idna": {
"hashes": [
- "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc",
- "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"
+ "sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac",
+ "sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603"
],
- "markers": "python_version >= '3.5'",
- "version": "==3.7"
+ "markers": "python_version >= '3.6'",
+ "version": "==3.8"
},
"jmespath": {
"hashes": [
@@ -592,177 +594,155 @@
},
"lxml": {
"hashes": [
- "sha256:04ab5415bf6c86e0518d57240a96c4d1fcfc3cb370bb2ac2a732b67f579e5a04",
- "sha256:057cdc6b86ab732cf361f8b4d8af87cf195a1f6dc5b0ff3de2dced242c2015e0",
- "sha256:058a1308914f20784c9f4674036527e7c04f7be6fb60f5d61353545aa7fcb739",
- "sha256:08802f0c56ed150cc6885ae0788a321b73505d2263ee56dad84d200cab11c07a",
- "sha256:0a15438253b34e6362b2dc41475e7f80de76320f335e70c5528b7148cac253a1",
- "sha256:0c3f67e2aeda739d1cc0b1102c9a9129f7dc83901226cc24dd72ba275ced4218",
- "sha256:0e7259016bc4345a31af861fdce942b77c99049d6c2107ca07dc2bba2435c1d9",
- "sha256:0ed777c1e8c99b63037b91f9d73a6aad20fd035d77ac84afcc205225f8f41188",
- "sha256:0f5d65c39f16717a47c36c756af0fb36144069c4718824b7533f803ecdf91138",
- "sha256:0f8c09ed18ecb4ebf23e02b8e7a22a05d6411911e6fabef3a36e4f371f4f2585",
- "sha256:11a04306fcba10cd9637e669fd73aa274c1c09ca64af79c041aa820ea992b637",
- "sha256:1ae67b4e737cddc96c99461d2f75d218bdf7a0c3d3ad5604d1f5e7464a2f9ffe",
- "sha256:1c5bb205e9212d0ebddf946bc07e73fa245c864a5f90f341d11ce7b0b854475d",
- "sha256:1f7785f4f789fdb522729ae465adcaa099e2a3441519df750ebdccc481d961a1",
- "sha256:200e63525948e325d6a13a76ba2911f927ad399ef64f57898cf7c74e69b71095",
- "sha256:21c2e6b09565ba5b45ae161b438e033a86ad1736b8c838c766146eff8ceffff9",
- "sha256:2213afee476546a7f37c7a9b4ad4d74b1e112a6fafffc9185d6d21f043128c81",
- "sha256:27aa20d45c2e0b8cd05da6d4759649170e8dfc4f4e5ef33a34d06f2d79075d57",
- "sha256:2a66bf12fbd4666dd023b6f51223aed3d9f3b40fef06ce404cb75bafd3d89536",
- "sha256:2c9d147f754b1b0e723e6afb7ba1566ecb162fe4ea657f53d2139bbf894d050a",
- "sha256:2ddfe41ddc81f29a4c44c8ce239eda5ade4e7fc305fb7311759dd6229a080052",
- "sha256:31e9a882013c2f6bd2f2c974241bf4ba68c85eba943648ce88936d23209a2e01",
- "sha256:3249cc2989d9090eeac5467e50e9ec2d40704fea9ab72f36b034ea34ee65ca98",
- "sha256:3545039fa4779be2df51d6395e91a810f57122290864918b172d5dc7ca5bb433",
- "sha256:394ed3924d7a01b5bd9a0d9d946136e1c2f7b3dc337196d99e61740ed4bc6fe1",
- "sha256:3a6b45da02336895da82b9d472cd274b22dc27a5cea1d4b793874eead23dd14f",
- "sha256:3a74c4f27167cb95c1d4af1c0b59e88b7f3e0182138db2501c353555f7ec57f4",
- "sha256:3d0c3dd24bb4605439bf91068598d00c6370684f8de4a67c2992683f6c309d6b",
- "sha256:3dbe858ee582cbb2c6294dc85f55b5f19c918c2597855e950f34b660f1a5ede6",
- "sha256:3dc773b2861b37b41a6136e0b72a1a44689a9c4c101e0cddb6b854016acc0aa8",
- "sha256:3f7765e69bbce0906a7c74d5fe46d2c7a7596147318dbc08e4a2431f3060e306",
- "sha256:417d14450f06d51f363e41cace6488519038f940676ce9664b34ebf5653433a5",
- "sha256:44f6c7caff88d988db017b9b0e4ab04934f11e3e72d478031efc7edcac6c622f",
- "sha256:491755202eb21a5e350dae00c6d9a17247769c64dcf62d8c788b5c135e179dc4",
- "sha256:4951e4f7a5680a2db62f7f4ab2f84617674d36d2d76a729b9a8be4b59b3659be",
- "sha256:52421b41ac99e9d91934e4d0d0fe7da9f02bfa7536bb4431b4c05c906c8c6919",
- "sha256:530e7c04f72002d2f334d5257c8a51bf409db0316feee7c87e4385043be136af",
- "sha256:533658f8fbf056b70e434dff7e7aa611bcacb33e01f75de7f821810e48d1bb66",
- "sha256:5670fb70a828663cc37552a2a85bf2ac38475572b0e9b91283dc09efb52c41d1",
- "sha256:56c22432809085b3f3ae04e6e7bdd36883d7258fcd90e53ba7b2e463efc7a6af",
- "sha256:58278b29cb89f3e43ff3e0c756abbd1518f3ee6adad9e35b51fb101c1c1daaec",
- "sha256:588008b8497667f1ddca7c99f2f85ce8511f8f7871b4a06ceede68ab62dff64b",
- "sha256:59565f10607c244bc4c05c0c5fa0c190c990996e0c719d05deec7030c2aa8289",
- "sha256:59689a75ba8d7ffca577aefd017d08d659d86ad4585ccc73e43edbfc7476781a",
- "sha256:5aea8212fb823e006b995c4dda533edcf98a893d941f173f6c9506126188860d",
- "sha256:5c670c0406bdc845b474b680b9a5456c561c65cf366f8db5a60154088c92d102",
- "sha256:5ca1e8188b26a819387b29c3895c47a5e618708fe6f787f3b1a471de2c4a94d9",
- "sha256:5d077bc40a1fe984e1a9931e801e42959a1e6598edc8a3223b061d30fbd26bbc",
- "sha256:5d5792e9b3fb8d16a19f46aa8208987cfeafe082363ee2745ea8b643d9cc5b45",
- "sha256:5dd1537e7cc06efd81371f5d1a992bd5ab156b2b4f88834ca852de4a8ea523fa",
- "sha256:5ea7b6766ac2dfe4bcac8b8595107665a18ef01f8c8343f00710b85096d1b53a",
- "sha256:622020d4521e22fb371e15f580d153134bfb68d6a429d1342a25f051ec72df1c",
- "sha256:627402ad8dea044dde2eccde4370560a2b750ef894c9578e1d4f8ffd54000461",
- "sha256:644df54d729ef810dcd0f7732e50e5ad1bd0a135278ed8d6bcb06f33b6b6f708",
- "sha256:64641a6068a16201366476731301441ce93457eb8452056f570133a6ceb15fca",
- "sha256:64c2baa7774bc22dd4474248ba16fe1a7f611c13ac6123408694d4cc93d66dbd",
- "sha256:6588c459c5627fefa30139be4d2e28a2c2a1d0d1c265aad2ba1935a7863a4913",
- "sha256:66bc5eb8a323ed9894f8fa0ee6cb3e3fb2403d99aee635078fd19a8bc7a5a5da",
- "sha256:68a2610dbe138fa8c5826b3f6d98a7cfc29707b850ddcc3e21910a6fe51f6ca0",
- "sha256:6935bbf153f9a965f1e07c2649c0849d29832487c52bb4a5c5066031d8b44fd5",
- "sha256:6992030d43b916407c9aa52e9673612ff39a575523c5f4cf72cdef75365709a5",
- "sha256:6a014510830df1475176466b6087fc0c08b47a36714823e58d8b8d7709132a96",
- "sha256:6ab833e4735a7e5533711a6ea2df26459b96f9eec36d23f74cafe03631647c41",
- "sha256:6cc6ee342fb7fa2471bd9b6d6fdfc78925a697bf5c2bcd0a302e98b0d35bfad3",
- "sha256:6cf58416653c5901e12624e4013708b6e11142956e7f35e7a83f1ab02f3fe456",
- "sha256:70a9768e1b9d79edca17890175ba915654ee1725975d69ab64813dd785a2bd5c",
- "sha256:70ac664a48aa64e5e635ae5566f5227f2ab7f66a3990d67566d9907edcbbf867",
- "sha256:71e97313406ccf55d32cc98a533ee05c61e15d11b99215b237346171c179c0b0",
- "sha256:7221d49259aa1e5a8f00d3d28b1e0b76031655ca74bb287123ef56c3db92f213",
- "sha256:74b28c6334cca4dd704e8004cba1955af0b778cf449142e581e404bd211fb619",
- "sha256:764b521b75701f60683500d8621841bec41a65eb739b8466000c6fdbc256c240",
- "sha256:78bfa756eab503673991bdcf464917ef7845a964903d3302c5f68417ecdc948c",
- "sha256:794f04eec78f1d0e35d9e0c36cbbb22e42d370dda1609fb03bcd7aeb458c6377",
- "sha256:79bd05260359170f78b181b59ce871673ed01ba048deef4bf49a36ab3e72e80b",
- "sha256:7a7efd5b6d3e30d81ec68ab8a88252d7c7c6f13aaa875009fe3097eb4e30b84c",
- "sha256:7c17b64b0a6ef4e5affae6a3724010a7a66bda48a62cfe0674dabd46642e8b54",
- "sha256:804f74efe22b6a227306dd890eecc4f8c59ff25ca35f1f14e7482bbce96ef10b",
- "sha256:853e074d4931dbcba7480d4dcab23d5c56bd9607f92825ab80ee2bd916edea53",
- "sha256:857500f88b17a6479202ff5fe5f580fc3404922cd02ab3716197adf1ef628029",
- "sha256:865bad62df277c04beed9478fe665b9ef63eb28fe026d5dedcb89b537d2e2ea6",
- "sha256:88e22fc0a6684337d25c994381ed8a1580a6f5ebebd5ad41f89f663ff4ec2885",
- "sha256:8b9c07e7a45bb64e21df4b6aa623cb8ba214dfb47d2027d90eac197329bb5e94",
- "sha256:8de8f9d6caa7f25b204fc861718815d41cbcf27ee8f028c89c882a0cf4ae4134",
- "sha256:8e77c69d5892cb5ba71703c4057091e31ccf534bd7f129307a4d084d90d014b8",
- "sha256:9123716666e25b7b71c4e1789ec829ed18663152008b58544d95b008ed9e21e9",
- "sha256:958244ad566c3ffc385f47dddde4145088a0ab893504b54b52c041987a8c1863",
- "sha256:96323338e6c14e958d775700ec8a88346014a85e5de73ac7967db0367582049b",
- "sha256:9676bfc686fa6a3fa10cd4ae6b76cae8be26eb5ec6811d2a325636c460da1806",
- "sha256:9b0ff53900566bc6325ecde9181d89afadc59c5ffa39bddf084aaedfe3b06a11",
- "sha256:9b9ec9c9978b708d488bec36b9e4c94d88fd12ccac3e62134a9d17ddba910ea9",
- "sha256:9c6ad0fbf105f6bcc9300c00010a2ffa44ea6f555df1a2ad95c88f5656104817",
- "sha256:9ca66b8e90daca431b7ca1408cae085d025326570e57749695d6a01454790e95",
- "sha256:9e2addd2d1866fe112bc6f80117bcc6bc25191c5ed1bfbcf9f1386a884252ae8",
- "sha256:a0af35bd8ebf84888373630f73f24e86bf016642fb8576fba49d3d6b560b7cbc",
- "sha256:a2b44bec7adf3e9305ce6cbfa47a4395667e744097faed97abb4728748ba7d47",
- "sha256:a2dfe7e2473f9b59496247aad6e23b405ddf2e12ef0765677b0081c02d6c2c0b",
- "sha256:a55ee573116ba208932e2d1a037cc4b10d2c1cb264ced2184d00b18ce585b2c0",
- "sha256:a7baf9ffc238e4bf401299f50e971a45bfcc10a785522541a6e3179c83eabf0a",
- "sha256:a8d5c70e04aac1eda5c829a26d1f75c6e5286c74743133d9f742cda8e53b9c2f",
- "sha256:a91481dbcddf1736c98a80b122afa0f7296eeb80b72344d7f45dc9f781551f56",
- "sha256:ab31a88a651039a07a3ae327d68ebdd8bc589b16938c09ef3f32a4b809dc96ef",
- "sha256:abc25c3cab9ec7fcd299b9bcb3b8d4a1231877e425c650fa1c7576c5107ab851",
- "sha256:adfb84ca6b87e06bc6b146dc7da7623395db1e31621c4785ad0658c5028b37d7",
- "sha256:afbbdb120d1e78d2ba8064a68058001b871154cc57787031b645c9142b937a62",
- "sha256:afd5562927cdef7c4f5550374acbc117fd4ecc05b5007bdfa57cc5355864e0a4",
- "sha256:b070bbe8d3f0f6147689bed981d19bbb33070225373338df755a46893528104a",
- "sha256:b0b58fbfa1bf7367dde8a557994e3b1637294be6cf2169810375caf8571a085c",
- "sha256:b560e3aa4b1d49e0e6c847d72665384db35b2f5d45f8e6a5c0072e0283430533",
- "sha256:b6241d4eee5f89453307c2f2bfa03b50362052ca0af1efecf9fef9a41a22bb4f",
- "sha256:b6787b643356111dfd4032b5bffe26d2f8331556ecb79e15dacb9275da02866e",
- "sha256:bcbf4af004f98793a95355980764b3d80d47117678118a44a80b721c9913436a",
- "sha256:beb72935a941965c52990f3a32d7f07ce869fe21c6af8b34bf6a277b33a345d3",
- "sha256:bf2e2458345d9bffb0d9ec16557d8858c9c88d2d11fed53998512504cd9df49b",
- "sha256:c2d35a1d047efd68027817b32ab1586c1169e60ca02c65d428ae815b593e65d4",
- "sha256:c38d7b9a690b090de999835f0443d8aa93ce5f2064035dfc48f27f02b4afc3d0",
- "sha256:c6f2c8372b98208ce609c9e1d707f6918cc118fea4e2c754c9f0812c04ca116d",
- "sha256:c817d420c60a5183953c783b0547d9eb43b7b344a2c46f69513d5952a78cddf3",
- "sha256:c8ba129e6d3b0136a0f50345b2cb3db53f6bda5dd8c7f5d83fbccba97fb5dcb5",
- "sha256:c94e75445b00319c1fad60f3c98b09cd63fe1134a8a953dcd48989ef42318534",
- "sha256:cc4691d60512798304acb9207987e7b2b7c44627ea88b9d77489bbe3e6cc3bd4",
- "sha256:cc518cea79fd1e2f6c90baafa28906d4309d24f3a63e801d855e7424c5b34144",
- "sha256:cd53553ddad4a9c2f1f022756ae64abe16da1feb497edf4d9f87f99ec7cf86bd",
- "sha256:cf22b41fdae514ee2f1691b6c3cdeae666d8b7fa9434de445f12bbeee0cf48dd",
- "sha256:d38c8f50ecf57f0463399569aa388b232cf1a2ffb8f0a9a5412d0db57e054860",
- "sha256:d3be9b2076112e51b323bdf6d5a7f8a798de55fb8d95fcb64bd179460cdc0704",
- "sha256:d4f2cc7060dc3646632d7f15fe68e2fa98f58e35dd5666cd525f3b35d3fed7f8",
- "sha256:d7520db34088c96cc0e0a3ad51a4fd5b401f279ee112aa2b7f8f976d8582606d",
- "sha256:d793bebb202a6000390a5390078e945bbb49855c29c7e4d56a85901326c3b5d9",
- "sha256:da052e7962ea2d5e5ef5bc0355d55007407087392cf465b7ad84ce5f3e25fe0f",
- "sha256:dae0ed02f6b075426accbf6b2863c3d0a7eacc1b41fb40f2251d931e50188dad",
- "sha256:ddc678fb4c7e30cf830a2b5a8d869538bc55b28d6c68544d09c7d0d8f17694dc",
- "sha256:df2e6f546c4df14bc81f9498bbc007fbb87669f1bb707c6138878c46b06f6510",
- "sha256:e02c5175f63effbd7c5e590399c118d5db6183bbfe8e0d118bdb5c2d1b48d937",
- "sha256:e196a4ff48310ba62e53a8e0f97ca2bca83cdd2fe2934d8b5cb0df0a841b193a",
- "sha256:e233db59c8f76630c512ab4a4daf5a5986da5c3d5b44b8e9fc742f2a24dbd460",
- "sha256:e32be23d538753a8adb6c85bd539f5fd3b15cb987404327c569dfc5fd8366e85",
- "sha256:e3d30321949861404323c50aebeb1943461a67cd51d4200ab02babc58bd06a86",
- "sha256:e89580a581bf478d8dcb97d9cd011d567768e8bc4095f8557b21c4d4c5fea7d0",
- "sha256:e998e304036198b4f6914e6a1e2b6f925208a20e2042563d9734881150c6c246",
- "sha256:ec42088248c596dbd61d4ae8a5b004f97a4d91a9fd286f632e42e60b706718d7",
- "sha256:efa7b51824aa0ee957ccd5a741c73e6851de55f40d807f08069eb4c5a26b2baa",
- "sha256:f0a1bc63a465b6d72569a9bba9f2ef0334c4e03958e043da1920299100bc7c08",
- "sha256:f18a5a84e16886898e51ab4b1d43acb3083c39b14c8caeb3589aabff0ee0b270",
- "sha256:f2a9efc53d5b714b8df2b4b3e992accf8ce5bbdfe544d74d5c6766c9e1146a3a",
- "sha256:f3bbbc998d42f8e561f347e798b85513ba4da324c2b3f9b7969e9c45b10f6169",
- "sha256:f42038016852ae51b4088b2862126535cc4fc85802bfe30dea3500fdfaf1864e",
- "sha256:f443cdef978430887ed55112b491f670bba6462cea7a7742ff8f14b7abb98d75",
- "sha256:f51969bac61441fd31f028d7b3b45962f3ecebf691a510495e5d2cd8c8092dbd",
- "sha256:f8aca2e3a72f37bfc7b14ba96d4056244001ddcc18382bd0daa087fd2e68a354",
- "sha256:f9737bf36262046213a28e789cc82d82c6ef19c85a0cf05e75c670a33342ac2c",
- "sha256:fd6037392f2d57793ab98d9e26798f44b8b4da2f2464388588f48ac52c489ea1",
- "sha256:feaa45c0eae424d3e90d78823f3828e7dc42a42f21ed420db98da2c4ecf0a2cb",
- "sha256:ff097ae562e637409b429a7ac958a20aab237a0378c42dabaa1e3abf2f896e5f",
- "sha256:ff46d772d5f6f73564979cd77a4fffe55c916a05f3cb70e7c9c0590059fb29ef"
+ "sha256:01220dca0d066d1349bd6a1726856a78f7929f3878f7e2ee83c296c69495309e",
+ "sha256:02ced472497b8362c8e902ade23e3300479f4f43e45f4105c85ef43b8db85229",
+ "sha256:052d99051e77a4f3e8482c65014cf6372e61b0a6f4fe9edb98503bb5364cfee3",
+ "sha256:07da23d7ee08577760f0a71d67a861019103e4812c87e2fab26b039054594cc5",
+ "sha256:094cb601ba9f55296774c2d57ad68730daa0b13dc260e1f941b4d13678239e70",
+ "sha256:0a7056921edbdd7560746f4221dca89bb7a3fe457d3d74267995253f46343f15",
+ "sha256:0c120f43553ec759f8de1fee2f4794452b0946773299d44c36bfe18e83caf002",
+ "sha256:0d7b36afa46c97875303a94e8f3ad932bf78bace9e18e603f2085b652422edcd",
+ "sha256:0fdf3a3059611f7585a78ee10399a15566356116a4288380921a4b598d807a22",
+ "sha256:109fa6fede314cc50eed29e6e56c540075e63d922455346f11e4d7a036d2b8cf",
+ "sha256:146173654d79eb1fc97498b4280c1d3e1e5d58c398fa530905c9ea50ea849b22",
+ "sha256:1473427aff3d66a3fa2199004c3e601e6c4500ab86696edffdbc84954c72d832",
+ "sha256:1483fd3358963cc5c1c9b122c80606a3a79ee0875bcac0204149fa09d6ff2727",
+ "sha256:168f2dfcfdedf611eb285efac1516c8454c8c99caf271dccda8943576b67552e",
+ "sha256:17e8d968d04a37c50ad9c456a286b525d78c4a1c15dd53aa46c1d8e06bf6fa30",
+ "sha256:18feb4b93302091b1541221196a2155aa296c363fd233814fa11e181adebc52f",
+ "sha256:1afe0a8c353746e610bd9031a630a95bcfb1a720684c3f2b36c4710a0a96528f",
+ "sha256:1d04f064bebdfef9240478f7a779e8c5dc32b8b7b0b2fc6a62e39b928d428e51",
+ "sha256:1fdc9fae8dd4c763e8a31e7630afef517eab9f5d5d31a278df087f307bf601f4",
+ "sha256:1ffc23010330c2ab67fac02781df60998ca8fe759e8efde6f8b756a20599c5de",
+ "sha256:20094fc3f21ea0a8669dc4c61ed7fa8263bd37d97d93b90f28fc613371e7a875",
+ "sha256:213261f168c5e1d9b7535a67e68b1f59f92398dd17a56d934550837143f79c42",
+ "sha256:218c1b2e17a710e363855594230f44060e2025b05c80d1f0661258142b2add2e",
+ "sha256:23e0553b8055600b3bf4a00b255ec5c92e1e4aebf8c2c09334f8368e8bd174d6",
+ "sha256:25f1b69d41656b05885aa185f5fdf822cb01a586d1b32739633679699f220391",
+ "sha256:2b3778cb38212f52fac9fe913017deea2fdf4eb1a4f8e4cfc6b009a13a6d3fcc",
+ "sha256:2bc9fd5ca4729af796f9f59cd8ff160fe06a474da40aca03fcc79655ddee1a8b",
+ "sha256:2c226a06ecb8cdef28845ae976da407917542c5e6e75dcac7cc33eb04aaeb237",
+ "sha256:2c3406b63232fc7e9b8783ab0b765d7c59e7c59ff96759d8ef9632fca27c7ee4",
+ "sha256:2c86bf781b12ba417f64f3422cfc302523ac9cd1d8ae8c0f92a1c66e56ef2e86",
+ "sha256:2d9b8d9177afaef80c53c0a9e30fa252ff3036fb1c6494d427c066a4ce6a282f",
+ "sha256:2dec2d1130a9cda5b904696cec33b2cfb451304ba9081eeda7f90f724097300a",
+ "sha256:2dfab5fa6a28a0b60a20638dc48e6343c02ea9933e3279ccb132f555a62323d8",
+ "sha256:2ecdd78ab768f844c7a1d4a03595038c166b609f6395e25af9b0f3f26ae1230f",
+ "sha256:315f9542011b2c4e1d280e4a20ddcca1761993dda3afc7a73b01235f8641e903",
+ "sha256:36aef61a1678cb778097b4a6eeae96a69875d51d1e8f4d4b491ab3cfb54b5a03",
+ "sha256:384aacddf2e5813a36495233b64cb96b1949da72bef933918ba5c84e06af8f0e",
+ "sha256:3879cc6ce938ff4eb4900d901ed63555c778731a96365e53fadb36437a131a99",
+ "sha256:3c174dc350d3ec52deb77f2faf05c439331d6ed5e702fc247ccb4e6b62d884b7",
+ "sha256:3eb44520c4724c2e1a57c0af33a379eee41792595023f367ba3952a2d96c2aab",
+ "sha256:406246b96d552e0503e17a1006fd27edac678b3fcc9f1be71a2f94b4ff61528d",
+ "sha256:41ce1f1e2c7755abfc7e759dc34d7d05fd221723ff822947132dc934d122fe22",
+ "sha256:423b121f7e6fa514ba0c7918e56955a1d4470ed35faa03e3d9f0e3baa4c7e492",
+ "sha256:44264ecae91b30e5633013fb66f6ddd05c006d3e0e884f75ce0b4755b3e3847b",
+ "sha256:482c2f67761868f0108b1743098640fbb2a28a8e15bf3f47ada9fa59d9fe08c3",
+ "sha256:4b0c7a688944891086ba192e21c5229dea54382f4836a209ff8d0a660fac06be",
+ "sha256:4c1fefd7e3d00921c44dc9ca80a775af49698bbfd92ea84498e56acffd4c5469",
+ "sha256:4e109ca30d1edec1ac60cdbe341905dc3b8f55b16855e03a54aaf59e51ec8c6f",
+ "sha256:501d0d7e26b4d261fca8132854d845e4988097611ba2531408ec91cf3fd9d20a",
+ "sha256:516f491c834eb320d6c843156440fe7fc0d50b33e44387fcec5b02f0bc118a4c",
+ "sha256:51806cfe0279e06ed8500ce19479d757db42a30fd509940b1701be9c86a5ff9a",
+ "sha256:562e7494778a69086f0312ec9689f6b6ac1c6b65670ed7d0267e49f57ffa08c4",
+ "sha256:56b9861a71575f5795bde89256e7467ece3d339c9b43141dbdd54544566b3b94",
+ "sha256:5b8f5db71b28b8c404956ddf79575ea77aa8b1538e8b2ef9ec877945b3f46442",
+ "sha256:5c2fb570d7823c2bbaf8b419ba6e5662137f8166e364a8b2b91051a1fb40ab8b",
+ "sha256:5c54afdcbb0182d06836cc3d1be921e540be3ebdf8b8a51ee3ef987537455f84",
+ "sha256:5d6a6972b93c426ace71e0be9a6f4b2cfae9b1baed2eed2006076a746692288c",
+ "sha256:609251a0ca4770e5a8768ff902aa02bf636339c5a93f9349b48eb1f606f7f3e9",
+ "sha256:62d172f358f33a26d6b41b28c170c63886742f5b6772a42b59b4f0fa10526cb1",
+ "sha256:62f7fdb0d1ed2065451f086519865b4c90aa19aed51081979ecd05a21eb4d1be",
+ "sha256:658f2aa69d31e09699705949b5fc4719cbecbd4a97f9656a232e7d6c7be1a367",
+ "sha256:65ab5685d56914b9a2a34d67dd5488b83213d680b0c5d10b47f81da5a16b0b0e",
+ "sha256:68934b242c51eb02907c5b81d138cb977b2129a0a75a8f8b60b01cb8586c7b21",
+ "sha256:68b87753c784d6acb8a25b05cb526c3406913c9d988d51f80adecc2b0775d6aa",
+ "sha256:69959bd3167b993e6e710b99051265654133a98f20cec1d9b493b931942e9c16",
+ "sha256:6a7095eeec6f89111d03dabfe5883a1fd54da319c94e0fb104ee8f23616b572d",
+ "sha256:6b038cc86b285e4f9fea2ba5ee76e89f21ed1ea898e287dc277a25884f3a7dfe",
+ "sha256:6ba0d3dcac281aad8a0e5b14c7ed6f9fa89c8612b47939fc94f80b16e2e9bc83",
+ "sha256:6e91cf736959057f7aac7adfc83481e03615a8e8dd5758aa1d95ea69e8931dba",
+ "sha256:6ee8c39582d2652dcd516d1b879451500f8db3fe3607ce45d7c5957ab2596040",
+ "sha256:6f651ebd0b21ec65dfca93aa629610a0dbc13dbc13554f19b0113da2e61a4763",
+ "sha256:71a8dd38fbd2f2319136d4ae855a7078c69c9a38ae06e0c17c73fd70fc6caad8",
+ "sha256:74068c601baff6ff021c70f0935b0c7bc528baa8ea210c202e03757c68c5a4ff",
+ "sha256:7437237c6a66b7ca341e868cda48be24b8701862757426852c9b3186de1da8a2",
+ "sha256:747a3d3e98e24597981ca0be0fd922aebd471fa99d0043a3842d00cdcad7ad6a",
+ "sha256:74bcb423462233bc5d6066e4e98b0264e7c1bed7541fff2f4e34fe6b21563c8b",
+ "sha256:78d9b952e07aed35fe2e1a7ad26e929595412db48535921c5013edc8aa4a35ce",
+ "sha256:7b1cd427cb0d5f7393c31b7496419da594fe600e6fdc4b105a54f82405e6626c",
+ "sha256:7d3d1ca42870cdb6d0d29939630dbe48fa511c203724820fc0fd507b2fb46577",
+ "sha256:7e2f58095acc211eb9d8b5771bf04df9ff37d6b87618d1cbf85f92399c98dae8",
+ "sha256:7f41026c1d64043a36fda21d64c5026762d53a77043e73e94b71f0521939cc71",
+ "sha256:81b4e48da4c69313192d8c8d4311e5d818b8be1afe68ee20f6385d0e96fc9512",
+ "sha256:86a6b24b19eaebc448dc56b87c4865527855145d851f9fc3891673ff97950540",
+ "sha256:874a216bf6afaf97c263b56371434e47e2c652d215788396f60477540298218f",
+ "sha256:89e043f1d9d341c52bf2af6d02e6adde62e0a46e6755d5eb60dc6e4f0b8aeca2",
+ "sha256:8c72e9563347c7395910de6a3100a4840a75a6f60e05af5e58566868d5eb2d6a",
+ "sha256:8dc2c0395bea8254d8daebc76dcf8eb3a95ec2a46fa6fae5eaccee366bfe02ce",
+ "sha256:8f0de2d390af441fe8b2c12626d103540b5d850d585b18fcada58d972b74a74e",
+ "sha256:92e67a0be1639c251d21e35fe74df6bcc40cba445c2cda7c4a967656733249e2",
+ "sha256:94d6c3782907b5e40e21cadf94b13b0842ac421192f26b84c45f13f3c9d5dc27",
+ "sha256:97acf1e1fd66ab53dacd2c35b319d7e548380c2e9e8c54525c6e76d21b1ae3b1",
+ "sha256:9ada35dd21dc6c039259596b358caab6b13f4db4d4a7f8665764d616daf9cc1d",
+ "sha256:9c52100e2c2dbb0649b90467935c4b0de5528833c76a35ea1a2691ec9f1ee7a1",
+ "sha256:9e41506fec7a7f9405b14aa2d5c8abbb4dbbd09d88f9496958b6d00cb4d45330",
+ "sha256:9e4b47ac0f5e749cfc618efdf4726269441014ae1d5583e047b452a32e221920",
+ "sha256:9fb81d2824dff4f2e297a276297e9031f46d2682cafc484f49de182aa5e5df99",
+ "sha256:a0eabd0a81625049c5df745209dc7fcef6e2aea7793e5f003ba363610aa0a3ff",
+ "sha256:a3d819eb6f9b8677f57f9664265d0a10dd6551d227afb4af2b9cd7bdc2ccbf18",
+ "sha256:a87de7dd873bf9a792bf1e58b1c3887b9264036629a5bf2d2e6579fe8e73edff",
+ "sha256:aa617107a410245b8660028a7483b68e7914304a6d4882b5ff3d2d3eb5948d8c",
+ "sha256:aac0bbd3e8dd2d9c45ceb82249e8bdd3ac99131a32b4d35c8af3cc9db1657179",
+ "sha256:ab6dd83b970dc97c2d10bc71aa925b84788c7c05de30241b9e96f9b6d9ea3080",
+ "sha256:ace2c2326a319a0bb8a8b0e5b570c764962e95818de9f259ce814ee666603f19",
+ "sha256:ae5fe5c4b525aa82b8076c1a59d642c17b6e8739ecf852522c6321852178119d",
+ "sha256:b11a5d918a6216e521c715b02749240fb07ae5a1fefd4b7bf12f833bc8b4fe70",
+ "sha256:b1c8c20847b9f34e98080da785bb2336ea982e7f913eed5809e5a3c872900f32",
+ "sha256:b369d3db3c22ed14c75ccd5af429086f166a19627e84a8fdade3f8f31426e52a",
+ "sha256:b710bc2b8292966b23a6a0121f7a6c51d45d2347edcc75f016ac123b8054d3f2",
+ "sha256:bd96517ef76c8654446fc3db9242d019a1bb5fe8b751ba414765d59f99210b79",
+ "sha256:c00f323cc00576df6165cc9d21a4c21285fa6b9989c5c39830c3903dc4303ef3",
+ "sha256:c162b216070f280fa7da844531169be0baf9ccb17263cf5a8bf876fcd3117fa5",
+ "sha256:c1a69e58a6bb2de65902051d57fde951febad631a20a64572677a1052690482f",
+ "sha256:c1f794c02903c2824fccce5b20c339a1a14b114e83b306ff11b597c5f71a1c8d",
+ "sha256:c24037349665434f375645fa9d1f5304800cec574d0310f618490c871fd902b3",
+ "sha256:c300306673aa0f3ed5ed9372b21867690a17dba38c68c44b287437c362ce486b",
+ "sha256:c56a1d43b2f9ee4786e4658c7903f05da35b923fb53c11025712562d5cc02753",
+ "sha256:c6379f35350b655fd817cd0d6cbeef7f265f3ae5fedb1caae2eb442bbeae9ab9",
+ "sha256:c802e1c2ed9f0c06a65bc4ed0189d000ada8049312cfeab6ca635e39c9608957",
+ "sha256:cb83f8a875b3d9b458cada4f880fa498646874ba4011dc974e071a0a84a1b033",
+ "sha256:cf120cce539453ae086eacc0130a324e7026113510efa83ab42ef3fcfccac7fb",
+ "sha256:dd36439be765e2dde7660212b5275641edbc813e7b24668831a5c8ac91180656",
+ "sha256:dd5350b55f9fecddc51385463a4f67a5da829bc741e38cf689f38ec9023f54ab",
+ "sha256:df5c7333167b9674aa8ae1d4008fa4bc17a313cc490b2cca27838bbdcc6bb15b",
+ "sha256:e63601ad5cd8f860aa99d109889b5ac34de571c7ee902d6812d5d9ddcc77fa7d",
+ "sha256:e92ce66cd919d18d14b3856906a61d3f6b6a8500e0794142338da644260595cd",
+ "sha256:e99f5507401436fdcc85036a2e7dc2e28d962550afe1cbfc07c40e454256a859",
+ "sha256:ea2e2f6f801696ad7de8aec061044d6c8c0dd4037608c7cab38a9a4d316bfb11",
+ "sha256:eafa2c8658f4e560b098fe9fc54539f86528651f61849b22111a9b107d18910c",
+ "sha256:ecd4ad8453ac17bc7ba3868371bffb46f628161ad0eefbd0a855d2c8c32dd81a",
+ "sha256:ee70d08fd60c9565ba8190f41a46a54096afa0eeb8f76bd66f2c25d3b1b83005",
+ "sha256:eec1bb8cdbba2925bedc887bc0609a80e599c75b12d87ae42ac23fd199445654",
+ "sha256:ef0c1fe22171dd7c7c27147f2e9c3e86f8bdf473fed75f16b0c2e84a5030ce80",
+ "sha256:f2901429da1e645ce548bf9171784c0f74f0718c3f6150ce166be39e4dd66c3e",
+ "sha256:f422a209d2455c56849442ae42f25dbaaba1c6c3f501d58761c619c7836642ec",
+ "sha256:f65e5120863c2b266dbcc927b306c5b78e502c71edf3295dfcb9501ec96e5fc7",
+ "sha256:f7d4a670107d75dfe5ad080bed6c341d18c4442f9378c9f58e5851e86eb79965",
+ "sha256:f914c03e6a31deb632e2daa881fe198461f4d06e57ac3d0e05bbcab8eae01945",
+ "sha256:fb66442c2546446944437df74379e9cf9e9db353e61301d1a0e26482f43f0dd8"
],
"markers": "python_version >= '3.6'",
- "version": "==5.2.1"
+ "version": "==5.3.0"
},
"mako": {
"hashes": [
- "sha256:5324b88089a8978bf76d1629774fcc2f1c07b82acdf00f4c5dd8ceadfffc4b40",
- "sha256:e16c01d9ab9c11f7290eef1cfefc093fb5a45ee4a3da09e2fec2e4d1bae54e73"
+ "sha256:260f1dbc3a519453a9c856dedfe4beb4e50bd5a26d96386cb6c80856556bb91a",
+ "sha256:48dbc20568c1d276a2698b36d968fa76161bf127194907ea6fc594fa81f943bc"
],
"markers": "python_version >= '3.8'",
- "version": "==1.3.3"
- },
- "markuppy": {
- "hashes": [
- "sha256:1adee2c0a542af378fe84548ff6f6b0168f3cb7f426b46961038a2bcfaad0d5f"
- ],
- "version": "==1.14"
+ "version": "==1.3.5"
},
"markupsafe": {
"hashes": [
@@ -832,18 +812,11 @@
},
"marshmallow": {
"hashes": [
- "sha256:4e65e9e0d80fc9e609574b9983cf32579f305c718afb30d7233ab818571768c3",
- "sha256:f085493f79efb0644f270a9bf2892843142d80d7174bbbd2f3713f2a589dc633"
+ "sha256:4972f529104a220bb8637d595aa4c9762afbe7f7a77d82dc58c1615d70c5823e",
+ "sha256:71a2dce49ef901c3f97ed296ae5051135fd3febd2bf43afe0ae9a82143a494d9"
],
"markers": "python_version >= '3.8'",
- "version": "==3.21.1"
- },
- "odfpy": {
- "hashes": [
- "sha256:db766a6e59c5103212f3cc92ec8dd50a0f3a02790233ed0b52148b70d3c438ec",
- "sha256:fc3b8d1bc098eba4a0fda865a76d9d1e577c4ceec771426bcb169a82c5e9dfe0"
- ],
- "version": "==1.4.1"
+ "version": "==3.22.0"
},
"oic": {
"hashes": [
@@ -854,13 +827,6 @@
"markers": "python_version ~= '3.8'",
"version": "==1.7.0"
},
- "openpyxl": {
- "hashes": [
- "sha256:a6f5977418eff3b2d5500d54d9db50c8277a368436f4e4f8ddb1be3422870184",
- "sha256:f91456ead12ab3c6c2e9491cf33ba6d08357d802192379bb482f1033ade496f5"
- ],
- "version": "==3.1.2"
- },
"orderedmultidict": {
"hashes": [
"sha256:04070bbb5e87291cc9bfa51df413677faf2141c73c61d2a5f7b26bea3cd882ad",
@@ -870,18 +836,18 @@
},
"packaging": {
"hashes": [
- "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5",
- "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"
+ "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002",
+ "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"
],
- "markers": "python_version >= '3.7'",
- "version": "==24.0"
+ "markers": "python_version >= '3.8'",
+ "version": "==24.1"
},
"phonenumberslite": {
"hashes": [
- "sha256:343b300d9c8ac4dca84e6b922ec51c3d838f2feabf9dd2418da64b639d220879",
- "sha256:64b513134b785fbeeaf4cc020e18d384541c4118ed3ece2118437d996f435ca0"
+ "sha256:63d650f2fe464602c8b01b7e0cda6b7057811a2410cbd1d21d90374642abdc51",
+ "sha256:ab6aa6e5fa115c89ea63e3c316c764ff449f8ecb826499cfc925f6a39f29e174"
],
- "version": "==8.13.35"
+ "version": "==8.13.44"
},
"psycopg2-binary": {
"hashes": [
@@ -1011,104 +977,114 @@
},
"pydantic": {
"hashes": [
- "sha256:e029badca45266732a9a79898a15ae2e8b14840b1eabbb25844be28f0b33f3d5",
- "sha256:e9dbb5eada8abe4d9ae5f46b9939aead650cd2b68f249bb3a8139dbe125803cc"
+ "sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a",
+ "sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8"
],
"markers": "python_version >= '3.8'",
- "version": "==2.7.1"
+ "version": "==2.8.2"
},
"pydantic-core": {
"hashes": [
- "sha256:0098300eebb1c837271d3d1a2cd2911e7c11b396eac9661655ee524a7f10587b",
- "sha256:042473b6280246b1dbf530559246f6842b56119c2926d1e52b631bdc46075f2a",
- "sha256:05b7133a6e6aeb8df37d6f413f7705a37ab4031597f64ab56384c94d98fa0e90",
- "sha256:0680b1f1f11fda801397de52c36ce38ef1c1dc841a0927a94f226dea29c3ae3d",
- "sha256:0d69b4c2f6bb3e130dba60d34c0845ba31b69babdd3f78f7c0c8fae5021a253e",
- "sha256:1404c69d6a676245199767ba4f633cce5f4ad4181f9d0ccb0577e1f66cf4c46d",
- "sha256:182245ff6b0039e82b6bb585ed55a64d7c81c560715d1bad0cbad6dfa07b4027",
- "sha256:1a388a77e629b9ec814c1b1e6b3b595fe521d2cdc625fcca26fbc2d44c816804",
- "sha256:1d90c3265ae107f91a4f279f4d6f6f1d4907ac76c6868b27dc7fb33688cfb347",
- "sha256:20aca1e2298c56ececfd8ed159ae4dde2df0781988c97ef77d5c16ff4bd5b400",
- "sha256:219da3f096d50a157f33645a1cf31c0ad1fe829a92181dd1311022f986e5fbe3",
- "sha256:22057013c8c1e272eb8d0eebc796701167d8377441ec894a8fed1af64a0bf399",
- "sha256:223ee893d77a310a0391dca6df00f70bbc2f36a71a895cecd9a0e762dc37b349",
- "sha256:224c421235f6102e8737032483f43c1a8cfb1d2f45740c44166219599358c2cd",
- "sha256:2334ce8c673ee93a1d6a65bd90327588387ba073c17e61bf19b4fd97d688d63c",
- "sha256:269322dcc3d8bdb69f054681edff86276b2ff972447863cf34c8b860f5188e2e",
- "sha256:2728b01246a3bba6de144f9e3115b532ee44bd6cf39795194fb75491824a1413",
- "sha256:2b8ed04b3582771764538f7ee7001b02e1170223cf9b75dff0bc698fadb00cf3",
- "sha256:2e29d20810dfc3043ee13ac7d9e25105799817683348823f305ab3f349b9386e",
- "sha256:36789b70d613fbac0a25bb07ab3d9dba4d2e38af609c020cf4d888d165ee0bf3",
- "sha256:390193c770399861d8df9670fb0d1874f330c79caaca4642332df7c682bf6b91",
- "sha256:3a6515ebc6e69d85502b4951d89131ca4e036078ea35533bb76327f8424531ce",
- "sha256:3f9a801e7c8f1ef8718da265bba008fa121243dfe37c1cea17840b0944dfd72c",
- "sha256:43f0f463cf89ace478de71a318b1b4f05ebc456a9b9300d027b4b57c1a2064fb",
- "sha256:4456f2dca97c425231d7315737d45239b2b51a50dc2b6f0c2bb181fce6207664",
- "sha256:470b94480bb5ee929f5acba6995251ada5e059a5ef3e0dfc63cca287283ebfa6",
- "sha256:4774f3184d2ef3e14e8693194f661dea5a4d6ca4e3dc8e39786d33a94865cefd",
- "sha256:4b4356d3538c3649337df4074e81b85f0616b79731fe22dd11b99499b2ebbdf3",
- "sha256:553ef617b6836fc7e4df130bb851e32fe357ce36336d897fd6646d6058d980af",
- "sha256:6132dd3bd52838acddca05a72aafb6eab6536aa145e923bb50f45e78b7251043",
- "sha256:6a46e22a707e7ad4484ac9ee9f290f9d501df45954184e23fc29408dfad61350",
- "sha256:6e5c584d357c4e2baf0ff7baf44f4994be121e16a2c88918a5817331fc7599d7",
- "sha256:75250dbc5290e3f1a0f4618db35e51a165186f9034eff158f3d490b3fed9f8a0",
- "sha256:75f7e9488238e920ab6204399ded280dc4c307d034f3924cd7f90a38b1829563",
- "sha256:78363590ef93d5d226ba21a90a03ea89a20738ee5b7da83d771d283fd8a56761",
- "sha256:7ca4ae5a27ad7a4ee5170aebce1574b375de390bc01284f87b18d43a3984df72",
- "sha256:800d60565aec896f25bc3cfa56d2277d52d5182af08162f7954f938c06dc4ee3",
- "sha256:82d5d4d78e4448683cb467897fe24e2b74bb7b973a541ea1dcfec1d3cbce39fb",
- "sha256:852e966fbd035a6468fc0a3496589b45e2208ec7ca95c26470a54daed82a0788",
- "sha256:868649da93e5a3d5eacc2b5b3b9235c98ccdbfd443832f31e075f54419e1b96b",
- "sha256:886eec03591b7cf058467a70a87733b35f44707bd86cf64a615584fd72488b7c",
- "sha256:8b172601454f2d7701121bbec3425dd71efcb787a027edf49724c9cefc14c038",
- "sha256:95b9d5e72481d3780ba3442eac863eae92ae43a5f3adb5b4d0a1de89d42bb250",
- "sha256:98758d627ff397e752bc339272c14c98199c613f922d4a384ddc07526c86a2ec",
- "sha256:997abc4df705d1295a42f95b4eec4950a37ad8ae46d913caeee117b6b198811c",
- "sha256:9b5155ff768083cb1d62f3e143b49a8a3432e6789a3abee8acd005c3c7af1c74",
- "sha256:9e08e867b306f525802df7cd16c44ff5ebbe747ff0ca6cf3fde7f36c05a59a81",
- "sha256:9fdad8e35f278b2c3eb77cbdc5c0a49dada440657bf738d6905ce106dc1de439",
- "sha256:a1874c6dd4113308bd0eb568418e6114b252afe44319ead2b4081e9b9521fe75",
- "sha256:a8309f67285bdfe65c372ea3722b7a5642680f3dba538566340a9d36e920b5f0",
- "sha256:ae0a8a797a5e56c053610fa7be147993fe50960fa43609ff2a9552b0e07013e8",
- "sha256:b14d82cdb934e99dda6d9d60dc84a24379820176cc4a0d123f88df319ae9c150",
- "sha256:b1bd7e47b1558ea872bd16c8502c414f9e90dcf12f1395129d7bb42a09a95438",
- "sha256:b3ef08e20ec49e02d5c6717a91bb5af9b20f1805583cb0adfe9ba2c6b505b5ae",
- "sha256:b89ed9eb7d616ef5714e5590e6cf7f23b02d0d539767d33561e3675d6f9e3857",
- "sha256:c4fcf5cd9c4b655ad666ca332b9a081112cd7a58a8b5a6ca7a3104bc950f2038",
- "sha256:c6fdc8627910eed0c01aed6a390a252fe3ea6d472ee70fdde56273f198938374",
- "sha256:c9bd70772c720142be1020eac55f8143a34ec9f82d75a8e7a07852023e46617f",
- "sha256:ca7b0c1f1c983e064caa85f3792dd2fe3526b3505378874afa84baf662e12241",
- "sha256:cbca948f2d14b09d20268cda7b0367723d79063f26c4ffc523af9042cad95592",
- "sha256:cc1cfd88a64e012b74e94cd00bbe0f9c6df57049c97f02bb07d39e9c852e19a4",
- "sha256:ccdd111c03bfd3666bd2472b674c6899550e09e9f298954cfc896ab92b5b0e6d",
- "sha256:cfeecd1ac6cc1fb2692c3d5110781c965aabd4ec5d32799773ca7b1456ac636b",
- "sha256:d4d938ec0adf5167cb335acb25a4ee69a8107e4984f8fbd2e897021d9e4ca21b",
- "sha256:d7d904828195733c183d20a54230c0df0eb46ec746ea1a666730787353e87182",
- "sha256:d91cb5ea8b11607cc757675051f61b3d93f15eca3cefb3e6c704a5d6e8440f4e",
- "sha256:d9319e499827271b09b4e411905b24a426b8fb69464dfa1696258f53a3334641",
- "sha256:e0e8b1be28239fc64a88a8189d1df7fad8be8c1ae47fcc33e43d4be15f99cc70",
- "sha256:e18609ceaa6eed63753037fc06ebb16041d17d28199ae5aba0052c51449650a9",
- "sha256:e1b395e58b10b73b07b7cf740d728dd4ff9365ac46c18751bf8b3d8cca8f625a",
- "sha256:e23ec367a948b6d812301afc1b13f8094ab7b2c280af66ef450efc357d2ae543",
- "sha256:e25add29b8f3b233ae90ccef2d902d0ae0432eb0d45370fe315d1a5cf231004b",
- "sha256:e6dac87ddb34aaec85f873d737e9d06a3555a1cc1a8e0c44b7f8d5daeb89d86f",
- "sha256:ef26c9e94a8c04a1b2924149a9cb081836913818e55681722d7f29af88fe7b38",
- "sha256:eff2de745698eb46eeb51193a9f41d67d834d50e424aef27df2fcdee1b153845",
- "sha256:f0a21cbaa69900cbe1a2e7cad2aa74ac3cf21b10c3efb0fa0b80305274c0e8a2",
- "sha256:f459a5ce8434614dfd39bbebf1041952ae01da6bed9855008cb33b875cb024c0",
- "sha256:f93a8a2e3938ff656a7c1bc57193b1319960ac015b6e87d76c76bf14fe0244b4",
- "sha256:fb2bd7be70c0fe4dfd32c951bc813d9fe6ebcbfdd15a07527796c8204bd36242"
+ "sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d",
+ "sha256:04024d270cf63f586ad41fff13fde4311c4fc13ea74676962c876d9577bcc78f",
+ "sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686",
+ "sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482",
+ "sha256:10d4204d8ca33146e761c79f83cc861df20e7ae9f6487ca290a97702daf56006",
+ "sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83",
+ "sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6",
+ "sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88",
+ "sha256:177f55a886d74f1808763976ac4efd29b7ed15c69f4d838bbd74d9d09cf6fa86",
+ "sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a",
+ "sha256:1eedfeb6089ed3fad42e81a67755846ad4dcc14d73698c120a82e4ccf0f1f9f6",
+ "sha256:225b67a1f6d602de0ce7f6c1c3ae89a4aa25d3de9be857999e9124f15dab486a",
+ "sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6",
+ "sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6",
+ "sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43",
+ "sha256:26ab812fa0c845df815e506be30337e2df27e88399b985d0bb4e3ecfe72df31c",
+ "sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4",
+ "sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e",
+ "sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203",
+ "sha256:2aafc5a503855ea5885559eae883978c9b6d8c8993d67766ee73d82e841300dd",
+ "sha256:2d036c7187b9422ae5b262badb87a20a49eb6c5238b2004e96d4da1231badef1",
+ "sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24",
+ "sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc",
+ "sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc",
+ "sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3",
+ "sha256:3c5ebac750d9d5f2706654c638c041635c385596caf68f81342011ddfa1e5598",
+ "sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98",
+ "sha256:407653af5617f0757261ae249d3fba09504d7a71ab36ac057c938572d1bc9331",
+ "sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2",
+ "sha256:41e81317dd6a0127cabce83c0c9c3fbecceae981c8391e6f1dec88a77c8a569a",
+ "sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6",
+ "sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688",
+ "sha256:4745f4ac52cc6686390c40eaa01d48b18997cb130833154801a442323cc78f91",
+ "sha256:4868f6bd7c9d98904b748a2653031fc9c2f85b6237009d475b1008bfaeb0a5aa",
+ "sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b",
+ "sha256:4dd484681c15e6b9a977c785a345d3e378d72678fd5f1f3c0509608da24f2ac0",
+ "sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840",
+ "sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c",
+ "sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd",
+ "sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3",
+ "sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231",
+ "sha256:5b5ff4911aea936a47d9376fd3ab17e970cc543d1b68921886e7f64bd28308d1",
+ "sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953",
+ "sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250",
+ "sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a",
+ "sha256:635fee4e041ab9c479e31edda27fcf966ea9614fff1317e280d99eb3e5ab6fe2",
+ "sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20",
+ "sha256:6b507132dcfc0dea440cce23ee2182c0ce7aba7054576efc65634f080dbe9434",
+ "sha256:6b9d9bb600328a1ce523ab4f454859e9d439150abb0906c5a1983c146580ebab",
+ "sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703",
+ "sha256:77bf3ac639c1ff567ae3b47f8d4cc3dc20f9966a2a6dd2311dcc055d3d04fb8a",
+ "sha256:784c1214cb6dd1e3b15dd8b91b9a53852aed16671cc3fbe4786f4f1db07089e2",
+ "sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac",
+ "sha256:7ed1b0132f24beeec5a78b67d9388656d03e6a7c837394f99257e2d55b461611",
+ "sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121",
+ "sha256:964faa8a861d2664f0c7ab0c181af0bea66098b1919439815ca8803ef136fc4e",
+ "sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b",
+ "sha256:9ebfef07dbe1d93efb94b4700f2d278494e9162565a54f124c404a5656d7ff09",
+ "sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906",
+ "sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9",
+ "sha256:a6d511cc297ff0883bc3708b465ff82d7560193169a8b93260f74ecb0a5e08a7",
+ "sha256:a8ad4c766d3f33ba8fd692f9aa297c9058970530a32c728a2c4bfd2616d3358b",
+ "sha256:aa2f457b4af386254372dfa78a2eda2563680d982422641a85f271c859df1987",
+ "sha256:b03f7941783b4c4a26051846dea594628b38f6940a2fdc0df00b221aed39314c",
+ "sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b",
+ "sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e",
+ "sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237",
+ "sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1",
+ "sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19",
+ "sha256:c6514f963b023aeee506678a1cf821fe31159b925c4b76fe2afa94cc70b3222b",
+ "sha256:c693e916709c2465b02ca0ad7b387c4f8423d1db7b4649c551f27a529181c5ad",
+ "sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0",
+ "sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94",
+ "sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312",
+ "sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f",
+ "sha256:d2fe69c5434391727efa54b47a1e7986bb0186e72a41b203df8f5b0a19a4f669",
+ "sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1",
+ "sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe",
+ "sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99",
+ "sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a",
+ "sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a",
+ "sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52",
+ "sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c",
+ "sha256:eaad4ff2de1c3823fddf82f41121bdf453d922e9a238642b1dedb33c4e4f98ad",
+ "sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1",
+ "sha256:f6d6cff3538391e8486a431569b77921adfcdef14eb18fbf19b7c0a5294d4e6a",
+ "sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f",
+ "sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a",
+ "sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27"
],
"markers": "python_version >= '3.8'",
- "version": "==2.18.2"
+ "version": "==2.20.1"
},
"pydantic-settings": {
"hashes": [
- "sha256:00b9f6a5e95553590434c0fa01ead0b216c3e10bc54ae02e37f359948643c5ed",
- "sha256:0235391d26db4d2190cb9b31051c4b46882d28a51533f97440867f012d4da091"
+ "sha256:bb6849dc067f1687574c12a639e231f3a6feeed0a12d710c1382045c5db1c315",
+ "sha256:ed81c3a0f46392b4d7c0a565c05884e6e54b3456e6f0fe4d8814981172dc9a88"
],
"markers": "python_version >= '3.8'",
- "version": "==2.2.1"
+ "version": "==2.4.0"
},
"pyjwkest": {
"hashes": [
@@ -1133,62 +1109,6 @@
"markers": "python_version >= '3.8'",
"version": "==1.0.1"
},
- "pyyaml": {
- "hashes": [
- "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5",
- "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc",
- "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df",
- "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741",
- "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206",
- "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27",
- "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595",
- "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62",
- "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98",
- "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696",
- "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290",
- "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9",
- "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d",
- "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6",
- "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867",
- "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47",
- "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486",
- "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6",
- "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3",
- "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007",
- "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938",
- "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0",
- "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c",
- "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735",
- "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d",
- "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28",
- "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4",
- "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba",
- "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8",
- "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef",
- "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5",
- "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd",
- "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3",
- "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0",
- "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515",
- "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c",
- "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c",
- "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924",
- "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34",
- "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43",
- "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859",
- "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673",
- "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54",
- "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a",
- "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b",
- "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab",
- "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa",
- "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c",
- "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585",
- "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d",
- "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"
- ],
- "version": "==6.0.1"
- },
"pyzipper": {
"hashes": [
"sha256:0adca90a00c36a93fbe49bfa8c5add452bfe4ef85a1b8e3638739dd1c7b26bfc",
@@ -1200,28 +1120,28 @@
},
"requests": {
"hashes": [
- "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f",
- "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"
+ "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760",
+ "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"
],
"index": "pypi",
- "markers": "python_version >= '3.7'",
- "version": "==2.31.0"
+ "markers": "python_version >= '3.8'",
+ "version": "==2.32.3"
},
"s3transfer": {
"hashes": [
- "sha256:5683916b4c724f799e600f41dd9e10a9ff19871bf87623cc8f491cb4f5fa0a19",
- "sha256:ceb252b11bcf87080fb7850a224fb6e05c8a776bab8f2b64b7f25b969464839d"
+ "sha256:0711534e9356d3cc692fdde846b4a1e4b0cb6519971860796e6bc4c7aea00ef6",
+ "sha256:eca1c20de70a39daee580aef4986996620f365c4e0fda6a86100231d62f1bf69"
],
"markers": "python_version >= '3.8'",
- "version": "==0.10.1"
+ "version": "==0.10.2"
},
"setuptools": {
"hashes": [
- "sha256:6c1fccdac05a97e598fb0ae3bbed5904ccb317337a51139dcd51453611bbb987",
- "sha256:c636ac361bc47580504644275c9ad802c50415c7522212252c033bd15f301f32"
+ "sha256:0274581a0037b638b9fc1c6883cc71c0210865aaa76073f7882376b641b84e8f",
+ "sha256:a85e96b8be2b906f3e3e789adec6a9323abf79758ecfa3065bd740d81158b11e"
],
"markers": "python_version >= '3.8'",
- "version": "==69.5.1"
+ "version": "==74.0.0"
},
"six": {
"hashes": [
@@ -1233,11 +1153,11 @@
},
"sqlparse": {
"hashes": [
- "sha256:714d0a4932c059d16189f58ef5411ec2287a4360f17cdd0edd2d09d4c5087c93",
- "sha256:c204494cd97479d0e39f28c93d46c0b2d5959c7b9ab904762ea6c7af211c8663"
+ "sha256:773dcbf9a5ab44a090f3441e2180efe2560220203dc2f8c0b0fa141e18b505e4",
+ "sha256:bb6b4df465655ef332548e24f08e205afc81b9ab86cb1c45657a7ff173a3a00e"
],
"markers": "python_version >= '3.8'",
- "version": "==0.5.0"
+ "version": "==0.5.1"
},
"tablib": {
"extras": [
@@ -1265,43 +1185,29 @@
},
"typing-extensions": {
"hashes": [
- "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0",
- "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a"
+ "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d",
+ "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==4.11.0"
+ "version": "==4.12.2"
},
"urllib3": {
"hashes": [
- "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d",
- "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"
+ "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472",
+ "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"
],
"markers": "python_version >= '3.8'",
- "version": "==2.2.1"
+ "version": "==2.2.2"
},
"whitenoise": {
"hashes": [
- "sha256:8998f7370973447fac1e8ef6e8ded2c5209a7b1f67c1012866dbcd09681c3251",
- "sha256:b1f9db9bf67dc183484d760b99f4080185633136a273a03f6436034a41064146"
+ "sha256:58c7a6cd811e275a6c91af22e96e87da0b1109e9a53bb7464116ef4c963bf636",
+ "sha256:a1ae85e01fdc9815d12fa33f17765bc132ed2c54fa76daf9e39e879dd93566f6"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==6.6.0"
- },
- "xlrd": {
- "hashes": [
- "sha256:6a33ee89877bd9abc1158129f6e94be74e2679636b8a205b43b85206c3f0bbdd",
- "sha256:f72f148f54442c6b056bf931dbc34f986fd0c3b0b6b5a58d013c9aef274d0c88"
- ],
- "version": "==2.0.1"
- },
- "xlwt": {
- "hashes": [
- "sha256:a082260524678ba48a297d922cc385f58278b8aa68741596a87de01a9c628b2e",
- "sha256:c59912717a9b28f1a3c2a98fd60741014b06b043936dcecbc113eaaada156c88"
- ],
- "version": "==1.3.0"
+ "version": "==6.7.0"
},
"zope.event": {
"hashes": [
@@ -1313,45 +1219,43 @@
},
"zope.interface": {
"hashes": [
- "sha256:014bb94fe6bf1786da1aa044eadf65bc6437bcb81c451592987e5be91e70a91e",
- "sha256:01a0b3dd012f584afcf03ed814bce0fc40ed10e47396578621509ac031be98bf",
- "sha256:10cde8dc6b2fd6a1d0b5ca4be820063e46ddba417ab82bcf55afe2227337b130",
- "sha256:187f7900b63845dcdef1be320a523dbbdba94d89cae570edc2781eb55f8c2f86",
- "sha256:1b0c4c90e5eefca2c3e045d9f9ed9f1e2cdbe70eb906bff6b247e17119ad89a1",
- "sha256:22e8a218e8e2d87d4d9342aa973b7915297a08efbebea5b25900c73e78ed468e",
- "sha256:26c9a37fb395a703e39b11b00b9e921c48f82b6e32cc5851ad5d0618cd8876b5",
- "sha256:2bb78c12c1ad3a20c0d981a043d133299117b6854f2e14893b156979ed4e1d2c",
- "sha256:2c3cfb272bcb83650e6695d49ae0d14dd06dc694789a3d929f23758557a23d92",
- "sha256:2f32010ffb87759c6a3ad1c65ed4d2e38e51f6b430a1ca11cee901ec2b42e021",
- "sha256:3c8731596198198746f7ce2a4487a0edcbc9ea5e5918f0ab23c4859bce56055c",
- "sha256:40aa8c8e964d47d713b226c5baf5f13cdf3a3169c7a2653163b17ff2e2334d10",
- "sha256:4137025731e824eee8d263b20682b28a0bdc0508de9c11d6c6be54163e5b7c83",
- "sha256:46034be614d1f75f06e7dcfefba21d609b16b38c21fc912b01a99cb29e58febb",
- "sha256:483e118b1e075f1819b3c6ace082b9d7d3a6a5eb14b2b375f1b80a0868117920",
- "sha256:4d6b229f5e1a6375f206455cc0a63a8e502ed190fe7eb15e94a312dc69d40299",
- "sha256:567d54c06306f9c5b6826190628d66753b9f2b0422f4c02d7c6d2b97ebf0a24e",
- "sha256:5683aa8f2639016fd2b421df44301f10820e28a9b96382a6e438e5c6427253af",
- "sha256:600101f43a7582d5b9504a7c629a1185a849ce65e60fca0f6968dfc4b76b6d39",
- "sha256:62e32f02b3f26204d9c02c3539c802afc3eefb19d601a0987836ed126efb1f21",
- "sha256:69dedb790530c7ca5345899a1b4cb837cc53ba669051ea51e8c18f82f9389061",
- "sha256:72d5efecad16c619a97744a4f0b67ce1bcc88115aa82fcf1dc5be9bb403bcc0b",
- "sha256:8d407e0fd8015f6d5dfad481309638e1968d70e6644e0753f229154667dd6cd5",
- "sha256:a058e6cf8d68a5a19cb5449f42a404f0d6c2778b897e6ce8fadda9cea308b1b0",
- "sha256:a1adc14a2a9d5e95f76df625a9b39f4709267a483962a572e3f3001ef90ea6e6",
- "sha256:a56fe1261230093bfeedc1c1a6cd6f3ec568f9b07f031c9a09f46b201f793a85",
- "sha256:ad4524289d8dbd6fb5aa17aedb18f5643e7d48358f42c007a5ee51a2afc2a7c5",
- "sha256:afa0491a9f154cf8519a02026dc85a416192f4cb1efbbf32db4a173ba28b289a",
- "sha256:bf34840e102d1d0b2d39b1465918d90b312b1119552cebb61a242c42079817b9",
- "sha256:c40df4aea777be321b7e68facb901bc67317e94b65d9ab20fb96e0eb3c0b60a1",
- "sha256:d0e7321557c702bd92dac3c66a2f22b963155fdb4600133b6b29597f62b71b12",
- "sha256:d165d7774d558ea971cb867739fb334faf68fc4756a784e689e11efa3becd59e",
- "sha256:e78a183a3c2f555c2ad6aaa1ab572d1c435ba42f1dc3a7e8c82982306a19b785",
- "sha256:e8fa0fb05083a1a4216b4b881fdefa71c5d9a106e9b094cd4399af6b52873e91",
- "sha256:f83d6b4b22262d9a826c3bd4b2fbfafe1d0000f085ef8e44cd1328eea274ae6a",
- "sha256:f95bebd0afe86b2adc074df29edb6848fc4d474ff24075e2c263d698774e108d"
+ "sha256:01e6e58078ad2799130c14a1d34ec89044ada0e1495329d72ee0407b9ae5100d",
+ "sha256:064ade95cb54c840647205987c7b557f75d2b2f7d1a84bfab4cf81822ef6e7d1",
+ "sha256:11fa1382c3efb34abf16becff8cb214b0b2e3144057c90611621f2d186b7e1b7",
+ "sha256:1bee1b722077d08721005e8da493ef3adf0b7908e0cd85cc7dc836ac117d6f32",
+ "sha256:1eeeb92cb7d95c45e726e3c1afe7707919370addae7ed14f614e22217a536958",
+ "sha256:21a207c6b2c58def5011768140861a73f5240f4f39800625072ba84e76c9da0b",
+ "sha256:2545d6d7aac425d528cd9bf0d9e55fcd47ab7fd15f41a64b1c4bf4c6b24946dc",
+ "sha256:2c4316a30e216f51acbd9fb318aa5af2e362b716596d82cbb92f9101c8f8d2e7",
+ "sha256:35062d93bc49bd9b191331c897a96155ffdad10744ab812485b6bad5b588d7e4",
+ "sha256:382d31d1e68877061daaa6499468e9eb38eb7625d4369b1615ac08d3860fe896",
+ "sha256:3aa8fcbb0d3c2be1bfd013a0f0acd636f6ed570c287743ae2bbd467ee967154d",
+ "sha256:3d4b91821305c8d8f6e6207639abcbdaf186db682e521af7855d0bea3047c8ca",
+ "sha256:3de1d553ce72868b77a7e9d598c9bff6d3816ad2b4cc81c04f9d8914603814f3",
+ "sha256:3fcdc76d0cde1c09c37b7c6b0f8beba2d857d8417b055d4f47df9c34ec518bdd",
+ "sha256:5112c530fa8aa2108a3196b9c2f078f5738c1c37cfc716970edc0df0414acda8",
+ "sha256:53d678bb1c3b784edbfb0adeebfeea6bf479f54da082854406a8f295d36f8386",
+ "sha256:6195c3c03fef9f87c0dbee0b3b6451df6e056322463cf35bca9a088e564a3c58",
+ "sha256:6d04b11ea47c9c369d66340dbe51e9031df2a0de97d68f442305ed7625ad6493",
+ "sha256:6dd647fcd765030638577fe6984284e0ebba1a1008244c8a38824be096e37fe3",
+ "sha256:799ef7a444aebbad5a145c3b34bff012b54453cddbde3332d47ca07225792ea4",
+ "sha256:7d92920416f31786bc1b2f34cc4fc4263a35a407425319572cbf96b51e835cd3",
+ "sha256:7e0c151a6c204f3830237c59ee4770cc346868a7a1af6925e5e38650141a7f05",
+ "sha256:84f8794bd59ca7d09d8fce43ae1b571be22f52748169d01a13d3ece8394d8b5b",
+ "sha256:95e5913ec718010dc0e7c215d79a9683b4990e7026828eedfda5268e74e73e11",
+ "sha256:9b9369671a20b8d039b8e5a1a33abd12e089e319a3383b4cc0bf5c67bd05fe7b",
+ "sha256:ab985c566a99cc5f73bc2741d93f1ed24a2cc9da3890144d37b9582965aff996",
+ "sha256:af94e429f9d57b36e71ef4e6865182090648aada0cb2d397ae2b3f7fc478493a",
+ "sha256:c96b3e6b0d4f6ddfec4e947130ec30bd2c7b19db6aa633777e46c8eecf1d6afd",
+ "sha256:cd2690d4b08ec9eaf47a85914fe513062b20da78d10d6d789a792c0b20307fb1",
+ "sha256:d3b7ce6d46fb0e60897d62d1ff370790ce50a57d40a651db91a3dde74f73b738",
+ "sha256:d976fa7b5faf5396eb18ce6c132c98e05504b52b60784e3401f4ef0b2e66709b",
+ "sha256:db6237e8fa91ea4f34d7e2d16d74741187e9105a63bbb5686c61fea04cdbacca",
+ "sha256:ecd32f30f40bfd8511b17666895831a51b532e93fc106bfa97f366589d3e4e0e",
+ "sha256:f418c88f09c3ba159b95a9d1cfcdbe58f208443abb1f3109f4b9b12fd60b187c"
],
- "markers": "python_version >= '3.7'",
- "version": "==6.3"
+ "markers": "python_version >= '3.8'",
+ "version": "==7.0.3"
}
},
"develop": {
@@ -1365,12 +1269,12 @@
},
"bandit": {
"hashes": [
- "sha256:36de50f720856ab24a24dbaa5fee2c66050ed97c1477e0a1159deab1775eab6b",
- "sha256:509f7af645bc0cd8fd4587abc1a038fc795636671ee8204d502b933aee44f381"
+ "sha256:52077cb339000f337fb25f7e045995c4ad01511e716e5daac37014b9752de8ec",
+ "sha256:7c395a436743018f7be0a4cbb0a4ea9b902b6d87264ddecf8cfdc73b4f78ff61"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==1.7.8"
+ "version": "==1.7.9"
},
"beautifulsoup4": {
"hashes": [
@@ -1382,49 +1286,49 @@
},
"black": {
"hashes": [
- "sha256:257d724c2c9b1660f353b36c802ccece186a30accc7742c176d29c146df6e474",
- "sha256:37aae07b029fa0174d39daf02748b379399b909652a806e5708199bd93899da1",
- "sha256:415e686e87dbbe6f4cd5ef0fbf764af7b89f9057b97c908742b6008cc554b9c0",
- "sha256:48a85f2cb5e6799a9ef05347b476cce6c182d6c71ee36925a6c194d074336ef8",
- "sha256:7768a0dbf16a39aa5e9a3ded568bb545c8c2727396d063bbaf847df05b08cd96",
- "sha256:7e122b1c4fb252fd85df3ca93578732b4749d9be076593076ef4d07a0233c3e1",
- "sha256:88c57dc656038f1ab9f92b3eb5335ee9b021412feaa46330d5eba4e51fe49b04",
- "sha256:8e537d281831ad0e71007dcdcbe50a71470b978c453fa41ce77186bbe0ed6021",
- "sha256:98e123f1d5cfd42f886624d84464f7756f60ff6eab89ae845210631714f6db94",
- "sha256:accf49e151c8ed2c0cdc528691838afd217c50412534e876a19270fea1e28e2d",
- "sha256:b1530ae42e9d6d5b670a34db49a94115a64596bc77710b1d05e9801e62ca0a7c",
- "sha256:b9176b9832e84308818a99a561e90aa479e73c523b3f77afd07913380ae2eab7",
- "sha256:bdde6f877a18f24844e381d45e9947a49e97933573ac9d4345399be37621e26c",
- "sha256:be8bef99eb46d5021bf053114442914baeb3649a89dc5f3a555c88737e5e98fc",
- "sha256:bf10f7310db693bb62692609b397e8d67257c55f949abde4c67f9cc574492cc7",
- "sha256:c872b53057f000085da66a19c55d68f6f8ddcac2642392ad3a355878406fbd4d",
- "sha256:d36ed1124bb81b32f8614555b34cc4259c3fbc7eec17870e8ff8ded335b58d8c",
- "sha256:da33a1a5e49c4122ccdfd56cd021ff1ebc4a1ec4e2d01594fef9b6f267a9e741",
- "sha256:dd1b5a14e417189db4c7b64a6540f31730713d173f0b63e55fabd52d61d8fdce",
- "sha256:e151054aa00bad1f4e1f04919542885f89f5f7d086b8a59e5000e6c616896ffb",
- "sha256:eaea3008c281f1038edb473c1aa8ed8143a5535ff18f978a318f10302b254063",
- "sha256:ef703f83fc32e131e9bcc0a5094cfe85599e7109f896fe8bc96cc402f3eb4b6e"
+ "sha256:09cdeb74d494ec023ded657f7092ba518e8cf78fa8386155e4a03fdcc44679e6",
+ "sha256:1f13f7f386f86f8121d76599114bb8c17b69d962137fc70efe56137727c7047e",
+ "sha256:2500945420b6784c38b9ee885af039f5e7471ef284ab03fa35ecdde4688cd83f",
+ "sha256:2b59b250fdba5f9a9cd9d0ece6e6d993d91ce877d121d161e4698af3eb9c1018",
+ "sha256:3c4285573d4897a7610054af5a890bde7c65cb466040c5f0c8b732812d7f0e5e",
+ "sha256:505289f17ceda596658ae81b61ebbe2d9b25aa78067035184ed0a9d855d18afd",
+ "sha256:62e8730977f0b77998029da7971fa896ceefa2c4c4933fcd593fa599ecbf97a4",
+ "sha256:649f6d84ccbae73ab767e206772cc2d7a393a001070a4c814a546afd0d423aed",
+ "sha256:6e55d30d44bed36593c3163b9bc63bf58b3b30e4611e4d88a0c3c239930ed5b2",
+ "sha256:707a1ca89221bc8a1a64fb5e15ef39cd755633daa672a9db7498d1c19de66a42",
+ "sha256:72901b4913cbac8972ad911dc4098d5753704d1f3c56e44ae8dce99eecb0e3af",
+ "sha256:73bbf84ed136e45d451a260c6b73ed674652f90a2b3211d6a35e78054563a9bb",
+ "sha256:7c046c1d1eeb7aea9335da62472481d3bbf3fd986e093cffd35f4385c94ae368",
+ "sha256:81c6742da39f33b08e791da38410f32e27d632260e599df7245cccee2064afeb",
+ "sha256:837fd281f1908d0076844bc2b801ad2d369c78c45cf800cad7b61686051041af",
+ "sha256:972085c618ee94f402da1af548a4f218c754ea7e5dc70acb168bfaca4c2542ed",
+ "sha256:9e84e33b37be070ba135176c123ae52a51f82306def9f7d063ee302ecab2cf47",
+ "sha256:b19c9ad992c7883ad84c9b22aaa73562a16b819c1d8db7a1a1a49fb7ec13c7d2",
+ "sha256:d6417535d99c37cee4091a2f24eb2b6d5ec42b144d50f1f2e436d9fe1916fe1a",
+ "sha256:eab4dd44ce80dea27dc69db40dab62d4ca96112f87996bca68cd75639aeb2e4c",
+ "sha256:f490dbd59680d809ca31efdae20e634f3fae27fba3ce0ba3208333b713bc3920",
+ "sha256:fb6e2c0b86bbd43dee042e48059c9ad7830abd5c94b0bc518c0eeec57c3eddc1"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==24.4.2"
+ "version": "==24.8.0"
},
"blinker": {
"hashes": [
- "sha256:5f1cdeff423b77c31b89de0565cd03e5275a03028f44b2b15f912632a58cced6",
- "sha256:da44ec748222dcd0105ef975eed946da197d5bdf8bafb6aa92f5bc89da63fa25"
+ "sha256:1779309f71bf239144b9399d06ae925637cf6634cf6bd131104184531bf67c01",
+ "sha256:8f77b09d3bf7c795e969e9486f39c2c5e9c39d4ee07424be2bc594ece9642d83"
],
"markers": "python_version >= '3.8'",
- "version": "==1.8.1"
+ "version": "==1.8.2"
},
"boto3": {
"hashes": [
- "sha256:decf52f8d5d8a1b10c9ff2a0e96ee207ed79e33d2e53fdf0880a5cbef70785e0",
- "sha256:e836b71d79671270fccac0a4d4c8ec239a6b82ea47c399b64675aa597d0ee63b"
+ "sha256:06eac4757de2a9c6020381205cb902f05964caad80b56e58c8931284a133b4cb",
+ "sha256:b9587131372a808bf6f99c5ed8b11be55cd113261cc3b437a917b4acc6c30bfe"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==1.34.95"
+ "version": "==1.35.8"
},
"boto3-mocking": {
"hashes": [
@@ -1437,28 +1341,28 @@
},
"boto3-stubs": {
"hashes": [
- "sha256:412006b27ee707e9b51a084b02ac92b143af8a3b56727582afec2a76ce93c3b6",
- "sha256:4fb5830626de42446c238ca72ca1a53e461281396007fb900edf50ceeb044a10"
+ "sha256:cfe2c813d8a43b91cccd7d1d4230b781fe3572e2d13e42d5ba60d78b42638bc8",
+ "sha256:e5767b1aabdbc5e84915e533f852605bbb07cfe1b86fe172ab27654a2f24b48d"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==1.34.95"
+ "version": "==1.35.8"
},
"botocore": {
"hashes": [
- "sha256:6bd76a2eadb42b91fa3528392e981ad5b4dfdee3968fa5b904278acf6cbf15ff",
- "sha256:ead5823e0dd6751ece5498cb979fd9abf190e691c8833bcac6876fd6ca261fa7"
+ "sha256:4b820cf680ab5d778bd2fe4feeef1ff8a2b96d5c535d4638ab30f703ade282f8",
+ "sha256:adf389eb8fd87775f193300e3431d1353f925807ad3a39958172cb644f0d60a1"
],
"markers": "python_version >= '3.8'",
- "version": "==1.34.95"
+ "version": "==1.35.8"
},
"botocore-stubs": {
"hashes": [
- "sha256:64d80a3467e3b19939e9c2750af33328b3087f8f524998dbdf7ed168227f507d",
- "sha256:b0345f55babd8b901c53804fc5c326a4a0bd2e23e3b71f9ea5d9f7663466e6ba"
+ "sha256:a49f9db19259dc280fee73d74f3a171310f3916a12e679b6c4bf8f719cb37461",
+ "sha256:dac2ebedcd8b0c98be89d6e708fa9ce6d5d12e1bc6b629e77ae8c0d289088c49"
],
- "markers": "python_version >= '3.8' and python_version < '4.0'",
- "version": "==1.34.94"
+ "markers": "python_version >= '3.8'",
+ "version": "==1.35.8"
},
"click": {
"hashes": [
@@ -1479,36 +1383,36 @@
},
"django-debug-toolbar": {
"hashes": [
- "sha256:0b0dddee5ea29b9cb678593bc0d7a6d76b21d7799cb68e091a2148341a80f3c4",
- "sha256:e09b7dcb8417b743234dfc57c95a7c1d1d87a88844abd13b4c5387f807b31bf6"
+ "sha256:36e421cb908c2f0675e07f9f41e3d1d8618dc386392ec82d23bcfcd5d29c7044",
+ "sha256:3beb671c9ec44ffb817fad2780667f172bd1c067dbcabad6268ce39a81335f45"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==4.3.0"
+ "version": "==4.4.6"
},
"django-model2puml": {
"hashes": [
- "sha256:6e773d742e556020a04d3216ce5dee5d3551da162e2d42a997f85b4ed1854771"
+ "sha256:f7ef57efbf261e8e0f90043c2be379e9457b30603ccc01fe7a01c233d0dfa27c"
],
"index": "pypi",
- "version": "==0.4.1"
+ "version": "==0.5.1"
},
"django-stubs": {
"hashes": [
- "sha256:084484cbe16a6d388e80ec687e46f529d67a232f3befaf55c936b3b476be289d",
- "sha256:b8a792bee526d6cab31e197cb414ee7fa218abd931a50948c66a80b3a2548621"
+ "sha256:78e3764488fdfd2695f12502136548ec22f8d4b1780541a835042b8238d11514",
+ "sha256:c2502f5ecbae50c68f9a86d52b5b2447d8648fd205036dad0ccb41e19a445927"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==5.0.0"
+ "version": "==5.0.4"
},
"django-stubs-ext": {
"hashes": [
- "sha256:5bacfbb498a206d5938454222b843d81da79ea8b6fcd1a59003f529e775bc115",
- "sha256:8e1334fdf0c8bff87e25d593b33d4247487338aaed943037826244ff788b56a8"
+ "sha256:85da065224204774208be29c7d02b4482d5a69218a728465c2fbe41725fdc819",
+ "sha256:910cbaff3d1e8e806a5c27d5ddd4088535aae8371ea921b7fd680fdfa5f14e30"
],
"markers": "python_version >= '3.8'",
- "version": "==5.0.0"
+ "version": "==5.0.4"
},
"django-webtest": {
"hashes": [
@@ -1520,12 +1424,12 @@
},
"flake8": {
"hashes": [
- "sha256:33f96621059e65eec474169085dc92bf26e7b2d47366b70be2f67ab80dc25132",
- "sha256:a6dfbb75e03252917f2473ea9653f7cd799c3064e54d4c8140044c5c065f53c3"
+ "sha256:049d058491e228e03e67b390f311bbf88fce2dbaa8fa673e7aea87b7198b8d38",
+ "sha256:597477df7860daa5aa0fdd84bf5208a043ab96b8e96ab708770ae0364dd03213"
],
"index": "pypi",
"markers": "python_full_version >= '3.8.1'",
- "version": "==7.0.0"
+ "version": "==7.1.1"
},
"jmespath": {
"hashes": [
@@ -1561,37 +1465,37 @@
},
"mypy": {
"hashes": [
- "sha256:075cbf81f3e134eadaf247de187bd604748171d6b79736fa9b6c9685b4083061",
- "sha256:12b6bfc1b1a66095ab413160a6e520e1dc076a28f3e22f7fb25ba3b000b4ef99",
- "sha256:1ec404a7cbe9fc0e92cb0e67f55ce0c025014e26d33e54d9e506a0f2d07fe5de",
- "sha256:28d0e038361b45f099cc086d9dd99c15ff14d0188f44ac883010e172ce86c38a",
- "sha256:2b0695d605ddcd3eb2f736cd8b4e388288c21e7de85001e9f85df9187f2b50f9",
- "sha256:3236a4c8f535a0631f85f5fcdffba71c7feeef76a6002fcba7c1a8e57c8be1ec",
- "sha256:3be66771aa5c97602f382230165b856c231d1277c511c9a8dd058be4784472e1",
- "sha256:3d087fcbec056c4ee34974da493a826ce316947485cef3901f511848e687c131",
- "sha256:3f298531bca95ff615b6e9f2fc0333aae27fa48052903a0ac90215021cdcfa4f",
- "sha256:4a2b5cdbb5dd35aa08ea9114436e0d79aceb2f38e32c21684dcf8e24e1e92821",
- "sha256:4cf18f9d0efa1b16478c4c129eabec36148032575391095f73cae2e722fcf9d5",
- "sha256:8b2cbaca148d0754a54d44121b5825ae71868c7592a53b7292eeb0f3fdae95ee",
- "sha256:8f55583b12156c399dce2df7d16f8a5095291354f1e839c252ec6c0611e86e2e",
- "sha256:92f93b21c0fe73dc00abf91022234c79d793318b8a96faac147cd579c1671746",
- "sha256:9e36fb078cce9904c7989b9693e41cb9711e0600139ce3970c6ef814b6ebc2b2",
- "sha256:9fd50226364cd2737351c79807775136b0abe084433b55b2e29181a4c3c878c0",
- "sha256:a781f6ad4bab20eef8b65174a57e5203f4be627b46291f4589879bf4e257b97b",
- "sha256:a87dbfa85971e8d59c9cc1fcf534efe664d8949e4c0b6b44e8ca548e746a8d53",
- "sha256:b808e12113505b97d9023b0b5e0c0705a90571c6feefc6f215c1df9381256e30",
- "sha256:bc6ac273b23c6b82da3bb25f4136c4fd42665f17f2cd850771cb600bdd2ebeda",
- "sha256:cd777b780312ddb135bceb9bc8722a73ec95e042f911cc279e2ec3c667076051",
- "sha256:da1cbf08fb3b851ab3b9523a884c232774008267b1f83371ace57f412fe308c2",
- "sha256:e22e1527dc3d4aa94311d246b59e47f6455b8729f4968765ac1eacf9a4760bc7",
- "sha256:f8c083976eb530019175aabadb60921e73b4f45736760826aa1689dda8208aee",
- "sha256:f90cff89eea89273727d8783fef5d4a934be2fdca11b47def50cf5d311aff727",
- "sha256:fa7ef5244615a2523b56c034becde4e9e3f9b034854c93639adb667ec9ec2976",
- "sha256:fcfc70599efde5c67862a07a1aaf50e55bce629ace26bb19dc17cece5dd31ca4"
+ "sha256:06d26c277962f3fb50e13044674aa10553981ae514288cb7d0a738f495550b36",
+ "sha256:2ff93107f01968ed834f4256bc1fc4475e2fecf6c661260066a985b52741ddce",
+ "sha256:36383a4fcbad95f2657642a07ba22ff797de26277158f1cc7bd234821468b1b6",
+ "sha256:37c7fa6121c1cdfcaac97ce3d3b5588e847aa79b580c1e922bb5d5d2902df19b",
+ "sha256:3a66169b92452f72117e2da3a576087025449018afc2d8e9bfe5ffab865709ca",
+ "sha256:3f14cd3d386ac4d05c5a39a51b84387403dadbd936e17cb35882134d4f8f0d24",
+ "sha256:41ea707d036a5307ac674ea172875f40c9d55c5394f888b168033177fce47383",
+ "sha256:478db5f5036817fe45adb7332d927daa62417159d49783041338921dcf646fc7",
+ "sha256:4a8a53bc3ffbd161b5b2a4fff2f0f1e23a33b0168f1c0778ec70e1a3d66deb86",
+ "sha256:539c570477a96a4e6fb718b8d5c3e0c0eba1f485df13f86d2970c91f0673148d",
+ "sha256:57555a7715c0a34421013144a33d280e73c08df70f3a18a552938587ce9274f4",
+ "sha256:6e658bd2d20565ea86da7d91331b0eed6d2eee22dc031579e6297f3e12c758c8",
+ "sha256:6e7184632d89d677973a14d00ae4d03214c8bc301ceefcdaf5c474866814c987",
+ "sha256:75746e06d5fa1e91bfd5432448d00d34593b52e7e91a187d981d08d1f33d4385",
+ "sha256:7f9993ad3e0ffdc95c2a14b66dee63729f021968bff8ad911867579c65d13a79",
+ "sha256:801780c56d1cdb896eacd5619a83e427ce436d86a3bdf9112527f24a66618fef",
+ "sha256:801ca29f43d5acce85f8e999b1e431fb479cb02d0e11deb7d2abb56bdaf24fd6",
+ "sha256:969ea3ef09617aff826885a22ece0ddef69d95852cdad2f60c8bb06bf1f71f70",
+ "sha256:a976775ab2256aadc6add633d44f100a2517d2388906ec4f13231fafbb0eccca",
+ "sha256:af8d155170fcf87a2afb55b35dc1a0ac21df4431e7d96717621962e4b9192e70",
+ "sha256:b499bc07dbdcd3de92b0a8b29fdf592c111276f6a12fe29c30f6c417dd546d12",
+ "sha256:cd953f221ac1379050a8a646585a29574488974f79d8082cedef62744f0a0104",
+ "sha256:d42a6dd818ffce7be66cce644f1dff482f1d97c53ca70908dff0b9ddc120b77a",
+ "sha256:e8960dbbbf36906c5c0b7f4fbf2f0c7ffb20f4898e6a879fcf56a41a08b0d318",
+ "sha256:edb91dded4df17eae4537668b23f0ff6baf3707683734b6a818d5b9d0c0c31a1",
+ "sha256:ee23de8530d99b6db0573c4ef4bd8f39a2a6f9b60655bf7a1357e585a3486f2b",
+ "sha256:f7821776e5c4286b6a13138cc935e2e9b6fde05e081bdebf5cdb2bb97c9df81d"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==1.10.0"
+ "version": "==1.11.2"
},
"mypy-extensions": {
"hashes": [
@@ -1611,11 +1515,11 @@
},
"packaging": {
"hashes": [
- "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5",
- "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"
+ "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002",
+ "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"
],
- "markers": "python_version >= '3.7'",
- "version": "==24.0"
+ "markers": "python_version >= '3.8'",
+ "version": "==24.1"
},
"pathspec": {
"hashes": [
@@ -1627,27 +1531,27 @@
},
"pbr": {
"hashes": [
- "sha256:4a7317d5e3b17a3dccb6a8cfe67dab65b20551404c52c8ed41279fa4f0cb4cda",
- "sha256:d1377122a5a00e2f940ee482999518efe16d745d423a670c27773dfbc3c9a7d9"
+ "sha256:788183e382e3d1d7707db08978239965e8b9e4e5ed42669bf4758186734d5f24",
+ "sha256:a776ae228892d8013649c0aeccbb3d5f99ee15e005a4cbb7e61d55a067b28a2a"
],
"markers": "python_version >= '2.6'",
- "version": "==6.0.0"
+ "version": "==6.1.0"
},
"platformdirs": {
"hashes": [
- "sha256:031cd18d4ec63ec53e82dceaac0417d218a6863f7745dfcc9efe7793b7039bdf",
- "sha256:17d5a1161b3fd67b390023cb2d3b026bbd40abde6fdb052dfbd3a29c3ba22ee1"
+ "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee",
+ "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"
],
"markers": "python_version >= '3.8'",
- "version": "==4.2.1"
+ "version": "==4.2.2"
},
"pycodestyle": {
"hashes": [
- "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f",
- "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"
+ "sha256:46f0fb92069a7c28ab7bb558f05bfc0110dac69a0cd23c61ea0040283a9d78b3",
+ "sha256:6838eae08bbce4f6accd5d5572075c63626a15ee3e6f842df996bf62f6d73521"
],
"markers": "python_version >= '3.8'",
- "version": "==2.11.1"
+ "version": "==2.12.1"
},
"pyflakes": {
"hashes": [
@@ -1659,11 +1563,11 @@
},
"pygments": {
"hashes": [
- "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c",
- "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"
+ "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199",
+ "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"
],
- "markers": "python_version >= '3.7'",
- "version": "==2.17.2"
+ "markers": "python_version >= '3.8'",
+ "version": "==2.18.0"
},
"python-dateutil": {
"hashes": [
@@ -1675,75 +1579,78 @@
},
"pyyaml": {
"hashes": [
- "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5",
- "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc",
- "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df",
- "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741",
- "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206",
- "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27",
- "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595",
- "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62",
- "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98",
- "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696",
- "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290",
- "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9",
- "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d",
- "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6",
- "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867",
- "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47",
- "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486",
- "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6",
- "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3",
- "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007",
- "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938",
- "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0",
- "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c",
- "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735",
- "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d",
- "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28",
- "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4",
- "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba",
- "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8",
- "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef",
- "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5",
- "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd",
- "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3",
- "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0",
- "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515",
- "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c",
- "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c",
- "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924",
- "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34",
- "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43",
- "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859",
- "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673",
- "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54",
- "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a",
- "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b",
- "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab",
- "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa",
- "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c",
- "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585",
- "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d",
- "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"
+ "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff",
+ "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48",
+ "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086",
+ "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e",
+ "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133",
+ "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5",
+ "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484",
+ "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee",
+ "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5",
+ "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68",
+ "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a",
+ "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf",
+ "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99",
+ "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8",
+ "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85",
+ "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19",
+ "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc",
+ "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a",
+ "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1",
+ "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317",
+ "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c",
+ "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631",
+ "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d",
+ "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652",
+ "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5",
+ "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e",
+ "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b",
+ "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8",
+ "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476",
+ "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706",
+ "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563",
+ "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237",
+ "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b",
+ "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083",
+ "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180",
+ "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425",
+ "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e",
+ "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f",
+ "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725",
+ "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183",
+ "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab",
+ "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774",
+ "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725",
+ "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e",
+ "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5",
+ "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d",
+ "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290",
+ "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44",
+ "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed",
+ "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4",
+ "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba",
+ "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12",
+ "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"
],
- "version": "==6.0.1"
+ "markers": "python_version >= '3.8'",
+ "version": "==6.0.2"
},
"rich": {
"hashes": [
- "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222",
- "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432"
+ "sha256:2e85306a063b9492dffc86278197a60cbece75bcb766022f3436f567cae11bdc",
+ "sha256:a5ac1f1cd448ade0d59cc3356f7db7a7ccda2c8cbae9c7a90c28ff463d3e91f4"
],
"markers": "python_full_version >= '3.7.0'",
- "version": "==13.7.1"
+ "version": "==13.8.0"
},
"s3transfer": {
"hashes": [
- "sha256:5683916b4c724f799e600f41dd9e10a9ff19871bf87623cc8f491cb4f5fa0a19",
- "sha256:ceb252b11bcf87080fb7850a224fb6e05c8a776bab8f2b64b7f25b969464839d"
+ "sha256:0711534e9356d3cc692fdde846b4a1e4b0cb6519971860796e6bc4c7aea00ef6",
+ "sha256:eca1c20de70a39daee580aef4986996620f365c4e0fda6a86100231d62f1bf69"
],
"markers": "python_version >= '3.8'",
- "version": "==0.10.1"
+ "version": "==0.10.2"
},
"six": {
"hashes": [
@@ -1755,27 +1662,27 @@
},
"soupsieve": {
"hashes": [
- "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690",
- "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7"
+ "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb",
+ "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9"
],
"markers": "python_version >= '3.8'",
- "version": "==2.5"
+ "version": "==2.6"
},
"sqlparse": {
"hashes": [
- "sha256:714d0a4932c059d16189f58ef5411ec2287a4360f17cdd0edd2d09d4c5087c93",
- "sha256:c204494cd97479d0e39f28c93d46c0b2d5959c7b9ab904762ea6c7af211c8663"
+ "sha256:773dcbf9a5ab44a090f3441e2180efe2560220203dc2f8c0b0fa141e18b505e4",
+ "sha256:bb6b4df465655ef332548e24f08e205afc81b9ab86cb1c45657a7ff173a3a00e"
],
"markers": "python_version >= '3.8'",
- "version": "==0.5.0"
+ "version": "==0.5.1"
},
"stevedore": {
"hashes": [
- "sha256:1c15d95766ca0569cad14cb6272d4d31dae66b011a929d7c18219c176ea1b5c9",
- "sha256:46b93ca40e1114cea93d738a6c1e365396981bb6bb78c27045b7587c9473544d"
+ "sha256:1efd34ca08f474dad08d9b19e934a22c68bb6fe416926479ba29e5013bcc8f78",
+ "sha256:9a64265f4060312828151c204efbe9b7a9852a0d9228756344dbc7e4023e375a"
],
"markers": "python_version >= '3.8'",
- "version": "==5.2.0"
+ "version": "==5.3.0"
},
"tomli": {
"hashes": [
@@ -1787,62 +1694,62 @@
},
"types-awscrt": {
"hashes": [
- "sha256:3ae374b553e7228ba41a528cf42bd0b2ad7303d806c73eff4aaaac1515e3ea4e",
- "sha256:64898a2f4a2468f66233cb8c29c5f66de907cf80ba1ef5bb1359aef2f81bb521"
+ "sha256:0839fe12f0f914d8f7d63ed777c728cb4eccc2d5d79a26e377d12b0604e7bf0e",
+ "sha256:84a9f4f422ec525c314fdf54c23a1e73edfbcec968560943ca2d41cfae623b38"
],
"markers": "python_version >= '3.7' and python_version < '4.0'",
- "version": "==0.20.9"
+ "version": "==0.21.2"
},
"types-cachetools": {
"hashes": [
- "sha256:27c982cdb9cf3fead8b0089ee6b895715ecc99dac90ec29e2cab56eb1aaf4199",
- "sha256:98c069dc7fc087b1b061703369c80751b0a0fc561f6fb072b554e5eee23773a0"
+ "sha256:b888ab5c1a48116f7799cd5004b18474cd82b5463acb5ffb2db2fc9c7b053bc0",
+ "sha256:efb2ed8bf27a4b9d3ed70d33849f536362603a90b8090a328acf0cd42fda82e2"
],
"index": "pypi",
- "markers": "python_version >= '3.7'",
- "version": "==5.3.0.7"
+ "markers": "python_version >= '3.8'",
+ "version": "==5.5.0.20240820"
},
"types-pyyaml": {
"hashes": [
- "sha256:a9e0f0f88dc835739b0c1ca51ee90d04ca2a897a71af79de9aec5f38cb0a5342",
- "sha256:b845b06a1c7e54b8e5b4c683043de0d9caf205e7434b3edc678ff2411979b8f6"
+ "sha256:b8f76ddbd7f65440a8bda5526a9607e4c7a322dc2f8e1a8c405644f9a6f4b9af",
+ "sha256:deda34c5c655265fc517b546c902aa6eed2ef8d3e921e4765fe606fe2afe8d35"
],
"markers": "python_version >= '3.8'",
- "version": "==6.0.12.20240311"
+ "version": "==6.0.12.20240808"
},
"types-requests": {
"hashes": [
- "sha256:4428df33c5503945c74b3f42e82b181e86ec7b724620419a2966e2de604ce1a1",
- "sha256:6216cdac377c6b9a040ac1c0404f7284bd13199c0e1bb235f4324627e8898cf5"
+ "sha256:90c079ff05e549f6bf50e02e910210b98b8ff1ebdd18e19c873cd237737c1358",
+ "sha256:f754283e152c752e46e70942fa2a146b5bc70393522257bb85bd1ef7e019dcc3"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==2.31.0.20240406"
+ "version": "==2.32.0.20240712"
},
"types-s3transfer": {
"hashes": [
- "sha256:02154cce46528287ad76ad1a0153840e0492239a0887e8833466eccf84b98da0",
- "sha256:49a7c81fa609ac1532f8de3756e64b58afcecad8767933310228002ec7adff74"
+ "sha256:60167a3bfb5c536ec6cdb5818f7f9a28edca9dc3e0b5ff85ae374526fc5e576e",
+ "sha256:7a3fec8cd632e2b5efb665a355ef93c2a87fdd5a45b74a949f95a9e628a86356"
],
- "markers": "python_version >= '3.8' and python_version < '4.0'",
- "version": "==0.10.1"
+ "markers": "python_version >= '3.8'",
+ "version": "==0.10.2"
},
"typing-extensions": {
"hashes": [
- "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0",
- "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a"
+ "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d",
+ "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==4.11.0"
+ "version": "==4.12.2"
},
"urllib3": {
"hashes": [
- "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d",
- "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"
+ "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472",
+ "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"
],
"markers": "python_version >= '3.8'",
- "version": "==2.2.1"
+ "version": "==2.2.2"
},
"waitress": {
"hashes": [
@@ -1854,11 +1761,11 @@
},
"webob": {
"hashes": [
- "sha256:73aae30359291c14fa3b956f8b5ca31960e420c28c1bec002547fb04928cf89b",
- "sha256:b64ef5141be559cfade448f044fa45c2260351edcb6a8ef6b7e00c7dcef0c323"
+ "sha256:2abc1555e118fc251e705fc6dc66c7f5353bb9fbfab6d20e22f1c02b4b71bcee",
+ "sha256:b60ba63f05c0cf61e086a10c3781a41fcfe30027753a8ae6d819c77592ce83ea"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
- "version": "==1.8.7"
+ "version": "==1.8.8"
},
"webtest": {
"hashes": [
diff --git a/src/models_diagram.puml b/src/models_diagram.puml
new file mode 100644
index 000000000..84c3cea39
--- /dev/null
+++ b/src/models_diagram.puml
@@ -0,0 +1,463 @@
+@startuml
+class "registrar.Contact " as registrar.Contact #d6f4e9 {
+ contact
+ --
+ + id (BigAutoField)
+ + created_at (DateTimeField)
+ + updated_at (DateTimeField)
+ + first_name (CharField)
+ + middle_name (CharField)
+ + last_name (CharField)
+ + title (CharField)
+ + email (EmailField)
+ + phone (PhoneNumberField)
+ --
+}
+
+
+class "registrar.Host " as registrar.Host #d6f4e9 {
+ host
+ --
+ + id (BigAutoField)
+ + created_at (DateTimeField)
+ + updated_at (DateTimeField)
+ + name (CharField)
+ ~ domain (ForeignKey)
+ --
+}
+registrar.Host -- registrar.Domain
+
+
+class "registrar.HostIP " as registrar.HostIP #d6f4e9 {
+ host ip
+ --
+ + id (BigAutoField)
+ + created_at (DateTimeField)
+ + updated_at (DateTimeField)
+ + address (CharField)
+ ~ host (ForeignKey)
+ --
+}
+registrar.HostIP -- registrar.Host
+
+
+class "registrar.PublicContact " as registrar.PublicContact #d6f4e9 {
+ public contact
+ --
+ + id (BigAutoField)
+ + created_at (DateTimeField)
+ + updated_at (DateTimeField)
+ + contact_type (CharField)
+ + registry_id (CharField)
+ ~ domain (ForeignKey)
+ + name (CharField)
+ + org (CharField)
+ + street1 (CharField)
+ + street2 (CharField)
+ + street3 (CharField)
+ + city (CharField)
+ + sp (CharField)
+ + pc (CharField)
+ + cc (CharField)
+ + email (EmailField)
+ + voice (CharField)
+ + fax (CharField)
+ + pw (CharField)
+ --
+}
+registrar.PublicContact -- registrar.Domain
+
+
+class "registrar.UserDomainRole " as registrar.UserDomainRole #d6f4e9 {
+ user domain role
+ --
+ + id (BigAutoField)
+ + created_at (DateTimeField)
+ + updated_at (DateTimeField)
+ ~ user (ForeignKey)
+ ~ domain (ForeignKey)
+ + role (TextField)
+ --
+}
+registrar.UserDomainRole -- registrar.User
+registrar.UserDomainRole -- registrar.Domain
+
+
+class "registrar.Domain " as registrar.Domain #d6f4e9 {
+ domain
+ --
+ + id (BigAutoField)
+ + created_at (DateTimeField)
+ + updated_at (DateTimeField)
+ + name (DomainField)
+ + state (FSMField)
+ + expiration_date (DateField)
+ + security_contact_registry_id (TextField)
+ + deleted (DateField)
+ + first_ready (DateField)
+ + dsdata_last_change (TextField)
+ --
+}
+
+
+class "registrar.FederalAgency " as registrar.FederalAgency #d6f4e9 {
+ Federal agency
+ --
+ + id (BigAutoField)
+ + created_at (DateTimeField)
+ + updated_at (DateTimeField)
+ + agency (CharField)
+ + federal_type (CharField)
+ + initials (CharField)
+ + is_fceb (BooleanField)
+ --
+}
+
+
+class "registrar.DomainRequest " as registrar.DomainRequest #d6f4e9 {
+ domain request
+ --
+ + id (BigAutoField)
+ + created_at (DateTimeField)
+ + updated_at (DateTimeField)
+ + status (FSMField)
+ + rejection_reason (TextField)
+ + action_needed_reason (TextField)
+ + action_needed_reason_email (TextField)
+ ~ federal_agency (ForeignKey)
+ ~ portfolio (ForeignKey)
+ ~ sub_organization (ForeignKey)
+ ~ creator (ForeignKey)
+ ~ investigator (ForeignKey)
+ + generic_org_type (CharField)
+ + is_election_board (BooleanField)
+ + organization_type (CharField)
+ + federally_recognized_tribe (BooleanField)
+ + state_recognized_tribe (BooleanField)
+ + tribe_name (CharField)
+ + federal_type (CharField)
+ + organization_name (CharField)
+ + address_line1 (CharField)
+ + address_line2 (CharField)
+ + city (CharField)
+ + state_territory (CharField)
+ + zipcode (CharField)
+ + urbanization (CharField)
+ + about_your_organization (TextField)
+ ~ senior_official (ForeignKey)
+ ~ approved_domain (OneToOneField)
+ ~ requested_domain (OneToOneField)
+ + purpose (TextField)
+ + no_other_contacts_rationale (TextField)
+ + anything_else (TextField)
+ + has_anything_else_text (BooleanField)
+ + cisa_representative_email (EmailField)
+ + cisa_representative_first_name (CharField)
+ + cisa_representative_last_name (CharField)
+ + has_cisa_representative (BooleanField)
+ + is_policy_acknowledged (BooleanField)
+ + submission_date (DateField)
+ + notes (TextField)
+ # current_websites (ManyToManyField)
+ # alternative_domains (ManyToManyField)
+ # other_contacts (ManyToManyField)
+ --
+}
+registrar.DomainRequest -- registrar.FederalAgency
+registrar.DomainRequest -- registrar.Portfolio
+registrar.DomainRequest -- registrar.Suborganization
+registrar.DomainRequest -- registrar.User
+registrar.DomainRequest -- registrar.User
+registrar.DomainRequest -- registrar.Contact
+registrar.DomainRequest -- registrar.Domain
+registrar.DomainRequest -- registrar.DraftDomain
+registrar.DomainRequest *--* registrar.Website
+registrar.DomainRequest *--* registrar.Website
+registrar.DomainRequest *--* registrar.Contact
+
+
+class "registrar.DomainInformation " as registrar.DomainInformation #d6f4e9 {
+ domain information
+ --
+ + id (BigAutoField)
+ + created_at (DateTimeField)
+ + updated_at (DateTimeField)
+ ~ federal_agency (ForeignKey)
+ ~ creator (ForeignKey)
+ ~ portfolio (ForeignKey)
+ ~ sub_organization (ForeignKey)
+ ~ domain_request (OneToOneField)
+ + generic_org_type (CharField)
+ + organization_type (CharField)
+ + federally_recognized_tribe (BooleanField)
+ + state_recognized_tribe (BooleanField)
+ + tribe_name (CharField)
+ + federal_type (CharField)
+ + is_election_board (BooleanField)
+ + organization_name (CharField)
+ + address_line1 (CharField)
+ + address_line2 (CharField)
+ + city (CharField)
+ + state_territory (CharField)
+ + zipcode (CharField)
+ + urbanization (CharField)
+ + about_your_organization (TextField)
+ ~ senior_official (ForeignKey)
+ ~ domain (OneToOneField)
+ + purpose (TextField)
+ + no_other_contacts_rationale (TextField)
+ + anything_else (TextField)
+ + has_anything_else_text (BooleanField)
+ + cisa_representative_email (EmailField)
+ + cisa_representative_first_name (CharField)
+ + cisa_representative_last_name (CharField)
+ + has_cisa_representative (BooleanField)
+ + is_policy_acknowledged (BooleanField)
+ + notes (TextField)
+ # other_contacts (ManyToManyField)
+ --
+}
+registrar.DomainInformation -- registrar.FederalAgency
+registrar.DomainInformation -- registrar.User
+registrar.DomainInformation -- registrar.Portfolio
+registrar.DomainInformation -- registrar.Suborganization
+registrar.DomainInformation -- registrar.DomainRequest
+registrar.DomainInformation -- registrar.Contact
+registrar.DomainInformation -- registrar.Domain
+registrar.DomainInformation *--* registrar.Contact
+
+
+class "registrar.DraftDomain " as registrar.DraftDomain #d6f4e9 {
+ draft domain
+ --
+ + id (BigAutoField)
+ + created_at (DateTimeField)
+ + updated_at (DateTimeField)
+ + name (CharField)
+ --
+}
+
+
+class "registrar.DomainInvitation " as registrar.DomainInvitation #d6f4e9 {
+ domain invitation
+ --
+ + id (BigAutoField)
+ + created_at (DateTimeField)
+ + updated_at (DateTimeField)
+ + email (EmailField)
+ ~ domain (ForeignKey)
+ + status (FSMField)
+ --
+}
+registrar.DomainInvitation -- registrar.Domain
+
+
+class "registrar.PortfolioInvitation " as registrar.PortfolioInvitation #d6f4e9 {
+ portfolio invitation
+ --
+ + id (BigAutoField)
+ + created_at (DateTimeField)
+ + updated_at (DateTimeField)
+ + email (EmailField)
+ ~ portfolio (ForeignKey)
+ + portfolio_roles (ArrayField)
+ + portfolio_additional_permissions (ArrayField)
+ + status (FSMField)
+ --
+}
+registrar.PortfolioInvitation -- registrar.Portfolio
+
+
+class "registrar.TransitionDomain " as registrar.TransitionDomain #d6f4e9 {
+ transition domain
+ --
+ + id (BigAutoField)
+ + created_at (DateTimeField)
+ + updated_at (DateTimeField)
+ + username (CharField)
+ + domain_name (CharField)
+ + status (CharField)
+ + email_sent (BooleanField)
+ + processed (BooleanField)
+ + generic_org_type (CharField)
+ + organization_name (CharField)
+ + federal_type (CharField)
+ + federal_agency (CharField)
+ + epp_creation_date (DateField)
+ + epp_expiration_date (DateField)
+ + first_name (CharField)
+ + middle_name (CharField)
+ + last_name (CharField)
+ + title (CharField)
+ + email (EmailField)
+ + phone (CharField)
+ + address_line (CharField)
+ + city (CharField)
+ + state_territory (CharField)
+ + zipcode (CharField)
+ --
+}
+
+
+class "registrar.VerifiedByStaff " as registrar.VerifiedByStaff #d6f4e9 {
+ verified by staff
+ --
+ + id (BigAutoField)
+ + created_at (DateTimeField)
+ + updated_at (DateTimeField)
+ + email (EmailField)
+ ~ requestor (ForeignKey)
+ + notes (TextField)
+ --
+}
+registrar.VerifiedByStaff -- registrar.User
+
+
+class "registrar.User " as registrar.User #d6f4e9 {
+ user
+ --
+ + id (BigAutoField)
+ + password (CharField)
+ + last_login (DateTimeField)
+ + is_superuser (BooleanField)
+ + username (CharField)
+ + first_name (CharField)
+ + last_name (CharField)
+ + email (EmailField)
+ + is_staff (BooleanField)
+ + is_active (BooleanField)
+ + date_joined (DateTimeField)
+ + status (CharField)
+ ~ portfolio (ForeignKey)
+ + portfolio_roles (ArrayField)
+ + portfolio_additional_permissions (ArrayField)
+ + phone (PhoneNumberField)
+ + middle_name (CharField)
+ + title (CharField)
+ + verification_type (CharField)
+ # groups (ManyToManyField)
+ # user_permissions (ManyToManyField)
+ # domains (ManyToManyField)
+ --
+}
+registrar.User -- registrar.Portfolio
+registrar.User *--* registrar.Domain
+
+
+class "registrar.UserGroup " as registrar.UserGroup #d6f4e9 {
+ User group
+ --
+ - id (AutoField)
+ + name (CharField)
+ ~ group_ptr (OneToOneField)
+ # permissions (ManyToManyField)
+ --
+}
+
+
+class "registrar.Website " as registrar.Website #d6f4e9 {
+ website
+ --
+ + id (BigAutoField)
+ + created_at (DateTimeField)
+ + updated_at (DateTimeField)
+ + website (CharField)
+ --
+}
+
+
+class "registrar.WaffleFlag " as registrar.WaffleFlag #d6f4e9 {
+ waffle flag
+ --
+ + id (BigAutoField)
+ + name (CharField)
+ + everyone (BooleanField)
+ + percent (DecimalField)
+ + testing (BooleanField)
+ + superusers (BooleanField)
+ + staff (BooleanField)
+ + authenticated (BooleanField)
+ + languages (TextField)
+ + rollout (BooleanField)
+ + note (TextField)
+ + created (DateTimeField)
+ + modified (DateTimeField)
+ # groups (ManyToManyField)
+ # users (ManyToManyField)
+ --
+}
+registrar.WaffleFlag *--* registrar.User
+
+
+class "registrar.Portfolio " as registrar.Portfolio #d6f4e9 {
+ portfolio
+ --
+ + id (BigAutoField)
+ + created_at (DateTimeField)
+ + updated_at (DateTimeField)
+ ~ creator (ForeignKey)
+ + organization_name (CharField)
+ + organization_type (CharField)
+ + notes (TextField)
+ ~ federal_agency (ForeignKey)
+ ~ senior_official (ForeignKey)
+ + address_line1 (CharField)
+ + address_line2 (CharField)
+ + city (CharField)
+ + state_territory (CharField)
+ + zipcode (CharField)
+ + urbanization (CharField)
+ + security_contact_email (EmailField)
+ --
+}
+registrar.Portfolio -- registrar.User
+registrar.Portfolio -- registrar.FederalAgency
+registrar.Portfolio -- registrar.SeniorOfficial
+
+
+class "registrar.DomainGroup " as registrar.DomainGroup #d6f4e9 {
+ domain group
+ --
+ + id (BigAutoField)
+ + created_at (DateTimeField)
+ + updated_at (DateTimeField)
+ + name (CharField)
+ ~ portfolio (ForeignKey)
+ # domains (ManyToManyField)
+ --
+}
+registrar.DomainGroup -- registrar.Portfolio
+registrar.DomainGroup *--* registrar.DomainInformation
+
+
+class "registrar.Suborganization " as registrar.Suborganization #d6f4e9 {
+ suborganization
+ --
+ + id (BigAutoField)
+ + created_at (DateTimeField)
+ + updated_at (DateTimeField)
+ + name (CharField)
+ ~ portfolio (ForeignKey)
+ --
+}
+registrar.Suborganization -- registrar.Portfolio
+
+
+class "registrar.SeniorOfficial " as registrar.SeniorOfficial #d6f4e9 {
+ senior official
+ --
+ + id (BigAutoField)
+ + created_at (DateTimeField)
+ + updated_at (DateTimeField)
+ + first_name (CharField)
+ + last_name (CharField)
+ + title (CharField)
+ + phone (PhoneNumberField)
+ + email (EmailField)
+ ~ federal_agency (ForeignKey)
+ --
+}
+registrar.SeniorOfficial -- registrar.FederalAgency
+
+
+@enduml
diff --git a/src/registrar/config/settings.py b/src/registrar/config/settings.py
index 73aecad7a..72bffdbb4 100644
--- a/src/registrar/config/settings.py
+++ b/src/registrar/config/settings.py
@@ -357,7 +357,7 @@ CSP_FORM_ACTION = allowed_sources
# and inline with a nonce, as well as allowing connections back to their domain.
# Note: If needed, we can embed chart.js instead of using the CDN
CSP_DEFAULT_SRC = ("'self'",)
-CSP_STYLE_SRC = ["'self'", "https://www.ssa.gov/accessibility/andi/andi.css"]
+CSP_STYLE_SRC = ["'self'", "https://www.ssa.gov"]
CSP_SCRIPT_SRC_ELEM = [
"'self'",
"https://www.googletagmanager.com/",
@@ -367,7 +367,7 @@ CSP_SCRIPT_SRC_ELEM = [
]
CSP_CONNECT_SRC = ["'self'", "https://www.google-analytics.com/", "https://www.ssa.gov/accessibility/andi/andi.js"]
CSP_INCLUDE_NONCE_IN = ["script-src-elem", "style-src"]
-CSP_IMG_SRC = ["'self'", "https://www.ssa.gov/accessibility/andi/icons/"]
+CSP_IMG_SRC = ["'self'", "https://www.ssa.gov"]
# Cross-Origin Resource Sharing (CORS) configuration
# Sets clients that allow access control to manage.get.gov
diff --git a/src/requirements.txt b/src/requirements.txt
index 3f7158449..4a6cec691 100644
--- a/src/requirements.txt
+++ b/src/requirements.txt
@@ -1,75 +1,68 @@
-i https://pypi.python.org/simple
-annotated-types==0.6.0; python_version >= '3.8'
+annotated-types==0.7.0; python_version >= '3.8'
asgiref==3.8.1; python_version >= '3.8'
-boto3==1.34.95; python_version >= '3.8'
-botocore==1.34.95; python_version >= '3.8'
-cachetools==5.3.3; python_version >= '3.7'
-certifi==2024.2.2; python_version >= '3.6'
+boto3==1.35.8; python_version >= '3.8'
+botocore==1.35.8; python_version >= '3.8'
+cachetools==5.5.0; python_version >= '3.7'
+certifi==2024.7.4; python_version >= '3.6'
cfenv==0.5.3
-cffi==1.16.0; platform_python_implementation != 'PyPy'
+cffi==1.17.0; platform_python_implementation != 'PyPy'
charset-normalizer==3.3.2; python_full_version >= '3.7.0'
-cryptography==42.0.5; python_version >= '3.7'
+cryptography==43.0.0; python_version >= '3.7'
defusedxml==0.7.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'
diff-match-patch==20230430; python_version >= '3.7'
-dj-database-url==2.1.0
+dj-database-url==2.2.0
dj-email-url==1.0.6
django==4.2.10; python_version >= '3.8'
django-admin-multiple-choice-list-filter==0.1.1
django-allow-cidr==0.7.1
django-auditlog==3.0.0; python_version >= '3.8'
django-cache-url==3.4.5
-django-cors-headers==4.3.1; python_version >= '3.8'
+django-cors-headers==4.4.0; python_version >= '3.8'
django-csp==3.8
django-fsm==2.8.1
-django-import-export==3.3.8; python_version >= '3.8'
+django-import-export==4.1.1; python_version >= '3.8'
django-login-required-middleware==0.9.0
-django-phonenumber-field[phonenumberslite]==7.3.0; python_version >= '3.8'
+django-phonenumber-field[phonenumberslite]==8.0.0; python_version >= '3.8'
django-waffle==4.1.0; python_version >= '3.8'
django-widget-tweaks==1.5.0; python_version >= '3.8'
environs[django]==11.0.0; python_version >= '3.8'
-et-xmlfile==1.1.0; python_version >= '3.6'
-faker==25.0.0; python_version >= '3.8'
+faker==28.0.0; python_version >= '3.8'
fred-epplib@ git+https://github.com/cisagov/epplib.git@d56d183f1664f34c40ca9716a3a9a345f0ef561c
furl==2.1.3
future==1.0.0; python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'
gevent==24.2.1; python_version >= '3.8'
greenlet==3.0.3; python_version >= '3.7'
-gunicorn==22.0.0; python_version >= '3.7'
-idna==3.7; python_version >= '3.5'
+gunicorn==23.0.0; python_version >= '3.7'
+idna==3.8; python_version >= '3.6'
jmespath==1.0.1; python_version >= '3.7'
-lxml==5.2.1; python_version >= '3.6'
-mako==1.3.3; python_version >= '3.8'
-markuppy==1.14
+lxml==5.3.0; python_version >= '3.6'
+mako==1.3.5; python_version >= '3.8'
markupsafe==2.1.5; python_version >= '3.7'
-marshmallow==3.21.1; python_version >= '3.8'
-odfpy==1.4.1
+marshmallow==3.22.0; python_version >= '3.8'
oic==1.7.0; python_version ~= '3.8'
-openpyxl==3.1.2
orderedmultidict==1.0.1
-packaging==24.0; python_version >= '3.7'
-phonenumberslite==8.13.35
+packaging==24.1; python_version >= '3.8'
+phonenumberslite==8.13.44
psycopg2-binary==2.9.9; python_version >= '3.7'
pycparser==2.22; python_version >= '3.8'
pycryptodomex==3.20.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'
-pydantic==2.7.1; python_version >= '3.8'
-pydantic-core==2.18.2; python_version >= '3.8'
-pydantic-settings==2.2.1; python_version >= '3.8'
+pydantic==2.8.2; python_version >= '3.8'
+pydantic-core==2.20.1; python_version >= '3.8'
+pydantic-settings==2.4.0; python_version >= '3.8'
pyjwkest==1.4.2
python-dateutil==2.9.0.post0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'
python-dotenv==1.0.1; python_version >= '3.8'
-pyyaml==6.0.1
pyzipper==0.3.6; python_version >= '3.4'
-requests==2.31.0; python_version >= '3.7'
-s3transfer==0.10.1; python_version >= '3.8'
-setuptools==69.5.1; python_version >= '3.8'
+requests==2.32.3; python_version >= '3.8'
+s3transfer==0.10.2; python_version >= '3.8'
+setuptools==74.0.0; python_version >= '3.8'
six==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'
-sqlparse==0.5.0; python_version >= '3.8'
+sqlparse==0.5.1; python_version >= '3.8'
tablib[html,ods,xls,xlsx,yaml]==3.5.0; python_version >= '3.8'
tblib==3.0.0; python_version >= '3.8'
-typing-extensions==4.11.0; python_version >= '3.8'
-urllib3==2.2.1; python_version >= '3.8'
-whitenoise==6.6.0; python_version >= '3.8'
-xlrd==2.0.1
-xlwt==1.3.0
+typing-extensions==4.12.2; python_version >= '3.8'
+urllib3==2.2.2; python_version >= '3.8'
+whitenoise==6.7.0; python_version >= '3.8'
zope.event==5.0; python_version >= '3.7'
-zope.interface==6.3; python_version >= '3.7'
+zope.interface==7.0.3; python_version >= '3.8'
From 171be9a642c3e178ee10199b8d6cd48a8e917791 Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Thu, 29 Aug 2024 09:29:39 -0700
Subject: [PATCH 022/150] Remove stragglign file
---
src/.zshrc | 1 -
1 file changed, 1 deletion(-)
delete mode 100644 src/.zshrc
diff --git a/src/.zshrc b/src/.zshrc
deleted file mode 100644
index 45a622a14..000000000
--- a/src/.zshrc
+++ /dev/null
@@ -1 +0,0 @@
-export DOCKER_DEFAULT_PLATFORM=linux/amd64
From 98a50fb178c22ce330294f46630640c462978589 Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Thu, 29 Aug 2024 09:37:53 -0700
Subject: [PATCH 023/150] Test diagram update
---
docs/architecture/diagrams/models_diagram.md | 56 ++-
src/models_diagram.puml | 463 -------------------
2 files changed, 47 insertions(+), 472 deletions(-)
delete mode 100644 src/models_diagram.puml
diff --git a/docs/architecture/diagrams/models_diagram.md b/docs/architecture/diagrams/models_diagram.md
index 1e9d3089e..4bbec31cc 100644
--- a/docs/architecture/diagrams/models_diagram.md
+++ b/docs/architecture/diagrams/models_diagram.md
@@ -38,7 +38,6 @@ class "registrar.Contact " as registrar.Contact #d6f4e9 {
+ id (BigAutoField)
+ created_at (DateTimeField)
+ updated_at (DateTimeField)
- ~ user (OneToOneField)
+ first_name (CharField)
+ middle_name (CharField)
+ last_name (CharField)
@@ -47,7 +46,6 @@ class "registrar.Contact " as registrar.Contact #d6f4e9 {
+ phone (PhoneNumberField)
--
}
-registrar.Contact -- registrar.User
class "registrar.Host " as registrar.Host #d6f4e9 {
@@ -143,6 +141,8 @@ class "registrar.FederalAgency " as registrar.FederalAgency #d6f4e9 {
+ updated_at (DateTimeField)
+ agency (CharField)
+ federal_type (CharField)
+ + initials (CharField)
+ + is_fceb (BooleanField)
--
}
@@ -159,6 +159,7 @@ class "registrar.DomainRequest " as registrar.DomainRequest #d6f4e9 {
+ action_needed_reason_email (TextField)
~ federal_agency (ForeignKey)
~ portfolio (ForeignKey)
+ ~ sub_organization (ForeignKey)
~ creator (ForeignKey)
~ investigator (ForeignKey)
+ generic_org_type (CharField)
@@ -197,12 +198,12 @@ class "registrar.DomainRequest " as registrar.DomainRequest #d6f4e9 {
}
registrar.DomainRequest -- registrar.FederalAgency
registrar.DomainRequest -- registrar.Portfolio
+registrar.DomainRequest -- registrar.Suborganization
registrar.DomainRequest -- registrar.User
registrar.DomainRequest -- registrar.User
registrar.DomainRequest -- registrar.Contact
registrar.DomainRequest -- registrar.Domain
registrar.DomainRequest -- registrar.DraftDomain
-registrar.DomainRequest -- registrar.Contact
registrar.DomainRequest *--* registrar.Website
registrar.DomainRequest *--* registrar.Website
registrar.DomainRequest *--* registrar.Contact
@@ -217,6 +218,7 @@ class "registrar.DomainInformation " as registrar.DomainInformation #
~ federal_agency (ForeignKey)
~ creator (ForeignKey)
~ portfolio (ForeignKey)
+ ~ sub_organization (ForeignKey)
~ domain_request (OneToOneField)
+ generic_org_type (CharField)
+ organization_type (CharField)
@@ -251,10 +253,10 @@ class "registrar.DomainInformation " as registrar.DomainInformation #
registrar.DomainInformation -- registrar.FederalAgency
registrar.DomainInformation -- registrar.User
registrar.DomainInformation -- registrar.Portfolio
+registrar.DomainInformation -- registrar.Suborganization
registrar.DomainInformation -- registrar.DomainRequest
registrar.DomainInformation -- registrar.Contact
registrar.DomainInformation -- registrar.Domain
-registrar.DomainInformation -- registrar.Contact
registrar.DomainInformation *--* registrar.Contact
@@ -283,6 +285,22 @@ class "registrar.DomainInvitation " as registrar.DomainInvitation #d6
registrar.DomainInvitation -- registrar.Domain
+class "registrar.PortfolioInvitation " as registrar.PortfolioInvitation #d6f4e9 {
+ portfolio invitation
+ --
+ + id (BigAutoField)
+ + created_at (DateTimeField)
+ + updated_at (DateTimeField)
+ + email (EmailField)
+ ~ portfolio (ForeignKey)
+ + portfolio_roles (ArrayField)
+ + portfolio_additional_permissions (ArrayField)
+ + status (FSMField)
+ --
+}
+registrar.PortfolioInvitation -- registrar.Portfolio
+
+
class "registrar.TransitionDomain " as registrar.TransitionDomain #d6f4e9 {
transition domain
--
@@ -343,6 +361,9 @@ class "registrar.User " as registrar.User #d6f4e9 {
+ is_active (BooleanField)
+ date_joined (DateTimeField)
+ status (CharField)
+ ~ portfolio (ForeignKey)
+ + portfolio_roles (ArrayField)
+ + portfolio_additional_permissions (ArrayField)
+ phone (PhoneNumberField)
+ middle_name (CharField)
+ title (CharField)
@@ -352,6 +373,7 @@ class "registrar.User " as registrar.User #d6f4e9 {
# domains (ManyToManyField)
--
}
+registrar.User -- registrar.Portfolio
registrar.User *--* registrar.Domain
@@ -407,10 +429,11 @@ class "registrar.Portfolio " as registrar.Portfolio #d6f4e9 {
+ created_at (DateTimeField)
+ updated_at (DateTimeField)
~ creator (ForeignKey)
+ + organization_name (CharField)
+ + organization_type (CharField)
+ notes (TextField)
~ federal_agency (ForeignKey)
- + organization_type (CharField)
- + organization_name (CharField)
+ ~ senior_official (ForeignKey)
+ address_line1 (CharField)
+ address_line2 (CharField)
+ city (CharField)
@@ -422,6 +445,7 @@ class "registrar.Portfolio " as registrar.Portfolio #d6f4e9 {
}
registrar.Portfolio -- registrar.User
registrar.Portfolio -- registrar.FederalAgency
+registrar.Portfolio -- registrar.SeniorOfficial
class "registrar.DomainGroup " as registrar.DomainGroup #d6f4e9 {
@@ -452,7 +476,21 @@ class "registrar.Suborganization " as registrar.Suborganization #d6f4
registrar.Suborganization -- registrar.Portfolio
-@enduml
-```
+class "registrar.SeniorOfficial " as registrar.SeniorOfficial #d6f4e9 {
+ senior official
+ --
+ + id (BigAutoField)
+ + created_at (DateTimeField)
+ + updated_at (DateTimeField)
+ + first_name (CharField)
+ + last_name (CharField)
+ + title (CharField)
+ + phone (PhoneNumberField)
+ + email (EmailField)
+ ~ federal_agency (ForeignKey)
+ --
+}
+registrar.SeniorOfficial -- registrar.FederalAgency
-
+
+@enduml
diff --git a/src/models_diagram.puml b/src/models_diagram.puml
deleted file mode 100644
index 84c3cea39..000000000
--- a/src/models_diagram.puml
+++ /dev/null
@@ -1,463 +0,0 @@
-@startuml
-class "registrar.Contact " as registrar.Contact #d6f4e9 {
- contact
- --
- + id (BigAutoField)
- + created_at (DateTimeField)
- + updated_at (DateTimeField)
- + first_name (CharField)
- + middle_name (CharField)
- + last_name (CharField)
- + title (CharField)
- + email (EmailField)
- + phone (PhoneNumberField)
- --
-}
-
-
-class "registrar.Host " as registrar.Host #d6f4e9 {
- host
- --
- + id (BigAutoField)
- + created_at (DateTimeField)
- + updated_at (DateTimeField)
- + name (CharField)
- ~ domain (ForeignKey)
- --
-}
-registrar.Host -- registrar.Domain
-
-
-class "registrar.HostIP " as registrar.HostIP #d6f4e9 {
- host ip
- --
- + id (BigAutoField)
- + created_at (DateTimeField)
- + updated_at (DateTimeField)
- + address (CharField)
- ~ host (ForeignKey)
- --
-}
-registrar.HostIP -- registrar.Host
-
-
-class "registrar.PublicContact " as registrar.PublicContact #d6f4e9 {
- public contact
- --
- + id (BigAutoField)
- + created_at (DateTimeField)
- + updated_at (DateTimeField)
- + contact_type (CharField)
- + registry_id (CharField)
- ~ domain (ForeignKey)
- + name (CharField)
- + org (CharField)
- + street1 (CharField)
- + street2 (CharField)
- + street3 (CharField)
- + city (CharField)
- + sp (CharField)
- + pc (CharField)
- + cc (CharField)
- + email (EmailField)
- + voice (CharField)
- + fax (CharField)
- + pw (CharField)
- --
-}
-registrar.PublicContact -- registrar.Domain
-
-
-class "registrar.UserDomainRole " as registrar.UserDomainRole #d6f4e9 {
- user domain role
- --
- + id (BigAutoField)
- + created_at (DateTimeField)
- + updated_at (DateTimeField)
- ~ user (ForeignKey)
- ~ domain (ForeignKey)
- + role (TextField)
- --
-}
-registrar.UserDomainRole -- registrar.User
-registrar.UserDomainRole -- registrar.Domain
-
-
-class "registrar.Domain " as registrar.Domain #d6f4e9 {
- domain
- --
- + id (BigAutoField)
- + created_at (DateTimeField)
- + updated_at (DateTimeField)
- + name (DomainField)
- + state (FSMField)
- + expiration_date (DateField)
- + security_contact_registry_id (TextField)
- + deleted (DateField)
- + first_ready (DateField)
- + dsdata_last_change (TextField)
- --
-}
-
-
-class "registrar.FederalAgency " as registrar.FederalAgency #d6f4e9 {
- Federal agency
- --
- + id (BigAutoField)
- + created_at (DateTimeField)
- + updated_at (DateTimeField)
- + agency (CharField)
- + federal_type (CharField)
- + initials (CharField)
- + is_fceb (BooleanField)
- --
-}
-
-
-class "registrar.DomainRequest " as registrar.DomainRequest #d6f4e9 {
- domain request
- --
- + id (BigAutoField)
- + created_at (DateTimeField)
- + updated_at (DateTimeField)
- + status (FSMField)
- + rejection_reason (TextField)
- + action_needed_reason (TextField)
- + action_needed_reason_email (TextField)
- ~ federal_agency (ForeignKey)
- ~ portfolio (ForeignKey)
- ~ sub_organization (ForeignKey)
- ~ creator (ForeignKey)
- ~ investigator (ForeignKey)
- + generic_org_type (CharField)
- + is_election_board (BooleanField)
- + organization_type (CharField)
- + federally_recognized_tribe (BooleanField)
- + state_recognized_tribe (BooleanField)
- + tribe_name (CharField)
- + federal_type (CharField)
- + organization_name (CharField)
- + address_line1 (CharField)
- + address_line2 (CharField)
- + city (CharField)
- + state_territory (CharField)
- + zipcode (CharField)
- + urbanization (CharField)
- + about_your_organization (TextField)
- ~ senior_official (ForeignKey)
- ~ approved_domain (OneToOneField)
- ~ requested_domain (OneToOneField)
- + purpose (TextField)
- + no_other_contacts_rationale (TextField)
- + anything_else (TextField)
- + has_anything_else_text (BooleanField)
- + cisa_representative_email (EmailField)
- + cisa_representative_first_name (CharField)
- + cisa_representative_last_name (CharField)
- + has_cisa_representative (BooleanField)
- + is_policy_acknowledged (BooleanField)
- + submission_date (DateField)
- + notes (TextField)
- # current_websites (ManyToManyField)
- # alternative_domains (ManyToManyField)
- # other_contacts (ManyToManyField)
- --
-}
-registrar.DomainRequest -- registrar.FederalAgency
-registrar.DomainRequest -- registrar.Portfolio
-registrar.DomainRequest -- registrar.Suborganization
-registrar.DomainRequest -- registrar.User
-registrar.DomainRequest -- registrar.User
-registrar.DomainRequest -- registrar.Contact
-registrar.DomainRequest -- registrar.Domain
-registrar.DomainRequest -- registrar.DraftDomain
-registrar.DomainRequest *--* registrar.Website
-registrar.DomainRequest *--* registrar.Website
-registrar.DomainRequest *--* registrar.Contact
-
-
-class "registrar.DomainInformation " as registrar.DomainInformation #d6f4e9 {
- domain information
- --
- + id (BigAutoField)
- + created_at (DateTimeField)
- + updated_at (DateTimeField)
- ~ federal_agency (ForeignKey)
- ~ creator (ForeignKey)
- ~ portfolio (ForeignKey)
- ~ sub_organization (ForeignKey)
- ~ domain_request (OneToOneField)
- + generic_org_type (CharField)
- + organization_type (CharField)
- + federally_recognized_tribe (BooleanField)
- + state_recognized_tribe (BooleanField)
- + tribe_name (CharField)
- + federal_type (CharField)
- + is_election_board (BooleanField)
- + organization_name (CharField)
- + address_line1 (CharField)
- + address_line2 (CharField)
- + city (CharField)
- + state_territory (CharField)
- + zipcode (CharField)
- + urbanization (CharField)
- + about_your_organization (TextField)
- ~ senior_official (ForeignKey)
- ~ domain (OneToOneField)
- + purpose (TextField)
- + no_other_contacts_rationale (TextField)
- + anything_else (TextField)
- + has_anything_else_text (BooleanField)
- + cisa_representative_email (EmailField)
- + cisa_representative_first_name (CharField)
- + cisa_representative_last_name (CharField)
- + has_cisa_representative (BooleanField)
- + is_policy_acknowledged (BooleanField)
- + notes (TextField)
- # other_contacts (ManyToManyField)
- --
-}
-registrar.DomainInformation -- registrar.FederalAgency
-registrar.DomainInformation -- registrar.User
-registrar.DomainInformation -- registrar.Portfolio
-registrar.DomainInformation -- registrar.Suborganization
-registrar.DomainInformation -- registrar.DomainRequest
-registrar.DomainInformation -- registrar.Contact
-registrar.DomainInformation -- registrar.Domain
-registrar.DomainInformation *--* registrar.Contact
-
-
-class "registrar.DraftDomain " as registrar.DraftDomain #d6f4e9 {
- draft domain
- --
- + id (BigAutoField)
- + created_at (DateTimeField)
- + updated_at (DateTimeField)
- + name (CharField)
- --
-}
-
-
-class "registrar.DomainInvitation " as registrar.DomainInvitation #d6f4e9 {
- domain invitation
- --
- + id (BigAutoField)
- + created_at (DateTimeField)
- + updated_at (DateTimeField)
- + email (EmailField)
- ~ domain (ForeignKey)
- + status (FSMField)
- --
-}
-registrar.DomainInvitation -- registrar.Domain
-
-
-class "registrar.PortfolioInvitation " as registrar.PortfolioInvitation #d6f4e9 {
- portfolio invitation
- --
- + id (BigAutoField)
- + created_at (DateTimeField)
- + updated_at (DateTimeField)
- + email (EmailField)
- ~ portfolio (ForeignKey)
- + portfolio_roles (ArrayField)
- + portfolio_additional_permissions (ArrayField)
- + status (FSMField)
- --
-}
-registrar.PortfolioInvitation -- registrar.Portfolio
-
-
-class "registrar.TransitionDomain " as registrar.TransitionDomain #d6f4e9 {
- transition domain
- --
- + id (BigAutoField)
- + created_at (DateTimeField)
- + updated_at (DateTimeField)
- + username (CharField)
- + domain_name (CharField)
- + status (CharField)
- + email_sent (BooleanField)
- + processed (BooleanField)
- + generic_org_type (CharField)
- + organization_name (CharField)
- + federal_type (CharField)
- + federal_agency (CharField)
- + epp_creation_date (DateField)
- + epp_expiration_date (DateField)
- + first_name (CharField)
- + middle_name (CharField)
- + last_name (CharField)
- + title (CharField)
- + email (EmailField)
- + phone (CharField)
- + address_line (CharField)
- + city (CharField)
- + state_territory (CharField)
- + zipcode (CharField)
- --
-}
-
-
-class "registrar.VerifiedByStaff " as registrar.VerifiedByStaff #d6f4e9 {
- verified by staff
- --
- + id (BigAutoField)
- + created_at (DateTimeField)
- + updated_at (DateTimeField)
- + email (EmailField)
- ~ requestor (ForeignKey)
- + notes (TextField)
- --
-}
-registrar.VerifiedByStaff -- registrar.User
-
-
-class "registrar.User " as registrar.User #d6f4e9 {
- user
- --
- + id (BigAutoField)
- + password (CharField)
- + last_login (DateTimeField)
- + is_superuser (BooleanField)
- + username (CharField)
- + first_name (CharField)
- + last_name (CharField)
- + email (EmailField)
- + is_staff (BooleanField)
- + is_active (BooleanField)
- + date_joined (DateTimeField)
- + status (CharField)
- ~ portfolio (ForeignKey)
- + portfolio_roles (ArrayField)
- + portfolio_additional_permissions (ArrayField)
- + phone (PhoneNumberField)
- + middle_name (CharField)
- + title (CharField)
- + verification_type (CharField)
- # groups (ManyToManyField)
- # user_permissions (ManyToManyField)
- # domains (ManyToManyField)
- --
-}
-registrar.User -- registrar.Portfolio
-registrar.User *--* registrar.Domain
-
-
-class "registrar.UserGroup " as registrar.UserGroup #d6f4e9 {
- User group
- --
- - id (AutoField)
- + name (CharField)
- ~ group_ptr (OneToOneField)
- # permissions (ManyToManyField)
- --
-}
-
-
-class "registrar.Website " as registrar.Website #d6f4e9 {
- website
- --
- + id (BigAutoField)
- + created_at (DateTimeField)
- + updated_at (DateTimeField)
- + website (CharField)
- --
-}
-
-
-class "registrar.WaffleFlag " as registrar.WaffleFlag #d6f4e9 {
- waffle flag
- --
- + id (BigAutoField)
- + name (CharField)
- + everyone (BooleanField)
- + percent (DecimalField)
- + testing (BooleanField)
- + superusers (BooleanField)
- + staff (BooleanField)
- + authenticated (BooleanField)
- + languages (TextField)
- + rollout (BooleanField)
- + note (TextField)
- + created (DateTimeField)
- + modified (DateTimeField)
- # groups (ManyToManyField)
- # users (ManyToManyField)
- --
-}
-registrar.WaffleFlag *--* registrar.User
-
-
-class "registrar.Portfolio " as registrar.Portfolio #d6f4e9 {
- portfolio
- --
- + id (BigAutoField)
- + created_at (DateTimeField)
- + updated_at (DateTimeField)
- ~ creator (ForeignKey)
- + organization_name (CharField)
- + organization_type (CharField)
- + notes (TextField)
- ~ federal_agency (ForeignKey)
- ~ senior_official (ForeignKey)
- + address_line1 (CharField)
- + address_line2 (CharField)
- + city (CharField)
- + state_territory (CharField)
- + zipcode (CharField)
- + urbanization (CharField)
- + security_contact_email (EmailField)
- --
-}
-registrar.Portfolio -- registrar.User
-registrar.Portfolio -- registrar.FederalAgency
-registrar.Portfolio -- registrar.SeniorOfficial
-
-
-class "registrar.DomainGroup " as registrar.DomainGroup #d6f4e9 {
- domain group
- --
- + id (BigAutoField)
- + created_at (DateTimeField)
- + updated_at (DateTimeField)
- + name (CharField)
- ~ portfolio (ForeignKey)
- # domains (ManyToManyField)
- --
-}
-registrar.DomainGroup -- registrar.Portfolio
-registrar.DomainGroup *--* registrar.DomainInformation
-
-
-class "registrar.Suborganization " as registrar.Suborganization #d6f4e9 {
- suborganization
- --
- + id (BigAutoField)
- + created_at (DateTimeField)
- + updated_at (DateTimeField)
- + name (CharField)
- ~ portfolio (ForeignKey)
- --
-}
-registrar.Suborganization -- registrar.Portfolio
-
-
-class "registrar.SeniorOfficial " as registrar.SeniorOfficial #d6f4e9 {
- senior official
- --
- + id (BigAutoField)
- + created_at (DateTimeField)
- + updated_at (DateTimeField)
- + first_name (CharField)
- + last_name (CharField)
- + title (CharField)
- + phone (PhoneNumberField)
- + email (EmailField)
- ~ federal_agency (ForeignKey)
- --
-}
-registrar.SeniorOfficial -- registrar.FederalAgency
-
-
-@enduml
From dd99f8f2d8b848e2f7e6d1c678b40d593c2b2a3a Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Thu, 29 Aug 2024 09:39:56 -0700
Subject: [PATCH 024/150] Revert Pipfile.lock
---
src/Pipfile.lock | 1367 +++++++++++++++++++++++++---------------------
1 file changed, 730 insertions(+), 637 deletions(-)
diff --git a/src/Pipfile.lock b/src/Pipfile.lock
index 09ac4a934..a42563c63 100644
--- a/src/Pipfile.lock
+++ b/src/Pipfile.lock
@@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
- "sha256": "2799ab9e493352740c6946e604ccc075c5c16359c809753296091bbe2b9fd837"
+ "sha256": "9095c4f98f58a9502444584067a63f329d5a5fc4b49454c4e129bda09552d19d"
},
"pipfile-spec": 6,
"requires": {},
@@ -16,11 +16,11 @@
"default": {
"annotated-types": {
"hashes": [
- "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53",
- "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"
+ "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43",
+ "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d"
],
"markers": "python_version >= '3.8'",
- "version": "==0.7.0"
+ "version": "==0.6.0"
},
"asgiref": {
"hashes": [
@@ -32,37 +32,37 @@
},
"boto3": {
"hashes": [
- "sha256:06eac4757de2a9c6020381205cb902f05964caad80b56e58c8931284a133b4cb",
- "sha256:b9587131372a808bf6f99c5ed8b11be55cd113261cc3b437a917b4acc6c30bfe"
+ "sha256:decf52f8d5d8a1b10c9ff2a0e96ee207ed79e33d2e53fdf0880a5cbef70785e0",
+ "sha256:e836b71d79671270fccac0a4d4c8ec239a6b82ea47c399b64675aa597d0ee63b"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==1.35.8"
+ "version": "==1.34.95"
},
"botocore": {
"hashes": [
- "sha256:4b820cf680ab5d778bd2fe4feeef1ff8a2b96d5c535d4638ab30f703ade282f8",
- "sha256:adf389eb8fd87775f193300e3431d1353f925807ad3a39958172cb644f0d60a1"
+ "sha256:6bd76a2eadb42b91fa3528392e981ad5b4dfdee3968fa5b904278acf6cbf15ff",
+ "sha256:ead5823e0dd6751ece5498cb979fd9abf190e691c8833bcac6876fd6ca261fa7"
],
"markers": "python_version >= '3.8'",
- "version": "==1.35.8"
+ "version": "==1.34.95"
},
"cachetools": {
"hashes": [
- "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292",
- "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"
+ "sha256:0abad1021d3f8325b2fc1d2e9c8b9c9d57b04c3932657a72465447332c24d945",
+ "sha256:ba29e2dfa0b8b556606f097407ed1aa62080ee108ab0dc5ec9d6a723a007d105"
],
"index": "pypi",
"markers": "python_version >= '3.7'",
- "version": "==5.5.0"
+ "version": "==5.3.3"
},
"certifi": {
"hashes": [
- "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b",
- "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"
+ "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f",
+ "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"
],
"markers": "python_version >= '3.6'",
- "version": "==2024.7.4"
+ "version": "==2024.2.2"
},
"cfenv": {
"hashes": [
@@ -74,76 +74,61 @@
},
"cffi": {
"hashes": [
- "sha256:011aff3524d578a9412c8b3cfaa50f2c0bd78e03eb7af7aa5e0df59b158efb2f",
- "sha256:0a048d4f6630113e54bb4b77e315e1ba32a5a31512c31a273807d0027a7e69ab",
- "sha256:0bb15e7acf8ab35ca8b24b90af52c8b391690ef5c4aec3d31f38f0d37d2cc499",
- "sha256:0d46ee4764b88b91f16661a8befc6bfb24806d885e27436fdc292ed7e6f6d058",
- "sha256:0e60821d312f99d3e1569202518dddf10ae547e799d75aef3bca3a2d9e8ee693",
- "sha256:0fdacad9e0d9fc23e519efd5ea24a70348305e8d7d85ecbb1a5fa66dc834e7fb",
- "sha256:14b9cbc8f7ac98a739558eb86fabc283d4d564dafed50216e7f7ee62d0d25377",
- "sha256:17c6d6d3260c7f2d94f657e6872591fe8733872a86ed1345bda872cfc8c74885",
- "sha256:1a2ddbac59dc3716bc79f27906c010406155031a1c801410f1bafff17ea304d2",
- "sha256:2404f3de742f47cb62d023f0ba7c5a916c9c653d5b368cc966382ae4e57da401",
- "sha256:24658baf6224d8f280e827f0a50c46ad819ec8ba380a42448e24459daf809cf4",
- "sha256:24aa705a5f5bd3a8bcfa4d123f03413de5d86e497435693b638cbffb7d5d8a1b",
- "sha256:2770bb0d5e3cc0e31e7318db06efcbcdb7b31bcb1a70086d3177692a02256f59",
- "sha256:331ad15c39c9fe9186ceaf87203a9ecf5ae0ba2538c9e898e3a6967e8ad3db6f",
- "sha256:3aa9d43b02a0c681f0bfbc12d476d47b2b2b6a3f9287f11ee42989a268a1833c",
- "sha256:41f4915e09218744d8bae14759f983e466ab69b178de38066f7579892ff2a555",
- "sha256:4304d4416ff032ed50ad6bb87416d802e67139e31c0bde4628f36a47a3164bfa",
- "sha256:435a22d00ec7d7ea533db494da8581b05977f9c37338c80bc86314bec2619424",
- "sha256:45f7cd36186db767d803b1473b3c659d57a23b5fa491ad83c6d40f2af58e4dbb",
- "sha256:48b389b1fd5144603d61d752afd7167dfd205973a43151ae5045b35793232aa2",
- "sha256:4e67d26532bfd8b7f7c05d5a766d6f437b362c1bf203a3a5ce3593a645e870b8",
- "sha256:516a405f174fd3b88829eabfe4bb296ac602d6a0f68e0d64d5ac9456194a5b7e",
- "sha256:5ba5c243f4004c750836f81606a9fcb7841f8874ad8f3bf204ff5e56332b72b9",
- "sha256:5bdc0f1f610d067c70aa3737ed06e2726fd9d6f7bfee4a351f4c40b6831f4e82",
- "sha256:6107e445faf057c118d5050560695e46d272e5301feffda3c41849641222a828",
- "sha256:6327b572f5770293fc062a7ec04160e89741e8552bf1c358d1a23eba68166759",
- "sha256:669b29a9eca6146465cc574659058ed949748f0809a2582d1f1a324eb91054dc",
- "sha256:6ce01337d23884b21c03869d2f68c5523d43174d4fc405490eb0091057943118",
- "sha256:6d872186c1617d143969defeadac5a904e6e374183e07977eedef9c07c8953bf",
- "sha256:6f76a90c345796c01d85e6332e81cab6d70de83b829cf1d9762d0a3da59c7932",
- "sha256:70d2aa9fb00cf52034feac4b913181a6e10356019b18ef89bc7c12a283bf5f5a",
- "sha256:7cbc78dc018596315d4e7841c8c3a7ae31cc4d638c9b627f87d52e8abaaf2d29",
- "sha256:856bf0924d24e7f93b8aee12a3a1095c34085600aa805693fb7f5d1962393206",
- "sha256:8a98748ed1a1df4ee1d6f927e151ed6c1a09d5ec21684de879c7ea6aa96f58f2",
- "sha256:93a7350f6706b31f457c1457d3a3259ff9071a66f312ae64dc024f049055f72c",
- "sha256:964823b2fc77b55355999ade496c54dde161c621cb1f6eac61dc30ed1b63cd4c",
- "sha256:a003ac9edc22d99ae1286b0875c460351f4e101f8c9d9d2576e78d7e048f64e0",
- "sha256:a0ce71725cacc9ebf839630772b07eeec220cbb5f03be1399e0457a1464f8e1a",
- "sha256:a47eef975d2b8b721775a0fa286f50eab535b9d56c70a6e62842134cf7841195",
- "sha256:a8b5b9712783415695663bd463990e2f00c6750562e6ad1d28e072a611c5f2a6",
- "sha256:a9015f5b8af1bb6837a3fcb0cdf3b874fe3385ff6274e8b7925d81ccaec3c5c9",
- "sha256:aec510255ce690d240f7cb23d7114f6b351c733a74c279a84def763660a2c3bc",
- "sha256:b00e7bcd71caa0282cbe3c90966f738e2db91e64092a877c3ff7f19a1628fdcb",
- "sha256:b50aaac7d05c2c26dfd50c3321199f019ba76bb650e346a6ef3616306eed67b0",
- "sha256:b7b6ea9e36d32582cda3465f54c4b454f62f23cb083ebc7a94e2ca6ef011c3a7",
- "sha256:bb9333f58fc3a2296fb1d54576138d4cf5d496a2cc118422bd77835e6ae0b9cb",
- "sha256:c1c13185b90bbd3f8b5963cd8ce7ad4ff441924c31e23c975cb150e27c2bf67a",
- "sha256:c3b8bd3133cd50f6b637bb4322822c94c5ce4bf0d724ed5ae70afce62187c492",
- "sha256:c5d97162c196ce54af6700949ddf9409e9833ef1003b4741c2b39ef46f1d9720",
- "sha256:c815270206f983309915a6844fe994b2fa47e5d05c4c4cef267c3b30e34dbe42",
- "sha256:cab2eba3830bf4f6d91e2d6718e0e1c14a2f5ad1af68a89d24ace0c6b17cced7",
- "sha256:d1df34588123fcc88c872f5acb6f74ae59e9d182a2707097f9e28275ec26a12d",
- "sha256:d6bdcd415ba87846fd317bee0774e412e8792832e7805938987e4ede1d13046d",
- "sha256:db9a30ec064129d605d0f1aedc93e00894b9334ec74ba9c6bdd08147434b33eb",
- "sha256:dbc183e7bef690c9abe5ea67b7b60fdbca81aa8da43468287dae7b5c046107d4",
- "sha256:dca802c8db0720ce1c49cce1149ff7b06e91ba15fa84b1d59144fef1a1bc7ac2",
- "sha256:dec6b307ce928e8e112a6bb9921a1cb00a0e14979bf28b98e084a4b8a742bd9b",
- "sha256:df8bb0010fdd0a743b7542589223a2816bdde4d94bb5ad67884348fa2c1c67e8",
- "sha256:e4094c7b464cf0a858e75cd14b03509e84789abf7b79f8537e6a72152109c76e",
- "sha256:e4760a68cab57bfaa628938e9c2971137e05ce48e762a9cb53b76c9b569f1204",
- "sha256:eb09b82377233b902d4c3fbeeb7ad731cdab579c6c6fda1f763cd779139e47c3",
- "sha256:eb862356ee9391dc5a0b3cbc00f416b48c1b9a52d252d898e5b7696a5f9fe150",
- "sha256:ef9528915df81b8f4c7612b19b8628214c65c9b7f74db2e34a646a0a2a0da2d4",
- "sha256:f3157624b7558b914cb039fd1af735e5e8049a87c817cc215109ad1c8779df76",
- "sha256:f3e0992f23bbb0be00a921eae5363329253c3b86287db27092461c887b791e5e",
- "sha256:f9338cc05451f1942d0d8203ec2c346c830f8e86469903d5126c1f0a13a2bcbb",
- "sha256:ffef8fd58a36fb5f1196919638f73dd3ae0db1a878982b27a9a5a176ede4ba91"
+ "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc",
+ "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a",
+ "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417",
+ "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab",
+ "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520",
+ "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36",
+ "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743",
+ "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8",
+ "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed",
+ "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684",
+ "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56",
+ "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324",
+ "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d",
+ "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235",
+ "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e",
+ "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088",
+ "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000",
+ "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7",
+ "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e",
+ "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673",
+ "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c",
+ "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe",
+ "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2",
+ "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098",
+ "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8",
+ "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a",
+ "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0",
+ "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b",
+ "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896",
+ "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e",
+ "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9",
+ "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2",
+ "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b",
+ "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6",
+ "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404",
+ "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f",
+ "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0",
+ "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4",
+ "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc",
+ "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936",
+ "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba",
+ "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872",
+ "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb",
+ "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614",
+ "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1",
+ "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d",
+ "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969",
+ "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b",
+ "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4",
+ "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627",
+ "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956",
+ "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"
],
"markers": "platform_python_implementation != 'PyPy'",
- "version": "==1.17.0"
+ "version": "==1.16.0"
},
"charset-normalizer": {
"hashes": [
@@ -243,36 +228,41 @@
},
"cryptography": {
"hashes": [
- "sha256:0663585d02f76929792470451a5ba64424acc3cd5227b03921dab0e2f27b1709",
- "sha256:08a24a7070b2b6804c1940ff0f910ff728932a9d0e80e7814234269f9d46d069",
- "sha256:232ce02943a579095a339ac4b390fbbe97f5b5d5d107f8a08260ea2768be8cc2",
- "sha256:2905ccf93a8a2a416f3ec01b1a7911c3fe4073ef35640e7ee5296754e30b762b",
- "sha256:299d3da8e00b7e2b54bb02ef58d73cd5f55fb31f33ebbf33bd00d9aa6807df7e",
- "sha256:2c6d112bf61c5ef44042c253e4859b3cbbb50df2f78fa8fae6747a7814484a70",
- "sha256:31e44a986ceccec3d0498e16f3d27b2ee5fdf69ce2ab89b52eaad1d2f33d8778",
- "sha256:3d9a1eca329405219b605fac09ecfc09ac09e595d6def650a437523fcd08dd22",
- "sha256:3dcdedae5c7710b9f97ac6bba7e1052b95c7083c9d0e9df96e02a1932e777895",
- "sha256:47ca71115e545954e6c1d207dd13461ab81f4eccfcb1345eac874828b5e3eaaf",
- "sha256:4a997df8c1c2aae1e1e5ac49c2e4f610ad037fc5a3aadc7b64e39dea42249431",
- "sha256:51956cf8730665e2bdf8ddb8da0056f699c1a5715648c1b0144670c1ba00b48f",
- "sha256:5bcb8a5620008a8034d39bce21dc3e23735dfdb6a33a06974739bfa04f853947",
- "sha256:64c3f16e2a4fc51c0d06af28441881f98c5d91009b8caaff40cf3548089e9c74",
- "sha256:6e2b11c55d260d03a8cf29ac9b5e0608d35f08077d8c087be96287f43af3ccdc",
- "sha256:7b3f5fe74a5ca32d4d0f302ffe6680fcc5c28f8ef0dc0ae8f40c0f3a1b4fca66",
- "sha256:844b6d608374e7d08f4f6e6f9f7b951f9256db41421917dfb2d003dde4cd6b66",
- "sha256:9a8d6802e0825767476f62aafed40532bd435e8a5f7d23bd8b4f5fd04cc80ecf",
- "sha256:aae4d918f6b180a8ab8bf6511a419473d107df4dbb4225c7b48c5c9602c38c7f",
- "sha256:ac1955ce000cb29ab40def14fd1bbfa7af2017cca696ee696925615cafd0dce5",
- "sha256:b88075ada2d51aa9f18283532c9f60e72170041bba88d7f37e49cbb10275299e",
- "sha256:cb013933d4c127349b3948aa8aaf2f12c0353ad0eccd715ca789c8a0f671646f",
- "sha256:cc70b4b581f28d0a254d006f26949245e3657d40d8857066c2ae22a61222ef55",
- "sha256:e9c5266c432a1e23738d178e51c2c7a5e2ddf790f248be939448c0ba2021f9d1",
- "sha256:ea9e57f8ea880eeea38ab5abf9fbe39f923544d7884228ec67d666abd60f5a47",
- "sha256:ee0c405832ade84d4de74b9029bedb7b31200600fa524d218fc29bfa371e97f5",
- "sha256:fdcb265de28585de5b859ae13e3846a8e805268a823a12a4da2597f1f5afc9f0"
+ "sha256:0270572b8bd2c833c3981724b8ee9747b3ec96f699a9665470018594301439ee",
+ "sha256:111a0d8553afcf8eb02a4fea6ca4f59d48ddb34497aa8706a6cf536f1a5ec576",
+ "sha256:16a48c23a62a2f4a285699dba2e4ff2d1cff3115b9df052cdd976a18856d8e3d",
+ "sha256:1b95b98b0d2af784078fa69f637135e3c317091b615cd0905f8b8a087e86fa30",
+ "sha256:1f71c10d1e88467126f0efd484bd44bca5e14c664ec2ede64c32f20875c0d413",
+ "sha256:2424ff4c4ac7f6b8177b53c17ed5d8fa74ae5955656867f5a8affaca36a27abb",
+ "sha256:2bce03af1ce5a5567ab89bd90d11e7bbdff56b8af3acbbec1faded8f44cb06da",
+ "sha256:329906dcc7b20ff3cad13c069a78124ed8247adcac44b10bea1130e36caae0b4",
+ "sha256:37dd623507659e08be98eec89323469e8c7b4c1407c85112634ae3dbdb926fdd",
+ "sha256:3eaafe47ec0d0ffcc9349e1708be2aaea4c6dd4978d76bf6eb0cb2c13636c6fc",
+ "sha256:5e6275c09d2badf57aea3afa80d975444f4be8d3bc58f7f80d2a484c6f9485c8",
+ "sha256:6fe07eec95dfd477eb9530aef5bead34fec819b3aaf6c5bd6d20565da607bfe1",
+ "sha256:7367d7b2eca6513681127ebad53b2582911d1736dc2ffc19f2c3ae49997496bc",
+ "sha256:7cde5f38e614f55e28d831754e8a3bacf9ace5d1566235e39d91b35502d6936e",
+ "sha256:9481ffe3cf013b71b2428b905c4f7a9a4f76ec03065b05ff499bb5682a8d9ad8",
+ "sha256:98d8dc6d012b82287f2c3d26ce1d2dd130ec200c8679b6213b3c73c08b2b7940",
+ "sha256:a011a644f6d7d03736214d38832e030d8268bcff4a41f728e6030325fea3e400",
+ "sha256:a2913c5375154b6ef2e91c10b5720ea6e21007412f6437504ffea2109b5a33d7",
+ "sha256:a30596bae9403a342c978fb47d9b0ee277699fa53bbafad14706af51fe543d16",
+ "sha256:b03c2ae5d2f0fc05f9a2c0c997e1bc18c8229f392234e8a0194f202169ccd278",
+ "sha256:b6cd2203306b63e41acdf39aa93b86fb566049aeb6dc489b70e34bcd07adca74",
+ "sha256:b7ffe927ee6531c78f81aa17e684e2ff617daeba7f189f911065b2ea2d526dec",
+ "sha256:b8cac287fafc4ad485b8a9b67d0ee80c66bf3574f655d3b97ef2e1082360faf1",
+ "sha256:ba334e6e4b1d92442b75ddacc615c5476d4ad55cc29b15d590cc6b86efa487e2",
+ "sha256:ba3e4a42397c25b7ff88cdec6e2a16c2be18720f317506ee25210f6d31925f9c",
+ "sha256:c41fb5e6a5fe9ebcd58ca3abfeb51dffb5d83d6775405305bfa8715b76521922",
+ "sha256:cd2030f6650c089aeb304cf093f3244d34745ce0cfcc39f20c6fbfe030102e2a",
+ "sha256:cd65d75953847815962c84a4654a84850b2bb4aed3f26fadcc1c13892e1e29f6",
+ "sha256:e4985a790f921508f36f81831817cbc03b102d643b5fcb81cd33df3fa291a1a1",
+ "sha256:e807b3188f9eb0eaa7bbb579b462c5ace579f1cedb28107ce8b48a9f7ad3679e",
+ "sha256:f12764b8fffc7a123f641d7d049d382b73f96a34117e0b637b80643169cec8ac",
+ "sha256:f8837fe1d6ac4a8052a9a8ddab256bc006242696f03368a4009be7ee3075cdb7"
],
"markers": "python_version >= '3.7'",
- "version": "==43.0.0"
+ "version": "==42.0.5"
},
"defusedxml": {
"hashes": [
@@ -292,10 +282,10 @@
},
"dj-database-url": {
"hashes": [
- "sha256:3e792567b0aa9a4884860af05fe2aa4968071ad351e033b6db632f97ac6db9de",
- "sha256:9f9b05058ddf888f1e6f840048b8d705ff9395e3b52a07165daa3d8b9360551b"
+ "sha256:04bc34b248d4c21aaa13e4ab419ae6575ef5f10f3df735ce7da97722caa356e0",
+ "sha256:f2042cefe1086e539c9da39fad5ad7f61173bf79665e69bf7e4de55fa88b135f"
],
- "version": "==2.2.0"
+ "version": "==2.1.0"
},
"dj-email-url": {
"hashes": [
@@ -347,12 +337,12 @@
},
"django-cors-headers": {
"hashes": [
- "sha256:5c6e3b7fe870876a1efdfeb4f433782c3524078fa0dc9e0195f6706ce7a242f6",
- "sha256:92cf4633e22af67a230a1456cb1b7a02bb213d6536d2dcb2a4a24092ea9cebc2"
+ "sha256:0b1fd19297e37417fc9f835d39e45c8c642938ddba1acce0c1753d3edef04f36",
+ "sha256:0bf65ef45e606aff1994d35503e6b677c0b26cafff6506f8fd7187f3be840207"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==4.4.0"
+ "version": "==4.3.1"
},
"django-csp": {
"hashes": [
@@ -372,12 +362,12 @@
},
"django-import-export": {
"hashes": [
- "sha256:16ecc5a9f0df46bde6eb278a3e65ebda0ee1db55656f36440e9fb83f40ab85a3",
- "sha256:730ae2443a02b1ba27d8dba078a27ae9123adfcabb78161b4f130843607b3df9"
+ "sha256:2eac09e8cec8670f36e24314760448011ad23c51e8fb930d55f50d0c3c926da0",
+ "sha256:4deabc557801d368093608c86fd0f4831bc9540e2ea41ca2f023e2efb3eb6f48"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==4.1.1"
+ "version": "==3.3.8"
},
"django-login-required-middleware": {
"hashes": [
@@ -391,11 +381,11 @@
"phonenumberslite"
],
"hashes": [
- "sha256:196c917b70c01a98e327f482eb8a4a4a55a29891db551f99078585397370b3ba",
- "sha256:8a560fe1b01b94c9de8cde22bc373b695f023cc6df4baba00264cb079da9f631"
+ "sha256:bc6eaa49d1f9d870944f5280258db511e3a1ba5e2fbbed255488dceacae45d06",
+ "sha256:f9cdb3de085f99c249328293a3b93d4e5fa440c0c8e3b99eb0d0f54748629797"
],
"markers": "python_version >= '3.8'",
- "version": "==8.0.0"
+ "version": "==7.3.0"
},
"django-waffle": {
"hashes": [
@@ -426,14 +416,22 @@
"markers": "python_version >= '3.8'",
"version": "==11.0.0"
},
+ "et-xmlfile": {
+ "hashes": [
+ "sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c",
+ "sha256:a2ba85d1d6a74ef63837eed693bcb89c3f752169b0e3e7ae5b16ca5e1b3deada"
+ ],
+ "markers": "python_version >= '3.6'",
+ "version": "==1.1.0"
+ },
"faker": {
"hashes": [
- "sha256:0d3c0399204aaf8205cc1750db443474ca0436f177126b2c27b798e8336cc74f",
- "sha256:6a3a08be54c37e05f7943d7ba5211d252c1de737687a46ad6f29209d8d5db11f"
+ "sha256:87ef41e24b39a5be66ecd874af86f77eebd26782a2681200e86c5326340a95d3",
+ "sha256:e23a2b74888885c3d23a9237bacb823041291c03d609a39acb9ebe6c123f3986"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==28.0.0"
+ "version": "==25.0.0"
},
"fred-epplib": {
"git": "https://github.com/cisagov/epplib.git",
@@ -569,20 +567,20 @@
},
"gunicorn": {
"hashes": [
- "sha256:ec400d38950de4dfd418cff8328b2c8faed0edb0d517d3394e457c317908ca4d",
- "sha256:f014447a0101dc57e294f6c18ca6b40227a4c90e9bdb586042628030cba004ec"
+ "sha256:350679f91b24062c86e386e198a15438d53a7a8207235a78ba1b53df4c4378d9",
+ "sha256:4a0b436239ff76fb33f11c07a16482c521a7e09c1ce3cc293c2330afe01bec63"
],
"index": "pypi",
"markers": "python_version >= '3.7'",
- "version": "==23.0.0"
+ "version": "==22.0.0"
},
"idna": {
"hashes": [
- "sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac",
- "sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603"
+ "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc",
+ "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"
],
- "markers": "python_version >= '3.6'",
- "version": "==3.8"
+ "markers": "python_version >= '3.5'",
+ "version": "==3.7"
},
"jmespath": {
"hashes": [
@@ -594,155 +592,177 @@
},
"lxml": {
"hashes": [
- "sha256:01220dca0d066d1349bd6a1726856a78f7929f3878f7e2ee83c296c69495309e",
- "sha256:02ced472497b8362c8e902ade23e3300479f4f43e45f4105c85ef43b8db85229",
- "sha256:052d99051e77a4f3e8482c65014cf6372e61b0a6f4fe9edb98503bb5364cfee3",
- "sha256:07da23d7ee08577760f0a71d67a861019103e4812c87e2fab26b039054594cc5",
- "sha256:094cb601ba9f55296774c2d57ad68730daa0b13dc260e1f941b4d13678239e70",
- "sha256:0a7056921edbdd7560746f4221dca89bb7a3fe457d3d74267995253f46343f15",
- "sha256:0c120f43553ec759f8de1fee2f4794452b0946773299d44c36bfe18e83caf002",
- "sha256:0d7b36afa46c97875303a94e8f3ad932bf78bace9e18e603f2085b652422edcd",
- "sha256:0fdf3a3059611f7585a78ee10399a15566356116a4288380921a4b598d807a22",
- "sha256:109fa6fede314cc50eed29e6e56c540075e63d922455346f11e4d7a036d2b8cf",
- "sha256:146173654d79eb1fc97498b4280c1d3e1e5d58c398fa530905c9ea50ea849b22",
- "sha256:1473427aff3d66a3fa2199004c3e601e6c4500ab86696edffdbc84954c72d832",
- "sha256:1483fd3358963cc5c1c9b122c80606a3a79ee0875bcac0204149fa09d6ff2727",
- "sha256:168f2dfcfdedf611eb285efac1516c8454c8c99caf271dccda8943576b67552e",
- "sha256:17e8d968d04a37c50ad9c456a286b525d78c4a1c15dd53aa46c1d8e06bf6fa30",
- "sha256:18feb4b93302091b1541221196a2155aa296c363fd233814fa11e181adebc52f",
- "sha256:1afe0a8c353746e610bd9031a630a95bcfb1a720684c3f2b36c4710a0a96528f",
- "sha256:1d04f064bebdfef9240478f7a779e8c5dc32b8b7b0b2fc6a62e39b928d428e51",
- "sha256:1fdc9fae8dd4c763e8a31e7630afef517eab9f5d5d31a278df087f307bf601f4",
- "sha256:1ffc23010330c2ab67fac02781df60998ca8fe759e8efde6f8b756a20599c5de",
- "sha256:20094fc3f21ea0a8669dc4c61ed7fa8263bd37d97d93b90f28fc613371e7a875",
- "sha256:213261f168c5e1d9b7535a67e68b1f59f92398dd17a56d934550837143f79c42",
- "sha256:218c1b2e17a710e363855594230f44060e2025b05c80d1f0661258142b2add2e",
- "sha256:23e0553b8055600b3bf4a00b255ec5c92e1e4aebf8c2c09334f8368e8bd174d6",
- "sha256:25f1b69d41656b05885aa185f5fdf822cb01a586d1b32739633679699f220391",
- "sha256:2b3778cb38212f52fac9fe913017deea2fdf4eb1a4f8e4cfc6b009a13a6d3fcc",
- "sha256:2bc9fd5ca4729af796f9f59cd8ff160fe06a474da40aca03fcc79655ddee1a8b",
- "sha256:2c226a06ecb8cdef28845ae976da407917542c5e6e75dcac7cc33eb04aaeb237",
- "sha256:2c3406b63232fc7e9b8783ab0b765d7c59e7c59ff96759d8ef9632fca27c7ee4",
- "sha256:2c86bf781b12ba417f64f3422cfc302523ac9cd1d8ae8c0f92a1c66e56ef2e86",
- "sha256:2d9b8d9177afaef80c53c0a9e30fa252ff3036fb1c6494d427c066a4ce6a282f",
- "sha256:2dec2d1130a9cda5b904696cec33b2cfb451304ba9081eeda7f90f724097300a",
- "sha256:2dfab5fa6a28a0b60a20638dc48e6343c02ea9933e3279ccb132f555a62323d8",
- "sha256:2ecdd78ab768f844c7a1d4a03595038c166b609f6395e25af9b0f3f26ae1230f",
- "sha256:315f9542011b2c4e1d280e4a20ddcca1761993dda3afc7a73b01235f8641e903",
- "sha256:36aef61a1678cb778097b4a6eeae96a69875d51d1e8f4d4b491ab3cfb54b5a03",
- "sha256:384aacddf2e5813a36495233b64cb96b1949da72bef933918ba5c84e06af8f0e",
- "sha256:3879cc6ce938ff4eb4900d901ed63555c778731a96365e53fadb36437a131a99",
- "sha256:3c174dc350d3ec52deb77f2faf05c439331d6ed5e702fc247ccb4e6b62d884b7",
- "sha256:3eb44520c4724c2e1a57c0af33a379eee41792595023f367ba3952a2d96c2aab",
- "sha256:406246b96d552e0503e17a1006fd27edac678b3fcc9f1be71a2f94b4ff61528d",
- "sha256:41ce1f1e2c7755abfc7e759dc34d7d05fd221723ff822947132dc934d122fe22",
- "sha256:423b121f7e6fa514ba0c7918e56955a1d4470ed35faa03e3d9f0e3baa4c7e492",
- "sha256:44264ecae91b30e5633013fb66f6ddd05c006d3e0e884f75ce0b4755b3e3847b",
- "sha256:482c2f67761868f0108b1743098640fbb2a28a8e15bf3f47ada9fa59d9fe08c3",
- "sha256:4b0c7a688944891086ba192e21c5229dea54382f4836a209ff8d0a660fac06be",
- "sha256:4c1fefd7e3d00921c44dc9ca80a775af49698bbfd92ea84498e56acffd4c5469",
- "sha256:4e109ca30d1edec1ac60cdbe341905dc3b8f55b16855e03a54aaf59e51ec8c6f",
- "sha256:501d0d7e26b4d261fca8132854d845e4988097611ba2531408ec91cf3fd9d20a",
- "sha256:516f491c834eb320d6c843156440fe7fc0d50b33e44387fcec5b02f0bc118a4c",
- "sha256:51806cfe0279e06ed8500ce19479d757db42a30fd509940b1701be9c86a5ff9a",
- "sha256:562e7494778a69086f0312ec9689f6b6ac1c6b65670ed7d0267e49f57ffa08c4",
- "sha256:56b9861a71575f5795bde89256e7467ece3d339c9b43141dbdd54544566b3b94",
- "sha256:5b8f5db71b28b8c404956ddf79575ea77aa8b1538e8b2ef9ec877945b3f46442",
- "sha256:5c2fb570d7823c2bbaf8b419ba6e5662137f8166e364a8b2b91051a1fb40ab8b",
- "sha256:5c54afdcbb0182d06836cc3d1be921e540be3ebdf8b8a51ee3ef987537455f84",
- "sha256:5d6a6972b93c426ace71e0be9a6f4b2cfae9b1baed2eed2006076a746692288c",
- "sha256:609251a0ca4770e5a8768ff902aa02bf636339c5a93f9349b48eb1f606f7f3e9",
- "sha256:62d172f358f33a26d6b41b28c170c63886742f5b6772a42b59b4f0fa10526cb1",
- "sha256:62f7fdb0d1ed2065451f086519865b4c90aa19aed51081979ecd05a21eb4d1be",
- "sha256:658f2aa69d31e09699705949b5fc4719cbecbd4a97f9656a232e7d6c7be1a367",
- "sha256:65ab5685d56914b9a2a34d67dd5488b83213d680b0c5d10b47f81da5a16b0b0e",
- "sha256:68934b242c51eb02907c5b81d138cb977b2129a0a75a8f8b60b01cb8586c7b21",
- "sha256:68b87753c784d6acb8a25b05cb526c3406913c9d988d51f80adecc2b0775d6aa",
- "sha256:69959bd3167b993e6e710b99051265654133a98f20cec1d9b493b931942e9c16",
- "sha256:6a7095eeec6f89111d03dabfe5883a1fd54da319c94e0fb104ee8f23616b572d",
- "sha256:6b038cc86b285e4f9fea2ba5ee76e89f21ed1ea898e287dc277a25884f3a7dfe",
- "sha256:6ba0d3dcac281aad8a0e5b14c7ed6f9fa89c8612b47939fc94f80b16e2e9bc83",
- "sha256:6e91cf736959057f7aac7adfc83481e03615a8e8dd5758aa1d95ea69e8931dba",
- "sha256:6ee8c39582d2652dcd516d1b879451500f8db3fe3607ce45d7c5957ab2596040",
- "sha256:6f651ebd0b21ec65dfca93aa629610a0dbc13dbc13554f19b0113da2e61a4763",
- "sha256:71a8dd38fbd2f2319136d4ae855a7078c69c9a38ae06e0c17c73fd70fc6caad8",
- "sha256:74068c601baff6ff021c70f0935b0c7bc528baa8ea210c202e03757c68c5a4ff",
- "sha256:7437237c6a66b7ca341e868cda48be24b8701862757426852c9b3186de1da8a2",
- "sha256:747a3d3e98e24597981ca0be0fd922aebd471fa99d0043a3842d00cdcad7ad6a",
- "sha256:74bcb423462233bc5d6066e4e98b0264e7c1bed7541fff2f4e34fe6b21563c8b",
- "sha256:78d9b952e07aed35fe2e1a7ad26e929595412db48535921c5013edc8aa4a35ce",
- "sha256:7b1cd427cb0d5f7393c31b7496419da594fe600e6fdc4b105a54f82405e6626c",
- "sha256:7d3d1ca42870cdb6d0d29939630dbe48fa511c203724820fc0fd507b2fb46577",
- "sha256:7e2f58095acc211eb9d8b5771bf04df9ff37d6b87618d1cbf85f92399c98dae8",
- "sha256:7f41026c1d64043a36fda21d64c5026762d53a77043e73e94b71f0521939cc71",
- "sha256:81b4e48da4c69313192d8c8d4311e5d818b8be1afe68ee20f6385d0e96fc9512",
- "sha256:86a6b24b19eaebc448dc56b87c4865527855145d851f9fc3891673ff97950540",
- "sha256:874a216bf6afaf97c263b56371434e47e2c652d215788396f60477540298218f",
- "sha256:89e043f1d9d341c52bf2af6d02e6adde62e0a46e6755d5eb60dc6e4f0b8aeca2",
- "sha256:8c72e9563347c7395910de6a3100a4840a75a6f60e05af5e58566868d5eb2d6a",
- "sha256:8dc2c0395bea8254d8daebc76dcf8eb3a95ec2a46fa6fae5eaccee366bfe02ce",
- "sha256:8f0de2d390af441fe8b2c12626d103540b5d850d585b18fcada58d972b74a74e",
- "sha256:92e67a0be1639c251d21e35fe74df6bcc40cba445c2cda7c4a967656733249e2",
- "sha256:94d6c3782907b5e40e21cadf94b13b0842ac421192f26b84c45f13f3c9d5dc27",
- "sha256:97acf1e1fd66ab53dacd2c35b319d7e548380c2e9e8c54525c6e76d21b1ae3b1",
- "sha256:9ada35dd21dc6c039259596b358caab6b13f4db4d4a7f8665764d616daf9cc1d",
- "sha256:9c52100e2c2dbb0649b90467935c4b0de5528833c76a35ea1a2691ec9f1ee7a1",
- "sha256:9e41506fec7a7f9405b14aa2d5c8abbb4dbbd09d88f9496958b6d00cb4d45330",
- "sha256:9e4b47ac0f5e749cfc618efdf4726269441014ae1d5583e047b452a32e221920",
- "sha256:9fb81d2824dff4f2e297a276297e9031f46d2682cafc484f49de182aa5e5df99",
- "sha256:a0eabd0a81625049c5df745209dc7fcef6e2aea7793e5f003ba363610aa0a3ff",
- "sha256:a3d819eb6f9b8677f57f9664265d0a10dd6551d227afb4af2b9cd7bdc2ccbf18",
- "sha256:a87de7dd873bf9a792bf1e58b1c3887b9264036629a5bf2d2e6579fe8e73edff",
- "sha256:aa617107a410245b8660028a7483b68e7914304a6d4882b5ff3d2d3eb5948d8c",
- "sha256:aac0bbd3e8dd2d9c45ceb82249e8bdd3ac99131a32b4d35c8af3cc9db1657179",
- "sha256:ab6dd83b970dc97c2d10bc71aa925b84788c7c05de30241b9e96f9b6d9ea3080",
- "sha256:ace2c2326a319a0bb8a8b0e5b570c764962e95818de9f259ce814ee666603f19",
- "sha256:ae5fe5c4b525aa82b8076c1a59d642c17b6e8739ecf852522c6321852178119d",
- "sha256:b11a5d918a6216e521c715b02749240fb07ae5a1fefd4b7bf12f833bc8b4fe70",
- "sha256:b1c8c20847b9f34e98080da785bb2336ea982e7f913eed5809e5a3c872900f32",
- "sha256:b369d3db3c22ed14c75ccd5af429086f166a19627e84a8fdade3f8f31426e52a",
- "sha256:b710bc2b8292966b23a6a0121f7a6c51d45d2347edcc75f016ac123b8054d3f2",
- "sha256:bd96517ef76c8654446fc3db9242d019a1bb5fe8b751ba414765d59f99210b79",
- "sha256:c00f323cc00576df6165cc9d21a4c21285fa6b9989c5c39830c3903dc4303ef3",
- "sha256:c162b216070f280fa7da844531169be0baf9ccb17263cf5a8bf876fcd3117fa5",
- "sha256:c1a69e58a6bb2de65902051d57fde951febad631a20a64572677a1052690482f",
- "sha256:c1f794c02903c2824fccce5b20c339a1a14b114e83b306ff11b597c5f71a1c8d",
- "sha256:c24037349665434f375645fa9d1f5304800cec574d0310f618490c871fd902b3",
- "sha256:c300306673aa0f3ed5ed9372b21867690a17dba38c68c44b287437c362ce486b",
- "sha256:c56a1d43b2f9ee4786e4658c7903f05da35b923fb53c11025712562d5cc02753",
- "sha256:c6379f35350b655fd817cd0d6cbeef7f265f3ae5fedb1caae2eb442bbeae9ab9",
- "sha256:c802e1c2ed9f0c06a65bc4ed0189d000ada8049312cfeab6ca635e39c9608957",
- "sha256:cb83f8a875b3d9b458cada4f880fa498646874ba4011dc974e071a0a84a1b033",
- "sha256:cf120cce539453ae086eacc0130a324e7026113510efa83ab42ef3fcfccac7fb",
- "sha256:dd36439be765e2dde7660212b5275641edbc813e7b24668831a5c8ac91180656",
- "sha256:dd5350b55f9fecddc51385463a4f67a5da829bc741e38cf689f38ec9023f54ab",
- "sha256:df5c7333167b9674aa8ae1d4008fa4bc17a313cc490b2cca27838bbdcc6bb15b",
- "sha256:e63601ad5cd8f860aa99d109889b5ac34de571c7ee902d6812d5d9ddcc77fa7d",
- "sha256:e92ce66cd919d18d14b3856906a61d3f6b6a8500e0794142338da644260595cd",
- "sha256:e99f5507401436fdcc85036a2e7dc2e28d962550afe1cbfc07c40e454256a859",
- "sha256:ea2e2f6f801696ad7de8aec061044d6c8c0dd4037608c7cab38a9a4d316bfb11",
- "sha256:eafa2c8658f4e560b098fe9fc54539f86528651f61849b22111a9b107d18910c",
- "sha256:ecd4ad8453ac17bc7ba3868371bffb46f628161ad0eefbd0a855d2c8c32dd81a",
- "sha256:ee70d08fd60c9565ba8190f41a46a54096afa0eeb8f76bd66f2c25d3b1b83005",
- "sha256:eec1bb8cdbba2925bedc887bc0609a80e599c75b12d87ae42ac23fd199445654",
- "sha256:ef0c1fe22171dd7c7c27147f2e9c3e86f8bdf473fed75f16b0c2e84a5030ce80",
- "sha256:f2901429da1e645ce548bf9171784c0f74f0718c3f6150ce166be39e4dd66c3e",
- "sha256:f422a209d2455c56849442ae42f25dbaaba1c6c3f501d58761c619c7836642ec",
- "sha256:f65e5120863c2b266dbcc927b306c5b78e502c71edf3295dfcb9501ec96e5fc7",
- "sha256:f7d4a670107d75dfe5ad080bed6c341d18c4442f9378c9f58e5851e86eb79965",
- "sha256:f914c03e6a31deb632e2daa881fe198461f4d06e57ac3d0e05bbcab8eae01945",
- "sha256:fb66442c2546446944437df74379e9cf9e9db353e61301d1a0e26482f43f0dd8"
+ "sha256:04ab5415bf6c86e0518d57240a96c4d1fcfc3cb370bb2ac2a732b67f579e5a04",
+ "sha256:057cdc6b86ab732cf361f8b4d8af87cf195a1f6dc5b0ff3de2dced242c2015e0",
+ "sha256:058a1308914f20784c9f4674036527e7c04f7be6fb60f5d61353545aa7fcb739",
+ "sha256:08802f0c56ed150cc6885ae0788a321b73505d2263ee56dad84d200cab11c07a",
+ "sha256:0a15438253b34e6362b2dc41475e7f80de76320f335e70c5528b7148cac253a1",
+ "sha256:0c3f67e2aeda739d1cc0b1102c9a9129f7dc83901226cc24dd72ba275ced4218",
+ "sha256:0e7259016bc4345a31af861fdce942b77c99049d6c2107ca07dc2bba2435c1d9",
+ "sha256:0ed777c1e8c99b63037b91f9d73a6aad20fd035d77ac84afcc205225f8f41188",
+ "sha256:0f5d65c39f16717a47c36c756af0fb36144069c4718824b7533f803ecdf91138",
+ "sha256:0f8c09ed18ecb4ebf23e02b8e7a22a05d6411911e6fabef3a36e4f371f4f2585",
+ "sha256:11a04306fcba10cd9637e669fd73aa274c1c09ca64af79c041aa820ea992b637",
+ "sha256:1ae67b4e737cddc96c99461d2f75d218bdf7a0c3d3ad5604d1f5e7464a2f9ffe",
+ "sha256:1c5bb205e9212d0ebddf946bc07e73fa245c864a5f90f341d11ce7b0b854475d",
+ "sha256:1f7785f4f789fdb522729ae465adcaa099e2a3441519df750ebdccc481d961a1",
+ "sha256:200e63525948e325d6a13a76ba2911f927ad399ef64f57898cf7c74e69b71095",
+ "sha256:21c2e6b09565ba5b45ae161b438e033a86ad1736b8c838c766146eff8ceffff9",
+ "sha256:2213afee476546a7f37c7a9b4ad4d74b1e112a6fafffc9185d6d21f043128c81",
+ "sha256:27aa20d45c2e0b8cd05da6d4759649170e8dfc4f4e5ef33a34d06f2d79075d57",
+ "sha256:2a66bf12fbd4666dd023b6f51223aed3d9f3b40fef06ce404cb75bafd3d89536",
+ "sha256:2c9d147f754b1b0e723e6afb7ba1566ecb162fe4ea657f53d2139bbf894d050a",
+ "sha256:2ddfe41ddc81f29a4c44c8ce239eda5ade4e7fc305fb7311759dd6229a080052",
+ "sha256:31e9a882013c2f6bd2f2c974241bf4ba68c85eba943648ce88936d23209a2e01",
+ "sha256:3249cc2989d9090eeac5467e50e9ec2d40704fea9ab72f36b034ea34ee65ca98",
+ "sha256:3545039fa4779be2df51d6395e91a810f57122290864918b172d5dc7ca5bb433",
+ "sha256:394ed3924d7a01b5bd9a0d9d946136e1c2f7b3dc337196d99e61740ed4bc6fe1",
+ "sha256:3a6b45da02336895da82b9d472cd274b22dc27a5cea1d4b793874eead23dd14f",
+ "sha256:3a74c4f27167cb95c1d4af1c0b59e88b7f3e0182138db2501c353555f7ec57f4",
+ "sha256:3d0c3dd24bb4605439bf91068598d00c6370684f8de4a67c2992683f6c309d6b",
+ "sha256:3dbe858ee582cbb2c6294dc85f55b5f19c918c2597855e950f34b660f1a5ede6",
+ "sha256:3dc773b2861b37b41a6136e0b72a1a44689a9c4c101e0cddb6b854016acc0aa8",
+ "sha256:3f7765e69bbce0906a7c74d5fe46d2c7a7596147318dbc08e4a2431f3060e306",
+ "sha256:417d14450f06d51f363e41cace6488519038f940676ce9664b34ebf5653433a5",
+ "sha256:44f6c7caff88d988db017b9b0e4ab04934f11e3e72d478031efc7edcac6c622f",
+ "sha256:491755202eb21a5e350dae00c6d9a17247769c64dcf62d8c788b5c135e179dc4",
+ "sha256:4951e4f7a5680a2db62f7f4ab2f84617674d36d2d76a729b9a8be4b59b3659be",
+ "sha256:52421b41ac99e9d91934e4d0d0fe7da9f02bfa7536bb4431b4c05c906c8c6919",
+ "sha256:530e7c04f72002d2f334d5257c8a51bf409db0316feee7c87e4385043be136af",
+ "sha256:533658f8fbf056b70e434dff7e7aa611bcacb33e01f75de7f821810e48d1bb66",
+ "sha256:5670fb70a828663cc37552a2a85bf2ac38475572b0e9b91283dc09efb52c41d1",
+ "sha256:56c22432809085b3f3ae04e6e7bdd36883d7258fcd90e53ba7b2e463efc7a6af",
+ "sha256:58278b29cb89f3e43ff3e0c756abbd1518f3ee6adad9e35b51fb101c1c1daaec",
+ "sha256:588008b8497667f1ddca7c99f2f85ce8511f8f7871b4a06ceede68ab62dff64b",
+ "sha256:59565f10607c244bc4c05c0c5fa0c190c990996e0c719d05deec7030c2aa8289",
+ "sha256:59689a75ba8d7ffca577aefd017d08d659d86ad4585ccc73e43edbfc7476781a",
+ "sha256:5aea8212fb823e006b995c4dda533edcf98a893d941f173f6c9506126188860d",
+ "sha256:5c670c0406bdc845b474b680b9a5456c561c65cf366f8db5a60154088c92d102",
+ "sha256:5ca1e8188b26a819387b29c3895c47a5e618708fe6f787f3b1a471de2c4a94d9",
+ "sha256:5d077bc40a1fe984e1a9931e801e42959a1e6598edc8a3223b061d30fbd26bbc",
+ "sha256:5d5792e9b3fb8d16a19f46aa8208987cfeafe082363ee2745ea8b643d9cc5b45",
+ "sha256:5dd1537e7cc06efd81371f5d1a992bd5ab156b2b4f88834ca852de4a8ea523fa",
+ "sha256:5ea7b6766ac2dfe4bcac8b8595107665a18ef01f8c8343f00710b85096d1b53a",
+ "sha256:622020d4521e22fb371e15f580d153134bfb68d6a429d1342a25f051ec72df1c",
+ "sha256:627402ad8dea044dde2eccde4370560a2b750ef894c9578e1d4f8ffd54000461",
+ "sha256:644df54d729ef810dcd0f7732e50e5ad1bd0a135278ed8d6bcb06f33b6b6f708",
+ "sha256:64641a6068a16201366476731301441ce93457eb8452056f570133a6ceb15fca",
+ "sha256:64c2baa7774bc22dd4474248ba16fe1a7f611c13ac6123408694d4cc93d66dbd",
+ "sha256:6588c459c5627fefa30139be4d2e28a2c2a1d0d1c265aad2ba1935a7863a4913",
+ "sha256:66bc5eb8a323ed9894f8fa0ee6cb3e3fb2403d99aee635078fd19a8bc7a5a5da",
+ "sha256:68a2610dbe138fa8c5826b3f6d98a7cfc29707b850ddcc3e21910a6fe51f6ca0",
+ "sha256:6935bbf153f9a965f1e07c2649c0849d29832487c52bb4a5c5066031d8b44fd5",
+ "sha256:6992030d43b916407c9aa52e9673612ff39a575523c5f4cf72cdef75365709a5",
+ "sha256:6a014510830df1475176466b6087fc0c08b47a36714823e58d8b8d7709132a96",
+ "sha256:6ab833e4735a7e5533711a6ea2df26459b96f9eec36d23f74cafe03631647c41",
+ "sha256:6cc6ee342fb7fa2471bd9b6d6fdfc78925a697bf5c2bcd0a302e98b0d35bfad3",
+ "sha256:6cf58416653c5901e12624e4013708b6e11142956e7f35e7a83f1ab02f3fe456",
+ "sha256:70a9768e1b9d79edca17890175ba915654ee1725975d69ab64813dd785a2bd5c",
+ "sha256:70ac664a48aa64e5e635ae5566f5227f2ab7f66a3990d67566d9907edcbbf867",
+ "sha256:71e97313406ccf55d32cc98a533ee05c61e15d11b99215b237346171c179c0b0",
+ "sha256:7221d49259aa1e5a8f00d3d28b1e0b76031655ca74bb287123ef56c3db92f213",
+ "sha256:74b28c6334cca4dd704e8004cba1955af0b778cf449142e581e404bd211fb619",
+ "sha256:764b521b75701f60683500d8621841bec41a65eb739b8466000c6fdbc256c240",
+ "sha256:78bfa756eab503673991bdcf464917ef7845a964903d3302c5f68417ecdc948c",
+ "sha256:794f04eec78f1d0e35d9e0c36cbbb22e42d370dda1609fb03bcd7aeb458c6377",
+ "sha256:79bd05260359170f78b181b59ce871673ed01ba048deef4bf49a36ab3e72e80b",
+ "sha256:7a7efd5b6d3e30d81ec68ab8a88252d7c7c6f13aaa875009fe3097eb4e30b84c",
+ "sha256:7c17b64b0a6ef4e5affae6a3724010a7a66bda48a62cfe0674dabd46642e8b54",
+ "sha256:804f74efe22b6a227306dd890eecc4f8c59ff25ca35f1f14e7482bbce96ef10b",
+ "sha256:853e074d4931dbcba7480d4dcab23d5c56bd9607f92825ab80ee2bd916edea53",
+ "sha256:857500f88b17a6479202ff5fe5f580fc3404922cd02ab3716197adf1ef628029",
+ "sha256:865bad62df277c04beed9478fe665b9ef63eb28fe026d5dedcb89b537d2e2ea6",
+ "sha256:88e22fc0a6684337d25c994381ed8a1580a6f5ebebd5ad41f89f663ff4ec2885",
+ "sha256:8b9c07e7a45bb64e21df4b6aa623cb8ba214dfb47d2027d90eac197329bb5e94",
+ "sha256:8de8f9d6caa7f25b204fc861718815d41cbcf27ee8f028c89c882a0cf4ae4134",
+ "sha256:8e77c69d5892cb5ba71703c4057091e31ccf534bd7f129307a4d084d90d014b8",
+ "sha256:9123716666e25b7b71c4e1789ec829ed18663152008b58544d95b008ed9e21e9",
+ "sha256:958244ad566c3ffc385f47dddde4145088a0ab893504b54b52c041987a8c1863",
+ "sha256:96323338e6c14e958d775700ec8a88346014a85e5de73ac7967db0367582049b",
+ "sha256:9676bfc686fa6a3fa10cd4ae6b76cae8be26eb5ec6811d2a325636c460da1806",
+ "sha256:9b0ff53900566bc6325ecde9181d89afadc59c5ffa39bddf084aaedfe3b06a11",
+ "sha256:9b9ec9c9978b708d488bec36b9e4c94d88fd12ccac3e62134a9d17ddba910ea9",
+ "sha256:9c6ad0fbf105f6bcc9300c00010a2ffa44ea6f555df1a2ad95c88f5656104817",
+ "sha256:9ca66b8e90daca431b7ca1408cae085d025326570e57749695d6a01454790e95",
+ "sha256:9e2addd2d1866fe112bc6f80117bcc6bc25191c5ed1bfbcf9f1386a884252ae8",
+ "sha256:a0af35bd8ebf84888373630f73f24e86bf016642fb8576fba49d3d6b560b7cbc",
+ "sha256:a2b44bec7adf3e9305ce6cbfa47a4395667e744097faed97abb4728748ba7d47",
+ "sha256:a2dfe7e2473f9b59496247aad6e23b405ddf2e12ef0765677b0081c02d6c2c0b",
+ "sha256:a55ee573116ba208932e2d1a037cc4b10d2c1cb264ced2184d00b18ce585b2c0",
+ "sha256:a7baf9ffc238e4bf401299f50e971a45bfcc10a785522541a6e3179c83eabf0a",
+ "sha256:a8d5c70e04aac1eda5c829a26d1f75c6e5286c74743133d9f742cda8e53b9c2f",
+ "sha256:a91481dbcddf1736c98a80b122afa0f7296eeb80b72344d7f45dc9f781551f56",
+ "sha256:ab31a88a651039a07a3ae327d68ebdd8bc589b16938c09ef3f32a4b809dc96ef",
+ "sha256:abc25c3cab9ec7fcd299b9bcb3b8d4a1231877e425c650fa1c7576c5107ab851",
+ "sha256:adfb84ca6b87e06bc6b146dc7da7623395db1e31621c4785ad0658c5028b37d7",
+ "sha256:afbbdb120d1e78d2ba8064a68058001b871154cc57787031b645c9142b937a62",
+ "sha256:afd5562927cdef7c4f5550374acbc117fd4ecc05b5007bdfa57cc5355864e0a4",
+ "sha256:b070bbe8d3f0f6147689bed981d19bbb33070225373338df755a46893528104a",
+ "sha256:b0b58fbfa1bf7367dde8a557994e3b1637294be6cf2169810375caf8571a085c",
+ "sha256:b560e3aa4b1d49e0e6c847d72665384db35b2f5d45f8e6a5c0072e0283430533",
+ "sha256:b6241d4eee5f89453307c2f2bfa03b50362052ca0af1efecf9fef9a41a22bb4f",
+ "sha256:b6787b643356111dfd4032b5bffe26d2f8331556ecb79e15dacb9275da02866e",
+ "sha256:bcbf4af004f98793a95355980764b3d80d47117678118a44a80b721c9913436a",
+ "sha256:beb72935a941965c52990f3a32d7f07ce869fe21c6af8b34bf6a277b33a345d3",
+ "sha256:bf2e2458345d9bffb0d9ec16557d8858c9c88d2d11fed53998512504cd9df49b",
+ "sha256:c2d35a1d047efd68027817b32ab1586c1169e60ca02c65d428ae815b593e65d4",
+ "sha256:c38d7b9a690b090de999835f0443d8aa93ce5f2064035dfc48f27f02b4afc3d0",
+ "sha256:c6f2c8372b98208ce609c9e1d707f6918cc118fea4e2c754c9f0812c04ca116d",
+ "sha256:c817d420c60a5183953c783b0547d9eb43b7b344a2c46f69513d5952a78cddf3",
+ "sha256:c8ba129e6d3b0136a0f50345b2cb3db53f6bda5dd8c7f5d83fbccba97fb5dcb5",
+ "sha256:c94e75445b00319c1fad60f3c98b09cd63fe1134a8a953dcd48989ef42318534",
+ "sha256:cc4691d60512798304acb9207987e7b2b7c44627ea88b9d77489bbe3e6cc3bd4",
+ "sha256:cc518cea79fd1e2f6c90baafa28906d4309d24f3a63e801d855e7424c5b34144",
+ "sha256:cd53553ddad4a9c2f1f022756ae64abe16da1feb497edf4d9f87f99ec7cf86bd",
+ "sha256:cf22b41fdae514ee2f1691b6c3cdeae666d8b7fa9434de445f12bbeee0cf48dd",
+ "sha256:d38c8f50ecf57f0463399569aa388b232cf1a2ffb8f0a9a5412d0db57e054860",
+ "sha256:d3be9b2076112e51b323bdf6d5a7f8a798de55fb8d95fcb64bd179460cdc0704",
+ "sha256:d4f2cc7060dc3646632d7f15fe68e2fa98f58e35dd5666cd525f3b35d3fed7f8",
+ "sha256:d7520db34088c96cc0e0a3ad51a4fd5b401f279ee112aa2b7f8f976d8582606d",
+ "sha256:d793bebb202a6000390a5390078e945bbb49855c29c7e4d56a85901326c3b5d9",
+ "sha256:da052e7962ea2d5e5ef5bc0355d55007407087392cf465b7ad84ce5f3e25fe0f",
+ "sha256:dae0ed02f6b075426accbf6b2863c3d0a7eacc1b41fb40f2251d931e50188dad",
+ "sha256:ddc678fb4c7e30cf830a2b5a8d869538bc55b28d6c68544d09c7d0d8f17694dc",
+ "sha256:df2e6f546c4df14bc81f9498bbc007fbb87669f1bb707c6138878c46b06f6510",
+ "sha256:e02c5175f63effbd7c5e590399c118d5db6183bbfe8e0d118bdb5c2d1b48d937",
+ "sha256:e196a4ff48310ba62e53a8e0f97ca2bca83cdd2fe2934d8b5cb0df0a841b193a",
+ "sha256:e233db59c8f76630c512ab4a4daf5a5986da5c3d5b44b8e9fc742f2a24dbd460",
+ "sha256:e32be23d538753a8adb6c85bd539f5fd3b15cb987404327c569dfc5fd8366e85",
+ "sha256:e3d30321949861404323c50aebeb1943461a67cd51d4200ab02babc58bd06a86",
+ "sha256:e89580a581bf478d8dcb97d9cd011d567768e8bc4095f8557b21c4d4c5fea7d0",
+ "sha256:e998e304036198b4f6914e6a1e2b6f925208a20e2042563d9734881150c6c246",
+ "sha256:ec42088248c596dbd61d4ae8a5b004f97a4d91a9fd286f632e42e60b706718d7",
+ "sha256:efa7b51824aa0ee957ccd5a741c73e6851de55f40d807f08069eb4c5a26b2baa",
+ "sha256:f0a1bc63a465b6d72569a9bba9f2ef0334c4e03958e043da1920299100bc7c08",
+ "sha256:f18a5a84e16886898e51ab4b1d43acb3083c39b14c8caeb3589aabff0ee0b270",
+ "sha256:f2a9efc53d5b714b8df2b4b3e992accf8ce5bbdfe544d74d5c6766c9e1146a3a",
+ "sha256:f3bbbc998d42f8e561f347e798b85513ba4da324c2b3f9b7969e9c45b10f6169",
+ "sha256:f42038016852ae51b4088b2862126535cc4fc85802bfe30dea3500fdfaf1864e",
+ "sha256:f443cdef978430887ed55112b491f670bba6462cea7a7742ff8f14b7abb98d75",
+ "sha256:f51969bac61441fd31f028d7b3b45962f3ecebf691a510495e5d2cd8c8092dbd",
+ "sha256:f8aca2e3a72f37bfc7b14ba96d4056244001ddcc18382bd0daa087fd2e68a354",
+ "sha256:f9737bf36262046213a28e789cc82d82c6ef19c85a0cf05e75c670a33342ac2c",
+ "sha256:fd6037392f2d57793ab98d9e26798f44b8b4da2f2464388588f48ac52c489ea1",
+ "sha256:feaa45c0eae424d3e90d78823f3828e7dc42a42f21ed420db98da2c4ecf0a2cb",
+ "sha256:ff097ae562e637409b429a7ac958a20aab237a0378c42dabaa1e3abf2f896e5f",
+ "sha256:ff46d772d5f6f73564979cd77a4fffe55c916a05f3cb70e7c9c0590059fb29ef"
],
"markers": "python_version >= '3.6'",
- "version": "==5.3.0"
+ "version": "==5.2.1"
},
"mako": {
"hashes": [
- "sha256:260f1dbc3a519453a9c856dedfe4beb4e50bd5a26d96386cb6c80856556bb91a",
- "sha256:48dbc20568c1d276a2698b36d968fa76161bf127194907ea6fc594fa81f943bc"
+ "sha256:5324b88089a8978bf76d1629774fcc2f1c07b82acdf00f4c5dd8ceadfffc4b40",
+ "sha256:e16c01d9ab9c11f7290eef1cfefc093fb5a45ee4a3da09e2fec2e4d1bae54e73"
],
"markers": "python_version >= '3.8'",
- "version": "==1.3.5"
+ "version": "==1.3.3"
+ },
+ "markuppy": {
+ "hashes": [
+ "sha256:1adee2c0a542af378fe84548ff6f6b0168f3cb7f426b46961038a2bcfaad0d5f"
+ ],
+ "version": "==1.14"
},
"markupsafe": {
"hashes": [
@@ -812,11 +832,18 @@
},
"marshmallow": {
"hashes": [
- "sha256:4972f529104a220bb8637d595aa4c9762afbe7f7a77d82dc58c1615d70c5823e",
- "sha256:71a2dce49ef901c3f97ed296ae5051135fd3febd2bf43afe0ae9a82143a494d9"
+ "sha256:4e65e9e0d80fc9e609574b9983cf32579f305c718afb30d7233ab818571768c3",
+ "sha256:f085493f79efb0644f270a9bf2892843142d80d7174bbbd2f3713f2a589dc633"
],
"markers": "python_version >= '3.8'",
- "version": "==3.22.0"
+ "version": "==3.21.1"
+ },
+ "odfpy": {
+ "hashes": [
+ "sha256:db766a6e59c5103212f3cc92ec8dd50a0f3a02790233ed0b52148b70d3c438ec",
+ "sha256:fc3b8d1bc098eba4a0fda865a76d9d1e577c4ceec771426bcb169a82c5e9dfe0"
+ ],
+ "version": "==1.4.1"
},
"oic": {
"hashes": [
@@ -827,6 +854,13 @@
"markers": "python_version ~= '3.8'",
"version": "==1.7.0"
},
+ "openpyxl": {
+ "hashes": [
+ "sha256:a6f5977418eff3b2d5500d54d9db50c8277a368436f4e4f8ddb1be3422870184",
+ "sha256:f91456ead12ab3c6c2e9491cf33ba6d08357d802192379bb482f1033ade496f5"
+ ],
+ "version": "==3.1.2"
+ },
"orderedmultidict": {
"hashes": [
"sha256:04070bbb5e87291cc9bfa51df413677faf2141c73c61d2a5f7b26bea3cd882ad",
@@ -836,18 +870,18 @@
},
"packaging": {
"hashes": [
- "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002",
- "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"
+ "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5",
+ "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"
],
- "markers": "python_version >= '3.8'",
- "version": "==24.1"
+ "markers": "python_version >= '3.7'",
+ "version": "==24.0"
},
"phonenumberslite": {
"hashes": [
- "sha256:63d650f2fe464602c8b01b7e0cda6b7057811a2410cbd1d21d90374642abdc51",
- "sha256:ab6aa6e5fa115c89ea63e3c316c764ff449f8ecb826499cfc925f6a39f29e174"
+ "sha256:343b300d9c8ac4dca84e6b922ec51c3d838f2feabf9dd2418da64b639d220879",
+ "sha256:64b513134b785fbeeaf4cc020e18d384541c4118ed3ece2118437d996f435ca0"
],
- "version": "==8.13.44"
+ "version": "==8.13.35"
},
"psycopg2-binary": {
"hashes": [
@@ -977,114 +1011,104 @@
},
"pydantic": {
"hashes": [
- "sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a",
- "sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8"
+ "sha256:e029badca45266732a9a79898a15ae2e8b14840b1eabbb25844be28f0b33f3d5",
+ "sha256:e9dbb5eada8abe4d9ae5f46b9939aead650cd2b68f249bb3a8139dbe125803cc"
],
"markers": "python_version >= '3.8'",
- "version": "==2.8.2"
+ "version": "==2.7.1"
},
"pydantic-core": {
"hashes": [
- "sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d",
- "sha256:04024d270cf63f586ad41fff13fde4311c4fc13ea74676962c876d9577bcc78f",
- "sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686",
- "sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482",
- "sha256:10d4204d8ca33146e761c79f83cc861df20e7ae9f6487ca290a97702daf56006",
- "sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83",
- "sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6",
- "sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88",
- "sha256:177f55a886d74f1808763976ac4efd29b7ed15c69f4d838bbd74d9d09cf6fa86",
- "sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a",
- "sha256:1eedfeb6089ed3fad42e81a67755846ad4dcc14d73698c120a82e4ccf0f1f9f6",
- "sha256:225b67a1f6d602de0ce7f6c1c3ae89a4aa25d3de9be857999e9124f15dab486a",
- "sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6",
- "sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6",
- "sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43",
- "sha256:26ab812fa0c845df815e506be30337e2df27e88399b985d0bb4e3ecfe72df31c",
- "sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4",
- "sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e",
- "sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203",
- "sha256:2aafc5a503855ea5885559eae883978c9b6d8c8993d67766ee73d82e841300dd",
- "sha256:2d036c7187b9422ae5b262badb87a20a49eb6c5238b2004e96d4da1231badef1",
- "sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24",
- "sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc",
- "sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc",
- "sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3",
- "sha256:3c5ebac750d9d5f2706654c638c041635c385596caf68f81342011ddfa1e5598",
- "sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98",
- "sha256:407653af5617f0757261ae249d3fba09504d7a71ab36ac057c938572d1bc9331",
- "sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2",
- "sha256:41e81317dd6a0127cabce83c0c9c3fbecceae981c8391e6f1dec88a77c8a569a",
- "sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6",
- "sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688",
- "sha256:4745f4ac52cc6686390c40eaa01d48b18997cb130833154801a442323cc78f91",
- "sha256:4868f6bd7c9d98904b748a2653031fc9c2f85b6237009d475b1008bfaeb0a5aa",
- "sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b",
- "sha256:4dd484681c15e6b9a977c785a345d3e378d72678fd5f1f3c0509608da24f2ac0",
- "sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840",
- "sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c",
- "sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd",
- "sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3",
- "sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231",
- "sha256:5b5ff4911aea936a47d9376fd3ab17e970cc543d1b68921886e7f64bd28308d1",
- "sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953",
- "sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250",
- "sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a",
- "sha256:635fee4e041ab9c479e31edda27fcf966ea9614fff1317e280d99eb3e5ab6fe2",
- "sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20",
- "sha256:6b507132dcfc0dea440cce23ee2182c0ce7aba7054576efc65634f080dbe9434",
- "sha256:6b9d9bb600328a1ce523ab4f454859e9d439150abb0906c5a1983c146580ebab",
- "sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703",
- "sha256:77bf3ac639c1ff567ae3b47f8d4cc3dc20f9966a2a6dd2311dcc055d3d04fb8a",
- "sha256:784c1214cb6dd1e3b15dd8b91b9a53852aed16671cc3fbe4786f4f1db07089e2",
- "sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac",
- "sha256:7ed1b0132f24beeec5a78b67d9388656d03e6a7c837394f99257e2d55b461611",
- "sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121",
- "sha256:964faa8a861d2664f0c7ab0c181af0bea66098b1919439815ca8803ef136fc4e",
- "sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b",
- "sha256:9ebfef07dbe1d93efb94b4700f2d278494e9162565a54f124c404a5656d7ff09",
- "sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906",
- "sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9",
- "sha256:a6d511cc297ff0883bc3708b465ff82d7560193169a8b93260f74ecb0a5e08a7",
- "sha256:a8ad4c766d3f33ba8fd692f9aa297c9058970530a32c728a2c4bfd2616d3358b",
- "sha256:aa2f457b4af386254372dfa78a2eda2563680d982422641a85f271c859df1987",
- "sha256:b03f7941783b4c4a26051846dea594628b38f6940a2fdc0df00b221aed39314c",
- "sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b",
- "sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e",
- "sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237",
- "sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1",
- "sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19",
- "sha256:c6514f963b023aeee506678a1cf821fe31159b925c4b76fe2afa94cc70b3222b",
- "sha256:c693e916709c2465b02ca0ad7b387c4f8423d1db7b4649c551f27a529181c5ad",
- "sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0",
- "sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94",
- "sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312",
- "sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f",
- "sha256:d2fe69c5434391727efa54b47a1e7986bb0186e72a41b203df8f5b0a19a4f669",
- "sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1",
- "sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe",
- "sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99",
- "sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a",
- "sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a",
- "sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52",
- "sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c",
- "sha256:eaad4ff2de1c3823fddf82f41121bdf453d922e9a238642b1dedb33c4e4f98ad",
- "sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1",
- "sha256:f6d6cff3538391e8486a431569b77921adfcdef14eb18fbf19b7c0a5294d4e6a",
- "sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f",
- "sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a",
- "sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27"
+ "sha256:0098300eebb1c837271d3d1a2cd2911e7c11b396eac9661655ee524a7f10587b",
+ "sha256:042473b6280246b1dbf530559246f6842b56119c2926d1e52b631bdc46075f2a",
+ "sha256:05b7133a6e6aeb8df37d6f413f7705a37ab4031597f64ab56384c94d98fa0e90",
+ "sha256:0680b1f1f11fda801397de52c36ce38ef1c1dc841a0927a94f226dea29c3ae3d",
+ "sha256:0d69b4c2f6bb3e130dba60d34c0845ba31b69babdd3f78f7c0c8fae5021a253e",
+ "sha256:1404c69d6a676245199767ba4f633cce5f4ad4181f9d0ccb0577e1f66cf4c46d",
+ "sha256:182245ff6b0039e82b6bb585ed55a64d7c81c560715d1bad0cbad6dfa07b4027",
+ "sha256:1a388a77e629b9ec814c1b1e6b3b595fe521d2cdc625fcca26fbc2d44c816804",
+ "sha256:1d90c3265ae107f91a4f279f4d6f6f1d4907ac76c6868b27dc7fb33688cfb347",
+ "sha256:20aca1e2298c56ececfd8ed159ae4dde2df0781988c97ef77d5c16ff4bd5b400",
+ "sha256:219da3f096d50a157f33645a1cf31c0ad1fe829a92181dd1311022f986e5fbe3",
+ "sha256:22057013c8c1e272eb8d0eebc796701167d8377441ec894a8fed1af64a0bf399",
+ "sha256:223ee893d77a310a0391dca6df00f70bbc2f36a71a895cecd9a0e762dc37b349",
+ "sha256:224c421235f6102e8737032483f43c1a8cfb1d2f45740c44166219599358c2cd",
+ "sha256:2334ce8c673ee93a1d6a65bd90327588387ba073c17e61bf19b4fd97d688d63c",
+ "sha256:269322dcc3d8bdb69f054681edff86276b2ff972447863cf34c8b860f5188e2e",
+ "sha256:2728b01246a3bba6de144f9e3115b532ee44bd6cf39795194fb75491824a1413",
+ "sha256:2b8ed04b3582771764538f7ee7001b02e1170223cf9b75dff0bc698fadb00cf3",
+ "sha256:2e29d20810dfc3043ee13ac7d9e25105799817683348823f305ab3f349b9386e",
+ "sha256:36789b70d613fbac0a25bb07ab3d9dba4d2e38af609c020cf4d888d165ee0bf3",
+ "sha256:390193c770399861d8df9670fb0d1874f330c79caaca4642332df7c682bf6b91",
+ "sha256:3a6515ebc6e69d85502b4951d89131ca4e036078ea35533bb76327f8424531ce",
+ "sha256:3f9a801e7c8f1ef8718da265bba008fa121243dfe37c1cea17840b0944dfd72c",
+ "sha256:43f0f463cf89ace478de71a318b1b4f05ebc456a9b9300d027b4b57c1a2064fb",
+ "sha256:4456f2dca97c425231d7315737d45239b2b51a50dc2b6f0c2bb181fce6207664",
+ "sha256:470b94480bb5ee929f5acba6995251ada5e059a5ef3e0dfc63cca287283ebfa6",
+ "sha256:4774f3184d2ef3e14e8693194f661dea5a4d6ca4e3dc8e39786d33a94865cefd",
+ "sha256:4b4356d3538c3649337df4074e81b85f0616b79731fe22dd11b99499b2ebbdf3",
+ "sha256:553ef617b6836fc7e4df130bb851e32fe357ce36336d897fd6646d6058d980af",
+ "sha256:6132dd3bd52838acddca05a72aafb6eab6536aa145e923bb50f45e78b7251043",
+ "sha256:6a46e22a707e7ad4484ac9ee9f290f9d501df45954184e23fc29408dfad61350",
+ "sha256:6e5c584d357c4e2baf0ff7baf44f4994be121e16a2c88918a5817331fc7599d7",
+ "sha256:75250dbc5290e3f1a0f4618db35e51a165186f9034eff158f3d490b3fed9f8a0",
+ "sha256:75f7e9488238e920ab6204399ded280dc4c307d034f3924cd7f90a38b1829563",
+ "sha256:78363590ef93d5d226ba21a90a03ea89a20738ee5b7da83d771d283fd8a56761",
+ "sha256:7ca4ae5a27ad7a4ee5170aebce1574b375de390bc01284f87b18d43a3984df72",
+ "sha256:800d60565aec896f25bc3cfa56d2277d52d5182af08162f7954f938c06dc4ee3",
+ "sha256:82d5d4d78e4448683cb467897fe24e2b74bb7b973a541ea1dcfec1d3cbce39fb",
+ "sha256:852e966fbd035a6468fc0a3496589b45e2208ec7ca95c26470a54daed82a0788",
+ "sha256:868649da93e5a3d5eacc2b5b3b9235c98ccdbfd443832f31e075f54419e1b96b",
+ "sha256:886eec03591b7cf058467a70a87733b35f44707bd86cf64a615584fd72488b7c",
+ "sha256:8b172601454f2d7701121bbec3425dd71efcb787a027edf49724c9cefc14c038",
+ "sha256:95b9d5e72481d3780ba3442eac863eae92ae43a5f3adb5b4d0a1de89d42bb250",
+ "sha256:98758d627ff397e752bc339272c14c98199c613f922d4a384ddc07526c86a2ec",
+ "sha256:997abc4df705d1295a42f95b4eec4950a37ad8ae46d913caeee117b6b198811c",
+ "sha256:9b5155ff768083cb1d62f3e143b49a8a3432e6789a3abee8acd005c3c7af1c74",
+ "sha256:9e08e867b306f525802df7cd16c44ff5ebbe747ff0ca6cf3fde7f36c05a59a81",
+ "sha256:9fdad8e35f278b2c3eb77cbdc5c0a49dada440657bf738d6905ce106dc1de439",
+ "sha256:a1874c6dd4113308bd0eb568418e6114b252afe44319ead2b4081e9b9521fe75",
+ "sha256:a8309f67285bdfe65c372ea3722b7a5642680f3dba538566340a9d36e920b5f0",
+ "sha256:ae0a8a797a5e56c053610fa7be147993fe50960fa43609ff2a9552b0e07013e8",
+ "sha256:b14d82cdb934e99dda6d9d60dc84a24379820176cc4a0d123f88df319ae9c150",
+ "sha256:b1bd7e47b1558ea872bd16c8502c414f9e90dcf12f1395129d7bb42a09a95438",
+ "sha256:b3ef08e20ec49e02d5c6717a91bb5af9b20f1805583cb0adfe9ba2c6b505b5ae",
+ "sha256:b89ed9eb7d616ef5714e5590e6cf7f23b02d0d539767d33561e3675d6f9e3857",
+ "sha256:c4fcf5cd9c4b655ad666ca332b9a081112cd7a58a8b5a6ca7a3104bc950f2038",
+ "sha256:c6fdc8627910eed0c01aed6a390a252fe3ea6d472ee70fdde56273f198938374",
+ "sha256:c9bd70772c720142be1020eac55f8143a34ec9f82d75a8e7a07852023e46617f",
+ "sha256:ca7b0c1f1c983e064caa85f3792dd2fe3526b3505378874afa84baf662e12241",
+ "sha256:cbca948f2d14b09d20268cda7b0367723d79063f26c4ffc523af9042cad95592",
+ "sha256:cc1cfd88a64e012b74e94cd00bbe0f9c6df57049c97f02bb07d39e9c852e19a4",
+ "sha256:ccdd111c03bfd3666bd2472b674c6899550e09e9f298954cfc896ab92b5b0e6d",
+ "sha256:cfeecd1ac6cc1fb2692c3d5110781c965aabd4ec5d32799773ca7b1456ac636b",
+ "sha256:d4d938ec0adf5167cb335acb25a4ee69a8107e4984f8fbd2e897021d9e4ca21b",
+ "sha256:d7d904828195733c183d20a54230c0df0eb46ec746ea1a666730787353e87182",
+ "sha256:d91cb5ea8b11607cc757675051f61b3d93f15eca3cefb3e6c704a5d6e8440f4e",
+ "sha256:d9319e499827271b09b4e411905b24a426b8fb69464dfa1696258f53a3334641",
+ "sha256:e0e8b1be28239fc64a88a8189d1df7fad8be8c1ae47fcc33e43d4be15f99cc70",
+ "sha256:e18609ceaa6eed63753037fc06ebb16041d17d28199ae5aba0052c51449650a9",
+ "sha256:e1b395e58b10b73b07b7cf740d728dd4ff9365ac46c18751bf8b3d8cca8f625a",
+ "sha256:e23ec367a948b6d812301afc1b13f8094ab7b2c280af66ef450efc357d2ae543",
+ "sha256:e25add29b8f3b233ae90ccef2d902d0ae0432eb0d45370fe315d1a5cf231004b",
+ "sha256:e6dac87ddb34aaec85f873d737e9d06a3555a1cc1a8e0c44b7f8d5daeb89d86f",
+ "sha256:ef26c9e94a8c04a1b2924149a9cb081836913818e55681722d7f29af88fe7b38",
+ "sha256:eff2de745698eb46eeb51193a9f41d67d834d50e424aef27df2fcdee1b153845",
+ "sha256:f0a21cbaa69900cbe1a2e7cad2aa74ac3cf21b10c3efb0fa0b80305274c0e8a2",
+ "sha256:f459a5ce8434614dfd39bbebf1041952ae01da6bed9855008cb33b875cb024c0",
+ "sha256:f93a8a2e3938ff656a7c1bc57193b1319960ac015b6e87d76c76bf14fe0244b4",
+ "sha256:fb2bd7be70c0fe4dfd32c951bc813d9fe6ebcbfdd15a07527796c8204bd36242"
],
"markers": "python_version >= '3.8'",
- "version": "==2.20.1"
+ "version": "==2.18.2"
},
"pydantic-settings": {
"hashes": [
- "sha256:bb6849dc067f1687574c12a639e231f3a6feeed0a12d710c1382045c5db1c315",
- "sha256:ed81c3a0f46392b4d7c0a565c05884e6e54b3456e6f0fe4d8814981172dc9a88"
+ "sha256:00b9f6a5e95553590434c0fa01ead0b216c3e10bc54ae02e37f359948643c5ed",
+ "sha256:0235391d26db4d2190cb9b31051c4b46882d28a51533f97440867f012d4da091"
],
"markers": "python_version >= '3.8'",
- "version": "==2.4.0"
+ "version": "==2.2.1"
},
"pyjwkest": {
"hashes": [
@@ -1109,6 +1133,62 @@
"markers": "python_version >= '3.8'",
"version": "==1.0.1"
},
+ "pyyaml": {
+ "hashes": [
+ "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5",
+ "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc",
+ "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df",
+ "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741",
+ "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206",
+ "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27",
+ "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595",
+ "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62",
+ "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98",
+ "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696",
+ "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290",
+ "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9",
+ "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d",
+ "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6",
+ "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867",
+ "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47",
+ "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486",
+ "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6",
+ "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3",
+ "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007",
+ "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938",
+ "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0",
+ "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c",
+ "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735",
+ "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d",
+ "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28",
+ "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4",
+ "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba",
+ "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8",
+ "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef",
+ "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5",
+ "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd",
+ "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3",
+ "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0",
+ "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515",
+ "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c",
+ "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c",
+ "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924",
+ "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34",
+ "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43",
+ "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859",
+ "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673",
+ "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54",
+ "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a",
+ "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b",
+ "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab",
+ "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa",
+ "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c",
+ "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585",
+ "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d",
+ "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"
+ ],
+ "version": "==6.0.1"
+ },
"pyzipper": {
"hashes": [
"sha256:0adca90a00c36a93fbe49bfa8c5add452bfe4ef85a1b8e3638739dd1c7b26bfc",
@@ -1120,28 +1200,28 @@
},
"requests": {
"hashes": [
- "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760",
- "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"
+ "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f",
+ "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"
],
"index": "pypi",
- "markers": "python_version >= '3.8'",
- "version": "==2.32.3"
+ "markers": "python_version >= '3.7'",
+ "version": "==2.31.0"
},
"s3transfer": {
"hashes": [
- "sha256:0711534e9356d3cc692fdde846b4a1e4b0cb6519971860796e6bc4c7aea00ef6",
- "sha256:eca1c20de70a39daee580aef4986996620f365c4e0fda6a86100231d62f1bf69"
+ "sha256:5683916b4c724f799e600f41dd9e10a9ff19871bf87623cc8f491cb4f5fa0a19",
+ "sha256:ceb252b11bcf87080fb7850a224fb6e05c8a776bab8f2b64b7f25b969464839d"
],
"markers": "python_version >= '3.8'",
- "version": "==0.10.2"
+ "version": "==0.10.1"
},
"setuptools": {
"hashes": [
- "sha256:0274581a0037b638b9fc1c6883cc71c0210865aaa76073f7882376b641b84e8f",
- "sha256:a85e96b8be2b906f3e3e789adec6a9323abf79758ecfa3065bd740d81158b11e"
+ "sha256:6c1fccdac05a97e598fb0ae3bbed5904ccb317337a51139dcd51453611bbb987",
+ "sha256:c636ac361bc47580504644275c9ad802c50415c7522212252c033bd15f301f32"
],
"markers": "python_version >= '3.8'",
- "version": "==74.0.0"
+ "version": "==69.5.1"
},
"six": {
"hashes": [
@@ -1153,11 +1233,11 @@
},
"sqlparse": {
"hashes": [
- "sha256:773dcbf9a5ab44a090f3441e2180efe2560220203dc2f8c0b0fa141e18b505e4",
- "sha256:bb6b4df465655ef332548e24f08e205afc81b9ab86cb1c45657a7ff173a3a00e"
+ "sha256:714d0a4932c059d16189f58ef5411ec2287a4360f17cdd0edd2d09d4c5087c93",
+ "sha256:c204494cd97479d0e39f28c93d46c0b2d5959c7b9ab904762ea6c7af211c8663"
],
"markers": "python_version >= '3.8'",
- "version": "==0.5.1"
+ "version": "==0.5.0"
},
"tablib": {
"extras": [
@@ -1185,29 +1265,43 @@
},
"typing-extensions": {
"hashes": [
- "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d",
- "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"
+ "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0",
+ "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==4.12.2"
+ "version": "==4.11.0"
},
"urllib3": {
"hashes": [
- "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472",
- "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"
+ "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d",
+ "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"
],
"markers": "python_version >= '3.8'",
- "version": "==2.2.2"
+ "version": "==2.2.1"
},
"whitenoise": {
"hashes": [
- "sha256:58c7a6cd811e275a6c91af22e96e87da0b1109e9a53bb7464116ef4c963bf636",
- "sha256:a1ae85e01fdc9815d12fa33f17765bc132ed2c54fa76daf9e39e879dd93566f6"
+ "sha256:8998f7370973447fac1e8ef6e8ded2c5209a7b1f67c1012866dbcd09681c3251",
+ "sha256:b1f9db9bf67dc183484d760b99f4080185633136a273a03f6436034a41064146"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==6.7.0"
+ "version": "==6.6.0"
+ },
+ "xlrd": {
+ "hashes": [
+ "sha256:6a33ee89877bd9abc1158129f6e94be74e2679636b8a205b43b85206c3f0bbdd",
+ "sha256:f72f148f54442c6b056bf931dbc34f986fd0c3b0b6b5a58d013c9aef274d0c88"
+ ],
+ "version": "==2.0.1"
+ },
+ "xlwt": {
+ "hashes": [
+ "sha256:a082260524678ba48a297d922cc385f58278b8aa68741596a87de01a9c628b2e",
+ "sha256:c59912717a9b28f1a3c2a98fd60741014b06b043936dcecbc113eaaada156c88"
+ ],
+ "version": "==1.3.0"
},
"zope.event": {
"hashes": [
@@ -1219,43 +1313,45 @@
},
"zope.interface": {
"hashes": [
- "sha256:01e6e58078ad2799130c14a1d34ec89044ada0e1495329d72ee0407b9ae5100d",
- "sha256:064ade95cb54c840647205987c7b557f75d2b2f7d1a84bfab4cf81822ef6e7d1",
- "sha256:11fa1382c3efb34abf16becff8cb214b0b2e3144057c90611621f2d186b7e1b7",
- "sha256:1bee1b722077d08721005e8da493ef3adf0b7908e0cd85cc7dc836ac117d6f32",
- "sha256:1eeeb92cb7d95c45e726e3c1afe7707919370addae7ed14f614e22217a536958",
- "sha256:21a207c6b2c58def5011768140861a73f5240f4f39800625072ba84e76c9da0b",
- "sha256:2545d6d7aac425d528cd9bf0d9e55fcd47ab7fd15f41a64b1c4bf4c6b24946dc",
- "sha256:2c4316a30e216f51acbd9fb318aa5af2e362b716596d82cbb92f9101c8f8d2e7",
- "sha256:35062d93bc49bd9b191331c897a96155ffdad10744ab812485b6bad5b588d7e4",
- "sha256:382d31d1e68877061daaa6499468e9eb38eb7625d4369b1615ac08d3860fe896",
- "sha256:3aa8fcbb0d3c2be1bfd013a0f0acd636f6ed570c287743ae2bbd467ee967154d",
- "sha256:3d4b91821305c8d8f6e6207639abcbdaf186db682e521af7855d0bea3047c8ca",
- "sha256:3de1d553ce72868b77a7e9d598c9bff6d3816ad2b4cc81c04f9d8914603814f3",
- "sha256:3fcdc76d0cde1c09c37b7c6b0f8beba2d857d8417b055d4f47df9c34ec518bdd",
- "sha256:5112c530fa8aa2108a3196b9c2f078f5738c1c37cfc716970edc0df0414acda8",
- "sha256:53d678bb1c3b784edbfb0adeebfeea6bf479f54da082854406a8f295d36f8386",
- "sha256:6195c3c03fef9f87c0dbee0b3b6451df6e056322463cf35bca9a088e564a3c58",
- "sha256:6d04b11ea47c9c369d66340dbe51e9031df2a0de97d68f442305ed7625ad6493",
- "sha256:6dd647fcd765030638577fe6984284e0ebba1a1008244c8a38824be096e37fe3",
- "sha256:799ef7a444aebbad5a145c3b34bff012b54453cddbde3332d47ca07225792ea4",
- "sha256:7d92920416f31786bc1b2f34cc4fc4263a35a407425319572cbf96b51e835cd3",
- "sha256:7e0c151a6c204f3830237c59ee4770cc346868a7a1af6925e5e38650141a7f05",
- "sha256:84f8794bd59ca7d09d8fce43ae1b571be22f52748169d01a13d3ece8394d8b5b",
- "sha256:95e5913ec718010dc0e7c215d79a9683b4990e7026828eedfda5268e74e73e11",
- "sha256:9b9369671a20b8d039b8e5a1a33abd12e089e319a3383b4cc0bf5c67bd05fe7b",
- "sha256:ab985c566a99cc5f73bc2741d93f1ed24a2cc9da3890144d37b9582965aff996",
- "sha256:af94e429f9d57b36e71ef4e6865182090648aada0cb2d397ae2b3f7fc478493a",
- "sha256:c96b3e6b0d4f6ddfec4e947130ec30bd2c7b19db6aa633777e46c8eecf1d6afd",
- "sha256:cd2690d4b08ec9eaf47a85914fe513062b20da78d10d6d789a792c0b20307fb1",
- "sha256:d3b7ce6d46fb0e60897d62d1ff370790ce50a57d40a651db91a3dde74f73b738",
- "sha256:d976fa7b5faf5396eb18ce6c132c98e05504b52b60784e3401f4ef0b2e66709b",
- "sha256:db6237e8fa91ea4f34d7e2d16d74741187e9105a63bbb5686c61fea04cdbacca",
- "sha256:ecd32f30f40bfd8511b17666895831a51b532e93fc106bfa97f366589d3e4e0e",
- "sha256:f418c88f09c3ba159b95a9d1cfcdbe58f208443abb1f3109f4b9b12fd60b187c"
+ "sha256:014bb94fe6bf1786da1aa044eadf65bc6437bcb81c451592987e5be91e70a91e",
+ "sha256:01a0b3dd012f584afcf03ed814bce0fc40ed10e47396578621509ac031be98bf",
+ "sha256:10cde8dc6b2fd6a1d0b5ca4be820063e46ddba417ab82bcf55afe2227337b130",
+ "sha256:187f7900b63845dcdef1be320a523dbbdba94d89cae570edc2781eb55f8c2f86",
+ "sha256:1b0c4c90e5eefca2c3e045d9f9ed9f1e2cdbe70eb906bff6b247e17119ad89a1",
+ "sha256:22e8a218e8e2d87d4d9342aa973b7915297a08efbebea5b25900c73e78ed468e",
+ "sha256:26c9a37fb395a703e39b11b00b9e921c48f82b6e32cc5851ad5d0618cd8876b5",
+ "sha256:2bb78c12c1ad3a20c0d981a043d133299117b6854f2e14893b156979ed4e1d2c",
+ "sha256:2c3cfb272bcb83650e6695d49ae0d14dd06dc694789a3d929f23758557a23d92",
+ "sha256:2f32010ffb87759c6a3ad1c65ed4d2e38e51f6b430a1ca11cee901ec2b42e021",
+ "sha256:3c8731596198198746f7ce2a4487a0edcbc9ea5e5918f0ab23c4859bce56055c",
+ "sha256:40aa8c8e964d47d713b226c5baf5f13cdf3a3169c7a2653163b17ff2e2334d10",
+ "sha256:4137025731e824eee8d263b20682b28a0bdc0508de9c11d6c6be54163e5b7c83",
+ "sha256:46034be614d1f75f06e7dcfefba21d609b16b38c21fc912b01a99cb29e58febb",
+ "sha256:483e118b1e075f1819b3c6ace082b9d7d3a6a5eb14b2b375f1b80a0868117920",
+ "sha256:4d6b229f5e1a6375f206455cc0a63a8e502ed190fe7eb15e94a312dc69d40299",
+ "sha256:567d54c06306f9c5b6826190628d66753b9f2b0422f4c02d7c6d2b97ebf0a24e",
+ "sha256:5683aa8f2639016fd2b421df44301f10820e28a9b96382a6e438e5c6427253af",
+ "sha256:600101f43a7582d5b9504a7c629a1185a849ce65e60fca0f6968dfc4b76b6d39",
+ "sha256:62e32f02b3f26204d9c02c3539c802afc3eefb19d601a0987836ed126efb1f21",
+ "sha256:69dedb790530c7ca5345899a1b4cb837cc53ba669051ea51e8c18f82f9389061",
+ "sha256:72d5efecad16c619a97744a4f0b67ce1bcc88115aa82fcf1dc5be9bb403bcc0b",
+ "sha256:8d407e0fd8015f6d5dfad481309638e1968d70e6644e0753f229154667dd6cd5",
+ "sha256:a058e6cf8d68a5a19cb5449f42a404f0d6c2778b897e6ce8fadda9cea308b1b0",
+ "sha256:a1adc14a2a9d5e95f76df625a9b39f4709267a483962a572e3f3001ef90ea6e6",
+ "sha256:a56fe1261230093bfeedc1c1a6cd6f3ec568f9b07f031c9a09f46b201f793a85",
+ "sha256:ad4524289d8dbd6fb5aa17aedb18f5643e7d48358f42c007a5ee51a2afc2a7c5",
+ "sha256:afa0491a9f154cf8519a02026dc85a416192f4cb1efbbf32db4a173ba28b289a",
+ "sha256:bf34840e102d1d0b2d39b1465918d90b312b1119552cebb61a242c42079817b9",
+ "sha256:c40df4aea777be321b7e68facb901bc67317e94b65d9ab20fb96e0eb3c0b60a1",
+ "sha256:d0e7321557c702bd92dac3c66a2f22b963155fdb4600133b6b29597f62b71b12",
+ "sha256:d165d7774d558ea971cb867739fb334faf68fc4756a784e689e11efa3becd59e",
+ "sha256:e78a183a3c2f555c2ad6aaa1ab572d1c435ba42f1dc3a7e8c82982306a19b785",
+ "sha256:e8fa0fb05083a1a4216b4b881fdefa71c5d9a106e9b094cd4399af6b52873e91",
+ "sha256:f83d6b4b22262d9a826c3bd4b2fbfafe1d0000f085ef8e44cd1328eea274ae6a",
+ "sha256:f95bebd0afe86b2adc074df29edb6848fc4d474ff24075e2c263d698774e108d"
],
- "markers": "python_version >= '3.8'",
- "version": "==7.0.3"
+ "markers": "python_version >= '3.7'",
+ "version": "==6.3"
}
},
"develop": {
@@ -1269,12 +1365,12 @@
},
"bandit": {
"hashes": [
- "sha256:52077cb339000f337fb25f7e045995c4ad01511e716e5daac37014b9752de8ec",
- "sha256:7c395a436743018f7be0a4cbb0a4ea9b902b6d87264ddecf8cfdc73b4f78ff61"
+ "sha256:36de50f720856ab24a24dbaa5fee2c66050ed97c1477e0a1159deab1775eab6b",
+ "sha256:509f7af645bc0cd8fd4587abc1a038fc795636671ee8204d502b933aee44f381"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==1.7.9"
+ "version": "==1.7.8"
},
"beautifulsoup4": {
"hashes": [
@@ -1286,49 +1382,49 @@
},
"black": {
"hashes": [
- "sha256:09cdeb74d494ec023ded657f7092ba518e8cf78fa8386155e4a03fdcc44679e6",
- "sha256:1f13f7f386f86f8121d76599114bb8c17b69d962137fc70efe56137727c7047e",
- "sha256:2500945420b6784c38b9ee885af039f5e7471ef284ab03fa35ecdde4688cd83f",
- "sha256:2b59b250fdba5f9a9cd9d0ece6e6d993d91ce877d121d161e4698af3eb9c1018",
- "sha256:3c4285573d4897a7610054af5a890bde7c65cb466040c5f0c8b732812d7f0e5e",
- "sha256:505289f17ceda596658ae81b61ebbe2d9b25aa78067035184ed0a9d855d18afd",
- "sha256:62e8730977f0b77998029da7971fa896ceefa2c4c4933fcd593fa599ecbf97a4",
- "sha256:649f6d84ccbae73ab767e206772cc2d7a393a001070a4c814a546afd0d423aed",
- "sha256:6e55d30d44bed36593c3163b9bc63bf58b3b30e4611e4d88a0c3c239930ed5b2",
- "sha256:707a1ca89221bc8a1a64fb5e15ef39cd755633daa672a9db7498d1c19de66a42",
- "sha256:72901b4913cbac8972ad911dc4098d5753704d1f3c56e44ae8dce99eecb0e3af",
- "sha256:73bbf84ed136e45d451a260c6b73ed674652f90a2b3211d6a35e78054563a9bb",
- "sha256:7c046c1d1eeb7aea9335da62472481d3bbf3fd986e093cffd35f4385c94ae368",
- "sha256:81c6742da39f33b08e791da38410f32e27d632260e599df7245cccee2064afeb",
- "sha256:837fd281f1908d0076844bc2b801ad2d369c78c45cf800cad7b61686051041af",
- "sha256:972085c618ee94f402da1af548a4f218c754ea7e5dc70acb168bfaca4c2542ed",
- "sha256:9e84e33b37be070ba135176c123ae52a51f82306def9f7d063ee302ecab2cf47",
- "sha256:b19c9ad992c7883ad84c9b22aaa73562a16b819c1d8db7a1a1a49fb7ec13c7d2",
- "sha256:d6417535d99c37cee4091a2f24eb2b6d5ec42b144d50f1f2e436d9fe1916fe1a",
- "sha256:eab4dd44ce80dea27dc69db40dab62d4ca96112f87996bca68cd75639aeb2e4c",
- "sha256:f490dbd59680d809ca31efdae20e634f3fae27fba3ce0ba3208333b713bc3920",
- "sha256:fb6e2c0b86bbd43dee042e48059c9ad7830abd5c94b0bc518c0eeec57c3eddc1"
+ "sha256:257d724c2c9b1660f353b36c802ccece186a30accc7742c176d29c146df6e474",
+ "sha256:37aae07b029fa0174d39daf02748b379399b909652a806e5708199bd93899da1",
+ "sha256:415e686e87dbbe6f4cd5ef0fbf764af7b89f9057b97c908742b6008cc554b9c0",
+ "sha256:48a85f2cb5e6799a9ef05347b476cce6c182d6c71ee36925a6c194d074336ef8",
+ "sha256:7768a0dbf16a39aa5e9a3ded568bb545c8c2727396d063bbaf847df05b08cd96",
+ "sha256:7e122b1c4fb252fd85df3ca93578732b4749d9be076593076ef4d07a0233c3e1",
+ "sha256:88c57dc656038f1ab9f92b3eb5335ee9b021412feaa46330d5eba4e51fe49b04",
+ "sha256:8e537d281831ad0e71007dcdcbe50a71470b978c453fa41ce77186bbe0ed6021",
+ "sha256:98e123f1d5cfd42f886624d84464f7756f60ff6eab89ae845210631714f6db94",
+ "sha256:accf49e151c8ed2c0cdc528691838afd217c50412534e876a19270fea1e28e2d",
+ "sha256:b1530ae42e9d6d5b670a34db49a94115a64596bc77710b1d05e9801e62ca0a7c",
+ "sha256:b9176b9832e84308818a99a561e90aa479e73c523b3f77afd07913380ae2eab7",
+ "sha256:bdde6f877a18f24844e381d45e9947a49e97933573ac9d4345399be37621e26c",
+ "sha256:be8bef99eb46d5021bf053114442914baeb3649a89dc5f3a555c88737e5e98fc",
+ "sha256:bf10f7310db693bb62692609b397e8d67257c55f949abde4c67f9cc574492cc7",
+ "sha256:c872b53057f000085da66a19c55d68f6f8ddcac2642392ad3a355878406fbd4d",
+ "sha256:d36ed1124bb81b32f8614555b34cc4259c3fbc7eec17870e8ff8ded335b58d8c",
+ "sha256:da33a1a5e49c4122ccdfd56cd021ff1ebc4a1ec4e2d01594fef9b6f267a9e741",
+ "sha256:dd1b5a14e417189db4c7b64a6540f31730713d173f0b63e55fabd52d61d8fdce",
+ "sha256:e151054aa00bad1f4e1f04919542885f89f5f7d086b8a59e5000e6c616896ffb",
+ "sha256:eaea3008c281f1038edb473c1aa8ed8143a5535ff18f978a318f10302b254063",
+ "sha256:ef703f83fc32e131e9bcc0a5094cfe85599e7109f896fe8bc96cc402f3eb4b6e"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==24.8.0"
+ "version": "==24.4.2"
},
"blinker": {
"hashes": [
- "sha256:1779309f71bf239144b9399d06ae925637cf6634cf6bd131104184531bf67c01",
- "sha256:8f77b09d3bf7c795e969e9486f39c2c5e9c39d4ee07424be2bc594ece9642d83"
+ "sha256:5f1cdeff423b77c31b89de0565cd03e5275a03028f44b2b15f912632a58cced6",
+ "sha256:da44ec748222dcd0105ef975eed946da197d5bdf8bafb6aa92f5bc89da63fa25"
],
"markers": "python_version >= '3.8'",
- "version": "==1.8.2"
+ "version": "==1.8.1"
},
"boto3": {
"hashes": [
- "sha256:06eac4757de2a9c6020381205cb902f05964caad80b56e58c8931284a133b4cb",
- "sha256:b9587131372a808bf6f99c5ed8b11be55cd113261cc3b437a917b4acc6c30bfe"
+ "sha256:decf52f8d5d8a1b10c9ff2a0e96ee207ed79e33d2e53fdf0880a5cbef70785e0",
+ "sha256:e836b71d79671270fccac0a4d4c8ec239a6b82ea47c399b64675aa597d0ee63b"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==1.35.8"
+ "version": "==1.34.95"
},
"boto3-mocking": {
"hashes": [
@@ -1341,28 +1437,28 @@
},
"boto3-stubs": {
"hashes": [
- "sha256:cfe2c813d8a43b91cccd7d1d4230b781fe3572e2d13e42d5ba60d78b42638bc8",
- "sha256:e5767b1aabdbc5e84915e533f852605bbb07cfe1b86fe172ab27654a2f24b48d"
+ "sha256:412006b27ee707e9b51a084b02ac92b143af8a3b56727582afec2a76ce93c3b6",
+ "sha256:4fb5830626de42446c238ca72ca1a53e461281396007fb900edf50ceeb044a10"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==1.35.8"
+ "version": "==1.34.95"
},
"botocore": {
"hashes": [
- "sha256:4b820cf680ab5d778bd2fe4feeef1ff8a2b96d5c535d4638ab30f703ade282f8",
- "sha256:adf389eb8fd87775f193300e3431d1353f925807ad3a39958172cb644f0d60a1"
+ "sha256:6bd76a2eadb42b91fa3528392e981ad5b4dfdee3968fa5b904278acf6cbf15ff",
+ "sha256:ead5823e0dd6751ece5498cb979fd9abf190e691c8833bcac6876fd6ca261fa7"
],
"markers": "python_version >= '3.8'",
- "version": "==1.35.8"
+ "version": "==1.34.95"
},
"botocore-stubs": {
"hashes": [
- "sha256:a49f9db19259dc280fee73d74f3a171310f3916a12e679b6c4bf8f719cb37461",
- "sha256:dac2ebedcd8b0c98be89d6e708fa9ce6d5d12e1bc6b629e77ae8c0d289088c49"
+ "sha256:64d80a3467e3b19939e9c2750af33328b3087f8f524998dbdf7ed168227f507d",
+ "sha256:b0345f55babd8b901c53804fc5c326a4a0bd2e23e3b71f9ea5d9f7663466e6ba"
],
- "markers": "python_version >= '3.8'",
- "version": "==1.35.8"
+ "markers": "python_version >= '3.8' and python_version < '4.0'",
+ "version": "==1.34.94"
},
"click": {
"hashes": [
@@ -1383,36 +1479,36 @@
},
"django-debug-toolbar": {
"hashes": [
- "sha256:36e421cb908c2f0675e07f9f41e3d1d8618dc386392ec82d23bcfcd5d29c7044",
- "sha256:3beb671c9ec44ffb817fad2780667f172bd1c067dbcabad6268ce39a81335f45"
+ "sha256:0b0dddee5ea29b9cb678593bc0d7a6d76b21d7799cb68e091a2148341a80f3c4",
+ "sha256:e09b7dcb8417b743234dfc57c95a7c1d1d87a88844abd13b4c5387f807b31bf6"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==4.4.6"
+ "version": "==4.3.0"
},
"django-model2puml": {
"hashes": [
- "sha256:f7ef57efbf261e8e0f90043c2be379e9457b30603ccc01fe7a01c233d0dfa27c"
+ "sha256:6e773d742e556020a04d3216ce5dee5d3551da162e2d42a997f85b4ed1854771"
],
"index": "pypi",
- "version": "==0.5.1"
+ "version": "==0.4.1"
},
"django-stubs": {
"hashes": [
- "sha256:78e3764488fdfd2695f12502136548ec22f8d4b1780541a835042b8238d11514",
- "sha256:c2502f5ecbae50c68f9a86d52b5b2447d8648fd205036dad0ccb41e19a445927"
+ "sha256:084484cbe16a6d388e80ec687e46f529d67a232f3befaf55c936b3b476be289d",
+ "sha256:b8a792bee526d6cab31e197cb414ee7fa218abd931a50948c66a80b3a2548621"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==5.0.4"
+ "version": "==5.0.0"
},
"django-stubs-ext": {
"hashes": [
- "sha256:85da065224204774208be29c7d02b4482d5a69218a728465c2fbe41725fdc819",
- "sha256:910cbaff3d1e8e806a5c27d5ddd4088535aae8371ea921b7fd680fdfa5f14e30"
+ "sha256:5bacfbb498a206d5938454222b843d81da79ea8b6fcd1a59003f529e775bc115",
+ "sha256:8e1334fdf0c8bff87e25d593b33d4247487338aaed943037826244ff788b56a8"
],
"markers": "python_version >= '3.8'",
- "version": "==5.0.4"
+ "version": "==5.0.0"
},
"django-webtest": {
"hashes": [
@@ -1424,12 +1520,12 @@
},
"flake8": {
"hashes": [
- "sha256:049d058491e228e03e67b390f311bbf88fce2dbaa8fa673e7aea87b7198b8d38",
- "sha256:597477df7860daa5aa0fdd84bf5208a043ab96b8e96ab708770ae0364dd03213"
+ "sha256:33f96621059e65eec474169085dc92bf26e7b2d47366b70be2f67ab80dc25132",
+ "sha256:a6dfbb75e03252917f2473ea9653f7cd799c3064e54d4c8140044c5c065f53c3"
],
"index": "pypi",
"markers": "python_full_version >= '3.8.1'",
- "version": "==7.1.1"
+ "version": "==7.0.0"
},
"jmespath": {
"hashes": [
@@ -1465,37 +1561,37 @@
},
"mypy": {
"hashes": [
- "sha256:06d26c277962f3fb50e13044674aa10553981ae514288cb7d0a738f495550b36",
- "sha256:2ff93107f01968ed834f4256bc1fc4475e2fecf6c661260066a985b52741ddce",
- "sha256:36383a4fcbad95f2657642a07ba22ff797de26277158f1cc7bd234821468b1b6",
- "sha256:37c7fa6121c1cdfcaac97ce3d3b5588e847aa79b580c1e922bb5d5d2902df19b",
- "sha256:3a66169b92452f72117e2da3a576087025449018afc2d8e9bfe5ffab865709ca",
- "sha256:3f14cd3d386ac4d05c5a39a51b84387403dadbd936e17cb35882134d4f8f0d24",
- "sha256:41ea707d036a5307ac674ea172875f40c9d55c5394f888b168033177fce47383",
- "sha256:478db5f5036817fe45adb7332d927daa62417159d49783041338921dcf646fc7",
- "sha256:4a8a53bc3ffbd161b5b2a4fff2f0f1e23a33b0168f1c0778ec70e1a3d66deb86",
- "sha256:539c570477a96a4e6fb718b8d5c3e0c0eba1f485df13f86d2970c91f0673148d",
- "sha256:57555a7715c0a34421013144a33d280e73c08df70f3a18a552938587ce9274f4",
- "sha256:6e658bd2d20565ea86da7d91331b0eed6d2eee22dc031579e6297f3e12c758c8",
- "sha256:6e7184632d89d677973a14d00ae4d03214c8bc301ceefcdaf5c474866814c987",
- "sha256:75746e06d5fa1e91bfd5432448d00d34593b52e7e91a187d981d08d1f33d4385",
- "sha256:7f9993ad3e0ffdc95c2a14b66dee63729f021968bff8ad911867579c65d13a79",
- "sha256:801780c56d1cdb896eacd5619a83e427ce436d86a3bdf9112527f24a66618fef",
- "sha256:801ca29f43d5acce85f8e999b1e431fb479cb02d0e11deb7d2abb56bdaf24fd6",
- "sha256:969ea3ef09617aff826885a22ece0ddef69d95852cdad2f60c8bb06bf1f71f70",
- "sha256:a976775ab2256aadc6add633d44f100a2517d2388906ec4f13231fafbb0eccca",
- "sha256:af8d155170fcf87a2afb55b35dc1a0ac21df4431e7d96717621962e4b9192e70",
- "sha256:b499bc07dbdcd3de92b0a8b29fdf592c111276f6a12fe29c30f6c417dd546d12",
- "sha256:cd953f221ac1379050a8a646585a29574488974f79d8082cedef62744f0a0104",
- "sha256:d42a6dd818ffce7be66cce644f1dff482f1d97c53ca70908dff0b9ddc120b77a",
- "sha256:e8960dbbbf36906c5c0b7f4fbf2f0c7ffb20f4898e6a879fcf56a41a08b0d318",
- "sha256:edb91dded4df17eae4537668b23f0ff6baf3707683734b6a818d5b9d0c0c31a1",
- "sha256:ee23de8530d99b6db0573c4ef4bd8f39a2a6f9b60655bf7a1357e585a3486f2b",
- "sha256:f7821776e5c4286b6a13138cc935e2e9b6fde05e081bdebf5cdb2bb97c9df81d"
+ "sha256:075cbf81f3e134eadaf247de187bd604748171d6b79736fa9b6c9685b4083061",
+ "sha256:12b6bfc1b1a66095ab413160a6e520e1dc076a28f3e22f7fb25ba3b000b4ef99",
+ "sha256:1ec404a7cbe9fc0e92cb0e67f55ce0c025014e26d33e54d9e506a0f2d07fe5de",
+ "sha256:28d0e038361b45f099cc086d9dd99c15ff14d0188f44ac883010e172ce86c38a",
+ "sha256:2b0695d605ddcd3eb2f736cd8b4e388288c21e7de85001e9f85df9187f2b50f9",
+ "sha256:3236a4c8f535a0631f85f5fcdffba71c7feeef76a6002fcba7c1a8e57c8be1ec",
+ "sha256:3be66771aa5c97602f382230165b856c231d1277c511c9a8dd058be4784472e1",
+ "sha256:3d087fcbec056c4ee34974da493a826ce316947485cef3901f511848e687c131",
+ "sha256:3f298531bca95ff615b6e9f2fc0333aae27fa48052903a0ac90215021cdcfa4f",
+ "sha256:4a2b5cdbb5dd35aa08ea9114436e0d79aceb2f38e32c21684dcf8e24e1e92821",
+ "sha256:4cf18f9d0efa1b16478c4c129eabec36148032575391095f73cae2e722fcf9d5",
+ "sha256:8b2cbaca148d0754a54d44121b5825ae71868c7592a53b7292eeb0f3fdae95ee",
+ "sha256:8f55583b12156c399dce2df7d16f8a5095291354f1e839c252ec6c0611e86e2e",
+ "sha256:92f93b21c0fe73dc00abf91022234c79d793318b8a96faac147cd579c1671746",
+ "sha256:9e36fb078cce9904c7989b9693e41cb9711e0600139ce3970c6ef814b6ebc2b2",
+ "sha256:9fd50226364cd2737351c79807775136b0abe084433b55b2e29181a4c3c878c0",
+ "sha256:a781f6ad4bab20eef8b65174a57e5203f4be627b46291f4589879bf4e257b97b",
+ "sha256:a87dbfa85971e8d59c9cc1fcf534efe664d8949e4c0b6b44e8ca548e746a8d53",
+ "sha256:b808e12113505b97d9023b0b5e0c0705a90571c6feefc6f215c1df9381256e30",
+ "sha256:bc6ac273b23c6b82da3bb25f4136c4fd42665f17f2cd850771cb600bdd2ebeda",
+ "sha256:cd777b780312ddb135bceb9bc8722a73ec95e042f911cc279e2ec3c667076051",
+ "sha256:da1cbf08fb3b851ab3b9523a884c232774008267b1f83371ace57f412fe308c2",
+ "sha256:e22e1527dc3d4aa94311d246b59e47f6455b8729f4968765ac1eacf9a4760bc7",
+ "sha256:f8c083976eb530019175aabadb60921e73b4f45736760826aa1689dda8208aee",
+ "sha256:f90cff89eea89273727d8783fef5d4a934be2fdca11b47def50cf5d311aff727",
+ "sha256:fa7ef5244615a2523b56c034becde4e9e3f9b034854c93639adb667ec9ec2976",
+ "sha256:fcfc70599efde5c67862a07a1aaf50e55bce629ace26bb19dc17cece5dd31ca4"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==1.11.2"
+ "version": "==1.10.0"
},
"mypy-extensions": {
"hashes": [
@@ -1515,11 +1611,11 @@
},
"packaging": {
"hashes": [
- "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002",
- "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"
+ "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5",
+ "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"
],
- "markers": "python_version >= '3.8'",
- "version": "==24.1"
+ "markers": "python_version >= '3.7'",
+ "version": "==24.0"
},
"pathspec": {
"hashes": [
@@ -1531,27 +1627,27 @@
},
"pbr": {
"hashes": [
- "sha256:788183e382e3d1d7707db08978239965e8b9e4e5ed42669bf4758186734d5f24",
- "sha256:a776ae228892d8013649c0aeccbb3d5f99ee15e005a4cbb7e61d55a067b28a2a"
+ "sha256:4a7317d5e3b17a3dccb6a8cfe67dab65b20551404c52c8ed41279fa4f0cb4cda",
+ "sha256:d1377122a5a00e2f940ee482999518efe16d745d423a670c27773dfbc3c9a7d9"
],
"markers": "python_version >= '2.6'",
- "version": "==6.1.0"
+ "version": "==6.0.0"
},
"platformdirs": {
"hashes": [
- "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee",
- "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"
+ "sha256:031cd18d4ec63ec53e82dceaac0417d218a6863f7745dfcc9efe7793b7039bdf",
+ "sha256:17d5a1161b3fd67b390023cb2d3b026bbd40abde6fdb052dfbd3a29c3ba22ee1"
],
"markers": "python_version >= '3.8'",
- "version": "==4.2.2"
+ "version": "==4.2.1"
},
"pycodestyle": {
"hashes": [
- "sha256:46f0fb92069a7c28ab7bb558f05bfc0110dac69a0cd23c61ea0040283a9d78b3",
- "sha256:6838eae08bbce4f6accd5d5572075c63626a15ee3e6f842df996bf62f6d73521"
+ "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f",
+ "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"
],
"markers": "python_version >= '3.8'",
- "version": "==2.12.1"
+ "version": "==2.11.1"
},
"pyflakes": {
"hashes": [
@@ -1563,11 +1659,11 @@
},
"pygments": {
"hashes": [
- "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199",
- "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"
+ "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c",
+ "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"
],
- "markers": "python_version >= '3.8'",
- "version": "==2.18.0"
+ "markers": "python_version >= '3.7'",
+ "version": "==2.17.2"
},
"python-dateutil": {
"hashes": [
@@ -1579,78 +1675,75 @@
},
"pyyaml": {
"hashes": [
- "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff",
- "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48",
- "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086",
- "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e",
- "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133",
- "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5",
- "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484",
- "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee",
- "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5",
- "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68",
- "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a",
- "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf",
- "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99",
- "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8",
- "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85",
- "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19",
- "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc",
- "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a",
- "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1",
- "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317",
- "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c",
- "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631",
- "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d",
- "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652",
- "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5",
- "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e",
- "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b",
- "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8",
- "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476",
- "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706",
- "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563",
- "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237",
- "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b",
- "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083",
- "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180",
- "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425",
- "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e",
- "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f",
- "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725",
- "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183",
- "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab",
- "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774",
- "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725",
- "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e",
- "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5",
- "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d",
- "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290",
- "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44",
- "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed",
- "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4",
- "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba",
- "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12",
- "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"
+ "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5",
+ "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc",
+ "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df",
+ "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741",
+ "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206",
+ "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27",
+ "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595",
+ "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62",
+ "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98",
+ "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696",
+ "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290",
+ "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9",
+ "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d",
+ "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6",
+ "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867",
+ "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47",
+ "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486",
+ "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6",
+ "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3",
+ "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007",
+ "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938",
+ "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0",
+ "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c",
+ "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735",
+ "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d",
+ "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28",
+ "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4",
+ "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba",
+ "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8",
+ "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef",
+ "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5",
+ "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd",
+ "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3",
+ "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0",
+ "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515",
+ "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c",
+ "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c",
+ "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924",
+ "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34",
+ "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43",
+ "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859",
+ "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673",
+ "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54",
+ "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a",
+ "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b",
+ "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab",
+ "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa",
+ "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c",
+ "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585",
+ "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d",
+ "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"
],
- "markers": "python_version >= '3.8'",
- "version": "==6.0.2"
+ "version": "==6.0.1"
},
"rich": {
"hashes": [
- "sha256:2e85306a063b9492dffc86278197a60cbece75bcb766022f3436f567cae11bdc",
- "sha256:a5ac1f1cd448ade0d59cc3356f7db7a7ccda2c8cbae9c7a90c28ff463d3e91f4"
+ "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222",
+ "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432"
],
"markers": "python_full_version >= '3.7.0'",
- "version": "==13.8.0"
+ "version": "==13.7.1"
},
"s3transfer": {
"hashes": [
- "sha256:0711534e9356d3cc692fdde846b4a1e4b0cb6519971860796e6bc4c7aea00ef6",
- "sha256:eca1c20de70a39daee580aef4986996620f365c4e0fda6a86100231d62f1bf69"
+ "sha256:5683916b4c724f799e600f41dd9e10a9ff19871bf87623cc8f491cb4f5fa0a19",
+ "sha256:ceb252b11bcf87080fb7850a224fb6e05c8a776bab8f2b64b7f25b969464839d"
],
"markers": "python_version >= '3.8'",
- "version": "==0.10.2"
+ "version": "==0.10.1"
},
"six": {
"hashes": [
@@ -1662,27 +1755,27 @@
},
"soupsieve": {
"hashes": [
- "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb",
- "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9"
+ "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690",
+ "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7"
],
"markers": "python_version >= '3.8'",
- "version": "==2.6"
+ "version": "==2.5"
},
"sqlparse": {
"hashes": [
- "sha256:773dcbf9a5ab44a090f3441e2180efe2560220203dc2f8c0b0fa141e18b505e4",
- "sha256:bb6b4df465655ef332548e24f08e205afc81b9ab86cb1c45657a7ff173a3a00e"
+ "sha256:714d0a4932c059d16189f58ef5411ec2287a4360f17cdd0edd2d09d4c5087c93",
+ "sha256:c204494cd97479d0e39f28c93d46c0b2d5959c7b9ab904762ea6c7af211c8663"
],
"markers": "python_version >= '3.8'",
- "version": "==0.5.1"
+ "version": "==0.5.0"
},
"stevedore": {
"hashes": [
- "sha256:1efd34ca08f474dad08d9b19e934a22c68bb6fe416926479ba29e5013bcc8f78",
- "sha256:9a64265f4060312828151c204efbe9b7a9852a0d9228756344dbc7e4023e375a"
+ "sha256:1c15d95766ca0569cad14cb6272d4d31dae66b011a929d7c18219c176ea1b5c9",
+ "sha256:46b93ca40e1114cea93d738a6c1e365396981bb6bb78c27045b7587c9473544d"
],
"markers": "python_version >= '3.8'",
- "version": "==5.3.0"
+ "version": "==5.2.0"
},
"tomli": {
"hashes": [
@@ -1694,62 +1787,62 @@
},
"types-awscrt": {
"hashes": [
- "sha256:0839fe12f0f914d8f7d63ed777c728cb4eccc2d5d79a26e377d12b0604e7bf0e",
- "sha256:84a9f4f422ec525c314fdf54c23a1e73edfbcec968560943ca2d41cfae623b38"
+ "sha256:3ae374b553e7228ba41a528cf42bd0b2ad7303d806c73eff4aaaac1515e3ea4e",
+ "sha256:64898a2f4a2468f66233cb8c29c5f66de907cf80ba1ef5bb1359aef2f81bb521"
],
"markers": "python_version >= '3.7' and python_version < '4.0'",
- "version": "==0.21.2"
+ "version": "==0.20.9"
},
"types-cachetools": {
"hashes": [
- "sha256:b888ab5c1a48116f7799cd5004b18474cd82b5463acb5ffb2db2fc9c7b053bc0",
- "sha256:efb2ed8bf27a4b9d3ed70d33849f536362603a90b8090a328acf0cd42fda82e2"
+ "sha256:27c982cdb9cf3fead8b0089ee6b895715ecc99dac90ec29e2cab56eb1aaf4199",
+ "sha256:98c069dc7fc087b1b061703369c80751b0a0fc561f6fb072b554e5eee23773a0"
],
"index": "pypi",
- "markers": "python_version >= '3.8'",
- "version": "==5.5.0.20240820"
+ "markers": "python_version >= '3.7'",
+ "version": "==5.3.0.7"
},
"types-pyyaml": {
"hashes": [
- "sha256:b8f76ddbd7f65440a8bda5526a9607e4c7a322dc2f8e1a8c405644f9a6f4b9af",
- "sha256:deda34c5c655265fc517b546c902aa6eed2ef8d3e921e4765fe606fe2afe8d35"
+ "sha256:a9e0f0f88dc835739b0c1ca51ee90d04ca2a897a71af79de9aec5f38cb0a5342",
+ "sha256:b845b06a1c7e54b8e5b4c683043de0d9caf205e7434b3edc678ff2411979b8f6"
],
"markers": "python_version >= '3.8'",
- "version": "==6.0.12.20240808"
+ "version": "==6.0.12.20240311"
},
"types-requests": {
"hashes": [
- "sha256:90c079ff05e549f6bf50e02e910210b98b8ff1ebdd18e19c873cd237737c1358",
- "sha256:f754283e152c752e46e70942fa2a146b5bc70393522257bb85bd1ef7e019dcc3"
+ "sha256:4428df33c5503945c74b3f42e82b181e86ec7b724620419a2966e2de604ce1a1",
+ "sha256:6216cdac377c6b9a040ac1c0404f7284bd13199c0e1bb235f4324627e8898cf5"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==2.32.0.20240712"
+ "version": "==2.31.0.20240406"
},
"types-s3transfer": {
"hashes": [
- "sha256:60167a3bfb5c536ec6cdb5818f7f9a28edca9dc3e0b5ff85ae374526fc5e576e",
- "sha256:7a3fec8cd632e2b5efb665a355ef93c2a87fdd5a45b74a949f95a9e628a86356"
+ "sha256:02154cce46528287ad76ad1a0153840e0492239a0887e8833466eccf84b98da0",
+ "sha256:49a7c81fa609ac1532f8de3756e64b58afcecad8767933310228002ec7adff74"
],
- "markers": "python_version >= '3.8'",
- "version": "==0.10.2"
+ "markers": "python_version >= '3.8' and python_version < '4.0'",
+ "version": "==0.10.1"
},
"typing-extensions": {
"hashes": [
- "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d",
- "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"
+ "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0",
+ "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a"
],
"index": "pypi",
"markers": "python_version >= '3.8'",
- "version": "==4.12.2"
+ "version": "==4.11.0"
},
"urllib3": {
"hashes": [
- "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472",
- "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"
+ "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d",
+ "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"
],
"markers": "python_version >= '3.8'",
- "version": "==2.2.2"
+ "version": "==2.2.1"
},
"waitress": {
"hashes": [
@@ -1761,11 +1854,11 @@
},
"webob": {
"hashes": [
- "sha256:2abc1555e118fc251e705fc6dc66c7f5353bb9fbfab6d20e22f1c02b4b71bcee",
- "sha256:b60ba63f05c0cf61e086a10c3781a41fcfe30027753a8ae6d819c77592ce83ea"
+ "sha256:73aae30359291c14fa3b956f8b5ca31960e420c28c1bec002547fb04928cf89b",
+ "sha256:b64ef5141be559cfade448f044fa45c2260351edcb6a8ef6b7e00c7dcef0c323"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
- "version": "==1.8.8"
+ "version": "==1.8.7"
},
"webtest": {
"hashes": [
From 8d324a81d1ccd061e75befbdb2b8b27c966b557f Mon Sep 17 00:00:00 2001
From: zandercymatics <141044360+zandercymatics@users.noreply.github.com>
Date: Thu, 29 Aug 2024 10:41:52 -0600
Subject: [PATCH 025/150] linting
---
.../commands/create_federal_portfolio.py | 21 +++++++++----------
.../transfer_transition_domains_to_domains.py | 2 +-
2 files changed, 11 insertions(+), 12 deletions(-)
diff --git a/src/registrar/management/commands/create_federal_portfolio.py b/src/registrar/management/commands/create_federal_portfolio.py
index 6d62a645b..29697723b 100644
--- a/src/registrar/management/commands/create_federal_portfolio.py
+++ b/src/registrar/management/commands/create_federal_portfolio.py
@@ -4,8 +4,8 @@ import argparse
import logging
from django.core.management import BaseCommand, CommandError
from registrar.management.commands.utility.terminal_helper import TerminalColors, TerminalHelper
-from registrar.models import DomainInformation, DomainRequest, FederalAgency, Suborganization, Portfolio, User, SeniorOfficial
-from django.db.models import Q
+from registrar.models import DomainInformation, DomainRequest, FederalAgency, Suborganization, Portfolio, User
+
logger = logging.getLogger(__name__)
@@ -55,7 +55,7 @@ class Command(BaseCommand):
if parse_requests:
self.handle_portfolio_requests(portfolio, federal_agency)
-
+
if parse_domains:
self.handle_portfolio_domains(portfolio, federal_agency)
@@ -83,10 +83,10 @@ class Command(BaseCommand):
TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
return portfolio
else:
-
+
proceed = TerminalHelper.prompt_for_execution(
system_exit_on_terminate=False,
- info_to_inspect=f"""The given portfolio '{federal_agency.agency}' already exists in our DB.
+ info_to_inspect=f"""The given portfolio '{federal_agency.agency}' already exists in our DB.
If you cancel, the rest of the script will still execute but this record will not update.
""",
prompt_title="Do you wish to modify this record?",
@@ -112,7 +112,7 @@ class Command(BaseCommand):
valid_agencies = DomainInformation.objects.filter(federal_agency=federal_agency)
org_names = valid_agencies.values_list("organization_name", flat=True)
if len(org_names) < 1:
- message =f"No suborganizations found for {federal_agency}"
+ message = f"No suborganizations found for {federal_agency}"
TerminalHelper.colorful_logger(logger.warning, TerminalColors.YELLOW, message)
return
@@ -145,7 +145,7 @@ class Command(BaseCommand):
message = f"Added {len(suborgs)} suborganizations"
TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
else:
- message =f"No suborganizations added"
+ message = "No suborganizations added"
TerminalHelper.colorful_logger(logger.warning, TerminalColors.YELLOW, message)
def _update_existing_suborganizations(self, portfolio, orgs_to_update):
@@ -169,9 +169,8 @@ class Command(BaseCommand):
message = f"Updated {len(orgs_to_update)} suborganizations"
TerminalHelper.colorful_logger(logger.info, TerminalColors.MAGENTA, message)
-
def _update_portfolio_location_details(self, portfolio: Portfolio, domain_info: DomainInformation):
- """Adds location information to the given portfolio based off of the values in
+ """Adds location information to the given portfolio based off of the values in
DomainInformation"""
location_props = [
"address_line1",
@@ -194,7 +193,7 @@ class Command(BaseCommand):
def handle_portfolio_requests(self, portfolio: Portfolio, federal_agency: FederalAgency):
domain_requests = DomainInformation.objects.filter(federal_agency=federal_agency)
if len(domain_requests) < 1:
- message = f"Portfolios not added to domain requests: no valid records found"
+ message = "Portfolios not added to domain requests: no valid records found"
TerminalHelper.colorful_logger(logger.info, TerminalColors.YELLOW, message)
return
@@ -209,7 +208,7 @@ class Command(BaseCommand):
domain_infos = DomainInformation.objects.filter(federal_agency=federal_agency)
if len(domain_infos) < 1:
- message = f"Portfolios not added to domains: no valid records found"
+ message = "Portfolios not added to domains: no valid records found"
TerminalHelper.colorful_logger(logger.info, TerminalColors.YELLOW, message)
return
diff --git a/src/registrar/management/commands/transfer_transition_domains_to_domains.py b/src/registrar/management/commands/transfer_transition_domains_to_domains.py
index acb886b92..727db6dab 100644
--- a/src/registrar/management/commands/transfer_transition_domains_to_domains.py
+++ b/src/registrar/management/commands/transfer_transition_domains_to_domains.py
@@ -423,7 +423,7 @@ class Command(BaseCommand):
valid_fed_type = fed_type in fed_choices
valid_fed_agency = fed_agency in agency_choices
- default_creator, _ = User.get_default_user()
+ default_creator = User.get_default_user()
new_domain_info_data = {
"domain": domain,
From bfbce5a5c5703e73bbec26b2c822ee4d71e9778a Mon Sep 17 00:00:00 2001
From: zandercymatics <141044360+zandercymatics@users.noreply.github.com>
Date: Thu, 29 Aug 2024 10:48:21 -0600
Subject: [PATCH 026/150] Comments
---
.../commands/create_federal_portfolio.py | 18 +++++++++++++++--
.../tests/test_management_scripts.py | 20 +++++++++++++++++++
2 files changed, 36 insertions(+), 2 deletions(-)
diff --git a/src/registrar/management/commands/create_federal_portfolio.py b/src/registrar/management/commands/create_federal_portfolio.py
index 29697723b..00da3b40b 100644
--- a/src/registrar/management/commands/create_federal_portfolio.py
+++ b/src/registrar/management/commands/create_federal_portfolio.py
@@ -149,6 +149,10 @@ class Command(BaseCommand):
TerminalHelper.colorful_logger(logger.warning, TerminalColors.YELLOW, message)
def _update_existing_suborganizations(self, portfolio, orgs_to_update):
+ """
+ Update existing suborganizations with new portfolio.
+ Prompts for user confirmation before proceeding.
+ """
proceed = TerminalHelper.prompt_for_execution(
system_exit_on_terminate=False,
info_to_inspect=f"""Some suborganizations already exist in our DB.
@@ -170,8 +174,10 @@ class Command(BaseCommand):
TerminalHelper.colorful_logger(logger.info, TerminalColors.MAGENTA, message)
def _update_portfolio_location_details(self, portfolio: Portfolio, domain_info: DomainInformation):
- """Adds location information to the given portfolio based off of the values in
- DomainInformation"""
+ """
+ Update portfolio location details based on DomainInformation.
+ Copies relevant fields and saves the portfolio.
+ """
location_props = [
"address_line1",
"address_line2",
@@ -191,6 +197,10 @@ class Command(BaseCommand):
TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
def handle_portfolio_requests(self, portfolio: Portfolio, federal_agency: FederalAgency):
+ """
+ Associate portfolio with domain requests for a federal agency.
+ Updates all relevant domain request records.
+ """
domain_requests = DomainInformation.objects.filter(federal_agency=federal_agency)
if len(domain_requests) < 1:
message = "Portfolios not added to domain requests: no valid records found"
@@ -205,6 +215,10 @@ class Command(BaseCommand):
TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
def handle_portfolio_domains(self, portfolio: Portfolio, federal_agency: FederalAgency):
+ """
+ Associate portfolio with domains for a federal agency.
+ Updates all relevant domain information records.
+ """
domain_infos = DomainInformation.objects.filter(federal_agency=federal_agency)
if len(domain_infos) < 1:
diff --git a/src/registrar/tests/test_management_scripts.py b/src/registrar/tests/test_management_scripts.py
index 1958454f5..9dab76063 100644
--- a/src/registrar/tests/test_management_scripts.py
+++ b/src/registrar/tests/test_management_scripts.py
@@ -1408,3 +1408,23 @@ class TestPopulateFederalAgencyInitialsAndFceb(TestCase):
missing_agency.refresh_from_db()
self.assertIsNone(missing_agency.initials)
self.assertIsNone(missing_agency.is_fceb)
+
+
+class TestCreateFederalPortfolio(TestCase):
+ def setUp(self):
+ self.csv_path = "registrar/tests/data/fake_federal_cio.csv"
+
+ # Create test FederalAgency objects
+ self.agency1, _ = FederalAgency.objects.get_or_create(agency="American Battle Monuments Commission")
+ self.agency2, _ = FederalAgency.objects.get_or_create(agency="Advisory Council on Historic Preservation")
+ self.agency3, _ = FederalAgency.objects.get_or_create(agency="AMTRAK")
+ self.agency4, _ = FederalAgency.objects.get_or_create(agency="John F. Kennedy Center for Performing Arts")
+
+ def tearDown(self):
+ SeniorOfficial.objects.all().delete()
+ FederalAgency.objects.all().delete()
+
+ # == create_or_modify_portfolio tests == #
+ # == create_suborganizations tests == #
+ # == handle_portfolio_requests tests == #
+ # == handle_portfolio_domains tests == #
From f46cc141b0ec54c9de694b87d25809c7e9b2a74c Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Thu, 29 Aug 2024 09:57:48 -0700
Subject: [PATCH 027/150] Correct migrations
---
...e.py => 0120_remove_domaininformation_submitter_and_more.py} | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
rename src/registrar/migrations/{0119_remove_domaininformation_submitter_and_more.py => 0120_remove_domaininformation_submitter_and_more.py} (91%)
diff --git a/src/registrar/migrations/0119_remove_domaininformation_submitter_and_more.py b/src/registrar/migrations/0120_remove_domaininformation_submitter_and_more.py
similarity index 91%
rename from src/registrar/migrations/0119_remove_domaininformation_submitter_and_more.py
rename to src/registrar/migrations/0120_remove_domaininformation_submitter_and_more.py
index d438d6744..d8992845f 100644
--- a/src/registrar/migrations/0119_remove_domaininformation_submitter_and_more.py
+++ b/src/registrar/migrations/0120_remove_domaininformation_submitter_and_more.py
@@ -8,7 +8,7 @@ import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
- ("registrar", "0118_alter_portfolio_options_alter_portfolio_creator_and_more"),
+ ("registrar", "0119_remove_user_portfolio_and_more"),
]
operations = [
From ce0befc06377d99cfa02299f24652431d49adbc4 Mon Sep 17 00:00:00 2001
From: Rebecca Hsieh
Date: Thu, 29 Aug 2024 10:19:08 -0700
Subject: [PATCH 028/150] Update diagrams
---
docs/architecture/diagrams/models_diagram.md | 20 +++++++++++++++----
docs/architecture/diagrams/models_diagram.svg | 2 +-
src/registrar/tests/test_views_request.py | 2 +-
3 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/docs/architecture/diagrams/models_diagram.md b/docs/architecture/diagrams/models_diagram.md
index 4bbec31cc..1856407aa 100644
--- a/docs/architecture/diagrams/models_diagram.md
+++ b/docs/architecture/diagrams/models_diagram.md
@@ -285,6 +285,22 @@ class "registrar.DomainInvitation " as registrar.DomainInvitation #d6
registrar.DomainInvitation -- registrar.Domain
+class "registrar.UserPortfolioPermission " as registrar.UserPortfolioPermission #d6f4e9 {
+ user portfolio permission
+ --
+ + id (BigAutoField)
+ + created_at (DateTimeField)
+ + updated_at (DateTimeField)
+ ~ user (ForeignKey)
+ ~ portfolio (ForeignKey)
+ + roles (ArrayField)
+ + additional_permissions (ArrayField)
+ --
+}
+registrar.UserPortfolioPermission -- registrar.User
+registrar.UserPortfolioPermission -- registrar.Portfolio
+
+
class "registrar.PortfolioInvitation " as registrar.PortfolioInvitation #d6f4e9 {
portfolio invitation
--
@@ -361,9 +377,6 @@ class "registrar.User " as registrar.User #d6f4e9 {
+ is_active (BooleanField)
+ date_joined (DateTimeField)
+ status (CharField)
- ~ portfolio (ForeignKey)
- + portfolio_roles (ArrayField)
- + portfolio_additional_permissions (ArrayField)
+ phone (PhoneNumberField)
+ middle_name (CharField)
+ title (CharField)
@@ -373,7 +386,6 @@ class "registrar.User " as registrar.User #d6f4e9 {
# domains (ManyToManyField)
--
}
-registrar.User -- registrar.Portfolio
registrar.User *--* registrar.Domain
diff --git a/docs/architecture/diagrams/models_diagram.svg b/docs/architecture/diagrams/models_diagram.svg
index f8cf3a46d..85c0e7620 100644
--- a/docs/architecture/diagrams/models_diagram.svg
+++ b/docs/architecture/diagrams/models_diagram.svg
@@ -1 +1 @@
-registrar registrar.Contact Registrar contact id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) user (OneToOneField) first_name (CharField) middle_name (CharField) last_name (CharField) title (CharField) email (EmailField) phone (PhoneNumberField) registrar.User Registrar user id (BigAutoField) password (CharField) last_login (DateTimeField) is_superuser (BooleanField) username (CharField) first_name (CharField) last_name (CharField) email (EmailField) is_staff (BooleanField) is_active (BooleanField) date_joined (DateTimeField) status (CharField) phone (PhoneNumberField) middle_name (CharField) title (CharField) verification_type (CharField) groups (ManyToManyField) user_permissions (ManyToManyField) domains (ManyToManyField) registrar.Host Registrar host id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) name (CharField) domain (ForeignKey) registrar.Domain Registrar domain id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) name (DomainField) state (FSMField) expiration_date (DateField) security_contact_registry_id (TextField) deleted (DateField) first_ready (DateField) dsdata_last_change (TextField) registrar.HostIP Registrar host ip id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) address (CharField) host (ForeignKey) registrar.PublicContact Registrar public contact id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) contact_type (CharField) registry_id (CharField) domain (ForeignKey) name (CharField) org (CharField) street1 (CharField) street2 (CharField) street3 (CharField) city (CharField) sp (CharField) pc (CharField) cc (CharField) email (EmailField) voice (CharField) fax (CharField) pw (CharField) registrar.UserDomainRole Registrar user domain role id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) user (ForeignKey) domain (ForeignKey) role (TextField) registrar.FederalAgency Registrar Federal agency id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) agency (CharField) federal_type (CharField) registrar.DomainRequest Registrar domain request id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) status (FSMField) rejection_reason (TextField) action_needed_reason (TextField) action_needed_reason_email (TextField) federal_agency (ForeignKey) portfolio (ForeignKey) creator (ForeignKey) investigator (ForeignKey) generic_org_type (CharField) is_election_board (BooleanField) organization_type (CharField) federally_recognized_tribe (BooleanField) state_recognized_tribe (BooleanField) tribe_name (CharField) federal_type (CharField) organization_name (CharField) address_line1 (CharField) address_line2 (CharField) city (CharField) state_territory (CharField) zipcode (CharField) urbanization (CharField) about_your_organization (TextField) senior_official (ForeignKey) approved_domain (OneToOneField) requested_domain (OneToOneField) submitter (ForeignKey) purpose (TextField) no_other_contacts_rationale (TextField) anything_else (TextField) has_anything_else_text (BooleanField) cisa_representative_email (EmailField) cisa_representative_first_name (CharField) cisa_representative_last_name (CharField) has_cisa_representative (BooleanField) is_policy_acknowledged (BooleanField) submission_date (DateField) notes (TextField) current_websites (ManyToManyField) alternative_domains (ManyToManyField) other_contacts (ManyToManyField) registrar.Portfolio Registrar portfolio id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) creator (ForeignKey) notes (TextField) federal_agency (ForeignKey) organization_type (CharField) organization_name (CharField) address_line1 (CharField) address_line2 (CharField) city (CharField) state_territory (CharField) zipcode (CharField) urbanization (CharField) security_contact_email (EmailField) registrar.DraftDomain Registrar draft domain id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) name (CharField) registrar.Website Registrar website id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) website (CharField) registrar.DomainInformation Registrar domain information id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) federal_agency (ForeignKey) creator (ForeignKey) portfolio (ForeignKey) domain_request (OneToOneField) generic_org_type (CharField) organization_type (CharField) federally_recognized_tribe (BooleanField) state_recognized_tribe (BooleanField) tribe_name (CharField) federal_type (CharField) is_election_board (BooleanField) organization_name (CharField) address_line1 (CharField) address_line2 (CharField) city (CharField) state_territory (CharField) zipcode (CharField) urbanization (CharField) about_your_organization (TextField) senior_official (ForeignKey) domain (OneToOneField) submitter (ForeignKey) purpose (TextField) no_other_contacts_rationale (TextField) anything_else (TextField) has_anything_else_text (BooleanField) cisa_representative_email (EmailField) cisa_representative_first_name (CharField) cisa_representative_last_name (CharField) has_cisa_representative (BooleanField) is_policy_acknowledged (BooleanField) notes (TextField) other_contacts (ManyToManyField) registrar.DomainInvitation Registrar domain invitation id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) email (EmailField) domain (ForeignKey) status (FSMField) registrar.TransitionDomain Registrar transition domain id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) username (CharField) domain_name (CharField) status (CharField) email_sent (BooleanField) processed (BooleanField) generic_org_type (CharField) organization_name (CharField) federal_type (CharField) federal_agency (CharField) epp_creation_date (DateField) epp_expiration_date (DateField) first_name (CharField) middle_name (CharField) last_name (CharField) title (CharField) email (EmailField) phone (CharField) address_line (CharField) city (CharField) state_territory (CharField) zipcode (CharField) registrar.VerifiedByStaff Registrar verified by staff id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) email (EmailField) requestor (ForeignKey) notes (TextField) registrar.UserGroup Registrar User group id (AutoField) name (CharField) group_ptr (OneToOneField) permissions (ManyToManyField) registrar.WaffleFlag Registrar waffle flag id (BigAutoField) name (CharField) everyone (BooleanField) percent (DecimalField) testing (BooleanField) superusers (BooleanField) staff (BooleanField) authenticated (BooleanField) languages (TextField) rollout (BooleanField) note (TextField) created (DateTimeField) modified (DateTimeField) groups (ManyToManyField) users (ManyToManyField) registrar.DomainGroup Registrar domain group id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) name (CharField) portfolio (ForeignKey) domains (ManyToManyField) registrar.Suborganization Registrar suborganization id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) name (CharField) portfolio (ForeignKey)
\ No newline at end of file
+registrar registrar.Contact Registrar contact id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) first_name (CharField) middle_name (CharField) last_name (CharField) title (CharField) email (EmailField) phone (PhoneNumberField) registrar.Host Registrar host id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) name (CharField) domain (ForeignKey) registrar.Domain Registrar domain id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) name (DomainField) state (FSMField) expiration_date (DateField) security_contact_registry_id (TextField) deleted (DateField) first_ready (DateField) dsdata_last_change (TextField) registrar.HostIP Registrar host ip id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) address (CharField) host (ForeignKey) registrar.PublicContact Registrar public contact id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) contact_type (CharField) registry_id (CharField) domain (ForeignKey) name (CharField) org (CharField) street1 (CharField) street2 (CharField) street3 (CharField) city (CharField) sp (CharField) pc (CharField) cc (CharField) email (EmailField) voice (CharField) fax (CharField) pw (CharField) registrar.UserDomainRole Registrar user domain role id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) user (ForeignKey) domain (ForeignKey) role (TextField) registrar.User Registrar user id (BigAutoField) password (CharField) last_login (DateTimeField) is_superuser (BooleanField) username (CharField) first_name (CharField) last_name (CharField) email (EmailField) is_staff (BooleanField) is_active (BooleanField) date_joined (DateTimeField) status (CharField) portfolio (ForeignKey) portfolio_roles (ArrayField) portfolio_additional_permissions (ArrayField) phone (PhoneNumberField) middle_name (CharField) title (CharField) verification_type (CharField) groups (ManyToManyField) user_permissions (ManyToManyField) domains (ManyToManyField) registrar.FederalAgency Registrar Federal agency id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) agency (CharField) federal_type (CharField) initials (CharField) is_fceb (BooleanField) registrar.DomainRequest Registrar domain request id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) status (FSMField) rejection_reason (TextField) action_needed_reason (TextField) action_needed_reason_email (TextField) federal_agency (ForeignKey) portfolio (ForeignKey) sub_organization (ForeignKey) creator (ForeignKey) investigator (ForeignKey) generic_org_type (CharField) is_election_board (BooleanField) organization_type (CharField) federally_recognized_tribe (BooleanField) state_recognized_tribe (BooleanField) tribe_name (CharField) federal_type (CharField) organization_name (CharField) address_line1 (CharField) address_line2 (CharField) city (CharField) state_territory (CharField) zipcode (CharField) urbanization (CharField) about_your_organization (TextField) senior_official (ForeignKey) approved_domain (OneToOneField) requested_domain (OneToOneField) purpose (TextField) no_other_contacts_rationale (TextField) anything_else (TextField) has_anything_else_text (BooleanField) cisa_representative_email (EmailField) cisa_representative_first_name (CharField) cisa_representative_last_name (CharField) has_cisa_representative (BooleanField) is_policy_acknowledged (BooleanField) submission_date (DateField) notes (TextField) current_websites (ManyToManyField) alternative_domains (ManyToManyField) other_contacts (ManyToManyField) registrar.Portfolio Registrar portfolio id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) creator (ForeignKey) organization_name (CharField) organization_type (CharField) notes (TextField) federal_agency (ForeignKey) senior_official (ForeignKey) address_line1 (CharField) address_line2 (CharField) city (CharField) state_territory (CharField) zipcode (CharField) urbanization (CharField) security_contact_email (EmailField) registrar.Suborganization Registrar suborganization id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) name (CharField) portfolio (ForeignKey) registrar.DraftDomain Registrar draft domain id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) name (CharField) registrar.Website Registrar website id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) website (CharField) registrar.DomainInformation Registrar domain information id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) federal_agency (ForeignKey) creator (ForeignKey) portfolio (ForeignKey) sub_organization (ForeignKey) domain_request (OneToOneField) generic_org_type (CharField) organization_type (CharField) federally_recognized_tribe (BooleanField) state_recognized_tribe (BooleanField) tribe_name (CharField) federal_type (CharField) is_election_board (BooleanField) organization_name (CharField) address_line1 (CharField) address_line2 (CharField) city (CharField) state_territory (CharField) zipcode (CharField) urbanization (CharField) about_your_organization (TextField) senior_official (ForeignKey) domain (OneToOneField) purpose (TextField) no_other_contacts_rationale (TextField) anything_else (TextField) has_anything_else_text (BooleanField) cisa_representative_email (EmailField) cisa_representative_first_name (CharField) cisa_representative_last_name (CharField) has_cisa_representative (BooleanField) is_policy_acknowledged (BooleanField) notes (TextField) other_contacts (ManyToManyField) registrar.DomainInvitation Registrar domain invitation id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) email (EmailField) domain (ForeignKey) status (FSMField) registrar.PortfolioInvitation Registrar portfolio invitation id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) email (EmailField) portfolio (ForeignKey) portfolio_roles (ArrayField) portfolio_additional_permissions (ArrayField) status (FSMField) registrar.TransitionDomain Registrar transition domain id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) username (CharField) domain_name (CharField) status (CharField) email_sent (BooleanField) processed (BooleanField) generic_org_type (CharField) organization_name (CharField) federal_type (CharField) federal_agency (CharField) epp_creation_date (DateField) epp_expiration_date (DateField) first_name (CharField) middle_name (CharField) last_name (CharField) title (CharField) email (EmailField) phone (CharField) address_line (CharField) city (CharField) state_territory (CharField) zipcode (CharField) registrar.VerifiedByStaff Registrar verified by staff id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) email (EmailField) requestor (ForeignKey) notes (TextField) registrar.UserGroup Registrar User group id (AutoField) name (CharField) group_ptr (OneToOneField) permissions (ManyToManyField) registrar.WaffleFlag Registrar waffle flag id (BigAutoField) name (CharField) everyone (BooleanField) percent (DecimalField) testing (BooleanField) superusers (BooleanField) staff (BooleanField) authenticated (BooleanField) languages (TextField) rollout (BooleanField) note (TextField) created (DateTimeField) modified (DateTimeField) groups (ManyToManyField) users (ManyToManyField) registrar.SeniorOfficial Registrar senior official id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) first_name (CharField) last_name (CharField) title (CharField) phone (PhoneNumberField) email (EmailField) federal_agency (ForeignKey) registrar.DomainGroup Registrar domain group id (BigAutoField) created_at (DateTimeField) updated_at (DateTimeField) name (CharField) portfolio (ForeignKey) domains (ManyToManyField)
\ No newline at end of file
diff --git a/src/registrar/tests/test_views_request.py b/src/registrar/tests/test_views_request.py
index 8718abda7..07ce4f8f8 100644
--- a/src/registrar/tests/test_views_request.py
+++ b/src/registrar/tests/test_views_request.py
@@ -2212,7 +2212,7 @@ class DomainRequestTests(TestWithUser, WebTest):
2. then submit,
the domain request also updates its creator data to reflect user profile changes."""
- # Populate the database with a domain request
+ # Populate the database with a domain request
domain_request, _ = DomainRequest.objects.get_or_create(
generic_org_type="federal",
federal_type="executive",
From b162ae8d7fd14475bac6853f658955f9edd698e1 Mon Sep 17 00:00:00 2001
From: zandercymatics <141044360+zandercymatics@users.noreply.github.com>
Date: Thu, 29 Aug 2024 11:27:20 -0600
Subject: [PATCH 029/150] Simplify logic
---
.../commands/create_federal_portfolio.py | 124 +++++++-----------
1 file changed, 48 insertions(+), 76 deletions(-)
diff --git a/src/registrar/management/commands/create_federal_portfolio.py b/src/registrar/management/commands/create_federal_portfolio.py
index 00da3b40b..a0145418f 100644
--- a/src/registrar/management/commands/create_federal_portfolio.py
+++ b/src/registrar/management/commands/create_federal_portfolio.py
@@ -14,7 +14,11 @@ class Command(BaseCommand):
help = "Creates a federal portfolio given a FederalAgency name"
def add_arguments(self, parser):
- """Add our arguments."""
+ """Add three arguments:
+ 1. agency_name => the value of FederalAgency.agency
+ 2. --parse_requests => if true, adds the given portfolio to each related DomainRequest
+ 3. --parse_domains => if true, adds the given portfolio to each related DomainInformation
+ """
parser.add_argument(
"agency_name",
help="The name of the FederalAgency to add",
@@ -37,19 +41,14 @@ class Command(BaseCommand):
if not parse_requests and not parse_domains:
raise CommandError("You must specify at least one of --parse_requests or --parse_domains.")
- agencies = FederalAgency.objects.filter(agency__iexact=agency_name)
-
- # TODO - maybe we can add an option here to add this if it doesn't exist?
- if not agencies.exists():
+ federal_agency = FederalAgency.objects.filter(agency__iexact=agency_name).first()
+ if not federal_agency:
raise ValueError(
f"Cannot find the federal agency '{agency_name}' in our database. "
"The value you enter for `agency_name` must be "
"prepopulated in the FederalAgency table before proceeding."
)
- # There should be a one-to-one relationship between the name and the agency.
- federal_agency = agencies.get()
-
portfolio = self.create_or_modify_portfolio(federal_agency)
self.create_suborganizations(portfolio, federal_agency)
@@ -60,9 +59,7 @@ class Command(BaseCommand):
self.handle_portfolio_domains(portfolio, federal_agency)
def create_or_modify_portfolio(self, federal_agency):
- """Tries to create a portfolio record based off of a federal agency.
- If the record already exists, we prompt the user to proceed then
- update the record."""
+ """Creates or modifies a portfolio record based on a federal agency."""
portfolio_args = {
"federal_agency": federal_agency,
"organization_name": federal_agency.agency,
@@ -71,19 +68,15 @@ class Command(BaseCommand):
"notes": "Auto-generated record",
}
- senior_official = federal_agency.so_federal_agency
- if senior_official.exists():
- portfolio_args["senior_official"] = senior_official.first()
+ if federal_agency.so_federal_agency.exists():
+ portfolio_args["senior_official"] = federal_agency.so_federal_agency.first()
- # Create the Portfolio value if it doesn't exist
- existing_portfolio = Portfolio.objects.filter(organization_name=federal_agency.agency)
- if not existing_portfolio.exists():
- portfolio = Portfolio.objects.create(**portfolio_args)
+ portfolio, created = Portfolio.objects.get_or_create(**portfolio_args)
+
+ if created:
message = f"Created portfolio '{portfolio}'"
TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
- return portfolio
else:
-
proceed = TerminalHelper.prompt_for_execution(
system_exit_on_terminate=False,
info_to_inspect=f"""The given portfolio '{federal_agency.agency}' already exists in our DB.
@@ -91,62 +84,44 @@ class Command(BaseCommand):
""",
prompt_title="Do you wish to modify this record?",
)
- if not proceed:
- if len(existing_portfolio) > 1:
- raise ValueError(f"Could not use portfolio '{federal_agency.agency}': multiple records exist.")
- else:
- # Just return the portfolio object without modifying it
- return existing_portfolio.get()
+ if proceed:
+ for key, value in portfolio_args.items():
+ setattr(portfolio, key, value)
+ portfolio.save()
+ message = f"Modified portfolio '{portfolio}'"
+ TerminalHelper.colorful_logger(logger.info, TerminalColors.MAGENTA, message)
- if len(existing_portfolio) > 1:
- raise ValueError(f"Could not update portfolio '{federal_agency.agency}': multiple records exist.")
-
- existing_portfolio.update(**portfolio_args)
- message = f"Modified portfolio '{existing_portfolio.first()}'"
- TerminalHelper.colorful_logger(logger.info, TerminalColors.MAGENTA, message)
- return existing_portfolio.get()
+ return portfolio
def create_suborganizations(self, portfolio: Portfolio, federal_agency: FederalAgency):
- """Given a list of organization_names on DomainInformation objects (filtered by agency),
- create multiple Suborganizations tied to the given portfolio"""
- valid_agencies = DomainInformation.objects.filter(federal_agency=federal_agency)
- org_names = valid_agencies.values_list("organization_name", flat=True)
- if len(org_names) < 1:
- message = f"No suborganizations found for {federal_agency}"
- TerminalHelper.colorful_logger(logger.warning, TerminalColors.YELLOW, message)
+ """Create Suborganizations tied to the given portfolio based on DomainInformation objects"""
+ valid_agencies = DomainInformation.objects.filter(federal_agency=federal_agency, organization_name__isnull=False)
+ org_names = set(valid_agencies.values_list("organization_name", flat=True))
+
+ if not org_names:
+ TerminalHelper.colorful_logger(logger.warning, TerminalColors.YELLOW, f"No suborganizations found for {federal_agency}")
return
- # Check if we need to update any existing suborgs first.
- # This step is optional.
+ # Check if we need to update any existing suborgs first. This step is optional.
existing_suborgs = Suborganization.objects.filter(name__in=org_names)
- if len(existing_suborgs) > 0:
+ if existing_suborgs.exists():
self._update_existing_suborganizations(portfolio, existing_suborgs)
- # Add any suborgs that don't presently exist
- excluded_org_names = existing_suborgs.values_list("name", flat=True)
- suborgs = []
- for name in org_names:
- if name and name not in excluded_org_names:
- if portfolio.organization_name and name.lower() == portfolio.organization_name.lower():
- # If the suborg name is the name that currently exists,
- # thats not a suborg - thats the portfolio itself!
- # In this case, we can use this as an opportunity to update
- # address information and the like
- self._update_portfolio_location_details(portfolio, valid_agencies.get(organization_name=name))
- else:
- suborg = Suborganization(
- name=name,
- portfolio=portfolio,
- )
- suborgs.append(suborg)
+ # Create new suborgs, as long as they don't exist in the db already
+ new_suborgs = []
+ for name in org_names - set(existing_suborgs.values_list("name", flat=True)):
+ if name.lower() == portfolio.organization_name.lower():
+ # If the suborg name is a portfolio name that currently exists, thats not a suborg - thats the portfolio itself!
+ # In this case, we can use this as an opportunity to update address information.
+ self._update_portfolio_location_details(portfolio, valid_agencies.filter(organization_name=name).first())
+ else:
+ new_suborgs.append(Suborganization(name=name, portfolio=portfolio))
- if len(org_names) > 1:
- Suborganization.objects.bulk_create(suborgs)
- message = f"Added {len(suborgs)} suborganizations"
- TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
+ if new_suborgs:
+ Suborganization.objects.bulk_create(new_suborgs)
+ TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, f"Added {len(new_suborgs)} suborganizations")
else:
- message = "No suborganizations added"
- TerminalHelper.colorful_logger(logger.warning, TerminalColors.YELLOW, message)
+ TerminalHelper.colorful_logger(logger.warning, TerminalColors.YELLOW, "No suborganizations added")
def _update_existing_suborganizations(self, portfolio, orgs_to_update):
"""
@@ -163,15 +138,13 @@ class Command(BaseCommand):
""",
prompt_title="Do you wish to modify existing suborganizations?",
)
- if not proceed:
- return
+ if proceed:
+ for org in orgs_to_update:
+ org.portfolio = portfolio
- for org in orgs_to_update:
- org.portfolio = portfolio
-
- Suborganization.objects.bulk_update(orgs_to_update, ["portfolio"])
- message = f"Updated {len(orgs_to_update)} suborganizations"
- TerminalHelper.colorful_logger(logger.info, TerminalColors.MAGENTA, message)
+ Suborganization.objects.bulk_update(orgs_to_update, ["portfolio"])
+ message = f"Updated {len(orgs_to_update)} suborganizations"
+ TerminalHelper.colorful_logger(logger.info, TerminalColors.MAGENTA, message)
def _update_portfolio_location_details(self, portfolio: Portfolio, domain_info: DomainInformation):
"""
@@ -191,8 +164,8 @@ class Command(BaseCommand):
# Copy the value from the domain info object to the portfolio object
value = getattr(domain_info, prop_name)
setattr(portfolio, prop_name, value)
- portfolio.save()
+ portfolio.save()
message = f"Updated location details on portfolio '{portfolio}'"
TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
@@ -230,6 +203,5 @@ class Command(BaseCommand):
domain_info.portfolio = portfolio
DomainInformation.objects.bulk_update(domain_infos, ["portfolio"])
-
message = f"Added portfolio '{portfolio}' to {len(domain_infos)} domains"
TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
From b27913f124fa5a202fcb7fd733d0ae7bb06d6232 Mon Sep 17 00:00:00 2001
From: zandercymatics <141044360+zandercymatics@users.noreply.github.com>
Date: Thu, 29 Aug 2024 11:34:09 -0600
Subject: [PATCH 030/150] Avoid using an early return (consistency)
---
.../commands/create_federal_portfolio.py | 30 +++++++++----------
1 file changed, 14 insertions(+), 16 deletions(-)
diff --git a/src/registrar/management/commands/create_federal_portfolio.py b/src/registrar/management/commands/create_federal_portfolio.py
index a0145418f..da2c2327d 100644
--- a/src/registrar/management/commands/create_federal_portfolio.py
+++ b/src/registrar/management/commands/create_federal_portfolio.py
@@ -175,17 +175,16 @@ class Command(BaseCommand):
Updates all relevant domain request records.
"""
domain_requests = DomainInformation.objects.filter(federal_agency=federal_agency)
- if len(domain_requests) < 1:
+ if not domain_requests.exists():
message = "Portfolios not added to domain requests: no valid records found"
TerminalHelper.colorful_logger(logger.info, TerminalColors.YELLOW, message)
- return
+ else:
+ for domain_request in domain_requests:
+ domain_request.portfolio = portfolio
- for domain_request in domain_requests:
- domain_request.portfolio = portfolio
-
- DomainRequest.objects.bulk_update(domain_requests, ["portfolio"])
- message = f"Added portfolio '{portfolio}' to {len(domain_requests)} domain requests"
- TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
+ DomainRequest.objects.bulk_update(domain_requests, ["portfolio"])
+ message = f"Added portfolio '{portfolio}' to {len(domain_requests)} domain requests"
+ TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
def handle_portfolio_domains(self, portfolio: Portfolio, federal_agency: FederalAgency):
"""
@@ -193,15 +192,14 @@ class Command(BaseCommand):
Updates all relevant domain information records.
"""
domain_infos = DomainInformation.objects.filter(federal_agency=federal_agency)
-
- if len(domain_infos) < 1:
+ if not domain_infos.exists():
message = "Portfolios not added to domains: no valid records found"
TerminalHelper.colorful_logger(logger.info, TerminalColors.YELLOW, message)
return
+ else:
+ for domain_info in domain_infos:
+ domain_info.portfolio = portfolio
- for domain_info in domain_infos:
- domain_info.portfolio = portfolio
-
- DomainInformation.objects.bulk_update(domain_infos, ["portfolio"])
- message = f"Added portfolio '{portfolio}' to {len(domain_infos)} domains"
- TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
+ DomainInformation.objects.bulk_update(domain_infos, ["portfolio"])
+ message = f"Added portfolio '{portfolio}' to {len(domain_infos)} domains"
+ TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
From 12eab5c44fcac0d945cfc5a45d17764abfdab71d Mon Sep 17 00:00:00 2001
From: zandercymatics <141044360+zandercymatics@users.noreply.github.com>
Date: Thu, 29 Aug 2024 11:34:35 -0600
Subject: [PATCH 031/150] Update create_federal_portfolio.py
---
src/registrar/management/commands/create_federal_portfolio.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/registrar/management/commands/create_federal_portfolio.py b/src/registrar/management/commands/create_federal_portfolio.py
index da2c2327d..f7174ac68 100644
--- a/src/registrar/management/commands/create_federal_portfolio.py
+++ b/src/registrar/management/commands/create_federal_portfolio.py
@@ -195,7 +195,6 @@ class Command(BaseCommand):
if not domain_infos.exists():
message = "Portfolios not added to domains: no valid records found"
TerminalHelper.colorful_logger(logger.info, TerminalColors.YELLOW, message)
- return
else:
for domain_info in domain_infos:
domain_info.portfolio = portfolio
From 11d662aa3cd888ae0e07601da72ef60f60bb3942 Mon Sep 17 00:00:00 2001
From: zandercymatics <141044360+zandercymatics@users.noreply.github.com>
Date: Thu, 29 Aug 2024 11:42:32 -0600
Subject: [PATCH 032/150] use defaults
---
.../management/commands/create_federal_portfolio.py | 5 ++++-
src/registrar/tests/test_management_scripts.py | 3 +++
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/registrar/management/commands/create_federal_portfolio.py b/src/registrar/management/commands/create_federal_portfolio.py
index f7174ac68..a5b432247 100644
--- a/src/registrar/management/commands/create_federal_portfolio.py
+++ b/src/registrar/management/commands/create_federal_portfolio.py
@@ -71,7 +71,10 @@ class Command(BaseCommand):
if federal_agency.so_federal_agency.exists():
portfolio_args["senior_official"] = federal_agency.so_federal_agency.first()
- portfolio, created = Portfolio.objects.get_or_create(**portfolio_args)
+ portfolio, created = Portfolio.objects.get_or_create(
+ organization_name=portfolio_args.get("organization_name"),
+ defaults=portfolio_args
+ )
if created:
message = f"Created portfolio '{portfolio}'"
diff --git a/src/registrar/tests/test_management_scripts.py b/src/registrar/tests/test_management_scripts.py
index 9dab76063..f9c544bfe 100644
--- a/src/registrar/tests/test_management_scripts.py
+++ b/src/registrar/tests/test_management_scripts.py
@@ -1428,3 +1428,6 @@ class TestCreateFederalPortfolio(TestCase):
# == create_suborganizations tests == #
# == handle_portfolio_requests tests == #
# == handle_portfolio_domains tests == #
+ # test for parse_requests
+ # test for parse_domains
+ # test for both
From bf00f204b0122b73a728c83e1a454d34772c5fd7 Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Thu, 29 Aug 2024 11:30:49 -0700
Subject: [PATCH 033/150] remove unused INVESTIGATOR_NOT_SUBMITTER error code
---
src/registrar/utility/errors.py | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/src/registrar/utility/errors.py b/src/registrar/utility/errors.py
index 47d3feff5..8cb83c0ee 100644
--- a/src/registrar/utility/errors.py
+++ b/src/registrar/utility/errors.py
@@ -77,17 +77,15 @@ class FSMErrorCodes(IntEnum):
- 1 APPROVE_DOMAIN_IN_USE The domain is already in use
- 2 NO_INVESTIGATOR No investigator is assigned
- 3 INVESTIGATOR_NOT_STAFF Investigator is a non-staff user
- - 4 INVESTIGATOR_NOT_SUBMITTER The form submitter is not the investigator
- - 5 NO_REJECTION_REASON No rejection reason is specified
- - 6 NO_ACTION_NEEDED_REASON No action needed reason is specified
+ - 4 NO_REJECTION_REASON No rejection reason is specified
+ - 5 NO_ACTION_NEEDED_REASON No action needed reason is specified
"""
APPROVE_DOMAIN_IN_USE = 1
NO_INVESTIGATOR = 2
INVESTIGATOR_NOT_STAFF = 3
- INVESTIGATOR_NOT_SUBMITTER = 4
- NO_REJECTION_REASON = 5
- NO_ACTION_NEEDED_REASON = 6
+ NO_REJECTION_REASON = 4
+ NO_ACTION_NEEDED_REASON = 5
class FSMDomainRequestError(Exception):
@@ -100,7 +98,6 @@ class FSMDomainRequestError(Exception):
FSMErrorCodes.APPROVE_DOMAIN_IN_USE: ("Cannot approve. Requested domain is already in use."),
FSMErrorCodes.NO_INVESTIGATOR: ("Investigator is required for this status."),
FSMErrorCodes.INVESTIGATOR_NOT_STAFF: ("Investigator is not a staff user."),
- FSMErrorCodes.INVESTIGATOR_NOT_SUBMITTER: ("Only the assigned investigator can make this change."),
FSMErrorCodes.NO_REJECTION_REASON: ("A reason is required for this status."),
FSMErrorCodes.NO_ACTION_NEEDED_REASON: ("A reason is required for this status."),
}
From fde87230b49a516700b73cf176a0f1ae8e5a71eb Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Thu, 29 Aug 2024 11:32:10 -0700
Subject: [PATCH 034/150] Revert requirements.txt
---
src/requirements.txt | 67 ++++++++++++++++++++++++--------------------
1 file changed, 37 insertions(+), 30 deletions(-)
diff --git a/src/requirements.txt b/src/requirements.txt
index 4a6cec691..3f7158449 100644
--- a/src/requirements.txt
+++ b/src/requirements.txt
@@ -1,68 +1,75 @@
-i https://pypi.python.org/simple
-annotated-types==0.7.0; python_version >= '3.8'
+annotated-types==0.6.0; python_version >= '3.8'
asgiref==3.8.1; python_version >= '3.8'
-boto3==1.35.8; python_version >= '3.8'
-botocore==1.35.8; python_version >= '3.8'
-cachetools==5.5.0; python_version >= '3.7'
-certifi==2024.7.4; python_version >= '3.6'
+boto3==1.34.95; python_version >= '3.8'
+botocore==1.34.95; python_version >= '3.8'
+cachetools==5.3.3; python_version >= '3.7'
+certifi==2024.2.2; python_version >= '3.6'
cfenv==0.5.3
-cffi==1.17.0; platform_python_implementation != 'PyPy'
+cffi==1.16.0; platform_python_implementation != 'PyPy'
charset-normalizer==3.3.2; python_full_version >= '3.7.0'
-cryptography==43.0.0; python_version >= '3.7'
+cryptography==42.0.5; python_version >= '3.7'
defusedxml==0.7.1; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'
diff-match-patch==20230430; python_version >= '3.7'
-dj-database-url==2.2.0
+dj-database-url==2.1.0
dj-email-url==1.0.6
django==4.2.10; python_version >= '3.8'
django-admin-multiple-choice-list-filter==0.1.1
django-allow-cidr==0.7.1
django-auditlog==3.0.0; python_version >= '3.8'
django-cache-url==3.4.5
-django-cors-headers==4.4.0; python_version >= '3.8'
+django-cors-headers==4.3.1; python_version >= '3.8'
django-csp==3.8
django-fsm==2.8.1
-django-import-export==4.1.1; python_version >= '3.8'
+django-import-export==3.3.8; python_version >= '3.8'
django-login-required-middleware==0.9.0
-django-phonenumber-field[phonenumberslite]==8.0.0; python_version >= '3.8'
+django-phonenumber-field[phonenumberslite]==7.3.0; python_version >= '3.8'
django-waffle==4.1.0; python_version >= '3.8'
django-widget-tweaks==1.5.0; python_version >= '3.8'
environs[django]==11.0.0; python_version >= '3.8'
-faker==28.0.0; python_version >= '3.8'
+et-xmlfile==1.1.0; python_version >= '3.6'
+faker==25.0.0; python_version >= '3.8'
fred-epplib@ git+https://github.com/cisagov/epplib.git@d56d183f1664f34c40ca9716a3a9a345f0ef561c
furl==2.1.3
future==1.0.0; python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'
gevent==24.2.1; python_version >= '3.8'
greenlet==3.0.3; python_version >= '3.7'
-gunicorn==23.0.0; python_version >= '3.7'
-idna==3.8; python_version >= '3.6'
+gunicorn==22.0.0; python_version >= '3.7'
+idna==3.7; python_version >= '3.5'
jmespath==1.0.1; python_version >= '3.7'
-lxml==5.3.0; python_version >= '3.6'
-mako==1.3.5; python_version >= '3.8'
+lxml==5.2.1; python_version >= '3.6'
+mako==1.3.3; python_version >= '3.8'
+markuppy==1.14
markupsafe==2.1.5; python_version >= '3.7'
-marshmallow==3.22.0; python_version >= '3.8'
+marshmallow==3.21.1; python_version >= '3.8'
+odfpy==1.4.1
oic==1.7.0; python_version ~= '3.8'
+openpyxl==3.1.2
orderedmultidict==1.0.1
-packaging==24.1; python_version >= '3.8'
-phonenumberslite==8.13.44
+packaging==24.0; python_version >= '3.7'
+phonenumberslite==8.13.35
psycopg2-binary==2.9.9; python_version >= '3.7'
pycparser==2.22; python_version >= '3.8'
pycryptodomex==3.20.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'
-pydantic==2.8.2; python_version >= '3.8'
-pydantic-core==2.20.1; python_version >= '3.8'
-pydantic-settings==2.4.0; python_version >= '3.8'
+pydantic==2.7.1; python_version >= '3.8'
+pydantic-core==2.18.2; python_version >= '3.8'
+pydantic-settings==2.2.1; python_version >= '3.8'
pyjwkest==1.4.2
python-dateutil==2.9.0.post0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'
python-dotenv==1.0.1; python_version >= '3.8'
+pyyaml==6.0.1
pyzipper==0.3.6; python_version >= '3.4'
-requests==2.32.3; python_version >= '3.8'
-s3transfer==0.10.2; python_version >= '3.8'
-setuptools==74.0.0; python_version >= '3.8'
+requests==2.31.0; python_version >= '3.7'
+s3transfer==0.10.1; python_version >= '3.8'
+setuptools==69.5.1; python_version >= '3.8'
six==1.16.0; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'
-sqlparse==0.5.1; python_version >= '3.8'
+sqlparse==0.5.0; python_version >= '3.8'
tablib[html,ods,xls,xlsx,yaml]==3.5.0; python_version >= '3.8'
tblib==3.0.0; python_version >= '3.8'
-typing-extensions==4.12.2; python_version >= '3.8'
-urllib3==2.2.2; python_version >= '3.8'
-whitenoise==6.7.0; python_version >= '3.8'
+typing-extensions==4.11.0; python_version >= '3.8'
+urllib3==2.2.1; python_version >= '3.8'
+whitenoise==6.6.0; python_version >= '3.8'
+xlrd==2.0.1
+xlwt==1.3.0
zope.event==5.0; python_version >= '3.7'
-zope.interface==7.0.3; python_version >= '3.8'
+zope.interface==6.3; python_version >= '3.7'
From f41c6b3fa145b31b01543f5da47114d3b9eed131 Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Thu, 29 Aug 2024 11:56:46 -0700
Subject: [PATCH 035/150] Revert settings.py
---
src/registrar/config/settings.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/registrar/config/settings.py b/src/registrar/config/settings.py
index 72bffdbb4..73aecad7a 100644
--- a/src/registrar/config/settings.py
+++ b/src/registrar/config/settings.py
@@ -357,7 +357,7 @@ CSP_FORM_ACTION = allowed_sources
# and inline with a nonce, as well as allowing connections back to their domain.
# Note: If needed, we can embed chart.js instead of using the CDN
CSP_DEFAULT_SRC = ("'self'",)
-CSP_STYLE_SRC = ["'self'", "https://www.ssa.gov"]
+CSP_STYLE_SRC = ["'self'", "https://www.ssa.gov/accessibility/andi/andi.css"]
CSP_SCRIPT_SRC_ELEM = [
"'self'",
"https://www.googletagmanager.com/",
@@ -367,7 +367,7 @@ CSP_SCRIPT_SRC_ELEM = [
]
CSP_CONNECT_SRC = ["'self'", "https://www.google-analytics.com/", "https://www.ssa.gov/accessibility/andi/andi.js"]
CSP_INCLUDE_NONCE_IN = ["script-src-elem", "style-src"]
-CSP_IMG_SRC = ["'self'", "https://www.ssa.gov"]
+CSP_IMG_SRC = ["'self'", "https://www.ssa.gov/accessibility/andi/icons/"]
# Cross-Origin Resource Sharing (CORS) configuration
# Sets clients that allow access control to manage.get.gov
From 91e62a6cdfcb24710c9b1dc6cf868f18f17e85b9 Mon Sep 17 00:00:00 2001
From: zandercymatics <141044360+zandercymatics@users.noreply.github.com>
Date: Thu, 29 Aug 2024 14:18:38 -0600
Subject: [PATCH 036/150] Unit tests
---
docs/operations/data_migration.md | 42 ++++++
.../commands/create_federal_portfolio.py | 28 +++-
src/registrar/tests/common.py | 7 +-
.../tests/test_management_scripts.py | 141 +++++++++++++++---
4 files changed, 194 insertions(+), 24 deletions(-)
diff --git a/docs/operations/data_migration.md b/docs/operations/data_migration.md
index 5914eb179..c261e7a06 100644
--- a/docs/operations/data_migration.md
+++ b/docs/operations/data_migration.md
@@ -838,3 +838,45 @@ Example: `cf ssh getgov-za`
### Running locally
```docker-compose exec app ./manage.py populate_domain_request_dates```
+
+## Create federal portfolio
+This script takes the name of a `FederalAgency` (like 'AMTRAK') and does the following:
+1. Creates the portfolio record based off of data on the federal agency object itself
+2. Creates suborganizations from existing DomainInformation records
+3. Associates the SeniorOfficial record (if it exists)
+4. Adds this portfolio to DomainInformation / DomainRequests or both
+
+### Running on sandboxes
+
+#### Step 1: Login to CloudFoundry
+```cf login -a api.fr.cloud.gov --sso```
+
+#### Step 2: SSH into your environment
+```cf ssh getgov-{space}```
+
+Example: `cf ssh getgov-za`
+
+#### Step 3: Create a shell instance
+```/tmp/lifecycle/shell```
+
+#### Step 4: Upload your csv to the desired sandbox
+[Follow these steps](#use-scp-to-transfer-data-to-sandboxes) to upload the federal_cio csv to a sandbox of your choice.
+
+#### Step 5: Running the script
+```./manage.py create_federal_portfolio "{federal_agency_name}" --parse_requests --parse_domains```
+
+Example: `./manage.py create_federal_portfolio "AMTRAK" --parse_requests --parse_domains`
+
+### Running locally
+
+#### Step 1: Running the script
+```docker-compose exec app ./manage.py create_federal_portfolio "{federal_agency_name}" --parse_requests --parse_domains```
+
+##### Parameters
+| | Parameter | Description |
+|:-:|:-------------------------- |:-------------------------------------------------------------------------------------------|
+| 1 | **federal_agency_name** | Name of the FederalAgency record surrounded by quotes. For instance,"AMTRAK". |
+| 2 | **parse_requests** | Optional. If True, then the created portfolio is added to all related DomainRequests. |
+| 3 | **parse_domains** | Optional. If True, then the created portfolio is added to all related Domains. |
+
+Note: While you can specify both at the same time, you must specify either --parse_requests or --parse_domains. You cannot run the script without defining one or the other.
diff --git a/src/registrar/management/commands/create_federal_portfolio.py b/src/registrar/management/commands/create_federal_portfolio.py
index a5b432247..4ca6ba17f 100644
--- a/src/registrar/management/commands/create_federal_portfolio.py
+++ b/src/registrar/management/commands/create_federal_portfolio.py
@@ -72,8 +72,7 @@ class Command(BaseCommand):
portfolio_args["senior_official"] = federal_agency.so_federal_agency.first()
portfolio, created = Portfolio.objects.get_or_create(
- organization_name=portfolio_args.get("organization_name"),
- defaults=portfolio_args
+ organization_name=portfolio_args.get("organization_name"), defaults=portfolio_args
)
if created:
@@ -88,6 +87,15 @@ class Command(BaseCommand):
prompt_title="Do you wish to modify this record?",
)
if proceed:
+
+ # Don't override the creator and notes fields
+ if portfolio.creator:
+ portfolio_args.pop("creator")
+
+ if portfolio.notes:
+ portfolio_args.pop("notes")
+
+ # Update everything else
for key, value in portfolio_args.items():
setattr(portfolio, key, value)
portfolio.save()
@@ -98,11 +106,15 @@ class Command(BaseCommand):
def create_suborganizations(self, portfolio: Portfolio, federal_agency: FederalAgency):
"""Create Suborganizations tied to the given portfolio based on DomainInformation objects"""
- valid_agencies = DomainInformation.objects.filter(federal_agency=federal_agency, organization_name__isnull=False)
+ valid_agencies = DomainInformation.objects.filter(
+ federal_agency=federal_agency, organization_name__isnull=False
+ )
org_names = set(valid_agencies.values_list("organization_name", flat=True))
if not org_names:
- TerminalHelper.colorful_logger(logger.warning, TerminalColors.YELLOW, f"No suborganizations found for {federal_agency}")
+ TerminalHelper.colorful_logger(
+ logger.warning, TerminalColors.YELLOW, f"No suborganizations found for {federal_agency}"
+ )
return
# Check if we need to update any existing suborgs first. This step is optional.
@@ -116,13 +128,17 @@ class Command(BaseCommand):
if name.lower() == portfolio.organization_name.lower():
# If the suborg name is a portfolio name that currently exists, thats not a suborg - thats the portfolio itself!
# In this case, we can use this as an opportunity to update address information.
- self._update_portfolio_location_details(portfolio, valid_agencies.filter(organization_name=name).first())
+ self._update_portfolio_location_details(
+ portfolio, valid_agencies.filter(organization_name=name).first()
+ )
else:
new_suborgs.append(Suborganization(name=name, portfolio=portfolio))
if new_suborgs:
Suborganization.objects.bulk_create(new_suborgs)
- TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, f"Added {len(new_suborgs)} suborganizations")
+ TerminalHelper.colorful_logger(
+ logger.info, TerminalColors.OKGREEN, f"Added {len(new_suborgs)} suborganizations"
+ )
else:
TerminalHelper.colorful_logger(logger.warning, TerminalColors.YELLOW, "No suborganizations added")
diff --git a/src/registrar/tests/common.py b/src/registrar/tests/common.py
index bcd45f103..78cd1aafb 100644
--- a/src/registrar/tests/common.py
+++ b/src/registrar/tests/common.py
@@ -911,6 +911,8 @@ def completed_domain_request( # noqa
federal_type=None,
action_needed_reason=None,
portfolio=None,
+ organization_name=None,
+ city=None,
):
"""A completed domain request."""
if not user:
@@ -954,7 +956,7 @@ def completed_domain_request( # noqa
federal_type="executive",
purpose="Purpose of the site",
is_policy_acknowledged=True,
- organization_name="Testorg",
+ organization_name=organization_name if organization_name else "Testorg",
address_line1="address 1",
address_line2="address 2",
state_territory="NY",
@@ -984,6 +986,9 @@ def completed_domain_request( # noqa
if portfolio:
domain_request_kwargs["portfolio"] = portfolio
+ if city:
+ domain_request_kwargs["city"] = city
+
domain_request, _ = DomainRequest.objects.get_or_create(**domain_request_kwargs)
if has_other_contacts:
diff --git a/src/registrar/tests/test_management_scripts.py b/src/registrar/tests/test_management_scripts.py
index f9c544bfe..77822a022 100644
--- a/src/registrar/tests/test_management_scripts.py
+++ b/src/registrar/tests/test_management_scripts.py
@@ -1,4 +1,5 @@
import copy
+import boto3_mocking # type: ignore
from datetime import date, datetime, time
from django.core.management import call_command
from django.test import TestCase, override_settings
@@ -8,6 +9,7 @@ from django.utils import timezone
from django.utils.module_loading import import_string
import logging
import pyzipper
+from django.core.management.base import CommandError
from registrar.management.commands.clean_tables import Command as CleanTablesCommand
from registrar.management.commands.export_tables import Command as ExportTablesCommand
from registrar.models import (
@@ -23,14 +25,17 @@ from registrar.models import (
VerifiedByStaff,
PublicContact,
FederalAgency,
+ Portfolio,
+ Suborganization,
)
import tablib
from unittest.mock import patch, call, MagicMock, mock_open
from epplibwrapper import commands, common
-from .common import MockEppLib, less_console_noise, completed_domain_request
+from .common import MockEppLib, less_console_noise, completed_domain_request, MockSESClient
from api.tests.common import less_console_noise_decorator
+
logger = logging.getLogger(__name__)
@@ -1411,23 +1416,125 @@ class TestPopulateFederalAgencyInitialsAndFceb(TestCase):
class TestCreateFederalPortfolio(TestCase):
- def setUp(self):
- self.csv_path = "registrar/tests/data/fake_federal_cio.csv"
- # Create test FederalAgency objects
- self.agency1, _ = FederalAgency.objects.get_or_create(agency="American Battle Monuments Commission")
- self.agency2, _ = FederalAgency.objects.get_or_create(agency="Advisory Council on Historic Preservation")
- self.agency3, _ = FederalAgency.objects.get_or_create(agency="AMTRAK")
- self.agency4, _ = FederalAgency.objects.get_or_create(agency="John F. Kennedy Center for Performing Arts")
+ @less_console_noise_decorator
+ def setUp(self):
+ self.mock_client = MockSESClient()
+ self.user = User.objects.create(username="testuser")
+ self.federal_agency = FederalAgency.objects.create(agency="Test Federal Agency")
+ with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
+ self.domain_request = completed_domain_request(
+ status=DomainRequest.DomainRequestStatus.IN_REVIEW,
+ generic_org_type=DomainRequest.OrganizationChoices.FEDERAL,
+ federal_agency=self.federal_agency,
+ user=self.user,
+ city="WrongCity",
+ )
+ self.domain_request.approve()
+ self.domain_info = DomainInformation.objects.filter(domain_request=self.domain_request).get()
+
+ self.domain_request_2 = completed_domain_request(
+ name="sock@igorville.org",
+ status=DomainRequest.DomainRequestStatus.IN_REVIEW,
+ generic_org_type=DomainRequest.OrganizationChoices.FEDERAL,
+ federal_agency=self.federal_agency,
+ user=self.user,
+ organization_name="Test Federal Agency",
+ city="Block",
+ )
+ self.domain_request_2.approve()
+ self.domain_info_2 = DomainInformation.objects.filter(domain_request=self.domain_request_2).get()
def tearDown(self):
- SeniorOfficial.objects.all().delete()
+ DomainInformation.objects.all().delete()
+ DomainRequest.objects.all().delete()
+ Suborganization.objects.all().delete()
+ Portfolio.objects.all().delete()
FederalAgency.objects.all().delete()
-
- # == create_or_modify_portfolio tests == #
- # == create_suborganizations tests == #
- # == handle_portfolio_requests tests == #
- # == handle_portfolio_domains tests == #
- # test for parse_requests
- # test for parse_domains
- # test for both
+ User.objects.all().delete()
+
+ @less_console_noise_decorator
+ def run_create_federal_portfolio(self, agency_name, parse_requests=False, parse_domains=False):
+ with patch(
+ "registrar.management.commands.utility.terminal_helper.TerminalHelper.query_yes_no_exit",
+ return_value=True,
+ ):
+ call_command(
+ "create_federal_portfolio", agency_name, parse_requests=parse_requests, parse_domains=parse_domains
+ )
+
+ def test_create_or_modify_portfolio(self):
+ self.run_create_federal_portfolio("Test Federal Agency", parse_requests=True)
+
+ portfolio = Portfolio.objects.get(federal_agency=self.federal_agency)
+ self.assertEqual(portfolio.organization_name, self.federal_agency.agency)
+ self.assertEqual(portfolio.organization_type, DomainRequest.OrganizationChoices.FEDERAL)
+ self.assertEqual(portfolio.creator, User.get_default_user())
+ self.assertEqual(portfolio.notes, "Auto-generated record")
+
+ # Test the suborgs
+ suborganizations = Suborganization.objects.filter(portfolio__federal_agency=self.federal_agency)
+ self.assertEqual(suborganizations.count(), 1)
+ self.assertEqual(suborganizations.first().name, "Testorg")
+
+ # Test other address information
+ self.assertEqual(portfolio.address_line1, "address 1")
+ self.assertEqual(portfolio.city, "Block")
+ self.assertEqual(portfolio.state_territory, "NY")
+ self.assertEqual(portfolio.zipcode, "10002")
+
+ def test_handle_portfolio_requests(self):
+ self.run_create_federal_portfolio("Test Federal Agency", parse_requests=True)
+
+ self.domain_request.refresh_from_db()
+ self.assertIsNotNone(self.domain_request.portfolio)
+ self.assertEqual(self.domain_request.portfolio.federal_agency, self.federal_agency)
+
+ def test_handle_portfolio_domains(self):
+ self.run_create_federal_portfolio("Test Federal Agency", parse_domains=True)
+
+ self.domain_info.refresh_from_db()
+ self.assertIsNotNone(self.domain_info.portfolio)
+ self.assertEqual(self.domain_info.portfolio.federal_agency, self.federal_agency)
+
+ def test_handle_parse_both(self):
+ self.run_create_federal_portfolio("Test Federal Agency", parse_requests=True, parse_domains=True)
+
+ self.domain_request.refresh_from_db()
+ self.domain_info.refresh_from_db()
+ self.assertIsNotNone(self.domain_request.portfolio)
+ self.assertIsNotNone(self.domain_info.portfolio)
+ self.assertEqual(self.domain_request.portfolio, self.domain_info.portfolio)
+
+ def test_command_error_no_parse_options(self):
+ with self.assertRaisesRegex(
+ CommandError, "You must specify at least one of --parse_requests or --parse_domains."
+ ):
+ self.run_create_federal_portfolio("Test Federal Agency")
+
+ def test_command_error_agency_not_found(self):
+ expected_message = (
+ "Cannot find the federal agency 'Non-existent Agency' in our database. "
+ "The value you enter for `agency_name` must be prepopulated in the FederalAgency table before proceeding."
+ )
+ with self.assertRaisesRegex(ValueError, expected_message):
+ self.run_create_federal_portfolio("Non-existent Agency", parse_requests=True)
+
+ def test_update_existing_portfolio(self):
+ # Create an existing portfolio
+ existing_portfolio = Portfolio.objects.create(
+ federal_agency=self.federal_agency,
+ organization_name="Test Federal Agency",
+ organization_type=DomainRequest.OrganizationChoices.CITY,
+ creator=self.user,
+ notes="Old notes",
+ )
+
+ self.run_create_federal_portfolio("Test Federal Agency", parse_requests=True)
+
+ existing_portfolio.refresh_from_db()
+ self.assertEqual(existing_portfolio.organization_name, self.federal_agency.agency)
+ self.assertEqual(existing_portfolio.organization_type, DomainRequest.OrganizationChoices.FEDERAL)
+ # Notes and creator should be untouched
+ self.assertEqual(existing_portfolio.notes, "Old notes")
+ self.assertEqual(existing_portfolio.creator, self.user)
From f2288673a02851ab8714a9f2541bf516e653d16a Mon Sep 17 00:00:00 2001
From: zandercymatics <141044360+zandercymatics@users.noreply.github.com>
Date: Thu, 29 Aug 2024 15:18:14 -0600
Subject: [PATCH 037/150] Update create_federal_portfolio.py
---
.../management/commands/create_federal_portfolio.py | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/registrar/management/commands/create_federal_portfolio.py b/src/registrar/management/commands/create_federal_portfolio.py
index 4ca6ba17f..bf4297705 100644
--- a/src/registrar/management/commands/create_federal_portfolio.py
+++ b/src/registrar/management/commands/create_federal_portfolio.py
@@ -193,7 +193,14 @@ class Command(BaseCommand):
Associate portfolio with domain requests for a federal agency.
Updates all relevant domain request records.
"""
- domain_requests = DomainInformation.objects.filter(federal_agency=federal_agency)
+ invalid_states = [
+ DomainRequest.DomainRequestStatus.STARTED,
+ DomainRequest.DomainRequestStatus.INELIGIBLE,
+ DomainRequest.DomainRequestStatus.REJECTED,
+ ]
+ domain_requests = DomainRequest.objects.filter(
+ federal_agency=federal_agency
+ ).exclude(status__in=invalid_states)
if not domain_requests.exists():
message = "Portfolios not added to domain requests: no valid records found"
TerminalHelper.colorful_logger(logger.info, TerminalColors.YELLOW, message)
From d8790448ab4cfb900d8a0cfda06a46e383fcd637 Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Thu, 29 Aug 2024 15:45:46 -0700
Subject: [PATCH 038/150] Delete submitter contacts
---
.../0121_delete_cascade_submitter_contacts.py | 22 +++++++++++++
...ve_domaininformation_submitter_and_more.py | 33 -------------------
2 files changed, 22 insertions(+), 33 deletions(-)
create mode 100644 src/registrar/migrations/0121_delete_cascade_submitter_contacts.py
delete mode 100644 src/registrar/migrations/0121_remove_domaininformation_submitter_and_more.py
diff --git a/src/registrar/migrations/0121_delete_cascade_submitter_contacts.py b/src/registrar/migrations/0121_delete_cascade_submitter_contacts.py
new file mode 100644
index 000000000..434accd44
--- /dev/null
+++ b/src/registrar/migrations/0121_delete_cascade_submitter_contacts.py
@@ -0,0 +1,22 @@
+from django.db import migrations
+from typing import Any
+
+# Deletes Contact objects associated with a submitter which we are deprecating
+def cascade_delete_submitter_contacts(apps, schema_editor) -> Any:
+ contacts_model = apps.get_model("registrar", "Contact")
+ submitter_contacts = contacts_model.objects.filter(submitted_domain_requests__isnull=False)
+ submitter_contacts.delete()
+
+
+class Migration(migrations.Migration):
+ dependencies = [
+ ("registrar", "0120_add_domainrequest_submission_dates"),
+ ]
+
+ operations = [
+ migrations.RunPython(
+ cascade_delete_submitter_contacts,
+ reverse_code=migrations.RunPython.noop,
+ atomic=True
+ ),
+ ]
\ No newline at end of file
diff --git a/src/registrar/migrations/0121_remove_domaininformation_submitter_and_more.py b/src/registrar/migrations/0121_remove_domaininformation_submitter_and_more.py
deleted file mode 100644
index 91c392290..000000000
--- a/src/registrar/migrations/0121_remove_domaininformation_submitter_and_more.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# Generated by Django 4.2.10 on 2024-08-26 18:45
-
-from django.conf import settings
-from django.db import migrations, models
-import django.db.models.deletion
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ("registrar", "0120_add_domainrequest_submission_dates"),
- ]
-
- operations = [
- migrations.RemoveField(
- model_name="domaininformation",
- name="submitter",
- ),
- migrations.RemoveField(
- model_name="domainrequest",
- name="submitter",
- ),
- migrations.AlterField(
- model_name="domainrequest",
- name="creator",
- field=models.ForeignKey(
- help_text="Person who submitted the domain request. Will receive email updates.",
- on_delete=django.db.models.deletion.PROTECT,
- related_name="domain_requests_created",
- to=settings.AUTH_USER_MODEL,
- ),
- ),
- ]
From be54f8c4059ef0e19b4d890a1bf0b5320f4841de Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Thu, 29 Aug 2024 15:46:48 -0700
Subject: [PATCH 039/150] Add delete domain info migration
---
...ve_domaininformation_submitter_and_more.py | 33 +++++++++++++++++++
1 file changed, 33 insertions(+)
create mode 100644 src/registrar/migrations/0122_remove_domaininformation_submitter_and_more.py
diff --git a/src/registrar/migrations/0122_remove_domaininformation_submitter_and_more.py b/src/registrar/migrations/0122_remove_domaininformation_submitter_and_more.py
new file mode 100644
index 000000000..d8d6b7e32
--- /dev/null
+++ b/src/registrar/migrations/0122_remove_domaininformation_submitter_and_more.py
@@ -0,0 +1,33 @@
+# Generated by Django 4.2.10 on 2024-08-29 22:44
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("registrar", "0121_delete_cascade_submitter_contacts"),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name="domaininformation",
+ name="submitter",
+ ),
+ migrations.RemoveField(
+ model_name="domainrequest",
+ name="submitter",
+ ),
+ migrations.AlterField(
+ model_name="domainrequest",
+ name="creator",
+ field=models.ForeignKey(
+ help_text="Person who submitted the domain request. Will receive email updates.",
+ on_delete=django.db.models.deletion.PROTECT,
+ related_name="domain_requests_created",
+ to=settings.AUTH_USER_MODEL,
+ ),
+ ),
+ ]
From 76e35db66352e300a5e101d648b1733227543a00 Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Thu, 29 Aug 2024 15:50:28 -0700
Subject: [PATCH 040/150] Fix linting
---
.../migrations/0121_delete_cascade_submitter_contacts.py | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/src/registrar/migrations/0121_delete_cascade_submitter_contacts.py b/src/registrar/migrations/0121_delete_cascade_submitter_contacts.py
index 434accd44..d6ed2dfa5 100644
--- a/src/registrar/migrations/0121_delete_cascade_submitter_contacts.py
+++ b/src/registrar/migrations/0121_delete_cascade_submitter_contacts.py
@@ -1,6 +1,7 @@
from django.db import migrations
from typing import Any
+
# Deletes Contact objects associated with a submitter which we are deprecating
def cascade_delete_submitter_contacts(apps, schema_editor) -> Any:
contacts_model = apps.get_model("registrar", "Contact")
@@ -14,9 +15,5 @@ class Migration(migrations.Migration):
]
operations = [
- migrations.RunPython(
- cascade_delete_submitter_contacts,
- reverse_code=migrations.RunPython.noop,
- atomic=True
- ),
- ]
\ No newline at end of file
+ migrations.RunPython(cascade_delete_submitter_contacts, reverse_code=migrations.RunPython.noop, atomic=True),
+ ]
From d66c75a75dc214eac2fad8f5ec18339b39af701a Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Thu, 29 Aug 2024 16:18:39 -0700
Subject: [PATCH 041/150] Add migration changing submitted to cascade on delete
---
...er_domaininformation_submitter_and_more.py | 38 +++++++++++++++++++
1 file changed, 38 insertions(+)
create mode 100644 src/registrar/migrations/0121_alter_domaininformation_submitter_and_more.py
diff --git a/src/registrar/migrations/0121_alter_domaininformation_submitter_and_more.py b/src/registrar/migrations/0121_alter_domaininformation_submitter_and_more.py
new file mode 100644
index 000000000..178c6e666
--- /dev/null
+++ b/src/registrar/migrations/0121_alter_domaininformation_submitter_and_more.py
@@ -0,0 +1,38 @@
+# Generated by Django 4.2.10 on 2024-08-29 23:17
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("registrar", "0120_add_domainrequest_submission_dates"),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name="domaininformation",
+ name="submitter",
+ field=models.ForeignKey(
+ blank=True,
+ help_text='Person listed under "your contact information" in the request form',
+ null=True,
+ on_delete=django.db.models.deletion.CASCADE,
+ related_name="submitted_domain_requests_information",
+ to="registrar.contact",
+ ),
+ ),
+ migrations.AlterField(
+ model_name="domainrequest",
+ name="submitter",
+ field=models.ForeignKey(
+ blank=True,
+ help_text='Person listed under "your contact information" in the request form; will receive email updates',
+ null=True,
+ on_delete=django.db.models.deletion.CASCADE,
+ related_name="submitted_domain_requests",
+ to="registrar.contact",
+ ),
+ ),
+ ]
From 8db9ccda5d4d88b18aa5ef7b55fd1cf5567f6716 Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Thu, 29 Aug 2024 16:25:35 -0700
Subject: [PATCH 042/150] Rename migrations
---
...tter_contacts.py => 0122_delete_cascade_submitter_contacts.py} | 0
...ore.py => 0123_remove_domaininformation_submitter_and_more.py} | 0
2 files changed, 0 insertions(+), 0 deletions(-)
rename src/registrar/migrations/{0121_delete_cascade_submitter_contacts.py => 0122_delete_cascade_submitter_contacts.py} (100%)
rename src/registrar/migrations/{0122_remove_domaininformation_submitter_and_more.py => 0123_remove_domaininformation_submitter_and_more.py} (100%)
diff --git a/src/registrar/migrations/0121_delete_cascade_submitter_contacts.py b/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py
similarity index 100%
rename from src/registrar/migrations/0121_delete_cascade_submitter_contacts.py
rename to src/registrar/migrations/0122_delete_cascade_submitter_contacts.py
diff --git a/src/registrar/migrations/0122_remove_domaininformation_submitter_and_more.py b/src/registrar/migrations/0123_remove_domaininformation_submitter_and_more.py
similarity index 100%
rename from src/registrar/migrations/0122_remove_domaininformation_submitter_and_more.py
rename to src/registrar/migrations/0123_remove_domaininformation_submitter_and_more.py
From 5d1f86f2332f3430e93e4e47110977dad1ad6bbd Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Thu, 29 Aug 2024 16:32:21 -0700
Subject: [PATCH 043/150] Correct migration dependency
---
.../0123_remove_domaininformation_submitter_and_more.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/registrar/migrations/0123_remove_domaininformation_submitter_and_more.py b/src/registrar/migrations/0123_remove_domaininformation_submitter_and_more.py
index d8d6b7e32..aeaed494d 100644
--- a/src/registrar/migrations/0123_remove_domaininformation_submitter_and_more.py
+++ b/src/registrar/migrations/0123_remove_domaininformation_submitter_and_more.py
@@ -8,7 +8,7 @@ import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
- ("registrar", "0121_delete_cascade_submitter_contacts"),
+ ("registrar", "0122_delete_cascade_submitter_contacts"),
]
operations = [
From 017130143b06317287268b170f3ad66e4a66ec48 Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Thu, 29 Aug 2024 16:38:32 -0700
Subject: [PATCH 044/150] Correct migration dependencies
---
.../migrations/0122_delete_cascade_submitter_contacts.py | 2 +-
.../0123_remove_domaininformation_submitter_and_more.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py b/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py
index d6ed2dfa5..5002be293 100644
--- a/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py
+++ b/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py
@@ -11,7 +11,7 @@ def cascade_delete_submitter_contacts(apps, schema_editor) -> Any:
class Migration(migrations.Migration):
dependencies = [
- ("registrar", "0120_add_domainrequest_submission_dates"),
+ ("registrar", "0121_alter_domaininformation_submitter_and_more"),
]
operations = [
diff --git a/src/registrar/migrations/0123_remove_domaininformation_submitter_and_more.py b/src/registrar/migrations/0123_remove_domaininformation_submitter_and_more.py
index aeaed494d..dcad2885e 100644
--- a/src/registrar/migrations/0123_remove_domaininformation_submitter_and_more.py
+++ b/src/registrar/migrations/0123_remove_domaininformation_submitter_and_more.py
@@ -1,4 +1,4 @@
-# Generated by Django 4.2.10 on 2024-08-29 22:44
+# Generated by Django 4.2.10 on 2024-08-29 24:13
from django.conf import settings
from django.db import migrations, models
From d0c598f3538f0f5218d537e0cc16314202883608 Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Thu, 29 Aug 2024 16:47:04 -0700
Subject: [PATCH 045/150] Correct cascade delete migration
---
.../migrations/0122_delete_cascade_submitter_contacts.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py b/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py
index 5002be293..8f2a453bd 100644
--- a/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py
+++ b/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py
@@ -5,7 +5,7 @@ from typing import Any
# Deletes Contact objects associated with a submitter which we are deprecating
def cascade_delete_submitter_contacts(apps, schema_editor) -> Any:
contacts_model = apps.get_model("registrar", "Contact")
- submitter_contacts = contacts_model.objects.filter(submitted_domain_requests__isnull=False)
+ submitter_contacts = contacts_model.objects.filter(submitted_domain_requests__isnull=False) | contacts_model.objects.filter(submitted_domain_requests_information__isnull=False)
submitter_contacts.delete()
From bf83a15fc496f2b4b3a487c4861307cef6de66d1 Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Thu, 29 Aug 2024 16:48:06 -0700
Subject: [PATCH 046/150] Fix linting
---
.../migrations/0122_delete_cascade_submitter_contacts.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py b/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py
index 8f2a453bd..6bbe1e456 100644
--- a/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py
+++ b/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py
@@ -5,7 +5,9 @@ from typing import Any
# Deletes Contact objects associated with a submitter which we are deprecating
def cascade_delete_submitter_contacts(apps, schema_editor) -> Any:
contacts_model = apps.get_model("registrar", "Contact")
- submitter_contacts = contacts_model.objects.filter(submitted_domain_requests__isnull=False) | contacts_model.objects.filter(submitted_domain_requests_information__isnull=False)
+ submitter_contacts = contacts_model.objects.filter(
+ submitted_domain_requests__isnull=False
+ ) | contacts_model.objects.filter(submitted_domain_requests_information__isnull=False)
submitter_contacts.delete()
From 6272dab45514b1cf3d9b79b20d248338353e2ffd Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Thu, 29 Aug 2024 16:54:45 -0700
Subject: [PATCH 047/150] Fix cascade migration
---
.../migrations/0122_delete_cascade_submitter_contacts.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py b/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py
index 6bbe1e456..9d65c661b 100644
--- a/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py
+++ b/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py
@@ -1,13 +1,13 @@
from django.db import migrations
+from django.db.models import Q
from typing import Any
# Deletes Contact objects associated with a submitter which we are deprecating
def cascade_delete_submitter_contacts(apps, schema_editor) -> Any:
contacts_model = apps.get_model("registrar", "Contact")
- submitter_contacts = contacts_model.objects.filter(
- submitted_domain_requests__isnull=False
- ) | contacts_model.objects.filter(submitted_domain_requests_information__isnull=False)
+ submitter_contacts = contacts_model.objects.filter(Q(submitted_domain_requests__isnull=False)
+ | Q(submitted_domain_requests_information__isnull=False))
submitter_contacts.delete()
From c4c5ae87f9c9c7e3f8dd16c3fc88723f360ee8d4 Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Thu, 29 Aug 2024 16:55:46 -0700
Subject: [PATCH 048/150] Fix linting
---
.../migrations/0122_delete_cascade_submitter_contacts.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py b/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py
index 9d65c661b..e7ba24eb4 100644
--- a/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py
+++ b/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py
@@ -6,8 +6,9 @@ from typing import Any
# Deletes Contact objects associated with a submitter which we are deprecating
def cascade_delete_submitter_contacts(apps, schema_editor) -> Any:
contacts_model = apps.get_model("registrar", "Contact")
- submitter_contacts = contacts_model.objects.filter(Q(submitted_domain_requests__isnull=False)
- | Q(submitted_domain_requests_information__isnull=False))
+ submitter_contacts = contacts_model.objects.filter(
+ Q(submitted_domain_requests__isnull=False) | Q(submitted_domain_requests_information__isnull=False)
+ )
submitter_contacts.delete()
From cf86579467705ad2aa7688457b2c0ad1a9634250 Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Thu, 29 Aug 2024 17:23:32 -0700
Subject: [PATCH 049/150] Add more conditions to cascade delete
---
.../migrations/0122_delete_cascade_submitter_contacts.py | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py b/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py
index e7ba24eb4..b43639187 100644
--- a/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py
+++ b/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py
@@ -7,7 +7,12 @@ from typing import Any
def cascade_delete_submitter_contacts(apps, schema_editor) -> Any:
contacts_model = apps.get_model("registrar", "Contact")
submitter_contacts = contacts_model.objects.filter(
- Q(submitted_domain_requests__isnull=False) | Q(submitted_domain_requests_information__isnull=False)
+ Q(submitted_domain_requests__isnull=False)
+ | Q(submitted_domain_requests_information__isnull=False)
+ | Q(information_senior_official__isnull=True)
+ | Q(senior_official__isnull=True)
+ | Q(contact_domain_requests_information__isnull=True)
+ | Q(contact_domain_requests__isnull=True)
)
submitter_contacts.delete()
From 17dd4dd2717f7d60adfc05efe68cad00e3d4964b Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Thu, 29 Aug 2024 17:35:22 -0700
Subject: [PATCH 050/150] Add filter
---
.../migrations/0122_delete_cascade_submitter_contacts.py | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py b/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py
index b43639187..e37ddce7b 100644
--- a/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py
+++ b/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py
@@ -9,10 +9,7 @@ def cascade_delete_submitter_contacts(apps, schema_editor) -> Any:
submitter_contacts = contacts_model.objects.filter(
Q(submitted_domain_requests__isnull=False)
| Q(submitted_domain_requests_information__isnull=False)
- | Q(information_senior_official__isnull=True)
- | Q(senior_official__isnull=True)
- | Q(contact_domain_requests_information__isnull=True)
- | Q(contact_domain_requests__isnull=True)
+ ).filter(information_senior_official__isnull=True, senior_official__isnull=True, contact_domain_requests_information__isnull=True, contact_domain_requests__isnull=True
)
submitter_contacts.delete()
From 79f020b40217109f251690e9c531b2309ead7127 Mon Sep 17 00:00:00 2001
From: Erin Song <121973038+erinysong@users.noreply.github.com>
Date: Thu, 29 Aug 2024 17:36:08 -0700
Subject: [PATCH 051/150] Fix linting
---
.../migrations/0122_delete_cascade_submitter_contacts.py | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py b/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py
index e37ddce7b..0d3988421 100644
--- a/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py
+++ b/src/registrar/migrations/0122_delete_cascade_submitter_contacts.py
@@ -7,9 +7,12 @@ from typing import Any
def cascade_delete_submitter_contacts(apps, schema_editor) -> Any:
contacts_model = apps.get_model("registrar", "Contact")
submitter_contacts = contacts_model.objects.filter(
- Q(submitted_domain_requests__isnull=False)
- | Q(submitted_domain_requests_information__isnull=False)
- ).filter(information_senior_official__isnull=True, senior_official__isnull=True, contact_domain_requests_information__isnull=True, contact_domain_requests__isnull=True
+ Q(submitted_domain_requests__isnull=False) | Q(submitted_domain_requests_information__isnull=False)
+ ).filter(
+ information_senior_official__isnull=True,
+ senior_official__isnull=True,
+ contact_domain_requests_information__isnull=True,
+ contact_domain_requests__isnull=True,
)
submitter_contacts.delete()
From b3b415b56347f5f8f8fa693ef9ca4320912f2190 Mon Sep 17 00:00:00 2001
From: zandercymatics <141044360+zandercymatics@users.noreply.github.com>
Date: Fri, 30 Aug 2024 08:40:04 -0600
Subject: [PATCH 052/150] Remove logic for location information
---
.../commands/create_federal_portfolio.py | 40 +++++--------------
src/registrar/tests/common.py | 4 --
.../tests/test_management_scripts.py | 18 ++++-----
3 files changed, 18 insertions(+), 44 deletions(-)
diff --git a/src/registrar/management/commands/create_federal_portfolio.py b/src/registrar/management/commands/create_federal_portfolio.py
index bf4297705..219044fc5 100644
--- a/src/registrar/management/commands/create_federal_portfolio.py
+++ b/src/registrar/management/commands/create_federal_portfolio.py
@@ -98,6 +98,7 @@ class Command(BaseCommand):
# Update everything else
for key, value in portfolio_args.items():
setattr(portfolio, key, value)
+
portfolio.save()
message = f"Modified portfolio '{portfolio}'"
TerminalHelper.colorful_logger(logger.info, TerminalColors.MAGENTA, message)
@@ -126,11 +127,13 @@ class Command(BaseCommand):
new_suborgs = []
for name in org_names - set(existing_suborgs.values_list("name", flat=True)):
if name.lower() == portfolio.organization_name.lower():
- # If the suborg name is a portfolio name that currently exists, thats not a suborg - thats the portfolio itself!
- # In this case, we can use this as an opportunity to update address information.
- self._update_portfolio_location_details(
- portfolio, valid_agencies.filter(organization_name=name).first()
+ # You can use this to populate location information, when this occurs.
+ # However, this isn't needed for now so we can skip it.
+ message = (
+ f"Skipping suborganization create on record '{name}'. "
+ f"The federal agency name is the same as the portfolio name."
)
+ TerminalHelper.colorful_logger(logger.warning, TerminalColors.YELLOW, message)
else:
new_suborgs.append(Suborganization(name=name, portfolio=portfolio))
@@ -165,42 +168,17 @@ class Command(BaseCommand):
message = f"Updated {len(orgs_to_update)} suborganizations"
TerminalHelper.colorful_logger(logger.info, TerminalColors.MAGENTA, message)
- def _update_portfolio_location_details(self, portfolio: Portfolio, domain_info: DomainInformation):
- """
- Update portfolio location details based on DomainInformation.
- Copies relevant fields and saves the portfolio.
- """
- location_props = [
- "address_line1",
- "address_line2",
- "city",
- "state_territory",
- "zipcode",
- "urbanization",
- ]
-
- for prop_name in location_props:
- # Copy the value from the domain info object to the portfolio object
- value = getattr(domain_info, prop_name)
- setattr(portfolio, prop_name, value)
-
- portfolio.save()
- message = f"Updated location details on portfolio '{portfolio}'"
- TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
-
def handle_portfolio_requests(self, portfolio: Portfolio, federal_agency: FederalAgency):
"""
Associate portfolio with domain requests for a federal agency.
Updates all relevant domain request records.
"""
invalid_states = [
- DomainRequest.DomainRequestStatus.STARTED,
+ DomainRequest.DomainRequestStatus.STARTED,
DomainRequest.DomainRequestStatus.INELIGIBLE,
DomainRequest.DomainRequestStatus.REJECTED,
]
- domain_requests = DomainRequest.objects.filter(
- federal_agency=federal_agency
- ).exclude(status__in=invalid_states)
+ domain_requests = DomainRequest.objects.filter(federal_agency=federal_agency).exclude(status__in=invalid_states)
if not domain_requests.exists():
message = "Portfolios not added to domain requests: no valid records found"
TerminalHelper.colorful_logger(logger.info, TerminalColors.YELLOW, message)
diff --git a/src/registrar/tests/common.py b/src/registrar/tests/common.py
index 78cd1aafb..5e418da2b 100644
--- a/src/registrar/tests/common.py
+++ b/src/registrar/tests/common.py
@@ -912,7 +912,6 @@ def completed_domain_request( # noqa
action_needed_reason=None,
portfolio=None,
organization_name=None,
- city=None,
):
"""A completed domain request."""
if not user:
@@ -986,9 +985,6 @@ def completed_domain_request( # noqa
if portfolio:
domain_request_kwargs["portfolio"] = portfolio
- if city:
- domain_request_kwargs["city"] = city
-
domain_request, _ = DomainRequest.objects.get_or_create(**domain_request_kwargs)
if has_other_contacts:
diff --git a/src/registrar/tests/test_management_scripts.py b/src/registrar/tests/test_management_scripts.py
index 77822a022..5c049ac56 100644
--- a/src/registrar/tests/test_management_scripts.py
+++ b/src/registrar/tests/test_management_scripts.py
@@ -1422,13 +1422,15 @@ class TestCreateFederalPortfolio(TestCase):
self.mock_client = MockSESClient()
self.user = User.objects.create(username="testuser")
self.federal_agency = FederalAgency.objects.create(agency="Test Federal Agency")
+ self.senior_official = SeniorOfficial.objects.create(
+ first_name="first", last_name="last", email="testuser@igorville.gov", federal_agency=self.federal_agency
+ )
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
self.domain_request = completed_domain_request(
status=DomainRequest.DomainRequestStatus.IN_REVIEW,
- generic_org_type=DomainRequest.OrganizationChoices.FEDERAL,
+ generic_org_type=DomainRequest.OrganizationChoices.CITY,
federal_agency=self.federal_agency,
user=self.user,
- city="WrongCity",
)
self.domain_request.approve()
self.domain_info = DomainInformation.objects.filter(domain_request=self.domain_request).get()
@@ -1436,11 +1438,10 @@ class TestCreateFederalPortfolio(TestCase):
self.domain_request_2 = completed_domain_request(
name="sock@igorville.org",
status=DomainRequest.DomainRequestStatus.IN_REVIEW,
- generic_org_type=DomainRequest.OrganizationChoices.FEDERAL,
+ generic_org_type=DomainRequest.OrganizationChoices.CITY,
federal_agency=self.federal_agency,
user=self.user,
organization_name="Test Federal Agency",
- city="Block",
)
self.domain_request_2.approve()
self.domain_info_2 = DomainInformation.objects.filter(domain_request=self.domain_request_2).get()
@@ -1450,6 +1451,7 @@ class TestCreateFederalPortfolio(TestCase):
DomainRequest.objects.all().delete()
Suborganization.objects.all().delete()
Portfolio.objects.all().delete()
+ SeniorOfficial.objects.all().delete()
FederalAgency.objects.all().delete()
User.objects.all().delete()
@@ -1477,11 +1479,8 @@ class TestCreateFederalPortfolio(TestCase):
self.assertEqual(suborganizations.count(), 1)
self.assertEqual(suborganizations.first().name, "Testorg")
- # Test other address information
- self.assertEqual(portfolio.address_line1, "address 1")
- self.assertEqual(portfolio.city, "Block")
- self.assertEqual(portfolio.state_territory, "NY")
- self.assertEqual(portfolio.zipcode, "10002")
+ # Test the senior official
+ self.assertEqual(portfolio.senior_official, self.senior_official)
def test_handle_portfolio_requests(self):
self.run_create_federal_portfolio("Test Federal Agency", parse_requests=True)
@@ -1535,6 +1534,7 @@ class TestCreateFederalPortfolio(TestCase):
existing_portfolio.refresh_from_db()
self.assertEqual(existing_portfolio.organization_name, self.federal_agency.agency)
self.assertEqual(existing_portfolio.organization_type, DomainRequest.OrganizationChoices.FEDERAL)
+
# Notes and creator should be untouched
self.assertEqual(existing_portfolio.notes, "Old notes")
self.assertEqual(existing_portfolio.creator, self.user)
From 47b7ee45cc3cf3442a7386aab9aafffd5eb5db4e Mon Sep 17 00:00:00 2001
From: zandercymatics <141044360+zandercymatics@users.noreply.github.com>
Date: Fri, 30 Aug 2024 09:31:55 -0600
Subject: [PATCH 053/150] lint
---
.../management/commands/create_federal_portfolio.py | 7 +++++--
src/registrar/tests/test_management_scripts.py | 7 +++++++
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/src/registrar/management/commands/create_federal_portfolio.py b/src/registrar/management/commands/create_federal_portfolio.py
index 219044fc5..017854b91 100644
--- a/src/registrar/management/commands/create_federal_portfolio.py
+++ b/src/registrar/management/commands/create_federal_portfolio.py
@@ -81,7 +81,8 @@ class Command(BaseCommand):
else:
proceed = TerminalHelper.prompt_for_execution(
system_exit_on_terminate=False,
- info_to_inspect=f"""The given portfolio '{federal_agency.agency}' already exists in our DB.
+ info_to_inspect=f"""
+ The given portfolio '{federal_agency.agency}' already exists in our DB.
If you cancel, the rest of the script will still execute but this record will not update.
""",
prompt_title="Do you wish to modify this record?",
@@ -126,7 +127,9 @@ class Command(BaseCommand):
# Create new suborgs, as long as they don't exist in the db already
new_suborgs = []
for name in org_names - set(existing_suborgs.values_list("name", flat=True)):
- if name.lower() == portfolio.organization_name.lower():
+ # Stored in variables due to linter wanting type information here
+ portfolio_name: str = portfolio.organization_name if portfolio.organization_name is not None else ""
+ if name is not None and name.lower() == portfolio_name.lower():
# You can use this to populate location information, when this occurs.
# However, this isn't needed for now so we can skip it.
message = (
diff --git a/src/registrar/tests/test_management_scripts.py b/src/registrar/tests/test_management_scripts.py
index 5c049ac56..29db8a4c5 100644
--- a/src/registrar/tests/test_management_scripts.py
+++ b/src/registrar/tests/test_management_scripts.py
@@ -1466,6 +1466,7 @@ class TestCreateFederalPortfolio(TestCase):
)
def test_create_or_modify_portfolio(self):
+ """Test portfolio creation and modification with suborg and senior official."""
self.run_create_federal_portfolio("Test Federal Agency", parse_requests=True)
portfolio = Portfolio.objects.get(federal_agency=self.federal_agency)
@@ -1483,6 +1484,7 @@ class TestCreateFederalPortfolio(TestCase):
self.assertEqual(portfolio.senior_official, self.senior_official)
def test_handle_portfolio_requests(self):
+ """Verify portfolio association with domain requests."""
self.run_create_federal_portfolio("Test Federal Agency", parse_requests=True)
self.domain_request.refresh_from_db()
@@ -1490,6 +1492,7 @@ class TestCreateFederalPortfolio(TestCase):
self.assertEqual(self.domain_request.portfolio.federal_agency, self.federal_agency)
def test_handle_portfolio_domains(self):
+ """Check portfolio association with domain information."""
self.run_create_federal_portfolio("Test Federal Agency", parse_domains=True)
self.domain_info.refresh_from_db()
@@ -1497,6 +1500,7 @@ class TestCreateFederalPortfolio(TestCase):
self.assertEqual(self.domain_info.portfolio.federal_agency, self.federal_agency)
def test_handle_parse_both(self):
+ """Ensure correct parsing of both requests and domains."""
self.run_create_federal_portfolio("Test Federal Agency", parse_requests=True, parse_domains=True)
self.domain_request.refresh_from_db()
@@ -1506,12 +1510,14 @@ class TestCreateFederalPortfolio(TestCase):
self.assertEqual(self.domain_request.portfolio, self.domain_info.portfolio)
def test_command_error_no_parse_options(self):
+ """Verify error when no parse options are provided."""
with self.assertRaisesRegex(
CommandError, "You must specify at least one of --parse_requests or --parse_domains."
):
self.run_create_federal_portfolio("Test Federal Agency")
def test_command_error_agency_not_found(self):
+ """Check error handling for non-existent agency."""
expected_message = (
"Cannot find the federal agency 'Non-existent Agency' in our database. "
"The value you enter for `agency_name` must be prepopulated in the FederalAgency table before proceeding."
@@ -1520,6 +1526,7 @@ class TestCreateFederalPortfolio(TestCase):
self.run_create_federal_portfolio("Non-existent Agency", parse_requests=True)
def test_update_existing_portfolio(self):
+ """Test updating an existing portfolio."""
# Create an existing portfolio
existing_portfolio = Portfolio.objects.create(
federal_agency=self.federal_agency,
From db16ba284b412f80d1cfc3503bc317809e6d15a6 Mon Sep 17 00:00:00 2001
From: zandercymatics <141044360+zandercymatics@users.noreply.github.com>
Date: Fri, 30 Aug 2024 09:35:45 -0600
Subject: [PATCH 054/150] Update create_federal_portfolio.py
---
src/registrar/management/commands/create_federal_portfolio.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/registrar/management/commands/create_federal_portfolio.py b/src/registrar/management/commands/create_federal_portfolio.py
index 017854b91..d02762817 100644
--- a/src/registrar/management/commands/create_federal_portfolio.py
+++ b/src/registrar/management/commands/create_federal_portfolio.py
@@ -127,7 +127,7 @@ class Command(BaseCommand):
# Create new suborgs, as long as they don't exist in the db already
new_suborgs = []
for name in org_names - set(existing_suborgs.values_list("name", flat=True)):
- # Stored in variables due to linter wanting type information here
+ # Stored in variables due to linter wanting type information here.
portfolio_name: str = portfolio.organization_name if portfolio.organization_name is not None else ""
if name is not None and name.lower() == portfolio_name.lower():
# You can use this to populate location information, when this occurs.
@@ -138,7 +138,7 @@ class Command(BaseCommand):
)
TerminalHelper.colorful_logger(logger.warning, TerminalColors.YELLOW, message)
else:
- new_suborgs.append(Suborganization(name=name, portfolio=portfolio))
+ new_suborgs.append(Suborganization(name=name, portfolio=portfolio)) # type: ignore
if new_suborgs:
Suborganization.objects.bulk_create(new_suborgs)
From 02bc0cba1a942c90cec953d499fcc31db67698c5 Mon Sep 17 00:00:00 2001
From: zandercymatics <141044360+zandercymatics@users.noreply.github.com>
Date: Fri, 30 Aug 2024 09:49:43 -0600
Subject: [PATCH 055/150] Add suborg info to domains and requests
---
.../commands/create_federal_portfolio.py | 34 ++++++++++++-------
.../tests/test_management_scripts.py | 2 ++
2 files changed, 24 insertions(+), 12 deletions(-)
diff --git a/src/registrar/management/commands/create_federal_portfolio.py b/src/registrar/management/commands/create_federal_portfolio.py
index d02762817..cad318b57 100644
--- a/src/registrar/management/commands/create_federal_portfolio.py
+++ b/src/registrar/management/commands/create_federal_portfolio.py
@@ -185,13 +185,18 @@ class Command(BaseCommand):
if not domain_requests.exists():
message = "Portfolios not added to domain requests: no valid records found"
TerminalHelper.colorful_logger(logger.info, TerminalColors.YELLOW, message)
- else:
- for domain_request in domain_requests:
- domain_request.portfolio = portfolio
+ return None
+
+ # Get all suborg information and store it in a dict to avoid doing a db call
+ suborgs = Suborganization.objects.filter(portfolio=portfolio).in_bulk(field_name="name")
+ for domain_request in domain_requests:
+ domain_request.portfolio = portfolio
+ if domain_request.organization_name in suborgs:
+ domain_request.sub_organization = suborgs.get(domain_request.organization_name)
- DomainRequest.objects.bulk_update(domain_requests, ["portfolio"])
- message = f"Added portfolio '{portfolio}' to {len(domain_requests)} domain requests"
- TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
+ DomainRequest.objects.bulk_update(domain_requests, ["portfolio", "sub_organization"])
+ message = f"Added portfolio '{portfolio}' to {len(domain_requests)} domain requests"
+ TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
def handle_portfolio_domains(self, portfolio: Portfolio, federal_agency: FederalAgency):
"""
@@ -202,10 +207,15 @@ class Command(BaseCommand):
if not domain_infos.exists():
message = "Portfolios not added to domains: no valid records found"
TerminalHelper.colorful_logger(logger.info, TerminalColors.YELLOW, message)
- else:
- for domain_info in domain_infos:
- domain_info.portfolio = portfolio
+ return None
- DomainInformation.objects.bulk_update(domain_infos, ["portfolio"])
- message = f"Added portfolio '{portfolio}' to {len(domain_infos)} domains"
- TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
+ # Get all suborg information and store it in a dict to avoid doing a db call
+ suborgs = Suborganization.objects.filter(portfolio=portfolio).in_bulk(field_name="name")
+ for domain_info in domain_infos:
+ domain_info.portfolio = portfolio
+ if domain_info.organization_name in suborgs:
+ domain_info.sub_organization = suborgs.get(domain_info.organization_name)
+
+ DomainInformation.objects.bulk_update(domain_infos, ["portfolio", "sub_organization"])
+ message = f"Added portfolio '{portfolio}' to {len(domain_infos)} domains"
+ TerminalHelper.colorful_logger(logger.info, TerminalColors.OKGREEN, message)
diff --git a/src/registrar/tests/test_management_scripts.py b/src/registrar/tests/test_management_scripts.py
index 29db8a4c5..cbdc2c034 100644
--- a/src/registrar/tests/test_management_scripts.py
+++ b/src/registrar/tests/test_management_scripts.py
@@ -1490,6 +1490,7 @@ class TestCreateFederalPortfolio(TestCase):
self.domain_request.refresh_from_db()
self.assertIsNotNone(self.domain_request.portfolio)
self.assertEqual(self.domain_request.portfolio.federal_agency, self.federal_agency)
+ self.assertEqual(self.domain_request.sub_organization.name, "Testorg")
def test_handle_portfolio_domains(self):
"""Check portfolio association with domain information."""
@@ -1498,6 +1499,7 @@ class TestCreateFederalPortfolio(TestCase):
self.domain_info.refresh_from_db()
self.assertIsNotNone(self.domain_info.portfolio)
self.assertEqual(self.domain_info.portfolio.federal_agency, self.federal_agency)
+ self.assertEqual(self.domain_info.sub_organization.name, "Testorg")
def test_handle_parse_both(self):
"""Ensure correct parsing of both requests and domains."""
From 8732af18d9bf94b16a487e959be1a1f7dae25d9e Mon Sep 17 00:00:00 2001
From: zandercymatics <141044360+zandercymatics@users.noreply.github.com>
Date: Fri, 30 Aug 2024 09:55:29 -0600
Subject: [PATCH 056/150] Update create_federal_portfolio.py
---
src/registrar/management/commands/create_federal_portfolio.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/registrar/management/commands/create_federal_portfolio.py b/src/registrar/management/commands/create_federal_portfolio.py
index cad318b57..ff97d9db1 100644
--- a/src/registrar/management/commands/create_federal_portfolio.py
+++ b/src/registrar/management/commands/create_federal_portfolio.py
@@ -186,7 +186,7 @@ class Command(BaseCommand):
message = "Portfolios not added to domain requests: no valid records found"
TerminalHelper.colorful_logger(logger.info, TerminalColors.YELLOW, message)
return None
-
+
# Get all suborg information and store it in a dict to avoid doing a db call
suborgs = Suborganization.objects.filter(portfolio=portfolio).in_bulk(field_name="name")
for domain_request in domain_requests:
From 82cd91d923be346552e7db950f489f198e87d57d Mon Sep 17 00:00:00 2001
From: zandercymatics <141044360+zandercymatics@users.noreply.github.com>
Date: Tue, 3 Sep 2024 14:46:12 -0600
Subject: [PATCH 057/150] add portfolios view
---
src/registrar/admin.py | 4 ++-
src/registrar/models/user.py | 3 +++
.../django/admin/user_change_form.html | 26 +++++++++++++++++++
3 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/src/registrar/admin.py b/src/registrar/admin.py
index 6b42cf96b..640037847 100644
--- a/src/registrar/admin.py
+++ b/src/registrar/admin.py
@@ -962,7 +962,9 @@ class MyUserAdmin(BaseUserAdmin, ImportExportModelAdmin):
domain_ids = user_domain_roles.values_list("domain_id", flat=True)
domains = Domain.objects.filter(id__in=domain_ids).exclude(state=Domain.State.DELETED)
- extra_context = {"domain_requests": domain_requests, "domains": domains}
+ portfolio_ids = obj.get_portfolios().values_list("portfolio", flat=True)
+ portfolios = models.Portfolio.objects.filter(id__in=portfolio_ids)
+ extra_context = {"domain_requests": domain_requests, "domains": domains, "portfolios": portfolios}
return super().change_view(request, object_id, form_url, extra_context)
diff --git a/src/registrar/models/user.py b/src/registrar/models/user.py
index a7ea1e14a..48bde5281 100644
--- a/src/registrar/models/user.py
+++ b/src/registrar/models/user.py
@@ -244,6 +244,9 @@ class User(AbstractUser):
if permission:
return permission.portfolio
return None
+
+ def get_portfolios(self):
+ return self.portfolio_permissions.all()
@classmethod
def needs_identity_verification(cls, email, uuid):
diff --git a/src/registrar/templates/django/admin/user_change_form.html b/src/registrar/templates/django/admin/user_change_form.html
index 005d67aec..c78fae6cb 100644
--- a/src/registrar/templates/django/admin/user_change_form.html
+++ b/src/registrar/templates/django/admin/user_change_form.html
@@ -1,7 +1,33 @@
{% extends 'django/admin/email_clipboard_change_form.html' %}
{% load i18n static %}
+{% block field_sets %}
+ {% for fieldset in adminform %}
+ {% include "django/admin/includes/email_clipboard_fieldset.html" %}
+ {% endfor %}
+{% endblock %}
+
{% block after_related_objects %}
+ {% if portfolios %}
+
+
Portfolio information
+
+
+ {% endif %}
+
Associated requests and domains
From c70e098f5401e3860de73232aec883e0e827bf22 Mon Sep 17 00:00:00 2001
From: zandercymatics <141044360+zandercymatics@users.noreply.github.com>
Date: Tue, 3 Sep 2024 14:46:31 -0600
Subject: [PATCH 058/150] Update user_change_form.html
---
src/registrar/templates/django/admin/user_change_form.html | 6 ------
1 file changed, 6 deletions(-)
diff --git a/src/registrar/templates/django/admin/user_change_form.html b/src/registrar/templates/django/admin/user_change_form.html
index c78fae6cb..3a7ea5f92 100644
--- a/src/registrar/templates/django/admin/user_change_form.html
+++ b/src/registrar/templates/django/admin/user_change_form.html
@@ -1,12 +1,6 @@
{% extends 'django/admin/email_clipboard_change_form.html' %}
{% load i18n static %}
-{% block field_sets %}
- {% for fieldset in adminform %}
- {% include "django/admin/includes/email_clipboard_fieldset.html" %}
- {% endfor %}
-{% endblock %}
-
{% block after_related_objects %}
{% if portfolios %}
From 1cb14f8d6a0ef03fbae3d4ea3b01244dba1f3489 Mon Sep 17 00:00:00 2001
From: zandercymatics <141044360+zandercymatics@users.noreply.github.com>
Date: Tue, 3 Sep 2024 14:48:26 -0600
Subject: [PATCH 059/150] Update user_change_form.html
---
src/registrar/templates/django/admin/user_change_form.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/registrar/templates/django/admin/user_change_form.html b/src/registrar/templates/django/admin/user_change_form.html
index 3a7ea5f92..b545bed23 100644
--- a/src/registrar/templates/django/admin/user_change_form.html
+++ b/src/registrar/templates/django/admin/user_change_form.html
@@ -11,7 +11,7 @@
{% for portfolio in portfolios %}
-
+
{{ portfolio }}
From c57405a918c673adc672b62236f67f27f13f3e22 Mon Sep 17 00:00:00 2001
From: zandercymatics <141044360+zandercymatics@users.noreply.github.com>
Date: Tue, 3 Sep 2024 15:25:06 -0600
Subject: [PATCH 060/150] Update test_admin.py
---
src/registrar/tests/test_admin.py | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/src/registrar/tests/test_admin.py b/src/registrar/tests/test_admin.py
index a435c6a69..2e9122c38 100644
--- a/src/registrar/tests/test_admin.py
+++ b/src/registrar/tests/test_admin.py
@@ -2,6 +2,7 @@ from datetime import datetime
from django.utils import timezone
from django.test import TestCase, RequestFactory, Client
from django.contrib.admin.sites import AdminSite
+from registrar.models.utility.portfolio_helper import UserPortfolioRoleChoices
from api.tests.common import less_console_noise_decorator
from django.urls import reverse
from registrar.admin import (
@@ -41,6 +42,7 @@ from registrar.models import (
TransitionDomain,
Portfolio,
Suborganization,
+ UserPortfolioPermission,
)
from registrar.models.portfolio_invitation import PortfolioInvitation
from registrar.models.senior_official import SeniorOfficial
@@ -1223,6 +1225,25 @@ class TestMyUserAdmin(MockDbForSharedTests):
self.assertNotContains(response, "Portfolio roles:")
self.assertNotContains(response, "Portfolio additional permissions:")
+
+ @less_console_noise_decorator
+ def test_user_can_see_related_portfolios(self):
+ """Tests if a user can see the portfolios they are associated with on the user page"""
+ portfolio, _ = Portfolio.objects.get_or_create(organization_name="test", creator=self.user)
+ permission, _ = UserPortfolioPermission.objects.get_or_create(
+ user=self.user, portfolio=portfolio, roles=[UserPortfolioRoleChoices.ORGANIZATION_ADMIN]
+ )
+ self.user.refresh_from_db()
+ self.client.force_login(self.user)
+ response = self.client.get(
+ "/admin/registrar/user/{}/change/".format(self.user.id),
+ follow=True,
+ )
+ expected_href = reverse("admin:registrar_portfolio_change", args=[portfolio.pk])
+ self.assertContains(response, expected_href)
+ self.assertContains(response, str(portfolio))
+ permission.delete()
+ portfolio.delete()
class AuditedAdminTest(TestCase):
From 7a77cb8444343ae897f580dd65fc487bbebeb63d Mon Sep 17 00:00:00 2001
From: matthewswspence
Date: Wed, 4 Sep 2024 12:37:01 -0500
Subject: [PATCH 061/150] initial stab at a new json formatter
---
src/registrar/config/settings.py | 43 ++++++++++++++++++++++++++------
1 file changed, 35 insertions(+), 8 deletions(-)
diff --git a/src/registrar/config/settings.py b/src/registrar/config/settings.py
index 73aecad7a..016dda4d9 100644
--- a/src/registrar/config/settings.py
+++ b/src/registrar/config/settings.py
@@ -23,6 +23,8 @@ from cfenv import AppEnv # type: ignore
from pathlib import Path
from typing import Final
from botocore.config import Config
+import json
+from django.utils.log import ServerFormatter
# # # ###
# Setup code goes here #
@@ -192,7 +194,7 @@ MIDDLEWARE = [
"registrar.registrar_middleware.CheckPortfolioMiddleware",
]
-# application object used by Django’s built-in servers (e.g. `runserver`)
+# application object used by Django's built-in servers (e.g. `runserver`)
WSGI_APPLICATION = "registrar.config.wsgi.application"
# endregion
@@ -410,7 +412,7 @@ LANGUAGE_COOKIE_SECURE = True
# and to interpret datetimes entered in forms
TIME_ZONE = "UTC"
-# enable Django’s translation system
+# enable Django's translation system
USE_I18N = True
# enable localized formatting of numbers and dates
@@ -445,6 +447,30 @@ PHONENUMBER_DEFAULT_REGION = "US"
# logger.error("Can't do this important task. Something is very wrong.")
# logger.critical("Going to crash now.")
+class JsonFormatter(logging.Formatter):
+ def __init__(self):
+ super().__init__(datefmt="%d/%b/%Y %H:%M:%S")
+
+ def format(self, record):
+ log_record = {
+ "timestamp": self.formatTime(record, self.datefmt),
+ "level": record.levelname,
+ "name": record.name,
+ "lineno": record.lineno,
+ "message": record.getMessage(),
+ }
+ return json.dumps(log_record)
+
+class JsonServerFormatter(ServerFormatter):
+ def format(self, record):
+ formatted_record = super().format(record)
+ log_entry = {
+ "server_time": record.server_time,
+ "level": record.levelname,
+ "message": formatted_record
+ }
+ return json.dumps(log_entry)
+
LOGGING = {
"version": 1,
# Don't import Django's existing loggers
@@ -459,10 +485,11 @@ LOGGING = {
"simple": {
"format": "%(levelname)s %(message)s",
},
- "django.server": {
- "()": "django.utils.log.ServerFormatter",
- "format": "[{server_time}] {message}",
- "style": "{",
+ "json.server": {
+ "()": JsonServerFormatter,
+ },
+ "json": {
+ "()": JsonFormatter,
},
},
# define where log messages will be sent;
@@ -471,12 +498,12 @@ LOGGING = {
"console": {
"level": env_log_level,
"class": "logging.StreamHandler",
- "formatter": "verbose",
+ "formatter": "json",
},
"django.server": {
"level": "INFO",
"class": "logging.StreamHandler",
- "formatter": "django.server",
+ "formatter": "json.server",
},
# No file logger is configured,
# because containerized apps
From e2fde1f96808f0c00899e483905e6da4a7ee4dbe Mon Sep 17 00:00:00 2001
From: matthewswspence
Date: Wed, 4 Sep 2024 12:59:18 -0500
Subject: [PATCH 062/150] fix imports
---
src/registrar/config/settings.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/registrar/config/settings.py b/src/registrar/config/settings.py
index 016dda4d9..0b68a1574 100644
--- a/src/registrar/config/settings.py
+++ b/src/registrar/config/settings.py
@@ -24,6 +24,7 @@ from pathlib import Path
from typing import Final
from botocore.config import Config
import json
+import logging
from django.utils.log import ServerFormatter
# # # ###
From afd941e27ffa7db39cf179255fb25edd5ec7b6c0 Mon Sep 17 00:00:00 2001
From: matthewswspence
Date: Wed, 4 Sep 2024 15:26:54 -0500
Subject: [PATCH 063/150] temp: add error message to test logs
---
src/registrar/models/domain_request.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/registrar/models/domain_request.py b/src/registrar/models/domain_request.py
index b80e063cd..9cee17b18 100644
--- a/src/registrar/models/domain_request.py
+++ b/src/registrar/models/domain_request.py
@@ -1,4 +1,5 @@
from __future__ import annotations
+import traceback
from typing import Union
import logging
from django.apps import apps
@@ -644,6 +645,8 @@ class DomainRequest(TimeStampedModel):
self.sync_organization_type()
self.sync_yes_no_form_fields()
+ logger.error(traceback.print_stack())
+
if self._cached_status != self.status:
self.last_status_update = timezone.now().date()
From a61e8a16707466afee92af9ac35211f17fc162e2 Mon Sep 17 00:00:00 2001
From: matthewswspence
Date: Wed, 4 Sep 2024 15:42:31 -0500
Subject: [PATCH 064/150] more temp changes
---
src/registrar/models/domain_request.py | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/registrar/models/domain_request.py b/src/registrar/models/domain_request.py
index 9cee17b18..f6e215a27 100644
--- a/src/registrar/models/domain_request.py
+++ b/src/registrar/models/domain_request.py
@@ -644,8 +644,10 @@ class DomainRequest(TimeStampedModel):
"""Save override for custom properties"""
self.sync_organization_type()
self.sync_yes_no_form_fields()
-
- logger.error(traceback.print_stack())
+ try:
+ raise ValueError("TEST TEST TEST")
+ except Exception as e:
+ logger.error(e)
if self._cached_status != self.status:
self.last_status_update = timezone.now().date()
From d9898e3af2643985e091f3d72904643749e09458 Mon Sep 17 00:00:00 2001
From: matthewswspence
Date: Wed, 4 Sep 2024 15:52:13 -0500
Subject: [PATCH 065/150] moar testing!!!
---
src/registrar/models/domain_request.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/registrar/models/domain_request.py b/src/registrar/models/domain_request.py
index f6e215a27..95a20d4cd 100644
--- a/src/registrar/models/domain_request.py
+++ b/src/registrar/models/domain_request.py
@@ -645,9 +645,9 @@ class DomainRequest(TimeStampedModel):
self.sync_organization_type()
self.sync_yes_no_form_fields()
try:
- raise ValueError("TEST TEST TEST")
- except Exception as e:
- logger.error(e)
+ raise Exception("TEST TEST TEST")
+ except Exception:
+ logger.error(traceback.format_exc)
if self._cached_status != self.status:
self.last_status_update = timezone.now().date()
From bdec43e2f349ac52dbac79ef0abeaf5ebe7ac5d5 Mon Sep 17 00:00:00 2001
From: matthewswspence
Date: Wed, 4 Sep 2024 15:57:58 -0500
Subject: [PATCH 066/150] forgot parentheses :(
---
src/registrar/models/domain_request.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/registrar/models/domain_request.py b/src/registrar/models/domain_request.py
index 95a20d4cd..af8d22b5f 100644
--- a/src/registrar/models/domain_request.py
+++ b/src/registrar/models/domain_request.py
@@ -647,7 +647,7 @@ class DomainRequest(TimeStampedModel):
try:
raise Exception("TEST TEST TEST")
except Exception:
- logger.error(traceback.format_exc)
+ logger.error(traceback.format_exc())
if self._cached_status != self.status:
self.last_status_update = timezone.now().date()
From c043f44ef9a2f072eec36e535c140e1b0dd79ad3 Mon Sep 17 00:00:00 2001
From: asaki222
Date: Wed, 4 Sep 2024 17:59:54 -0400
Subject: [PATCH 067/150] refactoring code to meet ac reqs
---
src/registrar/views/domain.py | 40 ++++++++++++++++++++---------------
1 file changed, 23 insertions(+), 17 deletions(-)
diff --git a/src/registrar/views/domain.py b/src/registrar/views/domain.py
index 003f8dd0d..1fc6cb1ef 100644
--- a/src/registrar/views/domain.py
+++ b/src/registrar/views/domain.py
@@ -836,6 +836,23 @@ class DomainAddUserView(DomainFormBaseView):
exc_info=True,
)
return None
+
+ # Check to see if an invite has already been sent (NOTE: we do not want to create an invite just yet.)
+ try:
+ invite = DomainInvitation.objects.get(email=email, domain=self.object)
+ # that invitation already existed
+ if invite.status == DomainInvitation.DomainInvitationStatus.RETRIEVED:
+ messages.warning(
+ self.request,
+ f"{email} is already a manager for this domain.",
+ )
+ else:
+ messages.warning(
+ self.request,
+ f"{email} has already been invited to this domain"
+ )
+ except DomainInvitation.DoesNotExist:
+ logger.info("Domain Invitation Does Not Exist")
try:
send_templated_email(
@@ -859,25 +876,14 @@ class DomainAddUserView(DomainFormBaseView):
else:
if add_success:
messages.success(self.request, f"{email} has been invited to this domain.")
-
+
def _make_invitation(self, email_address: str, requestor: User):
"""Make a Domain invitation for this email and redirect with a message."""
- # Check to see if an invite has already been sent (NOTE: we do not want to create an invite just yet.)
try:
- invite = DomainInvitation.objects.get(email=email_address, domain=self.object)
- # that invitation already existed
- if invite is not None:
- messages.warning(
- self.request,
- f"{email_address} has already been invited to this domain.",
- )
- except DomainInvitation.DoesNotExist:
- # Try to send the invitation. If it succeeds, add it to the DomainInvitation table.
- try:
- self._send_domain_invitation_email(email=email_address, requestor=requestor)
- except EmailSendingError:
+ self._send_domain_invitation_email(email=email_address, requestor=requestor, add_success=False)
+ except EmailSendingError:
messages.warning(self.request, "Could not send email invitation.")
- else:
+ else:
# (NOTE: only create a domainInvitation if the e-mail sends correctly)
DomainInvitation.objects.get_or_create(email=email_address, domain=self.object)
return redirect(self.get_success_url())
@@ -921,8 +927,8 @@ class DomainAddUserView(DomainFormBaseView):
except IntegrityError:
# User already has the desired role! Do nothing??
pass
-
- messages.success(self.request, f"Added user {requested_email}.")
+ else:
+ messages.success(self.request, f"Added user {requested_email}.")
return redirect(self.get_success_url())
From 8da02de034de887690f4bf38e2aa5809de501b7e Mon Sep 17 00:00:00 2001
From: asaki222
Date: Wed, 4 Sep 2024 18:18:54 -0400
Subject: [PATCH 068/150] removed else from message success
---
src/registrar/views/domain.py | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/registrar/views/domain.py b/src/registrar/views/domain.py
index 1fc6cb1ef..e483c3f85 100644
--- a/src/registrar/views/domain.py
+++ b/src/registrar/views/domain.py
@@ -839,6 +839,7 @@ class DomainAddUserView(DomainFormBaseView):
# Check to see if an invite has already been sent (NOTE: we do not want to create an invite just yet.)
try:
+ add_success=False
invite = DomainInvitation.objects.get(email=email, domain=self.object)
# that invitation already existed
if invite.status == DomainInvitation.DomainInvitationStatus.RETRIEVED:
@@ -880,7 +881,7 @@ class DomainAddUserView(DomainFormBaseView):
def _make_invitation(self, email_address: str, requestor: User):
"""Make a Domain invitation for this email and redirect with a message."""
try:
- self._send_domain_invitation_email(email=email_address, requestor=requestor, add_success=False)
+ self._send_domain_invitation_email(email=email_address, requestor=requestor)
except EmailSendingError:
messages.warning(self.request, "Could not send email invitation.")
else:
@@ -927,8 +928,8 @@ class DomainAddUserView(DomainFormBaseView):
except IntegrityError:
# User already has the desired role! Do nothing??
pass
- else:
- messages.success(self.request, f"Added user {requested_email}.")
+
+ messages.success(self.request, f"Added user {requested_email}.")
return redirect(self.get_success_url())
From 0e7b5ae8cba88e3af95d13304c929146c2495c9e Mon Sep 17 00:00:00 2001
From: asaki222
Date: Wed, 4 Sep 2024 18:19:48 -0400
Subject: [PATCH 069/150] removed line
---
src/registrar/views/domain.py | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/registrar/views/domain.py b/src/registrar/views/domain.py
index e483c3f85..fcac53f29 100644
--- a/src/registrar/views/domain.py
+++ b/src/registrar/views/domain.py
@@ -927,8 +927,7 @@ class DomainAddUserView(DomainFormBaseView):
)
except IntegrityError:
# User already has the desired role! Do nothing??
- pass
-
+ pass
messages.success(self.request, f"Added user {requested_email}.")
return redirect(self.get_success_url())
From 914fbdc04b53310cf8abc0b23d8cfb08d734417d Mon Sep 17 00:00:00 2001
From: asaki222
Date: Wed, 4 Sep 2024 18:24:07 -0400
Subject: [PATCH 070/150] added comments
---
src/registrar/views/domain.py | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/src/registrar/views/domain.py b/src/registrar/views/domain.py
index fcac53f29..0cdfa0c77 100644
--- a/src/registrar/views/domain.py
+++ b/src/registrar/views/domain.py
@@ -837,17 +837,19 @@ class DomainAddUserView(DomainFormBaseView):
)
return None
- # Check to see if an invite has already been sent (NOTE: we do not want to create an invite just yet.)
+ # Check to see if an invite has already been sent
try:
- add_success=False
invite = DomainInvitation.objects.get(email=email, domain=self.object)
- # that invitation already existed
+ # check if the invite has already been accepted
if invite.status == DomainInvitation.DomainInvitationStatus.RETRIEVED:
+ add_success=False
messages.warning(
self.request,
f"{email} is already a manager for this domain.",
)
else:
+ add_success=False
+ #else if it has been sent but not accepted
messages.warning(
self.request,
f"{email} has already been invited to this domain"
From 236aac02b004091cba434d1bdaea0f98ca86f99b Mon Sep 17 00:00:00 2001
From: asaki222
Date: Wed, 4 Sep 2024 18:27:32 -0400
Subject: [PATCH 071/150] an error occured
---
src/registrar/views/domain.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/registrar/views/domain.py b/src/registrar/views/domain.py
index 0cdfa0c77..e0e59dd59 100644
--- a/src/registrar/views/domain.py
+++ b/src/registrar/views/domain.py
@@ -854,8 +854,8 @@ class DomainAddUserView(DomainFormBaseView):
self.request,
f"{email} has already been invited to this domain"
)
- except DomainInvitation.DoesNotExist:
- logger.info("Domain Invitation Does Not Exist")
+ except Exception:
+ logger.error("An error occured")
try:
send_templated_email(
From 0d00bd467d6c9638f47df6b2d06ece6e537a7b70 Mon Sep 17 00:00:00 2001
From: asaki222
Date: Wed, 4 Sep 2024 18:27:57 -0400
Subject: [PATCH 072/150] removed spacing
---
src/registrar/views/domain.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/registrar/views/domain.py b/src/registrar/views/domain.py
index e0e59dd59..eef2f0451 100644
--- a/src/registrar/views/domain.py
+++ b/src/registrar/views/domain.py
@@ -931,7 +931,6 @@ class DomainAddUserView(DomainFormBaseView):
# User already has the desired role! Do nothing??
pass
messages.success(self.request, f"Added user {requested_email}.")
-
return redirect(self.get_success_url())
From ef30e06b89ffd6b6aa78408b58faecfa51029032 Mon Sep 17 00:00:00 2001
From: asaki222
Date: Wed, 4 Sep 2024 18:32:07 -0400
Subject: [PATCH 073/150] added back the sucess message under else
---
src/registrar/views/domain.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/registrar/views/domain.py b/src/registrar/views/domain.py
index eef2f0451..b3b27f581 100644
--- a/src/registrar/views/domain.py
+++ b/src/registrar/views/domain.py
@@ -928,9 +928,9 @@ class DomainAddUserView(DomainFormBaseView):
role=UserDomainRole.Roles.MANAGER,
)
except IntegrityError:
- # User already has the desired role! Do nothing??
- pass
- messages.success(self.request, f"Added user {requested_email}.")
+ messages.warning(self.request, f"{requested_email} already added to this domain")
+ else:
+ messages.success(self.request, f"Added user {requested_email}.")
return redirect(self.get_success_url())
From 68b8a6086b4ae97b5bff59bd03030ecfb8ece473 Mon Sep 17 00:00:00 2001
From: asaki222
Date: Wed, 4 Sep 2024 19:53:44 -0400
Subject: [PATCH 074/150] formated changes
---
src/registrar/views/domain.py | 25 +++++++++++--------------
1 file changed, 11 insertions(+), 14 deletions(-)
diff --git a/src/registrar/views/domain.py b/src/registrar/views/domain.py
index b3b27f581..a672f37ef 100644
--- a/src/registrar/views/domain.py
+++ b/src/registrar/views/domain.py
@@ -836,24 +836,21 @@ class DomainAddUserView(DomainFormBaseView):
exc_info=True,
)
return None
-
+
# Check to see if an invite has already been sent
try:
invite = DomainInvitation.objects.get(email=email, domain=self.object)
# check if the invite has already been accepted
if invite.status == DomainInvitation.DomainInvitationStatus.RETRIEVED:
- add_success=False
+ add_success = False
messages.warning(
self.request,
f"{email} is already a manager for this domain.",
)
else:
- add_success=False
- #else if it has been sent but not accepted
- messages.warning(
- self.request,
- f"{email} has already been invited to this domain"
- )
+ add_success = False
+ # else if it has been sent but not accepted
+ messages.warning(self.request, f"{email} has already been invited to this domain")
except Exception:
logger.error("An error occured")
@@ -879,16 +876,16 @@ class DomainAddUserView(DomainFormBaseView):
else:
if add_success:
messages.success(self.request, f"{email} has been invited to this domain.")
-
+
def _make_invitation(self, email_address: str, requestor: User):
"""Make a Domain invitation for this email and redirect with a message."""
try:
- self._send_domain_invitation_email(email=email_address, requestor=requestor)
+ self._send_domain_invitation_email(email=email_address, requestor=requestor)
except EmailSendingError:
- messages.warning(self.request, "Could not send email invitation.")
+ messages.warning(self.request, "Could not send email invitation.")
else:
- # (NOTE: only create a domainInvitation if the e-mail sends correctly)
- DomainInvitation.objects.get_or_create(email=email_address, domain=self.object)
+ # (NOTE: only create a domainInvitation if the e-mail sends correctly)
+ DomainInvitation.objects.get_or_create(email=email_address, domain=self.object)
return redirect(self.get_success_url())
def form_valid(self, form):
@@ -928,7 +925,7 @@ class DomainAddUserView(DomainFormBaseView):
role=UserDomainRole.Roles.MANAGER,
)
except IntegrityError:
- messages.warning(self.request, f"{requested_email} already added to this domain")
+ messages.warning(self.request, f"{requested_email} already added to this domain")
else:
messages.success(self.request, f"Added user {requested_email}.")
return redirect(self.get_success_url())
From be8a618791a4e4f1d7941cbbe8a212d5a02207d8 Mon Sep 17 00:00:00 2001
From: Rachid Mrad
Date: Thu, 5 Sep 2024 00:13:18 -0400
Subject: [PATCH 075/150] wip
---
src/registrar/assets/js/get-gov.js | 86 +++++++++++++++++--
.../assets/sass/_theme/_accordions.scss | 3 +-
src/registrar/assets/sass/_theme/_base.scss | 5 ++
src/registrar/assets/sass/_theme/_header.scss | 6 +-
src/registrar/config/urls.py | 5 ++
.../includes/domain_requests_table.html | 7 +-
.../templates/includes/domains_table.html | 1 -
.../templates/includes/header_extended.html | 34 ++++++--
.../portfolio_no_domain_requests.html | 30 +++++++
...domains.html => portfolio_no_domains.html} | 0
src/registrar/views/domain_requests_json.py | 24 +++++-
src/registrar/views/portfolios.py | 33 ++++++-
12 files changed, 212 insertions(+), 22 deletions(-)
create mode 100644 src/registrar/templates/portfolio_no_domain_requests.html
rename src/registrar/templates/{no_portfolio_domains.html => portfolio_no_domains.html} (100%)
diff --git a/src/registrar/assets/js/get-gov.js b/src/registrar/assets/js/get-gov.js
index 70659b009..0aebb7ff6 100644
--- a/src/registrar/assets/js/get-gov.js
+++ b/src/registrar/assets/js/get-gov.js
@@ -1168,7 +1168,6 @@ document.addEventListener('DOMContentLoaded', function() {
const statusCheckboxes = document.querySelectorAll('input[name="filter-status"]');
const statusIndicator = document.querySelector('.domain__filter-indicator');
const statusToggle = document.querySelector('.usa-button--filter');
- const noPortfolioFlag = document.getElementById('no-portfolio-js-flag');
const portfolioElement = document.getElementById('portfolio-js-value');
const portfolioValue = portfolioElement ? portfolioElement.getAttribute('data-portfolio') : null;
@@ -1226,7 +1225,7 @@ document.addEventListener('DOMContentLoaded', function() {
let markupForSuborganizationRow = '';
- if (!noPortfolioFlag) {
+ if (portfolioValue) {
markupForSuborganizationRow = `
${suborganization}
@@ -1485,6 +1484,8 @@ document.addEventListener('DOMContentLoaded', function() {
const tableHeaders = document.querySelectorAll('.domain-requests__table th[data-sortable]');
const tableAnnouncementRegion = document.querySelector('.domain-requests__table-wrapper .usa-table__announcement-region');
const resetSearchButton = document.querySelector('.domain-requests__reset-search');
+ const portfolioElement = document.getElementById('portfolio-js-value');
+ const portfolioValue = portfolioElement ? portfolioElement.getAttribute('data-portfolio') : null;
/**
* Delete is actually a POST API that requires a csrf token. The token will be waiting for us in the template as a hidden input.
@@ -1533,7 +1534,7 @@ document.addEventListener('DOMContentLoaded', function() {
* @param {*} scroll - control for the scrollToElement functionality
* @param {*} searchTerm - the search term
*/
- function loadDomainRequests(page, sortBy = currentSortBy, order = currentOrder, scroll = scrollToTable, searchTerm = currentSearchTerm) {
+ function loadDomainRequests(page, sortBy = currentSortBy, order = currentOrder, scroll = scrollToTable, searchTerm = currentSearchTerm, portfolio = portfolioValue) {
// fetch json of page of domain requests, given params
let baseUrl = document.getElementById("get_domain_requests_json_url");
if (!baseUrl) {
@@ -1545,7 +1546,12 @@ document.addEventListener('DOMContentLoaded', function() {
return;
}
- fetch(`${baseUrlValue}?page=${page}&sort_by=${sortBy}&order=${order}&search_term=${searchTerm}`)
+ // fetch json of page of requests, given params
+ let url = `${baseUrlValue}?page=${page}&sort_by=${sortBy}&order=${order}&search_term=${searchTerm}`
+ if (portfolio)
+ url += `&portfolio=${portfolio}`
+
+ fetch(url)
.then(response => response.json())
.then(data => {
if (data.error) {
@@ -1601,10 +1607,11 @@ document.addEventListener('DOMContentLoaded', function() {
const actionLabel = request.action_label;
const submissionDate = request.last_submitted_date ? new Date(request.last_submitted_date).toLocaleDateString('en-US', options) : `Not submitted `;
- // Even if the request is not deletable, we may need this empty string for the td if the deletable column is displayed
+ // Delete markup will either be a simple trigger or a 3 dots menu with a hidden trigger (in the case of portfolio requests page)
+ // Even if the request is not deletable, we may need these empty strings for the td if the deletable column is displayed
let modalTrigger = '';
- // If the request is deletable, create modal body and insert it
+ // If the request is deletable, create modal body and insert it. This is true for both requests and portfolio requests pages
if (request.is_deletable) {
let modalHeading = '';
let modalDescription = '';
@@ -1692,8 +1699,45 @@ document.addEventListener('DOMContentLoaded', function() {
`
domainRequestsSectionWrapper.appendChild(modal);
+
+ // Request is deletable, modal and modalTrigger are built. Now test is portfolio requests page and enhace the modalTrigger markup
+ if (portfolioValue) {
+ modalTrigger = `
+
+ `
+ }
}
+
+
const row = document.createElement('tr');
row.innerHTML = `
@@ -1817,6 +1861,36 @@ document.addEventListener('DOMContentLoaded', function() {
});
}
+ function closeMoreActionMenu(accordionIsOpen) {
+ if (accordionIsOpen.getAttribute("aria-expanded") === "true") {
+ accordionIsOpen.click();
+ }
+ }
+
+ document.addEventListener('focusin', function(event) {
+ const accordions = document.querySelectorAll('.usa-accordion--more-actions');
+ const openAccordions = document.querySelectorAll('.usa-button--more-actions[aria-expanded="true"]');
+
+ openAccordions.forEach((openAccordionButton) => {
+ const accordion = openAccordionButton.closest('.usa-accordion--more-actions'); // Find the corresponding accordion
+ if (accordion && !accordion.contains(event.target)) {
+ closeMoreActionMenu(openAccordionButton); // Close the accordion if the focus is outside
+ }
+ });
+ });
+
+ document.addEventListener('click', function(event) {
+ const accordions = document.querySelectorAll('.usa-accordion--more-actions');
+ const openAccordions = document.querySelectorAll('.usa-button--more-actions[aria-expanded="true"]');
+
+ openAccordions.forEach((openAccordionButton) => {
+ const accordion = openAccordionButton.closest('.usa-accordion--more-actions'); // Find the corresponding accordion
+ if (accordion && !accordion.contains(event.target)) {
+ closeMoreActionMenu(openAccordionButton); // Close the accordion if the click is outside
+ }
+ });
+ });
+
// Initial load
loadDomainRequests(1);
}
diff --git a/src/registrar/assets/sass/_theme/_accordions.scss b/src/registrar/assets/sass/_theme/_accordions.scss
index 839d7ac42..b422945cb 100644
--- a/src/registrar/assets/sass/_theme/_accordions.scss
+++ b/src/registrar/assets/sass/_theme/_accordions.scss
@@ -1,6 +1,7 @@
@use "uswds-core" as *;
-.usa-accordion--select {
+.usa-accordion--select,
+.usa-accordion--more-actions {
display: inline-block;
width: auto;
position: relative;
diff --git a/src/registrar/assets/sass/_theme/_base.scss b/src/registrar/assets/sass/_theme/_base.scss
index 9f8a0cbb6..16a63c41c 100644
--- a/src/registrar/assets/sass/_theme/_base.scss
+++ b/src/registrar/assets/sass/_theme/_base.scss
@@ -192,3 +192,8 @@ abbr[title] {
max-width: 50ch;
}
}
+
+// Boost this USWDS utility class for the accordions in the portfolio requests table
+.left-auto {
+ left: auto!important;
+}
diff --git a/src/registrar/assets/sass/_theme/_header.scss b/src/registrar/assets/sass/_theme/_header.scss
index 3d72a09cf..726460c6f 100644
--- a/src/registrar/assets/sass/_theme/_header.scss
+++ b/src/registrar/assets/sass/_theme/_header.scss
@@ -89,14 +89,16 @@
.usa-nav__primary {
.usa-nav-link,
.usa-nav-link:hover,
- .usa-nav-link:active {
+ .usa-nav-link:active,
+ button {
color: color('primary');
font-weight: font-weight('normal');
font-size: 16px;
}
.usa-current,
.usa-current:hover,
- .usa-current:active {
+ .usa-current:active,
+ button.usa-current {
font-weight: font-weight('bold');
}
}
diff --git a/src/registrar/config/urls.py b/src/registrar/config/urls.py
index 19fa99809..12de5d2a7 100644
--- a/src/registrar/config/urls.py
+++ b/src/registrar/config/urls.py
@@ -78,6 +78,11 @@ urlpatterns = [
views.PortfolioDomainRequestsView.as_view(),
name="domain-requests",
),
+ path(
+ "no-organization-requests/",
+ views.PortfolioNoDomainRequestsView.as_view(),
+ name="no-portfolio-requests",
+ ),
path(
"organization/",
views.PortfolioOrganizationView.as_view(),
diff --git a/src/registrar/templates/includes/domain_requests_table.html b/src/registrar/templates/includes/domain_requests_table.html
index bd909350c..e5a3e046d 100644
--- a/src/registrar/templates/includes/domain_requests_table.html
+++ b/src/registrar/templates/includes/domain_requests_table.html
@@ -5,10 +5,13 @@
{{url}}
- {% if not has_domain_requests_portfolio_permission %}
+ {% if not portfolio %}
Domain requests
+ {% else %}
+
+
{% endif %}
@@ -45,7 +48,7 @@
Domain name
- Date submitted
+ Submitted
Status
Action
diff --git a/src/registrar/templates/includes/domains_table.html b/src/registrar/templates/includes/domains_table.html
index 48de2d98c..a132d47c7 100644
--- a/src/registrar/templates/includes/domains_table.html
+++ b/src/registrar/templates/includes/domains_table.html
@@ -9,7 +9,6 @@