Overview

Reporting Service is a service running independently on separate server. The main objective of this service is to provide a common framework for generating reports. This service loads the report configuration from a yaml file at the run time and provides the report details by using couple of API’s.

Pre-requisites

Before you proceed with the documentation, make sure the following pre-requisites are met -

Key Functionalities

Configuration Details

Definitions:

  1. Config file

  2. API

  3. Inline-table

How to Use:

Call the MDMS or any other API with the post method

  1. Configuring the post object in the yaml itself like below.
    externalService:

  2. Keep the post object in a seperate json file externally and call at runtime.

Sample yaml configuration :

ReportDefinitions:
- reportName: EmployeeReport
  decryptionPathId: EmployeeReport
  summary: Fetches employee data based on provided search parameters
  version: 1.0.0
  moduleName: hrms
  externalService:
  - entity: $.MdmsRes.common-masters.Department
    apiURL: http://egov-mdms-service:8080/egov-mdms-service/v1/_get?moduleName=common-masters&masterName=Department&tenantId=$tenantId
    keyOrder: name,code
    tableName: tbl_def_dept
  - entity: $.MdmsRes.common-masters.Designation
    apiURL: http://egov-mdms-service:8080/egov-mdms-service/v1/_get?moduleName=common-masters&masterName=Designation&tenantId=$tenantId
    keyOrder: name,code
    tableName: tbl_def_desig
  - entity: $.MdmsRes.ACCESSCONTROL-ROLES.roles
    apiURL: http://egov-mdms-service:8080/egov-mdms-service/v1/_get?moduleName=ACCESSCONTROL-ROLES&masterName=roles&tenantId=$tenantId
    keyOrder: name,code
    tableName: tbl_def_roles
  sourceColumns:
  - name: id
    label: reports.hrms.id
    type: string
    source: eg_hrms_employee
  - name: name
    label: reports.hrms.name
    type: string
    source: eg_hrms_employee
  - name: rolecodes
    label: reports.hrms.role
    type: stringarray
    source: eg_hrms_employee
    isLocalisationRequired: true
    localisationPrefix: ACCESSCONTROL_ROLES_ROLES_
  - name: designation
    label: reports.hrms.designation
    type: string
    source: eg_hrms_employee
    isLocalisationRequired: true
    localisationPrefix: COMMON_MASTERS_DESIGNATION_
  - name: department
    label: reports.hrms.department
    type: string
    source: eg_hrms_employee
    isLocalisationRequired: true
    localisationPrefix: COMMON_MASTERS_DEPARTMENT_
  - name: status
    label: reports.hrms.status
    type: string
    source: eg_hrms_employee
    isLocalisationRequired: true
    localisationPrefix: EGOV_HRMS_EMPLOYEESTATUS_
  searchParams:
  - name: ulb
    label: ULB
    type: singlevaluelist
    pattern: http://egov-mdms-service:8080/egov-mdms-service/v1/_get?tenantId=$tenantid&moduleName=tenant&masterName=tenants|$.MdmsRes.tenant.tenants.*.code|$.MdmsRes.tenant.tenants.*.name
    source: pt
    wrapper: true
    isMandatory: true
    searchClause: AND emp_data.tenantid = $ulb
  - name: status
    label: reports.hrms.status
    type: multivaluelist
    pattern: http://egov-mdms-service:8080/egov-mdms-service/v1/_get?tenantId=pb&moduleName=egov-hrms&masterName=EmployeeStatus|$.MdmsRes.egov-hrms.EmployeeStatus[?(@.active)].code|$.MdmsRes.egov-hrms.EmployeeStatus[?(@.active)].code
    source: seva
    isMandatory: false
    isLocalisationRequired: true
    localisationPrefix: EGOV_HRMS_EMPLOYEESTATUS_
    searchClause: AND emp_data.employeestatus IN ( $status )
  - name: role
    label: reports.hrms.role
    type: multivaluelist
    pattern: http://egov-mdms-service:8080/egov-mdms-service/v1/_get?tenantId=pb&moduleName=ACCESSCONTROL-ROLES&masterName=roles|$.MdmsRes.ACCESSCONTROL-ROLES.roles[?(@.code nin ['CITIZEN'])].code|$.MdmsRes.ACCESSCONTROL-ROLES.roles[?(@.code nin ['Citizen'])].code
    isMandatory: false
    isLocalisationRequired: true
    localisationPrefix: ACCESSCONTROL_ROLES_ROLES_
    searchClause: AND ARRAY[ $role ]::varchar[] && emp_data.rolecodes::varchar[]
  - name: deptname
    label: reports.pgr.dept.name
    type: multivaluelist
    source: eg_pgr_service
    pattern: http://egov-mdms-service:8080/egov-mdms-service/v1/_get?tenantId=$tenantid&moduleName=common-masters&masterName=Department|$.MdmsRes.common-masters.Department[*].code|$.MdmsRes.common-masters.Department[*].code
    isMandatory: false
    isLocalisationRequired: true
    localisationPrefix: COMMON_MASTERS_DEPARTMENT_
    searchClause: AND deptmap_def.code IN ($deptname)
  query: |
    WITH emp_data AS (SELECT DISTINCT
      ehe.id,
      ehe.uuid,
      ehe.tenantid,
      eu.name,
      (SELECT ARRAY(SELECT DISTINCT er.name from eg_user eu LEFT JOIN eg_userrole_v1 eur ON eu.id=eur.user_id AND eu.tenantid=eur.user_tenantid LEFT JOIN (VALUES tbl_def_roles) AS er(name,code) ON eur.role_code=er.code WHERE eu.uuid=ehe.uuid AND er.name IS NOT NULL)) as role,
      (SELECT ARRAY(SELECT DISTINCT er.code from eg_user eu LEFT JOIN eg_userrole_v1 eur ON eu.id=eur.user_id AND eu.tenantid=eur.user_tenantid LEFT JOIN (VALUES tbl_def_roles) AS er(name,code) ON eur.role_code=er.code WHERE eu.uuid=ehe.uuid AND er.code IS NOT NULL)) as rolecodes,
      eha.designation,
      eha.department,
      ehe.employeestatus
      FROM eg_hrms_employee ehe
      LEFT OUTER JOIN eg_user eu ON ehe.uuid = eu.uuid
      LEFT OUTER JOIN eg_hrms_assignment eha ON eu.uuid = eha.employeeid
      WHERE eu.active = true)
    SELECT emp_data.id as id,
      emp_data.name as name,
      ARRAY_TO_STRING(emp_data.role, ',') as role,
      ARRAY_TO_STRING(emp_data.rolecodes, ',') as rolecodes,
      desigmap_def.code as designation,
      deptmap_def.code as department,
      emp_data.employeestatus as status
    FROM emp_data
    INNER JOIN (VALUES tbl_def_dept) AS deptmap_def(name,code) ON deptmap_def.code=emp_data.department
    INNER JOIN (VALUES tbl_def_desig) AS desigmap_def(name,code) ON desigmap_def.code=emp_data.designation
    WHERE 1=1
  order by: ehe.id ASC

