Skip to content

Commit

Permalink
U4X-571: Change DSDM Stability Criteria to use API instead of Java API (
Browse files Browse the repository at this point in the history
  • Loading branch information
slubwama authored Jun 19, 2024
1 parent 537c388 commit a022909
Show file tree
Hide file tree
Showing 6 changed files with 710 additions and 278 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,260 +3,20 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openmrs.*;
import org.openmrs.api.ConceptService;
import org.openmrs.api.ObsService;
import org.openmrs.api.PatientService;
import org.openmrs.api.context.Context;
import org.openmrs.ui.framework.UiUtils;
import org.openmrs.ui.framework.fragment.FragmentModel;
import org.springframework.web.bind.annotation.RequestParam;

import java.text.DateFormat;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;



public class PatientStabilityFragmentController {

private static final Log log = LogFactory.getLog(PatientStabilityFragmentController.class);

public void controller(FragmentModel model, @RequestParam(value = "patientId", required = false) Patient patient, @RequestParam(value = "visitId", required = false) Visit visit, @RequestParam(value = "encounterId", required = false) Encounter encounter, UiUtils ui) throws ParseException {
String allowCliniciansToMakeDecisionOnDSDM=Context.getAdministrationService().getGlobalProperty("ugandaemr.dsdm.allowClinicalOverrideDSDMPatientStability");
if(allowCliniciansToMakeDecisionOnDSDM.equals("false")) {
Integer baselineRegimenConceptId = 99061;
Integer currentRegimenConceptId = 90315;
ObsService obsService = Context.getObsService();
ConceptService conceptService = Context.getConceptService();
PatientService patientService = Context.getPatientService();
Integer minimumDurationOnCurrentRegimen = Integer.parseInt(Context.getAdministrationService().getGlobalProperty("ugandaemr.dsdm.currentRegimenDurationRequirementInMonths"));

Visit encounterVisit = new Visit();
if (visit == null && encounter != null) {
encounterVisit = encounter.getVisit();
} else if (visit != null) {
encounterVisit = visit;
}


/**
* Last Viral Load
*/
List<Obs> vlDateObsList = getObsListFromIdList("SELECT obs_id FROM obs where obs.person_id='" + patient.getPatientId() + "' AND obs.concept_id = 163023 AND obs.voided = false ORDER BY obs.encounter_id DESC LIMIT 1");

if (vlDateObsList.size() > 0) {
List<Obs> vlObsList = getObsListFromIdList("SELECT obs_id FROM obs where obs.person_id='" + patient.getPatientId() + "' AND obs.concept_id = 856 AND encounter_id='" + vlDateObsList.get(0).getEncounter().getEncounterId() + "' AND obs.voided = false ORDER BY obs.encounter_id DESC LIMIT 1");

if (vlObsList.size() > 0) {
model.addAttribute("vlObs", vlObsList.get(0));
model.addAttribute("vlDateObs", vlDateObsList.get(0));
} else {
model.addAttribute("vlObs", null);
model.addAttribute("vlDateObs", null);
}
} else {
model.addAttribute("vlDateObs", null);
model.addAttribute("vlObs", null);
}

List<Person> personList = new ArrayList<>();
personList.add(patient.getPerson());

/**
* Current regimen
*/
int monthOffSet = -minimumDurationOnCurrentRegimen;

Obs obs = getMostRecentObservation(encounterVisit, "90315");

String query = "";
String queryCurrentRegimen = "";
List<Obs> regimenObsList = new ArrayList<>();
List<Obs> currentRegimenList = new ArrayList<>();

//Check if Obs of Regimen is on not Null
if (obs != null) {
//Check if Obs conceptId is the same as the art encounter regimen concept
// Check if regimen is a DTG regimen
if (checkIfDTG(obs)) {
query = "SELECT obs_id FROM obs where obs.obs_datetime <= DATE('" + encounterVisit.getStartDatetime() + "') AND obs.person_id='" + patient.getPatientId() + "' AND concept_id=" + currentRegimenConceptId + " AND obs.voided = false ORDER BY obs.obs_datetime DESC";
} else {
query = "SELECT obs_id FROM obs where obs.obs_datetime <= DATE('" + getDateBefore(encounterVisit.getStartDatetime(), monthOffSet, 0) + "') AND obs.person_id='" + patient.getPatientId() + "' AND obs.value_coded = " + obs.getValueCoded().getConceptId() + " AND obs.voided = false ORDER BY obs.encounter_id DESC";
}
regimenObsList = getObsListFromIdList(query);

queryCurrentRegimen = "SELECT obs_id FROM obs where obs.person_id='" + patient.getPatientId() + "' AND obs.obs_datetime <= DATE('" + encounterVisit.getStartDatetime() + "') AND obs.value_coded = " + obs.getValueCoded().getConceptId() + " AND obs.voided = false ORDER BY obs.obs_datetime ASC LIMIT 0,1";

currentRegimenList = getObsListFromIdList(queryCurrentRegimen);
}


if (regimenObsList.size() > 0) {
if (checkIfDTG(regimenObsList.get(0)) && regimenObsList.size() > 1) {
List<Obs> regimenBeforeDTGObs = getObsListFromIdList("SELECT obs_id FROM obs where obs.obs_datetime <= DATE('" + getDateBefore(encounterVisit.getStartDatetime(), -12, 0) + "') AND obs.person_id='" + patient.getPatientId() + "' AND obs.concept_id = " + currentRegimenConceptId + " AND obs.voided = false ORDER BY obs.encounter_id DESC");
if (regimenBeforeDTGObs.size() > 0) {
model.addAttribute("regimenBeforeDTGObs", regimenBeforeDTGObs.get(0));
} else {
model.addAttribute("regimenBeforeDTGObs", "");
}
} else {
model.addAttribute("regimenBeforeDTGObs", "");
}
model.addAttribute("regimenObs", regimenObsList.get(0));
} else {
model.addAttribute("regimenObs", null);
model.addAttribute("regimenBeforeDTGObs", "");
}

if (currentRegimenList.size() > 0) {
model.addAttribute("currentRegimenObs", currentRegimenList.get(0));
} else {
model.addAttribute("currentRegimenObs", null);
}
model.addAttribute("baselineRegimenConceptId", baselineRegimenConceptId);

/**
* Adherence
*/
List<Obs> adherenceObsList = getObsListFromIdList("SELECT obs_id FROM obs where obs.obs_datetime BETWEEN '" + getDateBefore(encounterVisit.getStartDatetime(), -6, 0) + "' AND '" + encounterVisit.getStartDatetime() + "' AND obs.person_id='" + patient.getPatientId() + "' AND obs.concept_id = 90221 AND obs.voided = false ORDER BY obs.encounter_id DESC");

if (adherenceObsList.size() > 0) {
model.addAttribute("adherenceObs", adherenceObsList);
} else {
model.addAttribute("adherenceObs", null);
}

/**
* ThirdLine Regimen
*/
List<Concept> concepts = new ArrayList<>();
Collection<ConceptAnswer> conceptAnswers = conceptService.getConcept(1).getAnswers(false);
for (ConceptAnswer conceptAnswer : conceptAnswers) {
if (conceptAnswer.getConcept().getConceptId() != 90002) {
conceptAnswers.remove(conceptAnswer);
concepts.add(conceptAnswer.getAnswerConcept());
}
}
if (regimenObsList.size() > 0 && concepts.contains(regimenObsList.get(0).getValueCoded())) {
model.addAttribute("onThirdRegimen", true);
} else {
model.addAttribute("onThirdRegimen", false);
}

/**
* Clinic Staging
*/

List<Concept> clinicStage = new ArrayList<>();
List<Obs> clinicStageObsList = getObsListFromIdList("SELECT obs_id FROM obs where obs.person_id='" + patient.getPatientId() + "' AND obs.concept_id IN (99083,90203) AND obs.voided = false ORDER BY obs.encounter_id DESC");

if (clinicStageObsList.size() > 0) {
model.addAttribute("conceptForClinicStage", clinicStageObsList.get(0).getValueCoded().getConceptId());
} else {
model.addAttribute("conceptForClinicStage", null);
}

/**
* Sputum Results
*/
Obs spetumObs = getMostRecentObservation(encounterVisit, "307");
model.addAttribute("sputumResultObs", spetumObs);

/**
* Sputum ResultDate
*/
Obs spetumDateObs = getMostRecentObservation(encounterVisit, "99392");
model.addAttribute("sputumResultDateObs", spetumDateObs);


/**
* Current Regimen
*/
model.addAttribute("artStartDate", getArtStartDate(patient));
model.addAttribute("enableCliniciansMakeStabilityDecisions", allowCliniciansToMakeDecisionOnDSDM);
}else{
model.addAttribute("enableCliniciansMakeStabilityDecisions", allowCliniciansToMakeDecisionOnDSDM);
}
}


/**
* This Subtracts a date provided by number of moths and years given and returns a new date
*
* @param referenceDate
* @param noOfMoths
* @return
*/
public String getDateBefore(Date referenceDate, int noOfMoths, int noOfYears) {
Calendar cal = Calendar.getInstance();
cal.setTime(referenceDate);
if (noOfMoths != 0) {
cal.set(Calendar.DAY_OF_MONTH, cal.getActualMinimum(Calendar.DAY_OF_MONTH));
}
cal.add(Calendar.MONTH, noOfMoths);
cal.add(Calendar.YEAR, noOfYears);
DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
String finalDate = null;
try {
finalDate = format.format(cal.getTime());
} catch (Exception e) {
log.error("Failed to format date",e);
}
return finalDate;
}

/**
* Gets List of Obs Basing on the query provided
*
* @param query
* @return
*/
private List<Obs> getObsListFromIdList(String query) {
List<Obs> obsList = new ArrayList<>();
for (Object o : Context.getAdministrationService().executeSQL(query, true)) {
obsList.add(Context.getObsService().getObs(Integer.parseInt(((ArrayList) o).get(0).toString())));
}
return obsList;
}

/**
* Get ART START DATE From Summary Page of a Patient
*
* @param patient
* @return
*/
public Date getArtStartDate(Patient patient) {
List<Obs> list = Context.getObsService().getObservationsByPersonAndConcept(patient, Context.getConceptService().getConcept(99161));
Date artStartDate = null;
if (list.size() > 0) {
artStartDate = list.get(0).getValueDatetime();
}
return artStartDate;

}

/**
* Check if DTG
*
* @param obs
* @return
*/
private boolean checkIfDTG(Obs obs) {
return "164976,164977,164978,164979".contains(obs.getValueCoded().getConceptId().toString());
}


/**
* gets the latest Observation basing on the visit Date and the concepts
* @param encounterVisit
* @param concepts Separate with , if many
* @return
*/
public Obs getMostRecentObservation(Visit encounterVisit, String concepts) {
String query = "SELECT obs_id FROM obs where obs.obs_datetime <= DATE('" + encounterVisit.getStartDatetime() + "') AND obs.person_id='" + encounterVisit.getPatient().getPatientId() + "' AND concept_id in ("+concepts+") AND obs.voided = false ORDER BY obs.obs_datetime DESC LIMIT 0,1";
List<Obs> obs = getObsListFromIdList(query);
if (obs.size() > 0) {
return obs.get(0);
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import org.openmrs.module.htmlformentry.FormEntryContext;
import org.openmrs.module.htmlformentry.FormEntryContext.Mode;
import org.openmrs.module.htmlformentry.FormEntrySession;
import org.openmrs.module.ugandaemr.fragment.controller.PatientSummaryFragmentController;
import org.openmrs.module.ugandaemr.metadata.core.Programs;

import java.util.ArrayList;
Expand All @@ -32,7 +31,7 @@
* 2. Adds the patient to the ART First Line Regimen workflow state of the HIV Care Program
*/
public class ARTEnrollmentSubmissionAction implements CustomFormSubmissionAction {
private static final Log log = LogFactory.getLog(PatientSummaryFragmentController.class);
private static final Log log = LogFactory.getLog(ARTEnrollmentSubmissionAction.class);

@Override
public void applyAction(FormEntrySession session) {
Expand Down
Loading

0 comments on commit a022909

Please sign in to comment.