Comparison between OpenMRS DHIS2 integrations

OpenMRS-DHIS2 integration is a crucial requirement when it comes to pandemics such as COVID-19. There are a few implementations done by several groups to integrate OpenMRS with DHIS2. This study mainly focused on the pros and cons of the following implementations.

  1. DHIS2 Connector module
  2. DHIS2 Reporting module
    a. adx branch
    b. GSoC 2020 Project
  3. UgandaEMR
Summary: Comparison between OpenMRS DHIS2 integrations

1. DHIS2 Connector module

The DHIS2 Connector module was built to post OpenMRS Period Indicator Report data to DHIS2. This module depends on the reporting module and uses the DHIS2 API to gather metadata. However, there’s no import functionality with the connector module. All the mappings including mappings of Data elements, disaggregation of DHIS2 should be done using the module. There’s a GUI to define those mappings using the drag and drop function. Users need to go through the mappings of DHIS2 and need to reflect them using that UI. Since it is a manual process it might lead to unexpected results.

The module supports only daily, weekly, and monthly period types. The date selector will be changed based on the period type of the DHIS2 Data Set; it gives users a friendly user interface. The module uses a specific XML format named DXF to send data to DHIS2. In addition to that, the module allows users to download the DXF output. One of the amazing features that come with the DHIS2 Connector Module is the scheduling option. With that, it enables automated reporting instead of manual pushings.


  • Scheduled reporting


  • It takes a lot of effort to define the DHIS2 mappings
  • Can’t export mapped metadata using the module
  • Supports only daily, weekly, and monthly period types

Source code:

Last updated: 15/12/2017

2. a. DHIS2 Reporting module — adx branch

The DHIS2 Reporting module is built on top of the DHIS2 Connector module. But the connector module is not a dependency of this module. The module depends on the OpenMRS reporting module. A core difference between this and the DHIS2 connector module is this module has an import feature that can import the mappings of the DHIS2 metadata. The definition of the dataset and the relevant metadata should be mapped in the special file named “Report Definition file”. Currently, this file should be written manually. The file includes the mappings of Datasets, Data Elements, and Category Option Combinations and the SQL queries that are mapped with Data Value templates.

An amazing feature that comes with the module is the export functionality. With that, it is possible to export mapped report definitions in XML format. The export file can reimport to another instance. It will be a great feature if all the Data Value Templates mapped using SQL queries. Otherwise, it will contain only the mapped name of the Cohort indicators. If there are multiple indicators that used the same cohort queries it will still have the same label of the cohort query. It will not throw any errors but leads to unexpected outputs. In addition to that, it’s incapable to export only a single report definition. The export file contains all imported report definitions.

The SQL support is a mesmerizing feature that comes with the module. The Data Value Templates can be mapped with provided SQL queries; so we can make the module independent from the reporting module. However, there is no built-in validation for SQL queries. Therefore the users should be careful when adding SQL queries. If the queries are wrong, the module will not throw any errors but leads to unexpected outputs.

The module uses CODE values instead of UIDs to generate the ADX output. It has the following Pros and cons;


  • The CODE values do not depend on the connected DHIS2 module.
    Since the CODE values do not depend on the connected DHIS2 module, it is easy to push data to multiple DHIS2 instances by just changing the server details. (Assuming the connected DHIS2 instances has dataset which maps with the correct CODEs)
  • The ADX output is much more human-readable.
    The CODE values are human-readable. However, a readable output is not a functional requirement because there’s no human interaction between sending generated data from OpenMRS to DHIS2. Moreover, the user cannot access the generated output. Even though there’s something wrong with the payload DHIS2 uses friendly error messages.


  • The user has to manually enter the code values within the DHIS2 instance.
    The CODE property is not a mandatory field in DHIS2 or an automatically generated value. Therefore the user has to manually enter the code values for each element.
  • The CODE values can be changed within DHIS2
    The CODE property is an editable field. If someone changes it from the dashboard it won’t reflect in the modules database. It might lead to unexpected outputs. However, this can be avoided by using proper standards.
  • DHIS2 throws some random errors
    When trying to push ADX data to DHIS2 using CODEs, DHIS2 is throwing 500 errors. (Need to find the root course) Hopefully, this is something that can be fixed within DHIS2 and will not be an issue in the future.

