From 9a8317c3ea8a3d42f0cf9ada2234d21389979c9a Mon Sep 17 00:00:00 2001 From: "Hassan D. M. Sambo" Date: Tue, 8 Oct 2024 17:06:32 -0400 Subject: [PATCH] Adding a logic to convert award reference from 4 to 5 digits (#4361) * Adding a logic to convert award reference from 4 to 5 digits * Updated fixtures to reflect code change * Updated workbook fixture names --- ...ards-has-award-refs-of-mixed-lengths.xlsx} | Bin ...ings-has-award-refs-of-mixed-lengths.xlsx} | Bin backend/audit/intakelib/transforms/runners.py | 4 ++ .../xform_resize_award_references.py | 27 ++++++++ .../test_xform_resize_award_references.py | 53 ++++++++++++++++ ...federal-awards-audit-findings-entries.json | 60 +++++++++--------- 6 files changed, 114 insertions(+), 30 deletions(-) rename backend/audit/fixtures/workbooks/{should_fail/federal-awards/award-refs-of-mixed-lengths.xlsx => should_pass/federal_awards/federal-awards-has-award-refs-of-mixed-lengths.xlsx} (100%) rename backend/audit/fixtures/workbooks/{should_fail/audit-findings/award-refs-of-mixed-lengths.xlsx => should_pass/federal_awards_audit_findings/audit-findings-has-award-refs-of-mixed-lengths.xlsx} (100%) create mode 100644 backend/audit/intakelib/transforms/xform_resize_award_references.py create mode 100644 backend/audit/test_xform_resize_award_references.py diff --git a/backend/audit/fixtures/workbooks/should_fail/federal-awards/award-refs-of-mixed-lengths.xlsx b/backend/audit/fixtures/workbooks/should_pass/federal_awards/federal-awards-has-award-refs-of-mixed-lengths.xlsx similarity index 100% rename from backend/audit/fixtures/workbooks/should_fail/federal-awards/award-refs-of-mixed-lengths.xlsx rename to backend/audit/fixtures/workbooks/should_pass/federal_awards/federal-awards-has-award-refs-of-mixed-lengths.xlsx diff --git a/backend/audit/fixtures/workbooks/should_fail/audit-findings/award-refs-of-mixed-lengths.xlsx b/backend/audit/fixtures/workbooks/should_pass/federal_awards_audit_findings/audit-findings-has-award-refs-of-mixed-lengths.xlsx similarity index 100% rename from backend/audit/fixtures/workbooks/should_fail/audit-findings/award-refs-of-mixed-lengths.xlsx rename to backend/audit/fixtures/workbooks/should_pass/federal_awards_audit_findings/audit-findings-has-award-refs-of-mixed-lengths.xlsx diff --git a/backend/audit/intakelib/transforms/runners.py b/backend/audit/intakelib/transforms/runners.py index 67863afbf3..48ed5ef234 100644 --- a/backend/audit/intakelib/transforms/runners.py +++ b/backend/audit/intakelib/transforms/runners.py @@ -1,6 +1,8 @@ import logging from copy import deepcopy +from .xform_resize_award_references import resize_award_reference + from .xform_all_amount_expended_need_to_be_integers import ( convert_amount_expended_to_integers, ) @@ -112,9 +114,11 @@ def run_all_secondary_auditors_transforms(ir): regenerate_uniform_cluster_names, reformat_federal_agency_prefix, generate_cfda_keys, + resize_award_reference, ] audit_findings_transforms = general_transforms + [ reformat_award_reference, reformat_prior_references, + resize_award_reference, ] diff --git a/backend/audit/intakelib/transforms/xform_resize_award_references.py b/backend/audit/intakelib/transforms/xform_resize_award_references.py new file mode 100644 index 0000000000..822ce8090a --- /dev/null +++ b/backend/audit/intakelib/transforms/xform_resize_award_references.py @@ -0,0 +1,27 @@ +import logging +from audit.intakelib.intermediate_representation import ( + get_range_by_name, + replace_range_by_name, +) +from audit.intakelib.checks.check_finding_award_references_pattern import ( + AWARD_LEN_5_DIGITS, +) + +logger = logging.getLogger(__name__) + + +def resize_award_reference(ir): + references = get_range_by_name(ir, "award_reference") + new_values = list(map(_format_reference, references["values"])) + new_ir = replace_range_by_name(ir, "award_reference", new_values) + + return new_ir + + +def _format_reference(v): + + if v and len(v) < AWARD_LEN_5_DIGITS: + parts = v.split("-") + padding = "0" * (AWARD_LEN_5_DIGITS - len(v)) + return f"{parts[0]}-{padding}{parts[1]}" + return v diff --git a/backend/audit/test_xform_resize_award_references.py b/backend/audit/test_xform_resize_award_references.py new file mode 100644 index 0000000000..90648c87a1 --- /dev/null +++ b/backend/audit/test_xform_resize_award_references.py @@ -0,0 +1,53 @@ +from unittest.mock import patch + +from django.test import SimpleTestCase + +from audit.intakelib.transforms.xform_resize_award_references import ( + _format_reference, + resize_award_reference, +) + + +class TestResizeAwardReference(SimpleTestCase): + + @patch("audit.intakelib.transforms.xform_resize_award_references.get_range_by_name") + @patch( + "audit.intakelib.transforms.xform_resize_award_references.replace_range_by_name" + ) + def test_resize_award_reference( + self, mock_replace_range_by_name, mock_get_range_by_name + ): + """Test the resize_award_reference function""" + ir = [] + references = { + "values": [ + "AWARD-123", # Will need padding + "AWARD-4567", # Will need padding + "AWARD-12345", # Correct length, no padding + None, # No change for None + ] + } + expected_new_values = [ + "AWARD-00123", + "AWARD-04567", + "AWARD-12345", + None, + ] + + mock_get_range_by_name.return_value = references + new_ir = resize_award_reference(ir) + + mock_get_range_by_name.assert_called_once_with(ir, "award_reference") + mock_replace_range_by_name.assert_called_once_with( + ir, "award_reference", expected_new_values + ) + + self.assertEqual(new_ir, mock_replace_range_by_name.return_value) + + def test_format_reference(self): + """Test the _format_reference function""" + self.assertEqual(_format_reference("AWARD-123"), "AWARD-00123") + self.assertEqual(_format_reference("AWARD-4567"), "AWARD-04567") + self.assertEqual(_format_reference("AWARD-12345"), "AWARD-12345") + self.assertEqual(_format_reference(None), None) + self.assertEqual(_format_reference(""), "") diff --git a/backend/data_fixtures/audit/test_data_entries/federal-awards-audit-findings-entries.json b/backend/data_fixtures/audit/test_data_entries/federal-awards-audit-findings-entries.json index b4c87b82af..6a3576e6d9 100644 --- a/backend/data_fixtures/audit/test_data_entries/federal-awards-audit-findings-entries.json +++ b/backend/data_fixtures/audit/test_data_entries/federal-awards-audit-findings-entries.json @@ -1,30 +1,30 @@ -[ - { - "award_reference": "AWARD-0001", - "compliance_requirement": "AB", - "reference_number": "2023-001", - "repeat_prior_reference": "Y", - "prior_references": "2020-001", - "is_valid": "Y", - "questioned_costs": "N", - "significant_deficiency": "N", - "other_matters": "N", - "other_findings": "N", - "modified_opinion": "Y", - "material_weakness": "N" - }, - { - "award_reference": "AWARD-0002", - "compliance_requirement": "E", - "reference_number": "2023-001", - "repeat_prior_reference": "N", - "prior_references": "N/A", - "is_valid": "Y", - "questioned_costs": "N", - "significant_deficiency": "N", - "other_matters": "Y", - "other_findings": "N", - "modified_opinion": "N", - "material_weakness": "Y" - } -] +[ + { + "award_reference": "AWARD-00001", + "compliance_requirement": "AB", + "reference_number": "2023-001", + "repeat_prior_reference": "Y", + "prior_references": "2020-001", + "is_valid": "Y", + "questioned_costs": "N", + "significant_deficiency": "N", + "other_matters": "N", + "other_findings": "N", + "modified_opinion": "Y", + "material_weakness": "N" + }, + { + "award_reference": "AWARD-00002", + "compliance_requirement": "E", + "reference_number": "2023-001", + "repeat_prior_reference": "N", + "prior_references": "N/A", + "is_valid": "Y", + "questioned_costs": "N", + "significant_deficiency": "N", + "other_matters": "Y", + "other_findings": "N", + "modified_opinion": "N", + "material_weakness": "Y" + } +]