Exemple #1
0
 def test_relationship_invalid(self):
     with self.assertRaises(TypeError):
         as_value_source({
             'supercase_value_source': {
                 'case_property': 'foo'
             },
             'relationship': 'invalid',
         })
Exemple #2
0
 def test_subcase_value_source(self):
     value_source = as_value_source({
         'subcase_value_source': {
             'case_property': 'foo'
         },
     })
     self.assertIsInstance(value_source, SubcaseValueSource)
Exemple #3
0
    def test_set_external_data(self):
        value_source_configs = [{
            'case_property':
            'value',
            'jsonpath':
            '$.valueQuantity.value',
            'external_data_type':
            COMMCARE_DATA_TYPE_DECIMAL,
        }, {
            'value': 'degrees Celsius',
            'jsonpath': '$.valueQuantity.unit',
        }, {
            'supercase_value_source': {
                'case_property': 'case_id',
                'jsonpath': '$.subject.reference',
            },
            'identifier': 'parent',
            'referenced_type': 'person',
        }, {
            'supercase_value_source': {
                'case_property': 'name',
                'jsonpath': '$.subject.display',
            },
            'identifier': 'parent',
            'referenced_type': 'person',
        }]

        resources = []
        for case in (self.child_case_1, self.child_case_2):
            external_data = {}
            info = get_case_trigger_info_for_case(case, value_source_configs)
            for value_source_config in value_source_configs:
                value_source = as_value_source(value_source_config)
                value_source.set_external_value(external_data, info)
            resources.append(external_data)

        self.assertEqual(
            resources,
            [
                {
                    'subject': {
                        'reference': self.parent_case_id,
                        'display': 'Joe',
                    },
                    'valueQuantity': {
                        'value': 36.2,  # case 1
                        'unit': 'degrees Celsius',
                    },
                },
                {
                    'subject': {
                        'reference': self.parent_case_id,
                        'display': 'Joe',
                    },
                    'valueQuantity': {
                        'value': 36.6,  # case 2
                        'unit': 'degrees Celsius',
                    },
                }
            ])
 def test_with_location_field_doc_type(self):
     json_object = as_value_source({
         "doc_type": "CaseOwnerAncestorLocationField",
         "location_field": "dhis_id",
     })
     self.assertIsInstance(json_object, CaseOwnerAncestorLocationField)
     self.assertEqual(json_object.case_owner_ancestor_location_field,
                      "dhis_id")
 def test_blank_path(self):
     json_doc = {"foo": {"bar": "baz"}}
     value_source = as_value_source({
         "case_property": "bar",
         "jsonpath": "",
     })
     with self.assertRaises(JsonpathError):
         value_source.get_import_value(json_doc)
Exemple #6
0
 def test_case_types(self):
     value_source = as_value_source({
         'subcase_value_source': {
             'case_property': 'foo'
         },
         'case_types': ['bar'],
     })
     self.assertIsInstance(value_source, SubcaseValueSource)
Exemple #7
0
 def test_is_closed(self):
     value_source = as_value_source({
         'subcase_value_source': {
             'case_property': 'foo'
         },
         'is_closed': False,
     })
     self.assertIsInstance(value_source, SubcaseValueSource)
 def test_one_value(self):
     json_doc = {"foo": {"bar": "baz"}}
     value_source = as_value_source({
         "case_property": "bar",
         "jsonpath": "foo.bar",
     })
     external_value = value_source.get_import_value(json_doc)
     self.assertEqual(external_value, "baz")
Exemple #9
0
def get_export_data(config, properties, case_trigger_info):
    export_data = {}
    for property_, value_source_config in config.items():
        value_source = as_value_source(value_source_config)
        if (property_ in properties and value_source.can_export
                and value_source.get_value(case_trigger_info)):
            export_data[property_] = value_source.get_value(case_trigger_info)
    return export_data
 def test_no_values(self):
     json_doc = {"foo": {"bar": "baz"}}
     value_source = as_value_source({
         "case_property": "bar",
         "jsonpath": "foo.qux",
     })
     external_value = value_source.get_import_value(json_doc)
     self.assertIsNone(external_value)
Exemple #11
0
 def test_relationship(self):
     value_source = as_value_source({
         'supercase_value_source': {
             'case_property': 'foo'
         },
         'relationship': 'extension',
     })
     self.assertIsInstance(value_source, SupercaseValueSource)