API Details

There are two API calls to report service ‘GET METADATA’ and ‘GET DATA’. 

GET METADATA:

This request to report service is made to get metadata for any report. The metadata contains information about search filters to be used in the report before actually sending request to get actual data. The user selected values are then used in GET_DATA request to filter data.

endpoint: /report/{moduleName}/{report name}/metadata/_get

moduleName:- It is used to define the names of module which contains current report

Body: Body consists the following:

  1. RequestInfo: Header details as used on the egov platform

  2. tenantId: tenantId of ULB

  3. reportName: name of the report to be used

Instance: 

URL: https://{domain name}/report/rainmaker-tl/metadata/_get

Body:

{
  "RequestInfo": {
    "apiId": "emp",
    "ver": "1.0",
    "ts": 1558889531536,
    "action": "create",
    "did": "1",
    "key": "abcdkey",
    "msgId": "20170310130900",
    "requesterId": "",
    "authToken": "{auth Token}"
  },
  "tenantId": "pb.amritsar",
  "reportName": "TradeWiseCollectionReport"
}

GET DATA:

This request to report service is used to get data for the report. Inputs given by user for filters are sent in request body. These filters values are used while querying data from DB.

endpoint: report/{moduleName}/{report name}/_get

moduleName: It is used to define the names of module which contains current repo

