Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
public class HIVPositiveRule implements Rule {

/*
The central point of our implementation is the eval() method - it takes a patient and the criteria as arguments. Basically this is the place that will contain the business logic defined above. So let's see what it looks like, step-by-step: */

public Result eval(Patient patient, LogicCriteria criteria) {

Result allDiagnoses = Result.nullResult();
The allDiagnoses result is used for keeping all the results from individual data lookups below. It is initialized by using a static Result.nullResult() method, to indicate to the logic service it is actually just a placeholder for future results. 
try
  { Boolean ageOK = Context.getLogicService().eval(patient, new LogicCriteria("AGE").gt(1)).toBoolean();
  if (!ageOK) return Result.nullResult();

/*
As defined earlier, our criteria for HIV positive can only be fulfilled if and only if the patient is older than 1. Thus, we use the Logic Service to do the thinking for us by supplying it this criteria as _new LogicCriteria("AGE").gt(1).toBoolean()_. Simple enough. What this call actually does is it invokes the AgeRule behind the scenes, which does the actual birthdate retrieval (via DemographicsRule) and age calculation. Although we could code our _age > 1_ condition here, it is best left to the Logic Service, since it transforms the request into a much faster database query. When we apply the _gt(1)_ criteria to our "AGE" token, the actual result (patient's age) is returned only if the patient's data matches the criteria. Otherwise, the result returned is a null result. When a non-null result is coerced into a Boolean, the resulting boolean value is _true_. Null results are coerced into _false_. 
*/

// we find the first HIV diagnosis
allDiagnoses.add(Context.getLogicService().eval( patient, new LogicCriteria("PROBLEM ADDED").contains( "HUMAN IMMUNODEFICIENCY VIRUS").first()));
allDiagnoses.add(Context.getLogicService().eval( patient, new LogicCriteria("PROBLEM ADDED").contains("HIV INFECTED") .first()));
allDiagnoses.add(Context.getLogicService().eval( patient, new LogicCriteria("PROBLEM ADDED").contains( "ASYMPTOMATIC HIV INFECTION").first()));

/*
This is where we begin our actual data retrievals. (All these _eval(...)_ calls are actually calling ObservationRule's _eval()_ method behind the scenes.) Since the criteria we seek deals with coded results, we need to use the _contains()_ operator. The mechanism behind the _new LogicCriteria("PROBLEM ADDED").contains("HUMAN IMMUNODEFICIENCY VIRUS").first()_ call is:# The obs table is looked up for the given patient, using as filter the [PROBLEM ADDED|http://demo.openmrs.org/openmrs/dictionary/concept.htm?conceptId=6042] concept# The list of observations is then filtered to match the value_coded=884, which is the concept ID for [HUMAN IMMUNODEFICIENCY VIRUS|http://demo.openmrs.org/openmrs/dictionary/concept.htm?conceptId=884]# The result would then normally be returned to the user, listing all observations that match the criteria. But, since there is a _.first()_ method attached to the end of the criteria, only the earliest result (sorted by _date_created_) is returned. Again, if there are no observations that match the given criteria, a null result is returned. */

// first viral load
allDiagnoses.add(Context.getLogicService().eval(patient, new LogicCriteria("HIV VIRAL LOAD").first()));

// first qualitative viral load
allDiagnoses.add(Context.getLogicService().eval(patient, new LogicCriteria("HIV VIRAL LOAD, QUALITATIVE").first()));

// first CD4 COUNT < 200
allDiagnoses.add(Context.getLogicService().eval(patient, new LogicCriteria("CD4 COUNT").lt(200).first()));

Next, we fetch more observation results, this time with no need for the _contains()_ operator, since these are trivial lookups. The _first()_ method is used in the same fashion, returning the first result by date (if any).

return allDiagnoses.getFirstByDate();

}

catch (LogicException e) {
  return Result.nullResult();
}

}

...