Exemple #12
0
 def test_referenced_type(self):
     value_source = as_value_source({
         'supercase_value_source': {
             'case_property': 'foo'
         },
         'referenced_type': 'bar',
     })
     self.assertIsInstance(value_source, SupercaseValueSource)
Exemple #13
0
 def test_identifier(self):
     value_source = as_value_source({
         'supercase_value_source': {
             'case_property': 'foo'
         },
         'identifier': 'bar',
     })
     self.assertIsInstance(value_source, SupercaseValueSource)
 def test_many_values(self):
     json_doc = {"foo": [{"bar": "baz"}, {"bar": "qux"}]}
     value_source = as_value_source({
         "case_property": "bar",
         "jsonpath": "foo[*].bar",
     })
     external_value = value_source.get_import_value(json_doc)
     self.assertEqual(external_value, ["baz", "qux"])
 def test_doc_type(self):
     case_property = as_value_source({
         "doc_type": "CaseProperty",
         "case_property": "foo",
     })
     self.assertIsInstance(case_property, CaseProperty)
     self.assertEqual(case_property.case_property, "foo")
     with self.assertRaises(AttributeError):
         case_property.doc_type
Exemple #16
0
    def get_value_source(self) -> ValueSource:
        """
        Returns a ValueSource for building FHIR resources.
        """
        if self.value_source_config:
            return as_value_source(self.value_source_config)

        if not (self.case_property and self.jsonpath):
            raise ConfigurationError(
                'Unable to set FHIR resource property value without case '
                'property and JSONPath.')
        value_source_config = {
            'case_property': self.case_property.name,
            'jsonpath': self.jsonpath,
        }
        if self.value_map:
            value_source_config['value_map'] = self.value_map
        return as_value_source(value_source_config)
 def test_with_form_user_ancestor_location_field_doc_type(self):
     json_object = as_value_source({
         "doc_type":
         "FormUserAncestorLocationField",
         "form_user_ancestor_location_field":
         "dhis_id",
     })
     self.assertIsInstance(json_object, FormUserAncestorLocationField)
     self.assertEqual(json_object.form_user_ancestor_location_field,
                      "dhis_id")
 def test_deserialize(self):
     """
     deserialize() should convert from external data type to CommCare
     data type
     """
     one = as_value_source({
         "value": 1.0,
         "value_data_type": COMMCARE_DATA_TYPE_DECIMAL,
         "commcare_data_type": COMMCARE_DATA_TYPE_TEXT,
         "external_data_type": COMMCARE_DATA_TYPE_INTEGER,
     })
     self.assertEqual(one.deserialize("foo"), '1')
def get_encounter_datetime_value_sources(
        repeater: OpenmrsRepeater) -> List[ValueSource]:
    value_sources = []
    for form_config in repeater.openmrs_config.form_configs:
        encounter_datetime_config = form_config.openmrs_start_datetime
        if encounter_datetime_config and "case_property" in encounter_datetime_config:
            value_source = as_value_source(encounter_datetime_config)
            if value_source.can_import:
                if not value_source.jsonpath:
                    value_source.jsonpath = "encounterDateTime"
                value_sources.append(value_source)
    return value_sources
 def test_get_commcare_value(self):
     """
     get_commcare_value() should convert from value data type to
     CommCare data type
     """
     one = as_value_source({
         "value": 1.0,
         "value_data_type": COMMCARE_DATA_TYPE_DECIMAL,
         "commcare_data_type": COMMCARE_DATA_TYPE_INTEGER,
         "external_data_type": COMMCARE_DATA_TYPE_TEXT,
     })
     self.assertEqual(one.get_commcare_value('foo'), 1)
 def _get_values_for_concept(self, form_config):
     values_for_concept = {}
     for obs in form_config.openmrs_observations:
         if not obs.concept:
             # Skip ObservationMappings for importing all observations.
             continue
         value_source = as_value_source(obs.value)
         if value_source.can_export and not is_blank(
                 value_source.get_value(self.info)):
             values_for_concept[obs.concept] = [
                 value_source.get_value(self.info)
             ]
     return values_for_concept
