def supervision_period_counts_towards_supervision_population_in_date_range_state_specific(
    date_range: DateRange,
    supervision_sentences: List[StateSupervisionSentence],
    incarceration_sentences: List[StateIncarcerationSentence],
    supervision_period: StateSupervisionPeriod,
) -> bool:
    """Returns False if there is state-specific information to indicate that the supervision period should not count
    towards any supervision metrics in the date range. Returns True if either there is a state-specific check that
    indicates that the supervision period should count or if there is no state-specific check to perform.
    """
    if supervision_period.state_code == "US_MO":
        overlapping_range = DateRangeDiff(
            range_1=date_range, range_2=supervision_period.duration
        ).overlapping_range

        if not overlapping_range:
            return False

        return (
            us_mo_get_most_recent_supervision_period_supervision_type_before_upper_bound_day(
                upper_bound_exclusive_date=overlapping_range.upper_bound_exclusive_date,
                lower_bound_inclusive_date=overlapping_range.lower_bound_inclusive_date,
                incarceration_sentences=incarceration_sentences,
                supervision_sentences=supervision_sentences,
            )
            is not None
        )

    return True
Exemple #2
0
def terminating_supervision_period_supervision_type(
    supervision_period: StateSupervisionPeriod,
    supervision_sentences: List[StateSupervisionSentence],
    incarceration_sentences: List[StateIncarcerationSentence],
) -> StateSupervisionPeriodSupervisionType:
    """Calculates the supervision type that should be associated with a terminated supervision period. In some cases,
    the supervision period will be terminated long after the person has been incarcerated (e.g. in the case of a board
    hold, someone might remain assigned to a PO until their parole is revoked), so we do a lookback to see the most
    recent supervision period supervision type we can associate with this termination.
    """

    if not supervision_period.termination_date:
        raise ValueError(
            f'Expected a terminated supervision period for period '
            f'[{supervision_period.supervision_period_id}]')

    if supervision_period.state_code == 'US_MO':
        supervision_type = us_mo_get_most_recent_supervision_period_supervision_type_before_upper_bound_day(
            upper_bound_exclusive_date=supervision_period.termination_date,
            lower_bound_inclusive_date=supervision_period.start_date,
            incarceration_sentences=incarceration_sentences,
            supervision_sentences=supervision_sentences)

        return supervision_type if supervision_type else StateSupervisionPeriodSupervisionType.INTERNAL_UNKNOWN

    if supervision_period.state_code == 'US_ID':
        return (supervision_period.supervision_period_supervision_type
                if supervision_period.supervision_period_supervision_type else
                StateSupervisionPeriodSupervisionType.INTERNAL_UNKNOWN)

    return get_month_supervision_type_default(
        supervision_period.termination_date, supervision_sentences,
        incarceration_sentences, supervision_period)
def should_produce_supervision_time_bucket_for_period(
        supervision_period: StateSupervisionPeriod,
        incarceration_sentences: List[StateIncarcerationSentence],
        supervision_sentences: List[StateSupervisionSentence]):
    """Whether or not any SupervisionTimeBuckets should be created using the supervision_period. In some cases,
    supervision period pre-processing will not drop periods entirely because we need them for context in some of the
    calculations, but we do not want to create metrics using the periods.

    If this returns True, it does not necessarily mean they should be counted towards the supervision population for
    any part of this period. It just means that a person was actively assigned to supervision at this time and various
    characteristics of this period may be relevant for generating metrics (such as the termination reason / date) even
    if we may not count this person towards the supervision population during the period time span (e.g. if they are
    incarcerated the whole time).
    """
    if supervision_period.state_code == 'US_MO':
        # If no days of this supervision_period should count towards any metrics, we can drop this period entirely
        sp_range = supervision_period.duration

        return us_mo_get_most_recent_supervision_period_supervision_type_before_upper_bound_day(
            upper_bound_exclusive_date=sp_range.upper_bound_exclusive_date,
            lower_bound_inclusive_date=sp_range.lower_bound_inclusive_date,
            incarceration_sentences=incarceration_sentences,
            supervision_sentences=supervision_sentences) is not None

    if ((
            supervision_period.supervision_period_supervision_type
            == StateSupervisionPeriodSupervisionType.INVESTIGATION
            # TODO(#2891): Remove this check when we remove supervision_type from StateSupervisionPeriods
            or supervision_period.supervision_type
            == StateSupervisionType.PRE_CONFINEMENT)
            and not investigation_periods_in_supervision_population(
                supervision_period.state_code)):
        return False
    return True
