Example #1
0
def expunge_deceased(crecord: CRecord) -> Tuple[CRecord, Decision]:
    """
    Analyze a crecord for expungments if the individual has been dead for three years.

    18 Pa.C.S. 9122(b)(2) provides for expungement of records for an individual who has been dead for three years.
    """
    conclusion = Decision(
        name="A deceased person's record can be expunged after three years.",
        reasoning=[
            Decision(
                name=
                f"Has {crecord.person.first_name} been deceased for 3 years?",
                value=crecord.person.years_dead() > 3,
                reasoning=
                f"{crecord.person.first_name} is not dead, as far as I know."
                if crecord.person.years_dead() < 0 else
                f"It has been {crecord.person.years_dead()} since {crecord.person.first_name}'s death."
            )
        ])

    if all(conclusion.reasoning):
        exps = [Expungement(crecord.person, c) for c in crecord.cases]
        for e in exps:
            e.expungement_type = Expungement.ExpungementTypes.FULL_EXPUNGEMENT
        conclusion.value = exps
        remaining_recordord = CRecord(person=copy.deepcopy(crecord.person),
                                      cases=[])
    else:
        conclusion.value = []
        remaining_recordord = crecord

    return remaining_recordord, conclusion
Example #2
0
def not_felony1(charge: Charge) -> Decision:
    """
    Any F1 graded offense disqualifies a whole record from sealing. 18 PA Code 9122.1(b)(2)(i)

    Returns:
        a True decision if the charge was NOT a felony1 conviction.
    """
    decision = Decision(name="Is the charge an F1 conviction?")
    if charge.grade.strip() == "":
        decision.value = False
        decision.reasoning = (
            "The charge's grade is unknown, so we don't know its *not* an F1."
        )
    elif re.match("F1", charge.grade):
        if charge.is_conviction():
            decision.value = False
            decision.reasoning = "The charge is an F1 conviction"
        else:
            decision.value = True
            decision.reasoning = (
                f"The charge was F1, but the disposition was {charge.disposition}"
            )
    else:
        decision.value = True
        decision.reasoning = f"The charge is {charge.grade}, which is not F1"

    return decision
Example #3
0
def expunge_over_70(crecord: CRecord) -> Tuple[CRecord, Decision]:
    """
    Analyze a crecord for expungements if the defendant is over 70.

    18 Pa.C.S. 9122(b)(1) provides for expungements of an individual who
    is 70 or older, and has been free of arrest or prosecution for 10
    years following the final release from confinement or supervision.
    """
    conclusion = Decision(
        name="A record can be expunged for a person over 70.",
        reasoning=[
            is_over_age(crecord.person, 70),
            years_since_last_contact(crecord, 10),
            years_since_final_release(crecord, 10)
        ])

    if all(conclusion.reasoning):
        exps = [
            Expungement(
                client=crecord.person,
                cases=[c],
                summary_expungement_language=
                "and the Petitioner is over 70 years old has been free of arrest or prosecution for ten years following from completion the sentence"
            ) for c in crecord.cases
        ]
        for e in exps:
            e.expungement_type = Expungement.ExpungementTypes.FULL_EXPUNGEMENT
        conclusion.value = exps
        remaining_recordord = CRecord(person=copy.deepcopy(crecord.person),
                                      cases=[])
    else:
        conclusion.value = []
        remaining_recordord = crecord

    return remaining_recordord, conclusion
