Skip to content

Commit

Permalink
#461 Assault convictions now provide warning. Also created general ap…
Browse files Browse the repository at this point in the history
…proach for adding offense-level warnings on the Petition page
  • Loading branch information
georgehelman committed Nov 16, 2024
1 parent c65fbe6 commit 32487e2
Show file tree
Hide file tree
Showing 6 changed files with 8,275 additions and 13 deletions.
1 change: 1 addition & 0 deletions dear_petition/petition/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

6. In dear_petition/petition/etl/load.py, add to create_batch_petitions function
7. Add to PETITION_FORM_NAMES constant in src/contstants/petitionConstants.js
8. Create a new offense record serializer for your new petition type in serializers.py and add it to the offense_record_serializer_map.



Expand Down
98 changes: 96 additions & 2 deletions dear_petition/petition/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from django.urls import reverse
from rest_framework import serializers
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from dateutil.relativedelta import relativedelta

from dear_petition.users.models import User
from dear_petition.petition.models import (
Expand All @@ -15,7 +16,14 @@
Petition,
PetitionDocument,
)
from dear_petition.petition.constants import ATTACHMENT, DISMISSED, UNDERAGED_CONVICTIONS
from dear_petition.petition.constants import (
ATTACHMENT,
DISMISSED,
UNDERAGED_CONVICTIONS,
NOT_GUILTY,
ADULT_FELONIES,
ADULT_MISDEMEANORS,
)

from .fields import ValidationField

Expand Down Expand Up @@ -92,6 +100,91 @@ class Meta:
]


class DismissedOffenseRecordSerializer(OffenseRecordSerializer):
warnings = serializers.SerializerMethodField()

def get_warnings(self, offense_record):
warnings = []
dob = self.get_dob(offense_record)
if dob:
eighteenth_birthday = dob + relativedelta(years=18)
if offense_record.offense.ciprs_record.offense_date.date() < eighteenth_birthday:
warnings.append("This offense may be a candidate for the AOC-CR-293 petition form")
return warnings

class Meta:
model = OffenseRecord
fields = OffenseRecordSerializer.Meta.fields + ["warnings"]


class NotGuiltyOffenseRecordSerializer(OffenseRecordSerializer):
warnings = serializers.SerializerMethodField()

def get_warnings(self, offense_record):
warnings = []
dob = self.get_dob(offense_record)
if dob:
eighteenth_birthday = dob + relativedelta(years=18)
if offense_record.offense.ciprs_record.offense_date.date() < eighteenth_birthday:
warnings.append("This offense may be a candidate for the AOC-CR-293 petition form")
return warnings

class Meta:
model = OffenseRecord
fields = OffenseRecordSerializer.Meta.fields + ["warnings"]


class UnderagedConvictionOffenseRecordSerializer(OffenseRecordSerializer):
warnings = serializers.SerializerMethodField()

def get_warnings(self, offense_record):
warnings = []
if "assault" in offense_record.description.lower():
warnings.append("This is an assault conviction")
return warnings

class Meta:
model = OffenseRecord
fields = OffenseRecordSerializer.Meta.fields + ["warnings"]


class AdultFelonyOffenseRecordSerializer(OffenseRecordSerializer):
warnings = serializers.SerializerMethodField()

def get_warnings(self, offense_record):
warnings = []
if "assault" in offense_record.description.lower():
warnings.append("This is an assault conviction")
return warnings

class Meta:
model = OffenseRecord
fields = OffenseRecordSerializer.Meta.fields + ["warnings"]


class AdultMisdemeanorOffenseRecordSerializer(OffenseRecordSerializer):
warnings = serializers.SerializerMethodField()

def get_warnings(self, offense_record):
warnings = []
if "assault" in offense_record.description.lower():
warnings.append("This is an assault conviction")
return warnings

class Meta:
model = OffenseRecord
fields = OffenseRecordSerializer.Meta.fields + ["warnings"]


offense_record_serializer_map = {
DISMISSED: DismissedOffenseRecordSerializer,
NOT_GUILTY: NotGuiltyOffenseRecordSerializer,
UNDERAGED_CONVICTIONS: UnderagedConvictionOffenseRecordSerializer,
ADULT_FELONIES: AdultFelonyOffenseRecordSerializer,
ADULT_MISDEMEANORS: AdultMisdemeanorOffenseRecordSerializer,
}