def get_diagnosis_mappings(
        repeater: OpenmrsRepeater
) -> DefaultDict[str, List[ObservationMapping]]:
    diag_mappings = defaultdict(list)
    for form_config in repeater.openmrs_config.form_configs:
        for diag_mapping in form_config.bahmni_diagnoses:
            value_source = as_value_source(diag_mapping.value)
            if (value_source.can_import
                    and (diag_mapping.case_property
                         or diag_mapping.indexed_case_mapping)):
                concept = diag_mapping.concept or None
                diag_mappings[concept].append(diag_mapping)
    return diag_mappings
 def run(self):
     """
     Returns WorkflowTasks for creating and updating OpenMRS patient identifiers.
     """
     subtasks = []
     existing_patient_identifiers = {
         identifier['identifierType']['uuid']:
         (identifier['uuid'], identifier['identifier'])
         for identifier in self.patient['identifiers']
     }
     for patient_identifier_type, dict_ in self.openmrs_config.case_config.patient_identifiers.items(
     ):
         value_source = as_value_source(dict_)
         if not value_source.can_export:
             continue
         if patient_identifier_type == PERSON_UUID_IDENTIFIER_TYPE_ID:
             # Don't try to sync the OpenMRS person UUID; It's not a
             # user-defined identifier and it can't be changed.
             continue
         identifier = value_source.get_value(self.info)
         # If the patient is new, and its case property that
         # corresponds to the identifier is blank, then the
         # patient's identifier will have been generated by
         # repeater_helpers.generate_identifier(). The case will have
         # been updated by repeater_helpers.save_match_ids() but
         # self.info will not contain the newly-generated identifier.
         # `identifier` will be None. Don't try to update the
         # patient's identifier to None; it's already set correctly.
         if not identifier:
             continue
         if patient_identifier_type in existing_patient_identifiers:
             identifier_uuid, existing_identifier = existing_patient_identifiers[
                 patient_identifier_type]
             if identifier != existing_identifier:
                 subtasks.append(
                     UpdatePatientIdentifierTask(self.requests,
                                                 self.patient['uuid'],
                                                 identifier_uuid,
                                                 patient_identifier_type,
                                                 identifier,
                                                 existing_identifier))
         else:
             subtasks.append(
                 CreatePatientIdentifierTask(self.requests,
                                             self.patient['uuid'],
                                             patient_identifier_type,
                                             identifier))
     return subtasks
Exemple #24
0
 def get_identifiers():
     identifiers = []
     for patient_identifier_type, value_source_config in case_config.patient_identifiers.items(
     ):
         value_source = as_value_source(value_source_config)
         if (patient_identifier_type != PERSON_UUID_IDENTIFIER_TYPE_ID
                 and value_source.can_export):
             identifier = (value_source.get_value(info)
                           or generate_identifier(requests,
                                                  patient_identifier_type))
             if identifier:
                 identifiers.append({
                     'identifierType': patient_identifier_type,
                     'identifier': identifier
                 })
     return identifiers
    def test_as_value_source(self):
        @attr.s(auto_attribs=True, kw_only=True)
        class StringValueSource(ValueSource):
            test_value: str

            @classmethod
            def get_schema_params(cls):
                (schema, *other_args), kwargs = super().get_schema_params()
                schema.update({"test_value":
                               Use(str)})  # Casts value as string
                return (schema, *other_args), kwargs

        data = {"test_value": 10}
        value_source = as_value_source(data)
        self.assertEqual(data, {"test_value": 10})
        self.assertIsInstance(value_source, StringValueSource)
        self.assertEqual(value_source.test_value, "10")
Exemple #26
0
def get_values_for_concept(form_config, info):
    """
    Returns a dictionary mapping OpenMRS concept UUIDs to lists of
    values. Each value will be exported as a separate Observation.
    """
    values_for_concept = defaultdict(list)
    for obs in form_config.openmrs_observations:
        if obs.concept == ALL_CONCEPTS:
            # ALL_CONCEPTS is a special value for importing all
            # Observations as extension cases. It's not applicable here.
            continue
        value_source = as_value_source(obs.value)
        if value_source.can_export and not is_blank(
                value_source.get_value(info)):
            values_for_concept[obs.concept].append(
                value_source.get_value(info))
    return values_for_concept
