Report module

Components

Repositories

Backend

https://github.com/openimis/openimis-be-report_py/

 

Frontend

There is no frontend module for reports

Dependencies

Backend

 

 

 

 

 

The openIMIS report module provides the core functionality of the reports but does not actually implement the reports. According to the modularity principles, each module is able to provide his own reports.

The reports are based on the ReportBro engine and are able to produce PDF files as well as XLSX (Microsoft Excel). The report templates can be visually edited in openIMIS to customize them.

The report backend module exposes the necessary API to list available reports, execute and edit them. Each report can have its own filters. This means that the openIMIS report module is generally not able to run all reports without some frontend customization. Just like in the backend, of course, each module can provide the specific requirements for its own reports.

Since the reports are running native code on the server with full access to the data, it is not possible to create a report entirely from the user interface.

Creating a report

Backend module

Report definitions

The starting point of the report module is the <app>/report.py file that contains the list of available reports with their configuration:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 report_definitions = [ { "name": "insuree_family_overview", "engine": 0, "default_report": insuree_family_overview.template, "description": "Simple claim report", "module": "insuree", "python_query": insuree_family_overview_query, "permission": ["131215"], }, { "name": "enrolled_families", "engine": 0, "default_report": enrolled_families.template, "description": "Enrolled families", "module": "insuree", "python_query": enrolled_families_query, "permission": ["131215"], }, ]

name

Name of the report that will be exposed

engine

0 for ReportBro, this is currently the only engine available

default_report

This specifies the report template to use when there is no local customization yet. This can be a simple string but we recommend to load that definition from a dedicated file

description

Human readable description of the report

module

The reports are exposed within a module, this should be the same as the current module name.

python_query

A report needs data. This specifies the Python function to be called to fetch the data and present it in the format required by the report template.

permission

This is an array of permissions that allow to run the report. They are exactly the same as in the various other features of the application.

Data fetching function

The above examples use two versions of the same report, one using the stored procedure, the other using native Python code.