Example #4
0
def no_danger_to_person_offense(
    item: Union[CRecord, Charge],
    within_years: int,
    penalty_limit: int,
    conviction_limit: int,
) -> Decision:
    """
    Individual is not eligible for sealing if they have been convicted within 20 years of an offense
    punishable by imprisonment of seven or more years which is an offense under Article B of Part II.
    
    18 Pa.C.S. 9122.1(b)(2)(A)(I) 


    A charge is not eligible for sealing if it is a conviction for an Article B of Part II (danger to the person)

    TODO currently sealing functions don't evaluate the time requirements (penalty_limit or within_years). B/C charges don't know when they happened.

    Args:
        item: A criminal record or a single Charge
        within_years: Person cannot have been convicted of the relevant offense within this number of years..
        penalty_limit: This rule applies to offenses with a sentence equal or greater than this limit.
        conviction_limit: The max number of times a peron can have this conviction before failing the rule.
    """
    # Suppose `item` is a whole Record.
    try:
        decision = Decision(
            name=
            "No convictions in the record for article B offenses, felonies or punishable by more than 7 years, in the last 20 years.",
            reasoning=[
                no_danger_to_person_offense(charge,
                                            within_years=within_years,
                                            penalty_limit=penalty_limit,
                                            conviction_limit=conviction_limit)
                for case in item.cases for charge in case.charges
            ])
        decision.value = all(decision.reasoning)
    except AttributeError:
        # `item` is probably a charge.
        decision = Decision(
            name="Is this not a conviction for an Article B offense")
        try:
            if (item.get_statute_chapter() == 18
                    and item.get_statute_section() > 2300
                    and item.get_statute_section() < 3300
                    and item.is_conviction()):
                decision.value = False
                decision.reasoning = f"Statute {item.statute} is an Article B conviction"
            else:
                decison.value = True
                decison.reasoning = f"Statute {item.statute} appears not to be an Article B conviction."
        except:
            decision.value = True
            decision.reasoning = f"Couldn't read the statute {item.statute}, so its probably not Article B."

    return decision
Example #5
0
def offenses_punishable_by_two_or_more_years(
    crecord: CRecord, conviction_limit: int, within_years: int
) -> Decision:
    """
    Not too many convictions for offenses punishable by two or more years.
    
    No sealing a record if it has four or more offenses punishable by two or more years within 20 years. 
    18 PaCS 9122.1(b)(2)(ii)(B)
    
    No sealing a record if it has two or more offenses punishable by more than two years in prison within
    15 years.. 18 PaCS 9122.1(b)(2)(iii)(A)

    The Expungement Generator uses the charge grade as a proxy for this. See Charge.php:284.

    So will RecordLib.

    Returns:
        A Decision we'll call `d`. `bool(d)` is True if there were no offenses punishable by more than 
        two years in `crecord`.

    """
    # Grades that approximately the grades of offenses that also have penalty's of two or more years.
    proxy_grades = ["F1", "F2", "F3", "F", "M1", "M2"]
    decision = Decision(
        name=f"The record has no more than {conviction_limit} convictions for offenses punishable by two or more years in the last {within_years} years.",
        reasoning=[
            charge for case in crecord.cases for charge in case.charges 
                if (charge.is_conviction() and 
                    (charge.grade in proxy_grades) and 
                    case.years_passed_disposition() < within_years)
        ]
    )
Example #6
0
def years_since_last_contact(crec: CRecord, year_min: int) -> Decision:
    return Decision(
        name=
        f"Has {crec.person.first_name} been free of arrest or prosecution for {year_min} years?",
        value=crec.years_since_last_arrested_or_prosecuted() >= 10,
        reasoning=
        f"It has been {crec.years_since_last_arrested_or_prosecuted()} years.")
Example #7
0
def no_f1_convictions(crecord: CRecord) -> Decision:
    """
    Any conviction for Murder, any F1 conviction, or any conviction punishable by imprisonment of 
    more than 20 years disqualifies a record from sealing.

    18 Pa.C.S. 9122.1(b)(2)(i)

    This method only checks for F1 and murder convictions, 
    not for convictions punishable by more than 20 years which are not F1 or murder.
    """
    decision = Decision(name="No F1 or murder convictions in the record?")
    decision.reasoning = [
        not_felony1(charge) and not_murder(charge) for case in crecord.cases
        for charge in case.charges
    ]
    decision.value = all(decision.reasoning)
    return decision
