Exemple #1
0
def update_patient(repeater, patient_uuid):
    """
    Fetch patient from OpenMRS, submit case update for all mapped case
    properties.

    .. NOTE:: OpenMRS UUID must be saved to "external_id" case property

    """
    _assert(
        len(repeater.white_listed_case_types) == 1,
        'Unable to update patients from OpenMRS unless a single case type is '
        'specified. domain: "{}". repeater: "{}".'.format(
            repeater.domain, repeater.get_id
        )
    )
    case_type = repeater.white_listed_case_types[0]
    patient = get_patient_by_uuid(repeater.requests, patient_uuid)
    case, error = importer_util.lookup_case(
        EXTERNAL_ID,
        patient_uuid,
        repeater.domain,
        case_type=case_type,
    )
    if error == LookupErrors.NotFound:
        owner = get_one_commcare_user_at_location(repeater.domain, repeater.location_id)
        _assert(
            owner,
            'No users found at location "{}" to own patients added from '
            'OpenMRS atom feed. domain: "{}". repeater: "{}".'.format(
                repeater.location_id, repeater.domain, repeater.get_id
            )
        )
        case_block = get_addpatient_caseblock(case_type, owner, patient, repeater)

    else:
        _assert(
            error != LookupErrors.MultipleResults,
            # Multiple cases matched to the same patient.
            # Could be caused by:
            # * The cases were given the same identifier value. It could
            #   be user error, or case config assumed identifier was
            #   unique but it wasn't.
            # * PatientFinder matched badly.
            # * Race condition where a patient was previously added to
            #   both CommCare and OpenMRS.
            'More than one case found matching unique OpenMRS UUID. '
            'domain: "{}". case external_id: "{}". repeater: "{}".'.format(
                repeater.domain, patient_uuid, repeater.get_id
            )
        )
        case_block = get_updatepatient_caseblock(case, patient, repeater)

    if case_block:
        submit_case_blocks(
            [case_block.as_string()],
            repeater.domain,
            xmlns=XMLNS_OPENMRS,
            device_id=OPENMRS_ATOM_FEED_DEVICE_ID + repeater.get_id,
        )
def update_patient(repeater, patient_uuid):
    """
    Fetch patient from OpenMRS, submit case update for all mapped case
    properties.

    .. NOTE:: OpenMRS UUID must be saved to "external_id" case property

    """
    if len(repeater.white_listed_case_types) != 1:
        raise ConfigurationError(
            _(f'{repeater.domain}: {repeater}: Error in settings: Unable to update '
              f'patients from OpenMRS unless only one case type is specified.')
        )
    case_type = repeater.white_listed_case_types[0]
    try:
        patient = get_patient_by_uuid(repeater.requests, patient_uuid)
    except (RequestException, ValueError) as err:
        raise OpenmrsException(
            _(f'{repeater.domain}: {repeater}: Error fetching Patient '
              f'{patient_uuid!r}: {err}')) from err

    case, error = importer_util.lookup_case(
        EXTERNAL_ID,
        patient_uuid,
        repeater.domain,
        case_type=case_type,
    )
    if error == LookupErrors.NotFound:
        if not repeater.openmrs_config.case_config.import_creates_cases:
            # We can't create cases via the Atom feed, just update them.
            # Nothing to do here.
            return
        default_owner: Optional[CommCareUser] = repeater.first_user
        case_block = get_addpatient_caseblock(case_type, default_owner,
                                              patient, repeater)
    elif error == LookupErrors.MultipleResults:
        # Multiple cases have been matched to the same patient.
        # Could be caused by:
        # * The cases were given the same identifier value. It could
        #   be user error, or case config assumed identifier was
        #   unique but it wasn't.
        # * PatientFinder matched badly.
        # * Race condition where a patient was previously added to
        #   both CommCare and OpenMRS.
        raise DuplicateCaseMatch(
            _(f'{repeater.domain}: {repeater}: More than one case found '
              f'matching unique OpenMRS UUID. case external_id: "{patient_uuid}"'
              ))
    else:
        case_block = get_updatepatient_caseblock(case, patient, repeater)

    if case_block:
        submit_case_blocks(
            [case_block.as_text()],
            repeater.domain,
            xmlns=XMLNS_OPENMRS,
            device_id=OPENMRS_ATOM_FEED_DEVICE_ID + repeater.get_id,
        )
