Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KH-392: Added a Disbursement Report for Cambodia. #68

Merged
merged 10 commits into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@ It bundles two groups of reports:
* [MSPP: Antenatal](readme/MSPPantenatal.md) report
* [MSPP: Vaccination](readme/MSPPvaccination.md) report
* [MSPP: Child Care](readme/MSPPchildCareDiseases.md) report
* [Disbursement](readme/Disbursement.md) report
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package org.openmrs.module.commonreports.reports;

import static org.openmrs.module.commonreports.common.Helper.getStringFromResource;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.openmrs.Location;
import org.openmrs.module.commonreports.ActivatedReportManager;
import org.openmrs.module.initializer.api.InitializerService;
import org.openmrs.module.reporting.common.DateUtil;
import org.openmrs.module.reporting.common.MessageUtil;
import org.openmrs.module.reporting.dataset.definition.SqlDataSetDefinition;
import org.openmrs.module.reporting.evaluation.parameter.Parameter;
import org.openmrs.module.reporting.report.ReportDesign;
import org.openmrs.module.reporting.report.definition.ReportDefinition;
import org.openmrs.module.reporting.report.manager.ReportManagerUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class DisbursementReportManager extends ActivatedReportManager {

@Autowired
private InitializerService inizService;

@Override
public boolean isActivated() {
return inizService.getBooleanFromKey("report.disbursement.active", false);
}

@Override
public String getVersion() {
return "1.0.0-SNAPSHOT";
}

@Override
public String getUuid() {
return "72b05407-53d2-43e0-8ccc-ab6099dbe5ab";
}

@Override
public String getName() {
return MessageUtil.translate("commonreports.report.disbursement.reportName");
}

@Override
public String getDescription() {
return MessageUtil.translate("commonreports.report.disbursement.reportDescription");
}

private Parameter getStartDateParameter() {
String startDate = new SimpleDateFormat("yyyy-MM-dd").format(DateUtil.getStartOfMonth(new Date()));
return new Parameter("startDate", "Start Date", Date.class, null, DateUtil.parseDate(startDate, "yyyy-MM-dd"));
}

private Parameter getEndDateParameter() {
String endDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
return new Parameter("endDate", "End Date", Date.class, null, DateUtil.parseDate(endDate, "yyyy-MM-dd"));
}

private Parameter getLocationParameter() {
return new Parameter("locationList", "Visit Location", Location.class, List.class, null);
}

@Override
public List<Parameter> getParameters() {
List<Parameter> params = new ArrayList<Parameter>();
params.add(getStartDateParameter());
params.add(getEndDateParameter());
params.add(getLocationParameter());
return params;
}

@Override
public ReportDefinition constructReportDefinition() {

ReportDefinition rd = new ReportDefinition();

rd.setName(getName());
rd.setDescription(getDescription());
rd.setParameters(getParameters());
rd.setUuid(getUuid());

SqlDataSetDefinition sqlDsd = new SqlDataSetDefinition();
sqlDsd.setName(MessageUtil.translate("commonreports.report.disbursement.table.datasetName"));
sqlDsd.setDescription(MessageUtil.translate("commonreports.report.disbursement.table.datasetDescription"));

String sql = getStringFromResource("org/openmrs/module/commonreports/sql/disbursement.sql");
applyMetadataReplacements(sql);

sqlDsd.setSqlQuery(sql);
sqlDsd.addParameters(getParameters());

Map<String, Object> parameterMappings = new HashMap<String, Object>();
parameterMappings.put("startDate", "${startDate}");
parameterMappings.put("endDate", "${endDate}");
parameterMappings.put("locationList", "${locationList}");

rd.addDataSetDefinition(getName(), sqlDsd, parameterMappings);

return rd;
}

@Override
public List<ReportDesign> constructReportDesigns(ReportDefinition reportDefinition) {
ReportDesign reportDesign = ReportManagerUtil.createCsvReportDesign("77b6c2cb-4b96-47d8-bcde-b1b7f16f5670",
reportDefinition);
return Arrays.asList(reportDesign);
}

private String applyMetadataReplacements(String rawSql) {
Map<String, String> metadataReplacements = getMetadataReplacements();

for (String key : metadataReplacements.keySet()) {
rawSql = rawSql.replaceAll(":" + key, metadataReplacements.get(key));
}
return rawSql;
}

private Map<String, String> getMetadataReplacements() {
Map<String, String> map = new HashMap<String, String>();

map.put("ccsEncounterType", inizService.getValueFromKey("report.disbursement.ccs.encounter.type.uuid"));
map.put("ncdEncounterTypeUuid", inizService.getValueFromKey("report.disbursement.ncd.encounter.type.uuid"));
map.put("yesConceptUuid", inizService.getValueFromKey("report.disbursement.yes.concept.uuid"));
map.put("positiveConceptUuid", inizService.getValueFromKey("report.disbursement.positive.concept.uuid"));
map.put("viaDiagnosisQuestionConceptUuid",
inizService.getValueFromKey("report.disbursement.via.diagnosis.question.concept.uuid"));
map.put("followupQuestionConceptUuid",
inizService.getValueFromKey("report.disbursement.followup.question.concept.uuid"));
map.put("startedMedicationQuestionConceptUuid",
inizService.getValueFromKey("report.disbursement.started.medication.question.concept.uuid"));

return map;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
-- Patients aged 40 and above with NCD form filled out for the first time
SELECT
'Registered patients aged 40 and above that have had their NCD screening for the first time' AS 'Indicator',
CAST(COUNT(DISTINCT p.person_id) AS CHAR) AS 'Value'
FROM
encounter e
INNER JOIN
person p ON e.patient_id = p.person_id
WHERE
e.location_id in (:locationList)
AND e.encounter_datetime > :startDate
AND e.encounter_datetime < :endDate
AND e.encounter_type = (
SELECT encounter_type_id
FROM encounter_type s_et
WHERE s_et.uuid LIKE '422b7e0c-b8f3-4748-8e60-d6684315f141'
)
AND ROUND(DATEDIFF(e.encounter_datetime, p.birthdate) / 365.25, 0) >= 40
AND e.patient_id NOT IN (
SELECT patient_id
FROM encounter s_e
WHERE s_e.encounter_type = (
SELECT encounter_type_id
FROM encounter_type ss_et
WHERE ss_et.uuid LIKE '422b7e0c-b8f3-4748-8e60-d6684315f141'
)
AND s_e.encounter_datetime <= :startDate
)

UNION ALL

-- Women aged 30 to 49 years with CCS form filled out for the first time
SELECT
'Registered women aged 30 to 49 years that have had their CCS screening for the first time' AS 'Indicator',
CAST(COUNT(DISTINCT p.person_id) AS CHAR) AS 'Value'
FROM
encounter e
INNER JOIN
person p ON e.patient_id = p.person_id
WHERE
e.location_id in (:locationList)
AND e.encounter_datetime > :startDate
AND e.encounter_datetime < :endDate
AND e.encounter_type = (
SELECT encounter_type_id
FROM encounter_type s_et
WHERE s_et.uuid LIKE '3fd606b6-4c9d-4077-a532-c1ac58644ad2'
)
AND ROUND(DATEDIFF(e.encounter_datetime, p.birthdate) / 365.25, 0) BETWEEN 30 AND 49
AND e.patient_id NOT IN (
SELECT patient_id
FROM encounter s_e
WHERE s_e.encounter_type = (
SELECT encounter_type_id
FROM encounter_type ss_et
WHERE ss_et.uuid LIKE '3fd606b6-4c9d-4077-a532-c1ac58644ad2'
)
AND s_e.encounter_datetime <= :startDate
)

UNION ALL

-- 80% (of women aged 30 to 49 years with CCS form filled out for the first time) were VIA positive, and referred
SELECT
'80% (of registered women aged 30 to 49 years that have had their CCS screening for the first time) were VIA positive and referred' AS 'Indicator',
CASE
WHEN SUM(CASE
WHEN o_v_p.value_coded = (
SELECT concept_id
FROM concept
WHERE uuid LIKE '703AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
)
AND o_f.concept_id = (
SELECT concept_id
FROM concept
WHERE uuid LIKE '758b9dd8-b6d0-4ac2-b245-0e7bffb4693a'
) THEN 1
ELSE 0
END) >= 0.8 * COUNT(*) THEN 'Yes'
ELSE 'No'
END AS 'Value'
FROM
encounter e
INNER JOIN
person p ON e.patient_id = p.person_id
LEFT OUTER JOIN
obs o_v_p ON o_v_p.encounter_id = e.encounter_id
AND o_v_p.concept_id = (
SELECT concept_id
FROM concept
WHERE uuid LIKE '27912a31-4b1e-40d4-a3a0-947e0eb2e588'
)
AND o_v_p.value_coded = (
SELECT concept_id
FROM concept
WHERE uuid LIKE '703AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
)
LEFT OUTER JOIN
obs o_f ON o_f.encounter_id = e.encounter_id
AND o_f.concept_id = (
SELECT concept_id
FROM concept
WHERE uuid LIKE '758b9dd8-b6d0-4ac2-b245-0e7bffb4693a'
)
WHERE
e.location_id in (:locationList)
AND e.encounter_datetime > :startDate
AND e.encounter_datetime < :endDate
AND e.encounter_type = (
SELECT encounter_type_id
FROM encounter_type s_et
WHERE s_et.uuid LIKE '3fd606b6-4c9d-4077-a532-c1ac58644ad2'
)
AND ROUND(DATEDIFF(e.encounter_datetime, p.birthdate) / 365.25, 0) BETWEEN 30 AND 49
AND e.patient_id NOT IN (
SELECT patient_id
FROM encounter s_e
WHERE s_e.encounter_type = (
SELECT encounter_type_id
FROM encounter_type ss_et
WHERE ss_et.uuid LIKE '3fd606b6-4c9d-4077-a532-c1ac58644ad2'
)
AND s_e.encounter_datetime <= :startDate
)

UNION ALL

-- 80% have a Follow-up date and were given medication at least 4 weeks ago
SELECT
'80% (of registered patients with a Follow-up date) were given medication with at least a 4 weeks prescription' AS 'Indicator',
CASE
WHEN SUM(CASE
WHEN medication_table.medication_duration_in_weeks >= 4 THEN 1
ELSE 0
END) >= 0.8 * COUNT(*) THEN 'Yes'
ELSE 'No'
END AS 'Value'
FROM
patient p
INNER JOIN
encounter e ON p.patient_id = e.patient_id
INNER JOIN
obs o_f ON e.encounter_id = o_f.encounter_id
AND o_f.concept_id = (
SELECT concept_id
FROM concept
WHERE uuid LIKE 'e9c145c1-f4e9-4c34-b237-da069939dc38'
)
LEFT OUTER JOIN
(
SELECT
CASE
WHEN c.uuid LIKE '1822AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' THEN (d_o.duration / 672)
WHEN c.uuid LIKE '1072AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' THEN (d_o.duration / 7)
WHEN c.uuid LIKE '1073AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' THEN d_o.duration
WHEN c.uuid LIKE '1074AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' THEN (d_o.duration * 4.34524)
WHEN c.uuid LIKE '1734AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' THEN (d_o.duration * 52.1429)
ELSE 0
END AS 'medication_duration_in_weeks',
o.encounter_id
FROM
drug_order d_o
INNER JOIN
orders o ON d_o.order_id = o.order_id
INNER JOIN
concept c ON d_o.duration_units = c.concept_id
) medication_table ON medication_table.encounter_id = e.encounter_id
WHERE
e.location_id in (:locationList)
AND o_f.value_datetime BETWEEN :startDate AND :endDate
Loading
Loading