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
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
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)
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, )