Example #1
0
 def save(self, domain):
     try:
         settings = Dhis2Settings.for_domain(domain.name)
         if settings is None:
             # Create settings
             settings = Dhis2Settings()
             settings.domain = domain.name
             settings.dhis2 = {
                 'enabled': self.cleaned_data['enabled'],
                 'host': self.cleaned_data['host'],
                 'username': self.cleaned_data['username'],
                 'password': self.cleaned_data['password'],
                 'top_org_unit_name': self.cleaned_data['top_org_unit_name'],
             }
             settings.save()
         else:
             # Update settings
             settings.dhis2.update({
                 'enabled': self.cleaned_data['enabled'],
                 'host': self.cleaned_data['host'],
                 'username': self.cleaned_data['username'],
                 'top_org_unit_name': self.cleaned_data['top_org_unit_name'],
             })
             # Only update the password if it has been set
             if self.cleaned_data['password']:
                 settings.dhis2['password'] = self.cleaned_data['password']
             settings.save()
         return True
     except Exception as err:  # TODO: What Exception?
         logger.error('Unable to save DHIS2 API settings: %s' % err)
         return False
Example #2
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()
Example #3
0
    def get_payload(self, repeat_record, form):
        if not Dhis2Settings.is_enabled_for_domain(form['domain']):
            return

        from casexml.apps.case.models import CommCareCase  # avoid circular import
        settings = Dhis2Settings.for_domain(form['domain'])
        dhis2_api = Dhis2Api(settings.dhis2.host, settings.dhis2.username, settings.dhis2.password,
                             settings.dhis2.top_org_unit_name)
        if form['xmlns'] == 'http://openrosa.org/formdesigner/b6a45e8c03a6167acefcdb225ee671cbeb332a40':
            # This is a growth monitoring form. It needs to be converted into
            # a paediatric nutrition assessment event.
            nutrition_id = dhis2_api.get_program_id('Paediatric Nutrition Assessment')
            event = dhis2_api.form_to_event(nutrition_id, form, NUTRITION_ASSESSMENT_EVENT_FIELDS)
            # If the form is not to be forwarded, the event will be None
            return json.dumps(event, default=json_serializer) if event else None

        elif form['xmlns'] == 'http://openrosa.org/formdesigner/39F09AD4-B770-491E-9255-C97B34BDD7FC':
            # This is a risk assessment form. It needs to be converted into a
            # risk assessment event.
            risk_id = dhis2_api.get_program_id('Underlying Risk Assessment')
            # Check whether the case needs to be enrolled in the Risk Assessment Program
            cases = CommCareCase.get_by_xform_id(form.get_id)
            if len(cases) != 1:
                # TODO: Fail permanently
                return None
            case = cases[0]
            if not case.get('external_id'):
                # This case has not yet been pushed to DHIS2.
                # TODO: Try again later
                return None
            # TODO: Test one-line alternative below with risk assessment forms
            # Either ...
            if not dhis2_api.enrolled_in(case['external_id'], 'Underlying Risk Assessment'):
                today = date.today().strftime('%Y-%m-%d')
                program_data = {dhis2_attr: case[cchq_attr]
                                for cchq_attr, dhis2_attr in RISK_ASSESSMENT_PROGRAM_FIELDS.iteritems()}
                dhis2_api.enroll_in_id(case['external_id'], risk_id, today, program_data)
            event = dhis2_api.form_to_event(risk_id, form, RISK_ASSESSMENT_EVENT_FIELDS)
            # ... or just ...
            # event = dhis2_api.form_to_event(risk_id, form, RISK_ASSESSMENT_EVENT_FIELDS, case['external_id'])
            # ...?
            return json.dumps(event, default=json_serializer) if event else None

        else:
            # This is not a form we care about
            return None
