Пример #1
0
    def _test_us_nd_pre_commitment_supervision_period(
        admission_date: date,
        admission_reason: StateIncarcerationPeriodAdmissionReason,
        supervision_periods: List[StateSupervisionPeriod],
    ) -> Optional[StateSupervisionPeriod]:
        ip = StateIncarcerationPeriod.new_with_defaults(
            state_code="US_ND",
            incarceration_period_id=111,
            status=StateIncarcerationPeriodStatus.IN_CUSTODY,
            admission_date=admission_date,
            admission_reason=admission_reason,
        )

        incarceration_periods = [ip]

        return _get_commitment_from_supervision_supervision_period(
            incarceration_period=ip,
            commitment_from_supervision_delegate=
            UsNdCommitmentFromSupervisionDelegate(),
            supervision_period_index=PreProcessedSupervisionPeriodIndex(
                supervision_periods),
            incarceration_period_index=PreProcessedIncarcerationPeriodIndex(
                incarceration_periods=incarceration_periods,
                ip_id_to_pfi_subtype={
                    ip.incarceration_period_id: None
                    for ip in incarceration_periods
                    if ip.incarceration_period_id
                },
            ),
        )
    def test_us_nd_infer_supervision_period_previous_period_termination_reason_revocation(
        self,
    ) -> None:
        previous_supervision_period: StateSupervisionPeriod = (
            StateSupervisionPeriod.new_with_defaults(
                supervision_period_id=111,
                external_id="sp1",
                status=StateSupervisionPeriodStatus.UNDER_SUPERVISION,
                state_code="US_XX",
                supervising_officer="AGENTX",
                start_date=date(2018, 2, 20),
                termination_date=date(2018, 2, 22),
                termination_reason=StateSupervisionPeriodTerminationReason.REVOCATION,
                supervision_type=StateSupervisionType.PAROLE,
            )
        )
        current_supervision_period: StateSupervisionPeriod = (
            StateSupervisionPeriod.new_with_defaults(
                supervision_period_id=111,
                external_id="sp1",
                status=StateSupervisionPeriodStatus.UNDER_SUPERVISION,
                state_code="US_XX",
                supervising_officer="AGENTY",
                start_date=date(2018, 3, 5),
                termination_date=date(2018, 5, 19),
                termination_reason=StateSupervisionPeriodTerminationReason.DISCHARGE,
                supervision_type=StateSupervisionType.PAROLE,
            )
        )

        supervision_period_index = PreProcessedSupervisionPeriodIndex(
            supervision_periods=[
                previous_supervision_period,
                current_supervision_period,
            ]
        )

        incarceration_period_index = PreProcessedIncarcerationPeriodIndex(
            incarceration_periods=[],
            ip_id_to_pfi_subtype={},
        )

        admission_reason: Optional[
            StateSupervisionPeriodAdmissionReason
        ] = us_nd_infer_supervision_period_admission(
            current_supervision_period,
            supervision_period_index,
            incarceration_period_index,
        )

        self.assertEqual(
            admission_reason,
            StateSupervisionPeriodAdmissionReason.COURT_SENTENCE,
        )
    def test_us_nd_infer_supervision_period_admission_return_from_absconsion(
        self,
    ) -> None:
        previous_supervision_period: StateSupervisionPeriod = (
            StateSupervisionPeriod.new_with_defaults(
                supervision_period_id=111,
                external_id="sp1",
                status=StateSupervisionPeriodStatus.UNDER_SUPERVISION,
                state_code="US_XX",
                start_date=date(2018, 2, 20),
                termination_date=date(2018, 2, 22),
                termination_reason=StateSupervisionPeriodTerminationReason.ABSCONSION,
                supervision_type=None,
            )
        )
        current_supervision_period: StateSupervisionPeriod = (
            StateSupervisionPeriod.new_with_defaults(
                supervision_period_id=111,
                external_id="sp1",
                status=StateSupervisionPeriodStatus.UNDER_SUPERVISION,
                state_code="US_XX",
                start_date=date(2018, 3, 5),
                termination_date=date(2018, 5, 19),
                termination_reason=StateSupervisionPeriodTerminationReason.DISCHARGE,
                supervision_type=None,
            )
        )

        supervision_period_index = PreProcessedSupervisionPeriodIndex(
            supervision_periods=[
                previous_supervision_period,
                current_supervision_period,
            ]
        )

        incarceration_period_index = PreProcessedIncarcerationPeriodIndex(
            incarceration_periods=[],
            ip_id_to_pfi_subtype={},
        )

        admission_reason: Optional[
            StateSupervisionPeriodAdmissionReason
        ] = us_nd_infer_supervision_period_admission(
            current_supervision_period,
            supervision_period_index,
            incarceration_period_index,
        )

        self.assertEqual(
            admission_reason,
            StateSupervisionPeriodAdmissionReason.RETURN_FROM_ABSCONSION,
        )
    def test_us_nd_infer_supervision_period_admission_conditional_release(self) -> None:
        previous_incarceration_period: StateIncarcerationPeriod = StateIncarcerationPeriod.new_with_defaults(
            incarceration_period_id=1112,
            external_id="2",
            incarceration_type=StateIncarcerationType.STATE_PRISON,
            status=StateIncarcerationPeriodStatus.NOT_IN_CUSTODY,
            state_code="US_ND",
            facility="PRISON",
            admission_date=date(2018, 2, 20),
            admission_reason=StateIncarcerationPeriodAdmissionReason.PROBATION_REVOCATION,
            admission_reason_raw_text="Revocation",
            release_date=date(2018, 2, 21),
            release_reason=StateIncarcerationPeriodReleaseReason.CONDITIONAL_RELEASE,
            release_reason_raw_text="NOT A VALID RAW TEXT VALUE",
        )
        current_supervision_period: StateSupervisionPeriod = (
            StateSupervisionPeriod.new_with_defaults(
                supervision_period_id=111,
                external_id="sp1",
                status=StateSupervisionPeriodStatus.UNDER_SUPERVISION,
                state_code="US_XX",
                start_date=date(2018, 3, 5),
                termination_date=date(2018, 5, 19),
                termination_reason=StateSupervisionPeriodTerminationReason.DISCHARGE,
                supervision_type=None,
            )
        )

        supervision_period_index = PreProcessedSupervisionPeriodIndex(
            supervision_periods=[current_supervision_period]
        )

        incarceration_period_index = PreProcessedIncarcerationPeriodIndex(
            incarceration_periods=[previous_incarceration_period],
            ip_id_to_pfi_subtype={1112: None},
        )

        admission_reason: Optional[
            StateSupervisionPeriodAdmissionReason
        ] = us_nd_infer_supervision_period_admission(
            current_supervision_period,
            supervision_period_index,
            incarceration_period_index,
        )

        self.assertEqual(
            admission_reason, StateSupervisionPeriodAdmissionReason.CONDITIONAL_RELEASE
        )
