def get_task(info, form_json, form_config_dict):
    return CreateVisitsEncountersObsTask(
        requests=None,
        domain="test-domain",
        info=info,
        form_json=form_json,
        openmrs_config=OpenmrsConfig.wrap({
            "case_config": {},
            "form_configs": [form_config_dict],
        }),
        person_uuid="test-person_uuid",
    )
def test_concept_directions():
    form_json = {
        "form": {
            "@xmlns": "http://openrosa.org/formdesigner/9ECA0608-307A-4357-954D-5A79E45C3879",
            "pneumonia": "no",
            "malnutrition": "no",
        }
    }
    form_config_dict = get_form_config_dict()
    openmrs_config = OpenmrsConfig.wrap({
        "case_config": {},
        "form_configs": [form_config_dict]
    })
    info = CaseTriggerInfo(
        domain="test-domain",
        case_id="c0ffee",
        form_question_values={
            "/data/pneumonia": "no",
            "/data/malnutrition": "no",
        }
    )
    task = CreateVisitsEncountersObsTask(
        requests=None,
        domain="test-domain",
        info=info,
        form_json=form_json,
        openmrs_config=openmrs_config,
        person_uuid="test-person_uuid",
    )
    values_for_concept = task._get_values_for_concept(
        OpenmrsFormConfig.wrap(form_config_dict)
    )
    eq(values_for_concept, {
        # "direction": "out"
        'e7fdcd25-6d11-4d85-a80a-8979785f0f4b': ['eea8e4e9-4a91-416c-b0f5-ef0acfbc51c0'],
        # "direction": null, or not specified
        '4000cf24-8fab-437d-9950-ea8d9bb05a09': ['eea8e4e9-4a91-416c-b0f5-ef0acfbc51c0'],
        # "direction": "in" should be missing
    })
Beispiel #3
0
def send_openmrs_data(requests, domain, form_json, openmrs_config,
                      case_trigger_infos):
    """
    Updates an OpenMRS patient and (optionally) creates visits.

    This involves several requests to the `OpenMRS REST Web Services`_. If any of those requests fail, we want to
    roll back previous changes to avoid inconsistencies in OpenMRS. To do this we define a workflow of tasks we
    want to do. Each workflow task has a rollback task. If a task fails, all previous tasks are rolled back in
    reverse order.

    :return: A response-like object that can be used by Repeater.handle_response(),
             RepeatRecord.handle_success() and RepeatRecord.handle_failure()


    .. _OpenMRS REST Web Services: https://wiki.openmrs.org/display/docs/REST+Web+Services+API+For+Clients
    """
    warnings = []
    errors = []
    for info in case_trigger_infos:
        assert isinstance(info, CaseTriggerInfo)
        try:
            patient = get_patient(requests, domain, info, openmrs_config)
        except (RequestException, HTTPError) as err:
            errors.append(
                _("Unable to create an OpenMRS patient for case "
                  f"{info.case_id!r}: {err}"))
            continue
        if patient is None:
            warnings.append(
                f"CommCare case '{info.case_id}' was not matched to a "
                f"patient in OpenMRS instance '{requests.base_url}'.")
            continue

        # case_trigger_infos are info about all of the cases
        # created/updated by the form. Execute a separate workflow to
        # update each patient.
        workflow = [
            # Update name first. If the current name in OpenMRS fails
            # validation, other API requests will be rejected.
            UpdatePersonNameTask(requests, info, openmrs_config,
                                 patient['person']),
            # Update identifiers second. If a current identifier fails
            # validation, other API requests will be rejected.
            SyncPatientIdentifiersTask(requests, info, openmrs_config,
                                       patient),
            # Now we should be able to update the rest.
            UpdatePersonPropertiesTask(requests, info, openmrs_config,
                                       patient['person']),
            SyncPersonAttributesTask(requests, info, openmrs_config,
                                     patient['person']['uuid'],
                                     patient['person']['attributes']),
        ]
        if patient['person']['preferredAddress']:
            workflow.append(
                UpdatePersonAddressTask(requests, info, openmrs_config,
                                        patient['person']))
        else:
            workflow.append(
                CreatePersonAddressTask(requests, info, openmrs_config,
                                        patient['person']))
        workflow.append(
            CreateVisitsEncountersObsTask(requests, domain, info, form_json,
                                          openmrs_config,
                                          patient['person']['uuid']), )

        errors.extend(execute_workflow(workflow))

    if errors:
        requests.notify_error(
            f'Errors encountered sending OpenMRS data: {errors}')
        # If the form included multiple patients, some workflows may
        # have succeeded, but don't say everything was OK if any
        # workflows failed. (Of course most forms will only involve one
        # case, so one workflow.)
        return OpenmrsResponse(
            400, 'Bad Request',
            "Errors: " + pformat_json([str(e) for e in errors]))

    if warnings:
        return OpenmrsResponse(
            201, "Accepted",
            "Warnings: " + pformat_json([str(e) for e in warnings]))

    return OpenmrsResponse(200, "OK")