Skip to content

Commit

Permalink
Merge pull request #1961 from patryllus/feat/Appointment_tracker_report
Browse files Browse the repository at this point in the history
Added Appointment tracker report : with date scheduled and appointment date given stored in patient_appointment table
  • Loading branch information
ojwanganto authored Jul 26, 2024
2 parents 1bb7cfe + 4b1da2f commit 50375d8
Show file tree
Hide file tree
Showing 8 changed files with 449 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/
package org.openmrs.module.kenyaemr.reporting.builder.hiv;

import org.openmrs.PatientIdentifierType;
import org.openmrs.module.kenyacore.report.HybridReportDescriptor;
import org.openmrs.module.kenyacore.report.ReportDescriptor;
import org.openmrs.module.kenyacore.report.ReportUtils;
import org.openmrs.module.kenyacore.report.builder.AbstractHybridReportBuilder;
import org.openmrs.module.kenyacore.report.builder.Builds;
import org.openmrs.module.kenyacore.report.data.patient.definition.CalculationDataDefinition;
import org.openmrs.module.kenyaemr.calculation.library.hiv.*;
import org.openmrs.module.kenyaemr.calculation.library.hiv.art.DateOfEnrollmentArtCalculation;
import org.openmrs.module.kenyaemr.metadata.CommonMetadata;
import org.openmrs.module.kenyaemr.metadata.HivMetadata;
import org.openmrs.module.kenyaemr.reporting.calculation.converter.DateArtStartDateConverter;
import org.openmrs.module.kenyaemr.reporting.calculation.converter.IPTOutcomeDataConverter;
import org.openmrs.module.kenyaemr.reporting.calculation.converter.SimpleResultDateConverter;
import org.openmrs.module.kenyaemr.reporting.cohort.definition.ActivePatientsSnapshotCohortDefinition;
import org.openmrs.module.kenyaemr.reporting.cohort.definition.HivConsultationDuringPeriodCohortDefinition;
import org.openmrs.module.kenyaemr.reporting.data.converter.ActiveInProgramConverter;
import org.openmrs.module.kenyaemr.reporting.data.converter.BooleanResultsConverter;
import org.openmrs.module.kenyaemr.reporting.data.converter.definition.ActivePatientsPopulationTypeDataDefinition;
import org.openmrs.module.kenyaemr.reporting.data.converter.definition.MFLCodeDataDefinition;
import org.openmrs.module.kenyaemr.reporting.data.converter.definition.art.*;
import org.openmrs.module.metadatadeploy.MetadataUtils;
import org.openmrs.module.reporting.cohort.definition.CohortDefinition;
import org.openmrs.module.reporting.data.DataDefinition;
import org.openmrs.module.reporting.data.converter.BirthdateConverter;
import org.openmrs.module.reporting.data.converter.DataConverter;
import org.openmrs.module.reporting.data.converter.DateConverter;
import org.openmrs.module.reporting.data.converter.ObjectFormatter;
import org.openmrs.module.reporting.data.patient.definition.ConvertedPatientDataDefinition;
import org.openmrs.module.reporting.data.patient.definition.PatientIdDataDefinition;
import org.openmrs.module.reporting.data.patient.definition.PatientIdentifierDataDefinition;
import org.openmrs.module.reporting.data.person.definition.*;
import org.openmrs.module.reporting.dataset.definition.DataSetDefinition;
import org.openmrs.module.reporting.dataset.definition.PatientDataSetDefinition;
import org.openmrs.module.reporting.evaluation.parameter.Mapped;
import org.openmrs.module.reporting.evaluation.parameter.Parameter;
import org.openmrs.module.reporting.report.definition.ReportDefinition;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Component
@Builds({"kenyaemr.hiv.report.appointmentsTracker"})
public class AppointmentsTrackerReportBuilder extends AbstractHybridReportBuilder {
public static final String DATE_FORMAT = "dd/MM/yyyy";

@Override
protected List<Parameter> getParameters(ReportDescriptor reportDescriptor) {
return Arrays.asList(
new Parameter("startDate", "Start Date", Date.class),
new Parameter("endDate", "End Date", Date.class),
new Parameter("dateBasedReporting", "", String.class)
);
}

@Override
protected void addColumns(HybridReportDescriptor report, PatientDataSetDefinition dsd) {
}

@Override
protected Mapped<CohortDefinition> buildCohort(HybridReportDescriptor descriptor, PatientDataSetDefinition dsd) {
return null;
}


protected Mapped<CohortDefinition> patientsWithHivVisitsCohort() {
CohortDefinition cd = new HivConsultationDuringPeriodCohortDefinition();
cd.addParameter(new Parameter("startDate", "Start Date", Date.class));
cd.addParameter(new Parameter("endDate", "End Date", Date.class));
cd.setName("Patients Visits");
return ReportUtils.map(cd, "startDate=${startDate},endDate=${endDate}");
}

@Override
protected List<Mapped<DataSetDefinition>> buildDataSets(ReportDescriptor descriptor, ReportDefinition report) {

PatientDataSetDefinition allVisits = patientsWithVisitsDataSetDefinition("visitedPatients");
allVisits.addRowFilter(patientsWithHivVisitsCohort());
DataSetDefinition patientsDSD = allVisits;

return Arrays.asList(
ReportUtils.map(patientsDSD, "startDate=${startDate},endDate=${endDate}")
);
}

protected PatientDataSetDefinition patientsWithVisitsDataSetDefinition(String datasetName) {

PatientDataSetDefinition dsd = new PatientDataSetDefinition(datasetName);
dsd.addParameter(new Parameter("startDate", "Start Date", Date.class));
dsd.addParameter(new Parameter("endDate", "End Date", Date.class));
String defParam = "startDate=${startDate},endDate=${endDate}";

PatientIdentifierType upn = MetadataUtils.existing(PatientIdentifierType.class, HivMetadata._PatientIdentifierType.UNIQUE_PATIENT_NUMBER);
DataConverter identifierFormatter = new ObjectFormatter("{identifier}");
DataDefinition identifierDef = new ConvertedPatientDataDefinition("identifier", new PatientIdentifierDataDefinition(upn.getName(), upn), identifierFormatter);

PatientAppointmentScheduledDateDataDefinition patientAppointmentScheduledDateDataDefinition = new PatientAppointmentScheduledDateDataDefinition();
patientAppointmentScheduledDateDataDefinition.addParameter(new Parameter("endDate", "End Date", Date.class));
patientAppointmentScheduledDateDataDefinition.addParameter(new Parameter("startDate", "Start Date", Date.class));

PatientAppointmentTCADateDataDefinition patientAppointmentTCADateDataDefinition = new PatientAppointmentTCADateDataDefinition();
patientAppointmentTCADateDataDefinition.addParameter(new Parameter("endDate", "End Date", Date.class));
patientAppointmentTCADateDataDefinition.addParameter(new Parameter("startDate", "Start Date", Date.class));

DataConverter formatter = new ObjectFormatter("{familyName}, {givenName}");
DataDefinition nameDef = new ConvertedPersonDataDefinition("name", new PreferredNameDataDefinition(), formatter);

dsd.addColumn("id", new PatientIdDataDefinition(), "");
dsd.addColumn("Name", nameDef, "");
dsd.addColumn("Date of Birth", new BirthdateDataDefinition(), "", new BirthdateConverter(DATE_FORMAT));
dsd.addColumn("Age", new AgeDataDefinition(), "");
dsd.addColumn("Sex", new GenderDataDefinition(), "");
dsd.addColumn("CCC No", identifierDef, "");
dsd.addColumn("Date Appointment Scheduled", patientAppointmentScheduledDateDataDefinition,"startDate=${startDate},endDate=${endDate}", new DateConverter(DATE_FORMAT));
dsd.addColumn("Next Appointment Date", patientAppointmentTCADateDataDefinition, "startDate=${startDate},endDate=${endDate}", new DateConverter(DATE_FORMAT));
return dsd;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/
package org.openmrs.module.kenyaemr.reporting.cohort.definition;

import org.openmrs.module.reporting.cohort.definition.BaseCohortDefinition;
import org.openmrs.module.reporting.common.Localized;
import org.openmrs.module.reporting.definition.configuration.ConfigurationPropertyCachingStrategy;
import org.openmrs.module.reporting.evaluation.caching.Caching;

/**
* Hiv Consultation Visits Done During Period cohort definition
*/
@Caching(strategy = ConfigurationPropertyCachingStrategy.class)
@Localized("reporting.HivConsultationDuringPeriodCohortDefinition")
public class HivConsultationDuringPeriodCohortDefinition extends BaseCohortDefinition {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/
package org.openmrs.module.kenyaemr.reporting.cohort.definition.evaluator;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openmrs.Cohort;
import org.openmrs.annotation.Handler;
import org.openmrs.module.kenyaemr.reporting.cohort.definition.HivConsultationDuringPeriodCohortDefinition;
import org.openmrs.module.reporting.cohort.EvaluatedCohort;
import org.openmrs.module.reporting.cohort.definition.CohortDefinition;
import org.openmrs.module.reporting.cohort.definition.evaluator.CohortDefinitionEvaluator;
import org.openmrs.module.reporting.evaluation.EvaluationContext;
import org.openmrs.module.reporting.evaluation.EvaluationException;
import org.openmrs.module.reporting.evaluation.querybuilder.SqlQueryBuilder;
import org.openmrs.module.reporting.evaluation.service.EvaluationService;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;
import java.util.HashSet;
import java.util.List;

/**
* Evaluator for HivConsultationDuringPeriodCohortDefinition
* Includes patients who had visits Done During Period cohort definition
* Provides a snapshot of a patient with regard to the last visit
*/
@Handler(supports = {HivConsultationDuringPeriodCohortDefinition.class})
public class HivConsultationDuringPeriodCohortDefinitionEvaluator implements CohortDefinitionEvaluator {

private final Log log = LogFactory.getLog(this.getClass());

@Autowired
EvaluationService evaluationService;

@Override
public EvaluatedCohort evaluate(CohortDefinition cohortDefinition, EvaluationContext context) throws EvaluationException {

HivConsultationDuringPeriodCohortDefinition definition = (HivConsultationDuringPeriodCohortDefinition) cohortDefinition;

if (definition == null)
return null;

Cohort newCohort = new Cohort();

String qry="select\n" +
" e.patient_id\n" +
" from encounter e\n" +
" inner join person p on p.person_id=e.patient_id and p.voided=0\n" +
" inner join form f on f.form_id = e.form_id and f.uuid in ('22c68f86-bbf0-49ba-b2d1-23fa7ccf0259','23b4ebbd-29ad-455e-be0e-04aa6bc30798','465a92f2-baf8-42e9-9612-53064be868e8')\n" +
"where date(e.encounter_datetime) between date(:startDate) and date(:endDate) and e.voided=0\n" +
"group by e.patient_id,e.encounter_datetime;";

SqlQueryBuilder builder = new SqlQueryBuilder();
builder.append(qry);
Date startDate = (Date)context.getParameterValue("startDate");
Date endDate = (Date)context.getParameterValue("endDate");
builder.addParameter("startDate", startDate);
builder.addParameter("endDate", endDate);

List<Integer> ptIds = evaluationService.evaluateToList(builder, Integer.class, context);
newCohort.setMemberIds(new HashSet<Integer>(ptIds));
return new EvaluatedCohort(newCohort, definition, context);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/
package org.openmrs.module.kenyaemr.reporting.data.converter.definition.art;

import org.openmrs.module.reporting.data.BaseDataDefinition;
import org.openmrs.module.reporting.data.person.definition.PersonDataDefinition;
import org.openmrs.module.reporting.definition.configuration.ConfigurationPropertyCachingStrategy;
import org.openmrs.module.reporting.evaluation.caching.Caching;

/**
* Scheduled Date From patient Appointment Data Definition
*/
@Caching(strategy=ConfigurationPropertyCachingStrategy.class)
public class PatientAppointmentScheduledDateDataDefinition extends BaseDataDefinition implements PersonDataDefinition {

public static final long serialVersionUID = 1L;

/**
* Default Constructor
*/
public PatientAppointmentScheduledDateDataDefinition() {
super();
}

/**
* Constructor to populate name only
*/
public PatientAppointmentScheduledDateDataDefinition(String name) {
super(name);
}

//***** INSTANCE METHODS *****

/**
* @see org.openmrs.module.reporting.data.DataDefinition#getDataType()
*/
public Class<?> getDataType() {
return Double.class;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/
package org.openmrs.module.kenyaemr.reporting.data.converter.definition.art;

import org.openmrs.module.reporting.data.BaseDataDefinition;
import org.openmrs.module.reporting.data.person.definition.PersonDataDefinition;
import org.openmrs.module.reporting.definition.configuration.ConfigurationPropertyCachingStrategy;
import org.openmrs.module.reporting.evaluation.caching.Caching;

/**
* Next Appointment Date From patient Appointment Data Definition
*/
@Caching(strategy=ConfigurationPropertyCachingStrategy.class)
public class PatientAppointmentTCADateDataDefinition extends BaseDataDefinition implements PersonDataDefinition {

public static final long serialVersionUID = 1L;

/**
* Default Constructor
*/
public PatientAppointmentTCADateDataDefinition() {
super();
}

/**
* Constructor to populate name only
*/
public PatientAppointmentTCADateDataDefinition(String name) {
super(name);
}

//***** INSTANCE METHODS *****

/**
* @see org.openmrs.module.reporting.data.DataDefinition#getDataType()
*/
public Class<?> getDataType() {
return Double.class;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
* the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
*
* Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
* graphic logo is a trademark of OpenMRS Inc.
*/
package org.openmrs.module.kenyaemr.reporting.data.converter.definition.evaluator.art;

import org.openmrs.annotation.Handler;
import org.openmrs.module.kenyaemr.reporting.data.converter.definition.art.ETLNextAppointmentDateDataDefinition;
import org.openmrs.module.kenyaemr.reporting.data.converter.definition.art.PatientAppointmentScheduledDateDataDefinition;
import org.openmrs.module.reporting.data.person.EvaluatedPersonData;
import org.openmrs.module.reporting.data.person.definition.PersonDataDefinition;
import org.openmrs.module.reporting.data.person.evaluator.PersonDataEvaluator;
import org.openmrs.module.reporting.evaluation.EvaluationContext;
import org.openmrs.module.reporting.evaluation.EvaluationException;
import org.openmrs.module.reporting.evaluation.querybuilder.SqlQueryBuilder;
import org.openmrs.module.reporting.evaluation.service.EvaluationService;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;
import java.util.Map;

/**
* Evaluates Scheduled date for Patient appointment Data Definition
*/
@Handler(supports= PatientAppointmentScheduledDateDataDefinition.class, order=50)
public class PatientAppointmentScheduledDateDateDataEvaluator implements PersonDataEvaluator {

@Autowired
private EvaluationService evaluationService;

public EvaluatedPersonData evaluate(PersonDataDefinition definition, EvaluationContext context) throws EvaluationException {
EvaluatedPersonData c = new EvaluatedPersonData(definition, context);

String qry = "select\n" +
" pp.patient_id,\n" +
" date(mid(max(concat(pp.date_created,pp.date_appointment_scheduled, '' )),20)) as scheduled_date\n" +
"from patient_appointment pp\n" +
" inner join person d on d.person_id=pp.patient_id and d.voided=0\n" +
" inner join encounter e on e.patient_id = pp.patient_id\n" +
"where pp.appointment_service_id = 1 and date(e.encounter_datetime) = date(pp.date_appointment_scheduled)\n" +
" and date(pp.date_created) <= date(:endDate)\n" +
"group by pp.patient_id,pp.date_appointment_scheduled;";

SqlQueryBuilder queryBuilder = new SqlQueryBuilder();
queryBuilder.append(qry);
Date startDate = (Date)context.getParameterValue("startDate");
Date endDate = (Date)context.getParameterValue("endDate");
queryBuilder.addParameter("endDate", endDate);
queryBuilder.addParameter("startDate", startDate);

Map<Integer, Object> data = evaluationService.evaluateToMap(queryBuilder, Integer.class, Object.class, context);
c.setData(data);
return c;
}
}
Loading

0 comments on commit 50375d8

Please sign in to comment.