def test_associatePeriodsWithSentence_doNotMovePlaceholderPeriods(self):
        # Arrange
        placeholder_sp = StateSupervisionPeriod.new_with_defaults()
        placeholder_ip = StateIncarcerationPeriod.new_with_defaults()

        inc_s_2 = StateIncarcerationSentence.new_with_defaults(
            external_id=_EXTERNAL_ID,
            start_date=_DATE_1,
            completion_date=_DATE_8)

        inc_s = StateIncarcerationSentence.new_with_defaults(
            external_id=_EXTERNAL_ID_2,
            start_date=_DATE_1,
            completion_date=_DATE_8,
            incarceration_periods=[placeholder_ip],
            supervision_periods=[placeholder_sp])

        sg = StateSentenceGroup.new_with_defaults(
            incarceration_sentences=[inc_s, inc_s_2])

        state_person = StatePerson.new_with_defaults(sentence_groups=[sg])

        # Should remain unchanged - placeholder period should not get attached to any other sentences
        expected_person = attr.evolve(state_person)

        # Act
        input_people = converter.convert_entity_people_to_schema_people(
            [state_person])
        move_periods_onto_sentences_by_date(input_people)

        # Assert
        self.assert_people_match([expected_person], input_people)
    def test_associateSvrsWithIps_dontAssociateTheSameSvr(self):
        # Arrange
        svr_1 = StateSupervisionViolationResponse.new_with_defaults(
            response_date=_DATE_1,
            revocation_type=StateSupervisionViolationResponseRevocationType.
            REINCARCERATION)
        placeholder_sv = StateSupervisionViolation.new_with_defaults(
            supervision_violation_responses=[svr_1])
        placeholder_sp = StateSupervisionPeriod.new_with_defaults(
            supervision_violation_entries=[placeholder_sv])
        placeholder_ss = StateSupervisionSentence.new_with_defaults(
            supervision_periods=[placeholder_sp])

        ip_1 = StateIncarcerationPeriod.new_with_defaults(
            admission_date=_DATE_2,
            admission_reason=StateIncarcerationPeriodAdmissionReason.
            PROBATION_REVOCATION)
        ip_2 = StateIncarcerationPeriod.new_with_defaults(
            admission_date=_DATE_4,
            admission_reason=StateIncarcerationPeriodAdmissionReason.
            PROBATION_REVOCATION)
        placeholder_is = StateIncarcerationSentence.new_with_defaults(
            incarceration_periods=[ip_1, ip_2])
        placeholder_sg = StateSentenceGroup.new_with_defaults(
            incarceration_sentences=[placeholder_is],
            supervision_sentences=[placeholder_ss])
        placeholder_person = StatePerson.new_with_defaults(
            sentence_groups=[placeholder_sg])

        expected_svr_1 = attr.evolve(svr_1)
        expected_placeholder_sv = attr.evolve(
            placeholder_sv, supervision_violation_responses=[expected_svr_1])
        expected_placeholder_sp = attr.evolve(
            placeholder_sp,
            supervision_violation_entries=[expected_placeholder_sv])
        expected_placeholder_ss = attr.evolve(
            placeholder_ss, supervision_periods=[expected_placeholder_sp])

        expected_ip_1 = attr.evolve(
            ip_1, source_supervision_violation_response=expected_svr_1)
        expected_ip_2 = attr.evolve(ip_2)

        expected_placeholder_is = attr.evolve(
            placeholder_is,
            incarceration_periods=[expected_ip_1, expected_ip_2])
        expected_placeholder_sg = attr.evolve(
            placeholder_sg,
            supervision_sentences=[expected_placeholder_ss],
            incarceration_sentences=[expected_placeholder_is])
        expected_placeholder_person = attr.evolve(
            placeholder_person, sentence_groups=[expected_placeholder_sg])

        # Act
        input_people = \
            converter.convert_entity_people_to_schema_people(
                [placeholder_person])
        associate_revocation_svrs_with_ips(input_people)

        # Assert
        self.assert_people_match([expected_placeholder_person], input_people)
    def test_associatePeriodsWithSentence_doNotMatchSentenceWithNoStart(self):
        # Arrange
        placeholder_sp = StateSupervisionPeriod.new_with_defaults()

        sp = StateSupervisionPeriod.new_with_defaults(
            external_id=_EXTERNAL_ID_3,
            start_date=_DATE_2,
            termination_date=_DATE_3)
        ip = StateIncarcerationPeriod.new_with_defaults(
            external_id=_EXTERNAL_ID_3,
            admission_date=_DATE_2,
            release_date=_DATE_3)

        inc_s_no_dates = StateIncarcerationSentence.new_with_defaults(
            external_id=_EXTERNAL_ID, supervision_periods=[placeholder_sp])

        placeholder_inc_s = StateIncarcerationSentence.new_with_defaults(
            incarceration_periods=[ip], supervision_periods=[sp])

        sg = StateSentenceGroup.new_with_defaults(
            incarceration_sentences=[inc_s_no_dates, placeholder_inc_s])

        state_person = StatePerson.new_with_defaults(sentence_groups=[sg])

        # Should remain unchanged - the non-placeholder period should not get moved onto sentence with an id
        # but no start date
        expected_person = attr.evolve(state_person)

        # Act
        input_people = converter.convert_entity_people_to_schema_people(
            [state_person])
        move_periods_onto_sentences_by_date(input_people)

        # Assert
        self.assert_people_match([expected_person], input_people)
    def test_associatePeriodsWithSentence_periodNoLongerMatches(self):
        # Arrange
        sp_which_no_longer_overlaps = StateSupervisionPeriod.new_with_defaults(
            supervision_period_id=_ID,
            external_id=_EXTERNAL_ID,
            state_code=_STATE_CODE,
            start_date=_DATE_6)
        ip_which_no_longer_overlaps = StateIncarcerationPeriod.new_with_defaults(
            incarceration_period_id=_ID,
            external_id=_EXTERNAL_ID,
            state_code=_STATE_CODE,
            admission_date=_DATE_6)

        # This sentence, which has already been written to the DB, has presumably been updated so that the date range no
        # longer overlaps with the attached periods.
        inc_s_updated_dates = StateIncarcerationSentence.new_with_defaults(
            incarceration_sentence_id=_ID_2,
            external_id=_EXTERNAL_ID,
            state_code=_STATE_CODE,
            start_date=_DATE_3,
            completion_date=_DATE_5,
            incarceration_periods=[ip_which_no_longer_overlaps],
            supervision_periods=[sp_which_no_longer_overlaps])

        sg = StateSentenceGroup.new_with_defaults(
            sentence_group_id=_ID_3,
            state_code=_STATE_CODE,
            incarceration_sentences=[inc_s_updated_dates])

        state_person = StatePerson.new_with_defaults(person_id=_ID,
                                                     sentence_groups=[sg])

        expected_sp = attr.evolve(sp_which_no_longer_overlaps)
        expected_ip = attr.evolve(ip_which_no_longer_overlaps)
        expected_is = attr.evolve(inc_s_updated_dates,
                                  incarceration_periods=[],
                                  supervision_periods=[])

        # We expect that a new placeholder supervision sentence has been created to hold on to the orphaned periods
        expected_placeholder_ss = StateSupervisionSentence.new_with_defaults(
            state_code=_STATE_CODE,
            status=StateSentenceStatus.PRESENT_WITHOUT_INFO,
            incarceration_periods=[expected_ip],
            supervision_periods=[expected_sp])
        expected_sg = attr.evolve(
            sg,
            incarceration_sentences=[expected_is],
            supervision_sentences=[expected_placeholder_ss])
        expected_person = attr.evolve(state_person,
                                      sentence_groups=[expected_sg])

        # Act
        input_people = converter.convert_entity_people_to_schema_people(
            [state_person])
        move_periods_onto_sentences_by_date(input_people)

        # Assert
        self.assert_people_match([expected_person], input_people)
