Esempio n. 1
0
def _move_events_onto_supervision_periods_for_person(
        matched_persons: List[schema.StatePerson],
        event_cls: Type[DatabaseEntity],
        event_field_name: str,
        state_code: str):
    """For each person in |matched_persons|, moves all events of type |event_cls| onto the |event_field_name| field of
    a matching supervision period, based on date. If there is no matching supervision period, ensures that the events
    hang off of a placeholder chain.
    """
    for person in matched_persons:
        unmatched_events = _move_events_onto_supervision_periods(person, event_cls, event_field_name)
        if not unmatched_events:
            continue

        # We may hit this case if an entity that has already been committed to the DB has a date updated in a
        # later run such that the dates of the existing supervision periods no longer line up with one of the
        # existing events. In this case, we want to store the event on a placeholder chain starting at sentence_group.
        # We do this to show that the supervision violation isn't associated with anything other than the person.
        placeholder_sg = get_or_create_placeholder_child(
            person, 'sentence_groups', schema.StateSentenceGroup,
            state_code=state_code, status=StateSentenceStatus.PRESENT_WITHOUT_INFO.value)
        placeholder_s = get_or_create_placeholder_child(
            placeholder_sg, 'supervision_sentences', schema.StateSupervisionSentence,
            person=person, state_code=state_code, status=StateSentenceStatus.PRESENT_WITHOUT_INFO.value)
        placeholder_sp = get_or_create_placeholder_child(
            placeholder_s, 'supervision_periods', schema.StateSupervisionPeriod,
            person=person, state_code=state_code, status=StateSupervisionPeriodStatus.PRESENT_WITHOUT_INFO.value)
        placeholder_sp.set_field_from_list(event_field_name, unmatched_events)
def move_violations_onto_supervision_periods_for_sentence(
    matched_persons: List[schema.StatePerson],
) -> None:
    """Given a list of |matched_persons|, for each sentence (either Incarceration or Supervision) associates all
    violations in that sentence with the corresponding SupervisionPeriod(s) based on date.
    """
    for person in matched_persons:
        for sentence_group in person.sentence_groups:
            for sentence in (
                sentence_group.supervision_sentences
                + sentence_group.incarceration_sentences
            ):
                unmatched_svs = _move_events_onto_supervision_periods(
                    sentence,
                    schema.StateSupervisionViolation,
                    "supervision_violation_entries",
                )
                if not unmatched_svs:
                    continue
                placeholder_sp = get_or_create_placeholder_child(
                    sentence,
                    "supervision_periods",
                    schema.StateSupervisionPeriod,
                    person=person,
                    state_code=sentence.state_code,
                    status=StateSupervisionPeriodStatus.PRESENT_WITHOUT_INFO.value,
                )
                placeholder_sp.supervision_violation_entries = unmatched_svs
Esempio n. 3
0
def _move_periods_onto_sentences_for_sentence_group(
        sentence_group: schema.StateSentenceGroup,
        period_type: Type[schema.SchemaPeriodType]):
    """Looks at all SupervisionPeriods in the provided |sentence_group|, and attempts to match them to any
    corresponding sentences, based on date.
    """
    sentences = sentence_group.supervision_sentences + sentence_group.incarceration_sentences

    # Get all periods from sentence group
    periods = get_all_entities_of_cls([sentence_group], period_type)

    # Clear non-placeholder links from sentence to period. We will re-add/update these relationships below.
    for sentence in sentences:
        _only_keep_placeholder_periods_on_sentence(sentence, period_type)

    unmatched_periods = []
    matchable_sentences = _get_date_matchable_sentences(sentences)

    non_placeholder_periods = [p for p in periods if not is_placeholder(p)]

    # Match periods to non_placeholder_sentences by date.
    for p in non_placeholder_periods:
        matched = False
        p_start_date = _get_period_start_date(p)
        p_end_date = _get_period_end_date(p)

        for s in matchable_sentences:
            s_start_date = s.start_date
            if not s_start_date:
                continue

            s_completion_date = s.completion_date if s.completion_date else datetime.date.max

            if date_spans_overlap_exclusive(start_1=p_start_date,
                                            end_1=p_end_date,
                                            start_2=s_start_date,
                                            end_2=s_completion_date):
                matched = True
                _add_period_to_sentence(p, s)

        # Unmatched periods will be re-added to a placeholder sentence at the end.
        if not matched:
            unmatched_periods.append(p)

    # Add unmatched periods to a placeholder sentence
    if unmatched_periods:
        placeholder_sentences = [s for s in sentences if is_placeholder(s)]
        if not placeholder_sentences:
            placeholder_sentence = get_or_create_placeholder_child(
                sentence_group,
                'supervision_sentences',
                schema.StateSupervisionSentence,
                state_code=sentence_group.state_code,
                status=StateSentenceStatus.PRESENT_WITHOUT_INFO.value,
                person=sentence_group.person)
        else:
            placeholder_sentence = placeholder_sentences[0]
        for unmatched_period in unmatched_periods:
            _add_period_to_sentence(unmatched_period, placeholder_sentence)