diff --git a/backend/audit/intakelib/checks/check_finding_reference_year.py b/backend/audit/intakelib/checks/check_finding_reference_year.py
new file mode 100644
index 0000000000..5a4dbd9a39
--- /dev/null
+++ b/backend/audit/intakelib/checks/check_finding_reference_year.py
@@ -0,0 +1,47 @@
+import logging
+from django.core.exceptions import ValidationError
+from audit.intakelib.intermediate_representation import (
+ get_range_by_name,
+)
+from audit.intakelib.common import (
+ get_message,
+ build_cell_error_tuple,
+)
+
+from audit.context import get_sac_from_context
+from audit.intakelib.common.util import get_range_start_row
+
+logger = logging.getLogger(__name__)
+
+
+# DESCRIPTION
+# Finding references should be in 20##-### format where the first four
+# digits match the audit_year.
+
+
+def finding_reference_year(ir, is_gsa_migration=False):
+ references = get_range_by_name(ir, "reference_number")
+ range_start = int(get_range_start_row(references))
+ errors = []
+ if is_gsa_migration:
+ return errors
+ sac = get_sac_from_context()
+ audit_date = sac.general_information["auditee_fiscal_period_end"]
+ audit_year = int(audit_date.split("-")[0])
+ for index, reference in enumerate(references["values"]):
+ year = int(reference.split("-")[0])
+ if audit_year != year:
+ errors.append(
+ build_cell_error_tuple(
+ ir,
+ references,
+ index,
+ get_message("check_invalid_finding_reference_year").format(
+ reference, index + range_start, audit_year
+ ),
+ )
+ )
+
+ if len(errors) > 0:
+ logger.info("Raising a validation error.")
+ raise ValidationError(errors)
diff --git a/backend/audit/intakelib/checks/runners.py b/backend/audit/intakelib/checks/runners.py
index 5e0e502f2d..fb5a4457c4 100644
--- a/backend/audit/intakelib/checks/runners.py
+++ b/backend/audit/intakelib/checks/runners.py
@@ -56,6 +56,7 @@
from .check_findings_grid_validation import findings_grid_validation
from .check_finding_prior_references_pattern import prior_references_pattern
from .check_finding_reference_pattern import finding_reference_pattern
+from .check_finding_reference_year import finding_reference_year
from .check_aln_prefix_pattern import aln_agency_prefix
logger = logging.getLogger(__name__)
@@ -111,6 +112,7 @@
award_references_pattern,
prior_references_pattern,
finding_reference_pattern,
+ finding_reference_year,
no_repeat_findings,
findings_grid_validation,
# See ticket #4385 for more information on why this check is disabled
diff --git a/backend/audit/intakelib/common/error_messages.py b/backend/audit/intakelib/common/error_messages.py
index 88ea14df37..170cf560f6 100644
--- a/backend/audit/intakelib/common/error_messages.py
+++ b/backend/audit/intakelib/common/error_messages.py
@@ -69,6 +69,7 @@
"check_aln_three_digit_extension_invalid": "The three digit extension should follow one of these formats: ###, RD#, or U##, where # represents a number",
"check_prior_references_invalid": "Prior references must be N/A or a comma-separated list of values in the format 20##-###, for example, 2019-001, 2019-002",
"check_finding_reference_invalid": "Finding references must be in the format 20##-### where the first four digits are a year after 2010, for example, 2019-001, 2019-002",
+ "check_invalid_finding_reference_year": "The reference year in the finding reference {} declared in row {} does not match the audit year {}",
"check_award_references_invalid": "Combining award references of 4 and 5-digit lengths is not allowed. If needed, zero-pad this number to make it 5 digits",
"check_aln_prefix_invalid": "The federal agency prefix should be a two-digit value, for example, 10",
"check_additional_award_identification_present": "Missing additional award identification",
diff --git a/backend/audit/views/views.py b/backend/audit/views/views.py
index c5a87acf72..1448055a7c 100644
--- a/backend/audit/views/views.py
+++ b/backend/audit/views/views.py
@@ -44,6 +44,7 @@
)
from audit.utils import FORM_SECTION_HANDLERS
+from audit.context import set_sac_to_context
from dissemination.remove_workbook_artifacts import remove_workbook_artifacts
from dissemination.file_downloads import get_download_url, get_filename
from dissemination.models import General
@@ -233,14 +234,14 @@ def post(self, request, *_args, **kwargs):
and "auditee_uei" in sac.general_information
):
auditee_uei = sac.general_information["auditee_uei"]
+ with set_sac_to_context(sac):
+ audit_data = self._extract_and_validate_data(
+ form_section, excel_file, auditee_uei
+ )
- audit_data = self._extract_and_validate_data(
- form_section, excel_file, auditee_uei
- )
-
- self._save_audit_data(sac, form_section, audit_data)
+ self._save_audit_data(sac, form_section, audit_data)
- return redirect("/")
+ return redirect("/")
except SingleAuditChecklist.DoesNotExist as err:
logger.warning("no SingleAuditChecklist found with report ID %s", report_id)