Skip to content

Commit 4ae29be

Browse files
authored
Merge pull request #2982 from fedspendingtransparency/qat
Merge QAT -> Staging
2 parents 1c161c6 + b0db1cf commit 4ae29be

File tree

3 files changed

+115
-40
lines changed

3 files changed

+115
-40
lines changed

usaspending_api/etl/management/commands/load_submission.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -167,19 +167,20 @@ def get_broker_submission(self):
167167
)
168168
) AS history
169169
from
170-
(select distinct
171-
submission_id,
172-
publish_history_id,
173-
certify_history_id
174-
from published_files_history
175-
where submission_id = %s) as distinct_pairings
176-
left join
177-
publish_history as ph
178-
on distinct_pairings.publish_history_id = ph.publish_history_id
179-
left join
180-
certify_history as ch
181-
on distinct_pairings.certify_history_id = ch.certify_history_id
182-
group by distinct_pairings.submission_id)
170+
(
171+
select distinct
172+
submission_id,
173+
publish_history_id,
174+
certify_history_id
175+
from published_files_history
176+
where submission_id = %s
177+
) as distinct_pairings
178+
left outer join
179+
publish_history as ph using (publish_history_id)
180+
left outer join
181+
certify_history as ch using (certify_history_id)
182+
group by distinct_pairings.submission_id
183+
)
183184
select
184185
s.submission_id,
185186
(
@@ -203,9 +204,8 @@ def get_broker_submission(self):
203204
pch.history
204205
from
205206
submission as s
206-
join
207-
publish_certify_history as pch
208-
on pch.submission_id = s.submission_id
207+
inner join
208+
publish_certify_history as pch using (submission_id)
209209
""",
210210
[self.submission_id],
211211
)
Lines changed: 73 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
import json
12
import pytest
3+
24
from model_mommy import mommy
35
from rest_framework import status
46

57

6-
url = "/api/v2/reporting/agencies/{agency_data}/submission_history/"
8+
url = "/api/v2/reporting/agencies/{agency}/{fy}/{period}/submission_history/"
79

810

911
@pytest.fixture
@@ -17,6 +19,9 @@ def setup_test_data(db):
1719
published_date="2019-07-16 16:09:52.125837-04",
1820
certified_date="2019-07-16 16:09:52.125837-04",
1921
toptier_code="020",
22+
history=json.loads(
23+
'[{"certified_date": "2019-07-16T16:09:52.125837Z", "published_date": "2019-07-16T16:09:52.125837Z"}]'
24+
),
2025
)
2126
mommy.make(
2227
"submissions.SubmissionAttributes",
@@ -26,6 +31,10 @@ def setup_test_data(db):
2631
published_date="2020-08-17 18:37:21.605023-04",
2732
certified_date="2020-08-17 18:37:21.605023-04",
2833
toptier_code="020",
34+
history=json.loads(
35+
'[{"certified_date": "2020-08-17T18:37:21.605023Z", "published_date": "2020-08-17T18:37:21.605023Z"},'
36+
+ '{"certified_date": "2017-08-14T14:17:00.729315Z", "published_date": "2017-08-14T14:17:00.729315Z"}]'
37+
),
2938
)
3039
mommy.make(
3140
"submissions.SubmissionAttributes",
@@ -34,42 +43,90 @@ def setup_test_data(db):
3443
reporting_fiscal_period=7,
3544
published_date="2017-08-14 14:17:00.729315-04",
3645
certified_date="2017-08-14 14:17:00.729315-04",
37-
toptier_code="020",
46+
toptier_code="075",
47+
history=json.loads(
48+
'[{"certified_date": "2017-08-14T14:17:00.729315Z", "published_date": "2017-08-14T14:17:00.729315Z"}]'
49+
),
3850
)
3951
mommy.make(
4052
"submissions.SubmissionAttributes",
41-
submission_id=4,
42-
reporting_fiscal_year=2019,
43-
reporting_fiscal_period=7,
44-
published_date="2017-08-14 14:17:00.729315-04",
45-
certified_date="2017-08-14 14:17:00.729315-04",
46-
toptier_code="075",
53+
submission_id=10,
54+
reporting_fiscal_year=2020,
55+
reporting_fiscal_period=12,
56+
published_date="2021-02-16 18:20:00.729315-04",
57+
certified_date="2021-02-16 18:17:00.729315-04",
58+
toptier_code="222",
59+
history=json.loads(
60+
'[{"certified_date": null, "published_date": "2020-01-17T18:37:21.605023Z"},'
61+
+ '{"certified_date": null, "published_date": "2020-01-14T14:17:00.729315Z"},'
62+
+ '{"certified_date": "2021-02-14T14:17:00.729315Z", "published_date": "2021-02-14T14:16:00.729315Z"},'
63+
+ '{"certified_date": "2021-02-16T14:17:00.729315Z", "published_date": "2021-02-16T14:16:00.729315Z"}]'
64+
),
4765
)
4866

4967

5068
def test_basic_success(client, setup_test_data):
51-
resp = client.get(url.format(agency_data="020/2019/6"))
69+
resp = client.get(url.format(agency="020", fy=2019, period=6))
5270
assert resp.status_code == status.HTTP_200_OK
5371
response = resp.json()
5472
assert len(response["results"]) == 1
5573
assert response["results"] == [
56-
{"publication_date": "2019-07-16T20:09:52.125837Z", "certification_date": "2019-07-16T20:09:52.125837Z"}
74+
{"publication_date": "2019-07-16T16:09:52.125837Z", "certification_date": "2019-07-16T16:09:52.125837Z"}
75+
]
76+
77+
resp = client.get(url.format(agency="075", fy=2019, period=7))
78+
assert resp.status_code == status.HTTP_200_OK
79+
response = resp.json()
80+
assert len(response["results"]) == 1
81+
assert response["results"] == [
82+
{"publication_date": "2017-08-14T14:17:00.729315Z", "certification_date": "2017-08-14T14:17:00.729315Z"}
5783
]
5884

5985

6086
def test_multiple_submissions(client, setup_test_data):
61-
resp = client.get(url.format(agency_data="020/2019/7"))
87+
resp = client.get(url.format(agency="020", fy=2019, period=7))
88+
assert resp.status_code == status.HTTP_200_OK
89+
response = resp.json()
90+
assert len(response["results"]) == 2
91+
assert response["results"] == [
92+
{"publication_date": "2020-08-17T18:37:21.605023Z", "certification_date": "2020-08-17T18:37:21.605023Z"},
93+
{"publication_date": "2017-08-14T14:17:00.729315Z", "certification_date": "2017-08-14T14:17:00.729315Z"},
94+
]
95+
96+
resp = client.get(url.format(agency="020", fy=2019, period=7) + "?sort=publication_date&order=asc")
6297
assert resp.status_code == status.HTTP_200_OK
6398
response = resp.json()
6499
assert len(response["results"]) == 2
65100
assert response["results"] == [
66-
{"publication_date": "2020-08-17T22:37:21.605023Z", "certification_date": "2020-08-17T22:37:21.605023Z"},
67-
{"publication_date": "2017-08-14T18:17:00.729315Z", "certification_date": "2017-08-14T18:17:00.729315Z"},
101+
{"publication_date": "2017-08-14T14:17:00.729315Z", "certification_date": "2017-08-14T14:17:00.729315Z"},
102+
{"publication_date": "2020-08-17T18:37:21.605023Z", "certification_date": "2020-08-17T18:37:21.605023Z"},
68103
]
69-
resp = client.get(url.format(agency_data="075/2019/7"))
104+
105+
106+
def test_no_data(client, setup_test_data):
107+
resp = client.get(url.format(agency="222", fy=2021, period=12))
108+
assert resp.status_code == status.HTTP_204_NO_CONTENT
109+
110+
111+
def test_certification_nulls(client, setup_test_data):
112+
resp = client.get(url.format(agency="222", fy=2020, period=12) + "?sort=certification_date&order=desc")
70113
assert resp.status_code == status.HTTP_200_OK
71114
response = resp.json()
72-
assert len(response["results"]) == 1
115+
assert len(response["results"]) == 4
116+
assert response["results"] == [
117+
{"certification_date": "2021-02-16T14:17:00.729315Z", "publication_date": "2021-02-16T14:16:00.729315Z"},
118+
{"certification_date": "2021-02-14T14:17:00.729315Z", "publication_date": "2021-02-14T14:16:00.729315Z"},
119+
{"certification_date": None, "publication_date": "2020-01-17T18:37:21.605023Z"},
120+
{"certification_date": None, "publication_date": "2020-01-14T14:17:00.729315Z"},
121+
]
122+
123+
resp = client.get(url.format(agency="222", fy=2020, period=12) + "?sort=certification_date&order=asc")
124+
assert resp.status_code == status.HTTP_200_OK
125+
response = resp.json()
126+
assert len(response["results"]) == 4
73127
assert response["results"] == [
74-
{"publication_date": "2017-08-14T18:17:00.729315Z", "certification_date": "2017-08-14T18:17:00.729315Z"}
128+
{"certification_date": None, "publication_date": "2020-01-14T14:17:00.729315Z"},
129+
{"certification_date": None, "publication_date": "2020-01-17T18:37:21.605023Z"},
130+
{"certification_date": "2021-02-14T14:17:00.729315Z", "publication_date": "2021-02-14T14:16:00.729315Z"},
131+
{"certification_date": "2021-02-16T14:17:00.729315Z", "publication_date": "2021-02-16T14:16:00.729315Z"},
75132
]

usaspending_api/reporting/v2/views/submission_history.py

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
from django.db.models import F
21
from rest_framework.response import Response
32

43
from usaspending_api.agency.v2.views.agency_base import AgencyBase, PaginationMixin
5-
4+
from usaspending_api.common.exceptions import NoDataFoundException
5+
from usaspending_api.common.helpers.date_helper import now
66
from usaspending_api.common.helpers.generic_helper import get_pagination_metadata
77
from usaspending_api.submissions.models import SubmissionAttributes
88

@@ -17,14 +17,32 @@ def get(self, request, toptier_code, fiscal_year, fiscal_period):
1717
self.sortable_columns = ["publication_date", "certification_date"]
1818
self.default_sort_column = "publication_date"
1919
self.validate_fiscal_period({"fiscal_period": int(fiscal_period)})
20-
results = (
20+
record = list(
2121
SubmissionAttributes.objects.filter(
22-
toptier_code=toptier_code, reporting_fiscal_year=fiscal_year, reporting_fiscal_period=fiscal_period
23-
)
24-
.annotate(publication_date=F("published_date"), certification_date=F("certified_date"))
25-
.order_by(f"{'-' if self.pagination.sort_order == 'desc' else ''}{self.pagination.sort_key}")
26-
.values("publication_date", "certification_date")
22+
toptier_code=toptier_code,
23+
reporting_fiscal_year=fiscal_year,
24+
reporting_fiscal_period=fiscal_period,
25+
submission_window_id__submission_reveal_date__lte=now(),
26+
).values_list("history", flat=True)
2727
)
28+
29+
if len(record) == 0:
30+
raise NoDataFoundException("No Agency Account Submission History records match the provided parameters")
31+
32+
# Convoluted list comprehension and sort to
33+
# A) construct the dict list
34+
# B) add secondary sort key and handle nulls in `certification_date` for sorting
35+
results = sorted(
36+
[
37+
{"publication_date": row["published_date"], "certification_date": row["certified_date"]}
38+
for row in record[0]
39+
],
40+
key=lambda x: x["publication_date"]
41+
if self.pagination.sort_key == "publication_date"
42+
else (x["certification_date"] or "", x["publication_date"]),
43+
reverse=self.pagination.sort_order == "desc",
44+
)
45+
2846
page_metadata = get_pagination_metadata(len(results), self.pagination.limit, self.pagination.page)
2947
results = results[self.pagination.lower_limit : self.pagination.upper_limit]
3048
return Response(

0 commit comments

Comments
 (0)