From c93535f191385bb11fd9ca1fd43454dae03c9e70 Mon Sep 17 00:00:00 2001 From: Rebecca Drabenstott Date: Sun, 25 Aug 2024 14:30:20 -0400 Subject: [PATCH] Fix missing petitions when importing form Portal --- dear_petition/petition/conftest.py | 14 +---- dear_petition/petition/constants.py | 21 +++++-- .../etl/tests/test_petition_offenses.py | 6 +- .../petition/types/adult_felonies.py | 12 +++- .../petition/types/adult_misdemeanors.py | 11 +++- dear_petition/petition/types/dismissed.py | 19 ++++-- dear_petition/petition/types/not_guilty.py | 11 +++- .../types/tests/test_adult_felonies.py | 47 +++++++++++---- .../types/tests/test_adult_misdemeanors.py | 47 +++++++++++---- .../petition/types/tests/test_dismissed.py | 47 ++++++++------- .../types/tests/test_distinct_petitions.py | 6 +- .../petition/types/tests/test_not_guilty.py | 59 +++++++++---------- .../types/tests/test_underaged_convictions.py | 6 -- .../petition/types/underaged_convictions.py | 7 +-- dear_petition/portal/etl/models.py | 11 ---- dear_petition/portal/etl/transform.py | 1 - .../tests/transform/test_dispositions.py | 20 ------- .../portal/tests/transform/test_record.py | 1 - 18 files changed, 191 insertions(+), 155 deletions(-) diff --git a/dear_petition/petition/conftest.py b/dear_petition/petition/conftest.py index 0f60ec00..eaf5e8dd 100644 --- a/dear_petition/petition/conftest.py +++ b/dear_petition/petition/conftest.py @@ -173,7 +173,7 @@ def client(): @pytest.fixture def dismissed_offense(record1): return OffenseFactory( - disposition_method=dismissed.DISMISSED_DISPOSITION_METHODS[0], + disposition_method=dismissed.CIPRS_DISPOSITION_METHODS_DISMISSED[0], ciprs_record=record1, jurisdiction=constants.DISTRICT_COURT, ) @@ -209,18 +209,6 @@ def convicted_guilty_record(guilty_offense): yield OffenseRecordFactory(action=CONVICTED, offense=guilty_offense) -@pytest.fixture -def adult_convicted_guilty_record(record1): - guilty_offense = OffenseFactory( - ciprs_record=record1, - jurisdiction=constants.DISTRICT_COURT, - verdict="GUILTY", - disposition_method="", - disposed_on=date(2010, 1, 1), # account for waiting period - ) - yield OffenseRecordFactory(action=CONVICTED, offense=guilty_offense) - - @pytest.fixture def not_guilty_offense(record1): return OffenseFactory( diff --git a/dear_petition/petition/constants.py b/dear_petition/petition/constants.py index e56411f2..125eb09e 100644 --- a/dear_petition/petition/constants.py +++ b/dear_petition/petition/constants.py @@ -98,7 +98,7 @@ DISTRICT_COURT_WITHOUT_DA_LEAVE = "Dismissal without Leave by DA" -DISMISSED_DISPOSITION_METHODS = ( +CIPRS_DISPOSITION_METHODS_DISMISSED = ( DISTRICT_COURT_WITHOUT_DA_LEAVE, "Dismissed by Court", "Deferred Prosecution Dismissal", @@ -107,9 +107,22 @@ "No Probable Cause", "Never To Be Served", "Deferred Proceeding or Deferred Prosecution Dismissal", - # Portal: +) + +PORTAL_DISPOSITION_METHODS_DISMISSED = ( "VD-District Dismissals w/o Leave by DA - No Plea Agreement", "VD-Superior Dismissals w/o Leave by DA - No Plea Agreement", + "No Probable Cause Found", +) + +PORTAL_DISPOSITION_METHODS_NOT_GUILTY = ( + "District Not Guilty - Judge", + "Superior Not Guilty - Judge" +) + +PORTAL_DISPOSITION_METHODS_CONVICTED = ( + "District Guilty - Judge", + "Superior Guilty - Judge" ) DISP_METHOD_SUPERSEDING_INDICTMENT = "SUPERSEDING INDICTMENT OR PROCESS" @@ -183,5 +196,5 @@ SEVERITY_FELONY = "FELONY" SEVERITY_MISDEMEANOR = "MISDEMEANOR" -CHARGED_DEGREE_FELONY = ("FH", "FNC") -CHARGED_DEGREE_MISDEMEANOR = ("MNC",) +CHARGED_DEGREE_FELONY = ("FA", "FB", "FC", "FD", "FE", "FF", "FG", "FH", "FI", "FNC") +CHARGED_DEGREE_MISDEMEANOR = ("MA1", "M1", "M2", "M3", "MNC") diff --git a/dear_petition/petition/etl/tests/test_petition_offenses.py b/dear_petition/petition/etl/tests/test_petition_offenses.py index b48f7c3e..2e834ab2 100644 --- a/dear_petition/petition/etl/tests/test_petition_offenses.py +++ b/dear_petition/petition/etl/tests/test_petition_offenses.py @@ -20,7 +20,7 @@ def many_offense_records(batch, size): batch=batch, jurisdiction=constants.DISTRICT_COURT, county="DURHAM" ) offense = OffenseFactory( - disposition_method=dismissed.DISMISSED_DISPOSITION_METHODS[0], + disposition_method=dismissed.CIPRS_DISPOSITION_METHODS_DISMISSED[0], ciprs_record=record, jurisdiction=constants.DISTRICT_COURT, ) @@ -146,7 +146,7 @@ def test_paginator_same_record_number_order(petition, records_10): # attach a 2nd dismissed charge charge_2 = OffenseRecordFactory( offense=OffenseFactory( - disposition_method=dismissed.DISMISSED_DISPOSITION_METHODS[0], + disposition_method=dismissed.CIPRS_DISPOSITION_METHODS_DISMISSED[0], ciprs_record=charge_1.offense.ciprs_record, jurisdiction=constants.DISTRICT_COURT, ), @@ -176,7 +176,7 @@ def create_new_ciprs_record(file_no): offense = OffenseFactory( ciprs_record=ciprs_record, jurisdiction=constants.DISTRICT_COURT, - disposition_method=dismissed.DISMISSED_DISPOSITION_METHODS[0], + disposition_method=dismissed.CIPRS_DISPOSITION_METHODS_DISMISSED[0], ) offense_record = OffenseRecordFactory(offense=offense) return offense_record.id diff --git a/dear_petition/petition/types/adult_felonies.py b/dear_petition/petition/types/adult_felonies.py index d65eea34..59ad2741 100644 --- a/dear_petition/petition/types/adult_felonies.py +++ b/dear_petition/petition/types/adult_felonies.py @@ -4,6 +4,7 @@ from django.utils import timezone from django.db.models import Q +from dear_petition.petition.constants import PORTAL_DISPOSITION_METHODS_CONVICTED from dear_petition.petition.models import OffenseRecord from dear_petition.petition import constants as pc @@ -25,5 +26,12 @@ def build_query(): today = timezone.now().date() waiting_period_start_date = today - relativedelta(years=10) waiting_period = Q(offense__disposed_on__lt=waiting_period_start_date) - query = action & severity & waiting_period - return query + adult_felony_ciprs = action & severity & waiting_period + + methods = Q() + for method in PORTAL_DISPOSITION_METHODS_CONVICTED: + methods |= Q(offense__disposition_method__iexact=method) + adult_felony_portal = methods & severity & waiting_period + + return adult_felony_ciprs | adult_felony_portal + diff --git a/dear_petition/petition/types/adult_misdemeanors.py b/dear_petition/petition/types/adult_misdemeanors.py index b82adaaa..ed80ba8d 100644 --- a/dear_petition/petition/types/adult_misdemeanors.py +++ b/dear_petition/petition/types/adult_misdemeanors.py @@ -4,6 +4,7 @@ from django.db.models import Q from django.utils import timezone +from dear_petition.petition.constants import PORTAL_DISPOSITION_METHODS_CONVICTED from dear_petition.petition.models import OffenseRecord from dear_petition.petition import constants as pc @@ -25,5 +26,11 @@ def build_query(): today = timezone.now().date() waiting_period_start_date = today - relativedelta(years=5) waiting_period = Q(offense__disposed_on__lt=waiting_period_start_date) - query = action & severity & waiting_period - return query + adult_misdemeanor_ciprs = action & severity & waiting_period + + methods = Q() + for method in PORTAL_DISPOSITION_METHODS_CONVICTED: + methods |= Q(offense__disposition_method__iexact=method) + adult_misdemeanor_portal = methods & severity & waiting_period + + return adult_misdemeanor_ciprs | adult_misdemeanor_portal diff --git a/dear_petition/petition/types/dismissed.py b/dear_petition/petition/types/dismissed.py index 3dfbdacb..f3403c4d 100644 --- a/dear_petition/petition/types/dismissed.py +++ b/dear_petition/petition/types/dismissed.py @@ -1,7 +1,7 @@ from django.db.models import Q from dear_petition.petition.models import OffenseRecord -from dear_petition.petition.constants import DISMISSED_DISPOSITION_METHODS +from dear_petition.petition.constants import CIPRS_DISPOSITION_METHODS_DISMISSED, PORTAL_DISPOSITION_METHODS_DISMISSED def get_offense_records(batch, jurisdiction=""): @@ -14,8 +14,15 @@ def get_offense_records(batch, jurisdiction=""): def build_query(): action = Q(action="CHARGED") - methods = Q() - for method in DISMISSED_DISPOSITION_METHODS: - methods |= Q(offense__disposition_method__iexact=method) - query = action & methods - return query + + methods_ciprs = Q() + for method in CIPRS_DISPOSITION_METHODS_DISMISSED: + methods_ciprs |= Q(offense__disposition_method__iexact=method) + dismissed_ciprs = action & methods_ciprs + + methods_portal = Q() + for method in PORTAL_DISPOSITION_METHODS_DISMISSED: + methods_portal |= Q(offense__disposition_method__iexact=method) + dismissed_portal = methods_portal + + return dismissed_ciprs | dismissed_portal diff --git a/dear_petition/petition/types/not_guilty.py b/dear_petition/petition/types/not_guilty.py index 1106d33d..57612c0c 100644 --- a/dear_petition/petition/types/not_guilty.py +++ b/dear_petition/petition/types/not_guilty.py @@ -1,5 +1,6 @@ from django.db.models import Q +from dear_petition.petition.constants import PORTAL_DISPOSITION_METHODS_NOT_GUILTY from dear_petition.petition.models import OffenseRecord from dear_petition.petition.types.dismissed import build_query as build_dismissed_query @@ -17,5 +18,11 @@ def build_query(): action = Q(action="CHARGED") verdict = Q(offense__verdict__iexact="Not Guilty") dismissed_query = build_dismissed_query() - query = action & verdict & ~dismissed_query - return query + not_guilty_ciprs = action & verdict & ~dismissed_query + + methods = Q() + for method in PORTAL_DISPOSITION_METHODS_NOT_GUILTY: + methods |= Q(offense__disposition_method__iexact=method) + not_guilty_portal = methods + + return not_guilty_ciprs | not_guilty_portal diff --git a/dear_petition/petition/types/tests/test_adult_felonies.py b/dear_petition/petition/types/tests/test_adult_felonies.py index e10a8445..e81e780f 100644 --- a/dear_petition/petition/types/tests/test_adult_felonies.py +++ b/dear_petition/petition/types/tests/test_adult_felonies.py @@ -1,19 +1,40 @@ +from datetime import datetime + import pytest -from dear_petition.petition import constants +from dear_petition.petition.constants import CONVICTED, CHARGED, SEVERITIES +from dear_petition.petition.models import Offense, OffenseRecord pytestmark = pytest.mark.django_db -def test_adult_felony_included(batch, adult_convicted_guilty_record): - adult_convicted_guilty_record.severity = constants.SEVERITIES.FELONY - adult_convicted_guilty_record.save() - - assert adult_convicted_guilty_record in batch.adult_felony_records() - - -def test_adult_misdemeanor_not_included(batch, adult_convicted_guilty_record): - adult_convicted_guilty_record.severity = constants.SEVERITIES.MISDEMEANOR - adult_convicted_guilty_record.save() - - assert adult_convicted_guilty_record not in batch.adult_felony_records() +@pytest.mark.parametrize( + "action, disposition_method, severity, date, should_be_included", [ + # records that have data as they would from Portal (no action) + ("", "District Guilty - Judge", SEVERITIES.FELONY, datetime(2014, 8, 1), True), + ("", "District Not Guilty - Judge", SEVERITIES.FELONY, datetime(2014, 8, 1), False), # exclude because not Portal guilty disposition method + ("", "District Guilty - Judge", SEVERITIES.MISDEMEANOR, datetime(2014, 8, 1), False), # exclude because misdemeanor severity + ("", "District Guilty - Judge", SEVERITIES.FELONY, datetime(2024, 8, 1), False), # exclude because too recent + # records that have data as they would from CIPRS (disposition_method not one seen in Portal) + (CONVICTED, "Disposed By Judge", SEVERITIES.FELONY, datetime(2014, 8, 1), True), + (CHARGED, "Disposed By Judge", SEVERITIES.FELONY, datetime(2014, 8, 1), False), # exclude because not convicted action + (CONVICTED, "Disposed By Judge", SEVERITIES.MISDEMEANOR, datetime(2014, 8, 1), False), # exclude because misdemeanor severity + (CONVICTED, "Disposed By Judge", SEVERITIES.FELONY, datetime(2024, 8, 1), False), # exclude because too recent + ] +) +def test_adult_felonies(action, disposition_method, severity, date, should_be_included, batch, record1): + offense = Offense.objects.create( + ciprs_record=record1, + disposition_method=disposition_method, + disposed_on=date, + ) + offense_record = OffenseRecord.objects.create( + offense=offense, + action=action, + severity=severity, + ) + + if should_be_included: + assert offense_record in batch.adult_felony_records() + else: + assert offense_record not in batch.adult_felony_records() diff --git a/dear_petition/petition/types/tests/test_adult_misdemeanors.py b/dear_petition/petition/types/tests/test_adult_misdemeanors.py index 3148f03b..a22a2d3b 100644 --- a/dear_petition/petition/types/tests/test_adult_misdemeanors.py +++ b/dear_petition/petition/types/tests/test_adult_misdemeanors.py @@ -1,19 +1,40 @@ +from datetime import datetime + import pytest -from dear_petition.petition import constants +from dear_petition.petition.constants import SEVERITIES, CONVICTED, CHARGED +from dear_petition.petition.models import Offense, OffenseRecord pytestmark = pytest.mark.django_db -def test_adult_misdemeanor_included(batch, adult_convicted_guilty_record): - adult_convicted_guilty_record.severity = constants.SEVERITIES.MISDEMEANOR - adult_convicted_guilty_record.save() - - assert adult_convicted_guilty_record in batch.adult_misdemeanor_records() - - -def test_adult_felony_not_included(batch, adult_convicted_guilty_record): - adult_convicted_guilty_record.severity = constants.SEVERITIES.FELONY - adult_convicted_guilty_record.save() - - assert adult_convicted_guilty_record not in batch.adult_misdemeanor_records() +@pytest.mark.parametrize( + "action, disposition_method, severity, date, should_be_included", [ + # records that have data as they would from Portal (no action) + ("", "District Guilty - Judge", SEVERITIES.MISDEMEANOR, datetime(2019, 8, 1), True), + ("", "District Not Guilty - Judge", SEVERITIES.MISDEMEANOR, datetime(2019, 8, 1), False), # exclude because not Portal guilty disposition method + ("", "District Guilty - Judge", SEVERITIES.FELONY, datetime(2019, 8, 1), False), # exclude because felony severity + ("", "District Guilty - Judge", SEVERITIES.MISDEMEANOR, datetime(2024, 8, 1), False), # exclude because too recent + # records that have data as they would from CIPRS (disposition_method not one seen in Portal) + (CONVICTED, "Disposed By Judge", SEVERITIES.MISDEMEANOR, datetime(2019, 8, 1), True), + (CHARGED, "Disposed By Judge", SEVERITIES.MISDEMEANOR, datetime(2019, 8, 1), False), # exclude because not convicted action + (CONVICTED, "Disposed By Judge", SEVERITIES.FELONY, datetime(2019, 8, 1), False), # exclude because felony severity + (CONVICTED, "Disposed By Judge", SEVERITIES.MISDEMEANOR, datetime(2024, 8, 1), False), # exclude because too recent + ] +) +def test_adult_misdemeanors(action, disposition_method, severity, date, should_be_included, batch, record1): + offense = Offense.objects.create( + ciprs_record=record1, + disposition_method=disposition_method, + disposed_on=date, + ) + offense_record = OffenseRecord.objects.create( + offense=offense, + action=action, + severity=severity, + ) + + if should_be_included: + assert offense_record in batch.adult_misdemeanor_records() + else: + assert offense_record not in batch.adult_misdemeanor_records() diff --git a/dear_petition/petition/types/tests/test_dismissed.py b/dear_petition/petition/types/tests/test_dismissed.py index ba8ba86f..5784187c 100644 --- a/dear_petition/petition/types/tests/test_dismissed.py +++ b/dear_petition/petition/types/tests/test_dismissed.py @@ -7,30 +7,37 @@ OffenseRecordFactory, PetitionFactory, ) +from dear_petition.petition.constants import CONVICTED, CHARGED +from dear_petition.petition.models import Offense, OffenseRecord pytestmark = pytest.mark.django_db -@pytest.mark.parametrize("method", constants.DISMISSED_DISPOSITION_METHODS) -def test_charged_disposition_methods(batch, record1, method): - """CHARGED offense records should be included for all dismissed disposition methods.""" - offense = OffenseFactory(disposition_method=method, ciprs_record=record1) - offense_record = OffenseRecordFactory(action="CHARGED", offense=offense) - assert offense_record in batch.dismissed_offense_records() - - -def test_non_charged_offense_record(batch, dismissed_offense): - """Non-CHARGED dismissed offense records should be excluded.""" - offense_record = OffenseRecordFactory(action="CONVICTED", offense=dismissed_offense) - assert offense_record not in batch.dismissed_offense_records() - - -def test_non_dismissed_disposition_method(batch, non_dismissed_offense): - """Offenses with non-dismissed disposition methods should be excluded.""" - offense_record = OffenseRecordFactory( - action="CHARGED", offense=non_dismissed_offense +@pytest.mark.parametrize( + "action, disposition_method, should_be_included", [ + # records that have data as they would from Portal (no action) + ("", "No Probable Cause Found", True), + ("", "District Guilty - Judge", False), # exclude because not Portal dismissed disposition method + # records that have data as they would from CIPRS (disposition_method not one seen in Portal) + (CHARGED, "No Probable Cause", True), + (CONVICTED, "No Probable Cause", False), # exclude because not charged action + (CHARGED, "Disposed By Judge", False), # exclude because not CIPRS dismissed disposition method + ] +) +def test_dismissed(action, disposition_method, should_be_included, batch, record1): + offense = Offense.objects.create( + ciprs_record=record1, + disposition_method=disposition_method, ) - assert offense_record not in batch.dismissed_offense_records() + offense_record = OffenseRecord.objects.create( + offense=offense, + action=action, + ) + + if should_be_included: + assert offense_record in batch.dismissed_offense_records() + else: + assert offense_record not in batch.dismissed_offense_records() def test_infraction_severity_offense_record(batch, dismissed_offense): @@ -52,7 +59,7 @@ def test_offense_records_by_jurisdiction(batch, jurisdiction): """Offense records helper function should allow filtering by jurisdiction.""" ciprs_record = CIPRSRecordFactory(jurisdiction=jurisdiction, batch=batch) offense = OffenseFactory( - disposition_method=constants.DISMISSED_DISPOSITION_METHODS[0], + disposition_method=constants.CIPRS_DISPOSITION_METHODS_DISMISSED[0], ciprs_record=ciprs_record, ) offense_record = OffenseRecordFactory(action="CHARGED", offense=offense) diff --git a/dear_petition/petition/types/tests/test_distinct_petitions.py b/dear_petition/petition/types/tests/test_distinct_petitions.py index 57d0d1dc..e316bef1 100644 --- a/dear_petition/petition/types/tests/test_distinct_petitions.py +++ b/dear_petition/petition/types/tests/test_distinct_petitions.py @@ -24,7 +24,7 @@ def test_distinct_petition(batch, dismissed_offense): def test_distinct_petition__many(batch): """Identified petitions should include unique pairing of jurisdiction and county.""" - method = constants.DISMISSED_DISPOSITION_METHODS[0] + method = constants.CIPRS_DISPOSITION_METHODS_DISMISSED[0] for jurisdiction in [constants.DISTRICT_COURT, constants.SUPERIOR_COURT]: for county in ["DURHAM", "WAKE"]: record = CIPRSRecordFactory( @@ -50,7 +50,7 @@ def test_distinct_petition__distinct_ciprs_records(batch): OffenseRecordFactory( action="CHARGED", offense=OffenseFactory( - disposition_method=dismissed.DISMISSED_DISPOSITION_METHODS[0], + disposition_method=dismissed.CIPRS_DISPOSITION_METHODS_DISMISSED[0], ciprs_record=record1, ), ) @@ -63,7 +63,7 @@ def test_distinct_petition__distinct_ciprs_records(batch): OffenseRecordFactory( action="CHARGED", offense=OffenseFactory( - disposition_method=dismissed.DISMISSED_DISPOSITION_METHODS[0], + disposition_method=dismissed.CIPRS_DISPOSITION_METHODS_DISMISSED[0], ciprs_record=record2, ), ) diff --git a/dear_petition/petition/types/tests/test_not_guilty.py b/dear_petition/petition/types/tests/test_not_guilty.py index bb95bf24..9fb30256 100644 --- a/dear_petition/petition/types/tests/test_not_guilty.py +++ b/dear_petition/petition/types/tests/test_not_guilty.py @@ -2,27 +2,42 @@ from dear_petition.petition import constants from dear_petition.petition.tests.factories import ( - CIPRSRecordFactory, - OffenseFactory, OffenseRecordFactory, PetitionFactory, ) +from dear_petition.petition.constants import CONVICTED, CHARGED, VERDICT_GUILTY, VERDICT_NOT_GUILTY +from dear_petition.petition.models import Offense, OffenseRecord pytestmark = pytest.mark.django_db -def test_charged_not_guilty_record(batch, not_guilty_offense): - """Charged not guilty records should be included""" - offense_record = OffenseRecordFactory(action="CHARGED", offense=not_guilty_offense) - assert offense_record in batch.not_guilty_offense_records() - - -def test_non_charged_offense_record(batch, not_guilty_offense): - """Non-charged records should be excluded.""" - offense_record = OffenseRecordFactory( - action="CONVICTED", offense=not_guilty_offense +@pytest.mark.parametrize( + "action, verdict, disposition_method, should_be_included", [ + # records that have data as they would from Portal (no action or verdict) + ("", "", "District Not Guilty - Judge", True), + ("", "", "District Guilty - Judge", False), # exclude because not Portal not-guilty disposition method + # records that have data as they would from CIPRS (disposition_method not one seen in Portal) + (CHARGED, VERDICT_NOT_GUILTY, "Disposed By Judge", True), + (CONVICTED, VERDICT_NOT_GUILTY, "Disposed By Judge", False), # exclude because not charged action + (CHARGED, VERDICT_GUILTY, "Disposed By Judge", False), # exclude because not not-guilty verdict + (CHARGED, VERDICT_NOT_GUILTY, "Dismissed by Court", False), # exclude because meets dismissed criteria + ] +) +def test_not_guilty(action, verdict, disposition_method, should_be_included, batch, record1): + offense = Offense.objects.create( + ciprs_record=record1, + verdict=verdict, + disposition_method=disposition_method, + ) + offense_record = OffenseRecord.objects.create( + offense=offense, + action=action, ) - assert offense_record not in batch.not_guilty_offense_records() + + if should_be_included: + assert offense_record in batch.not_guilty_offense_records() + else: + assert offense_record not in batch.not_guilty_offense_records() def test_infraction_severity_offense_record(batch, not_guilty_offense): @@ -37,24 +52,6 @@ def test_infraction_severity_offense_record(batch, not_guilty_offense): assert traffic_record in batch.not_guilty_offense_records() -def test_non_not_guilty_verdict(batch, record1): - offense = OffenseFactory(verdict="Guilty", ciprs_record=record1) - offense_record = OffenseRecordFactory(action="CHARGED", offense=offense) - assert offense_record not in batch.not_guilty_offense_records() - - -def test_not_both_dismissed_and_not_guilty(batch, record1): - offense = OffenseFactory( - disposition_method="DISMISSAL WITHOUT LEAVE BY DA", - verdict="Not Guilty", - ciprs_record=record1, - ) - offense_record = OffenseRecordFactory(action="CHARGED", offense=offense) - assert offense_record not in batch.not_guilty_offense_records( - jurisdiction=record1.jurisdiction - ) - - def test_petition_offenses(batch, record1, not_guilty_offense): """Petitions should return their own offense records.""" offense_record = OffenseRecordFactory(action="CHARGED", offense=not_guilty_offense) diff --git a/dear_petition/petition/types/tests/test_underaged_convictions.py b/dear_petition/petition/types/tests/test_underaged_convictions.py index 015a2fa0..50485b58 100644 --- a/dear_petition/petition/types/tests/test_underaged_convictions.py +++ b/dear_petition/petition/types/tests/test_underaged_convictions.py @@ -1,14 +1,8 @@ import pytest from datetime import datetime -from django.utils import timezone - -from dear_petition.petition import constants from dear_petition.petition.tests.factories import ( - CIPRSRecordFactory, - OffenseFactory, OffenseRecordFactory, - PetitionFactory, ) pytestmark = pytest.mark.django_db diff --git a/dear_petition/petition/types/underaged_convictions.py b/dear_petition/petition/types/underaged_convictions.py index 6914d7ac..600574b1 100644 --- a/dear_petition/petition/types/underaged_convictions.py +++ b/dear_petition/petition/types/underaged_convictions.py @@ -1,8 +1,7 @@ import logging from dateutil.relativedelta import relativedelta -from django.utils import timezone -from django.db.models import Q, F, DurationField, ExpressionWrapper +from django.db.models import Q from dear_petition.petition.models import OffenseRecord from dear_petition.petition.types.dismissed import build_query as build_dismissed_query @@ -41,6 +40,6 @@ def build_query(dob): logger.debug(f"Using {eighteenth_birthday} as eighteenth birthday (dob={dob})") dismissed_query = build_dismissed_query() not_guilty_query = build_not_guilty_query() - action = Q(offense__ciprs_record__offense_date__date__lt=eighteenth_birthday) - query = action & ~dismissed_query & ~not_guilty_query + before_eighteen = Q(offense__ciprs_record__offense_date__date__lt=eighteenth_birthday) + query = before_eighteen & ~dismissed_query & ~not_guilty_query return query diff --git a/dear_petition/portal/etl/models.py b/dear_petition/portal/etl/models.py index 9069327b..351469fc 100644 --- a/dear_petition/portal/etl/models.py +++ b/dear_petition/portal/etl/models.py @@ -74,18 +74,7 @@ class Disposition(BaseModel): def parse_date(cls, v): return parse_date(v); - def is_dismissed(self) -> bool: - return self.criminal_disposition in constants.DISMISSED_DISPOSITION_METHODS - - def transform_action(self) -> str: - action = self.event - if self.is_dismissed(): - action = constants.CHARGED - return action - def transform_disposition_method(self) -> str: - if self.is_dismissed(): - return constants.DISTRICT_COURT_WITHOUT_DA_LEAVE return self.criminal_disposition diff --git a/dear_petition/portal/etl/transform.py b/dear_petition/portal/etl/transform.py index f7de5768..c30aa5dc 100644 --- a/dear_petition/portal/etl/transform.py +++ b/dear_petition/portal/etl/transform.py @@ -48,7 +48,6 @@ def transform_offenses(portal_record: PortalRecord): { "Law": charge.statute if charge else "", "Count": disposition.charge_number, - "Action": disposition.transform_action(), "Severity": charge.transform_severity(), "Description": disposition.charge_offense, "Agency": charge.agency if charge else None, diff --git a/dear_petition/portal/tests/transform/test_dispositions.py b/dear_petition/portal/tests/transform/test_dispositions.py index 9c57e2ed..5bb85772 100644 --- a/dear_petition/portal/tests/transform/test_dispositions.py +++ b/dear_petition/portal/tests/transform/test_dispositions.py @@ -16,26 +16,6 @@ def disposition(self): criminal_disposition="VD-District Dismissals w/o Leave by DA - No Plea Agreement", ) - def test_is_dismissed(self, disposition: Disposition): - assert disposition.is_dismissed() - - def test_dismissed_transform_action(self, disposition: Disposition): - assert disposition.transform_action() == constants.CHARGED - - def test_dismissed_transform_disposition_method(self, disposition: Disposition): - assert ( - disposition.transform_disposition_method() - == constants.DISTRICT_COURT_WITHOUT_DA_LEAVE - ) - - def test_not_is_dismissed(self, disposition): - disposition.criminal_disposition = "Other" - assert not disposition.is_dismissed() - - def test_unknown_transform_action(self, disposition: Disposition): - disposition.criminal_disposition = "Other" - assert disposition.transform_action() == disposition.event - def test_unknown_transform_disposition_method(self, disposition: Disposition): disposition.criminal_disposition = "Other" assert ( diff --git a/dear_petition/portal/tests/transform/test_record.py b/dear_petition/portal/tests/transform/test_record.py index 35635af6..371b8be6 100644 --- a/dear_petition/portal/tests/transform/test_record.py +++ b/dear_petition/portal/tests/transform/test_record.py @@ -19,7 +19,6 @@ def test_transform_full_record(sample_record): "Disposition Method": "District Dismissed by the Court - No Plea Agreement", "Records": [ { - "Action": "Disposition", "Count": 1, "Description": "EXTRADITION/FUGITIVE OTH STATE", "Law": "15A-727;733;734",