Example #5
0
    def test_associatedSupervisionPeriodsWithSentences(self):
        # Arrange
        sp_no_match = StateSupervisionPeriod.new_with_defaults(
            external_id=_EXTERNAL_ID,
            start_date=_DATE,
            termination_date=_DATE_2)

        sp_1 = StateSupervisionPeriod.new_with_defaults(
            external_id=_EXTERNAL_ID,
            start_date=_DATE_4,
            termination_date=_DATE_6)

        sp_2 = StateSupervisionPeriod.new_with_defaults(
            external_id=_EXTERNAL_ID_2,
            start_date=_DATE_6,
            termination_date=None)

        placeholder_ss = StateSupervisionSentence.new_with_defaults(
            supervision_periods=[sp_no_match, sp_1, sp_2])

        ss = StateSupervisionSentence.new_with_defaults(
            external_id=_EXTERNAL_ID, start_date=_DATE_4, completion_date=None)
        inc_s = StateIncarcerationSentence.new_with_defaults(
            external_id=_EXTERNAL_ID,
            start_date=_DATE_3,
            completion_date=_DATE_5)

        sg = StateSentenceGroup.new_with_defaults(
            incarceration_sentences=[inc_s],
            supervision_sentences=[ss, placeholder_ss])

        state_person = StatePerson.new_with_defaults(sentence_groups=[sg])

        expected_sp_1 = attr.evolve(sp_1)
        expected_sp_2 = attr.evolve(sp_2)

        expected_placeholder_ss = attr.evolve(
            placeholder_ss, supervision_periods=[sp_no_match])
        expected_inc_s = attr.evolve(inc_s,
                                     supervision_periods=[expected_sp_1])
        expected_ss = attr.evolve(
            ss, supervision_periods=[expected_sp_1, expected_sp_2])

        expected_sg = attr.evolve(
            sg,
            supervision_sentences=[expected_ss, expected_placeholder_ss],
            incarceration_sentences=[expected_inc_s])
        expected_person = attr.evolve(state_person,
                                      sentence_groups=[expected_sg])

        # Act
        input_people = \
            converter.convert_entity_people_to_schema_people(
                [state_person])
        move_supervision_periods_onto_sentences_by_date(input_people)

        # Assert
        self.assert_people_match([expected_person], input_people)
 def assert_people_match(self, expected_people: List[StatePerson],
                         matched_people: List[schema.StatePerson]):
     converted_matched = \
         converter.convert_schema_objects_to_entity(matched_people)
     db_expected_with_backedges = \
         converter.convert_entity_people_to_schema_people(expected_people)
     expected_with_backedges = \
         converter.convert_schema_objects_to_entity(
             db_expected_with_backedges)
     self.assertEqual(expected_with_backedges, converted_matched)
    def test_associatedPeriodsWithSentences_doNotAssociateToClosedButUnterminatedSentences(
            self):
        # Arrange
        sp_1 = StateSupervisionPeriod.new_with_defaults(
            external_id=_EXTERNAL_ID,
            start_date=_DATE_6,
            termination_date=None)

        ip_1 = StateIncarcerationPeriod.new_with_defaults(
            external_id=_EXTERNAL_ID,
            admission_date=_DATE_6,
            release_date=None)

        placeholder_ss = StateSupervisionSentence.new_with_defaults(
            supervision_periods=[sp_1], incarceration_periods=[ip_1])
        ss = StateSupervisionSentence.new_with_defaults(
            external_id=_EXTERNAL_ID,
            status=StateSentenceStatus.COMPLETED,
            start_date=_DATE_4,
            completion_date=None)
        inc_s = StateIncarcerationSentence.new_with_defaults(
            external_id=_EXTERNAL_ID,
            status=StateSentenceStatus.COMPLETED,
            start_date=_DATE_4,
            completion_date=None)

        sg = StateSentenceGroup.new_with_defaults(
            incarceration_sentences=[inc_s],
            supervision_sentences=[ss, placeholder_ss])

        state_person = StatePerson.new_with_defaults(sentence_groups=[sg])

        expected_sp_1 = attr.evolve(sp_1)
        expected_ip_1 = attr.evolve(ip_1)

        expected_placeholder_ss = attr.evolve(
            placeholder_ss,
            supervision_periods=[expected_sp_1],
            incarceration_periods=[expected_ip_1])
        expected_inc_s = attr.evolve(inc_s)
        expected_ss = attr.evolve(ss)
        expected_sg = attr.evolve(
            sg,
            supervision_sentences=[expected_ss, expected_placeholder_ss],
            incarceration_sentences=[expected_inc_s])
        expected_person = attr.evolve(state_person,
                                      sentence_groups=[expected_sg])

        # Act
        input_people = converter.convert_entity_people_to_schema_people(
            [state_person])
        move_periods_onto_sentences_by_date(input_people)

        # Assert
        self.assert_people_match([expected_person], input_people)