class OffenseSerializer(serializers.ModelSerializer):
offense_records = OffenseRecordSerializer(many=True, read_only=True)

Expand Down Expand Up @@ -297,7 +390,8 @@ def get_attachments(self, instance):

def get_offense_records(self, petition):
offense_records = petition.offense_records.all()
return OffenseRecordSerializer(offense_records, many=True).data
Serializer = offense_record_serializer_map.get(petition.form_type, OffenseRecordSerializer)
return Serializer(offense_records, many=True).data

def get_active_records(self, petition):
return petition.offense_records.filter(petitionoffenserecord__active=True).values_list(
Expand Down
76 changes: 74 additions & 2 deletions dear_petition/petition/api/tests/test_serializers.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
import pytest
from datetime import timedelta, datetime

from dear_petition.petition.api.serializers import OffenseRecordSerializer
import pytest
from dear_petition.petition.api.serializers import (
AdultFelonyOffenseRecordSerializer,
AdultMisdemeanorOffenseRecordSerializer,
DismissedOffenseRecordSerializer,
NotGuiltyOffenseRecordSerializer,
OffenseRecordSerializer,
UnderagedConvictionOffenseRecordSerializer,
)
from dear_petition.petition.tests.factories import OffenseRecordFactory
import dear_petition.petition.constants as pc


@pytest.mark.django_db
Expand All @@ -15,3 +24,66 @@ def test_offense_date_none(self):
record = OffenseRecordFactory(offense__ciprs_record__offense_date=None)
serializer = OffenseRecordSerializer(record)
assert serializer.data["offense_date"] is None

def test_dismissed_record_underaged_warning(self, charged_dismissed_record):
charged_dismissed_record.offense.ciprs_record.dob = (
charged_dismissed_record.offense.ciprs_record.offense_date.date()
- timedelta(days=365 * 16)
)
charged_dismissed_record.offense.ciprs_record.save()

serializer = DismissedOffenseRecordSerializer(charged_dismissed_record)
assert serializer.data["warnings"] == [
"This offense may be a candidate for the AOC-CR-293 petition form"
]

def test_not_guilty_underaged_warning(self, charged_not_guilty_record):
charged_not_guilty_record.offense.ciprs_record.dob = (
charged_not_guilty_record.offense.ciprs_record.offense_date.date()
- timedelta(days=365 * 16)
)
charged_not_guilty_record.offense.ciprs_record.save()

serializer = NotGuiltyOffenseRecordSerializer(charged_not_guilty_record)
assert serializer.data["warnings"] == [
"This offense may be a candidate for the AOC-CR-293 petition form"
]

def test_underaged_conviction_assault_warning(self, record1, non_dismissed_offense):
record1.dob = datetime(2000, 1, 2)
record1.offense_date = datetime(2018, 1, 1)
record1.save()

offense_record = OffenseRecordFactory(
action="CONVICTED", description="Assault", offense=non_dismissed_offense
)
serializer = UnderagedConvictionOffenseRecordSerializer(offense_record)
assert serializer.data["warnings"] == ["This is an assault conviction"]

def test_adult_felony_assault_warning(self, record1, non_dismissed_offense):
record1.dob = datetime(2000, 1, 2)
record1.offense_date = datetime(2019, 1, 1)
record1.save()

offense_record = OffenseRecordFactory(
action="CONVICTED",
description="Assault",
severity=pc.SEVERITY_FELONY,
offense=non_dismissed_offense,
)
serializer = AdultFelonyOffenseRecordSerializer(offense_record)
assert serializer.data["warnings"] == ["This is an assault conviction"]

def test_adult_misdemeanor_assault_warning(self, record1, non_dismissed_offense):
record1.dob = datetime(2000, 1, 2)
record1.offense_date = datetime(2019, 1, 1)
record1.save()

offense_record = OffenseRecordFactory(
action="CONVICTED",
description="Assault",
severity=pc.SEVERITY_MISDEMEANOR,
offense=non_dismissed_offense,
)
serializer = AdultFelonyOffenseRecordSerializer(offense_record)
assert serializer.data["warnings"] == ["This is an assault conviction"]
Loading

0 comments on commit 32487e2

Please sign in to comment.