Example #8
0
def is_felony_conviction(charge: Charge) -> Decision:
    """
    Was `charge` a felony conviction

    Args:
        charge: A Charge.

    Return:
        A Decision that is True if the charge is a felony conviction.
    """
    decision = Decision(name=f"Was the charge [{charge.offense}, {charge.grade}, {charge.disposition}] a felony conviction?")
    decision.reasoning = [
        re.match("F", charge.grade, re.IGNORECASE),
        charge.is_conviction(),
    ]
    decision.value = all(decision.reasoning)
    return decision
Example #9
0
def no_indecent_exposure(crecord,
                         conviction_limit: int,
                         within_years: int = 15) -> Decision:
    """
    Cannot seal if record contains conviction for indecent exposure within 15 years.
    
    18 PaCS 9122.1(b)(2)(iii)(B)(I)
    """
    decision = Decision(
        name="No indecent exposure convictions in this record.",
        reasoning=[
            not (case.years_passed_disposition() < within_years and
                 charge.is_conviction() and charge.get_statute_chapter() == 18
                 and charge.get_statute_section() == 3127)
            for case in crecord.cases for charge in case.charges
        ])
    decision.value = all(decision.reasoning)
    return decision
Example #10
0
def no_weapons_of_escape(crecord: CRecord,
                         conviction_limit: int,
                         within_years: int = 15) -> Decision:
    """
    Cannot seal if record contains conviction for possession of implement or weapon of escape within 15 years.

    18 PA.C.S. 9122.1(b)(2)(iii)(B)(IV)
    """
    decision = Decision(
        name="No possion-of-implement-of-escape convictions in this record.",
        reasoning=[
            not (case.years_passed_disposition() < within_years and
                 charge.is_conviction() and charge.get_statute_chapter() == 18
                 and charge.get_statute_section() == 5122)
            for case in crecord.cases for charge in case.charges
        ])
    decision.value = all(decision.reasoning)
    return decision
Example #11
0
def no_sexual_intercourse_w_animal(crecord: CRecord,
                                   conviction_limit: int,
                                   within_years: int = 15) -> Decision:
    """
    Cannot seal if record contains conviction for intercourse w/ animal within 15 years.

    18 PA.C.S. 9122.1(b)(2)(iii)(B)(II)
    """
    decision = Decision(
        name="No intercourse with animals convictions in this record.",
        reasoning=[
            not (case.years_passed_disposition() < within_years and
                 charge.is_conviction() and charge.get_statute_chapter() == 18
                 and charge.get_statute_section() == 3129)
            for case in crecord.cases for charge in case.charges
        ])
    decision.value = all(decision.reasoning)
    return decision
Example #12
0
def no_paramilitary_training(crecord: CRecord,
                             conviction_limit: int,
                             within_years: int = 15) -> Decision:
    """
    Cannot seal if record contains conviction for paramilitary training within 15 years.

    18 PA.C.S. 9122.1(b)(2)(iii)(B)(VI)
    """
    decision = Decision(
        name="No paramilitary training offenses in this record.",
        # list where TRUE indicates a charge that is not a paramil. conviction.
        reasoning=[
            not (case.years_passed_disposition() < within_years and
                 charge.is_conviction() and charge.get_statute_chapter() == 18
                 and charge.get_statute_section() == 5515)
            for case in crecord.cases for charge in case.charges
        ])
    decision.value = all(decision.reasoning)
    return decision
Example #13
0
def no_abuse_of_corpse(crecord: CRecord,
                       conviction_limit: int,
                       within_years: int = 15) -> Decision:
    """
    Cannot seal if record contains conviction for abuse of corpse within 15 years.

    18 PA.C.S. 9122.1(b)(2)(iii)(B)(V)
    """
    decision = Decision(name="No abuse of corpse convictions in this record.",
                        reasoning=[
                            not (case.years_passed_disposition() < within_years
                                 and charge.is_conviction()
                                 and charge.get_statute_chapter() == 18
                                 and charge.get_statute_section() == 5510)
                            for case in crecord.cases
                            for charge in case.charges
                        ])
    decision.value = all(decision.reasoning)
    return decision
