From 32973eca82500246954519a6ef7723384e31cee1 Mon Sep 17 00:00:00 2001 From: ruhanga Date: Mon, 22 Jan 2024 09:38:17 +0300 Subject: [PATCH 01/10] KH-392: Added a Disbursement report --- .../reports/DisbursementReportManager.java | 108 ++++++++++++++++++ .../module/commonreports/sql/disbursement.sql | 64 +++++++++++ 2 files changed, 172 insertions(+) create mode 100644 api/src/main/java/org/openmrs/module/commonreports/reports/DisbursementReportManager.java create mode 100644 api/src/main/resources/org/openmrs/module/commonreports/sql/disbursement.sql diff --git a/api/src/main/java/org/openmrs/module/commonreports/reports/DisbursementReportManager.java b/api/src/main/java/org/openmrs/module/commonreports/reports/DisbursementReportManager.java new file mode 100644 index 00000000..8b8ff340 --- /dev/null +++ b/api/src/main/java/org/openmrs/module/commonreports/reports/DisbursementReportManager.java @@ -0,0 +1,108 @@ +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.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", true); + } + + @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 today = new SimpleDateFormat("yyyy-MM-dd").format(new Date()); + return new Parameter("endDate", "End Date", Date.class, null, DateUtil.parseDate(today, "yyyy-MM-dd")); + } + + @Override + public List getParameters() { + List params = new ArrayList(); + params.add(getStartDateParameter()); + params.add(getEndDateParameter()); + 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"); + + sqlDsd.setSqlQuery(sql); + sqlDsd.addParameters(getParameters()); + + Map parameterMappings = new HashMap(); + parameterMappings.put("startDate", "${startDate}"); + parameterMappings.put("endDate", "${endDate}"); + + rd.addDataSetDefinition(getName(), sqlDsd, parameterMappings); + + return rd; + } + + @Override + public List constructReportDesigns(ReportDefinition reportDefinition) { + ReportDesign reportDesign = ReportManagerUtil.createCsvReportDesign("77b6c2cb-4b96-47d8-bcde-b1b7f16f5670", + reportDefinition); + return Arrays.asList(reportDesign); + } + +} diff --git a/api/src/main/resources/org/openmrs/module/commonreports/sql/disbursement.sql b/api/src/main/resources/org/openmrs/module/commonreports/sql/disbursement.sql new file mode 100644 index 00000000..124289bb --- /dev/null +++ b/api/src/main/resources/org/openmrs/module/commonreports/sql/disbursement.sql @@ -0,0 +1,64 @@ +SELECT 'Patients aged 40 and above with NCD form filled out for the rist 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.encounter_datetime > '2023-07-31' +AND e.encounter_datetime < '2023-09-01' +AND e.encounter_type = (select encounter_type_id from encounter_type s_et where s_et.`name` like 'Health Center - NCD Screening') +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.`name` like 'Health Center - NCD Screening') and s_e.encounter_datetime <= '2023-07-31') + +UNION ALL + +SELECT 'Women aged 30 to 49 years with CCS form filled out 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.encounter_datetime > '2023-11-31' +AND e.encounter_datetime < '2023-12-31' +AND e.encounter_type = (select encounter_type_id from encounter_type s_et where s_et.`name` like 'Cervical Cancer Screening') +AND round(DATEDIFF(e.encounter_datetime, p.birthdate)/365.25, 0) >= 30 +AND round(DATEDIFF(e.encounter_datetime, p.birthdate)/365.25, 0) <= 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.`name` like 'Cervical Cancer Screening') and s_e.encounter_datetime <= '2023-11-31') + +UNION ALL + +SELECT '80% had their first CCS screening, 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.encounter_datetime > '2023-11-31' +AND e.encounter_datetime < '2023-12-31' +AND e.encounter_type = (select encounter_type_id from encounter_type s_et where s_et.`name` like 'Cervical Cancer Screening') +AND round(DATEDIFF(e.encounter_datetime, p.birthdate)/365.25, 0) >= 30 +AND round(DATEDIFF(e.encounter_datetime, p.birthdate)/365.25, 0) <= 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.`name` like 'Cervical Cancer Screening') and s_e.encounter_datetime <= '2023-11-31') + +UNION ALL + +SELECT + '80% have a Follow-up date and where given medication at-least 3 weeks ago' AS 'Indicator', + CASE + WHEN SUM(CASE WHEN o_m.value_coded = (select concept_id from concept where uuid like '1065AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA') 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') +INNER JOIN obs o_m + ON e.encounter_id = o_m.encounter_id AND o_m.concept_id = (select concept_id from concept where uuid like '805c3a0b-cd38-4ed6-b4f8-f3af0fc118ad') AND o_m.value_coded = (select concept_id from concept where uuid like '1065AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA') +WHERE ((o_f.value_datetime >= '2024-01-01' AND o_f.value_datetime <= '2024-01-3') AND (o_m.obs_datetime < '2024-01-01') OR (o_f.value_datetime >= '2024-01-01' AND o_f.value_datetime <= '2024-01-3')); From 23e24f1a24714cf7f15fc397c67bf00196a220fa Mon Sep 17 00:00:00 2001 From: ruhanga Date: Mon, 22 Jan 2024 18:13:44 +0300 Subject: [PATCH 02/10] Added metadata substitutions --- .../reports/DisbursementReportManager.java | 26 ++- .../module/commonreports/sql/disbursement.sql | 207 +++++++++++++----- 2 files changed, 180 insertions(+), 53 deletions(-) diff --git a/api/src/main/java/org/openmrs/module/commonreports/reports/DisbursementReportManager.java b/api/src/main/java/org/openmrs/module/commonreports/reports/DisbursementReportManager.java index 8b8ff340..5df83789 100644 --- a/api/src/main/java/org/openmrs/module/commonreports/reports/DisbursementReportManager.java +++ b/api/src/main/java/org/openmrs/module/commonreports/reports/DisbursementReportManager.java @@ -29,7 +29,7 @@ public class DisbursementReportManager extends ActivatedReportManager { @Override public boolean isActivated() { - return inizService.getBooleanFromKey("report.disbursement.active", true); + return inizService.getBooleanFromKey("report.disbursement.active", false); } @Override @@ -85,6 +85,7 @@ public ReportDefinition constructReportDefinition() { 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()); @@ -105,4 +106,27 @@ public List constructReportDesigns(ReportDefinition reportDefiniti return Arrays.asList(reportDesign); } + private String applyMetadataReplacements(String rawSql) { + Map metadataReplacements = getMetadataReplacements(); + + for (String key : metadataReplacements.keySet()) { + rawSql = rawSql.replaceAll(":" + key, metadataReplacements.get(key)); + } + return rawSql; + } + + private Map getMetadataReplacements() { + Map map = new HashMap(); + + map.put("familyPlanningVisitTypeId", inizService.getValueFromKey("report.disbursement.ccs.encounter.type.uuid")); + map.put("prenatalVisitTypeId", inizService.getValueFromKey("report.disbursement.ncd.encounter.type.uuid")); + map.put("prenatalVisitTypeId", inizService.getValueFromKey("report.disbursement.yes.concept.uuid")); + map.put("prenatalVisitTypeId", inizService.getValueFromKey("report.disbursement.positive.concept.uuid")); + map.put("prenatalVisitTypeId", inizService.getValueFromKey("report.disbursement.via.diagnosis.question.concept.uuid")); + map.put("prenatalVisitTypeId", inizService.getValueFromKey("report.disbursement.followup.question.concept.uuid")); + map.put("prenatalVisitTypeId", inizService.getValueFromKey("report.disbursement.started.on.medication.question.concept.uuid")); + + return map; + } + } diff --git a/api/src/main/resources/org/openmrs/module/commonreports/sql/disbursement.sql b/api/src/main/resources/org/openmrs/module/commonreports/sql/disbursement.sql index 124289bb..3008ef29 100644 --- a/api/src/main/resources/org/openmrs/module/commonreports/sql/disbursement.sql +++ b/api/src/main/resources/org/openmrs/module/commonreports/sql/disbursement.sql @@ -1,64 +1,167 @@ -SELECT 'Patients aged 40 and above with NCD form filled out for the rist 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.encounter_datetime > '2023-07-31' -AND e.encounter_datetime < '2023-09-01' -AND e.encounter_type = (select encounter_type_id from encounter_type s_et where s_et.`name` like 'Health Center - NCD Screening') -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.`name` like 'Health Center - NCD Screening') and s_e.encounter_datetime <= '2023-07-31') +-- Patients aged 40 and above with NCD form filled out for the first time +SELECT + 'Patients aged 40 and above with NCD form filled out 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.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 -SELECT 'Women aged 30 to 49 years with CCS form filled out 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.encounter_datetime > '2023-11-31' -AND e.encounter_datetime < '2023-12-31' -AND e.encounter_type = (select encounter_type_id from encounter_type s_et where s_et.`name` like 'Cervical Cancer Screening') -AND round(DATEDIFF(e.encounter_datetime, p.birthdate)/365.25, 0) >= 30 -AND round(DATEDIFF(e.encounter_datetime, p.birthdate)/365.25, 0) <= 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.`name` like 'Cervical Cancer Screening') and s_e.encounter_datetime <= '2023-11-31') +-- Women aged 30 to 49 years with CCS form filled out for the first time +SELECT + 'Women aged 30 to 49 years with CCS form filled out 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.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 -SELECT '80% had their first CCS screening, 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.encounter_datetime > '2023-11-31' -AND e.encounter_datetime < '2023-12-31' -AND e.encounter_type = (select encounter_type_id from encounter_type s_et where s_et.`name` like 'Cervical Cancer Screening') -AND round(DATEDIFF(e.encounter_datetime, p.birthdate)/365.25, 0) >= 30 -AND round(DATEDIFF(e.encounter_datetime, p.birthdate)/365.25, 0) <= 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.`name` like 'Cervical Cancer Screening') and s_e.encounter_datetime <= '2023-11-31') +-- 80% (of women aged 30 to 49 years with CCS form filled out for the first time) had their first CCS screening, were VIA positive, and referred +SELECT + '80% (of women aged 30 to 49 years with CCS form filled out for the first time) had their first CCS screening, 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.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 3 weeks ago SELECT - '80% have a Follow-up date and where given medication at-least 3 weeks ago' AS 'Indicator', - CASE - WHEN SUM(CASE WHEN o_m.value_coded = (select concept_id from concept where uuid like '1065AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA') THEN 1 ELSE 0 END) >= 0.8 * COUNT(*) THEN 'Yes' + '80% have a Follow-up date and were given medication at least 3 weeks ago' AS 'Indicator', + CASE + WHEN SUM(CASE + WHEN o_m.value_coded = ( + SELECT concept_id + FROM concept + WHERE uuid LIKE '1065AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + ) 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') -INNER JOIN obs o_m - ON e.encounter_id = o_m.encounter_id AND o_m.concept_id = (select concept_id from concept where uuid like '805c3a0b-cd38-4ed6-b4f8-f3af0fc118ad') AND o_m.value_coded = (select concept_id from concept where uuid like '1065AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA') -WHERE ((o_f.value_datetime >= '2024-01-01' AND o_f.value_datetime <= '2024-01-3') AND (o_m.obs_datetime < '2024-01-01') OR (o_f.value_datetime >= '2024-01-01' AND o_f.value_datetime <= '2024-01-3')); +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' + ) +INNER JOIN + obs o_m ON e.encounter_id = o_m.encounter_id + AND o_m.concept_id = ( + SELECT concept_id + FROM concept + WHERE uuid LIKE '805c3a0b-cd38-4ed6-b4f8-f3af0fc118ad' + ) + AND o_m.value_coded = ( + SELECT concept_id + FROM concept + WHERE uuid LIKE '1065AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + ) +WHERE + ( + (o_f.value_datetime >= ':startDate' AND o_f.value_datetime <= ':endDate') + AND (o_m.obs_datetime < DATE_SUB(DATE(':endDate'), INTERVAL 3 WEEK)) + OR (o_f.value_datetime >= ':startDate' AND o_f.value_datetime <= ':endDate') + ); From d528f155dc510f34dd1514a0388e6db2fe4c48a5 Mon Sep 17 00:00:00 2001 From: ruhanga Date: Mon, 22 Jan 2024 18:39:41 +0300 Subject: [PATCH 03/10] Added metadata substitutions --- .../reports/DisbursementReportManager.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/api/src/main/java/org/openmrs/module/commonreports/reports/DisbursementReportManager.java b/api/src/main/java/org/openmrs/module/commonreports/reports/DisbursementReportManager.java index 5df83789..4f79c8ef 100644 --- a/api/src/main/java/org/openmrs/module/commonreports/reports/DisbursementReportManager.java +++ b/api/src/main/java/org/openmrs/module/commonreports/reports/DisbursementReportManager.java @@ -118,13 +118,13 @@ private String applyMetadataReplacements(String rawSql) { private Map getMetadataReplacements() { Map map = new HashMap(); - map.put("familyPlanningVisitTypeId", inizService.getValueFromKey("report.disbursement.ccs.encounter.type.uuid")); - map.put("prenatalVisitTypeId", inizService.getValueFromKey("report.disbursement.ncd.encounter.type.uuid")); - map.put("prenatalVisitTypeId", inizService.getValueFromKey("report.disbursement.yes.concept.uuid")); - map.put("prenatalVisitTypeId", inizService.getValueFromKey("report.disbursement.positive.concept.uuid")); - map.put("prenatalVisitTypeId", inizService.getValueFromKey("report.disbursement.via.diagnosis.question.concept.uuid")); - map.put("prenatalVisitTypeId", inizService.getValueFromKey("report.disbursement.followup.question.concept.uuid")); - map.put("prenatalVisitTypeId", inizService.getValueFromKey("report.disbursement.started.on.medication.question.concept.uuid")); + 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; } From 27db60d8ac0a2abc134fc3ad22c5aa62ec5fc476 Mon Sep 17 00:00:00 2001 From: ruhanga Date: Tue, 23 Jan 2024 14:37:42 +0300 Subject: [PATCH 04/10] Added unit tests --- .../reports/DisbursementReportManager.java | 13 +- .../module/commonreports/sql/disbursement.sql | 40 ++--- .../DisbursementReportManagerTest.java | 124 +++++++++++++++ .../include/disbursementReportTestDataset.xml | 146 ++++++++++++++++++ .../configuration/jsonkeyvalues/config.json | 3 +- 5 files changed, 300 insertions(+), 26 deletions(-) create mode 100644 api/src/test/java/org/openmrs/module/commonreports/reports/DisbursementReportManagerTest.java create mode 100644 api/src/test/resources/org/openmrs/module/commonreports/include/disbursementReportTestDataset.xml diff --git a/api/src/main/java/org/openmrs/module/commonreports/reports/DisbursementReportManager.java b/api/src/main/java/org/openmrs/module/commonreports/reports/DisbursementReportManager.java index 4f79c8ef..1d4c1e1e 100644 --- a/api/src/main/java/org/openmrs/module/commonreports/reports/DisbursementReportManager.java +++ b/api/src/main/java/org/openmrs/module/commonreports/reports/DisbursementReportManager.java @@ -58,8 +58,8 @@ private Parameter getStartDateParameter() { } private Parameter getEndDateParameter() { - String today = new SimpleDateFormat("yyyy-MM-dd").format(new Date()); - return new Parameter("endDate", "End Date", Date.class, null, DateUtil.parseDate(today, "yyyy-MM-dd")); + 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")); } @Override @@ -122,9 +122,12 @@ private Map getMetadataReplacements() { 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")); + 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; } diff --git a/api/src/main/resources/org/openmrs/module/commonreports/sql/disbursement.sql b/api/src/main/resources/org/openmrs/module/commonreports/sql/disbursement.sql index 3008ef29..09c53366 100644 --- a/api/src/main/resources/org/openmrs/module/commonreports/sql/disbursement.sql +++ b/api/src/main/resources/org/openmrs/module/commonreports/sql/disbursement.sql @@ -7,12 +7,12 @@ FROM INNER JOIN person p ON e.patient_id = p.person_id WHERE - e.encounter_datetime > ':startDate' - AND e.encounter_datetime < ':endDate' + 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' + 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 ( @@ -21,9 +21,9 @@ WHERE WHERE s_e.encounter_type = ( SELECT encounter_type_id FROM encounter_type ss_et - WHERE ss_et.`uuid` LIKE '422b7e0c-b8f3-4748-8e60-d6684315f141' + WHERE ss_et.uuid LIKE '422b7e0c-b8f3-4748-8e60-d6684315f141' ) - AND s_e.encounter_datetime <= ':startDate' + AND s_e.encounter_datetime <= :startDate ) UNION ALL @@ -37,12 +37,12 @@ FROM INNER JOIN person p ON e.patient_id = p.person_id WHERE - e.encounter_datetime > ':startDate' - AND e.encounter_datetime < ':endDate' + 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' + 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 ( @@ -51,16 +51,16 @@ WHERE WHERE s_e.encounter_type = ( SELECT encounter_type_id FROM encounter_type ss_et - WHERE ss_et.`uuid` LIKE '3fd606b6-4c9d-4077-a532-c1ac58644ad2' + WHERE ss_et.uuid LIKE '3fd606b6-4c9d-4077-a532-c1ac58644ad2' ) - AND s_e.encounter_datetime <= ':startDate' + 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) had their first CCS screening, were VIA positive, and referred +-- 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 women aged 30 to 49 years with CCS form filled out for the first time) had their first CCS screening, were VIA positive and referred' AS 'Indicator', + '80% (of women aged 30 to 49 years with CCS form filled out for the first time) were VIA positive and referred' AS 'Indicator', CASE WHEN SUM(CASE WHEN o_v_p.value_coded = ( @@ -101,12 +101,12 @@ LEFT OUTER JOIN WHERE uuid LIKE '758b9dd8-b6d0-4ac2-b245-0e7bffb4693a' ) WHERE - e.encounter_datetime > ':startDate' - AND e.encounter_datetime < ':endDate' + 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' + 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 ( @@ -115,9 +115,9 @@ WHERE WHERE s_e.encounter_type = ( SELECT encounter_type_id FROM encounter_type ss_et - WHERE ss_et.`uuid` LIKE '3fd606b6-4c9d-4077-a532-c1ac58644ad2' + WHERE ss_et.uuid LIKE '3fd606b6-4c9d-4077-a532-c1ac58644ad2' ) - AND s_e.encounter_datetime <= ':startDate' + AND s_e.encounter_datetime <= :startDate ) UNION ALL @@ -161,7 +161,7 @@ INNER JOIN ) WHERE ( - (o_f.value_datetime >= ':startDate' AND o_f.value_datetime <= ':endDate') - AND (o_m.obs_datetime < DATE_SUB(DATE(':endDate'), INTERVAL 3 WEEK)) - OR (o_f.value_datetime >= ':startDate' AND o_f.value_datetime <= ':endDate') + (o_f.value_datetime >= :startDate AND o_f.value_datetime <= :endDate) + AND (o_m.obs_datetime < DATE_SUB(:endDate, INTERVAL 3 WEEK)) + OR (o_f.value_datetime >= :startDate AND o_f.value_datetime <= :endDate) ); diff --git a/api/src/test/java/org/openmrs/module/commonreports/reports/DisbursementReportManagerTest.java b/api/src/test/java/org/openmrs/module/commonreports/reports/DisbursementReportManagerTest.java new file mode 100644 index 00000000..f73c59b5 --- /dev/null +++ b/api/src/test/java/org/openmrs/module/commonreports/reports/DisbursementReportManagerTest.java @@ -0,0 +1,124 @@ +package org.openmrs.module.commonreports.reports; + +import static java.math.BigDecimal.ONE; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Properties; + +import org.hibernate.cfg.Environment; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openmrs.Cohort; +import org.openmrs.api.ConceptService; +import org.openmrs.module.initializer.Domain; +import org.openmrs.module.initializer.api.InitializerService; +import org.openmrs.module.initializer.api.loaders.Loader; +import org.openmrs.module.reporting.common.DateUtil; +import org.openmrs.module.reporting.dataset.DataSet; +import org.openmrs.module.reporting.dataset.DataSetRow; +import org.openmrs.module.reporting.evaluation.EvaluationContext; +import org.openmrs.module.reporting.report.ReportData; +import org.openmrs.module.reporting.report.definition.ReportDefinition; +import org.openmrs.module.reporting.report.definition.service.ReportDefinitionService; +import org.openmrs.module.reporting.report.manager.ReportManagerUtil; +import org.openmrs.module.reporting.report.service.ReportService; +import org.openmrs.test.BaseModuleContextSensitiveTest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +public class DisbursementReportManagerTest extends BaseModuleContextSensitiveMysqlBackedTest { + + @Autowired + private InitializerService iniz; + + @Autowired + private ReportService rs; + + @Autowired + private ReportDefinitionService rds; + + @Autowired + @Qualifier("conceptService") + private ConceptService cs; + + @Autowired + private DisbursementReportManager manager; + + @Before + public void setup() throws Exception { + executeDataSet("org/openmrs/module/reporting/include/ReportTestDataset-openmrs-2.0.xml"); + executeDataSet("org/openmrs/module/commonreports/include/disbursementReportTestDataset.xml"); + + String path = getClass().getClassLoader().getResource("testAppDataDir").getPath() + File.separator; + System.setProperty("OPENMRS_APPLICATION_DATA_DIRECTORY", path); + + for (Loader loader : iniz.getLoaders()) { + if (loader.getDomainName().equals(Domain.JSON_KEY_VALUES.getName())) { + loader.load(); + } + } + } + + @Test + public void setupReport_shouldSetupEmergencyReport() { + + // replay + ReportManagerUtil.setupReport(manager); + + // verify + Assert.assertNotNull(rs.getReportDesignByUuid("77b6c2cb-4b96-47d8-bcde-b1b7f16f5670")); + + } + + @Test + public void testReport() throws Exception { + // setup + EvaluationContext context = new EvaluationContext(); + context.addParameterValue("startDate", DateUtil.parseDate("2023-12-01", "yyyy-MM-dd")); + context.addParameterValue("endDate", DateUtil.parseDate("2024-04-28", "yyyy-MM-dd")); + + // replay + ReportDefinition rd = manager.constructReportDefinition(); + ReportData data = rds.evaluate(rd, context); + getConnection().commit(); + + // verify + boolean indicator1 = true; + boolean indicator2 = true; + boolean indicator3 = true; + boolean indicator4 = true; + for (DataSet ds : data.getDataSets().values()) { + for (Iterator itr = ds.iterator(); itr.hasNext();) { + DataSetRow row = itr.next(); + + if (row.getColumnValue("Indicator").equals("Patients aged 40 and above with NCD form filled out for the first time")) { + assertEquals("7", row.getColumnValue("Value")); + indicator1 = true; + } + if (row.getColumnValue("Indicator").equals("Women aged 30 to 49 years with CCS form filled out for the first time")) { + assertEquals("8", row.getColumnValue("Value")); + indicator2 = true; + } + if (row.getColumnValue("Indicator").equals("80% (of women aged 30 to 49 years with CCS form filled out for the first time) had their first CCS screening, were VIA positive and referred")) { + assertEquals("Yes", row.getColumnValue("Value")); + indicator3 = true; + } + if (row.getColumnValue("Indicator").equals("80% have a Follow-up date and were given medication at least 3 weeks ago")) { + assertEquals("No", row.getColumnValue("Value")); + indicator4 = true; + } + } + assertTrue(indicator1 && indicator2 && indicator3 && indicator4); + } + } +} diff --git a/api/src/test/resources/org/openmrs/module/commonreports/include/disbursementReportTestDataset.xml b/api/src/test/resources/org/openmrs/module/commonreports/include/disbursementReportTestDataset.xml new file mode 100644 index 00000000..e61c2adf --- /dev/null +++ b/api/src/test/resources/org/openmrs/module/commonreports/include/disbursementReportTestDataset.xml @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/api/src/test/resources/testAppDataDir/configuration/jsonkeyvalues/config.json b/api/src/test/resources/testAppDataDir/configuration/jsonkeyvalues/config.json index 812a6b19..3f0d34dc 100644 --- a/api/src/test/resources/testAppDataDir/configuration/jsonkeyvalues/config.json +++ b/api/src/test/resources/testAppDataDir/configuration/jsonkeyvalues/config.json @@ -131,5 +131,6 @@ "report.programs.active" : "true", "report.patients.active" : "true", "report.appointments.active" : "true", - "report.visits.active" : "true" + "report.visits.active" : "true", + "report.disbursement.active": "true" } \ No newline at end of file From 62e6ce05f8bf735ec5e302048b9862ea1882cc17 Mon Sep 17 00:00:00 2001 From: ruhanga Date: Tue, 23 Jan 2024 20:33:33 +0300 Subject: [PATCH 05/10] Minor test modifications --- .../reports/DisbursementReportManagerTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/api/src/test/java/org/openmrs/module/commonreports/reports/DisbursementReportManagerTest.java b/api/src/test/java/org/openmrs/module/commonreports/reports/DisbursementReportManagerTest.java index f73c59b5..4693dc47 100644 --- a/api/src/test/java/org/openmrs/module/commonreports/reports/DisbursementReportManagerTest.java +++ b/api/src/test/java/org/openmrs/module/commonreports/reports/DisbursementReportManagerTest.java @@ -93,10 +93,10 @@ public void testReport() throws Exception { getConnection().commit(); // verify - boolean indicator1 = true; - boolean indicator2 = true; - boolean indicator3 = true; - boolean indicator4 = true; + boolean indicator1 = false; + boolean indicator2 = false; + boolean indicator3 = false; + boolean indicator4 = false; for (DataSet ds : data.getDataSets().values()) { for (Iterator itr = ds.iterator(); itr.hasNext();) { DataSetRow row = itr.next(); From 4037894fad96374882b93a0f77804d675f5662aa Mon Sep 17 00:00:00 2001 From: ruhanga Date: Wed, 24 Jan 2024 04:00:14 +0300 Subject: [PATCH 06/10] Adding requested changes --- .../reports/DisbursementReportManager.java | 8 +++ .../module/commonreports/sql/disbursement.sql | 58 +++++++++---------- .../DisbursementReportManagerTest.java | 36 +++++------- .../include/disbursementReportTestDataset.xml | 14 +++++ 4 files changed, 66 insertions(+), 50 deletions(-) diff --git a/api/src/main/java/org/openmrs/module/commonreports/reports/DisbursementReportManager.java b/api/src/main/java/org/openmrs/module/commonreports/reports/DisbursementReportManager.java index 1d4c1e1e..2ccc823e 100644 --- a/api/src/main/java/org/openmrs/module/commonreports/reports/DisbursementReportManager.java +++ b/api/src/main/java/org/openmrs/module/commonreports/reports/DisbursementReportManager.java @@ -9,6 +9,8 @@ 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; @@ -62,11 +64,16 @@ private Parameter getEndDateParameter() { 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 getParameters() { List params = new ArrayList(); params.add(getStartDateParameter()); params.add(getEndDateParameter()); + params.add(getLocationParameter()); return params; } @@ -93,6 +100,7 @@ public ReportDefinition constructReportDefinition() { Map parameterMappings = new HashMap(); parameterMappings.put("startDate", "${startDate}"); parameterMappings.put("endDate", "${endDate}"); + parameterMappings.put("locationList", "${locationList}"); rd.addDataSetDefinition(getName(), sqlDsd, parameterMappings); diff --git a/api/src/main/resources/org/openmrs/module/commonreports/sql/disbursement.sql b/api/src/main/resources/org/openmrs/module/commonreports/sql/disbursement.sql index 09c53366..70ea0453 100644 --- a/api/src/main/resources/org/openmrs/module/commonreports/sql/disbursement.sql +++ b/api/src/main/resources/org/openmrs/module/commonreports/sql/disbursement.sql @@ -1,13 +1,14 @@ -- Patients aged 40 and above with NCD form filled out for the first time SELECT - 'Patients aged 40 and above with NCD form filled out for the first time' AS 'Indicator', + 'Registered patients aged 40 and above that have had their NCD screenign 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.encounter_datetime > :startDate + e.location_id in (:locationList) + AND e.encounter_datetime > :startDate AND e.encounter_datetime < :endDate AND e.encounter_type = ( SELECT encounter_type_id @@ -30,14 +31,15 @@ UNION ALL -- Women aged 30 to 49 years with CCS form filled out for the first time SELECT - 'Women aged 30 to 49 years with CCS form filled out for the first time' AS 'Indicator', + '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.encounter_datetime > :startDate + e.location_id in (:locationList) + AND e.encounter_datetime > :startDate AND e.encounter_datetime < :endDate AND e.encounter_type = ( SELECT encounter_type_id @@ -60,7 +62,7 @@ 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 women aged 30 to 49 years with CCS form filled out for the first time) were VIA positive and referred' AS 'Indicator', + '80% (of registered patients with a Follow-up date) were given medication with at least a 3 weeks prescription' AS 'Indicator', CASE WHEN SUM(CASE WHEN o_v_p.value_coded = ( @@ -101,7 +103,8 @@ LEFT OUTER JOIN WHERE uuid LIKE '758b9dd8-b6d0-4ac2-b245-0e7bffb4693a' ) WHERE - e.encounter_datetime > :startDate + e.location_id in (:locationList) + AND e.encounter_datetime > :startDate AND e.encounter_datetime < :endDate AND e.encounter_type = ( SELECT encounter_type_id @@ -124,14 +127,10 @@ UNION ALL -- 80% have a Follow-up date and were given medication at least 3 weeks ago SELECT - '80% have a Follow-up date and were given medication at least 3 weeks ago' AS 'Indicator', + '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_m.value_coded = ( - SELECT concept_id - FROM concept - WHERE uuid LIKE '1065AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - ) THEN 1 + WHEN medication_table.medication_duration_in_weeks >= 3 THEN 1 ELSE 0 END) >= 0.8 * COUNT(*) THEN 'Yes' ELSE 'No' @@ -147,21 +146,22 @@ INNER JOIN FROM concept WHERE uuid LIKE 'e9c145c1-f4e9-4c34-b237-da069939dc38' ) -INNER JOIN - obs o_m ON e.encounter_id = o_m.encounter_id - AND o_m.concept_id = ( - SELECT concept_id - FROM concept - WHERE uuid LIKE '805c3a0b-cd38-4ed6-b4f8-f3af0fc118ad' - ) - AND o_m.value_coded = ( - SELECT concept_id - FROM concept - WHERE uuid LIKE '1065AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - ) -WHERE +LEFT OUTER JOIN ( - (o_f.value_datetime >= :startDate AND o_f.value_datetime <= :endDate) - AND (o_m.obs_datetime < DATE_SUB(:endDate, INTERVAL 3 WEEK)) - OR (o_f.value_datetime >= :startDate AND o_f.value_datetime <= :endDate) - ); + SELECT + CASE + WHEN c.uuid LIKE '1072AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' THEN (d_o.duration / 7) + WHEN c.uuid LIKE '1073AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' THEN d_o.duration + 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 diff --git a/api/src/test/java/org/openmrs/module/commonreports/reports/DisbursementReportManagerTest.java b/api/src/test/java/org/openmrs/module/commonreports/reports/DisbursementReportManagerTest.java index 4693dc47..5d8edc41 100644 --- a/api/src/test/java/org/openmrs/module/commonreports/reports/DisbursementReportManagerTest.java +++ b/api/src/test/java/org/openmrs/module/commonreports/reports/DisbursementReportManagerTest.java @@ -1,25 +1,16 @@ package org.openmrs.module.commonreports.reports; -import static java.math.BigDecimal.ONE; -import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import java.io.File; -import java.math.BigDecimal; -import java.util.HashMap; +import java.util.Collections; import java.util.Iterator; -import java.util.Map; -import java.util.Properties; - -import org.hibernate.cfg.Environment; import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.openmrs.Cohort; import org.openmrs.api.ConceptService; +import org.openmrs.api.LocationService; import org.openmrs.module.initializer.Domain; import org.openmrs.module.initializer.api.InitializerService; import org.openmrs.module.initializer.api.loaders.Loader; @@ -32,7 +23,6 @@ import org.openmrs.module.reporting.report.definition.service.ReportDefinitionService; import org.openmrs.module.reporting.report.manager.ReportManagerUtil; import org.openmrs.module.reporting.report.service.ReportService; -import org.openmrs.test.BaseModuleContextSensitiveTest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -47,6 +37,10 @@ public class DisbursementReportManagerTest extends BaseModuleContextSensitiveMys @Autowired private ReportDefinitionService rds; + @Autowired + @Qualifier("locationService") + private LocationService ls; + @Autowired @Qualifier("conceptService") private ConceptService cs; @@ -86,12 +80,12 @@ public void testReport() throws Exception { EvaluationContext context = new EvaluationContext(); context.addParameterValue("startDate", DateUtil.parseDate("2023-12-01", "yyyy-MM-dd")); context.addParameterValue("endDate", DateUtil.parseDate("2024-04-28", "yyyy-MM-dd")); + context.addParameterValue("locationList", Collections.singletonList(ls.getLocation(1))); // replay ReportDefinition rd = manager.constructReportDefinition(); ReportData data = rds.evaluate(rd, context); - getConnection().commit(); - + // verify boolean indicator1 = false; boolean indicator2 = false; @@ -101,22 +95,22 @@ public void testReport() throws Exception { for (Iterator itr = ds.iterator(); itr.hasNext();) { DataSetRow row = itr.next(); - if (row.getColumnValue("Indicator").equals("Patients aged 40 and above with NCD form filled out for the first time")) { + if (row.getColumnValue("Indicator").equals("Registered patients aged 40 and above that have had their NCD screenign for the first time")) { assertEquals("7", row.getColumnValue("Value")); indicator1 = true; } - if (row.getColumnValue("Indicator").equals("Women aged 30 to 49 years with CCS form filled out for the first time")) { + if (row.getColumnValue("Indicator").equals("Registered women aged 30 to 49 years that have had their CCS screening for the first time")) { assertEquals("8", row.getColumnValue("Value")); indicator2 = true; } - if (row.getColumnValue("Indicator").equals("80% (of women aged 30 to 49 years with CCS form filled out for the first time) had their first CCS screening, were VIA positive and referred")) { + if (row.getColumnValue("Indicator").equals("80% (of registered patients with a Follow-up date) were given medication with at least a 3 weeks prescription")) { assertEquals("Yes", row.getColumnValue("Value")); - indicator3 = true; - } - if (row.getColumnValue("Indicator").equals("80% have a Follow-up date and were given medication at least 3 weeks ago")) { - assertEquals("No", row.getColumnValue("Value")); indicator4 = true; } + if (row.getColumnValue("Indicator").equals("80% (of registered women aged 30 to 49 years that have had their CCS screening for the first time) were VIA positive and referred")) { + assertEquals("Yes", row.getColumnValue("Value")); + indicator3 = true; + } } assertTrue(indicator1 && indicator2 && indicator3 && indicator4); } diff --git a/api/src/test/resources/org/openmrs/module/commonreports/include/disbursementReportTestDataset.xml b/api/src/test/resources/org/openmrs/module/commonreports/include/disbursementReportTestDataset.xml index e61c2adf..2b7ed1d2 100644 --- a/api/src/test/resources/org/openmrs/module/commonreports/include/disbursementReportTestDataset.xml +++ b/api/src/test/resources/org/openmrs/module/commonreports/include/disbursementReportTestDataset.xml @@ -13,7 +13,11 @@ + + + + @@ -143,4 +147,14 @@ + + + + + + + + + + From 07e18ad15f1d550b8bab34cf5e2a70c6e65229b9 Mon Sep 17 00:00:00 2001 From: ruhanga Date: Wed, 24 Jan 2024 10:28:37 +0300 Subject: [PATCH 07/10] Prescribed medication duration measure to be 4 weeks --- .../org/openmrs/module/commonreports/sql/disbursement.sql | 5 ++++- .../commonreports/include/disbursementReportTestDataset.xml | 6 +++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/api/src/main/resources/org/openmrs/module/commonreports/sql/disbursement.sql b/api/src/main/resources/org/openmrs/module/commonreports/sql/disbursement.sql index 70ea0453..5506d428 100644 --- a/api/src/main/resources/org/openmrs/module/commonreports/sql/disbursement.sql +++ b/api/src/main/resources/org/openmrs/module/commonreports/sql/disbursement.sql @@ -130,7 +130,7 @@ 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 medication_table.medication_duration_in_weeks >= 3 THEN 1 + WHEN medication_table.medication_duration_in_weeks >= 4 THEN 1 ELSE 0 END) >= 0.8 * COUNT(*) THEN 'Yes' ELSE 'No' @@ -150,8 +150,11 @@ 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 diff --git a/api/src/test/resources/org/openmrs/module/commonreports/include/disbursementReportTestDataset.xml b/api/src/test/resources/org/openmrs/module/commonreports/include/disbursementReportTestDataset.xml index 2b7ed1d2..91cc6885 100644 --- a/api/src/test/resources/org/openmrs/module/commonreports/include/disbursementReportTestDataset.xml +++ b/api/src/test/resources/org/openmrs/module/commonreports/include/disbursementReportTestDataset.xml @@ -154,7 +154,7 @@ - - - + + + From dcc3156e64b3c1803db8617530be3da2fba9e80e Mon Sep 17 00:00:00 2001 From: ruhanga Date: Wed, 24 Jan 2024 10:41:11 +0300 Subject: [PATCH 08/10] Fix report labelling --- .../org/openmrs/module/commonreports/sql/disbursement.sql | 6 +++--- .../reports/DisbursementReportManagerTest.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/src/main/resources/org/openmrs/module/commonreports/sql/disbursement.sql b/api/src/main/resources/org/openmrs/module/commonreports/sql/disbursement.sql index 5506d428..c421a290 100644 --- a/api/src/main/resources/org/openmrs/module/commonreports/sql/disbursement.sql +++ b/api/src/main/resources/org/openmrs/module/commonreports/sql/disbursement.sql @@ -62,7 +62,7 @@ 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 patients with a Follow-up date) were given medication with at least a 3 weeks prescription' AS 'Indicator', + '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 = ( @@ -125,9 +125,9 @@ WHERE UNION ALL --- 80% have a Follow-up date and were given medication at least 3 weeks ago +-- 80% have a Follow-up date and were given medication at least 4 weeks ago 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', + '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 diff --git a/api/src/test/java/org/openmrs/module/commonreports/reports/DisbursementReportManagerTest.java b/api/src/test/java/org/openmrs/module/commonreports/reports/DisbursementReportManagerTest.java index 5d8edc41..79c3271a 100644 --- a/api/src/test/java/org/openmrs/module/commonreports/reports/DisbursementReportManagerTest.java +++ b/api/src/test/java/org/openmrs/module/commonreports/reports/DisbursementReportManagerTest.java @@ -103,7 +103,7 @@ public void testReport() throws Exception { assertEquals("8", row.getColumnValue("Value")); indicator2 = true; } - if (row.getColumnValue("Indicator").equals("80% (of registered patients with a Follow-up date) were given medication with at least a 3 weeks prescription")) { + if (row.getColumnValue("Indicator").equals("80% (of registered patients with a Follow-up date) were given medication with at least a 4 weeks prescription")) { assertEquals("Yes", row.getColumnValue("Value")); indicator4 = true; } From 1613baa3348a483c5f4968e320f956c7e1d49a70 Mon Sep 17 00:00:00 2001 From: ruhanga Date: Wed, 24 Jan 2024 13:04:41 +0300 Subject: [PATCH 09/10] Add documentation --- README.md | 1 + readme/Disbursement.md | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 readme/Disbursement.md diff --git a/README.md b/README.md index 2c690bc4..57062c55 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/readme/Disbursement.md b/readme/Disbursement.md new file mode 100644 index 00000000..b844d9af --- /dev/null +++ b/readme/Disbursement.md @@ -0,0 +1,27 @@ +## Disbursement Report +It is a monthly report requested for NCD and CCS screening visits. + +**Setup** + +It is setup by setting the following properties in [initializer](https://github.com/mekomsolutions/openmrs-module-initializer) `jsonkeyvalues`' domain configuration. + +```bash +{ + "report.MSPP.disbursement.active" : "true" +} +``` +`report.MSPP.disbursement.active` activates the report to be usable when the module is loaded. + + +Find the report template below + +``` ++-----------------------------------------------------------------------------------------------------------------------------------+-------+ +|Indicator |Value | +|-----------------------------------------------------------------------------------------------------------------------------------+-------+ +|Registered patients aged 40 and above that have had their NCD screenign for the first time |55 | +|Registered women aged 30 to 49 years that have had their CCS screening for the first time |66 | +|80% (of registered women aged 30 to 49 years that have had their CCS screening for the first time) were VIA positive and referred |Yes/No | +|80% (of registered patients with a Follow-up date) were given medication with at least a 4 weeks prescription |Yes/No | ++-----------------------------------------------------------------------------------------------------------------------------------+-------+ +``` \ No newline at end of file From 1487d63e4782d5544f61f1debce7338b204787ed Mon Sep 17 00:00:00 2001 From: ruhanga Date: Wed, 24 Jan 2024 17:06:02 +0300 Subject: [PATCH 10/10] Address PR reviews --- .../openmrs/module/commonreports/sql/disbursement.sql | 2 +- .../reports/DisbursementReportManagerTest.java | 10 +++++----- readme/Disbursement.md | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/api/src/main/resources/org/openmrs/module/commonreports/sql/disbursement.sql b/api/src/main/resources/org/openmrs/module/commonreports/sql/disbursement.sql index c421a290..aea63213 100644 --- a/api/src/main/resources/org/openmrs/module/commonreports/sql/disbursement.sql +++ b/api/src/main/resources/org/openmrs/module/commonreports/sql/disbursement.sql @@ -1,6 +1,6 @@ -- 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 screenign for the first time' AS 'Indicator', + '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 diff --git a/api/src/test/java/org/openmrs/module/commonreports/reports/DisbursementReportManagerTest.java b/api/src/test/java/org/openmrs/module/commonreports/reports/DisbursementReportManagerTest.java index 79c3271a..e35bc323 100644 --- a/api/src/test/java/org/openmrs/module/commonreports/reports/DisbursementReportManagerTest.java +++ b/api/src/test/java/org/openmrs/module/commonreports/reports/DisbursementReportManagerTest.java @@ -95,7 +95,7 @@ public void testReport() throws Exception { for (Iterator itr = ds.iterator(); itr.hasNext();) { DataSetRow row = itr.next(); - if (row.getColumnValue("Indicator").equals("Registered patients aged 40 and above that have had their NCD screenign for the first time")) { + if (row.getColumnValue("Indicator").equals("Registered patients aged 40 and above that have had their NCD screening for the first time")) { assertEquals("7", row.getColumnValue("Value")); indicator1 = true; } @@ -103,14 +103,14 @@ public void testReport() throws Exception { assertEquals("8", row.getColumnValue("Value")); indicator2 = true; } - if (row.getColumnValue("Indicator").equals("80% (of registered patients with a Follow-up date) were given medication with at least a 4 weeks prescription")) { - assertEquals("Yes", row.getColumnValue("Value")); - indicator4 = true; - } if (row.getColumnValue("Indicator").equals("80% (of registered women aged 30 to 49 years that have had their CCS screening for the first time) were VIA positive and referred")) { assertEquals("Yes", row.getColumnValue("Value")); indicator3 = true; } + if (row.getColumnValue("Indicator").equals("80% (of registered patients with a Follow-up date) were given medication with at least a 4 weeks prescription")) { + assertEquals("Yes", row.getColumnValue("Value")); + indicator4 = true; + } } assertTrue(indicator1 && indicator2 && indicator3 && indicator4); } diff --git a/readme/Disbursement.md b/readme/Disbursement.md index b844d9af..b40466f0 100644 --- a/readme/Disbursement.md +++ b/readme/Disbursement.md @@ -19,7 +19,7 @@ Find the report template below +-----------------------------------------------------------------------------------------------------------------------------------+-------+ |Indicator |Value | |-----------------------------------------------------------------------------------------------------------------------------------+-------+ -|Registered patients aged 40 and above that have had their NCD screenign for the first time |55 | +|Registered patients aged 40 and above that have had their NCD screening for the first time |55 | |Registered women aged 30 to 49 years that have had their CCS screening for the first time |66 | |80% (of registered women aged 30 to 49 years that have had their CCS screening for the first time) were VIA positive and referred |Yes/No | |80% (of registered patients with a Follow-up date) were given medication with at least a 4 weeks prescription |Yes/No |