Body: Body consists the following:

  1. RequestInfo: Header details as used on the egov platform

  2. tenantId: tenantId of ULB

  3. reportName: name of the report to be used

  4. Array of searchparams corresponding to each of filled filters by the user. Each searchparam contains:-

    1. Name: name of filter

    2. Input: user selected value 

Instance: 

URL: https://{domain name}/report/rainmaker-tl/_get

Body:

{
  "RequestInfo": {
    "apiId": "emp",
    "ver": "1.0",
    "ts": 1558888480562,
    "action": "create",
    "did": "1",
    "key": "abcdkey",
    "msgId": "20170310130900",
    "requesterId": "",
    "authToken": "{auth Token}"
  },
  "tenantId": "pb.amritsar",
  "reportName": "TradeLicenseRegistryReport",
  "searchParams": [
    {
      "name": "fromDate",
      "input": 1556649000000
    }
  ]
}

Deployment Details

  1. Write configuration as per your requirement. Structure of the config file is explained under Configuration Details section

  2. Check-in the config file to a remote location preferably github, currently we check the files into this folder - https://github.com/egovernments/configs/tree/DEV/reports/config for dev and QA environement.

  3. Add module name and corresponding report path in same format as used in https://github.com/egovernments/configs/blob/DEV/reports/reportFileLocationsv1.txt

  4. Provide the absolute path of the file mentioned in Point 3  to DevOps, to add it to the file-read path of report service. The file will be added to  environment manifest file for it to be read at start-up of the application.

  5. Deploy the latest version of report service app.

  6. Add Role-Action mapping for API’s.

  7. Use the module-name as path parameters in the URL of the requests for report service with required request body.

Integration

Integration Scope

The report service provide a common framework to generate report and show the report details base on the search criteria.

Integration Benefits

Steps to Integration

  1. To integrate, host of echallan-services module should be overwritten in helm chart.

  2. The API should be mentioned in ACCESSCONTROL-ACTIONS-TEST. Refer below example

  3. Add Role-Action mapping for API’s.

    //This entry is for to decide the location of report on UI screen
    {
          "id": {Placeholder1},
          "name": "{Report name}",
          "url": "url",
          "displayName": "{Display name}",
          "orderNumber": 1,
          "parentModule": "",
          "enabled": true,
          "serviceCode": "",
          "code": "null",
          "path": "{path}", // here we need to mentioned the path
          "navigationURL": "{Naviagtion url}",
          "leftIcon": "action:assignment",
          "rightIcon": ""
        },
    
    //This entry is to add GET DATA API of the report
        {
          "id": {Placeholder2},
          "name": "MCollectCollectionReport",
          "url": "/report/{moduleName}/{report name}/_get",
          "displayName": "{Display Name}",
          "orderNumber": 0,
          "enabled": true,
          "serviceCode": "{Service code}",
          "code": "null",
          "path": "{path}"
        },
        
    //This entry is to add GET METADATA API of the report
        {
          "id": 2155,
          "name": "MCollectCollectionReport",
          "url": "/report/{moduleName}/{report name}/metadata/_get",
          "displayName": "Collection Report",
          "orderNumber": 1,
          "enabled": true,
          "serviceCode": "{Service code}",
          "code": "null",
          "path": "{path}"
        },

Note: Refer to the document Guidelines for supporting User Privacy in a module, for the changes required in report config to support encryption/decryption process.

Reference Docs

Doc Links

Title 

Link

API Swagger Documentation

Swagger Documentation

Local Setup

Local Setup

Guidelines for supporting User privacy changes in report service

https://digit-discuss.atlassian.net/wiki/spaces/DD/pages/2147385366/Guidelines+for+supporting+User+Privacy+in+a+module#Report-Configuration-Changes%3A