Skip to content
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

Search: filter by auditee state #2888

Merged
merged 2 commits into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions backend/dissemination/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class SearchForm(forms.Form):
cog_or_oversight = forms.CharField(required=False)
agency_name = forms.CharField(required=False)
audit_year = forms.MultipleChoiceField(choices=AY_choices, required=False)
auditee_state = forms.CharField(required=False)

# Display params
limit = forms.CharField(required=False)
Expand Down
9 changes: 9 additions & 0 deletions backend/dissemination/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ def search_general(
cog_or_oversight=None,
agency_name=None,
audit_years=None,
auditee_state=None,
include_private=False,
):
query = Q()
Expand All @@ -23,6 +24,7 @@ def search_general(
query.add(_get_end_date_match_query(end_date), Q.AND)
query.add(_get_cog_or_oversight_match_query(agency_name, cog_or_oversight), Q.AND)
query.add(_get_audit_years_match_query(audit_years), Q.AND)
query.add(_get_auditee_state_match_query(auditee_state), Q.AND)

if not include_private:
query.add(Q(is_public=True), Q.AND)
Expand Down Expand Up @@ -167,3 +169,10 @@ def _get_audit_years_match_query(audit_years):
return Q()

return Q(audit_year__in=audit_years)


def _get_auditee_state_match_query(auditee_state):
if not auditee_state:
return Q()

return Q(auditee_state__in=[auditee_state])
13 changes: 13 additions & 0 deletions backend/dissemination/templates/search.html
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,19 @@ <h3>Filters</h3>
name="agency_name"
value="{{ form.cleaned_data.agency_name }}" />
</div>
<div class="usa-form-group">
<label class="usa-label" for="auditee_state">
State
</label>
<select class="usa-select" id="auditee_state" name="auditee_state" aria-required="false">
<option value>- Select -</option>
{% for state in state_abbrevs %}
<option value="{{ state }}" {% if form.cleaned_data.auditee_state == state %}selected{% endif %}>
{{ state }}
</option>
{% endfor %}
</select>
</div>
</div>
{% comment %} Submission {% endcomment %}
<div class="search-submit">
Expand Down
29 changes: 29 additions & 0 deletions backend/dissemination/test_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,14 +223,43 @@ def test_audit_year(self):
results = search_general(
audit_years=[2016],
)
assert_all_results_public(self, results)
self.assertEqual(len(results), 0)

results = search_general(
audit_years=[2020],
)
assert_all_results_public(self, results)
self.assertEqual(len(results), 1)

results = search_general(
audit_years=[2020, 2021, 2022],
)
assert_all_results_public(self, results)
self.assertEqual(len(results), 3)

def test_auditee_state(self):
"""Given a state, search_general should return only records with a matching auditee_state"""
al = baker.make(General, is_public=True, auditee_state="AL")
baker.make(General, is_public=True, auditee_state="AK")
baker.make(
General,
is_public=True,
auditee_state="AZ",
audit_year="2020",
oversight_agency="01",
auditee_uei="not-looking-for-this-uei",
)

# there should be on result for AL
results = search_general(auditee_state="AL")

assert_all_results_public(self, results)
self.assertEqual(len(results), 1)
self.assertEqual(results[0], al)

# there should be no results for WI
results = search_general(auditee_state="WI")

assert_all_results_public(self, results)
self.assertEqual(len(results), 0)
14 changes: 13 additions & 1 deletion backend/dissemination/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
from audit.file_downloads import get_download_url, get_filename
from audit.models import SingleAuditChecklist

from config.settings import STATE_ABBREVS

from dissemination.forms import SearchForm
from dissemination.search import search_general
from dissemination.mixins import ReportAccessRequiredMixin
Expand Down Expand Up @@ -41,7 +43,14 @@ class Search(View):
def get(self, request, *args, **kwargs):
form = SearchForm()

return render(request, "search.html", {"form": form})
return render(
request,
"search.html",
{
"form": form,
"state_abbrevs": STATE_ABBREVS,
},
)

def post(self, request, *args, **kwargs):
form = SearchForm(request.POST)
Expand All @@ -59,6 +68,7 @@ def post(self, request, *args, **kwargs):
audit_years = [
int(year) for year in form.cleaned_data["audit_year"]
] # Cast strings from HTML to int
auditee_state = form.cleaned_data["auditee_state"]

# TODO: Add a limit choice field to the form
limit = form.cleaned_data["limit"] or 30
Expand All @@ -77,6 +87,7 @@ def post(self, request, *args, **kwargs):
cog_or_oversight=cog_or_oversight,
agency_name=agency_name,
audit_years=audit_years,
auditee_state=auditee_state,
include_private=include_private,
)
results_count = results.count()
Expand All @@ -100,6 +111,7 @@ def post(self, request, *args, **kwargs):

context = context | {
"form": form,
"state_abbrevs": STATE_ABBREVS,
"limit": limit,
"results": results,
"results_count": results_count,
Expand Down