Example #14
0
def no_sexual_offense(
    item: Union[CRecord, Charge],
    penalty_limit: int,
    conviction_limit: int,
    within_years: int,
) -> Decision:
    """
    No disqualifying convictions for sexual offenses.

    No sealing a conviction if it was punishable by more than two years for offenses under 
    42 Pa.C.S. §§ 9799.14 (relating to sexual offenses and tier system) and 
    9799.55 (relating to registration). 18 Pa.C.S. 9122.1(b)(1)(iv)

    No sealing a record if it contains any conviction within 20 years for a felony or 
    offense punishable >= 7 years, for offenses under 42 Pa.C.S. §§ 9799.14 (relating to sexual 
    offenses and tier system) and 9799.55 (relating to registration). 18 PaCS 9122.1(b)(2)(ii)(A)(IV)

    Returns:
        True if the charge was NOT a disqualifying offense, or if the record does NOT contain any 
        disqulifying offenses.
    """
    # 18 Pa.C.S. 9799.14 and 9799.55 relate to quite a few other offenses.
    tiered_sex_offenses = ["2901a.1", "2902b",
					"2903b", "2904", "2910b", "3011b", "3121", "3122.1b", "3123",
					"3124.1", "3124.2a", "3124.2a.1", "3124.2a2", "3124.2a3",
					"3125", "3126a1", "3126a2", "3126a3", "3126a4", "3126a5",
					"3126a6", "3126a7", "3126a8", "4302b", "5902b", "5902b.1",
					"5903a3ii", "5903a4ii", "5903a5ii", "5903a6", "6301a1ii",
                    "6312", "6318", "6320", "7507.1"]
    # presume item is a Charge
    try:
        decision = Decision(name="This charge is not a disqualifying sexual or registration offense?")
        patt = re.compile(r"^(?P<chapt>\d+)\s*§\s(?P<section>\d+\.?\d*)\s*(?P<subsections>[\(\)A-Za-z0-9\.]+).*")
        matches = patt.match(item.statute)
        if not matches:
            decision.reasoning = "This doesn't appear to be one of the tiered sex offense statutes."
            decision.value = True
        else:
            this_offense = matches.group("section") + matches.group("subsections").replace("(","").replace(")","")
            decision.reasoning = [item.is_conviction(), 
                                  item.get_statute_chapter() == 18,
                                  this_offense in tiered_sex_offenses]
            decision.value = not all(decision.reasoning)
    except AttributeError: 
        # item is a CRecord
        decision = Decision(
            name=(f"Not convicted within {within_years} more than {conviction_limit} times " +
                  f"of certain sexual or registration-related offenses punishable by {penalty_limit} years"),
            reasoning = [no_sexual_offense(charge, penalty_limit=penalty_limit, conviction_limit=conviction_limit, within_years=within_years)
                         for case in item.cases for charge in case.charges
                         if case.years_passed_disposition() <= within_years]
        )
Example #15
0
def no_failure_to_register(crecord: CRecord,
                           conviction_limit: int,
                           within_years: int = 15) -> Decision:
    """
    Cannot seal if record contains conviction for failure to register within 15 years.

    18 PA.C.S. 9122.1(b)(2)(iii)(B)(III)
    """
    decision = Decision(
        name="No failure-to-register convictions in this record.",
        reasoning=[
            not (case.years_passed_disposition() < within_years
                 and charge.is_conviction()
                 and charge.get_statute_chapter() == 18 and
                 (charge.get_statute_section() == 4915.1
                  or charge.get_statute_section() == 4915.2))
            for case in crecord.cases for charge in case.charges
        ])
    decision.value = all(decision.reasoning)
    return decision
