-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cross validation and waivers for prior references #4443
Merged
Merged
Changes from 21 commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
2a9987e
Adding check_finding_prior_references and tests
phildominguez-gsa b17c5b5
Cleanup
phildominguez-gsa c02637e
Adding test_get_prior_refs_no_repeat_prior_reference
phildominguez-gsa 7c387ea
Removing unused fields
phildominguez-gsa a606d23
Changing EIN for UEI
phildominguez-gsa d8cf285
Replacing audit_year with auditee_fiscal_period_start and fixing erro…
phildominguez-gsa e732aea
Checking for prior refs earlier
phildominguez-gsa af203ef
Ignoring prior refs before 2022
phildominguez-gsa 81b9172
Checking for reports from prior ref's year
phildominguez-gsa 8e16196
Tests can now generate prior reports from priof ref numbers
phildominguez-gsa 491cfc9
Reducing complexity; adding comments
phildominguez-gsa b95f789
Supporting validation waiver
phildominguez-gsa 96f043f
Adding admin prior ref waiver creation case
phildominguez-gsa 347427c
Lint
phildominguez-gsa 21baea8
Querying all previous reports for prior refs
phildominguez-gsa a11b79d
Lint
phildominguez-gsa 2510a29
Removing report_id exclusion
phildominguez-gsa 0a8fd85
Updating cypress tests to use 2023 submission
phildominguez-gsa d015d94
Skipping validation for old prior refs
phildominguez-gsa 6afdbad
Numeric string check
phildominguez-gsa e9d3327
Fixing test wb
phildominguez-gsa 0db3780
Removing redundant N/A check
phildominguez-gsa bc36971
Reworking error message
phildominguez-gsa 03672d6
Error message tweak
phildominguez-gsa File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
122 changes: 122 additions & 0 deletions
122
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,122 @@ | ||
from .errors import ( | ||
err_prior_no_report, | ||
err_bad_repeat_prior_reference, | ||
err_prior_ref_not_found, | ||
) | ||
from dissemination.models import ( | ||
Finding, | ||
General, | ||
) | ||
|
||
from datetime import date | ||
|
||
|
||
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 | ||
|
||
|
||
def _validate_prior_refs( | ||
prior_refs, award_ref, auditee_uei, previous_report_ids, errors | ||
): | ||
""" | ||
Performs validation on the given list of prior reference numbers | ||
""" | ||
for prior_ref in prior_refs: | ||
prior_ref_year = prior_ref[:4] | ||
|
||
if prior_ref == "N/A": | ||
errors.append( | ||
{ | ||
"error": err_bad_repeat_prior_reference(award_ref), | ||
} | ||
) | ||
|
||
continue | ||
elif 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_no_report(auditee_uei, prior_ref), | ||
} | ||
) | ||
|
||
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(prior_ref), | ||
} | ||
) |
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.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feel free to remove (or keep) this check. Since we are enforcing validation for year > 2022 and we have these validations (v1 and v2) at intake time it is unlikely to have a case with
finding["findings"]["repeat_prior_reference"] == "Y"
andprior_ref == "N/A"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed