-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4490 from GSA-TTS/main
- Loading branch information
Showing
21 changed files
with
811 additions
and
726 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,7 +10,7 @@ We want to ensure a welcoming environment for all of our projects. Our staff fol | |
|
||
We adhere to the [18F Open Source Policy](https://github.com/18f/open-source-policy). If you have any questions, just [send us an email](mailto:[email protected]). | ||
|
||
As part of a U.S. government agency, the General Services Administration (GSA)’s Technology Transformation Services (TTS) takes seriously our responsibility to protect the public’s information, including financial and personal information, from unwarranted disclosure. For more information about security and vulnerability disclosure for our projects, please read our [18F Vulnerability Disclosure Policy](https://18f.gsa.gov/vulnerability-disclosure-policy/). | ||
As part of a U.S. government agency, the General Services Administration (GSA)’s Technology Transformation Services (TTS) takes seriously our responsibility to protect the public’s information, including financial and personal information, from unwarranted disclosure. For more information about security and vulnerability disclosure for our projects, please read the [GSA Vulnerability Disclosure Policy](https://www.gsa.gov/vulnerability-disclosure-policy/). | ||
|
||
## Public domain | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
129 changes: 129 additions & 0 deletions
129
backend/audit/cross_validation/check_finding_prior_references.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
from audit.fixtures.excel import ( | ||
FINDINGS_UNIFORM_TEMPLATE_DEFINITION, | ||
) | ||
from .errors import err_prior_ref_not_found | ||
from dissemination.models import ( | ||
Finding, | ||
General, | ||
) | ||
|
||
from django.conf import settings | ||
|
||
from datetime import date | ||
import json | ||
|
||
|
||
def check_finding_prior_references(sac_dict, *_args, **_kwargs): | ||
""" | ||
Check that prior references numbers point to findings that actually exist | ||
in a previously submitted report | ||
""" | ||
# Importing here to avoid circular import | ||
from audit.models import SacValidationWaiver | ||
|
||
if SacValidationWaiver.TYPES.PRIOR_REFERENCES in sac_dict.get("waiver_types", []): | ||
return [] | ||
|
||
all_sections = sac_dict.get("sf_sac_sections") | ||
findings_uniform_guidance_section = ( | ||
all_sections.get("findings_uniform_guidance") or {} | ||
) | ||
findings_uniform_guidance = findings_uniform_guidance_section.get( | ||
"findings_uniform_guidance_entries", [] | ||
) | ||
all_prior_refs = _get_prior_refs(findings_uniform_guidance) | ||
|
||
# No prior reference numbers to validate | ||
if not all_prior_refs: | ||
return [] | ||
|
||
general_information = all_sections.get("general_information") | ||
auditee_uei = general_information["auditee_uei"] | ||
audit_year = date.fromisoformat( | ||
general_information["auditee_fiscal_period_start"] | ||
).year | ||
|
||
# UEIs only become reliable as of 2022, so don't bother invalidating | ||
# prior references before that | ||
if audit_year < 2023: | ||
return [] | ||
|
||
# Get the report_ids for previous reports | ||
previous_report_ids = General.objects.filter(auditee_uei=auditee_uei).values_list( | ||
"report_id", flat=True | ||
) | ||
errors = [] | ||
|
||
# Validate all prior reference numbers for each award | ||
for award_ref, prior_refs_strings in all_prior_refs.items(): | ||
prior_refs = prior_refs_strings.split(",") | ||
_validate_prior_refs( | ||
prior_refs, | ||
award_ref, | ||
auditee_uei, | ||
previous_report_ids, | ||
errors, | ||
) | ||
|
||
return errors | ||
|
||
|
||
def _get_prior_refs(findings_uniform_guidance): | ||
""" | ||
Returns a dict that maps award references to a list of prior references | ||
strings | ||
""" | ||
all_prior_refs = {} | ||
|
||
for finding in findings_uniform_guidance: | ||
if finding["findings"]["repeat_prior_reference"] == "Y": | ||
award_ref = finding["program"]["award_reference"] | ||
cur_prior_refs = finding["findings"]["prior_references"] | ||
all_prior_refs[award_ref] = cur_prior_refs | ||
|
||
return all_prior_refs | ||
|
||
|
||
TEMPLATE_DEFINITION_PATH = ( | ||
settings.XLSX_TEMPLATE_JSON_DIR / FINDINGS_UNIFORM_TEMPLATE_DEFINITION | ||
) | ||
FINDINGS_TEMPLATE = json.loads(TEMPLATE_DEFINITION_PATH.read_text(encoding="utf-8")) | ||
|
||
|
||
def _validate_prior_refs( | ||
prior_refs, award_ref, auditee_uei, previous_report_ids, errors | ||
): | ||
""" | ||
Performs validation on the given list of prior reference numbers | ||
""" | ||
first_row = FINDINGS_TEMPLATE["title_row"] | ||
|
||
for index, prior_ref in enumerate(prior_refs): | ||
current_row = first_row + index + 1 | ||
prior_ref_year = prior_ref[:4] | ||
|
||
if prior_ref_year.isnumeric() and int(prior_ref_year) < 2022: | ||
# Skip validation for pre-UEI prior references | ||
continue | ||
elif not previous_report_ids: | ||
errors.append( | ||
{ | ||
"error": err_prior_ref_not_found( | ||
auditee_uei, prior_ref, award_ref, current_row | ||
), | ||
} | ||
) | ||
|
||
continue | ||
elif not Finding.objects.filter( | ||
report_id__in=previous_report_ids, | ||
reference_number=prior_ref, | ||
).exists(): | ||
# Error if we can't find the prior finding in previous reports | ||
errors.append( | ||
{ | ||
"error": err_prior_ref_not_found( | ||
auditee_uei, prior_ref, award_ref, current_row | ||
), | ||
} | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.