Example #16
0
def no_offense_against_family(
    item: Union[CRecord, Charge],
    penalty_limit: int,
    conviction_limit: int,
    within_years: int,
) -> Decision:
    """
    Individuals are ineligible for sealing with certain offenses against the family. (Article D of Part II)

    Individual ineligible after 1 conviction within 20 years of an offense against the family 
    if a felony or if punishable by seven or more years.  18 Pa.C.S. 9122.1(b)(2)(A).

    Individuals ineligible after 2 convictions within 15 years of an offense against the family 
    if a felony or punishable by more than 2 years. 18 Pa.C.S. 9122.1(b)(3)(ii)(B)
    """
    # Presume a Charge
    try:
        decision = Decision(
            name=
            f"Charge for {item.statute} is not an offense against the family.",
            reasoning=[
                item.is_conviction() and item.get_statute_chapter() == 18
                and item.get_statute_section() > 4300
                and item.get_statute_section() < 4500
            ])
        decision.value = not all(decision.reasoning)
    except AttributeError:
        # `item` may be a whole record.
        decision = Decision(
            name=
            (f"Not convicted within {within_years} more than {conviction_limit} times "
             + f"of felony or offense punishable by {penalty_limit} years."),
            # reasoning should be a list of charges w/in 20 years where no_offense_fam(charge) is False
            reasoning=[
                no_offense_against_family(charge,
                                          penalty_limit=penalty_limit,
                                          conviction_limit=conviction_limit,
                                          within_years=within_years)
                for case in item.cases for charge in case.charges
                if case.years_passed_disposition() <= within_years
            ])
Example #17
0
def ten_years_since_last_conviction(crecord: CRecord) -> Decision:
    """
    Person is not eligible for sealing unless they have been "free from conviction
    for a period of 10 years" 18 Pa C.S. § 9122.1(a)

    Args:
        crecord: A criminal record

    Returns:
        a Decision indicating if the record has a conviction that's more recent than 10 years.
    """

    decision = Decision(
        name="Has the person been free of conviction for at least 10 years?",
        reasoning= [
            charge.is_conviction() and (case.years_passed_disposition() >= 10) for case in crecord.cases for charge in case.charges
    ])
    decision.value = all(decision.reasoning)
    

    return decision
Example #18
0
def no_corruption_of_minors_offense(
    charge: Charge, penalty_limit: int, conviction_limit: int, within_years: int
) -> Decision:
    """
    No disqualifying convictions for corruption of minors.

    No sealing a conviction if it was punishable by more than two years for offenses under 
    section 6301(a)(1), corruption of minors. 18 Pa.C.S. 9122.1(b)(1)(v)

    Returns:
        a True Decision if the charge was NOT a disqualifying offense. Otherwise a False Decision.
    """
    decision = Decision(name="This charge is not a disqualifying corruption of minors offense?")
    patt = re.compile(r"^(?P<chapt>\d+)\s*§\s(?P<section>\d+\.?\d*)\s*(?P<subsections>[\(\)A-Za-z0-9\.]+).*")
    matches = patt.match(charge.statute)
    if not matches:
        decision.reasoning = "This doesn't appear to be one of the tiered sex offense statutes."
        decision.value = True
    else:
        this_offense = matches.group("section") + matches.group("subsections").replace("(","").replace(")","")
        decision.reasoning = [charge.is_conviction(), 
                                charge.get_statute_chapter() == 18,
                                this_offense == "6301a1"]
        decision.value = not all(decision.reasoning)
    return decision
Example #19
0
def any_felony_convictions_n_years(crecord: CRecord, years: int) -> Decision:
    """
    Were there any felony convictions in the last `years` years?

    Implemented for triaging.

    Args:
        crecord: a Criminal Record.
        years: The threshold number of years to consider

    Return:
        A Decision that is True if there were felony convictions within `years` years.

    """
    decision = Decision(name=f"Were there any felony convictions within {years}")
    decision.reasoning = [
        is_felony_conviction(charge) and case.years_passed_disposition() > years
        for case in crecord.cases
        for charge in case.charges
    ]
    decision.value = all(decision.reasoning)
    return decision
