diff --git a/src/registrar/management/commands/load_senior_official_table.py b/src/registrar/management/commands/load_senior_official_table.py index d28b1f451..4da874426 100644 --- a/src/registrar/management/commands/load_senior_official_table.py +++ b/src/registrar/management/commands/load_senior_official_table.py @@ -34,7 +34,7 @@ class Command(BaseCommand): For each item in this CSV, a SeniorOffical record will be added. Note: - If the row is missing a first_name, last_name, or title - it will not be added. + If the row is SO data - it will not be added. """, prompt_title="Do you wish to load records into the SeniorOfficial table?", ) @@ -45,7 +45,7 @@ class Command(BaseCommand): existing_agencies = FederalAgency.objects.all() # Read the CSV - added_senior_officials, skipped_rows, updated_rows = [], [], [] + added_senior_officials, skipped_rows = [], [] with open(federal_cio_csv_path, "r") as requested_file: for row in csv.DictReader(requested_file): # Note: the csv doesn't have a phone field, but we can try to pull one anyway. @@ -57,48 +57,48 @@ class Command(BaseCommand): "phone": row.get("Phone"), } + # Clean the returned data + for key, value in so_kwargs.items(): + if isinstance(value, str): + so_kwargs[key] = value.strip() + # Handle the federal_agency record seperately (db call) agency_name = row.get("Agency").strip() if row.get("Agency") else None + if agency_name: + so_kwargs["federal_agency"] = existing_agencies.filter(agency=agency_name).first() - # Only first_name, last_name, and title are required - required_fields = ["first_name", "last_name", "title"] - if row and all(so_kwargs[field] for field in required_fields): - - # Get the underlying federal agency record - if agency_name: - so_kwargs["federal_agency"] = existing_agencies.filter(agency=agency_name).first() + # Check if at least one field has a non-empty value + if row and any(so_kwargs.values()): + + # WORKAROUND: Placeholder value for first name, + # as not having these makes it impossible to access through DJA. + old_first_name = so_kwargs["first_name"] + if not so_kwargs["first_name"]: + so_kwargs["first_name"] = "-" # Create a new SeniorOfficial object new_so = SeniorOfficial(**so_kwargs) + # Store a variable for the console logger + if any([old_first_name, new_so.last_name]): + record_display = new_so + else: + record_display = so_kwargs + # Before adding this record, check to make sure we aren't adding a duplicate. - existing_field = existing_senior_officials.filter( - first_name=so_kwargs.get("first_name"), - last_name=so_kwargs.get("last_name"), - title=so_kwargs.get("title"), - ).first() - if not existing_field: + duplicate_field = existing_senior_officials.filter(**so_kwargs).exists() + if not duplicate_field: added_senior_officials.append(new_so) - message = f"Added record: {new_so}" + message = f"Creating record: {record_display}" TerminalHelper.colorful_logger("INFO", "OKCYAN", message) else: - duplicate_field = existing_senior_officials.filter(**so_kwargs).first() - if not duplicate_field: - # If we can, just update the row instead - for field, value in so_kwargs.items(): - if getattr(existing_field, field) != value: - setattr(existing_field, field, value) - updated_rows.append(existing_field) - message = f"Updating record: {existing_field}" - TerminalHelper.colorful_logger("INFO", "OKBLUE", message) - else: - # if this field is a duplicate, don't do anything - skipped_rows.append(duplicate_field) - message = f"Skipping add on duplicate record: {duplicate_field}" - TerminalHelper.colorful_logger("WARNING", "YELLOW", message) + # if this field is a duplicate, don't do anything + skipped_rows.append(row) + message = f"Skipping add on duplicate record: {record_display}" + TerminalHelper.colorful_logger("WARNING", "YELLOW", message) else: skipped_rows.append(row) - message = f"Skipping row (missing first_name, last_name, or title): {row}" + message = f"Skipping row (no data was found): {row}" TerminalHelper.colorful_logger("WARNING", "YELLOW", message) # Bulk create the SO fields @@ -108,14 +108,6 @@ class Command(BaseCommand): added_message = f"Added {len(added_senior_officials)} records" TerminalHelper.colorful_logger("INFO", "OKGREEN", added_message) - # Bulk update the SO fields (if any) - if len(updated_rows) > 0: - updated_fields = ["first_name", "last_name", "title", "email", "phone", "federal_agency"] - SeniorOfficial.objects.bulk_update(updated_rows, updated_fields) - - skipped_message = f"Updated {len(updated_rows)} records" - TerminalHelper.colorful_logger("INFO", "OKBLUE", skipped_message) - if len(skipped_rows) > 0: skipped_message = f"Skipped {len(skipped_rows)} records" TerminalHelper.colorful_logger("WARNING", "MAGENTA", skipped_message) diff --git a/src/registrar/migrations/0114_federalagency_initials_federalagency_is_fceb_and_more.py b/src/registrar/migrations/0114_federalagency_initials_federalagency_is_fceb_and_more.py index c149e8b93..d0caa6670 100644 --- a/src/registrar/migrations/0114_federalagency_initials_federalagency_is_fceb_and_more.py +++ b/src/registrar/migrations/0114_federalagency_initials_federalagency_is_fceb_and_more.py @@ -1,4 +1,4 @@ -# Generated by Django 4.2.10 on 2024-07-29 15:51 +# Generated by Django 4.2.10 on 2024-07-29 20:36 from django.db import migrations, models import django.db.models.deletion @@ -35,4 +35,19 @@ class Migration(migrations.Migration): to="registrar.federalagency", ), ), + migrations.AlterField( + model_name="seniorofficial", + name="first_name", + field=models.CharField(blank=True, null=True, verbose_name="first name"), + ), + migrations.AlterField( + model_name="seniorofficial", + name="last_name", + field=models.CharField(blank=True, null=True, verbose_name="last name"), + ), + migrations.AlterField( + model_name="seniorofficial", + name="title", + field=models.CharField(blank=True, null=True, verbose_name="title / role"), + ), ] diff --git a/src/registrar/models/senior_official.py b/src/registrar/models/senior_official.py index cd55c681d..38ce4f35d 100644 --- a/src/registrar/models/senior_official.py +++ b/src/registrar/models/senior_official.py @@ -12,20 +12,20 @@ class SeniorOfficial(TimeStampedModel): """ first_name = models.CharField( - null=False, - blank=False, + null=True, + blank=True, verbose_name="first name", ) last_name = models.CharField( - null=False, - blank=False, + null=True, + blank=True, verbose_name="last name", ) title = models.CharField( - null=False, - blank=False, + null=True, + blank=True, verbose_name="title / role", )