diff --git a/api/src/main/java/org/openmrs/module/drcreports/reports/DRCTxCurrReportManager.java b/api/src/main/java/org/openmrs/module/drcreports/reports/DRCTxCurrReportManager.java new file mode 100644 index 0000000..853cfea --- /dev/null +++ b/api/src/main/java/org/openmrs/module/drcreports/reports/DRCTxCurrReportManager.java @@ -0,0 +1,561 @@ +package org.openmrs.module.drcreports.reports; + +import static org.openmrs.module.drcreports.common.Helper.getStringFromResource; + +import java.util.*; + +import org.openmrs.Concept; +import org.openmrs.Program; +import org.openmrs.api.context.Context; +import org.openmrs.module.reporting.cohort.definition.CodedObsCohortDefinition; +import org.openmrs.module.reporting.cohort.definition.BaseObsCohortDefinition.TimeModifier; +import org.openmrs.module.reporting.common.SetComparator; +import org.openmrs.api.ConceptService; +import org.openmrs.module.reporting.cohort.definition.ProgramEnrollmentCohortDefinition; +import org.openmrs.api.ProgramWorkflowService; + +import org.openmrs.module.drcreports.ActivatedReportManager; +import org.openmrs.module.initializer.api.InitializerService; +import org.openmrs.module.reporting.cohort.definition.CompositionCohortDefinition; +import org.openmrs.module.reporting.cohort.definition.GenderCohortDefinition; +import org.openmrs.module.reporting.cohort.definition.BirthAndDeathCohortDefinition; + +import org.openmrs.module.reporting.cohort.definition.SqlCohortDefinition; +import org.openmrs.module.reporting.common.MessageUtil; +import org.openmrs.module.reporting.common.DurationUnit; + +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.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; +import org.openmrs.module.reporting.cohort.definition.AgeCohortDefinition; +import org.openmrs.module.reporting.cohort.definition.PresenceOrAbsenceCohortDefinition; +import org.openmrs.module.reporting.common.BooleanOperator; + +@Component +public class DRCTxCurrReportManager extends ActivatedReportManager { + + @Autowired + @Qualifier("initializer.InitializerService") + private InitializerService inizService; + + @Autowired + @Qualifier("programWorkflowService") + private ProgramWorkflowService ps; + + @Override + public boolean isActivated() { + return inizService.getBooleanFromKey("report.drc.txCurr.active", true); + } + + @Override + public String getVersion() { + return "1.0.0-SNAPSHOT"; + } + + @Override + public String getUuid() { + return "d65e699d-e116-4e2c-8517-6d1ef30f7153"; + } + + @Override + public String getName() { + return MessageUtil.translate("drcreports.report.drc.txCurr.reportName"); + } + + @Override + public String getDescription() { + return MessageUtil.translate("drcreports.report.drc.txCurr.reportDescription"); + } + + private Parameter getStartDateParameter() { + return new Parameter("startDate", MessageUtil.translate("drcreports.report.util.reportingStartDate"), Date.class); + } + + private Parameter getEndDateParameter() { + return new Parameter("endDate", MessageUtil.translate("drcreports.report.util.reportingEndDate"), Date.class); + } + + public static String col0 = ""; + + public static String col1 = ""; + + public static String col2 = ""; + + public static String col3 = ""; + + public static String col4 = ""; + + public static String col5 = ""; + + public static String col6 = ""; + + public static String col7 = ""; + + public static String col8 = ""; + + public static String col9 = ""; + + public static String col10 = ""; + + public static String col11 = ""; + + public static String col12 = ""; + + public static String col13 = ""; + + public static String col14 = ""; + + public static String col15 = ""; + + public static String col16 = ""; + + public static String col17 = ""; + + public static String col18 = ""; + + public static String col19 = ""; + + public static String col20 = ""; + + public static String col21 = ""; + + public static String col22 = ""; + + public static String col23 = ""; + + public static String col24 = ""; + + public static String col25 = ""; + + public static String col26 = ""; + + public static String col27 = ""; + + public static String col28 = ""; + + public static String col29 = ""; + + public static String col30 = ""; + + public static String col31 = ""; + + public static String col32 = ""; + + public static String col33 = ""; + + public static String col34 = ""; + + @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.setUuid(getUuid()); + rd.setName(getName()); + rd.setDescription(getDescription()); + rd.setParameters(getParameters()); + + // txCurr Grouping + CohortCrossTabDataSetDefinition txCurr = new CohortCrossTabDataSetDefinition(); + txCurr.addParameters(getParameters()); + rd.addDataSetDefinition(getName(), Mapped.mapStraightThrough(txCurr)); + + Map parameterMappings = new HashMap(); + parameterMappings.put("onOrAfter", "${startDate}"); + parameterMappings.put("onOrBefore", "${endDate}"); + + // HIV Care Program cohort + ProgramEnrollmentCohortDefinition pecd = new ProgramEnrollmentCohortDefinition(); + //ProgramWorkflowService ps = Context.getProgramWorkflowService(); + Program program = ps.getProgramByUuid("64f950e6-1b07-4ac0-8e7e-f3e148f3463f"); //HIV Care program + //pecd.setPrograms(Collections.singletonList(program)); + pecd.setPrograms(Arrays.asList(program)); + + // ART Initiated in date range + SqlCohortDefinition artInitiationSqlCD = new SqlCohortDefinition(); + String artInitiationSql = getStringFromResource("org/openmrs/module/drcreports/sql/DRCTxCurrInitiation.sql"); + artInitiationSqlCD.setQuery(artInitiationSql); + artInitiationSqlCD.addParameter(new Parameter("onOrAfter", "On Or After", Date.class)); + artInitiationSqlCD.addParameter(new Parameter("onOrBefore", "On Or Before", Date.class)); + + // Resume ART in date range + SqlCohortDefinition resumeARTSqlCD = new SqlCohortDefinition(); + String resumeARTSql = getStringFromResource("org/openmrs/module/drcreports/sql/DRCTxCurrResumeART.sql"); + resumeARTSqlCD.setQuery(resumeARTSql); + resumeARTSqlCD.addParameter(new Parameter("onOrAfter", "On Or After", Date.class)); + resumeARTSqlCD.addParameter(new Parameter("onOrBefore", "On Or Before", Date.class)); + + // Transfer In and PMTCT enrollment in date range + SqlCohortDefinition transferInPMTCTSqlCD = new SqlCohortDefinition(); + String transferInPMTCTSql = getStringFromResource("org/openmrs/module/drcreports/sql/DRCTxCurrTransferPMTCT.sql"); + transferInPMTCTSqlCD.setQuery(transferInPMTCTSql); + transferInPMTCTSqlCD.addParameter(new Parameter("onOrAfter", "On Or After", Date.class)); + transferInPMTCTSqlCD.addParameter(new Parameter("onOrBefore", "On Or Before", Date.class)); + + // Patients with drugs spaning <=3months with appt dates + SqlCohortDefinition multiMonthSqlCD = new SqlCohortDefinition(); + String multiMonthSql = getStringFromResource("org/openmrs/module/drcreports/sql/DRCTxCurrMultiMonth.sql"); + multiMonthSqlCD.setQuery(multiMonthSql); + multiMonthSqlCD.addParameter(new Parameter("onOrAfter", "On Or After", Date.class)); + multiMonthSqlCD.addParameter(new Parameter("onOrBefore", "On Or Before", Date.class)); + + // Not dead according to death attribute + BirthAndDeathCohortDefinition alive = new BirthAndDeathCohortDefinition(); + alive.setDied(false); + //Not dead according to death form + SqlCohortDefinition liveSqlCD = new SqlCohortDefinition(); + String liveSql = getStringFromResource("org/openmrs/module/drcreports/sql/DRCLivePatients.sql"); + liveSqlCD.setQuery(liveSql); + + // Not stopped ART in date range + SqlCohortDefinition notStoppedARTSqlCD = new SqlCohortDefinition(); + String notStoppedARTSql = getStringFromResource("org/openmrs/module/drcreports/sql/DRCTxCurrNotStoppedART.sql"); + notStoppedARTSqlCD.setQuery(notStoppedARTSql); + notStoppedARTSqlCD.addParameter(new Parameter("onOrAfter", "On Or After", Date.class)); + notStoppedARTSqlCD.addParameter(new Parameter("onOrBefore", "On Or Before", Date.class)); + + // Not Transferred out in date range + SqlCohortDefinition notTransferredOutSqlCD = new SqlCohortDefinition(); + String notTransferredOutSql = getStringFromResource( + "org/openmrs/module/drcreports/sql/DRCTxCurrNotTransferredOut.sql"); + notTransferredOutSqlCD.setQuery(notTransferredOutSql); + notTransferredOutSqlCD.addParameter(new Parameter("onOrAfter", "On Or After", Date.class)); + notTransferredOutSqlCD.addParameter(new Parameter("onOrBefore", "On Or Before", Date.class)); + + // Interrupted in date range + SqlCohortDefinition interruptedSqlCD = new SqlCohortDefinition(); + String interruptedSql = getStringFromResource("org/openmrs/module/drcreports/sql/DRCTxCurrInterrupted.sql"); + interruptedSqlCD.setQuery(interruptedSql); + interruptedSqlCD.addParameter(new Parameter("onOrAfter", "On Or After", Date.class)); + interruptedSqlCD.addParameter(new Parameter("onOrBefore", "On Or Before", Date.class)); + + // Less than 3 months ART Dispensation + SqlCohortDefinition belowThreeMonthsDispensingSqlCD = new SqlCohortDefinition(); + String belowThreeMonthsDispensingSql = getStringFromResource( + "org/openmrs/module/drcreports/sql/DRCArtLessthanThreeMonthsDispense.sql"); + belowThreeMonthsDispensingSqlCD.setQuery(belowThreeMonthsDispensingSql); + + // 3-5 months ART Dispensation + SqlCohortDefinition threeToFiveMonthsDispensingSqlCD = new SqlCohortDefinition(); + String threeToFiveMonthsDispensingSql = getStringFromResource( + "org/openmrs/module/drcreports/sql/DRCArtThreeToFiveMonthsDispense.sql"); + threeToFiveMonthsDispensingSqlCD.setQuery(threeToFiveMonthsDispensingSql); + + // 6 months and Above ART Dispensation + SqlCohortDefinition sixMonthsAndAboveDispensingSqlCD = new SqlCohortDefinition(); + String sixMonthsAndAboveDispensingSql = getStringFromResource( + "org/openmrs/module/drcreports/sql/DRCArtSixAndAboveMonthsDispense.sql"); + sixMonthsAndAboveDispensingSqlCD.setQuery(sixMonthsAndAboveDispensingSql); + + CompositionCohortDefinition ccd = new CompositionCohortDefinition(); + CompositionCohortDefinition atleastInArtInitiationOrTransferInOrPMTCTOrMultiMonthCD = new CompositionCohortDefinition(); + + // Composition for the OR condition (artInitiation OR resumeARTSqlCD OR transferInPMTCT OR multiMonth) + + atleastInArtInitiationOrTransferInOrPMTCTOrMultiMonthCD.initializeFromQueries(BooleanOperator.OR, artInitiationSqlCD, + resumeARTSqlCD, transferInPMTCTSqlCD, multiMonthSqlCD); + + // Remove interrupted Treatment patients + CompositionCohortDefinition excludingInterruptedCD = new CompositionCohortDefinition(); + + excludingInterruptedCD.initializeFromQueries(BooleanOperator.NOT, + atleastInArtInitiationOrTransferInOrPMTCTOrMultiMonthCD, interruptedSqlCD); + + // OR condition with the AND conditions (alive AND live AND Not stopped art AND Not Transferred Out) + ccd.initializeFromElements(excludingInterruptedCD, alive, liveSqlCD, notStoppedARTSqlCD, notTransferredOutSqlCD, + pecd); + + CompositionCohortDefinition interup = new CompositionCohortDefinition(); + interup.initializeFromElements(interruptedSqlCD); + + CompositionCohortDefinition lessThanThreeMonthsccd = new CompositionCohortDefinition(); + lessThanThreeMonthsccd.initializeFromElements(ccd, belowThreeMonthsDispensingSqlCD); + + CompositionCohortDefinition threeToFiveMonthsccd = new CompositionCohortDefinition(); + threeToFiveMonthsccd.initializeFromElements(ccd, threeToFiveMonthsDispensingSqlCD); + + CompositionCohortDefinition sixAndAboveMonthsccd = new CompositionCohortDefinition(); + sixAndAboveMonthsccd.initializeFromElements(ccd, sixMonthsAndAboveDispensingSqlCD); + + CompositionCohortDefinition ccd1 = new CompositionCohortDefinition(); + ccd1.initializeFromElements(artInitiationSqlCD, alive, liveSqlCD); + + CompositionCohortDefinition ccd2 = new CompositionCohortDefinition(); + ccd2.initializeFromElements(transferInPMTCTSqlCD, alive, liveSqlCD); + + CompositionCohortDefinition ccd3 = new CompositionCohortDefinition(); + ccd3.initializeFromElements(multiMonthSqlCD, alive, liveSqlCD); + + CompositionCohortDefinition ccd4 = new CompositionCohortDefinition(); + ccd4.initializeFromElements(liveSqlCD, alive, liveSqlCD); + + CompositionCohortDefinition ccd5 = new CompositionCohortDefinition(); + ccd5.initializeFromElements(resumeARTSqlCD, alive, liveSqlCD); + + txCurr.addRow("interup", interup, parameterMappings); + + txCurr.addRow(getName(), ccd, parameterMappings); + txCurr.addRow(MessageUtil.translate("drcreports.report.drc.lessThanThreeMonthsDrugsGiven.label"), + lessThanThreeMonthsccd, parameterMappings); + txCurr.addRow(MessageUtil.translate("drcreports.report.drc.threeToFiveMonthsDrugsGiven.label"), threeToFiveMonthsccd, + parameterMappings); + txCurr.addRow(MessageUtil.translate("drcreports.report.drc.sixPlusMonthsDrugsGiven.label"), sixAndAboveMonthsccd, + parameterMappings); + + setColumnNames(); + + GenderCohortDefinition males = new GenderCohortDefinition(); + males.setMaleIncluded(true); + + GenderCohortDefinition females = new GenderCohortDefinition(); + females.setFemaleIncluded(true); + + GenderCohortDefinition allGenders = new GenderCohortDefinition(); + allGenders.setFemaleIncluded(true); + allGenders.setMaleIncluded(true); + + txCurr.addColumn(col0, createCohortComposition(allGenders), null); + + // < 1 year + AgeCohortDefinition under1y = new AgeCohortDefinition(); + under1y.setMinAge(0); + under1y.setMinAgeUnit(DurationUnit.DAYS); + under1y.setMaxAge(11); + under1y.setMaxAgeUnit(DurationUnit.MONTHS); + under1y.addParameter(new Parameter("effectiveDate", "Effective Date", Date.class)); + txCurr.addColumn(col1, createCohortComposition(under1y, males), null); + txCurr.addColumn(col2, createCohortComposition(under1y, females), null); + + // 1-4 years + AgeCohortDefinition _1To4y = new AgeCohortDefinition(); + _1To4y.setMinAge(1); + _1To4y.setMinAgeUnit(DurationUnit.YEARS); + _1To4y.setMaxAge(4); + _1To4y.setMaxAgeUnit(DurationUnit.YEARS); + _1To4y.addParameter(new Parameter("effectiveDate", "Effective Date", Date.class)); + txCurr.addColumn(col3, createCohortComposition(_1To4y, males), null); + txCurr.addColumn(col4, createCohortComposition(_1To4y, females), null); + + // 5-9 years + AgeCohortDefinition _5To9y = new AgeCohortDefinition(); + _5To9y.setMinAge(5); + _5To9y.setMinAgeUnit(DurationUnit.YEARS); + _5To9y.setMaxAge(9); + _5To9y.setMaxAgeUnit(DurationUnit.YEARS); + _5To9y.addParameter(new Parameter("effectiveDate", "Effective Date", Date.class)); + txCurr.addColumn(col5, createCohortComposition(_5To9y, males), null); + txCurr.addColumn(col6, createCohortComposition(_5To9y, females), null); + + // 10-14 years + AgeCohortDefinition _10To14y = new AgeCohortDefinition(); + _10To14y.setMinAge(10); + _10To14y.setMinAgeUnit(DurationUnit.YEARS); + _10To14y.setMaxAge(14); + _10To14y.setMaxAgeUnit(DurationUnit.YEARS); + _10To14y.addParameter(new Parameter("effectiveDate", "Effective Date", Date.class)); + txCurr.addColumn(col7, createCohortComposition(_10To14y, males), null); + txCurr.addColumn(col8, createCohortComposition(_10To14y, females), null); + + // 15-19 years + AgeCohortDefinition _15To19y = new AgeCohortDefinition(); + _15To19y.setMinAge(15); + _15To19y.setMinAgeUnit(DurationUnit.YEARS); + _15To19y.setMaxAge(19); + _15To19y.setMaxAgeUnit(DurationUnit.YEARS); + _15To19y.addParameter(new Parameter("effectiveDate", "Effective Date", Date.class)); + txCurr.addColumn(col9, createCohortComposition(_15To19y, males), null); + txCurr.addColumn(col10, createCohortComposition(_15To19y, females), null); + + // 20-24 years + AgeCohortDefinition _20To24y = new AgeCohortDefinition(); + _20To24y.setMinAge(20); + _20To24y.setMinAgeUnit(DurationUnit.YEARS); + _20To24y.setMaxAge(24); + _20To24y.setMaxAgeUnit(DurationUnit.YEARS); + _20To24y.addParameter(new Parameter("effectiveDate", "Effective Date", Date.class)); + txCurr.addColumn(col11, createCohortComposition(_20To24y, males), null); + txCurr.addColumn(col12, createCohortComposition(_20To24y, females), null); + + // 25-49 years + AgeCohortDefinition _25To29y = new AgeCohortDefinition(); + _25To29y.setMinAge(25); + _25To29y.setMinAgeUnit(DurationUnit.YEARS); + _25To29y.setMaxAge(29); + _25To29y.setMaxAgeUnit(DurationUnit.YEARS); + _25To29y.addParameter(new Parameter("effectiveDate", "Effective Date", Date.class)); + txCurr.addColumn(col13, createCohortComposition(_25To29y, males), null); + txCurr.addColumn(col14, createCohortComposition(_25To29y, females), null); + + // 30-34 years + AgeCohortDefinition _30To34y = new AgeCohortDefinition(); + _30To34y.setMinAge(30); + _30To34y.setMinAgeUnit(DurationUnit.YEARS); + _30To34y.setMaxAge(34); + _30To34y.setMaxAgeUnit(DurationUnit.YEARS); + _30To34y.addParameter(new Parameter("effectiveDate", "Effective Date", Date.class)); + txCurr.addColumn(col15, createCohortComposition(_30To34y, males), null); + txCurr.addColumn(col16, createCohortComposition(_30To34y, females), null); + + // 35-39 years + AgeCohortDefinition _35To39y = new AgeCohortDefinition(); + _35To39y.setMinAge(35); + _35To39y.setMinAgeUnit(DurationUnit.YEARS); + _35To39y.setMaxAge(39); + _35To39y.setMaxAgeUnit(DurationUnit.YEARS); + _35To39y.addParameter(new Parameter("effectiveDate", "Effective Date", Date.class)); + txCurr.addColumn(col17, createCohortComposition(_35To39y, males), null); + txCurr.addColumn(col18, createCohortComposition(_35To39y, females), null); + + // 40-44 years + AgeCohortDefinition _40To44y = new AgeCohortDefinition(); + _40To44y.setMinAge(40); + _40To44y.setMinAgeUnit(DurationUnit.YEARS); + _40To44y.setMaxAge(44); + _40To44y.setMaxAgeUnit(DurationUnit.YEARS); + _40To44y.addParameter(new Parameter("effectiveDate", "Effective Date", Date.class)); + txCurr.addColumn(col19, createCohortComposition(_40To44y, males), null); + txCurr.addColumn(col20, createCohortComposition(_40To44y, females), null); + + // 45-49 years + AgeCohortDefinition _45To49y = new AgeCohortDefinition(); + _45To49y.setMinAge(45); + _45To49y.setMinAgeUnit(DurationUnit.YEARS); + _45To49y.setMaxAge(49); + _45To49y.setMaxAgeUnit(DurationUnit.YEARS); + _45To49y.addParameter(new Parameter("effectiveDate", "Effective Date", Date.class)); + txCurr.addColumn(col21, createCohortComposition(_45To49y, males), null); + txCurr.addColumn(col22, createCohortComposition(_45To49y, females), null); + + // 50-54 years + AgeCohortDefinition _50To54y = new AgeCohortDefinition(); + _50To54y.setMinAge(50); + _50To54y.setMinAgeUnit(DurationUnit.YEARS); + _50To54y.setMaxAge(54); + _50To54y.setMaxAgeUnit(DurationUnit.YEARS); + _50To54y.addParameter(new Parameter("effectiveDate", "Effective Date", Date.class)); + txCurr.addColumn(col23, createCohortComposition(_50To54y, males), null); + txCurr.addColumn(col24, createCohortComposition(_50To54y, females), null); + + // 55-59 years + AgeCohortDefinition _55To59y = new AgeCohortDefinition(); + _55To59y.setMinAge(55); + _55To59y.setMinAgeUnit(DurationUnit.YEARS); + _55To59y.setMaxAge(59); + _55To59y.setMaxAgeUnit(DurationUnit.YEARS); + _55To59y.addParameter(new Parameter("effectiveDate", "Effective Date", Date.class)); + txCurr.addColumn(col25, createCohortComposition(_55To59y, males), null); + txCurr.addColumn(col26, createCohortComposition(_55To59y, females), null); + + // 60-64 years + AgeCohortDefinition _60To64y = new AgeCohortDefinition(); + _60To64y.setMinAge(60); + _60To64y.setMinAgeUnit(DurationUnit.YEARS); + _60To64y.setMaxAge(64); + _60To64y.setMaxAgeUnit(DurationUnit.YEARS); + _60To64y.addParameter(new Parameter("effectiveDate", "Effective Date", Date.class)); + txCurr.addColumn(col27, createCohortComposition(_60To64y, males), null); + txCurr.addColumn(col28, createCohortComposition(_60To64y, females), null); + + // 65+ years + AgeCohortDefinition _66To69y = new AgeCohortDefinition(); + _66To69y.setMinAge(65); + _66To69y.setMinAgeUnit(DurationUnit.YEARS); + _66To69y.setMaxAge(200); + _66To69y.setMaxAgeUnit(DurationUnit.YEARS); + _66To69y.addParameter(new Parameter("effectiveDate", "Effective Date", Date.class)); + txCurr.addColumn(col29, createCohortComposition(_66To69y, males), null); + txCurr.addColumn(col30, createCohortComposition(_66To69y, females), null); + + // <15 years + AgeCohortDefinition below15y = new AgeCohortDefinition(); + below15y.setMinAge(0); + below15y.setMinAgeUnit(DurationUnit.DAYS); + below15y.setMaxAge(14); + below15y.setMaxAgeUnit(DurationUnit.YEARS); + below15y.addParameter(new Parameter("effectiveDate", "Effective Date", Date.class)); + txCurr.addColumn(col31, createCohortComposition(below15y, males), null); + txCurr.addColumn(col32, createCohortComposition(below15y, females), null); + + // 15+ years + AgeCohortDefinition above15y = new AgeCohortDefinition(); + above15y.setMinAge(15); + above15y.setMinAgeUnit(DurationUnit.YEARS); + above15y.setMaxAge(200); + above15y.setMaxAgeUnit(DurationUnit.YEARS); + above15y.addParameter(new Parameter("effectiveDate", "Effective Date", Date.class)); + txCurr.addColumn(col33, createCohortComposition(above15y, males), null); + txCurr.addColumn(col34, createCohortComposition(above15y, females), null); + + return rd; + } + + private void setColumnNames() { + col0 = MessageUtil.translate("drcreports.report.drc.total.label"); + + col1 = MessageUtil.translate("drcreports.report.drc.belowOneYrMales.label"); + col2 = MessageUtil.translate("drcreports.report.drc.belowOneYrFemales.label"); + + col3 = MessageUtil.translate("drcreports.report.drc.oneToFourYrsMales.label"); + col4 = MessageUtil.translate("drcreports.report.drc.oneToFourYrsFemales.label"); + col5 = MessageUtil.translate("drcreports.report.drc.fiveToNineYrsMales.label"); + col6 = MessageUtil.translate("drcreports.report.drc.fiveToNineYrsFemales.label"); + col7 = MessageUtil.translate("drcreports.report.drc.tenToFourteenYrsMales.label"); + col8 = MessageUtil.translate("drcreports.report.drc.tenToFourteenYrsFemales.label"); + col9 = MessageUtil.translate("drcreports.report.drc.fifteenToNineteenYrsMales.label"); + col10 = MessageUtil.translate("drcreports.report.drc.fifteenToNineteenYrsFemales.label"); + + col11 = MessageUtil.translate("drcreports.report.drc.twentyToTwentyFourYrsMales.label"); + col12 = MessageUtil.translate("drcreports.report.drc.twentyToTwentyFourYrsFemales.label"); + col13 = MessageUtil.translate("drcreports.report.drc.twentyFiveToTwentyNineYrsMales.label"); + col14 = MessageUtil.translate("drcreports.report.drc.twentyFiveToTwentyNineYrsFemales.label"); + + col15 = MessageUtil.translate("drcreports.report.drc.thirtyToThirtyFourYrsMales.label"); + col16 = MessageUtil.translate("drcreports.report.drc.thirtyToThirtyFourYrsFemales.label"); + col17 = MessageUtil.translate("drcreports.report.drc.thirtyFiveToThirtyNineYrsMales.label"); + col18 = MessageUtil.translate("drcreports.report.drc.thirtyFiveToThirtyNineYrsFemales.label"); + col19 = MessageUtil.translate("drcreports.report.drc.fortyToFortyFourYrsMales.label"); + col20 = MessageUtil.translate("drcreports.report.drc.fortyToFortyFourYrsFemales.label"); + col21 = MessageUtil.translate("drcreports.report.drc.fortyFiveToFortyNineYrsMales.label"); + col22 = MessageUtil.translate("drcreports.report.drc.fortyFiveToFortyNineYrsFemales.label"); + + col23 = MessageUtil.translate("drcreports.report.drc.fiftyToFiftyFourYrsMales.label"); + col24 = MessageUtil.translate("drcreports.report.drc.fiftyToFiftyFourYrsFemales.label"); + col25 = MessageUtil.translate("drcreports.report.drc.fiftyFiveToFiftyNineYrsMales.label"); + col26 = MessageUtil.translate("drcreports.report.drc.fiftyFiveToFiftyNineYrsFemales.label"); + col27 = MessageUtil.translate("drcreports.report.drc.sixtyToSixtyFourYrsMales.label"); + col28 = MessageUtil.translate("drcreports.report.drc.sixtyToSixtyFourYrsFemales.label"); + col29 = MessageUtil.translate("drcreports.report.drc.sixtyFiveAndAboveMales.label"); + col30 = MessageUtil.translate("drcreports.report.drc.sixtyFiveAndAboveFemales.label"); + + col31 = MessageUtil.translate("drcreports.report.drc.belowFifteenYrsMales.label"); + col32 = MessageUtil.translate("drcreports.report.drc.belowFifteenYrsFemales.label"); + col33 = MessageUtil.translate("drcreports.report.drc.fifteenYrsAndAboveMales.label"); + col34 = MessageUtil.translate("drcreports.report.drc.fifteenYrsAndAboveFemales.label"); + + } + + private CompositionCohortDefinition createCohortComposition(Object... elements) { + CompositionCohortDefinition compCD = new CompositionCohortDefinition(); + compCD.initializeFromElements(elements); + return compCD; + } + + @Override + public List constructReportDesigns(ReportDefinition reportDefinition) { + return Arrays + .asList(ReportManagerUtil.createCsvReportDesign("cb45687b-51b1-4d5d-a6a1-7a29ffd4d314", reportDefinition)); + + } +} diff --git a/api/src/main/resources/messages.properties b/api/src/main/resources/messages.properties index 2caa16c..448d7b2 100644 --- a/api/src/main/resources/messages.properties +++ b/api/src/main/resources/messages.properties @@ -360,6 +360,66 @@ ${project.parent.artifactId}.report.drc.ptStartedOnArtWithVLGT12MonthsLessEqual5 ${project.parent.artifactId}.report.drc.ptStartedOnArtWithVLGT12MonthsGreater50LessEqual1000=PLHIV on ARV who received biological monitoring of viral load at > 12 months > 50 and ≤ 1000 copies/ML ${project.parent.artifactId}.report.drc.ptStartedOnArtWithVLGT12MonthsGreaterthan1000=PLHIV on ARV who received biological monitoring of viral load at > 12 months > 1000 copies/ML +${project.parent.artifactId}.report.drc.txCurr.reportName=DRC TX_CURR Report +${project.parent.artifactId}.report.drc.txCurr.reportDescription=DRC TX_CURR Report + +${project.parent.artifactId}.report.drc.total.label=Total + +${project.parent.artifactId}.report.drc.belowOneYrMales.label=Below 1 year (Males) +${project.parent.artifactId}.report.drc.belowOneYrFemales.label=Below 1 year (Females) + +${project.parent.artifactId}.report.drc.oneToFourYrsMales.label=1-4 years (Males) +${project.parent.artifactId}.report.drc.oneToFourYrsFemales.label=1-4 years (Females) + +${project.parent.artifactId}.report.drc.fiveToNineYrsMales.label=5-9 years (Males) +${project.parent.artifactId}.report.drc.fiveToNineYrsFemales.label=5-9 years (Females) + +${project.parent.artifactId}.report.drc.tenToFourteenYrsMales.label=10-14 years (Males) +${project.parent.artifactId}.report.drc.tenToFourteenYrsFemales.label=10-14 years (Females) + +${project.parent.artifactId}.report.drc.fifteenToNineteenYrsMales.label=15-19 years (Males) +${project.parent.artifactId}.report.drc.fifteenToNineteenYrsFemales.label=15-19 years (Females) + +${project.parent.artifactId}.report.drc.twentyToTwentyFourYrsMales.label=20-24 years (Males) +${project.parent.artifactId}.report.drc.twentyToTwentyFourYrsFemales.label=20-24 years (Females) + +${project.parent.artifactId}.report.drc.twentyFiveToTwentyNineYrsMales.label=25-29 years (Males) +${project.parent.artifactId}.report.drc.twentyFiveToTwentyNineYrsFemales.label=25-29 years (Females) + +${project.parent.artifactId}.report.drc.thirtyToThirtyFourYrsMales.label=30-34 years (Males) +${project.parent.artifactId}.report.drc.thirtyToThirtyFourYrsFemales.label=30-34 years (Females) + +${project.parent.artifactId}.report.drc.thirtyFiveToThirtyNineYrsMales.label=35-39 years (Males) +${project.parent.artifactId}.report.drc.thirtyFiveToThirtyNineYrsFemales.label=35-39 years (Females) + +${project.parent.artifactId}.report.drc.fortyToFortyFourYrsMales.label=40-44 years (Males) +${project.parent.artifactId}.report.drc.fortyToFortyFourYrsFemales.label=40-44 years (Females) + +${project.parent.artifactId}.report.drc.fortyFiveToFortyNineYrsMales.label=45-49 years (Males) +${project.parent.artifactId}.report.drc.fortyFiveToFortyNineYrsFemales.label=45-49 years (Females) + +${project.parent.artifactId}.report.drc.fiftyToFiftyFourYrsMales.label=50-54 years (Males) +${project.parent.artifactId}.report.drc.fiftyToFiftyFourYrsFemales.label=50-54 years (Females) + +${project.parent.artifactId}.report.drc.fiftyFiveToFiftyNineYrsMales.label=55-59 years (Males) +${project.parent.artifactId}.report.drc.fiftyFiveToFiftyNineYrsFemales.label=55-59 years (Females) + +${project.parent.artifactId}.report.drc.sixtyToSixtyFourYrsMales.label=60-64 years (Males) +${project.parent.artifactId}.report.drc.sixtyToSixtyFourYrsFemales.label=60-64 years (Females) + +${project.parent.artifactId}.report.drc.sixtyFiveAndAboveMales.label=65+ years (Males) +${project.parent.artifactId}.report.drc.sixtyFiveAndAboveFemales.label=65+ years (Females) + +${project.parent.artifactId}.report.drc.belowFifteenYrsMales.label=Below 15 years (Males) +${project.parent.artifactId}.report.drc.belowFifteenYrsFemales.label=Below 15 years (Females) + +${project.parent.artifactId}.report.drc.fifteenYrsAndAboveMales.label=15+ years (Males) +${project.parent.artifactId}.report.drc.fifteenYrsAndAboveFemales.label=15+ years (Females) + +${project.parent.artifactId}.report.drc.lessThanThreeMonthsDrugsGiven.label=< 3 months drugs +${project.parent.artifactId}.report.drc.threeToFiveMonthsDrugsGiven.label=3-5 months drugs +${project.parent.artifactId}.report.drc.sixPlusMonthsDrugsGiven.label=6+ months drugs + ${project.parent.artifactId}.report.visits.reportName=Visits Report ${project.parent.artifactId}.report.visits.reportDescription= ${project.parent.artifactId}.report.visits.datasetName=Visits SQL Dataset diff --git a/api/src/main/resources/messages_fr.properties b/api/src/main/resources/messages_fr.properties index f0a9d07..b46c491 100644 --- a/api/src/main/resources/messages_fr.properties +++ b/api/src/main/resources/messages_fr.properties @@ -350,6 +350,66 @@ ${project.parent.artifactId}.report.drc.ptStartedOnArtWithVLGT12MonthsGreatertha ${project.parent.artifactId}.report.drc.artAbandonment.reportName=Patients de la RDC ayant abandonné ou refusé le traitement antirétroviral ${project.parent.artifactId}.report.drc.artAbandonment.datasetName=Patients de la RDC ayant abandonné ou refusé le traitement antirétroviral +${project.parent.artifactId}.report.drc.txCurr.reportName=Rapport TX_CURR RDC +${project.parent.artifactId}.report.drc.txCurr.reportDescription=Rapport TX_CURR RDC + +${project.parent.artifactId}.report.drc.total.label=Total + +${project.parent.artifactId}.report.drc.belowOneYrMales.label=Moins d’1 an (Hommes) +${project.parent.artifactId}.report.drc.belowOneYrFemales.label=Moins d’1 an (Femmes) + +${project.parent.artifactId}.report.drc.oneToFourYrsMales.label=1-4 ans (Hommes) +${project.parent.artifactId}.report.drc.oneToFourYrsFemales.label=1-4 ans (Femmes) + +${project.parent.artifactId}.report.drc.fiveToNineYrsMales.label=5-9 ans (Hommes) +${project.parent.artifactId}.report.drc.fiveToNineYrsFemales.label=5-9 ans (Femmes) + +${project.parent.artifactId}.report.drc.tenToFourteenYrsMales.label=10-14 ans (Hommes) +${project.parent.artifactId}.report.drc.tenToFourteenYrsFemales.label=10-14 ans (Femmes) + +${project.parent.artifactId}.report.drc.fifteenToNineteenYrsMales.label=15-19 ans (Hommes) +${project.parent.artifactId}.report.drc.fifteenToNineteenYrsFemales.label=15-19 ans (Femmes) + +${project.parent.artifactId}.report.drc.twentyToTwentyFourYrsMales.label=20-24 ans (Hommes) +${project.parent.artifactId}.report.drc.twentyToTwentyFourYrsFemales.label=20-24 ans (Femmes) + +${project.parent.artifactId}.report.drc.twentyFiveToTwentyNineYrsMales.label=25-29 ans (Hommes) +${project.parent.artifactId}.report.drc.twentyFiveToTwentyNineYrsFemales.label=25-29 ans (Femmes) + +${project.parent.artifactId}.report.drc.thirtyToThirtyFourYrsMales.label=30-34 ans (Hommes) +${project.parent.artifactId}.report.drc.thirtyToThirtyFourYrsFemales.label=30-34 ans (Femmes) + +${project.parent.artifactId}.report.drc.thirtyFiveToThirtyNineYrsMales.label=35-39 ans (Hommes) +${project.parent.artifactId}.report.drc.thirtyFiveToThirtyNineYrsFemales.label=35-39 ans (Femmes) + +${project.parent.artifactId}.report.drc.fortyToFortyFourYrsMales.label=40-44 ans (Hommes) +${project.parent.artifactId}.report.drc.fortyToFortyFourYrsFemales.label=40-44 ans (Femmes) + +${project.parent.artifactId}.report.drc.fortyFiveToFortyNineYrsMales.label=45-49 ans (Hommes) +${project.parent.artifactId}.report.drc.fortyFiveToFortyNineYrsFemales.label=45-49 ans (Femmes) + +${project.parent.artifactId}.report.drc.fiftyToFiftyFourYrsMales.label=50-54 ans (Hommes) +${project.parent.artifactId}.report.drc.fiftyToFiftyFourYrsFemales.label=50-54 ans (Femmes) + +${project.parent.artifactId}.report.drc.fiftyFiveToFiftyNineYrsMales.label=55-59 ans (Hommes) +${project.parent.artifactId}.report.drc.fiftyFiveToFiftyNineYrsFemales.label=55-59 ans (Femmes) + +${project.parent.artifactId}.report.drc.sixtyToSixtyFourYrsMales.label=60-64 ans (Hommes) +${project.parent.artifactId}.report.drc.sixtyToSixtyFourYrsFemales.label=60-64 ans (Femmes) + +${project.parent.artifactId}.report.drc.sixtyFiveAndAboveMales.label=65 ans et plus (Hommes) +${project.parent.artifactId}.report.drc.sixtyFiveAndAboveFemales.label=65 ans et plus (Femmes) + +${project.parent.artifactId}.report.drc.belowFifteenYrsMales.label=Moins de 15 ans (Hommes) +${project.parent.artifactId}.report.drc.belowFifteenYrsFemales.label=Moins de 15 ans (Femmes) + +${project.parent.artifactId}.report.drc.fifteenYrsAndAboveMales.label=15 ans et plus (Hommes) +${project.parent.artifactId}.report.drc.fifteenYrsAndAboveFemales.label=15 ans et plus (Femmes) + +${project.parent.artifactId}.report.drc.lessThanThreeMonthsDrugsGiven.label=Devrait \u00EAtre inf\u00E9rieur \u00E0 3 mois +${project.parent.artifactId}.report.drc.threeToFiveMonthsDrugsGiven.label=M\u00E9dicaments pour 3 \u00E0 5 mois +${project.parent.artifactId}.report.drc.sixPlusMonthsDrugsGiven.label=M\u00E9dicaments pour 6 mois et plus + ${project.parent.artifactId}.report.visits.reportName=Rapport de la Table des Visites ${project.parent.artifactId}.report.visits.reportDescription=Rapport de la Table des Visites ${project.parent.artifactId}.report.visits.datasetName=Jeu de Données SQL des Visites diff --git a/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCArtLessthanThreeMonthsDispense.sql b/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCArtLessthanThreeMonthsDispense.sql new file mode 100644 index 0000000..8c1b9cf --- /dev/null +++ b/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCArtLessthanThreeMonthsDispense.sql @@ -0,0 +1,24 @@ +SELECT DISTINCT p.patient_id +FROM patient p +INNER JOIN person pe ON p.patient_id = pe.person_id +WHERE pe.voided = 0 + AND p.voided = 0 + AND EXISTS ( + SELECT 1 + FROM obs o + INNER JOIN concept c ON o.concept_id = c.concept_id + WHERE o.person_id = p.patient_id + AND o.voided = 0 + AND c.uuid = '3a0709e9-d7a8-44b9-9512-111db5ce3989' + AND o.value_numeric < 90 + AND o.obs_datetime = ( + SELECT MAX(o2.obs_datetime) + FROM obs o2 + INNER JOIN concept c2 ON o2.concept_id = c2.concept_id + WHERE o2.person_id = o.person_id + AND o2.voided = 0 + AND c2.uuid = '3a0709e9-d7a8-44b9-9512-111db5ce3989' + AND o2.value_numeric IS NOT NULL + ) + ) +ORDER BY p.patient_id; \ No newline at end of file diff --git a/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCArtSixAndAboveMonthsDispense.sql b/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCArtSixAndAboveMonthsDispense.sql new file mode 100644 index 0000000..8ee8e66 --- /dev/null +++ b/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCArtSixAndAboveMonthsDispense.sql @@ -0,0 +1,24 @@ +SELECT DISTINCT p.patient_id +FROM patient p +INNER JOIN person pe ON p.patient_id = pe.person_id +WHERE pe.voided = 0 + AND p.voided = 0 + AND EXISTS ( + SELECT 1 + FROM obs o + INNER JOIN concept c ON o.concept_id = c.concept_id + WHERE o.person_id = p.patient_id + AND o.voided = 0 + AND c.uuid = '3a0709e9-d7a8-44b9-9512-111db5ce3989' + AND o.value_numeric >= 180 + AND o.obs_datetime = ( + SELECT MAX(o2.obs_datetime) + FROM obs o2 + INNER JOIN concept c2 ON o2.concept_id = c2.concept_id + WHERE o2.person_id = o.person_id + AND o2.voided = 0 + AND c2.uuid = '3a0709e9-d7a8-44b9-9512-111db5ce3989' + AND o2.value_numeric IS NOT NULL + ) + ) +ORDER BY p.patient_id; \ No newline at end of file diff --git a/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCArtThreeToFiveMonthsDispense.sql b/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCArtThreeToFiveMonthsDispense.sql new file mode 100644 index 0000000..689b5c9 --- /dev/null +++ b/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCArtThreeToFiveMonthsDispense.sql @@ -0,0 +1,26 @@ +SELECT DISTINCT p.patient_id +FROM patient p +INNER JOIN person pe ON p.patient_id = pe.person_id +WHERE pe.voided = 0 + AND p.voided = 0 + AND EXISTS ( + SELECT 1 + FROM obs o + INNER JOIN concept c ON o.concept_id = c.concept_id + WHERE o.person_id = p.patient_id + AND o.voided = 0 + AND c.uuid = '3a0709e9-d7a8-44b9-9512-111db5ce3989' + AND o.value_numeric IS NOT NULL + AND o.value_numeric >= 90 + AND o.value_numeric <= 179 + AND o.obs_datetime = ( + SELECT MAX(o2.obs_datetime) + FROM obs o2 + INNER JOIN concept c2 ON o2.concept_id = c2.concept_id + WHERE o2.person_id = o.person_id + AND o2.voided = 0 + AND c2.uuid = '3a0709e9-d7a8-44b9-9512-111db5ce3989' + AND o2.value_numeric IS NOT NULL + ) + ) +ORDER BY p.patient_id; \ No newline at end of file diff --git a/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCLivePatients.sql b/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCLivePatients.sql new file mode 100644 index 0000000..c3a5db8 --- /dev/null +++ b/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCLivePatients.sql @@ -0,0 +1,15 @@ +SELECT DISTINCT p.patient_id +FROM patient p +INNER JOIN person pe ON p.patient_id = pe.person_id +WHERE pe.voided = 0 + AND p.voided = 0 + AND NOT EXISTS ( + -- Check that patient does NOT have death date observation + SELECT 1 + FROM obs o + INNER JOIN concept c ON o.concept_id = c.concept_id + WHERE o.person_id = p.patient_id + AND o.voided = 0 + AND c.uuid = '1543AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + ) +ORDER BY p.patient_id; \ No newline at end of file diff --git a/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCTxCurrInitiation.sql b/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCTxCurrInitiation.sql new file mode 100644 index 0000000..a7fd7c6 --- /dev/null +++ b/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCTxCurrInitiation.sql @@ -0,0 +1,27 @@ +SELECT DISTINCT p.patient_id +FROM patient p +INNER JOIN person pe ON p.patient_id = pe.person_id +WHERE pe.voided = 0 + AND p.voided = 0 + AND EXISTS ( + SELECT 1 + FROM obs o + INNER JOIN concept c_question ON o.concept_id = c_question.concept_id + INNER JOIN concept c_answer ON o.value_coded = c_answer.concept_id + WHERE o.person_id = p.patient_id + AND o.voided = 0 + AND c_question.uuid = '1255AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' -- ART initiation during this visit + AND c_answer.uuid = '1256AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' -- Start ART + AND DATE(o.obs_datetime) BETWEEN :onOrAfter AND :onOrBefore + ) + AND EXISTS ( + -- Check for initiation date concept within date range + SELECT 1 + FROM obs o_init_date + INNER JOIN concept c_init_date ON o_init_date.concept_id = c_init_date.concept_id + WHERE o_init_date.person_id = p.patient_id + AND o_init_date.voided = 0 + AND c_init_date.uuid = '159599AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' -- Initiation date concept + AND DATE(o_init_date.value_datetime) BETWEEN :onOrAfter AND :onOrBefore + ) +ORDER BY p.patient_id; diff --git a/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCTxCurrInterrupted.sql b/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCTxCurrInterrupted.sql new file mode 100644 index 0000000..673643b --- /dev/null +++ b/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCTxCurrInterrupted.sql @@ -0,0 +1,64 @@ +SELECT DISTINCT p.patient_id +FROM patient p +INNER JOIN person pe ON p.patient_id = pe.person_id +WHERE pe.voided = 0 + AND p.voided = 0 + AND EXISTS ( + -- Filter for patients who have refill dates in the reporting period + SELECT 1 + FROM obs o_appt + INNER JOIN concept c_appt ON o_appt.concept_id = c_appt.concept_id + WHERE o_appt.person_id = p.patient_id + AND o_appt.voided = 0 + AND c_appt.uuid = '162549AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' -- Next Refill Date concept + AND DATE(o_appt.value_datetime) >= :onOrAfter + AND DATE(o_appt.value_datetime) <= :onOrBefore + ) + AND NOT EXISTS ( + -- Exclude patients who meet the compliance criteria based on their latest refill date + SELECT 1 + FROM obs o_appt + INNER JOIN concept c_appt ON o_appt.concept_id = c_appt.concept_id + WHERE o_appt.person_id = p.patient_id + AND o_appt.voided = 0 + AND c_appt.uuid = '162549AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' -- Next Refill Date concept + AND DATE(o_appt.value_datetime) >= :onOrAfter + AND DATE(o_appt.value_datetime) <= :onOrBefore + -- Ensure this is the latest refill date for this patient in the date range + AND o_appt.value_datetime = ( + SELECT MAX(o_latest.value_datetime) + FROM obs o_latest + INNER JOIN concept c_latest ON o_latest.concept_id = c_latest.concept_id + WHERE o_latest.person_id = p.patient_id + AND o_latest.voided = 0 + AND c_latest.uuid = '162549AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + AND DATE(o_latest.value_datetime) >= :onOrAfter + AND DATE(o_latest.value_datetime) <= :onOrBefore + ) + AND ( + -- If latest appointment is within 28 days of end date, this would be compliant + DATE(o_appt.value_datetime) > DATE_SUB(:onOrBefore, INTERVAL 28 DAY) + OR + -- If latest appointment is more than 28 days before end date, and has subsequent visit, this would be compliant + ( + DATE(o_appt.value_datetime) <= DATE_SUB(:onOrBefore, INTERVAL 28 DAY) + AND EXISTS ( + SELECT 1 + FROM encounter e_subsequent + INNER JOIN encounter_type et_subsequent ON e_subsequent.encounter_type = et_subsequent.encounter_type_id + INNER JOIN obs o_arv_subsequent ON o_arv_subsequent.encounter_id = e_subsequent.encounter_id + INNER JOIN concept c_arv_subsequent ON o_arv_subsequent.concept_id = c_arv_subsequent.concept_id + WHERE e_subsequent.patient_id = p.patient_id + AND e_subsequent.voided = 0 + AND o_arv_subsequent.voided = 0 + AND et_subsequent.uuid = 'cb0a65a7-0587-477e-89b9-cf2fd144f1d4' -- Consultation encounter type + AND c_arv_subsequent.uuid = '3a0709e9-d7a8-44b9-9512-111db5ce3989' -- ARV quantity concept + AND o_arv_subsequent.value_numeric IS NOT NULL + AND o_arv_subsequent.value_numeric > 0 + AND DATE(e_subsequent.encounter_datetime) > DATE(o_appt.value_datetime) + AND DATE(e_subsequent.encounter_datetime) <= :onOrBefore + ) + ) + ) + ) +ORDER BY p.patient_id; \ No newline at end of file diff --git a/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCTxCurrMultiMonth.sql b/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCTxCurrMultiMonth.sql new file mode 100644 index 0000000..7d75878 --- /dev/null +++ b/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCTxCurrMultiMonth.sql @@ -0,0 +1,73 @@ +SELECT DISTINCT p.patient_id +FROM patient p +INNER JOIN person pe ON p.patient_id = pe.person_id +WHERE pe.voided = 0 + AND p.voided = 0 + AND EXISTS ( + -- Check for "Next Refill Date" within or beyond date range + SELECT 1 + FROM obs o_appt + INNER JOIN concept c_appt ON o_appt.concept_id = c_appt.concept_id + WHERE o_appt.person_id = p.patient_id + AND o_appt.voided = 0 + AND c_appt.uuid = '162549AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + AND DATE(o_appt.value_datetime) >= :onOrAfter + ) + AND EXISTS ( + -- Check ARV coverage: Either drugs cover entire range OR drugs end in range with appointment/visit logic + SELECT 1 + FROM encounter e_consult + INNER JOIN encounter_type et ON e_consult.encounter_type = et.encounter_type_id + INNER JOIN obs o_arv ON o_arv.encounter_id = e_consult.encounter_id + INNER JOIN concept c_arv ON o_arv.concept_id = c_arv.concept_id + WHERE e_consult.patient_id = p.patient_id + AND e_consult.voided = 0 + AND o_arv.voided = 0 + AND et.uuid = 'cb0a65a7-0587-477e-89b9-cf2fd144f1d4' + AND c_arv.uuid = '3a0709e9-d7a8-44b9-9512-111db5ce3989' + AND DATE(e_consult.encounter_datetime) <= :onOrBefore + AND ( + -- Either: ARV quantity covers the entire date range + DATE_ADD(DATE(e_consult.encounter_datetime), INTERVAL o_arv.value_numeric DAY) >= :onOrBefore + OR + -- Or: Drugs end within date range with appointment/visit logic based on timing + ( + DATE_ADD(DATE(e_consult.encounter_datetime), INTERVAL o_arv.value_numeric DAY) < :onOrBefore + AND DATE_ADD(DATE(e_consult.encounter_datetime), INTERVAL o_arv.value_numeric DAY) >= :onOrAfter + AND EXISTS ( + SELECT 1 + FROM obs o_appt + INNER JOIN concept c_appt ON o_appt.concept_id = c_appt.concept_id + WHERE o_appt.person_id = p.patient_id + AND o_appt.voided = 0 + AND c_appt.uuid = '162549AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + AND ( + -- If appointment is within 28 days of end date, just check it exists + (DATE(o_appt.value_datetime) > DATE_SUB(:onOrBefore, INTERVAL 28 DAY)) + OR + -- If appointment is 28+ days before end date, must have subsequent visit WITH drug dispensing + ( + DATE(o_appt.value_datetime) <= DATE_SUB(:onOrBefore, INTERVAL 28 DAY) + AND EXISTS ( + SELECT 1 + FROM encounter e_subsequent + INNER JOIN encounter_type et_subsequent ON e_subsequent.encounter_type = et_subsequent.encounter_type_id + INNER JOIN obs o_arv_subsequent ON o_arv_subsequent.encounter_id = e_subsequent.encounter_id + INNER JOIN concept c_arv_subsequent ON o_arv_subsequent.concept_id = c_arv_subsequent.concept_id + WHERE e_subsequent.patient_id = p.patient_id + AND e_subsequent.voided = 0 + AND o_arv_subsequent.voided = 0 + AND et_subsequent.uuid = 'cb0a65a7-0587-477e-89b9-cf2fd144f1d4' + AND c_arv_subsequent.uuid = '3a0709e9-d7a8-44b9-9512-111db5ce3989' + AND o_arv_subsequent.value_numeric IS NOT NULL + AND o_arv_subsequent.value_numeric > 0 + AND DATE(e_subsequent.encounter_datetime) > DATE(o_appt.value_datetime) + AND DATE(e_subsequent.encounter_datetime) <= :onOrBefore + ) + ) + ) + ) + ) + ) + ) +ORDER BY p.patient_id; \ No newline at end of file diff --git a/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCTxCurrNotStoppedART.sql b/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCTxCurrNotStoppedART.sql new file mode 100644 index 0000000..1842a38 --- /dev/null +++ b/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCTxCurrNotStoppedART.sql @@ -0,0 +1,34 @@ +SELECT DISTINCT p.patient_id +FROM patient p +INNER JOIN person pe ON p.patient_id = pe.person_id +WHERE pe.voided = 0 + AND p.voided = 0 + AND NOT EXISTS ( + SELECT 1 + FROM obs o + INNER JOIN concept c_question ON o.concept_id = c_question.concept_id + INNER JOIN concept c_answer ON o.value_coded = c_answer.concept_id + INNER JOIN obs o_date ON o.encounter_id = o_date.encounter_id + INNER JOIN concept c_date ON o_date.concept_id = c_date.concept_id + WHERE o.person_id = p.patient_id + AND o.voided = 0 + AND o_date.voided = 0 + AND c_question.uuid = '1255AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' -- Decision on ART during this visit + AND c_answer.uuid = '1260AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' -- Stopped ART + AND c_date.uuid = '162572AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' -- Stop Date + AND DATE(o_date.value_datetime) BETWEEN :onOrAfter AND :onOrBefore + AND NOT EXISTS ( + -- Must have resumed ART after this stop in the same reporting period + SELECT 1 + FROM obs o_resume + INNER JOIN concept c_question_resume ON o_resume.concept_id = c_question_resume.concept_id + INNER JOIN concept c_answer_resume ON o_resume.value_coded = c_answer_resume.concept_id + WHERE o_resume.person_id = p.patient_id + AND o_resume.voided = 0 + AND c_question_resume.uuid = '1255AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' -- Decision on ART during this visit + AND c_answer_resume.uuid = '162904AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' -- Resume ART + AND DATE(o_resume.obs_datetime) BETWEEN :onOrAfter AND :onOrBefore + AND o_resume.obs_datetime > o_date.value_datetime + ) + ) +ORDER BY p.patient_id; \ No newline at end of file diff --git a/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCTxCurrNotTransferredOut.sql b/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCTxCurrNotTransferredOut.sql new file mode 100644 index 0000000..eb14b99 --- /dev/null +++ b/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCTxCurrNotTransferredOut.sql @@ -0,0 +1,37 @@ +SELECT DISTINCT p.patient_id +FROM patient p +INNER JOIN person pe ON p.patient_id = pe.person_id +WHERE pe.voided = 0 + AND p.voided = 0 + AND NOT EXISTS ( + SELECT 1 + FROM obs o + INNER JOIN concept c ON o.concept_id = c.concept_id + WHERE o.person_id = p.patient_id + AND o.voided = 0 + AND c.uuid = '160649AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' -- Date Transferred + AND DATE(o.value_datetime) BETWEEN :onOrAfter AND :onOrBefore + AND NOT EXISTS ( + -- Must have transferred back in after this transfer out in the same reporting period + SELECT 1 + FROM obs o_in + INNER JOIN concept c_question_in ON o_in.concept_id = c_question_in.concept_id + INNER JOIN concept c_answer_in ON o_in.value_coded = c_answer_in.concept_id + WHERE o_in.person_id = p.patient_id + AND o_in.voided = 0 + AND c_question_in.uuid = '83e40f2c-c316-43e6-a12e-20a338100281' -- What do you want to do? + AND c_answer_in.uuid = '160563AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' -- Transfer in + AND DATE(o_in.obs_datetime) BETWEEN :onOrAfter AND :onOrBefore + AND o_in.obs_datetime > o.value_datetime -- Transfer in must be after transfer out + AND EXISTS ( + SELECT 1 + FROM obs o_regimen + INNER JOIN concept c_regimen ON o_regimen.concept_id = c_regimen.concept_id + WHERE o_regimen.encounter_id = o_in.encounter_id + AND o_regimen.voided = 0 + AND c_regimen.uuid = 'dfbe256e-30ba-4033-837a-2e8477f2e7cd' -- ART Regimen + AND o_regimen.value_coded IS NOT NULL + ) + ) + ) +ORDER BY p.patient_id; \ No newline at end of file diff --git a/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCTxCurrResumeART.sql b/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCTxCurrResumeART.sql new file mode 100644 index 0000000..e1673de --- /dev/null +++ b/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCTxCurrResumeART.sql @@ -0,0 +1,17 @@ +SELECT DISTINCT p.patient_id +FROM patient p +INNER JOIN person pe ON p.patient_id = pe.person_id +WHERE pe.voided = 0 + AND p.voided = 0 + AND EXISTS ( + SELECT 1 + FROM obs o + INNER JOIN concept c_question ON o.concept_id = c_question.concept_id + INNER JOIN concept c_answer ON o.value_coded = c_answer.concept_id + WHERE o.person_id = p.patient_id + AND o.voided = 0 + AND c_question.uuid = '1255AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' -- Decision on ART during this visit + AND c_answer.uuid = '162904AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' -- Resume ART + AND DATE(o.obs_datetime) BETWEEN :onOrAfter AND :onOrBefore + ) +ORDER BY p.patient_id; diff --git a/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCTxCurrTransferPMTCT.sql b/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCTxCurrTransferPMTCT.sql new file mode 100644 index 0000000..c5be3ed --- /dev/null +++ b/api/src/main/resources/org/openmrs/module/drcreports/sql/DRCTxCurrTransferPMTCT.sql @@ -0,0 +1,48 @@ +SELECT DISTINCT p.patient_id +FROM patient p +INNER JOIN person pe ON p.patient_id = pe.person_id +WHERE pe.voided = 0 + AND p.voided = 0 + AND EXISTS ( + SELECT 1 + FROM obs o + INNER JOIN concept c_question ON o.concept_id = c_question.concept_id + INNER JOIN concept c_answer ON o.value_coded = c_answer.concept_id + WHERE o.person_id = p.patient_id + AND o.voided = 0 + AND c_question.uuid = '83e40f2c-c316-43e6-a12e-20a338100281' -- What do you want to do? + AND c_answer.uuid IN ( + '160563AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', -- Transfer in + '163532AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' -- Enroll into PMTCT + ) + AND DATE(o.obs_datetime) BETWEEN :onOrAfter AND :onOrBefore + AND ( + -- If answer is Transfer In, must have ART Regimen in same encounter + (c_answer.uuid = '160563AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + AND EXISTS ( + SELECT 1 + FROM obs o_regimen + INNER JOIN concept c_regimen ON o_regimen.concept_id = c_regimen.concept_id + WHERE o_regimen.encounter_id = o.encounter_id + AND o_regimen.voided = 0 + AND c_regimen.uuid = 'dfbe256e-30ba-4033-837a-2e8477f2e7cd' -- ART Regimen + AND o_regimen.value_coded IS NOT NULL + ) + ) + OR + -- If answer is PMTCT, must have Prevention being taken in same encounter + (c_answer.uuid = '163532AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + AND EXISTS ( + SELECT 1 + FROM obs o_prevention + INNER JOIN concept c_prevention ON o_prevention.concept_id = c_prevention.concept_id + INNER JOIN concept c_prevention_value ON o_prevention.value_coded = c_prevention_value.concept_id + WHERE o_prevention.encounter_id = o.encounter_id + AND o_prevention.voided = 0 + AND c_prevention.uuid = '163780AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' -- ART Prevention being taken + AND c_prevention_value.uuid = '1065AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' -- YES + ) + ) + ) + ) +ORDER BY p.patient_id; \ No newline at end of file diff --git a/api/src/test/java/org/openmrs/module/drcreports/reports/DRCTxCurrReportManagerTest.java b/api/src/test/java/org/openmrs/module/drcreports/reports/DRCTxCurrReportManagerTest.java new file mode 100644 index 0000000..56bc4b4 --- /dev/null +++ b/api/src/test/java/org/openmrs/module/drcreports/reports/DRCTxCurrReportManagerTest.java @@ -0,0 +1,439 @@ +package org.openmrs.module.drcreports.reports; + +import java.io.File; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +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.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.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.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.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; + +public class DRCTxCurrReportManagerTest extends BaseModuleContextSensitiveMysqlBackedTest { + + public DRCTxCurrReportManagerTest() throws SQLException { + super(); + } + + @Autowired + private InitializerService iniz; + + @Autowired + private ReportService rs; + + @Autowired + private ReportDefinitionService rds; + + @Autowired + @Qualifier("conceptService") + private ConceptService cs; + + @Autowired + private DRCTxCurrReportManager 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; + } + + @Before + public void setUp() throws Exception { + updateDatabase("org/openmrs/module/drcreports/liquibase/test-liquibase.xml"); + executeDataSet("org/openmrs/module/reporting/include/ReportTestDataset-openmrs-2.0.xml"); + executeDataSet("org/openmrs/module/drcreports/include/DRCTxCurrReportTestDataset.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_shouldCreateCsvDesign() throws Exception { + // setup + + // replay + ReportManagerUtil.setupReport(manager); + + // verify + assertThat(rs.getReportDesignByUuid("cb45687b-51b1-4d5d-a6a1-7a29ffd4d314"), is(notNullValue())); + + } + + @Test + public void testReport() throws Exception { + // setup + EvaluationContext context = new EvaluationContext(); + context.addParameterValue("startDate", DateUtil.parseDate("2025-06-01", "yyyy-MM-dd")); + context.addParameterValue("endDate", DateUtil.parseDate("2025-08-31", "yyyy-MM-dd")); + + // replay + ReportDefinition rd = manager.constructReportDefinition(); + ReportData data = rds.evaluate(rd, context); + + // verify + for (Iterator itr = data.getDataSets().get(rd.getName()).iterator(); itr.hasNext();) { + DataSetRow row = itr.next(); + Map columnValuePairs = getColumnValues(); + for (String column : columnValuePairs.keySet()) { + assertThat(column, ((Cohort) row.getColumnValue(column)).getSize(), is(columnValuePairs.get(column))); + } + } + + } + + private Map getColumnValues() { + Map map = new HashMap(); + + map.put("DRC TX_CURR Report.Total", 17); + + // Below 1 year + map.put("DRC TX_CURR Report.Below 1 year (Males)", 0); + map.put("DRC TX_CURR Report.Below 1 year (Females)", 0); + + // 1–4 years + map.put("DRC TX_CURR Report.1-4 years (Males)", 0); + map.put("DRC TX_CURR Report.1-4 years (Females)", 0); + + // 5–9 years + map.put("DRC TX_CURR Report.5-9 years (Males)", 0); + map.put("DRC TX_CURR Report.5-9 years (Females)", 0); + + // 10–14 years + map.put("DRC TX_CURR Report.10-14 years (Males)", 0); + map.put("DRC TX_CURR Report.10-14 years (Females)", 0); + + // 15–19 years + map.put("DRC TX_CURR Report.15-19 years (Males)", 0); + map.put("DRC TX_CURR Report.15-19 years (Females)", 0); + + // 20–24 years + map.put("DRC TX_CURR Report.20-24 years (Males)", 0); + map.put("DRC TX_CURR Report.20-24 years (Females)", 0); + + // 25–29 years + map.put("DRC TX_CURR Report.25-29 years (Males)", 0); + map.put("DRC TX_CURR Report.25-29 years (Females)", 0); + + // 30–34 years + map.put("DRC TX_CURR Report.30-34 years (Males)", 1); + map.put("DRC TX_CURR Report.30-34 years (Females)", 3); + + // 35–39 years + map.put("DRC TX_CURR Report.35-39 years (Males)", 6); + map.put("DRC TX_CURR Report.35-39 years (Females)", 5); + + // 40–44 years + map.put("DRC TX_CURR Report.40-44 years (Males)", 1); + map.put("DRC TX_CURR Report.40-44 years (Females)", 1); + + // 45–49 years + map.put("DRC TX_CURR Report.45-49 years (Males)", 0); + map.put("DRC TX_CURR Report.45-49 years (Females)", 0); + + // 50–54 years + map.put("DRC TX_CURR Report.50-54 years (Males)", 0); + map.put("DRC TX_CURR Report.50-54 years (Females)", 0); + + // 55–59 years + map.put("DRC TX_CURR Report.55-59 years (Males)", 0); + map.put("DRC TX_CURR Report.55-59 years (Females)", 0); + + // 60–64 years + map.put("DRC TX_CURR Report.60-64 years (Males)", 0); + map.put("DRC TX_CURR Report.60-64 years (Females)", 0); + + // 65+ years + map.put("DRC TX_CURR Report.65+ years (Males)", 0); + map.put("DRC TX_CURR Report.65+ years (Females)", 0); + + // Below 15 years + map.put("DRC TX_CURR Report.Below 15 years (Males)", 0); + map.put("DRC TX_CURR Report.Below 15 years (Females)", 0); + + // 15+ years + map.put("DRC TX_CURR Report.15+ years (Males)", 8); + map.put("DRC TX_CURR Report.15+ years (Females)", 9); + + map.put("< 3 months drugs.Total", 4); + + // Below 1 year + map.put("< 3 months drugs.Below 1 year (Males)", 0); + map.put("< 3 months drugs.Below 1 year (Females)", 0); + + // 1–4 years + map.put("< 3 months drugs.1-4 years (Males)", 0); + map.put("< 3 months drugs.1-4 years (Females)", 0); + + // 5–9 years + map.put("< 3 months drugs.5-9 years (Males)", 0); + map.put("< 3 months drugs.5-9 years (Females)", 0); + + // 10–14 years + map.put("< 3 months drugs.10-14 years (Males)", 0); + map.put("< 3 months drugs.10-14 years (Females)", 0); + + // 15–19 years + map.put("< 3 months drugs.15-19 years (Males)", 0); + map.put("< 3 months drugs.15-19 years (Females)", 0); + + // 20–24 years + map.put("< 3 months drugs.20-24 years (Males)", 0); + map.put("< 3 months drugs.20-24 years (Females)", 0); + + // 25–29 years + map.put("< 3 months drugs.25-29 years (Males)", 0); + map.put("< 3 months drugs.25-29 years (Females)", 0); + + // 30–34 years + map.put("< 3 months drugs.30-34 years (Males)", 0); + map.put("< 3 months drugs.30-34 years (Females)", 1); + + // 35–39 years + map.put("< 3 months drugs.35-39 years (Males)", 2); + map.put("< 3 months drugs.35-39 years (Females)", 1); + + // 40–44 years + map.put("< 3 months drugs.40-44 years (Males)", 0); + map.put("< 3 months drugs.40-44 years (Females)", 0); + + // 45–49 years + map.put("< 3 months drugs.45-49 years (Males)", 0); + map.put("< 3 months drugs.45-49 years (Females)", 0); + + // 50–54 years + map.put("< 3 months drugs.50-54 years (Males)", 0); + map.put("< 3 months drugs.50-54 years (Females)", 0); + + // 55–59 years + map.put("< 3 months drugs.55-59 years (Males)", 0); + map.put("< 3 months drugs.55-59 years (Females)", 0); + + // 60–64 years + map.put("< 3 months drugs.60-64 years (Males)", 0); + map.put("< 3 months drugs.60-64 years (Females)", 0); + + // 65+ years + map.put("< 3 months drugs.65+ years (Males)", 0); + map.put("< 3 months drugs.65+ years (Females)", 0); + + // Below 15 years + map.put("< 3 months drugs.Below 15 years (Males)", 0); + map.put("< 3 months drugs.Below 15 years (Females)", 0); + + // 15+ years + map.put("< 3 months drugs.15+ years (Males)", 2); + map.put("< 3 months drugs.15+ years (Females)", 2); + + map.put("3-5 months drugs.Total", 3); + + // Below 1 year + map.put("3-5 months drugs.Below 1 year (Males)", 0); + map.put("3-5 months drugs.Below 1 year (Females)", 0); + + // 1–4 years + map.put("3-5 months drugs.1-4 years (Males)", 0); + map.put("3-5 months drugs.1-4 years (Females)", 0); + + // 5–9 years + map.put("3-5 months drugs.5-9 years (Males)", 0); + map.put("3-5 months drugs.5-9 years (Females)", 0); + + // 10–14 years + map.put("3-5 months drugs.10-14 years (Males)", 0); + map.put("3-5 months drugs.10-14 years (Females)", 0); + + // 15–19 years + map.put("3-5 months drugs.15-19 years (Males)", 0); + map.put("3-5 months drugs.15-19 years (Females)", 0); + + // 20–24 years + map.put("3-5 months drugs.20-24 years (Males)", 0); + map.put("3-5 months drugs.20-24 years (Females)", 0); + + // 25–29 years + map.put("3-5 months drugs.25-29 years (Males)", 0); + map.put("3-5 months drugs.25-29 years (Females)", 0); + + // 30–34 years + map.put("3-5 months drugs.30-34 years (Males)", 1); + map.put("3-5 months drugs.30-34 years (Females)", 0); + + // 35–39 years + map.put("3-5 months drugs.35-39 years (Males)", 0); + map.put("3-5 months drugs.35-39 years (Females)", 1); + + // 40–44 years + map.put("3-5 months drugs.40-44 years (Males)", 0); + map.put("3-5 months drugs.40-44 years (Females)", 1); + + // 45–49 years + map.put("3-5 months drugs.45-49 years (Males)", 0); + map.put("3-5 months drugs.45-49 years (Females)", 0); + + // 50–54 years + map.put("3-5 months drugs.50-54 years (Males)", 0); + map.put("3-5 months drugs.50-54 years (Females)", 0); + + // 55–59 years + map.put("3-5 months drugs.55-59 years (Males)", 0); + map.put("3-5 months drugs.55-59 years (Females)", 0); + + // 60–64 years + map.put("3-5 months drugs.60-64 years (Males)", 0); + map.put("3-5 months drugs.60-64 years (Females)", 0); + + // 65+ years + map.put("3-5 months drugs.65+ years (Males)", 0); + map.put("3-5 months drugs.65+ years (Females)", 0); + + // Below 15 years + map.put("3-5 months drugs.Below 15 years (Males)", 0); + map.put("3-5 months drugs.Below 15 years (Females)", 0); + + // 15+ years + map.put("3-5 months drugs.15+ years (Males)", 1); + map.put("3-5 months drugs.15+ years (Females)", 2); + + map.put("6+ months drugs.Total", 0); + + // Below 1 year + map.put("6+ months drugs.Below 1 year (Males)", 0); + map.put("6+ months drugs.Below 1 year (Females)", 0); + + // 1–4 years + map.put("6+ months drugs.1-4 years (Males)", 0); + map.put("6+ months drugs.1-4 years (Females)", 0); + + // 5–9 years + map.put("6+ months drugs.5-9 years (Males)", 0); + map.put("6+ months drugs.5-9 years (Females)", 0); + + // 10–14 years + map.put("6+ months drugs.10-14 years (Males)", 0); + map.put("6+ months drugs.10-14 years (Females)", 0); + + // 15–19 years + map.put("6+ months drugs.15-19 years (Males)", 0); + map.put("6+ months drugs.15-19 years (Females)", 0); + + // 20–24 years + map.put("6+ months drugs.20-24 years (Males)", 0); + map.put("6+ months drugs.20-24 years (Females)", 0); + + // 25–29 years + map.put("6+ months drugs.25-29 years (Males)", 0); + map.put("6+ months drugs.25-29 years (Females)", 0); + + // 30–34 years + map.put("6+ months drugs.30-34 years (Males)", 0); + map.put("6+ months drugs.30-34 years (Females)", 0); + + // 35–39 years + map.put("6+ months drugs.35-39 years (Males)", 0); + map.put("6+ months drugs.35-39 years (Females)", 0); + + // 40–44 years + map.put("6+ months drugs.40-44 years (Males)", 0); + map.put("6+ months drugs.40-44 years (Females)", 0); + + // 45–49 years + map.put("6+ months drugs.45-49 years (Males)", 0); + map.put("6+ months drugs.45-49 years (Females)", 0); + + // 50–54 years + map.put("6+ months drugs.50-54 years (Males)", 0); + map.put("6+ months drugs.50-54 years (Females)", 0); + + // 55–59 years + map.put("6+ months drugs.55-59 years (Males)", 0); + map.put("6+ months drugs.55-59 years (Females)", 0); + + // 60–64 years + map.put("6+ months drugs.60-64 years (Males)", 0); + map.put("6+ months drugs.60-64 years (Females)", 0); + + // 65+ years + map.put("6+ months drugs.65+ years (Males)", 0); + map.put("6+ months drugs.65+ years (Females)", 0); + + // Below 15 years + map.put("6+ months drugs.Below 15 years (Males)", 0); + map.put("6+ months drugs.Below 15 years (Females)", 0); + + // 15+ years + map.put("6+ months drugs.15+ years (Males)", 0); + map.put("6+ months drugs.15+ years (Females)", 0); + + return map; + + } + + 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); + } +} diff --git a/api/src/test/resources/org/openmrs/module/drcreports/include/DRCTxCurrReportTestDataset.xml b/api/src/test/resources/org/openmrs/module/drcreports/include/DRCTxCurrReportTestDataset.xml new file mode 100644 index 0000000..c2b4ead --- /dev/null +++ b/api/src/test/resources/org/openmrs/module/drcreports/include/DRCTxCurrReportTestDataset.xml @@ -0,0 +1,693 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file