Example #20
0
def no_corruption_of_minors(charge: Charge, penalty_limit: int,
                            conviction_limit: int,
                            within_years: int) -> Decision:
    """
    No disqualifying convictions for corruption of minors.

    No sealing a conviction if it was punishable by more than two years for offenses under 
    section 6301(a)(1), corruption of minors. 18 Pa.C.S. 9122.1(b)(1)(v)

    """
    return Decision(name="Not a corruption of minors offense",
                    value=True,
                    reasoning="Not implemented yet.")
Example #21
0
def no_paramilitary_training(
    crecord: CRecord, conviction_limit: int, within_years: int=15) -> Decision:
    """
    Cannot seal if record contains conviction for paramilitary training within 15 years.

    18 PA.C.S. 9122.1(b)(2)(iii)(B)(VI)
    """
    decision = Decision(
        name="No paramilitary training offenses in this record.",
        reasoning=[charge for case in crecord.cases for charge in case.charges if 
                       (case.years_passed_disposition() < within_years and
                        charge.is_conviction() and 
                        charge.get_statute_chapter() == 18 and
                        charge.get_statute_section() == 5515)]
    )
Example #22
0
def expunge_nonconvictions(crecord: CRecord) -> Tuple[CRecord, dict]:
    """
    18 Pa.C.S. 9122(a) provides that non-convictions (cases are closed with no disposition recorded) "shall be expunged."
    
    Returns:
        a Decision with:
            name: str,
            value: [Petition],
            reasoning: [Decision]
    """
    conclusion = Decision(name="Expungements of nonconvictions.",
                          value=[],
                          reasoning=[])

    remaining_recordord = CRecord(person=crecord.person)
    for case in crecord.cases:
        case_d = Decision(
            name=f"Does {case.docket_number} have expungeable nonconvictions?",
            reasoning=[])
        unexpungeable_case = case.partialcopy()
        expungeable_case = case.partialcopy()
        for charge in case.charges:
            charge_d = Decision(
                name=f"Is the charge for {charge.offense} a nonconviction?",
                value=not charge.is_conviction(),
                reasoning=
                f"The charge's disposition {charge.disposition} indicates a conviction"
                if charge.is_conviction() else
                f"The charge's disposition {charge.disposition} indicates its not a conviction."
            )

            if bool(charge_d) is True:
                expungeable_case.charges.append(charge)
            else:
                unexpungeable_case.charges.append(charge)
            case_d.reasoning.append(charge_d)

        # If there are any expungeable charges, add an Expungepent to the Value of the decision about
        # this whole record.
        if len(expungeable_case.charges) > 0:
            case_d.value = True
            exp = Expungement(client=crecord.person, cases=[expungeable_case])
            if len(expungeable_case.charges) == len(case.charges):
                exp.expungement_type = Expungement.ExpungementTypes.FULL_EXPUNGEMENT
            else:
                exp.expungement_type = Expungement.ExpungementTypes.PARTIAL_EXPUNGEMENT
            conclusion.value.append(exp)
        else:
            case_d.value = False

        if len(unexpungeable_case.charges) > 0:
            remaining_recordord.cases.append(unexpungeable_case)
        conclusion.reasoning.append(case_d)
Example #23
0
def no_indecent_exposure(crecord, conviction_limit: int, within_years: int=15) -> Decision:
    """
    Cannot seal if record contains conviction for indecent exposure within 15 years.
    18 PaCS 9122.1(b)(2)(iii)(B)(I)
    
    Returns:
        A Decision we'll call `d`. `bool(d)` is True if there were no indecent exposure 
        offenses in `crecord`.

    """
    decision = Decision(
        name="No indecent exposure convictions in this record.",
        reasoning=[charge for case in crecord.cases for charge in case.charges if 
            (case.years_passed_disposition() < within_years and
                        charge.is_conviction() and 
                        charge.get_statute_chapter() == 18 and
                        charge.get_statute_section() == 3127)]
    )
