def get_program_dates(form_config, case_trigger_info):
    program = {}
    if form_config.enrollment_date:
        enrollment_date = get_value(form_config.enrollment_date,
                                    case_trigger_info)
        if enrollment_date:
            program["enrollmentDate"] = enrollment_date
    if form_config.incident_date:
        incident_date = get_value(form_config.incident_date, case_trigger_info)
        if incident_date:
            program["incidentDate"] = incident_date
    return program
示例#2
0
def create_relationships(
    requests,
    subcase_trigger_info,
    subcase_config,
    dhis2_entity_config,
):
    """
    Creates two relationships in DHIS2; one corresponding to a
    subcase-to-supercase relationship, and the other corresponding to a
    supercase-to-subcase relationship.
    """
    subcase_tei_id = get_value(subcase_config.tei_id, subcase_trigger_info)
    if not subcase_tei_id:
        raise Dhis2Exception(
            _('Unable to create DHIS2 relationship: The case {case} is not '
              'registered in DHIS2.').format(case=subcase_trigger_info))

    for rel_config in subcase_config.relationships_to_export:
        supercase = get_supercase(subcase_trigger_info, rel_config)
        supercase_config = get_case_config_for_case_type(
            supercase.type,
            dhis2_entity_config,
        )
        supercase_info = get_case_trigger_info_for_case(
            supercase,
            [supercase_config.tei_id],
        )
        supercase_tei_id = get_value(supercase_config.tei_id, supercase_info)
        if not supercase_tei_id:
            # The problem could be that the relationship is configured
            # in the CaseConfig for the subcase's case type, but there
            # is no CaseConfig for the supercase's case type.
            # Alternatively, registering the supercase in DHIS2 failed.
            raise ConfigurationError(
                _('Unable to create DHIS2 relationship: The case {case} is not '
                  'registered in DHIS2.').format(case=supercase_info))
        if rel_config.supercase_to_subcase_dhis2_id:
            create_relationship(
                requests,
                rel_config.supercase_to_subcase_dhis2_id,
                supercase_tei_id,
                subcase_tei_id,
            )
        if rel_config.subcase_to_supercase_dhis2_id:
            create_relationship(
                requests,
                rel_config.subcase_to_supercase_dhis2_id,
                subcase_tei_id,
                supercase_tei_id,
            )
示例#3
0
def _get_org_unit(config, case_trigger_info):
    org_unit_id = None
    if config.org_unit_id:
        org_unit_id = get_value(config.org_unit_id, case_trigger_info)
    if org_unit_id:
        return {'orgUnit': org_unit_id}
    return {}
示例#4
0
def get_enrollments(case_trigger_info, case_config):
    """
    DHIS2 allows tracked entity instances to be enrolled in programs
    without any events, but CommCare does not currently have a mechanism
    for that. Cases/TEIs are enrolled in a program when the first event
    in that program occurs.
    """
    case_org_unit = get_value(case_config.org_unit_id, case_trigger_info)
    programs_by_id = get_programs_by_id(case_trigger_info, case_config)
    enrollments = []
    for program_id, program in programs_by_id.items():
        enrollment = {
            "orgUnit": program["orgUnit"] or case_org_unit,
            "program": program_id,
            "status": program["status"],
            "events": program["events"],
        }
        if program.get("geometry"):
            enrollment["geometry"] = program["geometry"]
        if program.get("enrollmentDate"):
            enrollment["enrollmentDate"] = program["enrollmentDate"]
        if program.get("incidentDate"):
            enrollment["incidentDate"] = program["incidentDate"]
        enrollments.append(enrollment)
    return enrollments
示例#5
0
def _get_program_stage(config, case_trigger_info):
    program_stage_id = None
    if config.program_stage_id:
        program_stage_id = get_value(config.program_stage_id, case_trigger_info)
    if program_stage_id:
        return {'programStage': program_stage_id}
    return {}
def generate_value(requests, attr_id, generator_params, case_trigger_info):
    """
    Sends a request to DHIS2 to generate a value for a generated
    attribute, like a unique ID. DHIS2 may require parameters to
    generate the value. Returns the value.

    Example value source::

        {
            "case_property": "dhis2_unique_id",
            "is_generated": True,
            "generator_params": {
                "ORG_UNIT_CODE": {
                    "case_owner_ancestor_location_field": "dhis2_org_unit_code"
                }
            }
        }

    """
    params = {
        name: get_value(vsc, case_trigger_info)
        for name, vsc in generator_params.items()
    }
    response = requests.get(f"/api/trackedEntityAttributes/{attr_id}/generate",
                            params=params,
                            raise_for_status=True)
    return response.json()["value"]
def get_tracked_entity_instance_id(case_trigger_info, case_config):
    """
    Return the Tracked Entity instance ID stored in a case property (or
    other value source like a form question or a constant).
    """
    tei_id_value_source = case_config.tei_id
    return get_value(tei_id_value_source, case_trigger_info)