Exemple #3
0
def create_case(
    repeater: OpenmrsRepeater,
    patient_uuid: str,
) -> CaseBlock:

    case_type = repeater.white_listed_case_types[0]
    patient = get_patient_by_uuid(repeater.requests, patient_uuid)
    default_owner: Optional[CommCareUser] = repeater.first_user
    case_block = get_addpatient_caseblock(case_type, default_owner, patient, repeater)
    return case_block
Exemple #4
0
def update_patient(repeater, patient_uuid):
    """
    Fetch patient from OpenMRS, submit case update for all mapped case
    properties.

    .. NOTE:: OpenMRS UUID must be saved to "external_id" case property

    """
    _assert(
        len(repeater.white_listed_case_types) == 1,
        'Unable to update patients from OpenMRS unless a single case type is '
        'specified. domain: "{}". repeater: "{}".'.format(
            repeater.domain, repeater.get_id))
    case_type = repeater.white_listed_case_types[0]
    patient = get_patient_by_uuid(repeater.requests, patient_uuid)
    case, error = importer_util.lookup_case(
        EXTERNAL_ID,
        patient_uuid,
        repeater.domain,
        case_type=case_type,
    )
    if error == LookupErrors.NotFound:
        owner = get_one_commcare_user_at_location(repeater.domain,
                                                  repeater.location_id)
        _assert(
            owner,
            'No users found at location "{}" to own patients added from '
            'OpenMRS atom feed. domain: "{}". repeater: "{}".'.format(
                repeater.location_id, repeater.domain, repeater.get_id))
        case_block = get_addpatient_caseblock(case_type, owner, patient,
                                              repeater)

    else:
        _assert(
            error != LookupErrors.MultipleResults,
            # Multiple cases matched to the same patient.
            # Could be caused by:
            # * The cases were given the same identifier value. It could
            #   be user error, or case config assumed identifier was
            #   unique but it wasn't.
            # * PatientFinder matched badly.
            # * Race condition where a patient was previously added to
            #   both CommCare and OpenMRS.
            'More than one case found matching unique OpenMRS UUID. '
            'domain: "{}". case external_id: "{}". repeater: "{}".'.format(
                repeater.domain, patient_uuid, repeater.get_id))
        case_block = get_updatepatient_caseblock(case, patient, repeater)

    if case_block:
        submit_case_blocks(
            [case_block.as_text()],
            repeater.domain,
            xmlns=XMLNS_OPENMRS,
            device_id=OPENMRS_ATOM_FEED_DEVICE_ID + repeater.get_id,
        )
 def test_valid_uuid(self):
     patient = get_patient_by_uuid(self.requests, uuid='c83d9989-585f-4db3-bf55-ca1d0ee7c0af')
     self.assertEqual(patient, self.patient)
 def test_invalid_uuid(self):
     with self.assertRaises(ValueError):
         # OpenMRS UUIDs have "-" separators
         get_patient_by_uuid(self.requests, uuid='c83d9989585f4db3bf55ca1d0ee7c0af')
 def test_empty(self):
     patient = get_patient_by_uuid(self.requests, uuid='')
     self.assertIsNone(patient)
 def test_none(self):
     patient = get_patient_by_uuid(self.requests, uuid=None)
     self.assertIsNone(patient)
 def test_invalid_uuid(self):
     patient = get_patient_by_uuid(self.requests,
                                   uuid='c83d9989585f4db3bf55ca1d0ee7c0af')
     # OpenMRS UUIDs have "-" separators
     self.assertIsNone(patient)