Example #24
0
def no_offense_against_family(
    item: Union[CRecord, Charge],
    penalty_limit: int,
    conviction_limit: int,
    within_years: int,
) -> Decision:
    """
    Individuals are ineligible for sealing with certain offenses against the family. (Article D of Part II)

    Individual ineligible after 1 conviction within 20 years of an offense against the family 
    if a felony or if punishable by seven or more years.  18 Pa.C.S. 9122.1(b)(2)(A).

    Individuals ineligible after 2 convictions within 15 years of an offense against the family 
    if a felony or punishable by more than 2 years. 18 Pa.C.S. 9122.1(b)(3)(ii)(B)

    Returns:
        True if the charge was NOT a disqualifying offense, or if the record does NOT contain any 
        disqulifying offenses.
    """
    # Presume a Charge
    try:
        decision = Decision(
            name=f"Charge for {item.statute} is not an offense against the family.",
            reasoning=[
                item.is_conviction(), 
                item.get_statute_chapter() == 18, 
                item.get_statute_section() > 4300,
                item.get_statute_section() < 4500
            ])
        decision.value = not all(decision.reasoning)
    except TypeError:
        # `item`'s get_statute functions returned something that doesn't have < > defined, such as None.
        decision = Decision(
            name=f"Charge for {item.statute} is not an offense against the family.",
            reasoning = "The statute doesn't appear to be one of the Article D offense statutes.",
            value=True
        )
    except AttributeError:
        # `item` may be a whole record.
        decision = Decision(
            name=(f"Not convicted within {within_years} more than {conviction_limit} times " +
                  f"of felony or offense punishable by {penalty_limit} years."),
            # reasoning should be a list of charges w/in 20 years where no_offense_fam(charge) is False
            reasoning = [no_offense_against_family(charge, penalty_limit=penalty_limit, conviction_limit=conviction_limit, within_years=within_years)
                         for case in item.cases for charge in case.charges
                         if case.years_passed_disposition() <= within_years]
        )
Example #25
0
def no_firearms_offense(
    item: Union[CRecord, Charge],
    penalty_limit: int,
    conviction_limit: int,
    within_years: int,
) -> Decision:
    """
    No disqualifying convictions for firearms offenses. (Chapter 61 offenses) 
    
    No sealing conviction if punishable by more than two years for Chapter 61 (firearms) offenses. 
    18 Pa.C.S. 9122.1(b)(1)(iii)

    No sealing record if contains any conviction ithin 20 years for a felony or offense 
    punishable >= 7 years for Chapter 61 offenses. 18 Pa.C.S. 9122.1(b)(2)(ii)(A)(II)

    Returns:
        True if the charge was NOT a disqualifying offense, or if the record does NOT contain any 
        disqulifying offenses.
 
    """
    # assume item is a charge.
    try:
        decision = Decision(
            name=f"Charge for {item.statute} is not a firearms offense.",
            reasoning=[
                item.get_statute_chapter() == 18, 
                item.get_statute_section() > 6100,
                item.get_statute_section() < 6200
            ])
        decision.value = not all(decision.reasoning)
    except TypeError:
        # `item`'s get_statute functions returned something that doesn't have < > defined, such as None.
        decision = Decision(
            name=f"Charge for {item.statute} is not a Chapter 61 firearms offense.",
            reasoning = "The statute doesn't appear to be one of the Article D offense statutes.",
            value=True
        )
    except AttributeError:
        # `item` may be a whole record.
        decision = Decision(
            name=(f"Not convicted within {within_years} more than {conviction_limit} times " +
                  f"of felony or offense punishable by {penalty_limit} years."),
            # reasoning should be a list of charges w/in 20 years where no_offense_fam(charge) is False
            reasoning = [no_firearms_offense(charge, penalty_limit=penalty_limit, conviction_limit=conviction_limit, within_years=within_years)
                         for case in item.cases for charge in case.charges
                         if case.years_passed_disposition() <= within_years]
        )