Anyway, when writing the Report Template file, the user should add UIDs of metadata as well. The UID’s stores in the DataBase tables and it uses as an identifier for metadata. Since UID’s are generated within DHIS2 and it is specific for a single DHIS2 instance, the module still partially depends on the DHIS2 instance. One of the best approaches to solve this is by using the CODE value as an identifier when persisting data to the DataBase instead of using UIDs.

Period Type is an essential concept in DHIS2. There are 18 Period Types available at DHIS2 (Including 4 alternative weekly types). Refer to the DHIS2 Documentation. The module supports only two Period Types; Monthly and Weekly (doesn’t support alternative weekly types) The Period Type Daily is available within the UI but not yet implemented on the backend. Furthermore, there are no validations for the periods through the backend or frontend. Therefore the user should pay additional attention when entering periods; otherwise, DHIS2 will throw errors when pushing data. This might be tricky if the user is new to these concepts.

In addition to that, the period type should be selected whenever the user posts data. (refer figure 1) This is something misleading because each and every dataset has there own defined period type. In this approach, the user has to know the period type of the dataset. One of the best approaches is to solve this is displaying the relevant date picker according to the Period Type of the dataset.

Post/ Preview option of the DHIS2 Reporting module — adx branch

This module is doing a fascinating job, but the code base is not much optimized in many places. Having a clean and efficient code is vital when it comes to programming. Moreover, the readability of the code is not that good. Ex: Bad variable names; missing method-level comments, long methods, unoptimized logics, commented code lines, Sout print statements, etc. Refer to this file for an example. When it comes to DataBase, the report UUID is mapped with the DHIS2 report definition as well as in all Data Value Templates, which is redundant. However, the module comes with test cases. It ensures the module runs without errors in the given cases.

The following bugs are identified in the module:

  • The mapped report elements always displayed as default (unmapped) in the mapping UI (but mapped at the backend)
  • Mapped with the label of the indicator definition
  • The DHIS2 password is shown in the UI
  • Reports indicated in red color from time to time when the report is fully mapped. (red = partially mapped / unmapped repot)
  • When choosing the Preview / Post module throws 500 — Internal server error.


  • Export functionality
  • Can add SQL Queries


  • The period selector is redundant
  • Only 2-period types are available
  • Period validations are not available
  • The codebase is a lack of clean and optimization
  • Since code values are using it might lead to unexpected results
  • Creating the Report Definition file is a manual task. Might leads to unexpected results.
  • Throws an error when trying to post Data.
  • Not yet implemented in production

Source code:

Last updated: 01/08/2018

2. b. DHIS2 Reporting module GSoC 2020 project

This approach is developed as a GSoC 2020 project. This project is also from the same module DHIS2 Reporting Module. The main goal of the project was to improve the existing project and make it back to the working state.

The key difference between this approach and the existing module is the behavior of the import functionality. Instead of writing a report definition file, this provides the ability to directly import a dataset from DHIS2 using the export feature of DHIS2. It prevents the mistakes that can happen at the creating manually written import files; which ensures that the imported metadata is in the correct format. Also, it reduces the work of writing custom import files and saves time. It is so helpful that a nontechnical person can easily work with the module.

Another good thing is every term used within the module is DHIS2 specific terms. It leads to make the user as well as the developers familiar with the module and avoiding misconceptions. Ex: The term Report Definition is replaced with DataSet.