Example #8
0
    def test_associateViolationsWithSupervisionPeriodsWhereViolationNoLongerOverlaps(
            self):
        # Act
        sv_ss = StateSupervisionViolation.new_with_defaults(
            supervision_violation_id=_ID,
            state_code=_STATE_CODE,
            violation_date=_DATE_4)

        # This supervision period, which has already been written to the DB, has presumably been updated so that the
        # date range no longer overlaps with the attached violation (or the violation has been updated).
        sp_ss = StateSupervisionPeriod.new_with_defaults(
            supervision_period_id=_ID,
            external_id=_EXTERNAL_ID,
            state_code=_STATE_CODE,
            start_date=_DATE,
            termination_date=_DATE_3,
            supervision_violation_entries=[sv_ss])
        ss = StateSupervisionSentence.new_with_defaults(
            supervision_sentence_id=_ID,
            external_id=_EXTERNAL_ID,
            state_code=_STATE_CODE,
            supervision_periods=[sp_ss])

        sg = StateSentenceGroup.new_with_defaults(sentence_group_id=_ID,
                                                  state_code=_STATE_CODE,
                                                  supervision_sentences=[ss])

        state_person = StatePerson.new_with_defaults(person_id=_ID,
                                                     sentence_groups=[sg])

        expected_sv_ss = attr.evolve(sv_ss)
        expected_sp_ss = attr.evolve(sp_ss, supervision_violation_entries=[])
        expected_placeholder_sp_ss = StateSupervisionPeriod.new_with_defaults(
            state_code=_STATE_CODE,
            status=StateSupervisionPeriodStatus.PRESENT_WITHOUT_INFO,
            supervision_violation_entries=[expected_sv_ss])
        expected_ss = attr.evolve(
            ss,
            supervision_periods=[expected_placeholder_sp_ss, expected_sp_ss])
        expected_sg = attr.evolve(sg, supervision_sentences=[expected_ss])
        expected_person = attr.evolve(state_person,
                                      sentence_groups=[expected_sg])

        # Act
        input_people = \
            converter.convert_entity_people_to_schema_people(
                [state_person])
        move_violations_onto_supervision_periods_by_date(input_people)

        # Assert
        self.assert_people_match([expected_person], input_people)
 def assert_people_match(self,
                         expected_people: List[StatePerson],
                         matched_people: List[schema.StatePerson],
                         debug: bool = False):
     converted_matched = converter.convert_schema_objects_to_entity(
         matched_people)
     db_expected_with_backedges = converter.convert_entity_people_to_schema_people(
         expected_people)
     expected_with_backedges = converter.convert_schema_objects_to_entity(
         db_expected_with_backedges)
     if debug:
         print_visible_header_label('EXPECTED')
         print_entity_trees(expected_with_backedges)
         print_visible_header_label('FINAL')
         print_entity_trees(converted_matched)
     self.assertEqual(expected_with_backedges, converted_matched)
