Пример #1
0
    def test_get_resource_id(self):
        """
        get_resource_id should query the API for the details of a named resource, and return the ID
        """
        if not SETTINGS['dhis2_enabled']:
            self.skipTest('DHIS2 is not configured')
        resources = {
            'Knights': [
                {
                    'name': 'Michael Palin',
                    'id': 'c0ffee'
                },
            ]
        }
        dhis2_api = Dhis2Api(SETTINGS['dhis2_host'],
                             SETTINGS['dhis2_username'],
                             SETTINGS['dhis2_password'])
        dhis2_api._request.get = Mock(return_value=('foo', resources))

        result = dhis2_api.get_resource_id('Knights', 'Who Say "Ni!"')

        dhis2_api._request.get.assert_called_with('Knights',
                                                  params={
                                                      'links': 'false',
                                                      'query': 'Who Say "Ni!"'
                                                  })
        self.assertEqual(result, 'c0ffee')
Пример #2
0
 def test_get_top_org_unit(self):
     """
     get_top_org_unit should return the name and ID of the top org unit
     """
     # TODO: Make sure get_top_org_unit navigates up tree of org units
     dhis2_api = Dhis2Api(SETTINGS['dhis2_host'],
                          SETTINGS['dhis2_username'],
                          SETTINGS['dhis2_password'])
     org_unit = dhis2_api.get_top_org_unit()
     self.assertTrue(bool(org_unit['name']))
     self.assertTrue(bool(org_unit['id']))
Пример #3
0
 def test_get_top_org_unit_settings(self):
     """
     get_top_org_unit should return the name and ID of the org unit specified in settings
     """
     if not SETTINGS['dhis2_top_org_unit_name']:
         self.skipTest('An org unit is not set in settings.py')
     dhis2_api = Dhis2Api(SETTINGS['dhis2_host'],
                          SETTINGS['dhis2_username'],
                          SETTINGS['dhis2_password'])
     org_unit = dhis2_api.get_top_org_unit()
     self.assertEqual(org_unit['name'], SETTINGS['dhis2_top_org_unit_name'])
     self.assertTrue(bool(org_unit['id']))
Пример #4
0
def get_children_only_theirs(settings):
    """
    Returns a list of child entities that are enrolled in Paediatric Nutrition
    Assessment and don't have CCHQ Case ID set.
    """
    dhis2_api = Dhis2Api(settings.dhis2['host'], settings.dhis2['username'],
                         settings.dhis2['password'],
                         settings.dhis2['top_org_unit_name'])
    for inst in dhis2_api.gen_instances_in_program(
            'Paediatric Nutrition Assessment'):
        if not inst.get(CCHQ_CASE_ID):
            yield inst
Пример #5
0
    def test_get_resource_id_none(self):
        """
        get_resource_id should return None if none found
        """
        if not SETTINGS['dhis2_enabled']:
            self.skipTest('DHIS2 is not configured')
        resources = {'Knights': []}
        dhis2_api = Dhis2Api(SETTINGS['dhis2_host'],
                             SETTINGS['dhis2_username'],
                             SETTINGS['dhis2_password'])
        dhis2_api._request.get = Mock(return_value=('foo', resources))

        result = dhis2_api.get_resource_id('Knights', 'Who Say "Ni!"')

        self.assertIsNone(result)