def get_observation_mappings(
        repeater: OpenmrsRepeater
) -> DefaultDict[str, List[ObservationMapping]]:
    obs_mappings = defaultdict(list)
    for form_config in repeater.openmrs_config.form_configs:
        for obs_mapping in form_config.openmrs_observations:
            value_source = as_value_source(obs_mapping.value)
            if (value_source.can_import
                    and (obs_mapping.case_property
                         or obs_mapping.indexed_case_mapping)):
                # If obs_mapping.concept is "" or None, the mapping
                # should apply to any concept
                concept = obs_mapping.concept or None

                # It's possible that an OpenMRS concept appears more
                # than once in form_configs. We are using a
                # defaultdict(list) so that earlier definitions
                # don't get overwritten by later ones:
                obs_mappings[concept].append(obs_mapping)
    return obs_mappings
Exemple #28
0
def get_case_block_for_indexed_case(
    mapping: ObservationMapping,
    external_data: dict,
    parent_case_attrs: CaseAttrs,
) -> CaseBlock:
    parent_case_id, parent_case_type, default_owner_id = parent_case_attrs

    relationship = mapping.indexed_case_mapping.relationship
    case_block_kwargs = {
        "index": {
            mapping.indexed_case_mapping.identifier: IndexAttrs(
                parent_case_type,
                parent_case_id,
                relationship,
            )
        },
        "update": {}
    }
    for value_source_config in mapping.indexed_case_mapping.case_properties:
        value_source = as_value_source(value_source_config)
        value = value_source.get_import_value(external_data)
        if value_source.case_property in CASE_BLOCK_ARGS:
            case_block_kwargs[value_source.case_property] = value
        else:
            case_block_kwargs["update"][value_source.case_property] = value

    case_id = uuid.uuid4().hex
    case_type = mapping.indexed_case_mapping.case_type
    case_block_kwargs.setdefault("owner_id", default_owner_id)
    if not case_block_kwargs["owner_id"]:
        raise ConfigurationError(_(
            f'Unable to determine mobile worker to own new "{case_type}" '
            f'{relationship} case or parent case "{parent_case_id}"'
        ))
    case_block = CaseBlock(
        create=True,
        case_id=case_id,
        case_type=case_type,
        **case_block_kwargs
    )
    return case_block
 def run(self):
     """
     Returns WorkflowTasks for creating and updating OpenMRS person attributes.
     """
     subtasks = []
     existing_person_attributes = {
         attribute['attributeType']['uuid']:
         (attribute['uuid'], attribute['value'])
         for attribute in self.attributes
     }
     for person_attribute_type, value_source_dict in self.openmrs_config.case_config.person_attributes.items(
     ):
         value_source = as_value_source(value_source_dict)
         if not value_source.can_export:
             continue
         value = value_source.get_value(self.info)
         if person_attribute_type in existing_person_attributes:
             attribute_uuid, existing_value = existing_person_attributes[
                 person_attribute_type]
             if value != existing_value:
                 if value in ("", None):
                     subtasks.append(
                         DeletePersonAttributeTask(self.requests,
                                                   self.person_uuid,
                                                   attribute_uuid,
                                                   person_attribute_type,
                                                   existing_value))
                 else:
                     subtasks.append(
                         UpdatePersonAttributeTask(self.requests,
                                                   self.person_uuid,
                                                   attribute_uuid,
                                                   person_attribute_type,
                                                   value, existing_value))
         else:
             subtasks.append(
                 CreatePersonAttributeTask(self.requests, self.person_uuid,
                                           person_attribute_type, value))
     return subtasks
Exemple #30
0
    def test_set_external_data(self):
        value_source_configs = [
            {
                'case_property': 'name',
                'jsonpath': '$.name[0].text',
            },
            {
                'subcase_value_source': {
                    'case_property': 'given_names',
                    # Use counter1 to skip the name set by the parent case
                    'jsonpath': '$.name[{counter1}].given[0]',
                },
                'case_types': ['person_name'],
            },
            {
                'subcase_value_source': {
                    'case_property': 'family_name',
                    'jsonpath': '$.name[{counter1}].family',
                },
                'case_types': ['person_name'],
            }
        ]

        external_data = {}
        case_trigger_info = get_case_trigger_info_for_case(
            self.host_case,
            value_source_configs,
        )
        for value_source_config in value_source_configs:
            value_source = as_value_source(value_source_config)
            value_source.set_external_value(external_data, case_trigger_info)

        name = external_data['name']
        self.assertIn({'text': 'Ted'}, name)
        self.assertIn({
            'given': ['Theodore John'],
            'family': 'Kaczynski'
        }, name)
        self.assertIn({'given': ['Unabomber']}, name)