The native function looks like this:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 def insuree_family_overview_query(user, date_from=None, date_to=None, **kwargs): ... if date_from: filters &= Q(validity_from__gte=date_from) ... queryset = ( Insuree.objects.filter(filters) .values( "chf_id", "other_names", "last_name", enroll_date=F("validity_from"), ... return {"data": list(queryset)}

The function will always get the logged user as first parameter. All subsequent parameters are named and optional. Their names correspond to the expected report parameters. Adding **kwargs allows the function to receive additional parameters without crashing and should be kept.

⚠️ The parameters are passed in the URL and have to be thoroughly checked before use. Passing them directly to the database could be a security issue.

This abstract shows that we’re filtering according to the parameters and then the query is run. The function returns a dictionary that will be passed to the template.

Keep in mind that ReportBro has limited support for data types. Passing complex objects in this dictionary might not be supported in the template. Refer to the ReportBro documentation and test the data in the Designer.

Alternatively, existing stored procedures can also be wrapped into reports like our second example:

1 2 3 4 5 6 7 8 9 10 11 12 from report.services import run_stored_proc_report def enrolled_families_query(user, date_from=None, date_to=None, location_id=None, **kwargs): data = run_stored_proc_report( "uspSSRSEnroledFamilies", LocationId=location_id, StartDate=date_from, EndDate=date_to, ) return { "data": data }

The parameters are the same but the run_stored_proc_report will call the specified stored procedure, converting the location_id parameter to LocationIdfor the stored procedure. The data returned by the procedure is passed as an array of dict. Using this method, the report template variables have to match the stored procedure output column names.

Backend API

The first GraphQL API allows to browse the available reports:

1 2 3 4 5 6 7 query useReportsQuery { reports { name module description } }

Running the actual report is a direct HTTP call:

https://<server>/api/report/insuree/enrolled_families/pdf/?date_from=2022-01-01

/api/report/

branches to the report module

insuree

name of the module containing the report that we want to run

enrolled_families

name of the report

pdf

format of the report, could be xlsx

?date_from=2022-01-01

report parameter

ReportBro template

The openIMIS Web interface includes the ReportBro Designer. To create a new report template, the easiest is to use that Designer and then to use the button to output the template to the browser console:

Here are some screenshots of the ReportBro Designer:

Data format definition
Main UI
Table with a grouping by Batch

Frontend

As described above, the logic for the parameters of reports can vary greatly and are therefore left for the frontend to handle.

First of all, the index.js should contain the report definition:

1 2 3 4 5 6 7 8 9 10 11 12 13 const DEFAULT_CONFIG = { "translations": [{ key: "en", messages: messages_en }], "reducers": [{ key: "insuree", reducer }], "reports": [ { key: "insuree_family_overview", component: InsureeFamilyOverviewReport, isValid: (values) => values.dateFrom && values.dateTo, getParams: (values) => ({ dateFrom: values.dateFrom, dateTo: values.dateTo, }), },

The definition is pretty self-explanatory with the report key corresponding to the backend report key, isValid for required parameters, getParams that formats the parameters to send to the backend.

Here is the example of the report component that puts it together:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 const InsureeFamilyOverviewReport = (props) => { const { values, setValues } = props; return ( <Grid container direction="column" spacing={1}> <Grid item> <PublishedComponent pubRef="core.DatePicker" value={values.dateFrom} module="insuree" required label="InsureeFamilyOverviewReport.dateFrom" onChange={(dateFrom) => setValues({ ...values, dateFrom })} /> </Grid> <Grid item> <PublishedComponent pubRef="core.DatePicker" value={values.dateTo} module="insuree" required label="InsureeFamilyOverviewReport.dateTo" onChange={(dateTo) => setValues({ ...values, dateTo })} /> </Grid> </Grid> ); }; export default InsureeFamilyOverviewReport;

Reports migration

Status

Technical name

French

Parameters

 

 

 

 

 

 

 

 

Policies - Primary Operational Indicators

Indicateurs opérationnels principaux - polices

Year/Quarter/Month

Region/District

Product

 

 

 

 

 

 

Claims - Primary Operational Indicators

Indicateurs opérationnels primaires-prestation

Year/Quarter/Month

Region/District

Product

HF Code

 

 

 

 

 

Product - Derived Operational Indicators

Indicateurs opérationnels dérivés

Year/Quarter/Month

Region/District

Product

HF Code

 

 

 

 

 

Contributions - Collection

Collecte de cotisations

Date range

Region/District

Product

Payment Type

 

 

 

 

 

Products - Sales

Vente des produits

Date range

Region/District

Product

 

 

 

 

 

 

Contributions -  Distribution

Distribution des cotisations

Year/Month

Region/District

Product

 

 

 

 

 

 

Admin - User Activity Report

Rapport d'activité de I'utilisateur

Date range

Username

Action

Entity

 

 

 

 

 

Enrolment Performance Indicators

Indicateurs de performance des affiliations

Year/Quarter/Month

Region/District

Product

 

 

 

 

 

 

Admin - Status of Registers

Situation des registres

Region/District

 

 

 

 

 

 

 

 

Insurees - Missing Photos

Assurés sans photos

Region/District

Agent

 

 

 

 

 

 

 

Payments - Category Overview

Apercu de la catégorie de paiement

Date range

Region/District

Product

 

 

 

 

 

 

Contributions - Matching Funds

Subventions

Date range

Region/District

Payer

Previous

 

 

 

 

 

Claims - Overview

Aperçu de la prestation

Date range

Region/District

Product

HF Code

Catchment Area

Claim Status

 

 

 

Policies - Percentage of Referrals

Pourcentage de référencement

Date range

Region/District

 

 

 

 

 

 

 

Insurees - Overview with Families

Apercu des familles et assurés

Date range

Region/District/Muni/Village

Status (Active/suspended)

 

 

 

 

 

 

Insurees - Pending enrolment

Assuré(e)s en attente

Date range

Region/District

Enrollment Officer

 

 

 

 

 

 

Policies - Renewals

Renouvellements

Date range

Region/District

Product

Enrollment Agent

Sorting

 

 

 

 

Insuree - Rejected Photos

Photos rejeté

Date range

 

 

 

 

 

 

 

 

Contributions - Payment

Payement de contribution

Date range

Region/District

Product

CN

Payment status

 

 

 

 

Payments - Control Number Assignment

Assignement du N° de contréle

Date range

Region/District

Submission status

Assignment status

 

 

 

 

 

Contributions - Overview Of Commissions

Synthése des Commissions

Year/Month

Region/District

Product

Payer

Enrollment Officer

Mode (cont paid/requested)

Commission level

Scope

 

Claims - History Report

Rapport d'historique des prestations

Date range

Region/District

Product

HF Code

Catchment Area

Claim Status

Insurance Number