Пример #5
0
    def _test_get_commitment_from_supervision_details(
        incarceration_period: StateIncarcerationPeriod,
        supervision_periods: Optional[List[StateSupervisionPeriod]] = None,
        incarceration_period_index: Optional[
            PreProcessedIncarcerationPeriodIndex] = None,
        supervision_period_to_agent_associations: Optional[Dict[int, Dict[
            Any, Any]]] = None,
    ):
        """Helper function for testing get_commitment_from_supervision_details."""
        supervision_period_to_agent_associations = (
            supervision_period_to_agent_associations
            or DEFAULT_SUPERVISION_PERIOD_AGENT_ASSOCIATIONS)
        incarceration_period_index = (
            incarceration_period_index or PreProcessedIncarcerationPeriodIndex(
                incarceration_periods=[incarceration_period],
                ip_id_to_pfi_subtype=({
                    incarceration_period.incarceration_period_id:
                    None
                } if incarceration_period.incarceration_period_id else {}),
            ))

        supervision_period_index = PreProcessedSupervisionPeriodIndex(
            supervision_periods=(supervision_periods or []))

        return commitment_from_supervision_utils.get_commitment_from_supervision_details(
            incarceration_period=incarceration_period,
            incarceration_period_index=incarceration_period_index,
            supervision_period_index=supervision_period_index,
            # No state-agnostic tests require the sentences
            incarceration_sentences=[],
            supervision_sentences=[],
            commitment_from_supervision_delegate=
            UsXxCommitmentFromSupervisionDelegate(),
            supervision_period_to_agent_associations=
            supervision_period_to_agent_associations,
            state_specific_officer_and_location_info_from_supervision_period_fn
            =get_state_specific_supervising_officer_and_location_info_function(
                incarceration_period.state_code),
        )
    def test_us_nd_infer_supervision_period_admission_no_previous_period_parole(
        self,
    ) -> None:
        current_supervision_period: StateSupervisionPeriod = (
            StateSupervisionPeriod.new_with_defaults(
                supervision_period_id=111,
                external_id="sp1",
                status=StateSupervisionPeriodStatus.UNDER_SUPERVISION,
                state_code="US_XX",
                start_date=date(2018, 3, 5),
                termination_date=date(2018, 5, 19),
                termination_reason=StateSupervisionPeriodTerminationReason.DISCHARGE,
                supervision_type=StateSupervisionType.PAROLE,
            )
        )

        supervision_period_index = PreProcessedSupervisionPeriodIndex(
            supervision_periods=[
                current_supervision_period,
            ]
        )

        incarceration_period_index = PreProcessedIncarcerationPeriodIndex(
            incarceration_periods=[],
            ip_id_to_pfi_subtype={},
        )

        admission_reason: Optional[
            StateSupervisionPeriodAdmissionReason
        ] = us_nd_infer_supervision_period_admission(
            current_supervision_period,
            supervision_period_index,
            incarceration_period_index,
        )

        self.assertEqual(
            admission_reason,
            StateSupervisionPeriodAdmissionReason.CONDITIONAL_RELEASE,
        )
