Skip to content

Commit 3b3f774

Browse files
O3-5105: Observation value should not need to be bounded to be interpreted (#5401)
1 parent bdc8b25 commit 3b3f774

File tree

2 files changed

+95
-18
lines changed

2 files changed

+95
-18
lines changed

api/src/main/java/org/openmrs/validator/ObsValidator.java

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -509,27 +509,22 @@ private void setObsInterpretation(Obs obs) {
509509
return;
510510
}
511511

512-
if (referenceRange.getHiNormal() != null
513-
&& referenceRange.getHiCritical() != null
514-
&& obs.getValueNumeric() > referenceRange.getHiNormal()
515-
&& obs.getValueNumeric() < referenceRange.getHiCritical()) {
516-
obs.setInterpretation(Obs.Interpretation.HIGH);
517-
} else if (referenceRange.getHiCritical() != null
518-
&& obs.getValueNumeric() >= referenceRange.getHiCritical()) {
512+
Double obsValue = obs.getValueNumeric();
513+
Double hiCritical = referenceRange.getHiCritical();
514+
Double lowCritical = referenceRange.getLowCritical();
515+
Double lowNormal = referenceRange.getLowNormal();
516+
Double hiNormal = referenceRange.getHiNormal();
517+
518+
if (hiCritical != null && obsValue >= hiCritical) {
519519
obs.setInterpretation(Obs.Interpretation.CRITICALLY_HIGH);
520-
} else if (referenceRange.getLowNormal() != null
521-
&& referenceRange.getLowCritical() != null
522-
&& obs.getValueNumeric() < referenceRange.getLowNormal()
523-
&& obs.getValueNumeric() > referenceRange.getLowCritical()) {
520+
} else if (hiNormal != null && obsValue > hiNormal) {
521+
obs.setInterpretation(Obs.Interpretation.HIGH);
522+
} else if (lowCritical != null && obsValue <= lowCritical) {
523+
obs.setInterpretation(Obs.Interpretation.CRITICALLY_LOW);
524+
} else if (lowNormal != null && obsValue < lowNormal) {
524525
obs.setInterpretation(Obs.Interpretation.LOW);
525-
} else if (referenceRange.getLowNormal() != null
526-
&& referenceRange.getHiNormal() != null
527-
&& obs.getValueNumeric() >= referenceRange.getLowNormal()
528-
&& obs.getValueNumeric() <= referenceRange.getHiNormal()) {
526+
} else {
529527
obs.setInterpretation(Obs.Interpretation.NORMAL);
530-
} else if (referenceRange.getLowCritical() != null
531-
&& obs.getValueNumeric() <= referenceRange.getLowCritical()) {
532-
obs.setInterpretation(Obs.Interpretation.CRITICALLY_LOW);
533528
}
534529
}
535530

api/src/test/java/org/openmrs/validator/ObsValidatorTest.java

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.openmrs.ConceptReferenceRange;
3232
import org.openmrs.Drug;
3333
import org.openmrs.Obs;
34+
import org.openmrs.ObsReferenceRange;
3435
import org.openmrs.Person;
3536
import org.openmrs.api.APIException;
3637
import org.openmrs.api.context.Context;
@@ -865,6 +866,86 @@ public void shouldSetInterpretationToCriticalLowIfObsValueIsBelowLowCritical() {
865866
assertEquals(Obs.Interpretation.CRITICALLY_LOW, obs.getInterpretation());
866867
}
867868

869+
@Test
870+
public void shouldSetInterpretationToNormalIfObsValueIsAboveLowNormalAndHiNormalIsNull() {
871+
Obs obs = createObsWithReferenceRange(60, 97, 4090, 95.0, null, 90.0, null, 0.0, 100.0);
872+
873+
Errors errors = new BindException(obs, "obs");
874+
obsValidator.validate(obs, errors);
875+
876+
assertFalse(errors.hasErrors());
877+
assertEquals(Obs.Interpretation.NORMAL, obs.getInterpretation());
878+
}
879+
880+
@Test
881+
public void shouldSetInterpretationToNormalIfObsValueIsBelowHiNormalAndLowNormalIsNull() {
882+
Obs obs = createObsWithReferenceRange(60, 100, 4090, null, 140.0, null, null, null, null);
883+
884+
Errors errors = new BindException(obs, "obs");
885+
obsValidator.validate(obs, errors);
886+
887+
assertFalse(errors.hasErrors());
888+
assertEquals(Obs.Interpretation.NORMAL, obs.getInterpretation());
889+
}
890+
891+
@Test
892+
public void shouldSetInterpretationToHighIfObsValueIsAboveHiNormalAndHiCriticalIsNull() {
893+
Obs obs = createObsWithReferenceRange(60, 150, 4090, null, 140.0, null, null, null, null);
894+
895+
// Set obs ID to prevent reference range from being overwritten by database values
896+
obs.setId(1);
897+
898+
899+
Errors errors = new BindException(obs, "obs");
900+
obsValidator.validate(obs, errors);
901+
902+
assertFalse(errors.hasErrors());
903+
assertEquals(Obs.Interpretation.HIGH, obs.getInterpretation());
904+
}
905+
906+
@Test
907+
public void shouldSetInterpretationToLowIfObsValueIsBelowLowNormalAndLowCriticalIsNull() {
908+
Obs obs = createObsWithReferenceRange(60, 90, 4090, 100.0, 140.0, null, 180.0, 0.0, 100.0);
909+
910+
// Set obs ID to prevent reference range from being overwritten by database values
911+
obs.setId(1);
912+
913+
Errors errors = new BindException(obs, "obs");
914+
obsValidator.validate(obs, errors);
915+
916+
assertFalse(errors.hasErrors());
917+
assertEquals(Obs.Interpretation.LOW, obs.getInterpretation());
918+
}
919+
920+
/**
921+
* Helper method to create an Obs with specific reference range values
922+
* @param value The numeric value for the observation
923+
* @param conceptId The concept id for the observation
924+
* @param lowNormal Low normal value (can be null)
925+
* @param hiNormal High normal value (can be null)
926+
* @param lowCritical Low critical value (can be null)
927+
* @param hiCritical High critical value (can be null)
928+
* @param lowAbsolute Low absolute value (can be null)
929+
* @param hiAbsolute High absolute value (can be null)
930+
*/
931+
private static Obs createObsWithReferenceRange(int numberOfYears, double value, int conceptId, Double lowNormal, Double hiNormal,
932+
Double lowCritical, Double hiCritical, Double lowAbsolute, Double hiAbsolute) {
933+
Obs obs = getObs(numberOfYears, conceptId, value);
934+
935+
// Set up the reference range manually with the provided values
936+
ObsReferenceRange obsRefRange = new ObsReferenceRange();
937+
obsRefRange.setHiAbsolute(hiAbsolute);
938+
obsRefRange.setHiCritical(hiCritical);
939+
obsRefRange.setHiNormal(hiNormal);
940+
obsRefRange.setLowAbsolute(lowAbsolute);
941+
obsRefRange.setLowCritical(lowCritical);
942+
obsRefRange.setLowNormal(lowNormal);
943+
obsRefRange.setObs(obs);
944+
obs.setReferenceRange(obsRefRange);
945+
946+
return obs;
947+
}
948+
868949
private static Obs getObs(int numberOfYears, int conceptId, double valueNumeric) {
869950
Calendar calendar = Calendar.getInstance();
870951
calendar.add(Calendar.YEAR, -numberOfYears);
@@ -879,4 +960,5 @@ private static Obs getObs(int numberOfYears, int conceptId, double valueNumeric)
879960
obs.setObsDatetime(new Date());
880961
return obs;
881962
}
963+
882964
}

0 commit comments

Comments
 (0)