Пример #6
0
def pull_child_entities(settings, dhis2_children):
    """
    Create new child cases for nutrition tracking in CommCare.

    Sets external_id on new child cases, and CCHQ Case ID on DHIS2
    tracked entity instances. (CCHQ Case ID is initially unset because the
    case is new and does not exist in CommCare.)

    :param settings: DHIS2 settings, incl. relevant domain
    :param dhis2_children: A list of dictionaries of TRACKED_ENTITY (i.e.
                           "Child") tracked entities from the DHIS2 API where
                           CCHQ Case ID is unset

    This fulfills the third requirement of `DHIS2 Integration`_.


    .. _DHIS2 Integration: https://www.dropbox.com/s/8djk1vh797t6cmt/WV Sri Lanka Detailed Requirements.docx
    """
    dhis2_api = Dhis2Api(settings.dhis2['host'], settings.dhis2['username'],
                         settings.dhis2['password'],
                         settings.dhis2['top_org_unit_name'])
    for dhis2_child in dhis2_children:
        # Add each child separately. Although this is slower, it avoids problems if a DHIS2 API call fails
        # ("Instance" is DHIS2's friendly name for "id")
        logger.info('DHIS2: Syncing DHIS2 child "%s"', dhis2_child['Instance'])
        case = get_case_by_identifier(
            settings.domain,
            dhis2_child['Instance'])  # Get case by external_id
        if case:
            case_id = case['case_id']
        else:
            user = get_user_by_org_unit(settings.domain,
                                        dhis2_child['Org unit'],
                                        settings.dhis2['top_org_unit_name'])
            if not user:
                # No user is assigned to this or any higher organisation unit
                logger.error(
                    'DHIS2: Unable to import DHIS2 instance "%s"; there is no user at org unit "%s" or '
                    'above to assign the case to.', dhis2_child['Instance'],
                    dhis2_child['Org unit'])
                continue
            case_id = create_case_from_dhis2(dhis2_child, settings.domain,
                                             user)
        dhis2_child[CCHQ_CASE_ID] = case_id
        dhis2_api.update_te_inst(dhis2_child)
Пример #7
0
    def get_payload(self, repeat_record, form):
        from casexml.apps.case.xform import cases_referenced_by_xform

        logger.debug('DHIS2: Form domain "%s" XMLNS "%s"', form['domain'],
                     form['xmlns'])
        if form['xmlns'] not in (REGISTER_CHILD_XMLNS, GROWTH_MONITORING_XMLNS,
                                 RISK_ASSESSMENT_XMLNS):
            # This is not a form we care about
            raise IgnoreDocument

        settings = Dhis2Settings.for_domain(form['domain'])
        dhis2_api = Dhis2Api(settings.dhis2['host'],
                             settings.dhis2['username'],
                             settings.dhis2['password'],
                             settings.dhis2['top_org_unit_name'])
        cases = cases_referenced_by_xform(form)
        case = next(c for c in cases if c.type == CASE_TYPE)
        event = None

        if form['xmlns'] == REGISTER_CHILD_XMLNS:
            # Create a DHIS2 tracked entity instance from the form's case and
            # enroll in the nutrition assessment programme.
            logger.debug('DHIS2: Processing Register Child form')
            push_case(case, dhis2_api)
            #  We just need to enroll. No event to create
            raise IgnoreDocument

        elif form['xmlns'] == GROWTH_MONITORING_XMLNS:
            logger.debug('DHIS2: Processing Growth Monitoring form')
            if not getattr(case, 'external_id', None):
                logger.info(
                    'Register Child form must be processed before Growth Monitoring form'
                )
                return  # Try again later
            self._update_instance(dhis2_api, case)
            # Create a paediatric nutrition assessment event.
            program_id = dhis2_api.get_program_id(
                'Paediatric Nutrition Assessment')
            program_stage_id = dhis2_api.get_program_stage_id(
                'Nutrition Assessment')
            event = dhis2_api.form_to_event(program_id, form,
                                            NUTRITION_ASSESSMENT_EVENT_FIELDS,
                                            program_stage_id,
                                            case['external_id'])
Пример #8
0
def push_child_entities(settings, children):
    """
    Register child entities in DHIS2 and enroll them in the Pediatric
    Nutrition Assessment program.

    :param children: child_gmp cases where external_id is not set

    .. Note:: Once pushed, external_id is set to the ID of the
              tracked entity instance.

    This fulfills the second requirement of `DHIS2 Integration`_.


    .. _DHIS2 Integration: https://www.dropbox.com/s/8djk1vh797t6cmt/WV Sri Lanka Detailed Requirements.docx
    """
    dhis2_api = Dhis2Api(settings.dhis2['host'], settings.dhis2['username'],
                         settings.dhis2['password'],
                         settings.dhis2['top_org_unit_name'])
    # nutrition_id = dhis2_api.get_program_stage_id('Nutrition Assessment')
    for child in children:
        push_case(child, dhis2_api)
