Remove second script, modify first

This commit is contained in:
zandercymatics 2025-01-07 08:42:56 -07:00
parent ca9a40caaf
commit 2c5c9de6dc
No known key found for this signature in database
GPG key ID: FF4636ABEC9682B7
4 changed files with 24 additions and 188 deletions

View file

@ -919,36 +919,3 @@ Example (only requests): `./manage.py create_federal_portfolio --branch "executi
- Parameters #2-#3, you cannot use `--both` while using these. You must specify either `--parse_requests` or `--parse_domains` seperately. While all of these parameters are optional in that you do not need to specify all of them,
you must specify at least one to run this script.
## Populate requested suborg
This script populates the "requested suborganization" fields on DomainRequest.
These fields are: requested_suborganization, suborganization_city, suborganization_state_territory.
This is done by pulling from organization_name, city, and state_territory.
The script will only parse records with a portfolio but no suborganization attached to it.
Additionally, it will not parse records wherein the organization name matches the portfolio org name.
### 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
To create a specific portfolio:
```./manage.py populate_requested_suborg```
### Running locally
#### Step 1: Running the script
```docker-compose exec app ./manage.py populate_requested_suborg```

View file

@ -1,52 +0,0 @@
import logging
from django.core.management import BaseCommand
from registrar.management.commands.utility.terminal_helper import PopulateScriptTemplate, TerminalColors, TerminalHelper
from registrar.models import DomainRequest
from registrar.models.utility.generic_helper import normalize_string
logger = logging.getLogger(__name__)
class Command(BaseCommand, PopulateScriptTemplate):
help = "Loops through each domain request object and populates requested suborg info"
def handle(self, **kwargs):
"""Loops through each DomainRequest object and populates
its last_status_update and first_submitted_date values"""
filter_conditions = {
"portfolio__isnull": False,
"organization_name__isnull": False,
"sub_organization__isnull": True,
"portfolio__organization_name__isnull": False,
}
fields_to_update = ["requested_suborganization", "suborganization_city", "suborganization_state_territory"]
self.mass_update_records(DomainRequest, filter_conditions, fields_to_update)
def update_record(self, record: DomainRequest):
"""Adds data to requested_suborganization, suborganization_city, and suborganization_state_territory."""
record.requested_suborganization = record.organization_name
record.suborganization_city = record.city
record.suborganization_state_territory = record.state_territory
message = (
f"Updating {record} => requested_suborg: {record.organization_name}, "
f"sub_city: {record.city}, suborg_state_territory: {record.state_territory}."
)
TerminalHelper.colorful_logger(logger.info, TerminalColors.OKBLUE, message)
def should_skip_record(self, record) -> bool:
"""Skips updating the record if the portfolio name is the same as the org name,
or if we are trying to update a record in an invalid status."""
invalid_statuses = [
DomainRequest.DomainRequestStatus.REJECTED,
DomainRequest.DomainRequestStatus.INELIGIBLE,
DomainRequest.DomainRequestStatus.STARTED,
]
if record.status in invalid_statuses:
return True
portfolio_normalized = normalize_string(record.portfolio.organization_name)
org_normalized = normalize_string(record.organization_name)
if portfolio_normalized == org_normalized:
return True
return False

View file

@ -343,9 +343,3 @@ def value_of_attribute(obj, attribute_name: str):
if callable(value):
value = value()
return value
def normalize_string(string_to_normalize: str) -> str:
"""Normalizes a given string. Returns a string without extra spaces, in all lowercase."""
new_string = " ".join(string_to_normalize.split())
return new_string.lower()

View file

@ -1588,6 +1588,30 @@ class TestCreateFederalPortfolio(TestCase):
self.assertTrue(all([creator == User.get_default_user() for creator in creators]))
self.assertTrue(all([note == "Auto-generated record" for note in notes]))
def test_script_adds_requested_suborganization_information(self):
"""Tests that the script adds the requested suborg fields for domain requests"""
custom_suborg_request = completed_domain_request(
name="custom_org.gov",
status=DomainRequest.DomainRequestStatus.IN_REVIEW,
generic_org_type=DomainRequest.OrganizationChoices.FEDERAL,
federal_agency=self.executive_agency_2,
user=self.user,
organization_name="requested org name",
city="Austin",
state_territory=DomainRequest.StateTerritoryChoices.TEXAS
)
self.assertIsNone(custom_suborg_request.requested_suborganization)
self.assertIsNone(custom_suborg_request.suborganization_city)
self.assertIsNone(custom_suborg_request.suborganization_state_territory)
# Run the script and test it
self.run_create_federal_portfolio(branch="executive", parse_requests=True)
self.assertEqual(custom_suborg_request.requested_suborganization, "requested org name")
self.assertEqual(custom_suborg_request.suborganization_city, "Austin")
self.assertEqual(custom_suborg_request.suborganization_state_territory, DomainRequest.StateTerritoryChoices.TEXAS)
def test_create_multiple_portfolios_for_branch_executive(self):
"""Tests creating all portfolios under a given branch"""
federal_choice = DomainRequest.OrganizationChoices.FEDERAL
@ -1732,100 +1756,3 @@ class TestCreateFederalPortfolio(TestCase):
self.assertEqual(existing_portfolio.notes, "Old notes")
self.assertEqual(existing_portfolio.creator, self.user)
class TestPopulateRequestedSuborg(MockEppLib):
"""Tests for the populate_requested_suborg script"""
@less_console_noise_decorator
def setUp(self):
super().setUp()
self.user = create_user()
# Create a portfolio
self.portfolio = Portfolio.objects.create(organization_name="Test Portfolio", creator=self.user)
# Create a domain request with all required fields
self.complete_request = completed_domain_request(
name="complete.gov",
organization_name="Complete Org",
city="Washington",
state_territory="DC",
portfolio=self.portfolio,
status=DomainRequest.DomainRequestStatus.IN_REVIEW,
)
# Create a request that already has a suborganization
self.suborg = Suborganization.objects.create(name="Existing Suborg", portfolio=self.portfolio)
self.existing_suborg_request = completed_domain_request(
name="existing.gov",
organization_name="Existing Org",
city="New York",
state_territory="NY",
portfolio=self.portfolio,
sub_organization=self.suborg,
status=DomainRequest.DomainRequestStatus.IN_REVIEW,
)
# Create a request where org name matches portfolio name
self.matching_name_request = completed_domain_request(
name="matching.gov",
organization_name="Test Portfolio",
city="Boston",
state_territory="MA",
portfolio=self.portfolio,
user=self.user,
status=DomainRequest.DomainRequestStatus.IN_REVIEW,
)
def tearDown(self):
super().tearDown()
DomainRequest.objects.all().delete()
Suborganization.objects.all().delete()
Portfolio.objects.all().delete()
User.objects.all().delete()
@less_console_noise_decorator
def run_populate_requested_suborg(self):
"""Executes the populate_requested_suborg command"""
with patch(
"registrar.management.commands.utility.terminal_helper.TerminalHelper.query_yes_no_exit",
return_value=True,
):
call_command("populate_requested_suborg")
@less_console_noise_decorator
def test_populate_requested_suborg_complete_request(self):
"""Tests that complete requests are updated correctly"""
self.run_populate_requested_suborg()
self.complete_request.refresh_from_db()
# Verify fields were populated correctly
self.assertEqual(self.complete_request.requested_suborganization, "Complete Org")
self.assertEqual(self.complete_request.suborganization_city, "Washington")
self.assertEqual(self.complete_request.suborganization_state_territory, "DC")
@less_console_noise_decorator
def test_populate_requested_suborg_existing_suborg(self):
"""Tests that requests with existing suborgs are skipped"""
self.run_populate_requested_suborg()
self.existing_suborg_request.refresh_from_db()
# Verify the request wasn't modified
self.assertEqual(self.existing_suborg_request.sub_organization, self.suborg)
self.assertIsNone(self.existing_suborg_request.requested_suborganization)
self.assertIsNone(self.existing_suborg_request.suborganization_city)
self.assertIsNone(self.existing_suborg_request.suborganization_state_territory)
@less_console_noise_decorator
def test_populate_requested_suborg_matching_name(self):
"""Tests that requests with matching org/portfolio names are skipped"""
self.run_populate_requested_suborg()
self.matching_name_request.refresh_from_db()
# Verify the request wasn't modified since org name matches portfolio name
self.assertIsNone(self.matching_name_request.requested_suborganization)
self.assertIsNone(self.matching_name_request.suborganization_city)
self.assertIsNone(self.matching_name_request.suborganization_state_territory)