def create_commcare_case(data): cccsql = CommCareCase( case_id=data['case_id'], domain=data['domain'], type=data['type'], name=data['name'], owner_id=data['owner_id'], modified_by=data['modified_by'], modified_on=datetime.utcnow(), server_modified_on=datetime.utcnow(), ) cccsql.save() return cccsql
def _setup_case(self, cases=None): modify_date = datetime.utcnow() cases = cases or [(None, None)] for owner_id, case_id in cases: kwargs = {} if owner_id: kwargs['owner_id'] = owner_id backend_case = CommCareCase( case_id=case_id if case_id else uuid.uuid4().hex, domain=self.domain.name, modified_on=modify_date, server_modified_on=modify_date, **kwargs) backend_case.save() translated_doc = transform_case_for_elasticsearch( backend_case.to_json()) send_to_elasticsearch('cases', translated_doc) self.es.indices.refresh(CASE_INDEX_INFO.index) return backend_case
class TestGetInfoResourcesListSubCases(TestCase, DomainSubscriptionMixin): @classmethod def setUpClass(cls): super().setUpClass() cls.domain_obj = create_domain(DOMAIN) cls.setup_subscription(DOMAIN, SoftwarePlanEdition.PRO) cls.person_case_type = CaseType.objects.create(domain=DOMAIN, name='person') name = CaseProperty.objects.create(case_type=cls.person_case_type, name='name') resource_type_for_person = FHIRResourceType.objects.create( domain=DOMAIN, case_type=cls.person_case_type, name='Patient') FHIRResourceProperty.objects.create( resource_type=resource_type_for_person, case_property=name, jsonpath='$.name[0].text', ) FHIRResourceProperty.objects.create( resource_type=resource_type_for_person, value_source_config={ 'subcase_value_source': { 'case_property': 'given_names', # Use counter1 to skip the name set by the parent case 'jsonpath': '$.name[{counter1}].given', 'commcare_data_type': COMMCARE_DATA_TYPE_TEXT, 'external_data_type': FHIR_DATA_TYPE_LIST_OF_STRING, }, 'case_types': ['person_name'], }) FHIRResourceProperty.objects.create( resource_type=resource_type_for_person, value_source_config={ 'subcase_value_source': { 'case_property': 'family_name', 'jsonpath': '$.name[{counter1}].family', }, 'case_types': ['person_name'], }) @classmethod def tearDownClass(cls): cls.person_case_type.delete() cls.teardown_subscriptions() cls.domain_obj.delete() clear_plan_version_cache() super().tearDownClass() def setUp(self): now = datetime.utcnow() self.parent_case_id = str(uuid4()) self.parent_case = CommCareCase( case_id=self.parent_case_id, domain=DOMAIN, type='person', name='Ted', owner_id=str(uuid4()), modified_on=now, server_modified_on=now, ) self.parent_case.save() self.child_case_1 = CommCareCase( case_id='111111111', domain=DOMAIN, type='person_name', name='Theodore', case_json={ 'given_names': 'Theodore John', 'family_name': 'Kaczynski', }, owner_id=str(uuid4()), modified_on=now, server_modified_on=now, ) self.child_case_1.save() add_case_index( self.child_case_1, identifier='parent', referenced_type='person', referenced_id=self.parent_case_id, ) self.child_case_2 = CommCareCase( case_id='222222222', domain=DOMAIN, type='person_name', name='Unabomber', case_json={'given_names': 'Unabomber'}, owner_id=str(uuid4()), modified_on=now, server_modified_on=now, ) self.child_case_2.save() add_case_index( self.child_case_2, identifier='parent', referenced_type='person', referenced_id=self.parent_case_id, ) def tearDown(self): self.child_case_1.delete() self.child_case_2.delete() self.parent_case.delete() def test_get_info_resource_list(self): rt = get_resource_type_or_none(self.parent_case, FHIR_VERSION_4_0_1) case_trigger_infos = [get_case_trigger_info(self.parent_case, rt)] resource_types_by_case_type = {'person': rt} [(info, resource)] = get_info_resource_list( case_trigger_infos, resource_types_by_case_type, ) self.assertIn({'text': 'Ted'}, resource['name']) self.assertIn( { 'given': ['Theodore', 'John'], 'family': 'Kaczynski' }, resource['name'], ) self.assertIn({'given': ['Unabomber']}, resource['name'])
class TestGetInfoResourcesListOneCase(TestCase, DomainSubscriptionMixin): @classmethod def setUpClass(cls): super().setUpClass() cls.domain_obj = create_domain(DOMAIN) cls.setup_subscription(DOMAIN, SoftwarePlanEdition.PRO) cls.case_type = CaseType.objects.create(domain=DOMAIN, name='person') name = CaseProperty.objects.create(case_type=cls.case_type, name='name') resource_type = FHIRResourceType.objects.create( domain=DOMAIN, case_type=cls.case_type, name='Patient') FHIRResourceProperty.objects.create( resource_type=resource_type, case_property=name, jsonpath='$.name[0].text', ) @classmethod def tearDownClass(cls): cls.case_type.delete() cls.teardown_subscriptions() cls.domain_obj.delete() clear_plan_version_cache() super().tearDownClass() def setUp(self): now = datetime.utcnow() self.case_id = str(uuid4()) self.case = CommCareCase( case_id=self.case_id, domain=DOMAIN, type='person', name='Ted', owner_id=str(uuid4()), modified_on=now, server_modified_on=now, ) self.case.save() def tearDown(self): self.case.delete() def test_get_info_resource_list(self): resource_type = get_resource_type_or_none(self.case, FHIR_VERSION_4_0_1) case_trigger_infos = [get_case_trigger_info(self.case, resource_type)] resource_types_by_case_type = {'person': resource_type} [(info, resource)] = get_info_resource_list( case_trigger_infos, resource_types_by_case_type, ) self.assertEqual( resource, { 'id': self.case_id, 'name': [{ 'text': 'Ted' }], 'resourceType': 'Patient' })
class TestGetInfoResourcesListResources(TestCase, DomainSubscriptionMixin): """ Demonstrates building multiple resources using subcases. """ @classmethod def setUpClass(cls): super().setUpClass() cls.domain_obj = create_domain(DOMAIN) cls.setup_subscription(DOMAIN, SoftwarePlanEdition.PRO) cls.person_case_type = CaseType.objects.create(domain=DOMAIN, name='person') name = CaseProperty.objects.create(case_type=cls.person_case_type, name='name') resource_type_for_person = FHIRResourceType.objects.create( domain=DOMAIN, case_type=cls.person_case_type, name='Patient') FHIRResourceProperty.objects.create( resource_type=resource_type_for_person, case_property=name, jsonpath='$.name[0].text', ) cls.vitals_case_type = CaseType.objects.create(domain=DOMAIN, name='vitals') CaseProperty.objects.create(case_type=cls.vitals_case_type, name='temperature') resource_type_for_vitals = FHIRResourceType.objects.create( domain=DOMAIN, case_type=cls.vitals_case_type, name='Observation', ) FHIRResourceProperty.objects.create( resource_type=resource_type_for_vitals, value_source_config={ 'jsonpath': '$.code.coding[0].system', 'value': 'http://loinc.org', }) FHIRResourceProperty.objects.create( resource_type=resource_type_for_vitals, value_source_config={ 'jsonpath': '$.code.coding[0].code', 'value': '8310-5', }) FHIRResourceProperty.objects.create( resource_type=resource_type_for_vitals, value_source_config={ 'jsonpath': '$.code.coding[0].display', 'value': 'Body temperature', }) FHIRResourceProperty.objects.create( resource_type=resource_type_for_vitals, value_source_config={ 'jsonpath': '$.code.text', 'value': 'Temperature', }) FHIRResourceProperty.objects.create( resource_type=resource_type_for_vitals, value_source_config={ 'jsonpath': '$.valueQuantity.unit', 'value': 'degrees Celsius', }) FHIRResourceProperty.objects.create( resource_type=resource_type_for_vitals, value_source_config={ 'case_property': 'temperature', 'jsonpath': '$.valueQuantity.value', 'external_data_type': COMMCARE_DATA_TYPE_DECIMAL, }) FHIRResourceProperty.objects.create( resource_type=resource_type_for_vitals, value_source_config={ 'supercase_value_source': { 'case_property': 'name', 'jsonpath': '$.subject.display', } }) FHIRResourceProperty.objects.create( resource_type=resource_type_for_vitals, value_source_config={ 'supercase_value_source': { 'case_property': 'case_id', 'jsonpath': '$.subject.reference', } }) @classmethod def tearDownClass(cls): cls.person_case_type.delete() cls.vitals_case_type.delete() cls.teardown_subscriptions() cls.domain_obj.delete() clear_plan_version_cache() super().tearDownClass() def setUp(self): now = datetime.utcnow() owner_id = str(uuid4()) self.parent_case_id = str(uuid4()) self.parent_case = CommCareCase( case_id=self.parent_case_id, domain=DOMAIN, type='person', name='Beth', owner_id=owner_id, modified_on=now, server_modified_on=now, ) self.parent_case.save() self.child_case_id = str(uuid4()) self.child_case = CommCareCase( case_id=self.child_case_id, domain=DOMAIN, type='vitals', case_json={'temperature': 36.1}, owner_id=owner_id, modified_on=now, server_modified_on=now, ) self.child_case.save() add_case_index( self.child_case, identifier='parent', referenced_type='person', referenced_id=self.parent_case_id, ) def tearDown(self): self.child_case.delete() self.parent_case.delete() def test_get_info_resource_list(self): resource_type_for_person = get_resource_type_or_none( self.parent_case, FHIR_VERSION_4_0_1, ) resource_type_for_vitals = get_resource_type_or_none( self.child_case, FHIR_VERSION_4_0_1, ) case_trigger_infos = [ get_case_trigger_info(self.parent_case, resource_type_for_person), get_case_trigger_info(self.child_case, resource_type_for_vitals), ] resource_types_by_case_type = { 'person': resource_type_for_person, 'vitals': resource_type_for_vitals, } info_resource_list = get_info_resource_list( case_trigger_infos, resource_types_by_case_type, ) resources = [resource for info, resource in info_resource_list] self.assertEqual(resources, [{ 'id': self.parent_case_id, 'name': [{ 'text': 'Beth' }], 'resourceType': 'Patient', }, { 'id': self.child_case_id, 'code': { 'coding': [{ 'system': 'http://loinc.org', 'code': '8310-5', 'display': 'Body temperature', }], 'text': 'Temperature', }, 'valueQuantity': { 'value': 36.1, 'unit': 'degrees Celsius', }, 'subject': { 'reference': self.parent_case_id, 'display': 'Beth', }, 'resourceType': 'Observation', }])
class VoidedPatientTests(TestCase, TestFileMixin): file_path = ('data',) root = os.path.dirname(__file__) def setUp(self): self.case = CommCareCase( domain=DOMAIN, case_id="123456", type="person", name="Eric Idle", external_id="94d60c79-59b5-4a2c-90a5-325d6e32b3db", modified_on=datetime.utcnow(), server_modified_on=datetime.utcnow(), ) self.case.save() @mock.patch("corehq.motech.openmrs.repeater_helpers.submit_case_blocks") @mock.patch("corehq.motech.openmrs.repeater_helpers.get_patient_by_uuid") def test_identifier_case_property_deleted(self, get_patient_mock, case_blocks_mock): """ CommCare should drop the case's patient ID when an OpenMRS patient is voided """ requests = None info = CaseTriggerInfo( domain=self.case.domain, case_id=self.case.case_id, type=self.case.type, name=self.case.name, extra_fields={ "external_id": self.case.external_id, }, ) openmrs_config = OpenmrsConfig.wrap({ "case_config": { "patient_finder": {}, "patient_identifiers": { "uuid": {"case_property": "external_id"}, }, "match_on_ids": ["uuid"], "person_properties": {}, "person_preferred_address": {}, "person_preferred_name": {}, }, "form_configs": [], }) voided_patient = self.get_json("voided_patient") get_patient_mock.return_value = voided_patient patient = get_patient(requests, DOMAIN, info, openmrs_config) self.assertEqual(info.extra_fields, {"external_id": None}) case_block_re = strip_xml(f""" <case case_id="123456" » date_modified="{DATETIME_PATTERN}" » xmlns="http://commcarehq.org/case/transaction/v2"> <update> <external_id /> </update> </case> """) case_block = case_blocks_mock.call_args[0][0][0] self.assertIsNotNone(re.match(case_block_re, case_block)) self.assertIsNone(patient)