Example #26
0
def not_murder(charge: Charge) -> Decision:
    """
    Checks if a charge was a conviction for murder. 
    
    Returns true if the charge was NOT a murder conviction.

    TODO The Expungement Generator's test is for the statute 18 PaCS 1502. Does the implementation here even work? Need to find real murder convictions to see.
    """
    decision = Decision(name="Is the charge NOT a murder conviction?")
    if charge.is_conviction():
        if re.match("murder", charge.offense, re.IGNORECASE):
            decision.value = False
            decision.reasoning = "The charge was a murder conviction."
        else:
            decision.value = True
            decision.reasoning = "Conviction for something other than murder."
    else:
        decision.value = True
        decision.reasoning = "Not a conviction."
    return decision
Example #27
0
def fines_and_costs_paid(crecord: CRecord) -> Decision:
    """
    In individual is not eligible for sealing unless all fines and costs have been paid.

    18 Pa. C.S. § 9122.1(a).

    Args:
        crecord: A criminal record

    Returns:
        a Decision indicating if all fines and costs have been paid on the Record.
    """
    decision = Decision(
        name="Fines and costs are all paid on the whole record?",
        reasoning=[
            {"case": case.docket_number, "total fines": case.total_fines, "fines paid": case.fines_paid}
            for case in crecord.cases
        ],
    )
Example #28
0
def no_firearms_offense(
    item: Union[CRecord, Charge],
    penalty_limit: int,
    conviction_limit: int,
    within_years: int,
) -> Decision:
    """
    No disqualifying convictions for firearms offenses. 
    
    No sealing conviction if punishable by more than two years for Chapter 61 (firearms) offenses. 
    18 Pa.C.S. 9122.1(b)(1)(iii)

    No sealing record if contains any conviction ithin 20 years for a felony or offense 
    punishable >= 7 years for Chapter 61 offenses. 18 Pa.C.S. 9122.1(b)(2)(ii)(A)(II)

    """
    return Decision(name="Not a firearms offense",
                    value=True,
                    reasoning="Not implemented yet.")
Example #29
0
def no_failure_to_register(
    crecord: CRecord, conviction_limit: int, within_years: int=15) -> Decision:
    """
    Cannot seal if record contains conviction for failure to register within 15 years.

    18 PA.C.S. 9122.1(b)(2)(iii)(B)(III)

    Returns:
        a Decision that is True if there were no failure-to-register offenses in the record.
    """
    decision = Decision(
        name="No failure-to-register convictions in this record.",
        reasoning=[charge for case in crecord.cases for charge in case.charges if 
                       (case.years_passed_disposition() < within_years and
                        charge.is_conviction() and 
                        charge.get_statute_chapter() == 18 and
                        (charge.get_statute_section() == 4915.1 or
                         charge.get_statute_section() == 4915.2))]
    )
Example #30
0
def no_sexual_offense(
    item: Union[CRecord, Charge],
    penalty_limit: int,
    conviction_limit: int,
    within_years: int,
) -> Decision:
    """
    No disqualifying convictions for sexual offenses.

    No sealing a conviction if it was punishable by more than two years for offenses under 
    42 Pa.C.S. §§ 9799.14 (relating to sexual offenses and tier system) and 
    9799.55 (relating to registration). 18 Pa.C.S. 9122.1(b)(1)(iv)

    No sealing a record if it contains any conviction within 20 years for a felony or 
    offense punishable >= 7 years, for offenses under 42 Pa.C.S. §§ 9799.14 (relating to sexual 
    offenses and tier system) and 9799.55 (relating to registration). 18 PaCS 9122.1(b)(2)(ii)(A)(IV)
    """
    return Decision(name="Not a sexual offense",
                    value=True,
                    reasoning="Not implemented yet.")