def test_generate_samples(self): participant_id = self.send_post('Participant', {})['participantId'] self.send_consent(participant_id) self.send_post( 'Participant/%s/BiobankOrder' % participant_id, load_biobank_order_json( from_client_participant_id(participant_id))) # Sanity check that the orders were created correctly. bo_dao = BiobankOrderDao() self.assertEquals(1, bo_dao.count()) order = bo_dao.get_all()[0] self.assertEquals( 11, len(bo_dao.get_with_children(order.biobankOrderId).samples)) self.send_post('DataGen', { 'create_biobank_samples': True, 'samples_missing_fraction': 0.0 }) upsert_from_latest_csv( ) # Run the (usually offline) Biobank CSV import job. self.assertEquals(11, BiobankStoredSampleDao().count()) ps = ParticipantSummaryDao().get( from_client_participant_id(participant_id)) self.assertEquals(SampleStatus.RECEIVED, ps.samplesToIsolateDNA) self.assertEquals(10, ps.numBaselineSamplesArrived)
def test_auto_pair_called(self): pid_numeric = from_client_participant_id(self.participant_id) participant_dao = ParticipantDao() self.send_consent(self.participant_id) self.send_consent(self.participant_id_2) self.assertEquals(participant_dao.get(pid_numeric).hpoId, UNSET_HPO_ID) self._insert_measurements(datetime.datetime.utcnow().isoformat()) self.assertNotEqual(participant_dao.get(pid_numeric).hpoId, UNSET_HPO_ID)
def _post_supply_delivery(self, resource): try: fhir = SimpleFhirR4Reader(resource) patient = fhir.patient pid = patient.identifier p_id = from_client_participant_id(pid.value) bo_id = fhir.basedOn[0].identifier.value _id = self.dao.get_id( ObjDict({ 'participantId': p_id, 'order_id': int(bo_id) })) tracking_status = fhir.extension.get( url=DV_FHIR_URL + 'tracking-status').valueString.lower() except AttributeError as e: raise BadRequest(e.message) except Exception as e: raise BadRequest(e.message) if not _id: raise Conflict( 'Existing SupplyRequest for order required for SupplyDelivery') dvo = self.dao.get(_id) if not dvo: raise Conflict( 'Existing SupplyRequest for order required for SupplyDelivery') merged_resource = None # Note: POST tracking status should be either 'enroute/in_transit'. PUT should only be 'delivered'. if tracking_status in [ 'in_transit', 'enroute', 'delivered' ] and self._to_mayo(fhir) and not dvo.biobankOrderId: # Send to mayolink and create internal biobank order response = self.dao.send_order(resource, p_id) merged_resource = merge_dicts(response, resource) merged_resource['id'] = _id logging.info( 'Sending salivary order to biobank for participant: %s', p_id) self.dao.insert_biobank_order(p_id, merged_resource) response = super(DvOrderApi, self).put(bo_id, participant_id=p_id, skip_etag=True, resource=merged_resource) response[2]['Location'] = '/rdr/v1/SupplyDelivery/{}'.format(bo_id) response[2]['auth_user'] = resource['auth_user'] if response[1] == 200: created_response = list(response) created_response[1] = 201 return tuple(created_response) return response
def test_bio_after_cancelled_pm(self): self.participant_id = self.create_participant() self.send_consent(self.participant_id) measurement = load_measurement_json(self.participant_id) measurement2 = load_measurement_json(self.participant_id) # send both PM's pm_path = 'Participant/%s/PhysicalMeasurements' % self.participant_id response = self.send_post(pm_path, measurement) self.send_post(pm_path, measurement2) # cancel the 1st PM pm_path = pm_path + '/' + response['id'] cancel_info = get_restore_or_cancel_info() self.send_patch(pm_path, cancel_info) # set up questionnaires to hit the calculate_max_core_sample_time in participant summary questionnaire_id = self.create_questionnaire('questionnaire3.json') questionnaire_id_1 = self.create_questionnaire( 'all_consents_questionnaire.json') questionnaire_id_2 = self.create_questionnaire('questionnaire4.json') self._submit_consent_questionnaire_response( self.participant_id, questionnaire_id_1, CONSENT_PERMISSION_YES_CODE, time=TIME_6) self.submit_questionnaire_response(self.participant_id, questionnaire_id, RACE_NONE_OF_THESE_CODE, None, None, datetime.date(1978, 10, 10)) self._submit_empty_questionnaire_response(self.participant_id, questionnaire_id_2) # send a biobank order _id = int(self.participant_id[1:]) self.path = ('Participant/%s/BiobankOrder' % to_client_participant_id(_id)) pid_numeric = from_client_participant_id(self.participant_id) self.send_post(self.path, load_biobank_order_json(pid_numeric)) # fetch participant summary ps = self.send_get('ParticipantSummary?participantId=%s' % _id) self.assertTrue( ps['entry'][0]['resource']["physicalMeasurementsFinalizedTime"]) self.assertEquals( ps['entry'][0]['resource']["physicalMeasurementsFinalizedSite"], 'hpo-site-bannerphoenix') self.assertIsNotNone('biobankId', ps['entry'][0]['resource'])
def _post_supply_request(self, resource): fhir_resource = SimpleFhirR4Reader(resource) patient = fhir_resource.contained.get(resourceType='Patient') pid = patient.identifier.get(system=VIBRENT_FHIR_URL + 'participantId').value p_id = from_client_participant_id(pid) response = super(DvOrderApi, self).post(participant_id=p_id) order_id = fhir_resource.identifier.get(system=VIBRENT_FHIR_URL + 'orderId').value response[2]['Location'] = '/rdr/v1/SupplyRequest/{}'.format(order_id) if response[1] == 200: created_response = list(response) created_response[1] = 201 return tuple(created_response) return response
def _put_supply_request(self, resource, bo_id): # handle invalid FHIR documents try: fhir_resource = SimpleFhirR4Reader(resource) barcode_url = None if fhir_resource.extension.get( url=VIBRENT_FULFILLMENT_URL).valueString == 'shipped': barcode_url = fhir_resource.extension.get( url=VIBRENT_BARCODE_URL).url pid = fhir_resource.contained.get( resourceType='Patient').identifier.get( system=VIBRENT_FHIR_URL + 'participantId') p_id = from_client_participant_id(pid.value) except AttributeError as e: raise BadRequest(e.message) except Exception as e: raise BadRequest(e.message) merged_resource = None if not p_id: raise BadRequest( 'Request must include participant id and must be of type int') if str(barcode_url) == VIBRENT_BARCODE_URL: _id = self.dao.get_id( ObjDict({ 'participantId': p_id, 'order_id': int(bo_id) })) ex_obj = self.dao.get(_id) if not ex_obj.barcode: # Send to mayolink and create internal biobank order response = self.dao.send_order(resource, p_id) merged_resource = merge_dicts(response, resource) merged_resource['id'] = _id self.dao.insert_biobank_order(p_id, merged_resource) if merged_resource: response = super(DvOrderApi, self).put(bo_id, participant_id=p_id, skip_etag=True, resource=merged_resource) else: response = super(DvOrderApi, self).put(bo_id, participant_id=p_id, skip_etag=True) return response
def test_not_pairing_at_pm_when_has_bio(self): self.participant_id = self.create_participant() _id = int(self.participant_id[1:]) self.path = ( 'Participant/%s/BiobankOrder' % to_client_participant_id(_id)) pid_numeric = from_client_participant_id(self.participant_id) self.send_consent(self.participant_id) self.send_post(self.path, load_biobank_order_json(pid_numeric)) participant_paired = self.summary_dao.get(pid_numeric) self.assertEqual(participant_paired.siteId, participant_paired.biospecimenCollectedSiteId) self.path = ( 'Participant/%s/PhysicalMeasurements' % to_client_participant_id(pid_numeric)) self._insert_measurements(datetime.datetime.utcnow().isoformat()) self.assertNotEqual(participant_paired.siteId, participant_paired.physicalMeasurementsFinalizedSiteId)
def _post_supply_delivery(self, resource): fhir_resource = SimpleFhirR4Reader(resource) patient = fhir_resource.patient pid = patient.identifier p_id = from_client_participant_id(pid.value) bo_id = fhir_resource.basedOn[0].identifier.value pk = {'participantId': p_id, 'order_id': bo_id} obj = ObjDict(pk) if not self.dao.get_id(obj): raise Conflict( 'Existing SupplyRequest for order required for SupplyDelivery') response = super(DvOrderApi, self).put(bo_id, participant_id=p_id, skip_etag=True) response[2]['Location'] = '/rdr/v1/SupplyDelivery/{}'.format(bo_id) if response[1] == 200: created_response = list(response) created_response[1] = 201 return tuple(created_response) return response
def _put_supply_request(self, resource, bo_id): # handle invalid FHIR documents try: fhir_resource = SimpleFhirR4Reader(resource) pid = fhir_resource.contained.get( resourceType='Patient').identifier.get(system=DV_FHIR_URL + 'participantId') p_id = from_client_participant_id(pid.value) except AttributeError as e: raise BadRequest(e.message) except Exception as e: raise BadRequest(e.message) if not p_id: raise BadRequest('Request must include participant id') response = super(DvOrderApi, self).put(bo_id, participant_id=p_id, skip_etag=True) return response
def _put_supply_delivery(self, resource, bo_id): # handle invalid FHIR documents try: fhir = SimpleFhirR4Reader(resource) participant_id = fhir.patient.identifier.value p_id = from_client_participant_id(participant_id) update_time = dateutil.parser.parse(fhir.occurrenceDateTime) carrier_name = fhir.extension.get(url=VIBRENT_FHIR_URL + 'carrier').valueString eta = dateutil.parser.parse( fhir.extension.get(url=VIBRENT_FHIR_URL + "expected-delivery-date").valueDateTime) tracking_status = fhir.extension.get(url=VIBRENT_FHIR_URL + 'tracking-status').valueString except AttributeError as e: raise BadRequest(e.message) except Exception as e: raise BadRequest(e.message) tracking_status_enum = getattr(OrderShipmentTrackingStatus, tracking_status.upper(), OrderShipmentTrackingStatus.UNSET) biobank_dv_order_id = self.dao.get_id( ObjDict({ 'participantId': p_id, 'order_id': int(bo_id) })) order = self.dao.get(biobank_dv_order_id) order.shipmentLastUpdate = update_time.date() order.shipmentCarrier = carrier_name order.shipmentEstArrival = eta.date() order.shipmentStatus = tracking_status_enum response = super(DvOrderApi, self).put(bo_id, participant_id=p_id, skip_etag=True) return response
def test_insert(self): participant_id = self.create_participant() questionnaire_id = self.create_questionnaire('questionnaire1.json') with open(data_path('questionnaire_response3.json')) as fd: resource = json.load(fd) # Sending response with the dummy participant id in the file is an error self.send_post(_questionnaire_response_url('{participant_id}'), resource, expected_status=httplib.NOT_FOUND) # Fixing participant id but not the questionnaire id is also an error resource['subject']['reference'] = \ resource['subject']['reference'].format(participant_id=participant_id) self.send_post(_questionnaire_response_url(participant_id), resource, expected_status=httplib.BAD_REQUEST) # Fix the reference resource['questionnaire']['reference'] = \ resource['questionnaire']['reference'].format(questionnaire_id=questionnaire_id) # Sending the response before the consent is an error. self.send_post(_questionnaire_response_url(participant_id), resource, expected_status=httplib.BAD_REQUEST) # After consent, the post succeeds self.send_consent(participant_id) response = self.send_post(_questionnaire_response_url(participant_id), resource) resource['id'] = response['id'] # The resource gets rewritten to include the version resource['questionnaire'][ 'reference'] = 'Questionnaire/%s/_history/1' % questionnaire_id self.assertJsonResponseMatches(resource, response) # Do a get to fetch the questionnaire get_response = self.send_get( _questionnaire_response_url(participant_id) + "/" + response['id']) self.assertJsonResponseMatches(resource, get_response) code_dao = CodeDao() # Ensure we didn't create codes in the extra system self.assertIsNone(code_dao.get_code(PPI_EXTRA_SYSTEM, 'IgnoreThis')) name_of_child = code_dao.get_code("sys", "nameOfChild") birth_weight = code_dao.get_code("sys", "birthWeight") birth_length = code_dao.get_code("sys", "birthLength") vitamin_k_dose_1 = code_dao.get_code("sys", "vitaminKDose1") vitamin_k_dose_2 = code_dao.get_code("sys", "vitaminKDose2") hep_b_given = code_dao.get_code("sys", "hepBgiven") abnormalities_at_birth = code_dao.get_code("sys", "abnormalitiesAtBirth") answer_dao = QuestionnaireResponseAnswerDao() with answer_dao.session() as session: code_ids = [ code.codeId for code in [ name_of_child, birth_weight, birth_length, vitamin_k_dose_1, vitamin_k_dose_2, hep_b_given, abnormalities_at_birth ] ] current_answers = answer_dao.get_current_answers_for_concepts(session,\ from_client_participant_id(participant_id), code_ids) self.assertEquals(7, len(current_answers)) questionnaire = QuestionnaireDao().get_with_children(questionnaire_id) question_id_to_answer = { answer.questionId: answer for answer in current_answers } code_id_to_answer = { question.codeId: question_id_to_answer.get(question.questionnaireQuestionId) for question in questionnaire.questions } self.assertEquals("Cathy Jones", code_id_to_answer[name_of_child.codeId].valueString) self.assertEquals(3.25, code_id_to_answer[birth_weight.codeId].valueDecimal) self.assertEquals(44.3, code_id_to_answer[birth_length.codeId].valueDecimal) self.assertEquals(44, code_id_to_answer[birth_length.codeId].valueInteger) self.assertEquals(True, code_id_to_answer[hep_b_given.codeId].valueBoolean) self.assertEquals( 0, code_id_to_answer[abnormalities_at_birth.codeId].valueInteger) self.assertEquals(datetime.date(1972, 11, 30), code_id_to_answer[vitamin_k_dose_1.codeId].valueDate) self.assertEquals( datetime.datetime(1972, 11, 30, 12, 34, 42), code_id_to_answer[vitamin_k_dose_2.codeId].valueDateTime)
def _put_supply_delivery(self, resource, bo_id): # handle invalid FHIR documents try: fhir = SimpleFhirR4Reader(resource) participant_id = fhir.patient.identifier.value p_id = from_client_participant_id(participant_id) update_time = dateutil.parser.parse(fhir.occurrenceDateTime) carrier_name = fhir.extension.get(url=DV_FHIR_URL + 'carrier').valueString eta = None if hasattr(fhir['extension'], DV_FHIR_URL + 'expected-delivery-date'): eta = dateutil.parser.parse( fhir.extension.get(url=DV_FHIR_URL + "expected-delivery-date").valueDateTime) tracking_status = fhir.extension.get(url=DV_FHIR_URL + 'tracking-status').valueString if tracking_status: tracking_status = tracking_status.lower() except AttributeError as e: raise BadRequest(e.message) except Exception as e: raise BadRequest(e.message) _id = self.dao.get_id( ObjDict({ 'participantId': p_id, 'order_id': int(bo_id) })) if not _id: raise Conflict( 'Existing SupplyRequest for order required for SupplyDelivery') dvo = self.dao.get(_id) if not dvo: raise Conflict( 'Existing SupplyRequest for order required for SupplyDelivery') tracking_status_enum = \ getattr(OrderShipmentTrackingStatus, tracking_status.upper(), OrderShipmentTrackingStatus.UNSET) dvo.shipmentLastUpdate = update_time.date() dvo.shipmentCarrier = carrier_name if eta: dvo.shipmentEstArrival = eta.date() dvo.shipmentStatus = tracking_status_enum if not p_id: raise BadRequest('Request must include participant id') merged_resource = None # Note: PUT tracking status should only be 'delivered'. POST should be either 'enroute/in_transit'. if tracking_status in [ 'in_transit', 'enroute', 'delivered' ] and self._to_mayo(fhir) and not dvo.biobankOrderId: # Send to mayolink and create internal biobank order response = self.dao.send_order(resource, p_id) merged_resource = merge_dicts(response, resource) merged_resource['id'] = _id logging.info( 'Sending salivary order to biobank for participant: %s', p_id) self.dao.insert_biobank_order(p_id, merged_resource) response = super(DvOrderApi, self).put(bo_id, participant_id=p_id, skip_etag=True, resource=merged_resource) return response