Example #10
0
def infer_release_on_open_bookings(region_code: str,
                                   last_ingest_time: datetime.datetime,
                                   custody_status: CustodyStatus) -> None:
    """
    Look up all open bookings whose last_seen_time is earlier than the
    provided last_ingest_time in the provided region, update those
    bookings to have an inferred release date equal to the provided
    last_ingest_time.

    Args:
        region_code: the region_code
        last_ingest_time: The last time complete data was ingested for this
            region. In the normal ingest pipeline, this is the last start time
            of a background scrape for the region.
        custody_status: The custody status to be marked on the found open
            bookings. Defaults to INFERRED_RELEASE
    """

    session = SessionFactory.for_schema_base(JailsBase)
    try:
        logging.info("Reading all bookings that happened before [%s]",
                     last_ingest_time)
        people = county_dao.read_people_with_open_bookings_scraped_before_time(
            session, region_code, last_ingest_time)

        logging.info(
            "Found [%s] people with bookings that will be inferred released",
            len(people),
        )
        for person in people:
            persistence_utils.remove_pii_for_person(person)
            _infer_release_date_for_bookings(person.bookings, last_ingest_time,
                                             custody_status)
        db_people = converter.convert_entity_people_to_schema_people(people)
        database.write_people(
            session,
            db_people,
            IngestMetadata(region=region_code,
                           jurisdiction_id="",
                           ingest_time=last_ingest_time),
        )
        session.commit()
    except Exception:
        session.rollback()
        raise
    finally:
        session.close()
    def _assert_people_match(
            self, expected_people, matched_people, debug=False):
        converted_matched = \
            converter.convert_schema_objects_to_entity(matched_people)
        db_expected_with_backedges = \
            converter.convert_entity_people_to_schema_people(expected_people)
        expected_with_backedges = \
            converter.convert_schema_objects_to_entity(
                db_expected_with_backedges)

        clear_db_ids(converted_matched)
        clear_db_ids(expected_with_backedges)

        if debug:
            print('============== EXPECTED WITH BACKEDGES ==============')
            print_entity_trees(expected_with_backedges)
            print('============== CONVERTED MATCHED ==============')
            print_entity_trees(converted_matched)
        self.assertCountEqual(expected_with_backedges, converted_matched)
Example #12
0
    def assert_people_match(self,
                            expected_people: List[StatePerson],
                            matched_people: List[schema.StatePerson],
                            debug: bool = True):
        converted_matched = \
            converter.convert_schema_objects_to_entity(matched_people)
        db_expected_with_backedges = \
            converter.convert_entity_people_to_schema_people(expected_people)
        expected_with_backedges = \
            converter.convert_schema_objects_to_entity(
                db_expected_with_backedges)

        if debug:
            print('============== EXPECTED WITH BACKEDGES ==============')
            print_entity_trees(expected_with_backedges)
            print('============== CONVERTED MATCHED ==============')
            print_entity_trees(converted_matched)

        self.assertCountEqual(expected_with_backedges, converted_matched)
Example #13
0
def match_people_and_return_error_count(
        *, db_people: List[entities.Person],
        ingested_people: List[entities.Person]) -> MatchedEntities:
    """
    Attempts to match all people from |ingested_people| with people from the
    |db_people|. Returns an MatchedEntities object that contains the results
    of matching.
    """
    people = []
    orphaned_entities = []
    error_count = 0
    matched_people_by_db_id: Dict[int, entities.Person] = {}

    for ingested_person in ingested_people:
        try:
            ingested_person_orphans: List[Entity] = []
            match_person(
                ingested_person=ingested_person,
                db_people=db_people,
                orphaned_entities=ingested_person_orphans,
                matched_people_by_db_id=matched_people_by_db_id,
            )

            people.append(ingested_person)
            orphaned_entities.extend(ingested_person_orphans)
        except EntityMatchingError as e:
            logging.exception(
                "Found %s while matching ingested person. \nPerson: %s",
                e.__class__.__name__,
                ingested_person,
            )
            increment_error(e.entity_name)
            error_count += 1

    schema_people = converter.convert_entity_people_to_schema_people(people)
    schema_orphaned_entities = converter.convert_entities_to_schema(
        orphaned_entities)
    return MatchedEntities(
        people=schema_people,
        orphaned_entities=schema_orphaned_entities,
        error_count=error_count,
    )
    def test_associatedPeriodsWithSentences_oneDayPeriodOverlapsWithStartOfSentence(
            self):
        sp = StateSupervisionPeriod.new_with_defaults(external_id=_EXTERNAL_ID,
                                                      start_date=_DATE_2,
                                                      termination_date=_DATE_2)
        placeholder_ss = StateSupervisionSentence.new_with_defaults(
            supervision_periods=[sp])

        ss = StateSupervisionSentence.new_with_defaults(
            external_id=_EXTERNAL_ID,
            start_date=_DATE_2,
            completion_date=_DATE_3,
            status=StateSentenceStatus.SERVING)

        sg = StateSentenceGroup.new_with_defaults(
            supervision_sentences=[ss, placeholder_ss])

        state_person = StatePerson.new_with_defaults(sentence_groups=[sg])

        expected_sp = attr.evolve(sp)

        expected_placeholder_ss = attr.evolve(placeholder_ss,
                                              supervision_periods=[],
                                              incarceration_periods=[])
        expected_ss = attr.evolve(ss, supervision_periods=[expected_sp])
        expected_sg = attr.evolve(
            sg, supervision_sentences=[expected_ss, expected_placeholder_ss])
        expected_person = attr.evolve(state_person,
                                      sentence_groups=[expected_sg])

        # Act
        input_people = converter.convert_entity_people_to_schema_people(
            [state_person])
        move_periods_onto_sentences_by_date(input_people)

        # Assert
        self.assert_people_match([expected_person], input_people)
