Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#6286 Change covid caseclassifications #6319

Merged
merged 2 commits into from
Aug 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package de.symeda.sormas.api.caze.classification;

import java.lang.reflect.Field;
import java.util.List;

import de.symeda.sormas.api.Disease;
import de.symeda.sormas.api.caze.CaseDataDto;
import de.symeda.sormas.api.event.EventDto;
import de.symeda.sormas.api.i18n.I18nProperties;
import de.symeda.sormas.api.i18n.Strings;
import de.symeda.sormas.api.person.PersonDto;
import de.symeda.sormas.api.sample.PathogenTestDto;
import de.symeda.sormas.api.symptoms.SymptomState;
import de.symeda.sormas.api.symptoms.SymptomsDto;
import de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers;

public class ClassificationAnyOfSymptomsCriteriaDto extends ClassificationCriteriaDto {

private SymptomState symptomState;
private FieldVisibilityCheckers fieldVisibilityCheckers;

public ClassificationAnyOfSymptomsCriteriaDto(SymptomState symptomState, Disease disease, String countryLocale) {
this.symptomState = symptomState;
fieldVisibilityCheckers = FieldVisibilityCheckers.withDisease(disease).andWithCountry(countryLocale);
}

@Override
public boolean eval(CaseDataDto caze, PersonDto person, List<PathogenTestDto> pathogenTests, List<EventDto> events) {

for (Field field : SymptomsDto.class.getDeclaredFields()) {

SymptomsDto symptomsDto = caze.getSymptoms();
if (field.getType() == SymptomState.class && fieldVisibilityCheckers.isVisible(SymptomsDto.class, field.getName())) {
field.setAccessible(true);
try {
boolean matchedFieldState = field.get(symptomsDto) == symptomState;
field.setAccessible(false);
if (matchedFieldState) {
return true;
}
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
return false;
}

@Override
public String buildDescription() {
StringBuilder stringBuilder = new StringBuilder();

stringBuilder.append("<b> ")
.append(I18nProperties.getString(Strings.classificationSymptomsAnyOf).toUpperCase())
.append("</b>")
.append(" ")
.append(I18nProperties.getString(Strings.setTo))
.append(" ");

if (symptomState == null) {
stringBuilder.append("<b>").append(I18nProperties.getString(Strings.none).toUpperCase()).append("</b>").append("</br>");
} else {
stringBuilder.append("<b>").append(symptomState.toString().toUpperCase()).append("</b>").append("</br>");
}

for (Field field : SymptomsDto.class.getDeclaredFields()) {
if (field.getType() == SymptomState.class && fieldVisibilityCheckers.isVisible(SymptomsDto.class, field.getName())) {
stringBuilder.append(I18nProperties.getPrefixCaption(SymptomsDto.I18N_PREFIX, field.getName())).append("; ");
}
}

if (stringBuilder.length() > 0 && stringBuilder.charAt(stringBuilder.length() - 2) == ';') {
stringBuilder.delete(stringBuilder.length() - 2, stringBuilder.length() - 1);
}

return stringBuilder.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public interface Strings {
String classificationRulesFor = "classificationRulesFor";
String classificationSuspect = "classificationSuspect";
String classificationSymptomsAllOf = "classificationSymptomsAllOf";
String classificationSymptomsAnyOf = "classificationSymptomsAnyOf";
String classificationYearsOrLess = "classificationYearsOrLess";
String classificationYearsOrMore = "classificationYearsOrMore";
String comparedTo = "comparedTo";
Expand Down
1 change: 1 addition & 0 deletions sormas-api/src/main/resources/strings.properties
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ classificationNotACase = Not a case Classification
classificationProbable = Probable Classification
classificationRulesFor = Classification Rules For
classificationSymptomsAllOf = All symptoms
classificationSymptomsAnyOf = Any symptom
classificationSuspect = Suspect Classification
classificationYearsOrLess = years or less
classificationYearsOrMore = years or more
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,10 @@

package de.symeda.sormas.app.rest;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;

import androidx.fragment.app.FragmentActivity;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.Date;
import java.util.concurrent.TimeUnit;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
Expand All @@ -29,13 +27,16 @@
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializer;

import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;

import androidx.fragment.app.FragmentActivity;

import de.symeda.sormas.api.caze.classification.ClassificationAllOfCriteriaDto;
import de.symeda.sormas.api.caze.classification.ClassificationAllSymptomsCriteriaDto;
import de.symeda.sormas.api.caze.classification.ClassificationAnyOfSymptomsCriteriaDto;
import de.symeda.sormas.api.caze.classification.ClassificationCaseCriteriaDto;
import de.symeda.sormas.api.caze.classification.ClassificationCriteriaDto;
import de.symeda.sormas.api.caze.classification.ClassificationEpiDataCriteriaDto;
Expand Down Expand Up @@ -198,8 +199,8 @@ public static Gson initGson() {
.registerSubtype(ClassificationXOfCriteriaDto.ClassificationOneOfCompactCriteriaDto.class, "ClassificationOneOfCompactCriteriaDto")
.registerSubtype(ClassificationAllOfCriteriaDto.ClassificationAllOfCompactCriteriaDto.class, "ClassificationAllOfCompactCriteriaDto")
.registerSubtype(ClassificationEventClusterCriteriaDto.class, "ClassificationEventClusterCriteriaDto")
.registerSubtype(ClassificationAllSymptomsCriteriaDto.class, "ClassificationAllSymptomsCriteriaDto");

.registerSubtype(ClassificationAllSymptomsCriteriaDto.class, "ClassificationAllSymptomsCriteriaDto")
.registerSubtype(ClassificationAnyOfSymptomsCriteriaDto.class, "ClassificationAnyOfSymptomsCriteriaDto");

return new GsonBuilder().registerTypeAdapter(Date.class, (JsonDeserializer<Date>) (json, typeOfT, context1) -> {
if (json.isJsonNull()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import de.symeda.sormas.api.caze.classification.ClassificationAllOfCriteriaDto;
import de.symeda.sormas.api.caze.classification.ClassificationAllOfCriteriaDto.ClassificationAllOfCompactCriteriaDto;
import de.symeda.sormas.api.caze.classification.ClassificationAllSymptomsCriteriaDto;
import de.symeda.sormas.api.caze.classification.ClassificationAnyOfSymptomsCriteriaDto;
import de.symeda.sormas.api.caze.classification.ClassificationCaseCriteriaDto;
import de.symeda.sormas.api.caze.classification.ClassificationCriteriaDto;
import de.symeda.sormas.api.caze.classification.ClassificationEpiDataCriteriaDto;
Expand Down Expand Up @@ -465,6 +466,7 @@ private void buildCriteria() {
PathogenTestType.SEQUENCING,
PathogenTestType.RAPID_TEST));

// confirmed_no_symptoms = positive test AND at least one symptom set to no AND all covid-relevant symptoms are anything but yes
confirmedNoSymptoms = allOf(
positiveTestResult(
Disease.CORONAVIRUS,
Expand All @@ -473,19 +475,10 @@ private void buildCriteria() {
PathogenTestType.ISOLATION,
PathogenTestType.SEQUENCING,
PathogenTestType.RAPID_TEST),
xOf(
1,
allOfSymptoms(SymptomState.NO, Disease.CORONAVIRUS),
xOf(
1,
symptom(SymptomsDto.FEVER),
symptom(SymptomsDto.DIARRHEA),
symptom(SymptomsDto.FAST_HEART_RATE),
symptom(SymptomsDto.RAPID_BREATHING),
symptom(SymptomsDto.OXYGEN_SATURATION_LOWER_94),
symptom(SymptomsDto.VOMITING),
symptom(SymptomsDto.CHILLS_SWEATS))));
anyOfSymptoms(SymptomState.NO, Disease.CORONAVIRUS),
noneOf(anyOfSymptoms(SymptomState.YES, Disease.CORONAVIRUS)));

// confirmed_unknown_symptoms = positive test AND at least one symptom set to null or unknown AND covid-relevant symptoms are anything but yes or no
confirmedUnknownSymptoms = allOf(
positiveTestResult(
Disease.CORONAVIRUS,
Expand All @@ -494,7 +487,8 @@ private void buildCriteria() {
PathogenTestType.ISOLATION,
PathogenTestType.SEQUENCING,
PathogenTestType.RAPID_TEST),
xOf(1, allOfSymptoms(null, Disease.CORONAVIRUS), allOfSymptoms(SymptomState.UNKNOWN, Disease.CORONAVIRUS)));
xOf(1, anyOfSymptoms(SymptomState.UNKNOWN, Disease.CORONAVIRUS), anyOfSymptoms(null, Disease.CORONAVIRUS)),
noneOf(anyOfSymptoms(SymptomState.NO, Disease.CORONAVIRUS), anyOfSymptoms(SymptomState.YES, Disease.CORONAVIRUS)));

addCriteria(
Disease.CORONAVIRUS,
Expand Down Expand Up @@ -614,6 +608,10 @@ private ClassificationPersonAgeBetweenYearsCriteriaDto personAgeBetweenYears(Int
return new ClassificationPersonAgeBetweenYearsCriteriaDto(lowerYearsThreshold, upperYearsThreshold);
}

private ClassificationAnyOfSymptomsCriteriaDto anyOfSymptoms(SymptomState symptomState, Disease disease) {
return new ClassificationAnyOfSymptomsCriteriaDto(symptomState, disease, configFacade.getCountryLocale());
}

private ClassificationAllSymptomsCriteriaDto allOfSymptoms(SymptomState symptomState, Disease disease) {
return new ClassificationAllSymptomsCriteriaDto(symptomState, disease, configFacade.getCountryLocale());
}
Expand Down