Skip to content

Commit

Permalink
#170: implemented symptoms features for Mpox.
Browse files Browse the repository at this point in the history
  • Loading branch information
Flava177 committed Dec 13, 2024
1 parent b3911c6 commit ff22e55
Show file tree
Hide file tree
Showing 5 changed files with 190 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
// public static final int DATABASE_VERSION = 307;
//public static final int DATABASE_VERSION = 343;
// public static final int DATABASE_VERSION = 410;
public static final int DATABASE_VERSION = 419;
public static final int DATABASE_VERSION = 420;

private static DatabaseHelper instance = null;

Expand Down Expand Up @@ -4309,6 +4309,11 @@ public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource, int
getDao(Case.class).executeRaw("ALTER TABLE cases ADD COLUMN regionOfResidence_id bigint REFERENCES region(id);");
getDao(Case.class).executeRaw("ALTER TABLE cases ADD COLUMN districtOfResidence_id bigint REFERENCES district(id);");

case 419:
currentVersion = 419;
getDao(Symptoms.class).executeRaw("ALTER TABLE symptoms ADD COLUMN dateOfDeath Date;");
getDao(Symptoms.class).executeRaw("ALTER TABLE symptoms ADD COLUMN placeOfDeath varchar(255);");

// ATTENTION: break should only be done after last version
break;
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,10 @@ public class Symptoms extends PseudonymizableAdo {

@Enumerated(EnumType.STRING)
private YesNo pregnant;
@DatabaseField(dataType = DataType.DATE_LONG)
private Date dateOfDeath;
@Column
private String placeOfDeath;


@Override
Expand Down Expand Up @@ -2830,4 +2834,20 @@ public CaseOutcome getOutcome() {
public void setOutcome(CaseOutcome outcome) {
this.outcome = outcome;
}

public Date getDateOfDeath() {
return dateOfDeath;
}

public void setDateOfDeath(Date dateOfDeath) {
this.dateOfDeath = dateOfDeath;
}

public String getPlaceOfDeath() {
return placeOfDeath;
}

public void setPlaceOfDeath(String placeOfDeath) {
this.placeOfDeath = placeOfDeath;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,8 @@ public void fillInnerFromDto(Symptoms target, SymptomsDto source) {
target.setTrimester(source.getTrimester());
target.setPostpartum(source.getPostpartum());
target.setPregnant(source.getPregnant());
target.setDateOfDeath(source.getDateOfDeath());
target.setPlaceOfDeath(source.getPlaceOfDeath());
// target.setHealthConditions(healthConditionsDtoHelper.fillOrCreateFromDto(target.getHealthConditions(), source.getHealthConditions()));
target.setPseudonymized(source.isPseudonymized());
}
Expand Down Expand Up @@ -578,6 +580,8 @@ public void fillInnerFromAdo(SymptomsDto target, Symptoms source) {
target.setTrimester(source.getTrimester());
target.setPostpartum(source.getPostpartum());
target.setPregnant(source.getPregnant());
target.setDateOfDeath(source.getDateOfDeath());
target.setPlaceOfDeath(source.getPlaceOfDeath());

target.setPseudonymized(source.isPseudonymized());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,31 @@
import android.view.View;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import de.symeda.sormas.api.Disease;
import de.symeda.sormas.api.FormType;
import de.symeda.sormas.api.caze.CaseClassification;
import de.symeda.sormas.api.caze.CaseOutcome;
import de.symeda.sormas.api.caze.VaccinationStatus;
import de.symeda.sormas.api.hospitalization.SymptomsList;
import de.symeda.sormas.api.infrastructure.facility.FacilityTypeGroup;
import de.symeda.sormas.api.person.ApproximateAgeType;
import de.symeda.sormas.api.sample.IpSampleTestType;
import de.symeda.sormas.api.sample.SampleMaterial;
import de.symeda.sormas.api.symptoms.CongenitalHeartDiseaseType;
import de.symeda.sormas.api.symptoms.GuineaWormFirstSymptom;
import de.symeda.sormas.api.symptoms.SymptomState;
import de.symeda.sormas.api.symptoms.SymptomsContext;
import de.symeda.sormas.api.symptoms.SymptomsDto;
import de.symeda.sormas.api.symptoms.SymptomsHelper;
import de.symeda.sormas.api.symptoms.TemperatureSource;
import de.symeda.sormas.api.utils.BodyPart;
import de.symeda.sormas.api.utils.DependantOn;
import de.symeda.sormas.api.utils.InjectionSite;
import de.symeda.sormas.api.utils.YesNoUnknown;
Expand Down Expand Up @@ -78,8 +87,6 @@ public class SymptomsEditFragment extends BaseEditFragment<FragmentSymptomsEditL
private List<Item> bodyTempList;
private List<Item> tempSourceList;
private List<Item> congenitalHeartDiseaseList;
private List<Item> caseOutcomeList;

private IEntryItemOnClickListener clearAllCallback;
private IEntryItemOnClickListener setClearedToNoCallback;
private IEntryItemOnClickListener setClearedToUnknownCallback;
Expand Down Expand Up @@ -171,10 +178,9 @@ public void onLayoutBinding(final FragmentSymptomsEditLayoutBinding contentBindi
contentBinding.setClearAllCallback(clearAllCallback);
contentBinding.setSetClearedToNoCallback(setClearedToNoCallback);
contentBinding.setSetClearedToUnknownCallback(setClearedToUnknownCallback);
caseOutcomeList = DataUtils.getEnumItems(CaseOutcome.class, true);
contentBinding.symptomsOutcome.setSpinnerData(caseOutcomeList);
contentBinding.setYesNoUnknownClass(YesNoUnknown.class);
contentBinding.symptomsDateOnsetParalysis.initializeDateField(getFragmentManager());
contentBinding.symptomsDateOfDeath.initializeDateField(getFragmentManager());
injectionSiteList = DataUtils.getEnumItems(InjectionSite.class, true);
contentBinding.symptomsSiteOfParalysis.initializeCheckBoxGroup(injectionSiteList);

Expand Down Expand Up @@ -225,18 +231,51 @@ public void onAfterLayoutBinding(FragmentSymptomsEditLayoutBinding contentBindin
contentBinding.symptomsDateFirstWormEmergence.initializeDateField(getFragmentManager());
contentBinding.symptomsOutcome.initializeSpinner(outcomeList);
contentBinding.symptomsDateOfOnset.initializeDateField(getFragmentManager());
contentBinding.symptomsDateOfOnsetRash.initializeDateField(getFragmentManager());
contentBinding.symptomsTemperature.setSelectionOnOpen(37.0f);


initSymptomFields(contentBinding);
initOnsetSymptomField(contentBinding);

Set<SymptomsList> symptomList = Arrays.stream(SymptomsList.MpoxList())
.filter(c -> c != null)
.filter(c -> fieldVisibilityCheckers.isVisible(SymptomsList.class, c.name()))
.collect(Collectors.toSet());

List<Item> compatibleItems = DataUtils.toItems(new ArrayList<>(symptomList));
compatibleItems.removeIf(item -> item == null || item.toString().isEmpty());

contentBinding.symptomsSymptomsSelected.initializeCheckBoxGroup(compatibleItems);

contentBinding.symptomsSymptomsSelected.setOnValueChangeListener( field -> {
List<String> selectedValues = contentBinding.symptomsSymptomsSelected.getSelectedValues();

boolean other = selectedValues != null && selectedValues.contains("Other");
contentBinding.symptomsSymptomsSelectedOther.setVisibility(other ? View.VISIBLE : View.GONE);

});

List<Item> mainItems = DataUtils.getEnumItems(BodyPart.class);
mainItems.removeIf(item -> item == null || item.toString().isEmpty());

contentBinding.symptomsRashSymptoms.initializeCheckBoxGroup(mainItems);

contentBinding.symptomsRashSymptoms.setOnValueChangeListener( field -> {
List<String> selectedValues = contentBinding.symptomsRashSymptoms.getSelectedValues();

boolean otherRash = selectedValues != null && selectedValues.contains("Other");
contentBinding.symptomsRashSymptomsOtherAreas.setVisibility(otherRash ? View.VISIBLE : View.GONE);

});

// Remove the Complications heading for CRS; should be done automatically later
if (disease == Disease.CONGENITAL_RUBELLA||disease == Disease.MONKEYPOX) {
contentBinding.complicationsHeading.setVisibility(GONE);
}
//TODO: CHANGE FROM IF TO SWITCH AND REMOVE REDUNDANCY CODE

if (disease == Disease.YELLOW_FEVER || disease == Disease.AHF){
if (disease == Disease.YELLOW_FEVER || disease == Disease.AHF || disease == Disease.MONKEYPOX){

Set<CaseOutcome> outcomesToRemove = Set.of(
CaseOutcome.NO_OUTCOME,
Expand All @@ -247,11 +286,25 @@ public void onAfterLayoutBinding(FragmentSymptomsEditLayoutBinding contentBindin
CaseOutcome.RECOVERED
);

contentBinding.symptomsOutcome.initializeSpinner(outcomeList);
outcomeList.removeIf(item -> outcomesToRemove.contains(item.getValue()));

}

if (disease == Disease.MONKEYPOX) {
contentBinding.symptomsOutcome.setCaption("Status of the Patient");

List<SymptomsList> rashSymptomsList = Arrays.asList(
SymptomsList.MACULAR,
SymptomsList.MACULOPAPULAR,
SymptomsList.VESICULAR,
SymptomsList.PAPULAR,
SymptomsList.PETECHIAL
);

contentBinding.symptomsTypeOfRash.initializeSpinner(DataUtils.toItems(rashSymptomsList));

}

if (disease == Disease.YELLOW_FEVER || disease == Disease.AHF){
contentBinding.symptomsDateOfOnset.setCaption("Date Of Onset For The Fever");
}
Expand Down
102 changes: 101 additions & 1 deletion sormas-app/app/src/main/res/layout/fragment_symptoms_edit_layout.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,13 @@
<import type="de.symeda.sormas.api.symptoms.SymptomState" />
<import type="de.symeda.sormas.api.symptoms.GuineaWormFirstSymptom" />
<import type="de.symeda.sormas.api.caze.CaseOutcome" />
<import type="de.symeda.sormas.api.hospitalization.SymptomsList" />
<import type="de.symeda.sormas.api.utils.YesNo" />
<import type="de.symeda.sormas.api.utils.YesNoUnknown" />
<import type="de.symeda.sormas.api.utils.InjectionSite" />
<import type="de.symeda.sormas.api.utils.BodyPart" />
<import type="de.symeda.sormas.api.i18n.I18nProperties" />
<import type="de.symeda.sormas.api.i18n.Strings" />

<variable name="data" type="de.symeda.sormas.app.backend.symptoms.Symptoms"/>
<variable name="symptomStateClass" type="Class"/>
Expand Down Expand Up @@ -1710,12 +1714,17 @@
style="@style/ControlSingleColumnStyle" />

<de.symeda.sormas.app.component.controls.ControlDateField
android:id="@+id/symptoms_onsetDate"
app:value="@={data.onsetDate}"
style="@style/ControlSingleColumnStyle" />

<!--<de.symeda.sormas.app.component.controls.ControlDateField
android:id="@+id/symptoms_onsetDate"
app:value="@={data.onsetDate}"
app:softRequired="true"
app:goneIfVariable="@{symptomsContext}"
app:goneIfValue="@{SymptomsContext.CLINICAL_VISIT}"
style="@style/ControlSingleColumnStyle" />
style="@style/ControlSingleColumnStyle" />-->

<de.symeda.sormas.app.component.controls.ControlSpinnerField
android:id="@+id/symptoms_onsetSymptom"
Expand All @@ -1737,6 +1746,97 @@
app:dependencyParentValue="@{CaseOutcome.OTHER}"
style="@style/ControlSingleColumnStyle" />

<TextView
android:id="@+id/headingSymptoms"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{I18nProperties.getString(Strings.headingSymptoms)}"
style="@style/SubHeadingStyle" />

<de.symeda.sormas.app.component.controls.ControlCheckBoxGroupField
android:id="@+id/symptoms_symptomsSelected"
app:value="@{data.symptomsSelected}"
style="@style/ControlSingleColumnStyle" />

<de.symeda.sormas.app.component.controls.ControlTextEditField
android:id="@+id/symptoms_symptomsSelectedOther"
app:value="@{data.symptomsSelectedOther}"
style="@style/ControlSingleColumnStyle" />

<de.symeda.sormas.app.component.controls.ControlDateField
android:id="@+id/symptoms_dateOfOnsetRash"
app:value="@={data.dateOfOnsetRash}"
style="@style/ControlSingleColumnStyle" />

<de.symeda.sormas.app.component.controls.ControlCheckBoxGroupField
android:id="@+id/symptoms_rashSymptoms"
app:value="@{data.rashSymptoms}"
style="@style/ControlSingleColumnStyle" />

<de.symeda.sormas.app.component.controls.ControlTextEditField
android:id="@+id/symptoms_rashSymptomsOtherAreas"
app:value="@{data.rashSymptomsOtherAreas}"
style="@style/ControlSingleColumnStyle" />

<de.symeda.sormas.app.component.controls.ControlSwitchField
android:id="@+id/symptoms_areLesionsSameState"
app:enumClass="@{YesNoClass}"
app:value="@{data.areLesionsSameState}"
style="@style/ControlSingleColumnStyle" />

<de.symeda.sormas.app.component.controls.ControlSwitchField
android:id="@+id/symptoms_areLesionsSameSize"
app:enumClass="@{YesNoClass}"
app:value="@{data.areLesionsSameSize}"
style="@style/ControlSingleColumnStyle" />

<de.symeda.sormas.app.component.controls.ControlSwitchField
android:id="@+id/symptoms_areLesionsDeep"
app:enumClass="@{YesNoClass}"
app:value="@{data.areLesionsDeep}"
style="@style/ControlSingleColumnStyle" />

<de.symeda.sormas.app.component.controls.ControlSwitchField
android:id="@+id/symptoms_areUlcersAmong"
app:enumClass="@{YesNoClass}"
app:value="@{data.areUlcersAmong}"
style="@style/ControlSingleColumnStyle" />

<de.symeda.sormas.app.component.controls.ControlSpinnerField
android:id="@+id/symptoms_typeOfRash"
app:value="@{data.typeOfRash}"
style="@style/ControlSingleColumnStyle" />

<TextView
android:id="@+id/headingPatientStatus"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{I18nProperties.getString(Strings.headingPatientStatus)}"
style="@style/SubHeadingStyle" />

<LinearLayout
android:id="@+id/symptoms_deathDatePlace_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

<de.symeda.sormas.app.component.controls.ControlDateField
android:id="@+id/symptoms_dateOfDeath"
app:value="@={data.dateOfDeath}"
app:dependencyParentField="@{symptomsOutcome}"
app:dependencyParentValue="@{CaseOutcome.DECEASED}"
style="@style/ControlFirstOfTwoColumnsStyle" />

<de.symeda.sormas.app.component.controls.ControlTextEditField
android:id="@+id/symptoms_placeOfDeath"
app:value="@={data.placeOfDeath}"
app:dependencyParentField="@{symptomsOutcome}"
app:dependencyParentValue="@{CaseOutcome.DECEASED}"
style="@style/ControlSecondOfTwoColumnsStyle" />

</LinearLayout>


</LinearLayout>

</ScrollView>
Expand Down

0 comments on commit ff22e55

Please sign in to comment.