示例#1
0
def read_db_entity_trees_of_cls_to_merge(
        session: Session, state_code: str,
        schema_cls: Type[StateBase]) -> List[List[EntityTree]]:
    """
    Returns a list of lists of EntityTree where each inner list is a group
    of EntityTrees with entities of class |schema_cls| that need to be merged
    because their entities have the same external_id.

    Will assert if schema_cls does not have a person_id or external_id field.
    """
    if not StateCode.is_valid(state_code):
        raise ValueError(f"Invalid state code: [{state_code}]")

    external_ids = dao.read_external_ids_of_cls_with_external_id_match(
        session, state_code, schema_cls)
    people = dao.read_people_by_cls_external_ids(session, state_code,
                                                 schema_cls, external_ids)
    all_cls_trees = get_all_entity_trees_of_cls(people, schema_cls)

    external_ids_map: Dict[str, List[EntityTree]] = defaultdict(list)
    for tree in all_cls_trees:
        if not isinstance(tree.entity, schema_cls):
            raise ValueError(f"Unexpected entity type [{type(tree.entity)}]")

        if tree.entity.external_id in external_ids:
            external_ids_map[tree.entity.external_id].append(tree)

    return [tree_list for _, tree_list in external_ids_map.items()]
def _move_events_onto_supervision_periods_for_person(
    matched_persons: List[schema.StatePerson],
    event_cls: Type[DatabaseEntity],
    event_field_name: str,
    state_code: str,
) -> None:
    """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.
    """
    if not StateCode.is_valid(state_code):
        raise ValueError(f"Invalid state code: [{state_code}]")

    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)