Example #15
0
    def test_associateSvrsWithIps(self):
        # Arrange
        ip_1 = StateIncarcerationPeriod.new_with_defaults(
            admission_date=_DATE_1,
            admission_reason=
            StateIncarcerationPeriodAdmissionReason.PROBATION_REVOCATION)
        ip_2 = StateIncarcerationPeriod.new_with_defaults(
            admission_date=_DATE_2,
            admission_reason=
            StateIncarcerationPeriodAdmissionReason.PROBATION_REVOCATION)
        placeholder_is = StateIncarcerationSentence.new_with_defaults(
            incarceration_periods=[ip_1, ip_2])

        svr_1 = StateSupervisionViolationResponse.new_with_defaults(
            response_date=_DATE_1 - datetime.timedelta(days=1),
            revocation_type=StateSupervisionViolationResponseRevocationType.
            REINCARCERATION)
        svr_2 = StateSupervisionViolationResponse.new_with_defaults(
            response_date=_DATE_2 + datetime.timedelta(days=1),
            revocation_type=StateSupervisionViolationResponseRevocationType.
            REINCARCERATION)
        svr_3 = StateSupervisionViolationResponse.new_with_defaults(
            response_date=_DATE_2 + datetime.timedelta(days=30),
            revocation_type=StateSupervisionViolationResponseRevocationType.
            RETURN_TO_SUPERVISION)
        placeholder_sv = StateSupervisionViolation.new_with_defaults(
            supervision_violation_responses=[svr_1, svr_2, svr_3])
        placeholder_sp = StateSupervisionPeriod.new_with_defaults(
            supervision_violation_entries=[placeholder_sv])
        placeholder_ss = StateSupervisionSentence.new_with_defaults(
            supervision_periods=[placeholder_sp])

        placeholder_sg = StateSentenceGroup.new_with_defaults(
            incarceration_sentences=[placeholder_is],
            supervision_sentences=[placeholder_ss])
        placeholder_person = StatePerson.new_with_defaults(
            sentence_groups=[placeholder_sg])

        external_id = StatePersonExternalId.new_with_defaults(
            external_id=_EXTERNAL_ID)
        person_without_revocation = StatePerson.new_with_defaults(
            external_ids=[external_id])

        expected_svr_1 = attr.evolve(svr_1)
        expected_svr_2 = attr.evolve(svr_2)
        expected_svr_3 = attr.evolve(svr_3)
        expected_placeholder_sv = attr.evolve(
            placeholder_sv,
            supervision_violation_responses=[expected_svr_1, expected_svr_2,
                                             expected_svr_3])
        expected_placeholder_sp = attr.evolve(
            placeholder_sp,
            supervision_violation_entries=[expected_placeholder_sv])
        expected_placeholder_ss = attr.evolve(
            placeholder_ss, supervision_periods=[expected_placeholder_sp])

        expected_ip_1 = attr.evolve(
            ip_1, source_supervision_violation_response=expected_svr_1)
        expected_ip_2 = attr.evolve(
            ip_2, source_supervision_violation_response=expected_svr_2)

        expected_placeholder_is = attr.evolve(
            placeholder_is,
            incarceration_periods=[expected_ip_1, expected_ip_2])
        expected_placeholder_sg = attr.evolve(
            placeholder_sg,
            supervision_sentences=[expected_placeholder_ss],
            incarceration_sentences=[expected_placeholder_is])
        expected_placeholder_person = attr.evolve(
            placeholder_person, sentence_groups=[expected_placeholder_sg])
        expected_person_without_revocation = attr.evolve(
            person_without_revocation)

        # Act
        input_people = \
            converter.convert_entity_people_to_schema_people(
                [person_without_revocation, placeholder_person])
        associate_revocation_svrs_with_ips(input_people)

        # Assert
        self.assert_people_match(
            [expected_person_without_revocation, expected_placeholder_person],
            input_people)
    def test_moveContactsOntoSupervisionPeriodsForPerson(self):
        self.maxDiff = None
        # Arrange
        sc_1 = StateSupervisionContact.new_with_defaults(contact_date=_DATE_2)
        sc_2 = StateSupervisionContact.new_with_defaults(contact_date=_DATE_3)
        sc_3 = StateSupervisionContact.new_with_defaults(contact_date=_DATE_8)

        placeholder_sp_ss = StateSupervisionPeriod.new_with_defaults(
            supervision_contacts=[sc_1, sc_3])
        sp_ss = StateSupervisionPeriod.new_with_defaults(
            external_id=_EXTERNAL_ID,
            start_date=_DATE_1,
            termination_date=_DATE_3)
        sp_2_ss = StateSupervisionPeriod.new_with_defaults(
            external_id=_EXTERNAL_ID_2, start_date=_DATE_7)
        ss = StateSupervisionSentence.new_with_defaults(
            external_id=_EXTERNAL_ID,
            supervision_periods=[sp_ss, sp_2_ss, placeholder_sp_ss])

        placeholder_sp_is = StateSupervisionPeriod.new_with_defaults(
            supervision_contacts=[sc_2, sc_3])
        sp_is = StateSupervisionPeriod.new_with_defaults(
            external_id=_EXTERNAL_ID_3,
            start_date=_DATE_2,
            termination_date=_DATE_3)
        sp_2_is = StateSupervisionPeriod.new_with_defaults(
            external_id=_EXTERNAL_ID_4,
            start_date=_DATE_3,
            termination_date=_DATE_6)
        inc_s = StateIncarcerationSentence.new_with_defaults(
            external_id=_EXTERNAL_ID,
            supervision_periods=[sp_is, sp_2_is, placeholder_sp_is])

        sg = StateSentenceGroup.new_with_defaults(
            incarceration_sentences=[inc_s])
        sg_2 = StateSentenceGroup.new_with_defaults(supervision_sentences=[ss])

        state_person = StatePerson.new_with_defaults(
            sentence_groups=[sg, sg_2])

        expected_sc_1 = attr.evolve(sc_1)
        expected_sc_2 = attr.evolve(sc_2)
        expected_sc_3 = attr.evolve(sc_3)

        expected_placeholder_sp_ss = attr.evolve(placeholder_sp_ss,
                                                 supervision_contacts=[])
        expected_sp_ss = attr.evolve(sp_ss,
                                     supervision_contacts=[expected_sc_1])
        expected_sp_2_ss = attr.evolve(sp_2_ss,
                                       supervision_contacts=[expected_sc_3])
        expected_ss = attr.evolve(ss,
                                  supervision_periods=[
                                      expected_placeholder_sp_ss,
                                      expected_sp_ss, expected_sp_2_ss
                                  ])

        expected_placeholder_sp_is = attr.evolve(placeholder_sp_is,
                                                 supervision_contacts=[])
        expected_sp_is = attr.evolve(sp_is,
                                     supervision_contacts=[expected_sc_1])
        expected_sp_2_is = attr.evolve(sp_2_is,
                                       supervision_contacts=[expected_sc_2])
        expected_inc_s = attr.evolve(inc_s,
                                     supervision_periods=[
                                         expected_placeholder_sp_is,
                                         expected_sp_is, expected_sp_2_is
                                     ])
        expected_sg = attr.evolve(sg, incarceration_sentences=[expected_inc_s])
        expected_sg_2 = attr.evolve(sg_2, supervision_sentences=[expected_ss])

        expected_person = attr.evolve(
            state_person, sentence_groups=[expected_sg, expected_sg_2])

        # Act
        input_people = converter.convert_entity_people_to_schema_people(
            [state_person])
        move_contacts_onto_supervision_periods_for_person(
            input_people, _STATE_CODE)

        # Assert
        self.assert_people_match([expected_person], input_people)
