@Override public CalculationResultMap evaluate( Collection<Integer> cohort, Map<String, Object> parameterValues, PatientCalculationContext context) { Program hivProgram = MetadataUtils.existing(Program.class, HivMetadata._Program.HIV); Set<Integer> alive = Filters.alive(cohort, context); Set<Integer> inHivProgram = Filters.inProgram(hivProgram, alive, context); Set<Integer> aliveAndFemale = Filters.female(Filters.alive(cohort, context), context); CalculationResultMap ret = new CalculationResultMap(); // need to exclude those on ART already Set<Integer> onArt = CalculationUtils.patientsThatPass(calculate(new OnArtCalculation(), cohort, context)); // find the observation for viral load recorded CalculationResultMap viralLoad = Calculations.lastObs(Dictionary.getConcept(Dictionary.HIV_VIRAL_LOAD), cohort, context); // get a list of all the viral load CalculationResultMap viralLoadList = Calculations.allObs(Dictionary.getConcept(Dictionary.HIV_VIRAL_LOAD), cohort, context); // check for non detectables CalculationResultMap ldlViralLoad = Calculations.allObs( Dictionary.getConcept(Dictionary.HIV_VIRAL_LOAD_QUALITATIVE), cohort, context); // check for test orders CalculationResultMap testOrders = Calculations.allObs(Dictionary.getConcept(Dictionary.TESTS_ORDERED), cohort, context); // check for last ldl CalculationResultMap ldlLast = Calculations.lastObs( Dictionary.getConcept(Dictionary.HIV_VIRAL_LOAD_QUALITATIVE), cohort, context); // find for prgnant females CalculationResultMap pregStatusObss = Calculations.lastObs( Dictionary.getConcept(Dictionary.PREGNANCY_STATUS), aliveAndFemale, context); // get the initial art start date CalculationResultMap artStartDate = calculate(new InitialArtStartDateCalculation(), cohort, context); for (Integer ptId : cohort) { boolean needsViralLoadTest = false; Obs viralLoadObs = EmrCalculationUtils.obsResultForPatient(viralLoad, ptId); Date dateInitiated = EmrCalculationUtils.datetimeResultForPatient(artStartDate, ptId); ListResult listResult = (ListResult) viralLoadList.get(ptId); ListResult testOrdersList = (ListResult) testOrders.get(ptId); List<Obs> testObsList = CalculationUtils.extractResultValues(testOrdersList); List<Obs> listObsViralLoads = CalculationUtils.extractResultValues(listResult); ListResult ldlList = (ListResult) ldlViralLoad.get(ptId); List<List> listLdl = CalculationUtils.extractResultValues(ldlList); Obs lastLdlObs = EmrCalculationUtils.obsResultForPatient(ldlLast, ptId); // find pregnancy obs Obs pregnantEdd = EmrCalculationUtils.obsResultForPatient(pregStatusObss, ptId); // Find latest viral load test order Obs lastVlTestOrder = getLatestVlOrder(testObsList); if (inHivProgram.contains(ptId) && onArt.contains(ptId)) { if (listObsViralLoads.size() == 0 && listLdl.size() == 0 && dateInitiated != null && (daysSince(dateInitiated, context) >= 180)) { needsViralLoadTest = true; } // need to check here if patient has had any viral load /*if(dateInitiated != null && (daysSince(dateInitiated, context) >= 360)) { needsViralLoadTest = true; }*/ // those continuing should receive one VL every year // pick the date of the last viral load numeric values if (viralLoadObs != null && (daysSince(viralLoadObs.getObsDatetime(), context) >= 360)) { needsViralLoadTest = true; } // pick the date of the ldl if (lastLdlObs != null && (daysSince(lastLdlObs.getObsDatetime(), context) >= 360)) { needsViralLoadTest = true; } // if vl more than if (viralLoadObs != null && viralLoadObs.getValueNumeric() > 1000 && (daysSince(viralLoadObs.getObsDatetime(), context) > 90)) { needsViralLoadTest = true; if (lastLdlObs != null && (daysSince(lastLdlObs.getObsDatetime(), context) < 360)) { needsViralLoadTest = false; } } // check for pregnancy if (pregnantEdd != null && pregnantEdd.getValueCoded().equals(Dictionary.getConcept(Dictionary.YES)) && dateInitiated != null) { Date whenVLWillBeDue = DateUtil.adjustDate( DateUtil.adjustDate(dateInitiated, 6, DurationUnit.MONTHS), -1, DurationUnit.DAYS); // if last vl is 6 months older then the patient is due for vl if (viralLoadObs == null && lastLdlObs == null) { needsViralLoadTest = true; } if (viralLoadObs == null && lastLdlObs == null && (context.getNow().after(whenVLWillBeDue))) { needsViralLoadTest = true; } if (viralLoadObs != null && viralLoadObs.getValueNumeric() > 1000 && (monthsBetween(viralLoadObs.getObsDatetime(), context.getNow()) >= 3)) { needsViralLoadTest = true; if (lastLdlObs != null && (daysSince(lastLdlObs.getObsDatetime(), context) < 360)) { needsViralLoadTest = false; } } if (viralLoadObs != null && daysSince(viralLoadObs.getObsDatetime(), context) >= 180) { needsViralLoadTest = true; } if (lastLdlObs != null && daysSince(lastLdlObs.getObsDatetime(), context) >= 180) { needsViralLoadTest = true; } } // check if has vl test order within 6 months if (lastVlTestOrder != null && daysSince(lastVlTestOrder.getObsDatetime(), context) >= 180) { needsViralLoadTest = true; } if (lastVlTestOrder != null && daysSince(lastVlTestOrder.getObsDatetime(), context) < 180) { needsViralLoadTest = false; } } ret.put(ptId, new BooleanResult(needsViralLoadTest, this)); } return ret; }