Exemple #10
0
def import_encounter(repeater, encounter_uuid):
    # It's possible that an OpenMRS concept appears more than once in
    # form_configs. Use a defaultdict(list) so that earlier definitions
    # don't get overwritten by later ones:

    def fields_from_observations(observations, mappings):
        """
        Traverse a tree of observations, and return the ones mapped to
        case properties.
        """
        fields = {}
        for obs in observations:
            if obs['concept']['uuid'] in mappings:
                for mapping in mappings[obs['concept']['uuid']]:
                    fields[mapping.case_property] = mapping.value.deserialize(
                        obs['value'])
            if obs['groupMembers']:
                fields.update(
                    fields_from_observations(obs['groupMembers'], mappings))
        return fields

    response = repeater.requests.get(
        '/ws/rest/v1/bahmnicore/bahmniencounter/' + encounter_uuid,
        {'includeAll': 'true'},
        raise_for_status=True)
    encounter = response.json()

    case_property_updates = fields_from_observations(
        encounter['observations'], repeater.observation_mappings)

    if case_property_updates:
        case_blocks = []
        patient_uuid = encounter['patientUuid']
        case_type = repeater.white_listed_case_types[0]
        case, error = importer_util.lookup_case(
            EXTERNAL_ID,
            patient_uuid,
            repeater.domain,
            case_type=case_type,
        )
        if case:
            case_id = case.get_id

        elif error == LookupErrors.NotFound:
            # The encounter is for a patient that has not yet been imported
            patient = get_patient_by_uuid(repeater.requests, patient_uuid)
            owner = get_one_commcare_user_at_location(repeater.domain,
                                                      repeater.location_id)
            case_block = get_addpatient_caseblock(case_type, owner, patient,
                                                  repeater)
            case_blocks.append(case_block)
            case_id = case_block.case_id

        else:
            _assert(
                error != LookupErrors.MultipleResults,
                'More than one case found matching unique OpenMRS UUID. '
                'domain: "{}". case external_id: "{}". repeater: "{}".'.format(
                    repeater.domain, patient_uuid, repeater.get_id))
            return

        case_blocks.append(
            CaseBlock(
                case_id=case_id,
                create=False,
                update=case_property_updates,
            ))
        submit_case_blocks(
            [cb.as_text() for cb in case_blocks],
            repeater.domain,
            xmlns=XMLNS_OPENMRS,
            device_id=OPENMRS_ATOM_FEED_DEVICE_ID + repeater.get_id,
        )
Exemple #11
0
 def test_valid_uuid(self):
     patient = get_patient_by_uuid(self.requests, uuid='c83d9989-585f-4db3-bf55-ca1d0ee7c0af')
     self.assertEqual(patient, self.patient)
Exemple #12
0
 def test_invalid_uuid(self):
     with self.assertRaises(ValueError):
         # OpenMRS UUIDs have "-" separators
         get_patient_by_uuid(self.requests, uuid='c83d9989585f4db3bf55ca1d0ee7c0af')
Exemple #13
0
 def test_empty(self):
     patient = get_patient_by_uuid(self.requests, uuid='')
     self.assertIsNone(patient)
Exemple #14
0
 def test_none(self):
     patient = get_patient_by_uuid(self.requests, uuid=None)
     self.assertIsNone(patient)
Exemple #15
0
def import_encounter(repeater, encounter_uuid):
    # It's possible that an OpenMRS concept appears more than once in
    # form_configs. Use a defaultdict(list) so that earlier definitions
    # don't get overwritten by later ones:

    def fields_from_observations(observations, mappings):
        """
        Traverse a tree of observations, and return the ones mapped to
        case properties.
        """
        fields = {}
        for obs in observations:
            if obs['concept']['uuid'] in mappings:
                for mapping in mappings[obs['concept']['uuid']]:
                    fields[mapping.case_property] = mapping.value.deserialize(obs['value'])
            if obs['groupMembers']:
                fields.update(fields_from_observations(obs['groupMembers'], mappings))
        return fields

    response = repeater.requests.get(
        '/ws/rest/v1/bahmnicore/bahmniencounter/' + encounter_uuid,
        {'includeAll': 'true'},
        raise_for_status=True
    )
    encounter = response.json()

    case_property_updates = fields_from_observations(encounter['observations'], repeater.observation_mappings)

    if case_property_updates:
        case_blocks = []
        patient_uuid = encounter['patientUuid']
        case_type = repeater.white_listed_case_types[0]
        case, error = importer_util.lookup_case(
            EXTERNAL_ID,
            patient_uuid,
            repeater.domain,
            case_type=case_type,
        )
        if case:
            case_id = case.get_id

        elif error == LookupErrors.NotFound:
            # The encounter is for a patient that has not yet been imported
            patient = get_patient_by_uuid(repeater.requests, patient_uuid)
            owner = get_one_commcare_user_at_location(repeater.domain, repeater.location_id)
            case_block = get_addpatient_caseblock(case_type, owner, patient, repeater)
            case_blocks.append(case_block)
            case_id = case_block.case_id

        else:
            _assert(
                error != LookupErrors.MultipleResults,
                'More than one case found matching unique OpenMRS UUID. '
                'domain: "{}". case external_id: "{}". repeater: "{}".'.format(
                    repeater.domain, patient_uuid, repeater.get_id
                )
            )
            return

        case_blocks.append(CaseBlock(
            case_id=case_id,
            create=False,
            update=case_property_updates,
        ))
        submit_case_blocks(
            [cb.as_string() for cb in case_blocks],
            repeater.domain,
            xmlns=XMLNS_OPENMRS,
            device_id=OPENMRS_ATOM_FEED_DEVICE_ID + repeater.get_id,
        )