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

Add sorting by case number and by advisory opinions number in legal/search #5246

Merged
merged 1 commit into from
Jan 24, 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
20 changes: 16 additions & 4 deletions tests/integration/test_advisory_opinions.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ def test_pending_ao(self, get_bucket):
expected_ao = {
"type": "advisory_opinions",
"no": "2017-01",
"ao_no": "2017-01",
"ao_year": 2017,
"ao_serial": 1,
"doc_id": "advisory_opinions_2017-01",
"name": "An AO name",
"summary": "An AO summary",
Expand Down Expand Up @@ -330,6 +333,9 @@ def test_ao_offsets(self, get_bucket):
expected_ao1 = {
"type": "advisory_opinions",
"no": "2015-01",
"ao_no": "2015-01",
"ao_year": 2015,
"ao_serial": 1,
"doc_id": "advisory_opinions_2015-01",
"name": "AO name1",
"summary": "AO summary1",
Expand All @@ -351,8 +357,11 @@ def test_ao_offsets(self, get_bucket):
"entities": [],
}
expected_ao2 = {
"no": "2015-02",
"type": "advisory_opinions",
"no": "2015-02",
"ao_no": "2015-02",
"ao_year": 2015,
"ao_serial": 2,
"doc_id": "advisory_opinions_2015-02",
"name": "An AO name2",
"summary": "An AO summary2",
Expand All @@ -376,6 +385,9 @@ def test_ao_offsets(self, get_bucket):
expected_ao3 = {
"type": "advisory_opinions",
"no": "2016-01",
"ao_no": "2016-01",
"ao_year": 2016,
"ao_serial": 1,
"doc_id": "advisory_opinions_2016-01",
"name": "An AO name3",
"summary": "An AO summary3",
Expand All @@ -401,13 +413,13 @@ def test_ao_offsets(self, get_bucket):
self.create_ao(3, expected_ao3)

gen = get_advisory_opinions(None)
assert (next(gen)) == expected_ao1
assert (next(gen)) == expected_ao2
assert (next(gen)) == expected_ao3
assert (next(gen)) == expected_ao2
assert (next(gen)) == expected_ao1

gen = get_advisory_opinions('2015-02')
assert (next(gen)) == expected_ao2
assert (next(gen)) == expected_ao3
assert (next(gen)) == expected_ao2

def create_document(self, ao_id, document, filename='201801_C.pdf'):
self.connection.execute(
Expand Down
13 changes: 11 additions & 2 deletions tests/integration/test_current_cases.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ def test_simple_mur(self, get_bucket):
'mur_type': 'current',
'election_cycles': [2016],
'doc_id': 'mur_1',
'case_serial': 1,
'published_flg': True,
'participants': [],
'subjects': [mur_subject],
Expand Down Expand Up @@ -66,6 +67,7 @@ def test_unpublished_mur(self, get_bucket):
'mur_type': 'current',
'election_cycles': [2016],
'doc_id': 'mur_101',
'case_serial': 101,
'published_flg': False,
'participants': [],
'subjects': [mur_subject],
Expand Down Expand Up @@ -100,6 +102,7 @@ def test_simple_adr(self, get_bucket):
'name': 'Simple ADR',
'election_cycles': [2016],
'doc_id': 'adr_1',
'case_serial': 1,
'published_flg': True,
'participants': [],
'non_monetary_terms': [],
Expand Down Expand Up @@ -186,6 +189,7 @@ def test_admin_fine(self, get_bucket):
'no': '1',
'name': 'Big Admin Fine',
'doc_id': 'af_1',
'case_serial': 1,
'published_flg': True,
'documents': [],
'commission_votes': [{'action': None, 'vote_date': None}],
Expand Down Expand Up @@ -268,6 +272,7 @@ def test_mur_with_participants_and_documents(self, get_bucket, get_credential):
expected_mur = {
"type": "murs",
'no': '1',
'case_serial': 1,
'name': 'MUR with participants',
'mur_type': 'current',
'published_flg': True,
Expand Down Expand Up @@ -446,6 +451,7 @@ def test_mur_with_disposition(self, get_bucket, get_credential):
'participants': [],
'no': '1',
'doc_id': 'mur_1',
'case_serial': 1,
'published_flg': True,
'mur_type': 'current',
'name': 'Open Elections LLC',
Expand All @@ -468,6 +474,7 @@ def test_mur_offsets(self, get_bucket):
'mur_type': 'current',
'election_cycles': [2016],
'doc_id': 'mur_1',
'case_serial': 1,
'published_flg': True,
'participants': [],
'subjects': [mur_subject],
Expand All @@ -488,6 +495,7 @@ def test_mur_offsets(self, get_bucket):
'mur_type': 'current',
'election_cycles': [2016],
'doc_id': 'mur_2',
'case_serial': 2,
'published_flg': True,
'participants': [],
'subjects': [mur_subject],
Expand All @@ -508,6 +516,7 @@ def test_mur_offsets(self, get_bucket):
'mur_type': 'current',
'election_cycles': [2016],
'doc_id': 'mur_3',
'case_serial': 3,
'published_flg': True,
'participants': [],
'subjects': [mur_subject],
Expand Down Expand Up @@ -544,9 +553,9 @@ def test_mur_offsets(self, get_bucket):
)

gen = get_cases('MUR')
assert (next(gen)) == expected_mur1
assert (next(gen)) == expected_mur2
assert (next(gen)) == expected_mur3
assert (next(gen)) == expected_mur2
assert (next(gen)) == expected_mur1

actual_murs = [mur for mur in get_cases('MUR', '2')]
assert actual_murs == [expected_mur2]
Expand Down
3 changes: 2 additions & 1 deletion webservices/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ def make_multi_sort_args(default=None, validator=None, default_hide_null=False,
default_nulls_only=False, default_sort_nulls_last=False):
args = make_sort_args(default, validator, default_hide_null, default_nulls_only, default_sort_nulls_last)
args['sort'] = fields.List(fields.Str, missing=default, validate=validator, required=False, allow_none=True,
description='Provide a field to sort by. Use - for descending order.',)
description=docs.SORT)
return args


Expand Down Expand Up @@ -264,6 +264,7 @@ def make_seek_args(field=fields.Int, description=None):
'af_min_fd_date': fields.Date(required=False, description=docs.AF_MIN_FD_DATE),
'af_max_fd_date': fields.Date(required=False, description=docs.AF_MAX_FD_DATE),
'af_fd_fine_amount': fields.Int(IStr, required=False, description=docs.AF_FD_FINE_AMOUNT),
'sort':fields.Str(IStr, required=False, description=docs.SORT),
}

candidate_detail = {
Expand Down
5 changes: 5 additions & 0 deletions webservices/docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@
Number of pages in the document
'''

SORT = '''
Provide a field to sort by. Use `-` for descending order. \
ex: `-case_no`
'''

# ======== candidate start ===========
CANDIDATE_TAG = '''
Candidate endpoints give you access to information about the people running for office.
Expand Down
21 changes: 13 additions & 8 deletions webservices/legal_docs/advisory_opinions.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@

ALL_AOS = """
SELECT
ao_parsed.ao_id,
ao_parsed.ao_no,
ao_parsed.name,
ao_parsed.summary,
ao_parsed.req_date,
ao_parsed.issue_date,
ao.stage
ao_parsed.ao_id as ao_id,
ao_parsed.ao_no as ao_no,
ao_parsed.ao_year as ao_year,
ao_parsed.ao_serial as ao_serial,
ao_parsed.name as name,
ao_parsed.summary as summary,
ao_parsed.req_date as req_date,
ao_parsed.issue_date as issue_date,
ao.stage as stage
FROM aouser.aos_with_parsed_numbers ao_parsed
INNER JOIN aouser.ao ao
ON ao_parsed.ao_id = ao.ao_id
Expand All @@ -36,7 +38,7 @@
OR
(ao_parsed.ao_year > %s)
)
ORDER BY ao_parsed.ao_year, ao_parsed.ao_serial
ORDER BY ao_parsed.ao_year desc, ao_parsed.ao_serial desc
"""

AO_ENTITIES = """
Expand Down Expand Up @@ -173,6 +175,9 @@ def get_advisory_opinions(from_ao_no):
ao = {
"type": AO_DOC_TYPE,
"no": row["ao_no"],
"ao_no": row["ao_no"],
"ao_year": row["ao_year"],
"ao_serial": row["ao_serial"],
"doc_id": "{0}_{1}".format(AO_DOC_TYPE, row["ao_no"]),
"name": row["name"],
"summary": row["summary"],
Expand Down
7 changes: 5 additions & 2 deletions webservices/legal_docs/archived_murs.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,17 @@
ALL_ARCHIVED_MURS = """
SELECT DISTINCT
mur_id,
mur_number as mur_no
mur_number as mur_no,
mur_id as case_serial
FROM MUR_ARCH.ARCHIVED_MURS
ORDER BY mur_id
ORDER BY mur_id desc
Copy link
Contributor

@pkfec pkfec Jan 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fec-jli Just like cases and ao, should you also order by case_serial for archived murs?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for review.
It is better sort by column itself not alias name.
case_serial is the alias name of mur_id.

"""

SINGLE_MUR = """
SELECT DISTINCT
mur_number as mur_no,
mur_id,
mur_id as case_serial,
mur_name,
open_date,
close_date
Expand Down Expand Up @@ -172,6 +174,7 @@ def get_single_mur(mur_no):
"type": get_es_type(),
"doc_id": "mur_{0}".format(row["mur_no"]),
"no": row["mur_no"],
"case_serial": row["mur_id"],
"url": "/legal/matter-under-review/{0}/".format(row["mur_no"]),
"mur_type": "archived",
"mur_name": row["mur_name"],
Expand Down
13 changes: 8 additions & 5 deletions webservices/legal_docs/current_cases.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,20 @@
SELECT
case_id,
case_no,
case_serial,
name,
case_type,
published_flg
FROM fecmur.cases_with_parsed_case_serial_numbers_vw
WHERE case_type = %s
ORDER BY case_serial
ORDER BY case_serial desc
"""

SINGLE_CASE = """
SELECT DISTINCT
case_id,
case_no,
case_serial,
name,
case_type,
published_flg
Expand Down Expand Up @@ -237,10 +239,10 @@

""" For ADR's populate case_status based on event_name"""
adr_case_status_map = {
'Dismissed': 'Case Dismissed',
'Settlement Agreement - Complaint Unsubstantiated': 'Negotiated Settlement Approved',
'Dismissed - Agreement Rejected': 'Negotiated Settlement Rejected by Commission',
'Dismissed - Failed to Approve': 'Case Dismissed'
"Dismissed": "Case Dismissed",
"Settlement Agreement - Complaint Unsubstantiated": "Negotiated Settlement Approved",
"Dismissed - Agreement Rejected": "Negotiated Settlement Rejected by Commission",
"Dismissed - Failed to Approve": "Case Dismissed"
}

STATUTE_REGEX = re.compile(r"(?<!\(|\d)(?P<section>\d+([a-z](-1)?)?)")
Expand Down Expand Up @@ -364,6 +366,7 @@ def get_single_case(case_type, case_no, bucket):
"type": get_es_type(case_type),
"doc_id": "{0}_{1}".format(case_type.lower(), row["case_no"]),
"no": row["case_no"],
"case_serial": row["case_serial"],
"name": row["name"],
"published_flg": row["published_flg"],
"sort1": sort1,
Expand Down
7 changes: 7 additions & 0 deletions webservices/legal_docs/es_management.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"type": {"type": "keyword"},
"doc_id": {"type": "keyword"},
"no": {"type": "keyword"},
"case_serial": {"type": "integer"},
"name": {"type": "text", "analyzer": "english"},
"published_flg": {"type": "boolean"},
"commission_votes": {
Expand Down Expand Up @@ -127,6 +128,9 @@
ADVISORY_OPINIONS = {
"type": {"type": "keyword"},
"no": {"type": "keyword"},
"ao_no": {"type": "keyword"},
"ao_serial": {"type": "integer"},
"ao_year": {"type": "integer"},
"doc_id": {"type": "keyword"},
"name": {"type": "text", "analyzer": "english"},
"summary": {"type": "text", "analyzer": "english"},
Expand Down Expand Up @@ -198,6 +202,7 @@
"type": {"type": "keyword"},
"doc_id": {"type": "keyword"},
"no": {"type": "keyword"},
"case_serial": {"type": "integer"},
"name": {"type": "text", "analyzer": "english"},
"published_flg": {"type": "boolean"},
"commission_votes": {
Expand Down Expand Up @@ -244,6 +249,7 @@
"type": {"type": "keyword"},
"doc_id": {"type": "keyword"},
"no": {"type": "keyword"},
"case_serial": {"type": "integer"},
"name": {"type": "text", "analyzer": "english"},
"published_flg": {"type": "boolean"},
"complainant": {"type": "text"},
Expand Down Expand Up @@ -363,6 +369,7 @@
"type": {"type": "keyword"},
"doc_id": {"type": "keyword"},
"no": {"type": "keyword"},
"case_serial": {"type": "integer"},
"mur_name": {"type": "text"},
"mur_type": {"type": "keyword"},
"open_date": {"type": "date", "format": "dateOptionalTime"},
Expand Down
23 changes: 23 additions & 0 deletions webservices/resources/legal.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,13 +157,25 @@ def generic_query_builder(q, type_, from_hit, hits_returned, **kwargs):
.index("docs_search")
.sort("sort1", "sort2")
)

logger.debug("generic_query_builder =" + json.dumps(query.to_dict(), indent=3, cls=DateTimeEncoder))
return query


def case_query_builder(q, type_, from_hit, hits_returned, **kwargs):
query = generic_query_builder(None, type_, from_hit, hits_returned, **kwargs)

# sorting works in all three cases: ('murs','admin_fines','adrs').
# so far only be able to sort by 'case_no', default sort is descending order.
# descending order: 'sort=-case_no'; ascending order; sort=case_no
# https://fec-dev-api.app.cloud.gov/v1/legal/search/?type=murs&sort=-case_no
# https://fec-dev-api.app.cloud.gov/v1/legal/search/?type=murs&sort=case_no
if kwargs.get("sort"):
if kwargs.get("sort").upper() == "CASE_NO":
query = query.sort({"case_serial" : {"order" : "asc"}})
else:
query = query.sort({"case_serial" : {"order" : "desc"}})

should_query = [
get_case_document_query(q, **kwargs),
Q("query_string", query=q, fields=["no", "name"]),
Expand Down Expand Up @@ -438,6 +450,17 @@ def ao_query_builder(q, type_, from_hit, hits_returned, **kwargs):
# Only pass query string to document list below
query = generic_query_builder(None, type_, from_hit, hits_returned, **kwargs)

# so far only be able to sort by 'ao_no', default sort is descending order.
# descending order: 'sort=-ao_no'; ascending order; sort=ao_no
# https://fec-dev-api.app.cloud.gov/v1/legal/search/?type=advisory_opinions&sort=-ao_no
# https://fec-dev-api.app.cloud.gov/v1/legal/search/?type=advisory_opinions&sort=ao_no

if kwargs.get("sort"):
if kwargs.get("sort").upper() == "AO_NO":
query = query.sort({"ao_no" : {"order" : "asc"}})
else:
query = query.sort({"ao_no" : {"order" : "desc"}})

should_query = [
get_ao_document_query(q, **kwargs),
Q("query_string", query=q, fields=["no", "name", "summary"]),
Expand Down