Пример #1
0
def test_render_expungement_petition(example_person, example_attorney, example_case): 
    p = Expungement(attorney=example_attorney, client=example_person, cases=[example_case], 
                    expungement_type=Expungement.ExpungementTypes.FULL_EXPUNGEMENT)
    with open("tests/templates/790ExpungementTemplate_usingpythonvars.docx", "rb") as doc:
        p.set_template(doc)

    doc = p.render()
    # use doc.save() to manually inspect the rendered petition.
    assert "docx" in doc.__dict__.keys()
Пример #2
0
def expunge_nonconvictions(
        crecord: CRecord) -> Tuple[CRecord, PetitionDecision]:
    """
    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)
Пример #3
0
def test_expungement_petition(example_attorney, example_person, example_case):
    p = Expungement(attorney=example_attorney, client=example_person, cases=[example_case], 
                    expungement_type=Expungement.ExpungementTypes.FULL_EXPUNGEMENT,
                    procedure=Expungement.ExpungementProcedures.NONSUMMARY_EXPUNGEMENT)
    assert p.cases[0] == example_case
    assert p.expungement_type == Expungement.ExpungementTypes.FULL_EXPUNGEMENT
    assert p.procedure == Expungement.ExpungementProcedures.NONSUMMARY_EXPUNGEMENT
Пример #4
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
Пример #5
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
Пример #6
0
    def post(self, request):
        """
        Accept an object describing petitions to generate, and generate them.
        """
        try:
            serializer = DocumentRenderSerializer(data=request.data)
            if serializer.is_valid():
                petitions = []
                for petition_data in serializer.validated_data["petitions"]:
                    if petition_data["petition_type"] == "Sealing":
                        new_petition = Sealing.from_dict(petition_data)
                        # this could be done earlier, if needed, to avoid querying db over and over.
                        # but we'd need to test what types of templates are actually needed.
                        try:
                            new_petition.set_template(
                                request.user.userprofile.
                                sealing_petition_template.file)
                            petitions.append(new_petition)
                        except Exception as err:
                            logger.error(
                                "User has not set a sealing petition template, or "
                            )
                            logger.error(str(err))
                            continue
                    else:
                        new_petition = Expungement.from_dict(petition_data)
                        try:
                            new_petition.set_template(
                                request.user.userprofile.
                                expungement_petition_template.file)
                            petitions.append(new_petition)
                        except Exception as err:
                            logger.error(
                                "User has not set an expungement petition template, or "
                            )
                            logger.error(str(err))
                            continue
                client_last = petitions[0].client.last_name
                petitions = [(p.file_name(), p.render()) for p in petitions]
                package = Compressor(f"ExpungementsFor{client_last}.zip",
                                     petitions)

                logger.info("Returning x-accel-redirect to zip file.")

                resp = HttpResponse()
                resp["Content-Type"] = "application/zip"
                resp[
                    "Content-Disposition"] = f"attachment; filename={package.name}"
                resp["X-Accel-Redirect"] = f"/protected/{package.name}"
                return resp
            else:
                raise ValueError
        except Exception as e:
            logger.error(str(e))
            return Response("Something went wrong",
                            status=status.HTTP_400_BAD_REQUEST)
Пример #7
0
def example_expungement(example_crecord, example_attorney):
    return Expungement(
        expungement_type=Expungement.ExpungementTypes.FULL_EXPUNGEMENT,
        attorney=example_attorney,
        cases=example_crecord.cases,
        client=example_crecord.person,
        ifp_message="IFP Message",
        service_agencies=["Police Academy I"],
        include_crim_hist_report=True,
    )
Пример #8
0
def expunge_summary_convictions(crecord: CRecord) -> Tuple[CRecord, Decision]:
    """
    Analyze crecord for expungements of summary convictions.

    18 Pa.C.S. 9122(b)(3)(i) and (ii) provide for expungement of summary convictions if the individual has been free of arrest or prosecution for five years following the conviction for the offense.

    Not available if person got ARD for certain offenses listed in (b.1)

    Returns:
        The function creates a Decision. The Value of the decision is a list of the Petions that can be
        generated according to this rule. The Reasoning of the decision is a list of decisions. The first
        decision is the global requirement for any expungement under this rule. The following decisions
        are a decision about the expungeability of each case. Each case-decision, contains its own explanation
        of what charges were or were not expungeable.  

    TODO excluding ARD offenses from expungements here.

    TODO grades are often missing. We should tell users we're uncertain.
    """
    # Initialize the decision explaining this rule's outcome. It starts with reasoning that includes the
    # decisions that are conditions of any case being expungeable.
    conclusion = Decision(
        name="Expungements for summary convictions.",
        value=[],
        reasoning=[
            Decision(
                name=
                f"Has {crecord.person.first_name} been arrest free and prosecution free for five years?",
                value=crecord.years_since_last_arrested_or_prosecuted() > 5,
                reasoning=
                f"It has been {crecord.years_since_last_arrested_or_prosecuted()} since the last arrest or prosecection."
            )
        ])

    # initialize a blank crecord to hold the cases and charges that can't be expunged under this rule.
    remaining_recordord = CRecord(person=crecord.person)
    if all(conclusion.reasoning):
        for case in crecord.cases:
            # Find expungeable charges in a case. Save a Decision explaining what's expungeable to
            # the reasoning of the Decision about the whole record.
            case_d = Decision(name=f"Is {case.docket_number} expungeable?",
                              reasoning=[])
            expungeable_case = case.partialcopy(
            )  # The charges in this case that are expungeable.
            not_expungeable_case = case.partialcopy(
            )  # Charges in this case that are not expungeable.
            for charge in case.charges:
                charge_d = Decision(
                    name=
                    f"Is this charge for {charge.offense} a summary conviction?",
                    reasoning=[
                        Decision(
                            name=
                            f"Is this charge for {charge.offense} a summary?",
                            value=charge.grade.strip() == "S",
                            reasoning=
                            f"The charge's grade is {charge.grade.strip()}"),
                        Decision(
                            name=
                            f"Is this charge for {charge.offense} a conviction?",
                            value=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 all(charge_d.reasoning):
                    expungeable_case.charges.append(charge)
                    charge_d.value = True
                else:
                    charge_d.value = False
                    not_expungeable_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],
                    summary_expungement_language=
                    ".  The petitioner has been arrest free for more than five years since this summary conviction"
                )
                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)
            if len(not_expungeable_case.charges) > 0:
                case_d.value = False

        remaining_recordord.cases.append(not_expungeable_case)
        conclusion.reasoning.append(case_d)