The module uses the UID scheme instead of the CODE scheme that has cons as well as downsides.


  • No need to define CODE values for the metadata within DHIS2
    Since UID is auto-generated within DHIS2, there’s no need to add CODE values for each metadata.
  • Prevents the errors due to changing the code values later within DHIS2
    The CODE value can be changed within DHIS2 at any time. Since UIDs is are unique and immutable, it prevents the issues that can occur after changing code values. However, this can be avoided by using proper standards.


  • Highly depends on the connected DHIS2 instance
    The UID’s are randomly generated values from DHIS2 and can’t use the same payload with multiple instances. The user needs to import datasets separately and map it again if needs to push data to another instance.
  • The generated output is less human-readable
    Comparing the pros and cons of UIDs and CODE schemes seems the CODE scheme has more advantages than using the UID scheme. In such a case, fortunately, this module is capable to change it to the CODE scheme instead of using UIDs.

When it comes to Period Types, this module supports available DHIS2 Period Types except for Bi-weekly, Six-monthly, and Annual period types. The period selector UI changes according to the period type of the dataset and it makes it much easier for the user. In addition to that, the UI and the backend comes with validations.

This module uses the same mechanism as the adx branch’s implementation to map Data Value templates. Mapping the dataset with a period indicator report and Data values with report indicators. Instead of storing labels of cohorts, this uses the UUIDs of them. However, both approaches seem wrong since both of them can be repeated. Especially when using indicators. One of the best approaches might be storing the label of the report indicator and adding a friendly message to the user to have unique indicator names within a report. If a report has multiple indicators with the same name we can display a friendly message in the mapping UI.

The module has rewritten the inefficient logics to make it optimized at a significant level than the previous implementation. All the irrelevant Sout prints and irrelevant commented codes have been removed during the rewrite to make the codebase clean. However, the test cases are not available yet.

The module doesn’t have the ability to add SQL queries. Because of that, this module is fully dependant on the reporting module. If the user needs to add SQL queries they have to use the SQL query facility of the reporting module.

The method doesn’t have an export functionality. Since DHIS2 has a great export functionality there’s no significant requirement to reimplement it again within the module. Whenever the user needs to import metadata in another instance, the user can simply export the metadata within the DHIS2 instance and upload it to the instance. But, there’s no way to export mappings of DataValues from an OpenMRS instance to another.


  • DHIS2 friendly terms
  • Import datasets directly from DHIS2
  • Period type is automatically selected according to the defined period type of the dataset
  • Validated period ranges
  • Supports multiple period Types
  • Reduce manual work
  • Prevents the possible issues that can happen with manual work
  • Easy to handle by Non-Technical person


  • Can’t export mapped metadata using the module
  • SQL queries aren’t available — Highly depends with the OpenMRS Reporting module
  • Highly depends on the connected DHIS2 instance
  • Supports one DHIS2 instance at a time
  • Not yet implemented in production

Source code:

Last updated: 14/08/2020

3. Uganda EMR

Uganda EMR is endorsed by the Ministry of Health of Uganda as one of the national EMR systems. It is built on top of the OpenMRS Reference Application 2.10.x and installed in nearly 1000 sites in Uganda. They have implemented an impressive up and running DHIS integration in UgandaEMR.

The approach is quite different than other implementations. There’s no separate module for achieving this task and there’s no UI or an option to map reports with datasets and Data Value Templates; the CODE values are pre-built with the reporting module. It uses a mediator named UgISL (Uganda InterOperability Service Layer) to send data to DHIS2. The UgISL is converting code values to UIDs before sending the payload to DHIS2. It uses a special standardized format named UgEMR-eDX JSON format to exchange data between the interfaces. Since the Categories and Category Option CODEs are hardcoded, it takes much effort to add new categories or category options, etc. Furthermore, there’s no option to select the Period Type for a report. Users have to enter a manual date range.

A screenshot from UgandaEMR’s send to DHIS2 option


  • The category and category option codes are built within the system
  • Validates the payload before sending to DHIS2


  • Hard to add new categories/category options
  • Period Types are not available
  • Need a mediator to send data to DHIS2

Source code: N/A
Last updated: N/A

Let’s get connected

Follow/connect with me anytime.