diff --git a/backend/audit/templates/audit/unlock-after-certification.html b/backend/audit/templates/audit/unlock-after-certification.html
index a224502c7f..abd430c156 100644
--- a/backend/audit/templates/audit/unlock-after-certification.html
+++ b/backend/audit/templates/audit/unlock-after-certification.html
@@ -3,13 +3,13 @@
{% block content %}
- {% if submission_status == target_status %}
+ {% if submission_status in target_statuses %}
{% else %}
-
This form is only accessible for submissions with a “Ready for Certification” status. This submission is not locked for certification.
+
This form is only accessible for submissions that have been locked for certification. This submission is not locked for certification.
{% endif %}
diff --git a/backend/audit/test_models.py b/backend/audit/test_models.py
index afca1b9b79..f662ebe112 100644
--- a/backend/audit/test_models.py
+++ b/backend/audit/test_models.py
@@ -88,6 +88,8 @@ def test_submission_status_transitions(self):
(
[
SingleAuditChecklist.STATUS.READY_FOR_CERTIFICATION,
+ SingleAuditChecklist.STATUS.AUDITOR_CERTIFIED,
+ SingleAuditChecklist.STATUS.AUDITEE_CERTIFIED,
],
SingleAuditChecklist.STATUS.IN_PROGRESS,
"transition_to_in_progress_again",
diff --git a/backend/audit/views/unlock_after_certification.py b/backend/audit/views/unlock_after_certification.py
index d2971685a2..319b3107e8 100644
--- a/backend/audit/views/unlock_after_certification.py
+++ b/backend/audit/views/unlock_after_certification.py
@@ -29,13 +29,17 @@ def get(self, request, *args, **kwargs):
try:
sac = SingleAuditChecklist.objects.get(report_id=report_id)
- target_status = SingleAuditChecklist.STATUS.READY_FOR_CERTIFICATION
+ target_statuses = [
+ SingleAuditChecklist.STATUS.READY_FOR_CERTIFICATION,
+ SingleAuditChecklist.STATUS.AUDITOR_CERTIFIED,
+ SingleAuditChecklist.STATUS.AUDITEE_CERTIFIED,
+ ]
context = {
"auditee_uei": sac.auditee_uei,
"auditee_name": sac.auditee_name,
"report_id": report_id,
"submission_status": sac.submission_status,
- "target_status": target_status,
+ "target_statuses": target_statuses,
}
return render(
From 0c76af746ef311c1eb0ecb234922f36aa148f1e2 Mon Sep 17 00:00:00 2001
From: Tim Ballard <1425377+timoballard@users.noreply.github.com>
Date: Fri, 5 Jan 2024 13:27:38 -0600
Subject: [PATCH 2/5] BUG: Pre-submission validation should remain checked
after certifications (#3144)
* first pass
* lint
---
.../audit/views/submission_progress_view.py | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/backend/audit/views/submission_progress_view.py b/backend/audit/views/submission_progress_view.py
index 2e12613a39..c05c24684e 100644
--- a/backend/audit/views/submission_progress_view.py
+++ b/backend/audit/views/submission_progress_view.py
@@ -137,7 +137,12 @@ def get(self, request, *args, **kwargs):
"completed_by": None,
},
"pre_submission_validation": {
- "completed": sac.submission_status == "ready_for_certification",
+ "completed": sac.submission_status
+ in [
+ SingleAuditChecklist.STATUS.READY_FOR_CERTIFICATION,
+ SingleAuditChecklist.STATUS.AUDITOR_CERTIFIED,
+ SingleAuditChecklist.STATUS.AUDITEE_CERTIFIED,
+ ],
"completed_date": None,
"completed_by": None,
# We want the user to always be able to run this check:
@@ -146,15 +151,18 @@ def get(self, request, *args, **kwargs):
"certification": {
"auditor_certified": bool(sac.auditor_certification),
"auditor_enabled": sac.submission_status
- == "ready_for_certification",
+ == SingleAuditChecklist.STATUS.READY_FOR_CERTIFICATION,
"auditee_certified": bool(sac.auditee_certification),
- "auditee_enabled": sac.submission_status == "auditor_certified",
+ "auditee_enabled": sac.submission_status
+ == SingleAuditChecklist.STATUS.AUDITOR_CERTIFIED,
},
"submission": {
- "completed": sac.submission_status == "submitted",
+ "completed": sac.submission_status
+ == SingleAuditChecklist.STATUS.SUBMITTED,
"completed_date": None,
"completed_by": None,
- "enabled": sac.submission_status == "auditee_certified",
+ "enabled": sac.submission_status
+ == SingleAuditChecklist.STATUS.AUDITEE_CERTIFIED,
},
"report_id": report_id,
"auditee_name": sac.auditee_name,
From a5bd210d6b4eed8829aac0c69a5fbe9727325832 Mon Sep 17 00:00:00 2001
From: Tadhg O'Higgins <2626258+tadhg-ohiggins@users.noreply.github.com>
Date: Fri, 5 Jan 2024 13:48:44 -0800
Subject: [PATCH 3/5] Add missing auditor certification fields to dissemination
(#3085)
* Add auditor certification fields to intake.
* Properly handle Django two-step of adding default value, then removing it.
---
backend/audit/intake_to_dissemination.py | 15 ++++++++--
backend/audit/test_intake_to_dissemination.py | 22 ++++++++++++++
backend/dissemination/docs.py | 2 ++
...7_general_auditor_certify_name_and_more.py | 30 +++++++++++++++++++
...r_general_auditor_certify_name_and_more.py | 28 +++++++++++++++++
backend/dissemination/models.py | 8 +++++
6 files changed, 102 insertions(+), 3 deletions(-)
create mode 100644 backend/dissemination/migrations/0007_general_auditor_certify_name_and_more.py
create mode 100644 backend/dissemination/migrations/0008_alter_general_auditor_certify_name_and_more.py
diff --git a/backend/audit/intake_to_dissemination.py b/backend/audit/intake_to_dissemination.py
index 51ce528e85..070d486e92 100644
--- a/backend/audit/intake_to_dissemination.py
+++ b/backend/audit/intake_to_dissemination.py
@@ -272,11 +272,10 @@ def load_general(self):
dissemination. This structure is a list with one entry, a
dissemination.models.General instance.
"""
-
general_information = self.single_audit_checklist.general_information
audit_information = self.single_audit_checklist.audit_information
auditee_certification = self.single_audit_checklist.auditee_certification
- # auditor_certification = self.single_audit_checklist.auditor_certification or {}
+ auditor_certification = self.single_audit_checklist.auditor_certification or {}
tribal_data_consent = self.single_audit_checklist.tribal_data_consent or {}
cognizant_agency = self.single_audit_checklist.cognizant_agency
oversight_agency = self.single_audit_checklist.oversight_agency
@@ -295,6 +294,12 @@ def load_general(self):
auditee_certify_title = auditee_certification["auditee_signature"][
"auditee_title"
]
+ auditor_certify_name = auditor_certification["auditor_signature"][
+ "auditor_name"
+ ]
+ auditor_certify_title = auditor_certification["auditor_signature"][
+ "auditor_title"
+ ]
auditor_certified_date = dates_by_status[status.AUDITOR_CERTIFIED]
auditee_certified_date = dates_by_status[status.AUDITEE_CERTIFIED]
elif self.mode == IntakeToDissemination.PRE_CERTIFICATION_REVIEW:
@@ -302,8 +307,10 @@ def load_general(self):
fac_accepted_date = submitted_date
auditee_certify_name = None
auditee_certify_title = None
- auditor_certified_date = None
auditee_certified_date = None
+ auditor_certify_name = None
+ auditor_certify_title = None
+ auditor_certified_date = None
total_amount_expended = self.single_audit_checklist.federal_awards[
"FederalAwards"
@@ -381,6 +388,8 @@ def load_general(self):
report_id=self.report_id,
auditee_certify_name=auditee_certify_name,
auditee_certify_title=auditee_certify_title,
+ auditor_certify_name=auditor_certify_name,
+ auditor_certify_title=auditor_certify_title,
cognizant_agency=cognizant_agency,
oversight_agency=oversight_agency,
date_created=self.single_audit_checklist.date_created,
diff --git a/backend/audit/test_intake_to_dissemination.py b/backend/audit/test_intake_to_dissemination.py
index 32925faa3b..a7b58d280e 100644
--- a/backend/audit/test_intake_to_dissemination.py
+++ b/backend/audit/test_intake_to_dissemination.py
@@ -106,6 +106,7 @@ def _create_sac(
additional_eins=self._fake_additional_eins(),
audit_information=self._fake_audit_information(),
auditee_certification=self._fake_auditee_certification(),
+ auditor_certification=self._fake_auditor_certification(),
tribal_data_consent=self._fake_tribal_data_consent(privacy_flag),
cognizant_agency=cognizant_agency,
oversight_agency=oversight_agency,
@@ -185,6 +186,27 @@ def _fake_auditee_certification():
},
}
+ @staticmethod
+ def _fake_auditor_certification():
+ fake = Faker()
+ return {
+ "auditor_certification": {
+ "has_no_PII": fake.boolean(),
+ "has_no_BII": fake.boolean(),
+ "meets_2CFR_specifications": fake.boolean(),
+ "is_2CFR_compliant": fake.boolean(),
+ "is_complete_and_accurate": fake.boolean(),
+ "has_engaged_auditor": fake.boolean(),
+ "is_issued_and_signed": fake.boolean(),
+ "is_FAC_releasable": fake.boolean(),
+ },
+ "auditor_signature": {
+ "auditor_name": fake.name(),
+ "auditor_title": fake.job(),
+ "auditor_certification_date_signed": fake.date(),
+ },
+ }
+
@staticmethod
def _fake_federal_awards():
return {
diff --git a/backend/dissemination/docs.py b/backend/dissemination/docs.py
index ebee925ad7..c32c28c987 100644
--- a/backend/dissemination/docs.py
+++ b/backend/dissemination/docs.py
@@ -152,6 +152,8 @@
significant_deficiency = "Data sources: SF-SAC 2013-2015: III/7/i; SF-SAC 2016-2018: III/4/j; SF-SAC 2019-2021: III/4/j; SF-SAC 2022: III/4/j Census mapping: FINDINGS, SIGNIFICANTDEFICIENCY"
auditee_certify_name = "Data sources: SF-SAC 1997-2000: I/6/g; SF-SAC 2001-2003: I/6/g; SF-SAC 2004-2007: I/6/g; SF-SAC 2008-2009: I/5/g; SF-SAC 2010-2012: I/5/g; SF-SAC 2013-2015: certifications; SF-SAC 2016-2018: certifications; SF-SAC 2019-2021: certifications; SF-SAC 2022: certifications Census mapping: GENERAL, AUDITEECERTIFYNAME"
auditee_certify_title = "Data sources: SF-SAC 1997-2000: I/6/g; SF-SAC 2001-2003: I/6/g; SF-SAC 2004-2007: I/6/g; SF-SAC 2008-2009: I/5/g; SF-SAC 2010-2012: I/5/g; SF-SAC 2013-2015: certifications; SF-SAC 2016-2018: certifications; SF-SAC 2019-2021: certifications; SF-SAC 2022: certifications Census mapping: GENERAL, AUDITEECERTIFYTITLE"
+auditor_certify_name = "Data sources: SF-SAC 1997-2000: I/6/g; SF-SAC 2001-2003: I/6/g; SF-SAC 2004-2007: I/6/g; SF-SAC 2008-2009: I/5/g; SF-SAC 2010-2012: I/5/g; SF-SAC 2013-2015: certifications; SF-SAC 2016-2018: certifications; SF-SAC 2019-2021: certifications; SF-SAC 2022: certifications Census mapping: UNKNOWN"
+auditor_certify_title = "Data sources: SF-SAC 1997-2000: I/6/g; SF-SAC 2001-2003: I/6/g; SF-SAC 2004-2007: I/6/g; SF-SAC 2008-2009: I/5/g; SF-SAC 2010-2012: I/5/g; SF-SAC 2013-2015: certifications; SF-SAC 2016-2018: certifications; SF-SAC 2019-2021: certifications; SF-SAC 2022: certifications Census mapping: UNKNOWN"
auditee_contact = "Data sources: SF-SAC 1997-2000: I/6/c; SF-SAC 2001-2003: I/6/c; SF-SAC 2004-2007: I/6/c; SF-SAC 2008-2009: I/5/c; SF-SAC 2010-2012: I/5/c; SF-SAC 2013-2015: I/5/c; SF-SAC 2016-2018: I/5/c; SF-SAC 2019-2021: I/5/c; SF-SAC 2022: I/5/c Census mapping: GENERAL, AUDITEECONTACT"
auditee_date_signed = "Data sources: SF-SAC 1997-2000: I/6/g; SF-SAC 2001-2003: I/6/g; SF-SAC 2004-2007: I/6/g; SF-SAC 2008-2009: I/5/g; SF-SAC 2010-2012: I/5/g; SF-SAC 2013-2015: certifications; SF-SAC 2016-2018: certifications; SF-SAC 2019-2021: certifications; SF-SAC 2022: certifications Census mapping: GENERAL, AUDITEEDATESIGNED"
auditee_email = "Data sources: SF-SAC 1997-2000: I/6/f; SF-SAC 2001-2003: I/6/f; SF-SAC 2004-2007: I/6/f; SF-SAC 2008-2009: I/5/f; SF-SAC 2010-2012: I/5/f; SF-SAC 2013-2015: I/5/f; SF-SAC 2016-2018: I/5/e; SF-SAC 2019-2021: I/5/e; SF-SAC 2022: I/5/e Census mapping: GENERAL, AUDITEEEMAIL"
diff --git a/backend/dissemination/migrations/0007_general_auditor_certify_name_and_more.py b/backend/dissemination/migrations/0007_general_auditor_certify_name_and_more.py
new file mode 100644
index 0000000000..b202bb1610
--- /dev/null
+++ b/backend/dissemination/migrations/0007_general_auditor_certify_name_and_more.py
@@ -0,0 +1,30 @@
+# Generated by Django 4.2.6 on 2023-12-26 19:42
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+ dependencies = [
+ ("dissemination", "0006_migrationchangerecord"),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name="general",
+ name="auditor_certify_name",
+ field=models.TextField(
+ default="DEFAULT_AUDITOR_CERTIFY_NAME",
+ help_text="Data sources: SF-SAC 1997-2000: I/6/g; SF-SAC 2001-2003: I/6/g; SF-SAC 2004-2007: I/6/g; SF-SAC 2008-2009: I/5/g; SF-SAC 2010-2012: I/5/g; SF-SAC 2013-2015: certifications; SF-SAC 2016-2018: certifications; SF-SAC 2019-2021: certifications; SF-SAC 2022: certifications Census mapping: UNKNOWN",
+ verbose_name="Name of Auditor Certifying Official",
+ ),
+ ),
+ migrations.AddField(
+ model_name="general",
+ name="auditor_certify_title",
+ field=models.TextField(
+ default="DEFAULT_AUDITOR_CERTIFY_TITLE",
+ help_text="Data sources: SF-SAC 1997-2000: I/6/g; SF-SAC 2001-2003: I/6/g; SF-SAC 2004-2007: I/6/g; SF-SAC 2008-2009: I/5/g; SF-SAC 2010-2012: I/5/g; SF-SAC 2013-2015: certifications; SF-SAC 2016-2018: certifications; SF-SAC 2019-2021: certifications; SF-SAC 2022: certifications Census mapping: UNKNOWN",
+ verbose_name="Title of Auditor Certifying Official",
+ ),
+ ),
+ ]
diff --git a/backend/dissemination/migrations/0008_alter_general_auditor_certify_name_and_more.py b/backend/dissemination/migrations/0008_alter_general_auditor_certify_name_and_more.py
new file mode 100644
index 0000000000..77da7506f4
--- /dev/null
+++ b/backend/dissemination/migrations/0008_alter_general_auditor_certify_name_and_more.py
@@ -0,0 +1,28 @@
+# Generated by Django 4.2.6 on 2023-12-26 20:07
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+ dependencies = [
+ ("dissemination", "0007_general_auditor_certify_name_and_more"),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name="general",
+ name="auditor_certify_name",
+ field=models.TextField(
+ help_text="Data sources: SF-SAC 1997-2000: I/6/g; SF-SAC 2001-2003: I/6/g; SF-SAC 2004-2007: I/6/g; SF-SAC 2008-2009: I/5/g; SF-SAC 2010-2012: I/5/g; SF-SAC 2013-2015: certifications; SF-SAC 2016-2018: certifications; SF-SAC 2019-2021: certifications; SF-SAC 2022: certifications Census mapping: UNKNOWN",
+ verbose_name="Name of Auditor Certifying Official",
+ ),
+ ),
+ migrations.AlterField(
+ model_name="general",
+ name="auditor_certify_title",
+ field=models.TextField(
+ help_text="Data sources: SF-SAC 1997-2000: I/6/g; SF-SAC 2001-2003: I/6/g; SF-SAC 2004-2007: I/6/g; SF-SAC 2008-2009: I/5/g; SF-SAC 2010-2012: I/5/g; SF-SAC 2013-2015: certifications; SF-SAC 2016-2018: certifications; SF-SAC 2019-2021: certifications; SF-SAC 2022: certifications Census mapping: UNKNOWN",
+ verbose_name="Title of Auditor Certifying Official",
+ ),
+ ),
+ ]
diff --git a/backend/dissemination/models.py b/backend/dissemination/models.py
index ad603b80be..8469752aa9 100644
--- a/backend/dissemination/models.py
+++ b/backend/dissemination/models.py
@@ -248,6 +248,14 @@ class General(models.Model):
"Title of Auditee Certifying Official",
help_text=docs.auditee_certify_title,
)
+ auditor_certify_name = models.TextField(
+ "Name of Auditor Certifying Official",
+ help_text=docs.auditor_certify_name,
+ )
+ auditor_certify_title = models.TextField(
+ "Title of Auditor Certifying Official",
+ help_text=docs.auditor_certify_title,
+ )
auditee_contact_name = models.TextField(
"Name of Auditee Contact",
help_text=docs.auditee_contact,
From 42477595ed30d59eef9fe67afc5e88689b74c299 Mon Sep 17 00:00:00 2001
From: Tadhg O'Higgins <2626258+tadhg-ohiggins@users.noreply.github.com>
Date: Fri, 5 Jan 2024 13:58:19 -0800
Subject: [PATCH 4/5] Do not populate Audit Information form with
historical-only values (#3148)
* WIP checkin.
* Filter out historical_only=True values in audit.get_agency_names.get_audit_info_lists.
---
backend/audit/forms.py | 62 ++++-----------
backend/audit/get_agency_names.py | 57 ++++++++-----
.../templates/audit/audit-info-form.html | 24 +++---
.../output/audit/audit-info-values.json | 60 --------------
.../source/audit/audit-info-values.json | 79 +++++++++++++++++++
.../source/audit/audit-info-values.jsonnet | 3 -
backend/schemas/source/base/Base.libsonnet | 6 +-
backend/schemas/source/base/GAAP.libsonnet | 72 ++---------------
8 files changed, 152 insertions(+), 211 deletions(-)
delete mode 100644 backend/schemas/output/audit/audit-info-values.json
create mode 100644 backend/schemas/source/audit/audit-info-values.json
delete mode 100644 backend/schemas/source/audit/audit-info-values.jsonnet
diff --git a/backend/audit/forms.py b/backend/audit/forms.py
index e558b6e8f9..31cadb46a0 100644
--- a/backend/audit/forms.py
+++ b/backend/audit/forms.py
@@ -1,5 +1,10 @@
from django import forms
-from config.settings import AGENCY_NAMES
+from config.settings import (
+ AGENCY_NAMES,
+ GAAP_RESULTS,
+ SP_FRAMEWORK_BASIS,
+ SP_FRAMEWORK_OPINIONS,
+)
class UploadReportForm(forms.Form):
@@ -17,6 +22,10 @@ class UploadReportForm(forms.Form):
upload_report = forms.FileField()
+def _kvpair(info):
+ return (info["key"], info["value"])
+
+
class AuditInfoForm(forms.Form):
def clean_booleans(self):
data = self.cleaned_data
@@ -29,53 +38,10 @@ def clean_booleans(self):
return data
choices_YoN = (("True", "Yes"), ("False", "No"))
- # These should probably have the lowercase values from Jsonnet:
- choices_GAAP = (
- ("unmodified_opinion", "Unmodified opinion"),
- ("qualified_opinion", "Qualified opinion"),
- ("adverse_opinion", "Adverse opinion"),
- ("disclaimer_of_opinion", "Disclaimer of opinion"),
- (
- "not_gaap",
- "Financial statements were not prepared in accordance with GAAP but were prepared in accordance with a special purpose framework.",
- ),
- )
- choices_SP_FRAMEWORK_BASIS = (
- (
- "cash_basis",
- "Cash basis",
- ),
- (
- "tax_basis",
- "Tax basis",
- ),
- (
- "contractual_basis",
- "Contractual basis",
- ),
- (
- "other_basis",
- "Other basis",
- ),
- )
- choices_SP_FRAMEWORK_OPINIONS = (
- (
- "unmodified_opinion",
- "Unmodified opinion",
- ),
- (
- "qualified_opinion",
- "Qualified opinion",
- ),
- (
- "adverse_opinion",
- "Adverse opinion",
- ),
- (
- "disclaimer_of_opinion",
- "Disclaimer of opinion",
- ),
- )
+
+ choices_GAAP = [_kvpair(_) for _ in GAAP_RESULTS]
+ choices_SP_FRAMEWORK_BASIS = [_kvpair(_) for _ in SP_FRAMEWORK_BASIS]
+ choices_SP_FRAMEWORK_OPINIONS = [_kvpair(_) for _ in SP_FRAMEWORK_OPINIONS]
choices_agencies = list((i, i) for i in AGENCY_NAMES)
diff --git a/backend/audit/get_agency_names.py b/backend/audit/get_agency_names.py
index 55f236d96c..e1f20e52ae 100644
--- a/backend/audit/get_agency_names.py
+++ b/backend/audit/get_agency_names.py
@@ -1,4 +1,3 @@
-from collections import OrderedDict
from pathlib import Path
import csv
import glob
@@ -6,37 +5,57 @@
import os
-# Pull in agency names from the most recent cfda-agencies-YYYYMMDD.csv
-# Scraps rows with non-int agency nums and rows with empty agency names.
def get_agency_names():
- # Lets build a dictionary of names, mapping the agency number
- # to the name.
- _agency_names = dict()
- agency_names = OrderedDict()
+ """
+ From a CSV of agency data, return a dictionary with the agency codes as
+ keys and the names as values, in order:
+
+ {
+ "00": "None",
+ "01": "African Development Foundation",
+ "02": "Agency for International Development",
+ …
+ "97": "Department of Homeland Security",
+ "98": "Agency for International Development",
+ "99": "Miscellaneous",
+ }
+
+ Pull in agency names from the most recent cfda-agencies-YYYYMMDD.csv
+ Scrap rows with non-numeric agency nums and rows with empty agency names.
+ """
# Grab all the files, but we'll then sort and grab the latest one.
# MCJ: We need to figure out how to keep ALNs up-to-date...
# https://github.com/GSA-TTS/FAC/issues/1555
list_of_files = glob.glob("./schemas/source/data/cfda-agencies*.csv")
latest_file = max(list_of_files, key=os.path.getctime)
- with open(latest_file, "r") as file:
- csvreader = csv.reader(file)
- csvreader = sorted(csvreader, key=lambda x: x[0])
- for row in csvreader:
- if row[0].isnumeric() and row[1] != "":
- _agency_names[row[0]] = row[1]
- # Now, create an OrderedDict of all the values
- agency_names = OrderedDict(sorted(_agency_names.items(), key=lambda tupl: tupl[0]))
+ with open(latest_file, "r", newline="", encoding="UTF-8") as file:
+ agencies = csv.reader(file)
+ sorted_agencies = sorted(agencies, key=lambda x: x[0])
- return agency_names
+ valid_agencies = filter(lambda r: r[0].isnumeric() and r[1] != "", sorted_agencies)
+ return {row[0]: row[1] for row in valid_agencies}
def get_audit_info_lists(name):
"""
Get lists of internal values and friendly strings for the responses to the
Audit Information form section.
+
+ Filter out anything with historical_only set to true.
+
+ get_audit_info_lists("gaap_results")
+ =>
+ [
+ {
+ "value": "Unmodified opinion",
+ "key": "unmodified_opinion",
+ "property": "UNMODIFIED_OPINION"
+ },
+ …
+ ]
"""
- jsonfile = Path("./schemas/output/audit/audit-info-values.json")
+ jsonfile = Path("./schemas/source/audit/audit-info-values.json")
jobj = json.loads(jsonfile.read_text(encoding="UTF-8"))
- # Returns a list of dictionaries with the keys 'tag' and 'readable'
- return jobj[name]
+
+ return [info for info in jobj[name] if not info.get("historical_only") is True]
diff --git a/backend/audit/templates/audit/audit-info-form.html b/backend/audit/templates/audit/audit-info-form.html
index cde3614af5..6883b38d86 100644
--- a/backend/audit/templates/audit/audit-info-form.html
+++ b/backend/audit/templates/audit/audit-info-form.html
@@ -29,14 +29,14 @@ Financial statements
Select any of the following that apply.
{% for pair in gaap_results %}
-
- {{ pair.readable }}
+ value="{{ pair.key }}"
+ {% if pair.key in form.cleaned_data.gaap_results %}checked{% endif %} />
+ {{ pair.value }}
{% endfor %}
{{ form.errors.gaap_results|striptags }}
@@ -46,13 +46,13 @@ Financial statements
What was the special purpose framework? Select only one.
{% for pair in sp_framework_basis %}
-
- {{ pair.readable }}
+ value="{{ pair.key }}"
+ {% if pair.key in form.cleaned_data.sp_framework_basis %}checked{% endif %} />
+ {{ pair.value }}
{% endfor %}
{{ form.errors.gaap_results|striptags }}
@@ -88,13 +88,13 @@ Financial statements
Select any of the following that apply.
{% for pair in sp_framework_opinions %}
-
- {{ pair.readable }}
+ value="{{ pair.key }}"
+ {% if pair.key in form.cleaned_data.sp_framework_opinions %}checked{% endif %} />
+ {{ pair.value }}
{% endfor %}
{{ form.errors.gaap_results|striptags }}
diff --git a/backend/schemas/output/audit/audit-info-values.json b/backend/schemas/output/audit/audit-info-values.json
deleted file mode 100644
index 968dc75559..0000000000
--- a/backend/schemas/output/audit/audit-info-values.json
+++ /dev/null
@@ -1,60 +0,0 @@
-{
- "gaap_results": [
- {
- "readable": "Unmodified opinion",
- "tag": "unmodified_opinion"
- },
- {
- "readable": "Qualified opinion",
- "tag": "qualified_opinion"
- },
- {
- "readable": "Adverse opinion",
- "tag": "adverse_opinion"
- },
- {
- "readable": "Disclaimer of opinion",
- "tag": "disclaimer_of_opinion"
- },
- {
- "readable": "Financial statements were not prepared in accordance with GAAP but were prepared in accordance with a special purpose framework.",
- "tag": "not_gaap"
- }
- ],
- "sp_framework_basis": [
- {
- "readable": "Cash basis",
- "tag": "cash_basis"
- },
- {
- "readable": "Tax basis",
- "tag": "tax_basis"
- },
- {
- "readable": "Contractual basis",
- "tag": "contractual_basis"
- },
- {
- "readable": "Other basis",
- "tag": "other_basis"
- }
- ],
- "sp_framework_opinions": [
- {
- "readable": "Unmodified opinion",
- "tag": "unmodified_opinion"
- },
- {
- "readable": "Qualified opinion",
- "tag": "qualified_opinion"
- },
- {
- "readable": "Adverse opinion",
- "tag": "adverse_opinion"
- },
- {
- "readable": "Disclaimer of opinion",
- "tag": "disclaimer_of_opinion"
- }
- ]
-}
diff --git a/backend/schemas/source/audit/audit-info-values.json b/backend/schemas/source/audit/audit-info-values.json
new file mode 100644
index 0000000000..f19a7c6214
--- /dev/null
+++ b/backend/schemas/source/audit/audit-info-values.json
@@ -0,0 +1,79 @@
+{
+ "gaap_results": [
+ {
+ "value": "Unmodified opinion",
+ "key": "unmodified_opinion",
+ "property": "UNMODIFIED_OPINION"
+ },
+ {
+ "value": "Qualified opinion",
+ "key": "qualified_opinion",
+ "property": "QUALIFIED_OPINION"
+ },
+ {
+ "value": "Adverse opinion",
+ "key": "adverse_opinion",
+ "property": "ADVERSE_OPINION"
+ },
+ {
+ "value": "Disclaimer of opinion",
+ "key": "disclaimer_of_opinion",
+ "property": "DISCLAIMER_OF_OPINION"
+ },
+ {
+ "value": "Financial statements were not prepared in accordance with GAAP but were prepared in accordance with a special purpose framework.",
+ "key": "not_gaap",
+ "property": "NOT_GAAP"
+ }
+ ],
+ "sp_framework_basis": [
+ {
+ "value": "Cash basis",
+ "key": "cash_basis",
+ "property": "CASH_BASIS"
+ },
+ {
+ "value": "Tax basis",
+ "key": "tax_basis",
+ "property": "TAX_BASIS"
+ },
+ {
+ "value": "Contractual basis",
+ "key": "contractual_basis",
+ "property": "CONTRACTUAL_BASIS"
+ },
+ {
+ "value": "Regulatory basis",
+ "key": "regulatory_basis",
+ "property": "REGULATORY_BASIS",
+ "historical_only": true
+ },
+ {
+ "value": "Other basis",
+ "key": "other_basis",
+ "property": "OTHER_BASIS"
+ }
+ ],
+ "sp_framework_opinions": [
+ {
+ "value": "Unmodified opinion",
+ "key": "unmodified_opinion",
+ "property": "UNMODIFIED_OPINION"
+ },
+ {
+ "value": "Qualified opinion",
+ "key": "qualified_opinion",
+ "property": "QUALIFIED_OPINION"
+ },
+ {
+ "value": "Adverse opinion",
+ "key": "adverse_opinion",
+ "property": "ADVERSE_OPINION"
+ },
+ {
+ "value": "Disclaimer of opinion",
+ "key": "disclaimer_of_opinion",
+ "property": "DISCLAIMER_OF_OPINION"
+ }
+ ]
+}
diff --git a/backend/schemas/source/audit/audit-info-values.jsonnet b/backend/schemas/source/audit/audit-info-values.jsonnet
deleted file mode 100644
index 903acbb27b..0000000000
--- a/backend/schemas/source/audit/audit-info-values.jsonnet
+++ /dev/null
@@ -1,3 +0,0 @@
-local GAAP = import '../base/GAAP.libsonnet';
-
-GAAP
diff --git a/backend/schemas/source/base/Base.libsonnet b/backend/schemas/source/base/Base.libsonnet
index eb7709ba34..27a1168142 100644
--- a/backend/schemas/source/base/Base.libsonnet
+++ b/backend/schemas/source/base/Base.libsonnet
@@ -222,15 +222,15 @@ local Enum = {
},
GAAPResults: Types.string {
description: 'GAAP Results (Audit Information)',
- enum: std.map(function(pair) pair.tag, GAAP.gaap_results),
+ enum: std.map(function(pair) pair.key, GAAP.gaap_results),
},
SP_Framework_Basis: Types.string {
description: 'SP Framework Basis (Audit Information)',
- enum: std.map(function(pair) pair.tag, GAAP.sp_framework_basis),
+ enum: std.map(function(pair) pair.key, GAAP.sp_framework_basis),
},
SP_Framework_Opinions: Types.string {
description: 'SP Framework Opinions (Audit Information)',
- enum: std.map(function(pair) pair.tag, GAAP.sp_framework_opinions),
+ enum: std.map(function(pair) pair.key, GAAP.sp_framework_opinions),
},
UnitedStatesStateAbbr: {
description: 'US States 2-letter abbreviations',
diff --git a/backend/schemas/source/base/GAAP.libsonnet b/backend/schemas/source/base/GAAP.libsonnet
index 2b0232e20f..811baada3f 100644
--- a/backend/schemas/source/base/GAAP.libsonnet
+++ b/backend/schemas/source/base/GAAP.libsonnet
@@ -1,67 +1,7 @@
-local gaap_results = [
- {
- readable: 'Unmodified opinion',
- tag: 'unmodified_opinion',
- },
- {
- readable: 'Qualified opinion',
- tag: 'qualified_opinion',
- },
- {
- readable: 'Adverse opinion',
- tag: 'adverse_opinion',
- },
- {
- readable: 'Disclaimer of opinion',
- tag: 'disclaimer_of_opinion',
- },
- {
- readable: 'Financial statements were not prepared in accordance with GAAP but were prepared in accordance with a special purpose framework.',
- tag: 'not_gaap',
- },
-];
-local sp_framework_basis = [
- {
- readable: 'Cash basis',
- tag: 'cash_basis',
- },
- {
- readable: 'Tax basis',
- tag: 'tax_basis',
- },
- {
- readable: 'Contractual basis',
- tag: 'contractual_basis',
- },
- {
- readable: 'Regulatory basis',
- tag: 'regulatory_basis',
- },
- {
- readable: 'Other basis',
- tag: 'other_basis',
- },
-];
-local sp_framework_opinions = [
- {
- readable: 'Unmodified opinion',
- tag: 'unmodified_opinion',
- },
- {
- readable: 'Qualified opinion',
- tag: 'qualified_opinion',
- },
- {
- readable: 'Adverse opinion',
- tag: 'adverse_opinion',
- },
- {
- readable: 'Disclaimer of opinion',
- tag: 'disclaimer_of_opinion',
- },
-];
+local audit_info_data = import '../audit/audit-info-values.json';
-{ gaap_results: gaap_results,
- sp_framework_basis: sp_framework_basis,
- sp_framework_opinions: sp_framework_opinions,
-}
\ No newline at end of file
+{
+ gaap_results: audit_info_data.gaap_results,
+ sp_framework_basis: audit_info_data.sp_framework_basis,
+ sp_framework_opinions: audit_info_data.sp_framework_opinions,
+}
From a2c41b3096cb3dcac101efc5edda4c75ae62a616 Mon Sep 17 00:00:00 2001
From: Tadhg O'Higgins <2626258+tadhg-ohiggins@users.noreply.github.com>
Date: Mon, 8 Jan 2024 12:36:51 -0800
Subject: [PATCH 5/5] Fix dissemination migration chain. (#3164)
---
...nd_more.py => 0008_general_auditor_certify_name_and_more.py} | 2 +-
...e.py => 0009_alter_general_auditor_certify_name_and_more.py} | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
rename backend/dissemination/migrations/{0007_general_auditor_certify_name_and_more.py => 0008_general_auditor_certify_name_and_more.py} (94%)
rename backend/dissemination/migrations/{0008_alter_general_auditor_certify_name_and_more.py => 0009_alter_general_auditor_certify_name_and_more.py} (95%)
diff --git a/backend/dissemination/migrations/0007_general_auditor_certify_name_and_more.py b/backend/dissemination/migrations/0008_general_auditor_certify_name_and_more.py
similarity index 94%
rename from backend/dissemination/migrations/0007_general_auditor_certify_name_and_more.py
rename to backend/dissemination/migrations/0008_general_auditor_certify_name_and_more.py
index b202bb1610..ffbbd67ecd 100644
--- a/backend/dissemination/migrations/0007_general_auditor_certify_name_and_more.py
+++ b/backend/dissemination/migrations/0008_general_auditor_certify_name_and_more.py
@@ -5,7 +5,7 @@
class Migration(migrations.Migration):
dependencies = [
- ("dissemination", "0006_migrationchangerecord"),
+ ("dissemination", "0007_remove_migrationchangerecord_census_data_and_more"),
]
operations = [
diff --git a/backend/dissemination/migrations/0008_alter_general_auditor_certify_name_and_more.py b/backend/dissemination/migrations/0009_alter_general_auditor_certify_name_and_more.py
similarity index 95%
rename from backend/dissemination/migrations/0008_alter_general_auditor_certify_name_and_more.py
rename to backend/dissemination/migrations/0009_alter_general_auditor_certify_name_and_more.py
index 77da7506f4..89e2e34b2c 100644
--- a/backend/dissemination/migrations/0008_alter_general_auditor_certify_name_and_more.py
+++ b/backend/dissemination/migrations/0009_alter_general_auditor_certify_name_and_more.py
@@ -5,7 +5,7 @@
class Migration(migrations.Migration):
dependencies = [
- ("dissemination", "0007_general_auditor_certify_name_and_more"),
+ ("dissemination", "0008_general_auditor_certify_name_and_more"),
]
operations = [