Пример #7
0
def _get_commitment_from_supervision_supervision_period(
    incarceration_period: StateIncarcerationPeriod,
    commitment_from_supervision_delegate:
    StateSpecificCommitmentFromSupervisionDelegate,
    supervision_period_index: PreProcessedSupervisionPeriodIndex,
    incarceration_period_index: PreProcessedIncarcerationPeriodIndex,
) -> Optional[StateSupervisionPeriod]:
    """Identifies the supervision period associated with the commitment to supervision
    admission on the given |admission_date|.

    If |prioritize_overlapping_periods| is True, prioritizes supervision periods that
    are overlapping with the |admission_date|. Else, prioritizes the period that has
    most recently terminated within SUPERVISION_PERIOD_PROXIMITY_MONTH_LIMIT months of
    the |admission_date|.
    """
    if not supervision_period_index.supervision_periods:
        return None

    if not incarceration_period.admission_date:
        raise ValueError(
            "Unexpected missing admission_date on incarceration period: "
            f"[{incarceration_period}]")
    if not incarceration_period.admission_reason:
        raise ValueError(
            "Unexpected missing admission_reason on incarceration period: "
            f"[{incarceration_period}]")

    admission_date = incarceration_period.admission_date
    admission_reason = incarceration_period.admission_reason

    if not is_commitment_from_supervision(admission_reason):
        raise ValueError(
            "This function should only be called with an "
            "incarceration_period that is a commitment from supervision. "
            "Found an incarceration period with an admission_reason that "
            "is not a valid commitment from supervision admission: "
            f"{admission_reason}.")

    preceding_incarceration_period = (
        incarceration_period_index.preceding_incarceration_period_in_index(
            incarceration_period))

    if period_is_commitment_from_supervision_admission_from_parole_board_hold(
            incarceration_period=incarceration_period,
            preceding_incarceration_period=preceding_incarceration_period,
    ):
        if not preceding_incarceration_period:
            raise ValueError(
                "This should never happen, since the determination of "
                "whether the commitment came from a board hold requires "
                "the preceding_incarceration_period to be a board hold.")

        if not preceding_incarceration_period.admission_date:
            raise ValueError(
                "Unexpected missing admission_date on incarceration period: "
                f"[{preceding_incarceration_period}]")

        # If this person was a commitment from supervision from a parole board hold,
        # then the date that they entered prison was the date of the preceding
        # incarceration period.
        admission_date = preceding_incarceration_period.admission_date

    relevant_periods = _get_relevant_sps_for_pre_commitment_sp_search(
        admission_reason=admission_reason,
        supervision_periods=supervision_period_index.supervision_periods,
        commitment_from_supervision_delegate=
        commitment_from_supervision_delegate,
    )

    overlapping_periods = _supervision_periods_overlapping_with_date(
        admission_date, relevant_periods)

    # If there's more than one recently terminated period with the same
    # termination_date, prioritize the ones with REVOCATION or RETURN_TO_INCARCERATION
    # termination_reasons
    def _same_date_sort_override(period_a: StateSupervisionPeriod,
                                 period_b: StateSupervisionPeriod) -> int:
        prioritized_termination_reasons = [
            StateSupervisionPeriodTerminationReason.REVOCATION,
            StateSupervisionPeriodTerminationReason.RETURN_TO_INCARCERATION,
        ]
        prioritize_a = period_a.termination_reason in prioritized_termination_reasons
        prioritize_b = period_b.termination_reason in prioritized_termination_reasons

        if prioritize_a and prioritize_b:
            return sort_period_by_external_id(period_a, period_b)
        return -1 if prioritize_a else 1

    most_recent_terminated_period = find_last_terminated_period_before_date(
        upper_bound_date=admission_date,
        periods=relevant_periods,
        maximum_months_proximity=SUPERVISION_PERIOD_PROXIMITY_MONTH_LIMIT,
        same_date_sort_fn=_same_date_sort_override,
    )

    terminated_periods = ([most_recent_terminated_period]
                          if most_recent_terminated_period else [])

    if (admission_reason in commitment_from_supervision_delegate.
            admission_reasons_that_should_prioritize_overlaps_in_pre_commitment_sp_search(
            )):
        valid_pre_commitment_periods = (
            overlapping_periods if overlapping_periods else terminated_periods)
    else:
        valid_pre_commitment_periods = (
            terminated_periods if terminated_periods else overlapping_periods)

    if not valid_pre_commitment_periods:
        return None

    # In the case where there are multiple relevant SPs at this point, sort and return
    # the first one
    return min(
        valid_pre_commitment_periods,
        key=lambda e: (
            # Prioritize terminated periods with a termination_reason of REVOCATION
            # (False sorts before True)
            e.termination_reason != StateSupervisionPeriodTerminationReason.
            REVOCATION,
            # Prioritize termination_date closest to the admission_date
            abs(((e.termination_date or datetime.date.today()) - admission_date
                 ).days),
            # Deterministically sort by external_id in the case where there
            # are two REVOKED periods with the same termination_date
            e.external_id,
        ),
    )