Example #17
0
    def test_inferReleaseDateOnOpenBookings(self):
        # Arrange
        hold = county_entities.Hold.new_with_defaults(hold_id=ID,
                                                      status=HoldStatus.ACTIVE,
                                                      status_raw_text='ACTIVE')
        sentence = county_entities.Sentence.new_with_defaults(
            sentence_id=ID,
            status=SentenceStatus.SERVING,
            status_raw_text='SERVING',
            booking_id=ID)
        bond = county_entities.Bond.new_with_defaults(
            bond_id=ID,
            status=BondStatus.SET,
            status_raw_text='NOT_REQUIRED',
            booking_id=ID)
        charge = county_entities.Charge.new_with_defaults(
            charge_id=ID,
            status=ChargeStatus.PENDING,
            status_raw_text='PENDING',
            sentence=sentence,
            bond=bond)
        booking_open = county_entities.Booking.new_with_defaults(
            booking_id=ID,
            custody_status=CustodyStatus.IN_CUSTODY,
            custody_status_raw_text='IN CUSTODY',
            admission_date=DATE,
            last_seen_time=SCRAPER_START_DATETIME - timedelta(days=1),
            first_seen_time=SCRAPER_START_DATETIME - timedelta(days=1),
            charges=[charge],
            holds=[hold])
        booking_resolved = attr.evolve(booking_open,
                                       booking_id=ID_2,
                                       custody_status=CustodyStatus.RELEASED,
                                       custody_status_raw_text='RELEASED',
                                       release_date=DATE_2,
                                       charges=[],
                                       holds=[])
        booking_open_most_recent_scrape = attr.evolve(
            booking_open,
            booking_id=ID_3,
            last_seen_time=SCRAPER_START_DATETIME,
            charges=[],
            holds=[])

        person = county_entities.Person.new_with_defaults(
            person_id=ID,
            region=REGION_1,
            jurisdiction_id=JURISDICTION_ID,
            bookings=[booking_open, booking_resolved])
        person_unmatched = county_entities.Person.new_with_defaults(
            person_id=ID_2,
            region=REGION_1,
            jurisdiction_id=JURISDICTION_ID,
            bookings=[booking_open_most_recent_scrape])

        session = SessionFactory.for_schema_base(JailsBase)
        database.write_people(
            session,
            converter.convert_entity_people_to_schema_people(
                [person, person_unmatched]), DEFAULT_METADATA)
        session.commit()
        session.close()

        expected_hold = attr.evolve(hold,
                                    status=HoldStatus.REMOVED_WITHOUT_INFO,
                                    status_raw_text=None)
        expected_sentence = attr.evolve(
            sentence,
            status=SentenceStatus.REMOVED_WITHOUT_INFO,
            status_raw_text=None)
        expected_bond = attr.evolve(bond,
                                    status=BondStatus.REMOVED_WITHOUT_INFO,
                                    status_raw_text=None)
        expected_charge = attr.evolve(charge,
                                      status=ChargeStatus.REMOVED_WITHOUT_INFO,
                                      status_raw_text=None,
                                      bond=expected_bond,
                                      sentence=expected_sentence)
        expected_resolved_booking = attr.evolve(
            booking_open,
            custody_status=CustodyStatus.INFERRED_RELEASE,
            custody_status_raw_text=None,
            release_date=SCRAPER_START_DATETIME.date(),
            release_date_inferred=True,
            charges=[expected_charge],
            holds=[expected_hold])
        expected_person = attr.evolve(
            person, bookings=[expected_resolved_booking, booking_resolved])

        # Act
        persistence.infer_release_on_open_bookings(
            REGION_1, SCRAPER_START_DATETIME, CustodyStatus.INFERRED_RELEASE)

        # Assert
        people = county_dao.read_people(
            SessionFactory.for_schema_base(JailsBase))
        self.assertCountEqual(people, [expected_person, person_unmatched])
    def test_associateSvrsWithIps_within90Days(self) -> None:
        # Arrange
        svr_1 = StateSupervisionViolationResponse.new_with_defaults(
            state_code=_STATE_CODE,
            response_date=_DATE_2 + datetime.timedelta(days=1),
            revocation_type=StateSupervisionViolationResponseRevocationType.
            REINCARCERATION,
        )
        svr_2 = StateSupervisionViolationResponse.new_with_defaults(
            state_code=_STATE_CODE,
            response_date=_DATE_4 + datetime.timedelta(days=100),
            revocation_type=StateSupervisionViolationResponseRevocationType.
            RETURN_TO_SUPERVISION,
        )
        placeholder_sv = StateSupervisionViolation.new_with_defaults(
            state_code=_STATE_CODE,
            supervision_violation_responses=[svr_1, svr_2])
        placeholder_sp = StateSupervisionPeriod.new_with_defaults(
            state_code=_STATE_CODE,
            supervision_violation_entries=[placeholder_sv],
            status=StateSupervisionPeriodStatus.PRESENT_WITHOUT_INFO,
        )
        placeholder_ss = StateSupervisionSentence.new_with_defaults(
            state_code=_STATE_CODE,
            supervision_periods=[placeholder_sp],
            status=StateSentenceStatus.PRESENT_WITHOUT_INFO,
        )

        ip_1 = StateIncarcerationPeriod.new_with_defaults(
            state_code=_STATE_CODE,
            admission_date=_DATE_2,
            admission_reason=StateIncarcerationPeriodAdmissionReason.
            PROBATION_REVOCATION,
            status=StateIncarcerationPeriodStatus.PRESENT_WITHOUT_INFO,
        )
        ip_2 = StateIncarcerationPeriod.new_with_defaults(
            state_code=_STATE_CODE,
            admission_date=_DATE_4,
            admission_reason=StateIncarcerationPeriodAdmissionReason.
            PROBATION_REVOCATION,
            status=StateIncarcerationPeriodStatus.PRESENT_WITHOUT_INFO,
        )
        placeholder_is = StateIncarcerationSentence.new_with_defaults(
            state_code=_STATE_CODE,
            incarceration_periods=[ip_1, ip_2],
            status=StateSentenceStatus.PRESENT_WITHOUT_INFO,
        )
        placeholder_sg = StateSentenceGroup.new_with_defaults(
            state_code=_STATE_CODE,
            status=StateSentenceStatus.PRESENT_WITHOUT_INFO,
            incarceration_sentences=[placeholder_is],
            supervision_sentences=[placeholder_ss],
        )
        placeholder_person = StatePerson.new_with_defaults(
            state_code=_STATE_CODE, sentence_groups=[placeholder_sg])

        expected_svr_1 = attr.evolve(svr_1)
        expected_svr_2 = attr.evolve(svr_2)
        expected_placeholder_sv = attr.evolve(
            placeholder_sv,
            supervision_violation_responses=[expected_svr_1, expected_svr_2],
        )
        expected_placeholder_sp = attr.evolve(
            placeholder_sp,
            supervision_violation_entries=[expected_placeholder_sv])
        expected_placeholder_ss = attr.evolve(
            placeholder_ss, supervision_periods=[expected_placeholder_sp])

        expected_ip_1 = attr.evolve(
            ip_1, source_supervision_violation_response=expected_svr_1)
        expected_ip_2 = attr.evolve(ip_2)

        expected_placeholder_is = attr.evolve(
            placeholder_is,
            incarceration_periods=[expected_ip_1, expected_ip_2])
        expected_placeholder_sg = attr.evolve(
            placeholder_sg,
            supervision_sentences=[expected_placeholder_ss],
            incarceration_sentences=[expected_placeholder_is],
        )
        expected_placeholder_person = attr.evolve(
            placeholder_person, sentence_groups=[expected_placeholder_sg])

        # Act
        input_people = converter.convert_entity_people_to_schema_people(
            [placeholder_person])
        associate_revocation_svrs_with_ips(input_people)

        # Assert
        self.assert_people_match([expected_placeholder_person], input_people)