def register_tracked_entity_instance(requests, case_trigger_info, case_config):
    case_updates = {}
    tracked_entity = {
        "trackedEntityType": case_config.te_type_id,
        "orgUnit": get_value(case_config.org_unit_id, case_trigger_info),
        "attributes": [],
    }
    for attr_id, value_source_config in case_config.attributes.items():
        value, case_update = get_or_generate_value(requests, attr_id,
                                                   value_source_config,
                                                   case_trigger_info)
        set_te_attr(tracked_entity["attributes"], attr_id, value)
        case_updates.update(case_update)
    enrollments = get_enrollments(case_trigger_info, case_config)
    if enrollments:
        tracked_entity["enrollments"] = enrollments
    validate_tracked_entity(tracked_entity)
    endpoint = "/api/trackedEntityInstances/"
    response = requests.post(endpoint,
                             json=tracked_entity,
                             raise_for_status=True)
    summaries = response.json()["response"]["importSummaries"]
    if len(summaries) != 1:
        raise Dhis2Exception(
            _(f'{len(summaries)} tracked entity instances registered from '
              f'{case_trigger_info}.'))
    if case_config["tei_id"] and "case_property" in case_config["tei_id"]:
        case_property = case_config["tei_id"]["case_property"]
        tei_id = summaries[0]["reference"]
        case_updates[case_property] = tei_id
    if case_updates:
        save_case_updates(requests.domain_name, case_trigger_info.case_id,
                          case_updates)
示例#9
0
def _get_completed_date(config, case_trigger_info):
    completed_date = None
    if config.completed_date:
        completed_date = get_value(config.completed_date, case_trigger_info)
    if completed_date:
        return {'completedDate': completed_date}
    return {}
示例#10
0
def _get_coordinate(config, case_trigger_info):
    if config.event_location:
        location_string = get_value(config.event_location, case_trigger_info)

        if location_string:
            (lat, lon) = _dhis2_geolocation(location_string)
            return {'coordinate': {'latitude': lat, 'longitude': lon}}
    return {}
示例#11
0
def _get_datavalues(config, case_trigger_info):
    values = []
    for data_value in config.datavalue_maps:
        values.append({
            'dataElement': data_value.data_element_id,
            'value': get_value(data_value.value, case_trigger_info)
        })
    return {'dataValues': values}
def get_programs_by_id(case_trigger_info, case_config):
    programs_by_id = defaultdict(lambda: {"events": []})
    for form_config in case_config.form_configs:
        if case_trigger_info.form_question_values[
                '/metadata/xmlns'] != form_config.xmlns:
            continue
        event = get_event(case_trigger_info.domain,
                          form_config,
                          info=case_trigger_info)
        if event:
            program = programs_by_id[event["program"]]
            program["events"].append(event)
            program["orgUnit"] = get_value(form_config.org_unit_id,
                                           case_trigger_info)
            program["status"] = get_value(form_config.program_status,
                                          case_trigger_info)
            program.update(get_program_dates(form_config, case_trigger_info))
    return programs_by_id
示例#13
0
 def fetch_query_results(self, case_trigger_info):
     endpoint = "/api/trackedEntityInstances"
     query_filters = self.get_query_filters(case_trigger_info)
     if not query_filters:
         return []
     params = {
         "ou": get_value(self.case_config.org_unit_id, case_trigger_info),
         "filter": query_filters,
         "ouMode": "DESCENDANTS",
         "skipPaging": "true",
     }
     response = self.requests.get(endpoint,
                                  params=params,
                                  raise_for_status=True)
     return response.json()["trackedEntityInstances"]
def get_or_generate_value(requests, attr_id, value_source_config,
                          case_trigger_info):
    """
    Returns the value of ``value_source_config``, or a generated value
    returned by DHIS2, and a case update if the generated value should
    be saved in a case property.
    """
    case_update = {}

    # Instead of adding DHIS2-specific properties to the ValueSource
    # class, pop them here first.
    # Is the attribute generated by DHIS2 (e.g. unique IDs)?
    is_generated = value_source_config.pop("is_generated", False)
    # A dictionary of GET param name: value_source pairs
    generator_params = value_source_config.pop("generator_params", {})

    value = get_value(value_source_config, case_trigger_info)
    if is_blank(value) and is_generated:
        value = generate_value(requests, attr_id, generator_params,
                               case_trigger_info)
        if "case_property" in value_source_config:
            case_update[value_source_config["case_property"]] = value
    return value, case_update
示例#15
0
                     f'returned an unexpected response {response.status_code}: \r\n'
                     f'{response.content}'))
    return identifier


def find_or_create_patient(requests, domain, info, openmrs_config):
    case = CaseAccessors(domain).get_case(info.case_id)
    patient_finder = PatientFinder.wrap(
        openmrs_config.case_config.patient_finder)
    if patient_finder is None:
        return
    patients = patient_finder.find_patients(requests, case,
                                            openmrs_config.case_config)
    if len(patients) == 1:
        patient, = patients
    elif not patients and get_value(patient_finder.create_missing, info):
        patient = create_patient(requests, info, openmrs_config.case_config)
        if patient is None:
            # ``create_patient()`` will return None without an error
            # if the case has no basic data, not even a name. It
            # seems unlikely that the case is meant to be forwarded.
            # The user will get a warning, but not an error.
            return None
    else:
        # If PatientFinder can't narrow down the number of candidate
        # patients, don't guess. Just admit that we don't know.
        return None
    try:
        save_match_ids(case, openmrs_config.case_config, patient)
    except DuplicateCaseMatch as err:
        requests.notify_error(
示例#16
0
def _get_event_status(config, case_trigger_info):
    event_status = get_value(config.event_status, case_trigger_info)
    return {'status': event_status}
示例#17
0
def test_constant_false():
    info = CaseTriggerInfo('test-domain', '123456')
    assert_false(get_value(constant_false, info))
示例#18
0
def _get_event_date(config, case_trigger_info):
    event_date = get_value(config.event_date, case_trigger_info)
    return {'eventDate': event_date}