diff --git a/api/src/main/java/org/openmrs/module/commonreports/CommonReportsConstants.java b/api/src/main/java/org/openmrs/module/commonreports/CommonReportsConstants.java index f8d6331a..97b46289 100644 --- a/api/src/main/java/org/openmrs/module/commonreports/CommonReportsConstants.java +++ b/api/src/main/java/org/openmrs/module/commonreports/CommonReportsConstants.java @@ -36,7 +36,9 @@ public class CommonReportsConstants { public static final String COMPONENT_REPORTMANAGER_LAB = MODULE_ARTIFACT_ID + ".lab"; public static final String COMPONENT_REPORTMANAGER_VACCINATION = MODULE_ARTIFACT_ID + ".vaccination"; - + + public static final String COMPONENT_REPORTMANAGER_FAMILY_PLANNING = MODULE_ARTIFACT_ID + ".familyPlanning"; + /* * URIs URLs */ diff --git a/api/src/main/java/org/openmrs/module/commonreports/reports/MSPPFamilyPlanningReportManager.java b/api/src/main/java/org/openmrs/module/commonreports/reports/MSPPFamilyPlanningReportManager.java index 7065a839..78f25f28 100644 --- a/api/src/main/java/org/openmrs/module/commonreports/reports/MSPPFamilyPlanningReportManager.java +++ b/api/src/main/java/org/openmrs/module/commonreports/reports/MSPPFamilyPlanningReportManager.java @@ -1,29 +1,29 @@ package org.openmrs.module.commonreports.reports; -import static org.openmrs.module.commonreports.common.Helper.getStringFromResource; - -import java.io.InputStream; 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 java.util.Properties; -import org.apache.commons.io.IOUtils; + import org.openmrs.module.commonreports.ActivatedReportManager; +import org.openmrs.module.commonreports.CommonReportsConstants; import org.openmrs.module.initializer.api.InitializerService; import org.openmrs.module.reporting.common.MessageUtil; -import org.openmrs.module.reporting.dataset.definition.SqlDataSetDefinition; +import org.openmrs.module.reporting.cohort.definition.CompositionCohortDefinition; +import org.openmrs.module.reporting.cohort.definition.GenderCohortDefinition; +import org.openmrs.module.reporting.cohort.definition.SqlCohortDefinition; +import org.openmrs.module.reporting.dataset.definition.CohortCrossTabDataSetDefinition; +import org.openmrs.module.reporting.evaluation.parameter.Mapped; 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.openmrs.util.OpenmrsClassLoader; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -@Component +@Component(CommonReportsConstants.COMPONENT_REPORTMANAGER_FAMILY_PLANNING) public class MSPPFamilyPlanningReportManager extends ActivatedReportManager { @Autowired @@ -74,95 +74,188 @@ public List getParameters() { public ReportDefinition constructReportDefinition() { ReportDefinition rd = new ReportDefinition(); - + rd.setUuid(getUuid()); rd.setName(getName()); rd.setDescription(getDescription()); rd.setParameters(getParameters()); - rd.setUuid(getUuid()); - SqlDataSetDefinition sqlDsd = new SqlDataSetDefinition(); - sqlDsd.setName(MessageUtil.translate("commonreports.report.MSPP.familyPlanning.datasetName")); - sqlDsd.setDescription(MessageUtil.translate("commonreports.report.MSPP.familyPlanning.datasetDescription")); + CohortCrossTabDataSetDefinition familyPlanning = new CohortCrossTabDataSetDefinition(); + familyPlanning.addParameters(getParameters()); + rd.addDataSetDefinition(getName(), Mapped.mapStraightThrough(familyPlanning)); + + Map parameterMappings = new HashMap(); + parameterMappings.put("onOrAfter", "${startDate}"); + parameterMappings.put("onOrBefore", "${endDate}"); - String rawSql = getStringFromResource("org/openmrs/module/commonreports/sql/MSPPfamilyPlanning.sql"); - String sql = applyMetadataReplacements(rawSql); + int fpAdministredConceptId = inizService.getConceptFromKey("report.MSPP.familyPlanning.FPAdministred") + .getConceptId(); + int familyPlanningConceptId = inizService.getConceptFromKey("report.MSPP.familyPlanning.familyPlanning") + .getConceptId(); + int typeOfUserConceptId = inizService.getConceptFromKey("report.MSPP.familyPlanning.typeOfUser").getConceptId(); + int newConceptId = inizService.getConceptFromKey("report.MSPP.familyPlanning.new").getConceptId(); + int existentConceptId = inizService.getConceptFromKey("report.MSPP.familyPlanning.existent").getConceptId(); + int microgynonConceptId = inizService.getConceptFromKey("report.MSPP.familyPlanning.microgynon").getConceptId(); + int microlutConceptId = inizService.getConceptFromKey("report.MSPP.familyPlanning.microlut").getConceptId(); + int depoProveraInjectionConceptId = inizService.getConceptFromKey("report.MSPP.familyPlanning.depoProveraInjection") + .getConceptId(); + int jadelConceptId = inizService.getConceptFromKey("report.MSPP.familyPlanning.jadel").getConceptId(); + int condomConceptId = inizService.getConceptFromKey("report.MSPP.familyPlanning.condom").getConceptId(); - sqlDsd.setSqlQuery(sql); - sqlDsd.addParameters(getParameters()); + // Add rows for each method and user type combination + // Microgynon - New Users + familyPlanning.addRow("newMycogynonFemaleLT25", createFamilyPlanningCohort(fpAdministredConceptId, + microgynonConceptId, familyPlanningConceptId, typeOfUserConceptId, newConceptId, "F", 25, false, 1), + parameterMappings); + familyPlanning.addRow("newMycogynonFemaleGT25", createFamilyPlanningCohort(fpAdministredConceptId, + microgynonConceptId, familyPlanningConceptId, typeOfUserConceptId, newConceptId, "F", 25, true, 1), + parameterMappings); + familyPlanning + .addRow( + "existentMycogynonFemaleLT25", createFamilyPlanningCohort(fpAdministredConceptId, microgynonConceptId, + familyPlanningConceptId, typeOfUserConceptId, existentConceptId, "F", 25, false, 1), + parameterMappings); + familyPlanning + .addRow( + "existentMycogynonFemaleGT25", createFamilyPlanningCohort(fpAdministredConceptId, microgynonConceptId, + familyPlanningConceptId, typeOfUserConceptId, existentConceptId, "F", 25, true, 1), + parameterMappings); - Map parameterMappings = new HashMap(); - parameterMappings.put("startDate", "${startDate}"); - parameterMappings.put("endDate", "${endDate}"); + // Microlut - New Users + familyPlanning.addRow("newMicrolutFemaleLT25", createFamilyPlanningCohort(fpAdministredConceptId, microlutConceptId, + familyPlanningConceptId, typeOfUserConceptId, newConceptId, "F", 25, false, 1), parameterMappings); + familyPlanning.addRow("newMicrolutFemaleGT25", createFamilyPlanningCohort(fpAdministredConceptId, microlutConceptId, + familyPlanningConceptId, typeOfUserConceptId, newConceptId, "F", 25, true, 1), parameterMappings); + familyPlanning + .addRow( + "existentMicrolutFemaleLT25", createFamilyPlanningCohort(fpAdministredConceptId, microlutConceptId, + familyPlanningConceptId, typeOfUserConceptId, existentConceptId, "F", 25, false, 1), + parameterMappings); + familyPlanning + .addRow( + "existentMicrolutFemaleGT25", createFamilyPlanningCohort(fpAdministredConceptId, microlutConceptId, + familyPlanningConceptId, typeOfUserConceptId, existentConceptId, "F", 25, true, 1), + parameterMappings); + + // Depo Provera - New Users (3 months interval) + familyPlanning.addRow("newDepoFemaleLT25", createFamilyPlanningCohort(fpAdministredConceptId, + depoProveraInjectionConceptId, familyPlanningConceptId, typeOfUserConceptId, newConceptId, "F", 25, false, 3), + parameterMappings); + familyPlanning.addRow("newDepoFemaleGT25", createFamilyPlanningCohort(fpAdministredConceptId, + depoProveraInjectionConceptId, familyPlanningConceptId, typeOfUserConceptId, newConceptId, "F", 25, true, 3), + parameterMappings); + familyPlanning + .addRow("existentDepoFemaleLT25", + createFamilyPlanningCohort(fpAdministredConceptId, depoProveraInjectionConceptId, + familyPlanningConceptId, typeOfUserConceptId, existentConceptId, "F", 25, false, 3), + parameterMappings); + familyPlanning + .addRow("existentDepoFemaleGT25", + createFamilyPlanningCohort(fpAdministredConceptId, depoProveraInjectionConceptId, + familyPlanningConceptId, typeOfUserConceptId, existentConceptId, "F", 25, true, 3), + parameterMappings); + + // Jadel - New Users (5 years interval) + familyPlanning.addRow("newJadelFemaleLT25", createFamilyPlanningCohort(fpAdministredConceptId, jadelConceptId, + familyPlanningConceptId, typeOfUserConceptId, newConceptId, "F", 25, false, 60), parameterMappings); + familyPlanning.addRow("newJadelFemaleGT25", createFamilyPlanningCohort(fpAdministredConceptId, jadelConceptId, + familyPlanningConceptId, typeOfUserConceptId, newConceptId, "F", 25, true, 60), parameterMappings); + familyPlanning.addRow("existentJadelFemaleLT25", createFamilyPlanningCohort(fpAdministredConceptId, jadelConceptId, + familyPlanningConceptId, typeOfUserConceptId, existentConceptId, "F", 25, false, 60), parameterMappings); + familyPlanning.addRow("existentJadelFemaleGT25", createFamilyPlanningCohort(fpAdministredConceptId, jadelConceptId, + familyPlanningConceptId, typeOfUserConceptId, existentConceptId, "F", 25, true, 60), parameterMappings); + + // Condom - New Users (no interval) + familyPlanning.addRow("newCondomFemaleLT25", createFamilyPlanningCohort(fpAdministredConceptId, condomConceptId, + familyPlanningConceptId, typeOfUserConceptId, newConceptId, "F", 25, false, 0), parameterMappings); + familyPlanning.addRow("newCondomFemaleGT25", createFamilyPlanningCohort(fpAdministredConceptId, condomConceptId, + familyPlanningConceptId, typeOfUserConceptId, newConceptId, "F", 25, true, 0), parameterMappings); + familyPlanning.addRow("existentCondomFemaleLT25", createFamilyPlanningCohort(fpAdministredConceptId, condomConceptId, + familyPlanningConceptId, typeOfUserConceptId, existentConceptId, "F", 25, false, 0), parameterMappings); + familyPlanning.addRow("existentCondomFemaleGT25", createFamilyPlanningCohort(fpAdministredConceptId, condomConceptId, + familyPlanningConceptId, typeOfUserConceptId, existentConceptId, "F", 25, true, 0), parameterMappings); + + // Condom - Males + familyPlanning.addRow("newCondomMaleLT25", createFamilyPlanningCohort(fpAdministredConceptId, condomConceptId, + familyPlanningConceptId, typeOfUserConceptId, newConceptId, "M", 25, false, 0), parameterMappings); + familyPlanning.addRow("newCondomMaleGT25", createFamilyPlanningCohort(fpAdministredConceptId, condomConceptId, + familyPlanningConceptId, typeOfUserConceptId, newConceptId, "M", 25, true, 0), parameterMappings); + familyPlanning.addRow("existentCondomMaleLT25", createFamilyPlanningCohort(fpAdministredConceptId, condomConceptId, + familyPlanningConceptId, typeOfUserConceptId, existentConceptId, "M", 25, false, 0), parameterMappings); + familyPlanning.addRow("existentCondomMaleGT25", createFamilyPlanningCohort(fpAdministredConceptId, condomConceptId, + familyPlanningConceptId, typeOfUserConceptId, existentConceptId, "M", 25, true, 0), parameterMappings); - rd.addDataSetDefinition(getName(), sqlDsd, parameterMappings); + // Add a single column for "Total" (all patients) + GenderCohortDefinition allGender = new GenderCohortDefinition(); + allGender.setMaleIncluded(true); + allGender.setFemaleIncluded(true); + familyPlanning.addColumn("Total", createCohortComposition(allGender), null); return rd; } - @Override - public List constructReportDesigns(ReportDefinition reportDefinition) { - ReportDesign reportDesign = ReportManagerUtil.createExcelTemplateDesign("c51fc24f-50ba-48f8-9678-90462f7cff80", - reportDefinition, "org/openmrs/module/commonreports/reportTemplates/familyPlanningReportTemplate.xls"); - - Properties designProperties = new Properties(); - - designProperties.put("newUser.label", - MessageUtil.translate("commonreports.report.MSPP.familyPlanning.newUser.label")); - designProperties.put("existentUser.label", - MessageUtil.translate("commonreports.report.MSPP.familyPlanning.existentUser.label")); - designProperties.put("LT25years.label", - MessageUtil.translate("commonreports.report.MSPP.familyPlanning.LT25years.label")); - designProperties.put("GT25years.label", - MessageUtil.translate("commonreports.report.MSPP.familyPlanning.GT25years.label")); - designProperties.put("method.label", MessageUtil.translate("commonreports.report.MSPP.familyPlanning.method.label")); - designProperties.put("females.label", - MessageUtil.translate("commonreports.report.MSPP.familyPlanning.females.label")); - designProperties.put("males.label", MessageUtil.translate("commonreports.report.MSPP.familyPlanning.males.label")); - designProperties.put("PC.label", MessageUtil.translate("commonreports.report.MSPP.familyPlanning.PC.label")); - designProperties.put("PP.label", MessageUtil.translate("commonreports.report.MSPP.familyPlanning.PP.label")); - designProperties.put("depo.label", MessageUtil.translate("commonreports.report.MSPP.familyPlanning.depo.label")); - designProperties.put("implant.label", - MessageUtil.translate("commonreports.report.MSPP.familyPlanning.implant.label")); - designProperties.put("condoms.label", - MessageUtil.translate("commonreports.report.MSPP.familyPlanning.condoms.label")); - designProperties.put("total.label", MessageUtil.translate("commonreports.report.MSPP.familyPlanning.total.label")); - - reportDesign.setProperties(designProperties); - return Arrays.asList(reportDesign); + /** + * Creates a SqlCohortDefinition for family planning based on the provided parameters + * + * @param fpAdministredConceptId The concept ID for FP Administered + * @param methodConceptId The concept ID for the method (microgynon, microlut, etc.) + * @param familyPlanningConceptId The concept ID for family planning + * @param typeOfUserConceptId The concept ID for type of user + * @param userTypeConceptId The concept ID for new or existent user + * @param gender Gender filter: "F" for female, "M" for male + * @param ageThreshold Age threshold (e.g., 25) + * @param ageGreaterOrEqual true for >= ageThreshold, false for < ageThreshold + * @param intervalMonths Number of months to subtract from startDate (0 for no interval, 1 for 1 + * month, 3 for 3 months, 60 for 5 years) + * @return SqlCohortDefinition + */ + private SqlCohortDefinition createFamilyPlanningCohort(int fpAdministredConceptId, int methodConceptId, + int familyPlanningConceptId, int typeOfUserConceptId, int userTypeConceptId, String gender, int ageThreshold, + boolean ageGreaterOrEqual, int intervalMonths) { + + String intervalClause = ""; + if (intervalMonths > 0) { + if (intervalMonths == 60) { + intervalClause = "DATE_SUB(:onOrAfter, INTERVAL 5 YEAR)"; + } else { + intervalClause = "DATE_SUB(:onOrAfter, INTERVAL " + intervalMonths + " MONTH)"; + } + } else { + intervalClause = ":onOrAfter"; + } + + String ageCondition; + if (ageGreaterOrEqual) { + ageCondition = "round(DATEDIFF(obs.obs_datetime, person.birthdate)/365.25, 1) >= " + ageThreshold; + } else { + ageCondition = "round(DATEDIFF(obs.obs_datetime, person.birthdate)/365.25, 1) < " + ageThreshold; + } + + String sql = "SELECT DISTINCT obs.person_id " + "FROM obs " + + "INNER JOIN person ON obs.person_id = person.person_id " + "WHERE obs.voided = 0 " + + "AND obs.concept_id = " + fpAdministredConceptId + " AND obs.value_coded = " + methodConceptId + " " + + "AND obs.obs_group_id IN (" + " SELECT obs_group_id FROM obs WHERE " + "obs.obs_group_id IN (" + + " SELECT obs_id FROM obs " + "WHERE obs_datetime >= " + intervalClause + + " AND obs_datetime <= :onOrBefore " + "AND concept_id = " + familyPlanningConceptId + + " ) AND person.gender = '" + gender + "' " + "AND " + ageCondition + " AND obs.concept_id = " + + typeOfUserConceptId + " AND obs.value_coded = " + userTypeConceptId + ")"; + + SqlCohortDefinition cohort = new SqlCohortDefinition(sql); + cohort.addParameter(new Parameter("onOrAfter", "On Or After", Date.class)); + cohort.addParameter(new Parameter("onOrBefore", "On Or Before", Date.class)); + + return cohort; + } + + private CompositionCohortDefinition createCohortComposition(Object... elements) { + CompositionCohortDefinition compCD = new CompositionCohortDefinition(); + compCD.initializeFromElements(elements); + return compCD; } - private String applyMetadataReplacements(String rawSql) { - String s = rawSql - .replace(":FPAdministred", - inizService.getConceptFromKey("report.MSPP.familyPlanning.FPAdministred").getConceptId() + "") - .replace(":familyPlanning", - inizService.getConceptFromKey("report.MSPP.familyPlanning.familyPlanning").getConceptId() + "") - .replace(":femaleLT25", - "person.gender = 'F' AND round(DATEDIFF(obs.obs_datetime, person.birthdate)/365.25, 1) < 25") - .replace(":femaleGT25", - "person.gender = 'F' AND round(DATEDIFF(obs.obs_datetime, person.birthdate)/365.25, 1) >= 25") - .replace(":maleLT25", - "person.gender = 'M' AND round(DATEDIFF(obs.obs_datetime, person.birthdate)/365.25, 1) < 25") - .replace(":maleGT25", - "person.gender = 'M' AND round(DATEDIFF(obs.obs_datetime, person.birthdate)/365.25, 1) >= 25") - - .replace(":typeOfUser", - inizService.getConceptFromKey("report.MSPP.familyPlanning.typeOfUser").getConceptId() + "") - .replace(":new", inizService.getConceptFromKey("report.MSPP.familyPlanning.new").getConceptId() + "") - .replace(":existent", - inizService.getConceptFromKey("report.MSPP.familyPlanning.existent").getConceptId() + "") - - .replace(":microgynon", - inizService.getConceptFromKey("report.MSPP.familyPlanning.microgynon").getConceptId() + "") - - .replace(":microlut", - inizService.getConceptFromKey("report.MSPP.familyPlanning.microlut").getConceptId() + "") - - .replace(":depoProveraInjection", - inizService.getConceptFromKey("report.MSPP.familyPlanning.depoProveraInjection").getConceptId() + "") - .replace(":jadel", inizService.getConceptFromKey("report.MSPP.familyPlanning.jadel").getConceptId() + "") - .replace(":condom", inizService.getConceptFromKey("report.MSPP.familyPlanning.condom").getConceptId() + ""); - return s; + @Override + public List constructReportDesigns(ReportDefinition reportDefinition) { + return Arrays + .asList(ReportManagerUtil.createCsvReportDesign("8e300676-75d7-48f8-82eb-4fe9971459fe", reportDefinition)); } } diff --git a/api/src/main/resources/messages.properties b/api/src/main/resources/messages.properties index bd777430..ed37e0cd 100644 --- a/api/src/main/resources/messages.properties +++ b/api/src/main/resources/messages.properties @@ -122,8 +122,6 @@ ${project.parent.artifactId}.report.MSPP.emergency.0_14years=(0-14 years) ${project.parent.artifactId}.report.MSPP.emergency.above14years=(15 years and above) ${project.parent.artifactId}.report.MSPP.emergency.medicalAndSurgicalEmergency=Medical and surgical emergency -${project.parent.artifactId}.report.MSPP.familyPlanning.reportName=MSPP Family Planning -${project.parent.artifactId}.report.MSPP.familyPlanning.reportDescription=Family Planning report required by the Haitian MSPP ${project.parent.artifactId}.report.MSPP.familyPlanning.reportName=MSPP Family Planning ${project.parent.artifactId}.report.MSPP.familyPlanning.reportDescription=Family Planning report required by Haitian MSPP ${project.parent.artifactId}.report.MSPP.familyPlanning.datasetName=Family Planning SQL Dataset diff --git a/api/src/main/resources/org/openmrs/module/commonreports/sql/MSPPfamilyPlanning.sql b/api/src/main/resources/org/openmrs/module/commonreports/sql/MSPPfamilyPlanning.sql deleted file mode 100644 index e08205b5..00000000 --- a/api/src/main/resources/org/openmrs/module/commonreports/sql/MSPPfamilyPlanning.sql +++ /dev/null @@ -1,34 +0,0 @@ -SELECT -count(if( concept_id=:FPAdministred && value_coded=:microgynon && obs_group_id IN (select obs_group_id from obs where obs_group_id IN (SELECT obs_id FROM obs where obs_datetime >= DATE_SUB(:startDate, INTERVAL 1 MONTH) AND obs_datetime <= :endDate AND concept_id=:familyPlanning) AND :femaleLT25 AND concept_id=:typeOfUser AND value_coded=:new) ,1,null)) as newMycogynonFemaleLT25, -count(if( concept_id=:FPAdministred && value_coded=:microgynon && obs_group_id IN (select obs_group_id from obs where obs_group_id IN (SELECT obs_id FROM obs where obs_datetime >= DATE_SUB(:startDate, INTERVAL 1 MONTH) AND obs_datetime <= :endDate AND concept_id=:familyPlanning) AND :femaleGT25 AND concept_id=:typeOfUser AND value_coded=:new) ,1,null)) as newMycogynonFemaleGT25, -count(if( concept_id=:FPAdministred && value_coded=:microgynon && obs_group_id IN (select obs_group_id from obs where obs_group_id IN (SELECT obs_id FROM obs where obs_datetime >= DATE_SUB(:startDate, INTERVAL 1 MONTH) AND obs_datetime <= :endDate AND concept_id=:familyPlanning) AND :femaleLT25 AND concept_id=:typeOfUser AND value_coded=:existent) ,1,null)) as existentMycogynonFemaleLT25, -count(if( concept_id=:FPAdministred && value_coded=:microgynon && obs_group_id IN (select obs_group_id from obs where obs_group_id IN (SELECT obs_id FROM obs where obs_datetime >= DATE_SUB(:startDate, INTERVAL 1 MONTH) AND obs_datetime <= :endDate AND concept_id=:familyPlanning) AND :femaleGT25 AND concept_id=:typeOfUser AND value_coded=:existent) ,1,null)) as existentMycogynonFemaleGT25, - -count(if( concept_id=:FPAdministred && value_coded=:microlut && obs_group_id IN (select obs_group_id from obs where obs_group_id IN (SELECT obs_id FROM obs where obs_datetime >= DATE_SUB(:startDate, INTERVAL 1 MONTH) AND obs_datetime <= :endDate AND concept_id=:familyPlanning) AND :femaleLT25 AND concept_id=:typeOfUser AND value_coded=:new) ,1,null)) as newMicrolutFemaleLT25, -count(if( concept_id=:FPAdministred && value_coded=:microlut && obs_group_id IN (select obs_group_id from obs where obs_group_id IN (SELECT obs_id FROM obs where obs_datetime >= DATE_SUB(:startDate, INTERVAL 1 MONTH) AND obs_datetime <= :endDate AND concept_id=:familyPlanning) AND :femaleGT25 AND concept_id=:typeOfUser AND value_coded=:new) ,1,null)) as newMicrolutFemaleGT25, -count(if( concept_id=:FPAdministred && value_coded=:microlut && obs_group_id IN (select obs_group_id from obs where obs_group_id IN (SELECT obs_id FROM obs where obs_datetime >= DATE_SUB(:startDate, INTERVAL 1 MONTH) AND obs_datetime <= :endDate AND concept_id=:familyPlanning) AND :femaleLT25 AND concept_id=:typeOfUser AND value_coded=:existent) ,1,null)) as existentMicrolutFemaleLT25, -count(if( concept_id=:FPAdministred && value_coded=:microlut && obs_group_id IN (select obs_group_id from obs where obs_group_id IN (SELECT obs_id FROM obs where obs_datetime >= DATE_SUB(:startDate, INTERVAL 1 MONTH) AND obs_datetime <= :endDate AND concept_id=:familyPlanning) AND :femaleGT25 AND concept_id=:typeOfUser AND value_coded=:existent) ,1,null)) as existentMicrolutFemaleGT25, - -count(if( concept_id=:FPAdministred && value_coded=:depoProveraInjection && obs_group_id IN (select obs_group_id from obs where obs_group_id IN (SELECT obs_id FROM obs where obs_datetime >= DATE_SUB(:startDate, INTERVAL 3 MONTH) AND obs_datetime <= :endDate AND concept_id=:familyPlanning) AND :femaleLT25 AND concept_id=:typeOfUser AND value_coded=:new) ,1,null)) as newDepoFemaleLT25, -count(if( concept_id=:FPAdministred && value_coded=:depoProveraInjection && obs_group_id IN (select obs_group_id from obs where obs_group_id IN (SELECT obs_id FROM obs where obs_datetime >= DATE_SUB(:startDate, INTERVAL 3 MONTH) AND obs_datetime <= :endDate AND concept_id=:familyPlanning) AND :femaleGT25 AND concept_id=:typeOfUser AND value_coded=:new) ,1,null)) as newDepoFemaleGT25, -count(if( concept_id=:FPAdministred && value_coded=:depoProveraInjection && obs_group_id IN (select obs_group_id from obs where obs_group_id IN (SELECT obs_id FROM obs where obs_datetime >= DATE_SUB(:startDate, INTERVAL 3 MONTH) AND obs_datetime <= :endDate AND concept_id=:familyPlanning) AND :femaleLT25 AND concept_id=:typeOfUser AND value_coded=:existent) ,1,null)) as existentDepoFemaleLT25, -count(if( concept_id=:FPAdministred && value_coded=:depoProveraInjection && obs_group_id IN (select obs_group_id from obs where obs_group_id IN (SELECT obs_id FROM obs where obs_datetime >= DATE_SUB(:startDate, INTERVAL 3 MONTH) AND obs_datetime <= :endDate AND concept_id=:familyPlanning) AND :femaleGT25 AND concept_id=:typeOfUser AND value_coded=:existent) ,1,null)) as existentDepoFemaleGT25, - -count(if( concept_id=:FPAdministred && value_coded=:jadel && obs_group_id IN (select obs_group_id from obs where obs_group_id IN (SELECT obs_id FROM obs where obs_datetime >= DATE_SUB(:startDate, INTERVAL 5 YEAR) AND obs_datetime <= :endDate AND concept_id=:familyPlanning) AND :femaleLT25 AND concept_id=:typeOfUser AND value_coded=:new) ,1,null)) as newJadelFemaleLT25, -count(if( concept_id=:FPAdministred && value_coded=:jadel && obs_group_id IN (select obs_group_id from obs where obs_group_id IN (SELECT obs_id FROM obs where obs_datetime >= DATE_SUB(:startDate, INTERVAL 5 YEAR) AND obs_datetime <= :endDate AND concept_id=:familyPlanning) AND :femaleGT25 AND concept_id=:typeOfUser AND value_coded=:new) ,1,null)) as newJadelFemaleGT25, -count(if( concept_id=:FPAdministred && value_coded=:jadel && obs_group_id IN (select obs_group_id from obs where obs_group_id IN (SELECT obs_id FROM obs where obs_datetime >= DATE_SUB(:startDate, INTERVAL 5 YEAR) AND obs_datetime <= :endDate AND concept_id=:familyPlanning) AND :femaleLT25 AND concept_id=:typeOfUser AND value_coded=:existent) ,1,null)) as existentJadelFemaleLT25, -count(if( concept_id=:FPAdministred && value_coded=:jadel && obs_group_id IN (select obs_group_id from obs where obs_group_id IN (SELECT obs_id FROM obs where obs_datetime >= DATE_SUB(:startDate, INTERVAL 5 YEAR) AND obs_datetime <= :endDate AND concept_id=:familyPlanning) AND :femaleGT25 AND concept_id=:typeOfUser AND value_coded=:existent) ,1,null)) as existentJadelFemaleGT25, - -count(if( concept_id=:FPAdministred && value_coded=:condom && obs_group_id IN (select obs_group_id from obs where obs_group_id IN (SELECT obs_id FROM obs where obs_datetime >= :startDate AND obs_datetime <= :endDate AND concept_id=:familyPlanning) AND :femaleLT25 AND concept_id=:typeOfUser AND value_coded=:new) ,1,null)) as newCondomFemaleLT25, -count(if( concept_id=:FPAdministred && value_coded=:condom && obs_group_id IN (select obs_group_id from obs where obs_group_id IN (SELECT obs_id FROM obs where obs_datetime >= :startDate AND obs_datetime <= :endDate AND concept_id=:familyPlanning) AND :femaleGT25 AND concept_id=:typeOfUser AND value_coded=:new) ,1,null)) as newCondomFemaleGT25, -count(if( concept_id=:FPAdministred && value_coded=:condom && obs_group_id IN (select obs_group_id from obs where obs_group_id IN (SELECT obs_id FROM obs where obs_datetime >= :startDate AND obs_datetime <= :endDate AND concept_id=:familyPlanning) AND :femaleLT25 AND concept_id=:typeOfUser AND value_coded=:existent) ,1,null)) as existentCondomFemaleLT25, -count(if( concept_id=:FPAdministred && value_coded=:condom && obs_group_id IN (select obs_group_id from obs where obs_group_id IN (SELECT obs_id FROM obs where obs_datetime >= :startDate AND obs_datetime <= :endDate AND concept_id=:familyPlanning) AND :femaleGT25 AND concept_id=:typeOfUser AND value_coded=:existent) ,1,null)) as existentCondomFemaleGT25, - -count(if( concept_id=:FPAdministred && value_coded=:condom && obs_group_id IN (select obs_group_id from obs where obs_group_id IN (SELECT obs_id FROM obs where obs_datetime >= :startDate AND obs_datetime <= :endDate AND concept_id=:familyPlanning) AND :maleLT25 AND concept_id=:typeOfUser AND value_coded=:new) ,1,null)) as newCondomMaleLT25, -count(if( concept_id=:FPAdministred && value_coded=:condom && obs_group_id IN (select obs_group_id from obs where obs_group_id IN (SELECT obs_id FROM obs where obs_datetime >= :startDate AND obs_datetime <= :endDate AND concept_id=:familyPlanning) AND :maleGT25 AND concept_id=:typeOfUser AND value_coded=:new) ,1,null)) as newCondomMaleGT25, -count(if( concept_id=:FPAdministred && value_coded=:condom && obs_group_id IN (select obs_group_id from obs where obs_group_id IN (SELECT obs_id FROM obs where obs_datetime >= :startDate AND obs_datetime <= :endDate AND concept_id=:familyPlanning) AND :maleLT25 AND concept_id=:typeOfUser AND value_coded=:existent) ,1,null)) as existentCondomMaleLT25, -count(if( concept_id=:FPAdministred && value_coded=:condom && obs_group_id IN (select obs_group_id from obs where obs_group_id IN (SELECT obs_id FROM obs where obs_datetime >= :startDate AND obs_datetime <= :endDate AND concept_id=:familyPlanning) AND :maleGT25 AND concept_id=:typeOfUser AND value_coded=:existent) ,1,null)) as existentCondomMaleGT25 -from obs inner join person ON obs.person_id=person.person_id where obs.voided = 0 ; - - - diff --git a/api/src/test/java/org/openmrs/module/commonreports/reports/MSPPAntenatalReportManagerTest.java b/api/src/test/java/org/openmrs/module/commonreports/reports/MSPPAntenatalReportManagerTest.java index a0f81158..e8c8f403 100644 --- a/api/src/test/java/org/openmrs/module/commonreports/reports/MSPPAntenatalReportManagerTest.java +++ b/api/src/test/java/org/openmrs/module/commonreports/reports/MSPPAntenatalReportManagerTest.java @@ -114,6 +114,7 @@ public void testReport() throws Exception { for (Iterator itr = data.getDataSets().get("MSPP Antenatal Risks").iterator(); itr.hasNext();) { DataSetRow row = itr.next(); + // In CrossTabDataSet reports all rows and columns are in fact just columns of // one row diff --git a/api/src/test/java/org/openmrs/module/commonreports/reports/MSPPFamilyPlanningReportManagerTest.java b/api/src/test/java/org/openmrs/module/commonreports/reports/MSPPFamilyPlanningReportManagerTest.java index c77fe9f3..f28505e8 100644 --- a/api/src/test/java/org/openmrs/module/commonreports/reports/MSPPFamilyPlanningReportManagerTest.java +++ b/api/src/test/java/org/openmrs/module/commonreports/reports/MSPPFamilyPlanningReportManagerTest.java @@ -1,23 +1,15 @@ package org.openmrs.module.commonreports.reports; import java.io.File; -import java.sql.Connection; import java.sql.SQLException; import java.util.Iterator; -import org.dbunit.DatabaseUnitException; -import org.dbunit.DatabaseUnitRuntimeException; -import org.dbunit.database.DatabaseConfig; -import org.dbunit.database.DatabaseConnection; -import org.dbunit.database.IDatabaseConnection; -import org.dbunit.dataset.IDataSet; -import org.dbunit.ext.mysql.MySqlDataTypeFactory; -import org.dbunit.operation.DatabaseOperation; import org.junit.Assert; +import static org.junit.Assert.assertEquals; import org.junit.Before; import org.junit.Test; -import org.openmrs.api.ConceptService; -import org.openmrs.module.commonreports.reports.BaseModuleContextSensitiveMysqlBackedTest; -import org.openmrs.module.commonreports.reports.MSPPFamilyPlanningReportManager; +import org.openmrs.Cohort; +import org.openmrs.module.commonreports.ActivatedReportManager; +import org.openmrs.module.commonreports.CommonReportsConstants; import org.openmrs.module.initializer.Domain; import org.openmrs.module.initializer.api.InitializerService; import org.openmrs.module.initializer.api.loaders.Loader; @@ -25,20 +17,15 @@ 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.ReportDesign; 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.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; -import liquibase.Liquibase; -import liquibase.database.Database; -import liquibase.database.DatabaseFactory; -import liquibase.database.jvm.JdbcConnection; -import liquibase.resource.ClassLoaderResourceAccessor; -import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; public class MSPPFamilyPlanningReportManagerTest extends BaseModuleContextSensitiveMysqlBackedTest { @@ -56,36 +43,11 @@ public MSPPFamilyPlanningReportManagerTest() throws SQLException { private ReportDefinitionService rds; @Autowired - @Qualifier("conceptService") - private ConceptService cs; - - @Autowired - private MSPPFamilyPlanningReportManager manager; - - @Override - public void executeDataSet(IDataSet dataset) { - try { - Connection connection = getConnection(); - IDatabaseConnection dbUnitConn = setupDatabaseConnection(connection); - DatabaseOperation.REFRESH.execute(dbUnitConn, dataset); - } - catch (Exception e) { - throw new DatabaseUnitRuntimeException(e); - } - } - - private IDatabaseConnection setupDatabaseConnection(Connection connection) throws DatabaseUnitException { - IDatabaseConnection dbUnitConn = new DatabaseConnection(connection); - - DatabaseConfig config = dbUnitConn.getConfig(); - config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new MySqlDataTypeFactory()); - - return dbUnitConn; - } + @Qualifier(CommonReportsConstants.COMPONENT_REPORTMANAGER_FAMILY_PLANNING) + private ActivatedReportManager manager; @Before - public void setUp() throws Exception { - updateDatabase("org/openmrs/module/commonreports/liquibase/test-liquibase.xml"); + public void setup() throws Exception { executeDataSet("org/openmrs/module/reporting/include/ReportTestDataset-openmrs-2.0.xml"); executeDataSet("org/openmrs/module/commonreports/include/MSPPfamilyPlanningTestDataset.xml"); @@ -100,23 +62,18 @@ public void setUp() throws Exception { } @Test - public void setupReport_shouldCreateExcelTemplateDesign() throws Exception { - // setup + public void setupReport_shouldSetupFamilyPlanningReport() { // replay ReportManagerUtil.setupReport(manager); - // verif - ReportDesign design = rs.getReportDesignByUuid("c51fc24f-50ba-48f8-9678-90462f7cff80"); - - Assert.assertEquals(1, design.getResources().size()); + // verify + Assert.assertNotNull(rs.getReportDesignByUuid("8e300676-75d7-48f8-82eb-4fe9971459fe")); - ReportDefinition def = design.getReportDefinition(); - Assert.assertEquals("efd7ba26-7888-45a8-9184-423833ab79d3", def.getUuid()); } @Test - public void testReport() throws Exception { + public void testReport_shouldEvaluateReportWithCorrectData() throws Exception { // setup EvaluationContext context = new EvaluationContext(); context.addParameterValue("startDate", DateUtil.parseDate("2021-07-01", "yyyy-MM-dd")); @@ -127,43 +84,59 @@ public void testReport() throws Exception { ReportData data = rds.evaluate(rd, context); // verify - for (Iterator itr = data.getDataSets().get(rd.getName()).iterator(); itr.hasNext();) { + assertNotNull("Report data should not be null", data); + assertTrue("Should have data sets", data.getDataSets().size() > 0); + + for (Iterator itr = data.getDataSets().get("MSPP Family Planning").iterator(); itr.hasNext();) { DataSetRow row = itr.next(); - assertEquals(new Long(1), row.getColumnValue("existentMicrolutFemaleLT25")); - assertEquals(new Long(0), row.getColumnValue("existentMicrolutFemaleGT25")); + + Cohort existentMicrolutFemaleLT25 = (Cohort) row.getColumnValue("existentMicrolutFemaleLT25.Total"); + assertNotNull(existentMicrolutFemaleLT25); + assertEquals(1, existentMicrolutFemaleLT25.getSize()); + + Cohort existentMicrolutFemaleGT25 = (Cohort) row.getColumnValue("existentMicrolutFemaleGT25.Total"); + assertNotNull(existentMicrolutFemaleGT25); + assertEquals(0, existentMicrolutFemaleGT25.getSize()); + + Cohort newMicrolutFemaleLT25 = (Cohort) row.getColumnValue("newMicrolutFemaleLT25.Total"); + assertNotNull(newMicrolutFemaleLT25); + assertEquals(1, newMicrolutFemaleLT25.getSize()); + + Cohort newMicrolutFemaleGT25 = (Cohort) row.getColumnValue("newMicrolutFemaleGT25.Total"); + assertNotNull(newMicrolutFemaleGT25); + assertEquals(0, newMicrolutFemaleGT25.getSize()); + + Cohort newJadelFemaleLT25 = (Cohort) row.getColumnValue("newJadelFemaleLT25.Total"); + assertNotNull(newJadelFemaleLT25); + assertEquals(1, newJadelFemaleLT25.getSize()); + + Cohort newJadelFemaleGT25 = (Cohort) row.getColumnValue("newJadelFemaleGT25.Total"); + assertNotNull(newJadelFemaleGT25); + assertEquals(0, newJadelFemaleGT25.getSize()); - assertEquals(new Long(1), row.getColumnValue("newMicrolutFemaleLT25")); - assertEquals(new Long(0), row.getColumnValue("newMicrolutFemaleGT25")); + Cohort existentDepoFemaleGT25 = (Cohort) row.getColumnValue("existentDepoFemaleGT25.Total"); + assertNotNull(existentDepoFemaleGT25); + assertEquals(1, existentDepoFemaleGT25.getSize()); - assertEquals(new Long(1), row.getColumnValue("newJadelFemaleLT25")); - assertEquals(new Long(0), row.getColumnValue("newJadelFemaleGT25")); + Cohort existentDepoFemaleLT25 = (Cohort) row.getColumnValue("existentDepoFemaleLT25.Total"); + assertNotNull(existentDepoFemaleLT25); + assertEquals(0, existentDepoFemaleLT25.getSize()); - assertEquals(new Long(1), row.getColumnValue("existentDepoFemaleGT25")); - assertEquals(new Long(0), row.getColumnValue("existentDepoFemaleLT25")); + Cohort newCondomFemaleGT25 = (Cohort) row.getColumnValue("newCondomFemaleGT25.Total"); + assertNotNull(newCondomFemaleGT25); + assertEquals(1, newCondomFemaleGT25.getSize()); - assertEquals(new Long(1), row.getColumnValue("newCondomFemaleGT25")); - assertEquals(new Long(0), row.getColumnValue("newCondomFemaleLT25")); + Cohort newCondomFemaleLT25 = (Cohort) row.getColumnValue("newCondomFemaleLT25.Total"); + assertNotNull(newCondomFemaleLT25); + assertEquals(0, newCondomFemaleLT25.getSize()); - assertEquals(new Long(1), row.getColumnValue("newCondomMaleGT25")); - assertEquals(new Long(0), row.getColumnValue("newCondomMaleLT25")); + Cohort newCondomMaleGT25 = (Cohort) row.getColumnValue("newCondomMaleGT25.Total"); + assertNotNull(newCondomMaleGT25); + assertEquals(1, newCondomMaleGT25.getSize()); + Cohort newCondomMaleLT25 = (Cohort) row.getColumnValue("newCondomMaleLT25.Total"); + assertNotNull(newCondomMaleLT25); + assertEquals(0, newCondomMaleLT25.getSize()); } - - } - - private void updateDatabase(String filename) throws Exception { - Liquibase liquibase = getLiquibase(filename); - liquibase.update("Modify column datatype to longblob on reporting_report_design_resource table"); - liquibase.getDatabase().getConnection().commit(); - } - - private Liquibase getLiquibase(String filename) throws Exception { - Database liquibaseConnection = DatabaseFactory.getInstance() - .findCorrectDatabaseImplementation(new JdbcConnection(getConnection())); - - liquibaseConnection.setDatabaseChangeLogTableName("LIQUIBASECHANGELOG"); - liquibaseConnection.setDatabaseChangeLogLockTableName("LIQUIBASECHANGELOGLOCK"); - - return new Liquibase(filename, new ClassLoaderResourceAccessor(getClass().getClassLoader()), liquibaseConnection); } }