Example #4
0
def fetch_cases():
    """
    Import new child cases from DHIS2 for nutrition tracking
    """
    for settings in Dhis2Settings.all_enabled():
        logger.info('DHIS2: Fetching cases for domain "%s" from "%s"', settings.domain, settings.dhis2['host'])
        children = get_children_only_theirs(settings)
        pull_child_entities(settings, children)
Example #5
0
def fetch_cases():
    """
    Import new child cases from DHIS2 for nutrition tracking
    """
    for settings in Dhis2Settings.all_enabled():
        logger.info('DHIS2: Fetching cases for domain "%s" from "%s"',
                    settings.domain, settings.dhis2['host'])
        children = get_children_only_theirs(settings)
        pull_child_entities(settings, children)
    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'])

        elif form['xmlns'] == RISK_ASSESSMENT_XMLNS:
            logger.debug('DHIS2: Processing Risk Assessment form')
            if not getattr(case, 'external_id', None):
                logger.info('Register Child form must be processed before Risk Assessment form')
                return  # Try again later
            self._update_instance(dhis2_api, case)
            # Check whether the case needs to be enrolled in the Risk Assessment Program
            program_id = dhis2_api.get_program_id('Underlying Risk Assessment')
            if not dhis2_api.enrolled_in(case['external_id'], 'Underlying Risk Assessment'):
                today = json_format_date(date.today())
                program_data = {dhis2_attr: case[cchq_attr]
                                for cchq_attr, dhis2_attr in RISK_ASSESSMENT_PROGRAM_FIELDS.iteritems()}
                dhis2_api.enroll_in_id(case['external_id'], program_id, today, program_data)
            # Create a risk assessment event.
            program_stage_id = dhis2_api.get_program_stage_id('Underlying Risk Assessment')
            event = dhis2_api.form_to_event(program_id, form, RISK_ASSESSMENT_EVENT_FIELDS, program_stage_id,
                                            case['external_id'])

        return json.dumps(event, default=json_serializer)
Example #7
0
def sync_cases():
    """
    Create new child cases in CommCare for nutrition tracking, and associate
    CommCare child cases with DHIS2 child entities and enroll them in the
    Pediatric Nutrition Assessment and Underlying Risk Assessment programs.
    """
    for domain in Domain.get_all():
        settings = Dhis2Settings.for_domain(domain.name)
        if settings is None or not settings.is_enabled():
            continue

        children = get_children_only_theirs(settings)
        pull_child_entities(settings, children)

        children = gen_children_only_ours(domain.name)
        push_child_entities(settings, children)
Example #8
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'])
Example #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()
Example #10
0
def sync_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

    """
    # Loop through all enabled domains
    for domain in Domain.get_all():
        settings = Dhis2Settings.for_domain(domain.name)
        if settings is None or not settings.is_enabled():
            continue

        dhis2_api = Dhis2Api(settings.dhis2.host, settings.dhis2.username, settings.dhis2.password,
                             settings.dhis2.top_org_unit_name)
        # Is it a bad idea to read all org units into dictionaries and sync them ...
        their_org_units = {ou['id']: ou for ou in dhis2_api.gen_org_units_with_parents()}
        # ... or should we rather just drop all ours and import all theirs every time?
        org_unit_objects = FixtureManager(Dhis2OrgUnit, domain, ORG_UNIT_FIXTURES)
        our_org_units = {ou.id: ou for ou in org_unit_objects.all()}
        # Add new org units
        for id_, ou in their_org_units.iteritems():
            if id_ not in our_org_units:
                org_unit = Dhis2OrgUnit(id=id_, name=ou['name'], parent_id=ou['parent_id'])
                org_unit.save()
        # Delete former org units
        for id_, ou in our_org_units.iteritems():
            if id_ not in their_org_units:
                ou.delete()
Example #11
0
 def enabled_for_domain(domain):
     return Dhis2Settings.is_enabled_for_domain(domain)
Example #12
0
 def enabled_for_domain(domain):
     return Dhis2Settings.is_enabled_for_domain(domain)