Exemple #4
0
    def test_most_recent_supervision_type_no_sentences_same_day_bound(self):
        # Act
        supervision_period_supervision_type = us_mo_get_most_recent_supervision_period_supervision_type_before_upper_bound_day(
            upper_bound_exclusive_date=self.upper_bound_date,
            lower_bound_inclusive_date=self.upper_bound_date,
            supervision_sentences=[],
            incarceration_sentences=[],
        )

        # Assert
        self.assertEqual(supervision_period_supervision_type, None)
Exemple #5
0
    def test_most_recent_supervision_type_two_sentences_same_transition_day_one_different(
        self, ):
        # Arrange

        start_date = self.upper_bound_date - datetime.timedelta(days=5)
        transition_date_1 = self.upper_bound_date - datetime.timedelta(days=3)
        transition_date_2 = self.upper_bound_date - datetime.timedelta(days=1)

        incarceration_sentence = (
            FakeUsMoIncarcerationSentence.fake_sentence_from_sentence(
                StateIncarcerationSentence.new_with_defaults(
                    external_id="ss1",
                    state_code="US_MO",
                    start_date=start_date,
                    status=StateSentenceStatus.PRESENT_WITHOUT_INFO,
                ),
                supervision_type_spans=[
                    SupervisionTypeSpan(
                        start_date=start_date,
                        end_date=transition_date_2,
                        supervision_type=StateSupervisionType.PAROLE,
                    ),
                    SupervisionTypeSpan(
                        start_date=transition_date_2,
                        end_date=None,
                        supervision_type=None,
                    ),
                ],
            ))

        supervision_sentence_1 = (
            FakeUsMoSupervisionSentence.fake_sentence_from_sentence(
                StateSupervisionSentence.new_with_defaults(
                    external_id="ss1",
                    state_code="US_MO",
                    start_date=start_date,
                    status=StateSentenceStatus.PRESENT_WITHOUT_INFO,
                ),
                supervision_type_spans=[
                    SupervisionTypeSpan(
                        start_date=start_date,
                        end_date=transition_date_1,
                        supervision_type=StateSupervisionType.PROBATION,
                    ),
                    SupervisionTypeSpan(
                        start_date=transition_date_1,
                        end_date=None,
                        supervision_type=None,
                    ),
                ],
            ))

        supervision_sentence_2 = (
            FakeUsMoSupervisionSentence.fake_sentence_from_sentence(
                StateSupervisionSentence.new_with_defaults(
                    external_id="ss1",
                    state_code="US_MO",
                    start_date=start_date,
                    status=StateSentenceStatus.PRESENT_WITHOUT_INFO,
                ),
                supervision_type_spans=[
                    SupervisionTypeSpan(
                        start_date=start_date,
                        end_date=transition_date_2,
                        supervision_type=StateSupervisionType.PROBATION,
                    ),
                    SupervisionTypeSpan(
                        start_date=transition_date_2,
                        end_date=None,
                        supervision_type=StateSupervisionType.PAROLE,
                    ),
                ],
            ))

        # Act

        supervision_period_supervision_type = us_mo_get_most_recent_supervision_period_supervision_type_before_upper_bound_day(
            upper_bound_exclusive_date=self.upper_bound_date,
            lower_bound_inclusive_date=None,
            supervision_sentences=[
                supervision_sentence_1, supervision_sentence_2
            ],
            incarceration_sentences=[incarceration_sentence],
        )

        # Assert

        # Since the probation sentence ends before the parole sentence, the last valid supervision type is PAROLE
        self.assertEqual(
            supervision_period_supervision_type,
            StateSupervisionPeriodSupervisionType.PAROLE,
        )