Example #19
0
    def test_moveViolationsOntoSupervisionPeriodsForSentence(self):
        # Arrange
        sv_1 = StateSupervisionViolation.new_with_defaults(
            violation_date=_DATE_2)
        svr = StateSupervisionViolationResponse.new_with_defaults(
            response_date=_DATE_3)
        sv_2 = StateSupervisionViolation.new_with_defaults(
            supervision_violation_responses=[svr])
        sv_3 = StateSupervisionViolation.new_with_defaults(
            violation_date=_DATE_8)

        placeholder_sp_ss = StateSupervisionPeriod.new_with_defaults(
            supervision_violation_entries=[sv_1, sv_3])
        sp_ss = StateSupervisionPeriod.new_with_defaults(
            external_id=_EXTERNAL_ID,
            start_date=_DATE_1,
            termination_date=_DATE_3)
        sp_2_ss = StateSupervisionPeriod.new_with_defaults(
            external_id=_EXTERNAL_ID_2, start_date=_DATE_7)
        ss = StateSupervisionSentence.new_with_defaults(
            external_id=_EXTERNAL_ID,
            supervision_periods=[sp_ss, sp_2_ss, placeholder_sp_ss])

        placeholder_sp_is = StateSupervisionPeriod.new_with_defaults(
            supervision_violation_entries=[sv_2, sv_3])
        sp_is = StateSupervisionPeriod.new_with_defaults(
            external_id=_EXTERNAL_ID_3,
            start_date=_DATE_2,
            termination_date=_DATE_3)
        sp_2_is = StateSupervisionPeriod.new_with_defaults(
            external_id=_EXTERNAL_ID_4,
            start_date=_DATE_3,
            termination_date=_DATE_6)
        inc_s = StateIncarcerationSentence.new_with_defaults(
            external_id=_EXTERNAL_ID,
            supervision_periods=[sp_is, sp_2_is, placeholder_sp_is])

        sg = StateSentenceGroup.new_with_defaults(
            incarceration_sentences=[inc_s], supervision_sentences=[ss])

        state_person = StatePerson.new_with_defaults(sentence_groups=[sg])

        expected_sv_1 = attr.evolve(sv_1)
        expected_svr_2 = attr.evolve(svr)
        expected_sv_2 = attr.evolve(
            sv_2, supervision_violation_responses=[expected_svr_2])
        expected_sv_3 = attr.evolve(sv_3)

        expected_placeholder_sp_ss = attr.evolve(
            placeholder_sp_ss, supervision_violation_entries=[])
        expected_sp_ss = attr.evolve(
            sp_ss, supervision_violation_entries=[expected_sv_1])
        expected_sp_2_ss = attr.evolve(
            sp_2_ss, supervision_violation_entries=[expected_sv_3])
        expected_ss = attr.evolve(ss,
                                  supervision_periods=[
                                      expected_placeholder_sp_ss,
                                      expected_sp_ss, expected_sp_2_ss
                                  ])

        expected_placeholder_sp_is = attr.evolve(
            placeholder_sp_is, supervision_violation_entries=[expected_sv_3])
        expected_sp_is = attr.evolve(sp_is, supervision_violation_entries=[])
        expected_sp_2_is = attr.evolve(
            sp_2_is, supervision_violation_entries=[expected_sv_2])
        expected_inc_s = attr.evolve(inc_s,
                                     supervision_periods=[
                                         expected_placeholder_sp_is,
                                         expected_sp_is, expected_sp_2_is
                                     ])
        expected_sg = attr.evolve(sg,
                                  supervision_sentences=[expected_ss],
                                  incarceration_sentences=[expected_inc_s])
        expected_person = attr.evolve(state_person,
                                      sentence_groups=[expected_sg])

        # Act
        input_people = converter.convert_entity_people_to_schema_people(
            [state_person])
        move_violations_onto_supervision_periods_for_sentence(input_people)

        # Assert
        self.assert_people_match([expected_person], input_people)