Пример #8
0
    def test_get_commitment_from_supervision_details_us_pa_pvc(self):
        state_code = "US_PA"

        supervision_period = StateSupervisionPeriod.new_with_defaults(
            supervision_period_id=_DEFAULT_SUPERVISION_PERIOD_ID,
            external_id="sp1",
            status=StateSupervisionPeriodStatus.TERMINATED,
            case_type_entries=[
                StateSupervisionCaseTypeEntry.new_with_defaults(
                    state_code=state_code,
                    case_type=StateSupervisionCaseType.GENERAL)
            ],
            state_code=state_code,
            supervision_site="DISTRICT_1|OFFICE_2|ORG_CODE",
            start_date=date(2017, 12, 5),
            termination_date=date(2018, 5, 19),
            termination_reason=StateSupervisionPeriodTerminationReason.
            DISCHARGE,
            supervision_period_supervision_type=
            StateSupervisionPeriodSupervisionType.PAROLE,
            supervision_level=StateSupervisionLevel.MINIMUM,
            supervision_level_raw_text="LOW",
        )

        incarceration_period = StateIncarcerationPeriod.new_with_defaults(
            incarceration_period_id=222,
            external_id="ip2",
            state_code=state_code,
            incarceration_type=StateIncarcerationType.COUNTY_JAIL,
            status=StateIncarcerationPeriodStatus.NOT_IN_CUSTODY,
            admission_date=date(2018, 3, 11),
            admission_reason=StateIncarcerationPeriodAdmissionReason.
            PAROLE_REVOCATION,
            specialized_purpose_for_incarceration=
            StateSpecializedPurposeForIncarceration.SHOCK_INCARCERATION,
            # Program 26 indicates a revocation to a PVC
            specialized_purpose_for_incarceration_raw_text=
            PURPOSE_FOR_INCARCERATION_PVC,
            release_date=date(2019, 5, 3),
            release_reason=ReleaseReason.SENTENCE_SERVED,
            custodial_authority=StateCustodialAuthority.SUPERVISION_AUTHORITY,
        )

        ip_index = PreProcessedIncarcerationPeriodIndex(
            incarceration_periods=[incarceration_period],
            ip_id_to_pfi_subtype={
                incarceration_period.incarceration_period_id:
                SHOCK_INCARCERATION_PVC
            },
        )

        commitment_details = self._test_get_commitment_from_supervision_details(
            incarceration_period,
            supervision_periods=[supervision_period],
            incarceration_period_index=ip_index,
        )

        self.assertEqual(
            commitment_details,
            CommitmentDetails(
                purpose_for_incarceration=
                StateSpecializedPurposeForIncarceration.SHOCK_INCARCERATION,
                purpose_for_incarceration_subtype="PVC",
                level_1_supervision_location_external_id="OFFICE_2",
                level_2_supervision_location_external_id="DISTRICT_1",
                supervising_officer_external_id=
                DEFAULT_SUPERVISION_PERIOD_AGENT_ASSOCIATIONS.get(
                    supervision_period.supervision_period_id).get(
                        "agent_external_id"),
                case_type=StateSupervisionCaseType.GENERAL,
                supervision_level=supervision_period.supervision_level,
                supervision_level_raw_text=supervision_period.
                supervision_level_raw_text,
                supervision_type=StateSupervisionPeriodSupervisionType.PAROLE,
            ),
        )