Пример #9
0
def fetch_org_units():
    """
    Synchronize DHIS2 Organization Units with local data.

    This data is used to fulfill the first requirement of
    `DHIS2 Integration`_: Allow mobile users in CommCareHQ to be
    associated with a particular DHIS2 Organisation Unit, so that when
    they create cases their new cases can be associated with that area
    or facility.


    .. _DHIS2 Integration: https://www.dropbox.com/s/8djk1vh797t6cmt/WV Sri Lanka Detailed Requirements.docx

    """
    for settings in Dhis2Settings.all_enabled():
        logger.info('DHIS2: Fetching org units for domain "%s" with "%s"',
                    settings.domain, settings.dhis2['host'])
        dhis2_api = Dhis2Api(settings.dhis2['host'],
                             settings.dhis2['username'],
                             settings.dhis2['password'],
                             settings.dhis2['top_org_unit_name'])
        Dhis2OrgUnit.objects = FixtureManager(Dhis2OrgUnit, settings.domain,
                                              ORG_UNIT_FIXTURES)
        our_org_units = {ou.id: ou for ou in Dhis2OrgUnit.objects.all()}
        their_org_units = {}
        # Add new org units
        for ou in dhis2_api.gen_org_units():
            their_org_units[ou['id']] = ou
            if ou['id'] not in our_org_units:
                logger.info('DHIS2: Adding org unit "%s"', ou['name'])
                org_unit = Dhis2OrgUnit(
                    id=ou['id'],
                    name=ou['name'],
                    parent_id=dhis2_api.get_org_unit_parent_id(ou['id']))
                org_unit.save()
        # Delete former org units
        for id_, ou in our_org_units.iteritems():
            if id_ not in their_org_units:
                logger.info('DHIS2: Deleting org unit "%s"', ou.name)
                ou.delete()
Пример #10
0
    def test_get_resource_id_raises(self):
        """
        get_resource_id should raise Dhis2ApiQueryError if multiple found
        """
        if not SETTINGS['dhis2_enabled']:
            self.skipTest('DHIS2 is not configured')
        resources = {
            'Knights': [{
                'name': 'Michael Palin',
                'id': 'c0ffee'
            }, {
                'name': 'John Cleese',
                'id': 'deadbeef'
            }]
        }
        dhis2_api = Dhis2Api(SETTINGS['dhis2_host'],
                             SETTINGS['dhis2_username'],
                             SETTINGS['dhis2_password'])
        dhis2_api._request.get = Mock(return_value=('foo', resources))

        with self.assertRaises(Dhis2ApiQueryError):
            dhis2_api.get_resource_id('Knights', 'Who Say "Ni!"')
Пример #11
0
 def test__fetch_tracked_entity_attributes(self):
     """
     _fetch_tracked_entity_attributes should extend _tracked_entity_attributes
     """
     te_attrs = {
         'trackedEntityAttributes': [
             {
                 'name': 'ham',
                 'id': 'deadbeef'
             },
             {
                 'name': 'spam',
                 'id': 'c0ffee'
             },
         ]
     }
     dhis2_api = Dhis2Api('http://example.com/dhis', 'user', 'p4ssw0rd')
     dhis2_api._request.get = Mock(return_value=te_attrs)
     keys_before = set(dhis2_api._tracked_entity_attributes.keys())
     dhis2_api._fetch_tracked_entity_attributes()
     keys_after = set(dhis2_api._tracked_entity_attributes.keys())
     fetched = keys_after - keys_before
     self.assertIn('ham', fetched)
     self.assertIn('spam', fetched)