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

Lesser Charge #1721

Merged
merged 4 commits into from
Feb 3, 2024
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
9 changes: 9 additions & 0 deletions src/backend/expungeservice/charge_classifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
)
from expungeservice.models.disposition import DispositionStatus, Disposition
from expungeservice.models.record import Question, Answer
from expungeservice.models.charge_types.lesser_charge import LesserChargeEligible, LesserChargeIneligible


@dataclass
Expand Down Expand Up @@ -67,6 +68,7 @@ def __classifications_list(self) -> Iterator[AmbiguousChargeTypeWithQuestion]:
name = self.name.lower()
level = self.level.lower()
location = self.location.lower()
yield ChargeClassifier._lesser_charge(self.disposition)
yield ChargeClassifier._juvenile_charge(self.violation_type)
yield ChargeClassifier._parking_ticket(self.violation_type)
yield ChargeClassifier._fare_violation(name)
Expand Down Expand Up @@ -102,6 +104,13 @@ def _criminal_charge(
yield ChargeClassifier._attempt_to_commit(name, level, statute)
yield ChargeClassifier._classification_by_level(level, statute)

@staticmethod
def _lesser_charge(dispostion: Disposition):
if dispostion.lesser_charge:
question_string = "Is the convicted charge on this case that this charge was reduced to eligible?"
options = {"Yes": LesserChargeEligible(), "No": LesserChargeIneligible()}
return ChargeClassifier._build_ambiguous_charge_type_with_question(question_string, options)

@staticmethod
def _juvenile_charge(violation_type: str):
if "juvenile" in violation_type.lower():
Expand Down
27 changes: 27 additions & 0 deletions src/backend/expungeservice/models/charge_types/lesser_charge.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from dataclasses import dataclass

from expungeservice.models.charge import ChargeType
from expungeservice.models.expungement_result import TypeEligibility, EligibilityStatus


@dataclass(frozen=True)
class LesserChargeEligible(ChargeType):
type_name: str = "Lesser Charge, Eligible"
expungement_rules: str = """A conviction that has been dismissed due to a reduction to a lesser charge is eligible if and only if the new charge is eligible."""

def type_eligibility(self, disposition):
return TypeEligibility(
EligibilityStatus.ELIGIBLE,
reason="Reduced to another charge; eligible because the new charge is eligible.",
)

@dataclass(frozen=True)
class LesserChargeIneligible(ChargeType):
type_name: str = "Lesser Charge, Ineligible"
expungement_rules: str = """A conviction that has been dismissed due to a reduction to a lesser charge is eligible if and only if the new charge is eligible."""

def type_eligibility(self, disposition):
return TypeEligibility(
EligibilityStatus.INELIGIBLE,
reason="Reduced to another charge; ineligible because the new charge is ineligible.",
)
4 changes: 3 additions & 1 deletion src/backend/expungeservice/models/disposition.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class Disposition:
ruling: str
status: DispositionStatus
amended: bool = False
lesser_charge: bool = False


class DispositionCreator:
Expand All @@ -31,7 +32,8 @@ def empty():
@staticmethod
def create(date: date, ruling: str, amended: bool = False) -> Disposition:
status = DispositionCreator.__build_status(ruling)
return Disposition(date, ruling, status, amended)
lesser_charge = "lesser charge" in ruling.lower()
return Disposition(date, ruling, status, amended, lesser_charge)

@staticmethod
def __build_status(ruling_string):
Expand Down
15 changes: 15 additions & 0 deletions src/backend/tests/models/charge_types/test_lesser_charge.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from expungeservice.models.charge_types.lesser_charge import LesserChargeEligible, LesserChargeIneligible

from tests.factories.charge_factory import ChargeFactory
from tests.models.test_charge import Dispositions


def test_lesser_charge():
charge = ChargeFactory.create_ambiguous_charge(
name="Manufacture/Delivery",
statute="4759922b",
level="Felony Class A",
disposition=Dispositions.LESSER_CHARGE,
)
assert isinstance(charge[0].charge_type, LesserChargeEligible)
assert isinstance(charge[1].charge_type, LesserChargeIneligible)
1 change: 1 addition & 0 deletions src/backend/tests/models/test_charge.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class Dispositions:
DISMISSED = DispositionCreator.create(ruling="Dismissed", date=LAST_WEEK)
UNRECOGNIZED_DISPOSITION = DispositionCreator.create(ruling="Something unrecognized", date=LAST_WEEK)
NO_COMPLAINT = DispositionCreator.create(ruling="No Complaint", date=LAST_WEEK)
LESSER_CHARGE = DispositionCreator.create(ruling="Convicted - Lesser Charge", date=LAST_WEEK)


class TestChargeClass(unittest.TestCase):
Expand Down
Loading