diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/caze/CaseDao.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/caze/CaseDao.java index 223827e75e3..ee5909e2d2c 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/caze/CaseDao.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/caze/CaseDao.java @@ -83,6 +83,8 @@ import de.symeda.sormas.app.backend.foodhistory.FoodHistory; import de.symeda.sormas.app.backend.investigationnotes.InvestigationNotes; import de.symeda.sormas.app.backend.patientsymptomsprecedence.PatientSymptomsPrecedence; +import de.symeda.sormas.app.backend.patienttraveldetailsduring.PatientTravelDetailsDuring; +import de.symeda.sormas.app.backend.patienttraveldetailsprior.PatientTravelDetailsPrior; import de.symeda.sormas.app.backend.person.Person; import de.symeda.sormas.app.backend.persontravelhistory.PersonTravelHistory; import de.symeda.sormas.app.backend.region.Community; @@ -252,6 +254,16 @@ public Date getLatestChangeDate() { date = affectedPersonDate; } + Date patientTravelDetailsDuringDate = getLatestChangeDateSubJoin(RiskFactor.TABLE_NAME, Case.RISK_FACTOR, PatientTravelDetailsDuring.TABLE_NAME); + if (patientTravelDetailsDuringDate != null && patientTravelDetailsDuringDate.after(date)) { + date = patientTravelDetailsDuringDate; + } + + Date patientTravelDetailsPriorDate = getLatestChangeDateSubJoin(RiskFactor.TABLE_NAME, Case.RISK_FACTOR, PatientTravelDetailsPrior.TABLE_NAME); + if (patientTravelDetailsPriorDate != null && patientTravelDetailsPriorDate.after(date)) { + date = patientTravelDetailsPriorDate; + } + Date investigationNotesDate = getLatestChangeDateJoin(InvestigationNotes.TABLE_NAME, Case.INVESTIGATION_NOTES); if (investigationNotesDate != null && investigationNotesDate.after(date)) { date = investigationNotesDate; diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/DatabaseHelper.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/DatabaseHelper.java index fdde8e967de..d488929a6f4 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/DatabaseHelper.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/common/DatabaseHelper.java @@ -152,6 +152,10 @@ import de.symeda.sormas.app.backend.outbreak.OutbreakDao; import de.symeda.sormas.app.backend.patientsymptomsprecedence.PatientSymptomsPrecedence; import de.symeda.sormas.app.backend.patientsymptomsprecedence.PatientSymptomsPrecedenceDao; +import de.symeda.sormas.app.backend.patienttraveldetailsduring.PatientTravelDetailsDuring; +import de.symeda.sormas.app.backend.patienttraveldetailsduring.PatientTravelDetailsDuringDao; +import de.symeda.sormas.app.backend.patienttraveldetailsprior.PatientTravelDetailsPrior; +import de.symeda.sormas.app.backend.patienttraveldetailsprior.PatientTravelDetailsPriorDao; import de.symeda.sormas.app.backend.person.Person; import de.symeda.sormas.app.backend.person.PersonContactDetail; import de.symeda.sormas.app.backend.person.PersonContactDetailDao; @@ -318,6 +322,8 @@ public static void clearTables(boolean clearInfrastructure) { TableUtils.clearTable(connectionSource, AfpImmunization.class); TableUtils.clearTable(connectionSource, SixtyDay.class); TableUtils.clearTable(connectionSource, PatientSymptomsPrecedence.class); + TableUtils.clearTable(connectionSource, PatientTravelDetailsDuring.class); + TableUtils.clearTable(connectionSource, PatientTravelDetailsPrior.class); if (clearInfrastructure) { TableUtils.clearTable(connectionSource, UserUserRole.class); @@ -678,6 +684,14 @@ public static PatientSymptomsPrecedenceDao getPatientSymptomsPrecedenceDao() { return (PatientSymptomsPrecedenceDao) getAdoDao(PatientSymptomsPrecedence.class); } + public static PatientTravelDetailsDuringDao getPatientTravelDetailsDuringDao() { + return (PatientTravelDetailsDuringDao) getAdoDao(PatientTravelDetailsDuring.class); + } + + public static PatientTravelDetailsPriorDao getPatientTravelDetailsPriorDao() { + return (PatientTravelDetailsPriorDao) getAdoDao(PatientTravelDetailsPrior.class); + } + // TODO [vaccination info] integrate vaccination info // public static VaccinationInfoDao getVaccinationInfoDao() { // return (VaccinationInfoDao) getAdoDao(VaccinationInfo.class); @@ -796,6 +810,8 @@ public void onCreate(SQLiteDatabase db, ConnectionSource connectionSource) { TableUtils.createTable(connectionSource, AfpImmunization.class); TableUtils.createTable(connectionSource, SixtyDay.class); TableUtils.createTable(connectionSource, PatientSymptomsPrecedence.class); + TableUtils.createTable(connectionSource, PatientTravelDetailsPrior.class); + TableUtils.createTable(connectionSource, PatientTravelDetailsDuring.class); TableUtils.createTable(connectionSource, DiseaseFacility.class); } catch (SQLException e) { @@ -4459,6 +4475,44 @@ public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource, int case 428: currentVersion = 428; getDao(DiseaseConfiguration.class).executeRaw("CREATE TABLE IF NOT EXISTS facility_diseaseconfiguration(diseaseConfiguration_id integer, facility_id integer);"); + + case 429: + currentVersion = 429; + getDao(PatientTravelDetailsDuring.class).executeRaw( + "CREATE TABLE patienttraveldetailsduring (" + + " id INTEGER PRIMARY KEY AUTOINCREMENT," + + " uuid VARCHAR(36) NOT NULL UNIQUE," + + " changedate BIGINT NOT NULL," + + " creationdate BIGINT NOT NULL," + + " riskfactor_id BIGINT NOT NULL," + + " dateOfTravel DATE," + + " placeOfTravel VARCHAR(255)," + + " pseudonymized SMALLINT," + + " lastOpenedDate BIGINT," + + " localChangeDate BIGINT NOT NULL," + + " modified SMALLINT," + + " snapshot SMALLINT," + + " UNIQUE (snapshot ASC, uuid ASC)" + + ");" + ); + + getDao(PatientTravelDetailsPrior.class).executeRaw( + "CREATE TABLE patienttraveldetailsprior (" + + " id INTEGER PRIMARY KEY AUTOINCREMENT," + + " uuid VARCHAR(36) NOT NULL UNIQUE," + + " changedate BIGINT NOT NULL," + + " creationdate BIGINT NOT NULL," + + " riskfactor_id BIGINT NOT NULL," + + " dateOfTravel DATE," + + " placeOfTravel VARCHAR(255)," + + " pseudonymized SMALLINT," + + " lastOpenedDate BIGINT," + + " localChangeDate BIGINT NOT NULL," + + " modified SMALLINT," + + " snapshot SMALLINT," + + " UNIQUE (snapshot ASC, uuid ASC)" + + ");" + ); // ATTENTION: break should only be done after last version break; default: @@ -5277,6 +5331,8 @@ private void upgradeFromUnupgradableVersion(SQLiteDatabase db, ConnectionSource TableUtils.dropTable(connectionSource, ContaminationSource.class, true); TableUtils.dropTable(connectionSource, ContainmentMeasure.class, true); TableUtils.dropTable(connectionSource, AffectedPerson.class, true); + TableUtils.dropTable(connectionSource, PatientTravelDetailsDuring.class, true); + TableUtils.dropTable(connectionSource, PatientTravelDetailsPrior.class, true); TableUtils.dropTable(connectionSource, SixtyDay.class, true); TableUtils.dropTable(connectionSource, PatientSymptomsPrecedence.class, true); @@ -5446,6 +5502,10 @@ public AbstractAdoDao getAdoDaoInner(Cla dao = (AbstractAdoDao) new SixtyDayDao((Dao) innerDao); } else if (type.equals(PatientSymptomsPrecedence.class)) { dao = (AbstractAdoDao) new PatientSymptomsPrecedenceDao((Dao) innerDao); + } else if (type.equals(PatientTravelDetailsDuring.class)) { + dao = (AbstractAdoDao) new PatientTravelDetailsDuringDao((Dao) innerDao); + } else if (type.equals(PatientTravelDetailsPrior.class)) { + dao = (AbstractAdoDao) new PatientTravelDetailsPriorDao((Dao) innerDao); } else { throw new UnsupportedOperationException(type.toString()); } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/patienttraveldetailsduring/PatientTravelDetailsDuring.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/patienttraveldetailsduring/PatientTravelDetailsDuring.java new file mode 100644 index 00000000000..eee17fd10d5 --- /dev/null +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/patienttraveldetailsduring/PatientTravelDetailsDuring.java @@ -0,0 +1,62 @@ +package de.symeda.sormas.app.backend.patienttraveldetailsduring; + +import com.j256.ormlite.field.DataType; +import com.j256.ormlite.field.DatabaseField; +import com.j256.ormlite.table.DatabaseTable; + +import de.symeda.sormas.api.utils.TravelLocation; +import de.symeda.sormas.app.backend.common.EmbeddedAdo; +import de.symeda.sormas.app.backend.common.PseudonymizableAdo; +import de.symeda.sormas.app.backend.riskfactor.RiskFactor; + +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import java.util.Date; + +@Entity(name = PatientTravelDetailsDuring.TABLE_NAME) +@DatabaseTable(tableName = PatientTravelDetailsDuring.TABLE_NAME) +@EmbeddedAdo(parentAccessor = PatientTravelDetailsDuring.RISK_FACTOR) + +public class PatientTravelDetailsDuring extends PseudonymizableAdo { + public static final String I18N_PREFIX = "PatientTravelDetailsDuring"; + private static final long serialVersionUID = 6551672739041643942L; + + public static final String TABLE_NAME = "patienttraveldetailsduring"; + public static final String RISK_FACTOR = "riskFactor"; + + @DatabaseField(dataType = DataType.DATE_LONG) + private Date dateOfTravel; + @Enumerated(EnumType.STRING) + private TravelLocation placeOfTravel; + @DatabaseField(foreign = true, foreignAutoRefresh = true) + private RiskFactor riskFactor; + + @Override + public String getI18nPrefix() { + return I18N_PREFIX; + } + + public RiskFactor getRiskFactor() { + return riskFactor; + } + public void setRiskFactor(RiskFactor riskFactor) { + this.riskFactor = riskFactor; + } + + public Date getDateOfTravel() { + return dateOfTravel; + } + + public void setDateOfTravel(Date dateOfTravel) { + this.dateOfTravel = dateOfTravel; + } + + public TravelLocation getPlaceOfTravel() { + return placeOfTravel; + } + + public void setPlaceOfTravel(TravelLocation placeOfTravel) { + this.placeOfTravel = placeOfTravel; + } +} diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/patienttraveldetailsduring/PatientTravelDetailsDuringDao.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/patienttraveldetailsduring/PatientTravelDetailsDuringDao.java new file mode 100644 index 00000000000..4c76dd22579 --- /dev/null +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/patienttraveldetailsduring/PatientTravelDetailsDuringDao.java @@ -0,0 +1,54 @@ +package de.symeda.sormas.app.backend.patienttraveldetailsduring; + +import com.j256.ormlite.dao.Dao; + +import java.sql.SQLException; +import java.util.Date; +import java.util.List; + +import de.symeda.sormas.app.backend.common.AbstractAdoDao; +import de.symeda.sormas.app.backend.riskfactor.RiskFactor; + +public class PatientTravelDetailsDuringDao extends AbstractAdoDao { + + public PatientTravelDetailsDuringDao(Dao innerDao) { + super(innerDao); + } + + @Override + protected Class getAdoClass() { + return PatientTravelDetailsDuring.class; + } + + @Override + public PatientTravelDetailsDuring build() { + PatientTravelDetailsDuring patientTravelDetailsDuring = super.build(); + return patientTravelDetailsDuring; + } + + @Override + public void deleteCascade(PatientTravelDetailsDuring patientTravelDetailsDuring) throws SQLException { + super.delete(patientTravelDetailsDuring); + } + + public List getByRiskFactor(RiskFactor riskFactor) { + if (riskFactor.isSnapshot()) { + return querySnapshotsForEq(PatientTravelDetailsDuring.RISK_FACTOR + "_id", riskFactor, PatientTravelDetailsDuring.CHANGE_DATE, false); + } + return queryForEq(PatientTravelDetailsDuring.RISK_FACTOR + "_id", riskFactor, PatientTravelDetailsDuring.CHANGE_DATE, false); + } + + @Override + public Date getLatestChangeDate() { + Date date = super.getLatestChangeDate(); + if (date == null) { + return null; + } + return date; + } + + @Override + public String getTableName() { + return PatientTravelDetailsDuring.TABLE_NAME; + } +} diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/patienttraveldetailsduring/PatientTravelDetailsDuringDtoHelper.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/patienttraveldetailsduring/PatientTravelDetailsDuringDtoHelper.java new file mode 100644 index 00000000000..45a20b5a5f3 --- /dev/null +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/patienttraveldetailsduring/PatientTravelDetailsDuringDtoHelper.java @@ -0,0 +1,61 @@ +package de.symeda.sormas.app.backend.patienttraveldetailsduring; + +import java.util.List; + +import de.symeda.sormas.api.PostResponse; +import de.symeda.sormas.api.riskfactor.PatientTravelDetailsDuringDto; +import de.symeda.sormas.app.backend.common.AdoDtoHelper; +import de.symeda.sormas.app.rest.NoConnectionException; +import retrofit2.Call; + + +public class PatientTravelDetailsDuringDtoHelper extends AdoDtoHelper { + + public PatientTravelDetailsDuringDtoHelper() { + } + + @Override + protected Class getAdoClass() { + return PatientTravelDetailsDuring.class; + } + + @Override + protected Class getDtoClass() { + return PatientTravelDetailsDuringDto.class; + } + + @Override + protected Call> pullAllSince(long since, + Integer size, + String lastSynchronizedUuid) throws NoConnectionException { + throw new UnsupportedOperationException("Entity is embedded"); + } + + @Override + protected Call> pullByUuids(List uuids) throws NoConnectionException { + throw new UnsupportedOperationException("Entity is embedded"); + } + + @Override + protected Call> pushAll(List exposureDtos) throws NoConnectionException { + throw new UnsupportedOperationException("Entity is embedded"); + } + + @Override + protected void fillInnerFromDto(PatientTravelDetailsDuring target, PatientTravelDetailsDuringDto source) { + target.setDateOfTravel(source.getDateOfTravel()); + target.setPlaceOfTravel(source.getPlaceOfTravel()); + } + + @Override + protected void fillInnerFromAdo(PatientTravelDetailsDuringDto target, PatientTravelDetailsDuring source) { + target.setDateOfTravel(source.getDateOfTravel()); + target.setPlaceOfTravel(source.getPlaceOfTravel()); + } + + @Override + protected long getApproximateJsonSizeInBytes() { + return 0; + } + +} diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/patienttraveldetailsprior/PatientTravelDetailsPrior.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/patienttraveldetailsprior/PatientTravelDetailsPrior.java new file mode 100644 index 00000000000..9a283b39e57 --- /dev/null +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/patienttraveldetailsprior/PatientTravelDetailsPrior.java @@ -0,0 +1,64 @@ +package de.symeda.sormas.app.backend.patienttraveldetailsprior; + + +import com.j256.ormlite.field.DataType; +import com.j256.ormlite.field.DatabaseField; +import com.j256.ormlite.table.DatabaseTable; + +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import java.util.Date; + +import de.symeda.sormas.app.backend.common.EmbeddedAdo; +import de.symeda.sormas.app.backend.common.PseudonymizableAdo; +import de.symeda.sormas.app.backend.riskfactor.RiskFactor; +import de.symeda.sormas.api.utils.TravelLocation; + +@Entity(name = PatientTravelDetailsPrior.TABLE_NAME) +@DatabaseTable(tableName = PatientTravelDetailsPrior.TABLE_NAME) +@EmbeddedAdo(parentAccessor = PatientTravelDetailsPrior.RISK_FACTOR) + +public class PatientTravelDetailsPrior extends PseudonymizableAdo { + + public static final String I18N_PREFIX = "PatientTravelDetailsPrior"; + private static final long serialVersionUID = 6551672739041643942L; + + public static final String TABLE_NAME = "patienttraveldetailsprior"; + public static final String RISK_FACTOR = "riskFactor"; + + @DatabaseField(dataType = DataType.DATE_LONG) + private Date dateOfTravel; + @Enumerated(EnumType.STRING) + private TravelLocation placeOfTravel; + @DatabaseField(foreign = true, foreignAutoRefresh = true) + private RiskFactor riskFactor; + + @Override + public String getI18nPrefix() { + return I18N_PREFIX; + } + + public RiskFactor getRiskFactor() { + return riskFactor; + } + public void setRiskFactor(RiskFactor riskFactor) { + this.riskFactor = riskFactor; + } + + public Date getDateOfTravel() { + return dateOfTravel; + } + + public void setDateOfTravel(Date dateOfTravel) { + this.dateOfTravel = dateOfTravel; + } + + public TravelLocation getPlaceOfTravel() { + return placeOfTravel; + } + + public void setPlaceOfTravel(TravelLocation placeOfTravel) { + this.placeOfTravel = placeOfTravel; + } +} diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/patienttraveldetailsprior/PatientTravelDetailsPriorDao.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/patienttraveldetailsprior/PatientTravelDetailsPriorDao.java new file mode 100644 index 00000000000..b28addd504e --- /dev/null +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/patienttraveldetailsprior/PatientTravelDetailsPriorDao.java @@ -0,0 +1,54 @@ +package de.symeda.sormas.app.backend.patienttraveldetailsprior; + +import com.j256.ormlite.dao.Dao; + +import java.sql.SQLException; +import java.util.Date; +import java.util.List; + +import de.symeda.sormas.app.backend.common.AbstractAdoDao; +import de.symeda.sormas.app.backend.riskfactor.RiskFactor; + +public class PatientTravelDetailsPriorDao extends AbstractAdoDao { + + public PatientTravelDetailsPriorDao(Dao innerDao) { + super(innerDao); + } + + @Override + protected Class getAdoClass() { + return PatientTravelDetailsPrior.class; + } + + @Override + public PatientTravelDetailsPrior build() { + PatientTravelDetailsPrior patientTravelDetailsPrior = super.build(); + return patientTravelDetailsPrior; + } + + @Override + public void deleteCascade(PatientTravelDetailsPrior patientTravelDetailsPrior) throws SQLException { + super.delete(patientTravelDetailsPrior); + } + + public List getByRiskFactor(RiskFactor riskFactor) { + if (riskFactor.isSnapshot()) { + return querySnapshotsForEq(PatientTravelDetailsPrior.RISK_FACTOR + "_id", riskFactor, PatientTravelDetailsPrior.CHANGE_DATE, false); + } + return queryForEq(PatientTravelDetailsPrior.RISK_FACTOR + "_id", riskFactor, PatientTravelDetailsPrior.CHANGE_DATE, false); + } + + @Override + public Date getLatestChangeDate() { + Date date = super.getLatestChangeDate(); + if (date == null) { + return null; + } + return date; + } + + @Override + public String getTableName() { + return PatientTravelDetailsPrior.TABLE_NAME; + } +} diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/patienttraveldetailsprior/PatientTravelDetailsPriorDtoHelper.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/patienttraveldetailsprior/PatientTravelDetailsPriorDtoHelper.java new file mode 100644 index 00000000000..62c5d597ca8 --- /dev/null +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/patienttraveldetailsprior/PatientTravelDetailsPriorDtoHelper.java @@ -0,0 +1,61 @@ +package de.symeda.sormas.app.backend.patienttraveldetailsprior; + +import java.util.List; + +import de.symeda.sormas.api.PostResponse; +import de.symeda.sormas.api.riskfactor.PatientTravelDetailsPriorDto; +import de.symeda.sormas.app.backend.common.AdoDtoHelper; +import de.symeda.sormas.app.rest.NoConnectionException; +import retrofit2.Call; + + +public class PatientTravelDetailsPriorDtoHelper extends AdoDtoHelper { + + public PatientTravelDetailsPriorDtoHelper() { + } + + @Override + protected Class getAdoClass() { + return PatientTravelDetailsPrior.class; + } + + @Override + protected Class getDtoClass() { + return PatientTravelDetailsPriorDto.class; + } + + @Override + protected Call> pullAllSince(long since, + Integer size, + String lastSynchronizedUuid) throws NoConnectionException { + throw new UnsupportedOperationException("Entity is embedded"); + } + + @Override + protected Call> pullByUuids(List uuids) throws NoConnectionException { + throw new UnsupportedOperationException("Entity is embedded"); + } + + @Override + protected Call> pushAll(List exposureDtos) throws NoConnectionException { + throw new UnsupportedOperationException("Entity is embedded"); + } + + @Override + protected void fillInnerFromDto(PatientTravelDetailsPrior target, PatientTravelDetailsPriorDto source) { + target.setDateOfTravel(source.getDateOfTravel()); + target.setPlaceOfTravel(source.getPlaceOfTravel()); + } + + @Override + protected void fillInnerFromAdo(PatientTravelDetailsPriorDto target, PatientTravelDetailsPrior source) { + target.setDateOfTravel(source.getDateOfTravel()); + target.setPlaceOfTravel(source.getPlaceOfTravel()); + } + + @Override + protected long getApproximateJsonSizeInBytes() { + return 0; + } + +} diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/riskfactor/RiskFactor.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/riskfactor/RiskFactor.java index e8043a3cfa1..f8fbdfe13c4 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/riskfactor/RiskFactor.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/riskfactor/RiskFactor.java @@ -41,12 +41,15 @@ import de.symeda.sormas.api.utils.YesNo; import de.symeda.sormas.api.utils.YesNoUnknown; import de.symeda.sormas.app.backend.activityascase.ActivityAsCase; +import de.symeda.sormas.app.backend.affectedperson.AffectedPerson; import de.symeda.sormas.app.backend.common.EmbeddedAdo; import de.symeda.sormas.app.backend.common.PseudonymizableAdo; import de.symeda.sormas.app.backend.containmentmeasure.ContainmentMeasure; import de.symeda.sormas.app.backend.contaminationsource.ContaminationSource; import de.symeda.sormas.app.backend.exposure.Exposure; import de.symeda.sormas.app.backend.patientsymptomsprecedence.PatientSymptomsPrecedence; +import de.symeda.sormas.app.backend.patienttraveldetailsduring.PatientTravelDetailsDuring; +import de.symeda.sormas.app.backend.patienttraveldetailsprior.PatientTravelDetailsPrior; import de.symeda.sormas.app.backend.persontravelhistory.PersonTravelHistory; import de.symeda.sormas.app.backend.region.Community; import de.symeda.sormas.app.backend.region.District; @@ -151,6 +154,9 @@ public class RiskFactor extends PseudonymizableAdo { @Column(length = CHARACTER_LIMIT_DEFAULT) private String during3WeeksPatientContactWithSimilarSymptomsIfYes; + private List patientTravelDetailsDurings = new ArrayList<>(); + private List patientTravelDetailsPriors = new ArrayList<>(); + private List patientSymptomsPrecedences = new ArrayList<>(); public String getDrinkingWaterSourceOne() { @@ -512,6 +518,22 @@ public void setDuring3WeeksPatientContactWithSimilarSymptomsIfYes(String during3 this.during3WeeksPatientContactWithSimilarSymptomsIfYes = during3WeeksPatientContactWithSimilarSymptomsIfYes; } + public List getPatientTravelDetailsDurings() { + return patientTravelDetailsDurings; + } + + public void setPatientTravelDetailsDurings(List patientTravelDetailsDurings) { + this.patientTravelDetailsDurings = patientTravelDetailsDurings; + } + + public List getPatientTravelDetailsPriors() { + return patientTravelDetailsPriors; + } + + public void setPatientTravelDetailsPriors(List patientTravelDetailsPriors) { + this.patientTravelDetailsPriors = patientTravelDetailsPriors; + } + @Override public String getI18nPrefix() { diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/riskfactor/RiskFactorDao.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/riskfactor/RiskFactorDao.java index 91575471698..58ce30b4c2b 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/riskfactor/RiskFactorDao.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/riskfactor/RiskFactorDao.java @@ -69,6 +69,8 @@ public RiskFactor queryForId(Long id) { private RiskFactor initLazyData(RiskFactor riskFactor) { riskFactor.setPatientSymptomsPrecedences(DatabaseHelper.getPatientSymptomsPrecedenceDao().getByRiskFactor(riskFactor)); + riskFactor.setPatientTravelDetailsDurings(DatabaseHelper.getPatientTravelDetailsDuringDao().getByRiskFactor(riskFactor)); + riskFactor.setPatientTravelDetailsPriors(DatabaseHelper.getPatientTravelDetailsPriorDao().getByRiskFactor(riskFactor)); return riskFactor; } @@ -79,6 +81,12 @@ public RiskFactor saveAndSnapshot(RiskFactor ado) throws DaoException { DatabaseHelper.getPatientSymptomsPrecedenceDao().saveCollectionWithSnapshot(DatabaseHelper.getPatientSymptomsPrecedenceDao().getByRiskFactor(ado), ado.getPatientSymptomsPrecedences(), ado); + DatabaseHelper.getPatientTravelDetailsDuringDao().saveCollectionWithSnapshot(DatabaseHelper.getPatientTravelDetailsDuringDao().getByRiskFactor(ado), + ado.getPatientTravelDetailsDurings(), ado); + + DatabaseHelper.getPatientTravelDetailsPriorDao().saveCollectionWithSnapshot(DatabaseHelper.getPatientTravelDetailsPriorDao().getByRiskFactor(ado), + ado.getPatientTravelDetailsPriors(), ado); + return snapshot; } @@ -89,6 +97,8 @@ public Date getLatestChangeDate() { return null; } date = DateHelper.getLatestDate(date, DatabaseHelper.getPatientSymptomsPrecedenceDao().getLatestChangeDate()); + date = DateHelper.getLatestDate(date, DatabaseHelper.getPatientTravelDetailsDuringDao().getLatestChangeDate()); + date = DateHelper.getLatestDate(date, DatabaseHelper.getPatientTravelDetailsPriorDao().getLatestChangeDate()); return date; } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/riskfactor/RiskFactorDtoHelper.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/riskfactor/RiskFactorDtoHelper.java index ee67336322f..ef46939dc7f 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/riskfactor/RiskFactorDtoHelper.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/backend/riskfactor/RiskFactorDtoHelper.java @@ -21,19 +21,29 @@ import de.symeda.sormas.api.PostResponse; import de.symeda.sormas.api.activityascase.ActivityAsCaseDto; import de.symeda.sormas.api.riskfactor.PatientSymptomsPrecedenceDto; +import de.symeda.sormas.api.riskfactor.PatientTravelDetailsDuringDto; +import de.symeda.sormas.api.riskfactor.PatientTravelDetailsPriorDto; import de.symeda.sormas.api.riskfactor.RiskFactorDto; import de.symeda.sormas.app.backend.activityascase.ActivityAsCase; import de.symeda.sormas.app.backend.common.AdoDtoHelper; import de.symeda.sormas.app.backend.patientsymptomsprecedence.PatientSymptomsPrecedence; import de.symeda.sormas.app.backend.patientsymptomsprecedence.PatientSymptomsPrecedenceDtoHelper; +import de.symeda.sormas.app.backend.patienttraveldetailsduring.PatientTravelDetailsDuring; +import de.symeda.sormas.app.backend.patienttraveldetailsduring.PatientTravelDetailsDuringDtoHelper; +import de.symeda.sormas.app.backend.patienttraveldetailsprior.PatientTravelDetailsPrior; +import de.symeda.sormas.app.backend.patienttraveldetailsprior.PatientTravelDetailsPriorDtoHelper; import de.symeda.sormas.app.rest.NoConnectionException; import retrofit2.Call; public class RiskFactorDtoHelper extends AdoDtoHelper { private final PatientSymptomsPrecedenceDtoHelper patientSymptomsPrecedenceDtoHelper; + private final PatientTravelDetailsDuringDtoHelper patientTravelDetailsDuringDtoHelper; + private final PatientTravelDetailsPriorDtoHelper patientTravelDetailsPriorDtoHelper; public RiskFactorDtoHelper() { patientSymptomsPrecedenceDtoHelper = new PatientSymptomsPrecedenceDtoHelper(); + patientTravelDetailsDuringDtoHelper = new PatientTravelDetailsDuringDtoHelper(); + patientTravelDetailsPriorDtoHelper = new PatientTravelDetailsPriorDtoHelper(); } @Override @@ -119,6 +129,26 @@ public void fillInnerFromDto(RiskFactor target, RiskFactorDto source) { } target.setPatientSymptomsPrecedences(patientSymptomsPrecedences); + List patientTravelDetailsDurings = new ArrayList<>(); + if (!source.getPatientTravelDetailsDuring().isEmpty()) { + for (PatientTravelDetailsDuringDto patientTravelDetailsDuringDto : source.getPatientTravelDetailsDuring()) { + PatientTravelDetailsDuring patientTravelDetailsDuring = patientTravelDetailsDuringDtoHelper.fillOrCreateFromDto(null, patientTravelDetailsDuringDto); + patientTravelDetailsDuring.setRiskFactor(target); + patientTravelDetailsDurings.add(patientTravelDetailsDuring); + } + } + target.setPatientTravelDetailsDurings(patientTravelDetailsDurings); + + List patientTravelDetailsPriors = new ArrayList<>(); + if (!source.getPatientTravelDetailsPrior().isEmpty()) { + for (PatientTravelDetailsPriorDto patientTravelDetailsPriorDto : source.getPatientTravelDetailsPrior()) { + PatientTravelDetailsPrior patientTravelDetailsPrior = patientTravelDetailsPriorDtoHelper.fillOrCreateFromDto(null, patientTravelDetailsPriorDto); + patientTravelDetailsPrior.setRiskFactor(target); + patientTravelDetailsPriors.add(patientTravelDetailsPrior); + } + } + target.setPatientTravelDetailsPriors(patientTravelDetailsPriors); + } @Override @@ -178,6 +208,24 @@ public void fillInnerFromAdo(RiskFactorDto target, RiskFactor source) { } target.setPatientSymptomsPrecedence(patientSymptomsPrecedenceDtos); + List patientTravelDetailsDuringDtos = new ArrayList<>(); + if (!source.getPatientTravelDetailsDurings().isEmpty()) { + for (PatientTravelDetailsDuring patientTravelDetailsDuring : source.getPatientTravelDetailsDurings()) { + PatientTravelDetailsDuringDto patientTravelDetailsDuringDto = patientTravelDetailsDuringDtoHelper.adoToDto(patientTravelDetailsDuring); + patientTravelDetailsDuringDtos.add(patientTravelDetailsDuringDto); + } + } + target.setPatientTravelDetailsDuring(patientTravelDetailsDuringDtos); + + List patientTravelDetailsPriorDtos = new ArrayList<>(); + if (!source.getPatientTravelDetailsPriors().isEmpty()) { + for (PatientTravelDetailsPrior patientTravelDetailsPrior : source.getPatientTravelDetailsPriors()) { + PatientTravelDetailsPriorDto patientTravelDetailsPriorDto = patientTravelDetailsPriorDtoHelper.adoToDto(patientTravelDetailsPrior); + patientTravelDetailsPriorDtos.add(patientTravelDetailsPriorDto); + } + } + target.setPatientTravelDetailsPrior(patientTravelDetailsPriorDtos); + } @Override diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/caze/edit/CaseEditRiskFactorFragment.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/caze/edit/CaseEditRiskFactorFragment.java index b48bc090520..b8f9eff53bc 100644 --- a/sormas-app/app/src/main/java/de/symeda/sormas/app/caze/edit/CaseEditRiskFactorFragment.java +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/caze/edit/CaseEditRiskFactorFragment.java @@ -41,12 +41,16 @@ import de.symeda.sormas.app.backend.common.AbstractDomainObject; import de.symeda.sormas.app.backend.common.DatabaseHelper; import de.symeda.sormas.app.backend.patientsymptomsprecedence.PatientSymptomsPrecedence; +import de.symeda.sormas.app.backend.patienttraveldetailsduring.PatientTravelDetailsDuring; +import de.symeda.sormas.app.backend.patienttraveldetailsprior.PatientTravelDetailsPrior; import de.symeda.sormas.app.backend.riskfactor.RiskFactor; import de.symeda.sormas.app.component.Item; import de.symeda.sormas.app.core.IEntryItemOnClickListener; import de.symeda.sormas.app.databinding.FragmentCaseEditRiskfactorLayoutBinding; import de.symeda.sormas.app.epidata.PersonTravelHistoryDialog; import de.symeda.sormas.app.riskfactor.PatientSymptomsPrecedenceDialog; +import de.symeda.sormas.app.riskfactor.PatientTravelDetailsDuringDialog; +import de.symeda.sormas.app.riskfactor.PatientTravelDetailsPriorDialog; import de.symeda.sormas.app.util.DataUtils; import de.symeda.sormas.app.util.FieldVisibilityAndAccessHelper; @@ -56,6 +60,8 @@ public class CaseEditRiskFactorFragment extends BaseEditFragment listDrinkingWaterSources; private IEntryItemOnClickListener onPatientSymptomsPrecedenceItemClickListener; + private IEntryItemOnClickListener onPatientTravelDetailsDuringItemClickListener; + private IEntryItemOnClickListener onPatientTravelDetailsPriorItemClickListener; public static CaseEditRiskFactorFragment newInstance(Case activityRootData) { return newInstanceWithFieldCheckers( @@ -98,6 +104,18 @@ public void onLayoutBinding(final FragmentCaseEditRiskfactorLayoutBinding conten v -> FieldVisibilityAndAccessHelper .setFieldVisibilitiesAndAccesses(PatientSymptomsPrecedence.class, (ViewGroup) v, new FieldVisibilityCheckers(), getFieldAccessCheckers())); + contentBinding.setPatientTravelDetailsDuringList(getPatientTravelDetailsDurings()); + contentBinding.setPatientTravelDetailsDuringItemClickCallback(onPatientTravelDetailsDuringItemClickListener); + contentBinding.setPatientTravelDetailsDuringListBindCallback( + v -> FieldVisibilityAndAccessHelper + .setFieldVisibilitiesAndAccesses(PatientTravelDetailsDuring.class, (ViewGroup) v, new FieldVisibilityCheckers(), getFieldAccessCheckers())); + + contentBinding.setPatientTravelDetailsPriorList(getPatientTravelDetailsPriors()); + contentBinding.setPatientTravelDetailsPriorItemClickCallback(onPatientTravelDetailsPriorItemClickListener); + contentBinding.setPatientTravelDetailsPriorListBindCallback( + v -> FieldVisibilityAndAccessHelper + .setFieldVisibilitiesAndAccesses(PatientTravelDetailsPrior.class, (ViewGroup) v, new FieldVisibilityCheckers(), getFieldAccessCheckers())); + if (caze.getDisease() != null) { super.hideFieldsForDisease(caze.getDisease(), contentBinding.mainContent, FormType.RISK_FACTOR_EDIT); } @@ -130,6 +148,12 @@ protected void onAfterLayoutBinding(FragmentCaseEditRiskfactorLayoutBinding cont if (getActivityRootData() == null) { contentBinding.patientSymptomsPrecedenceLayout.setVisibility(GONE); } + if (getActivityRootData() == null) { + contentBinding.patientTravelDetailsDuringLayout.setVisibility(GONE); + } + if (getActivityRootData() == null) { + contentBinding.patientTravelDetailsPriorLayout.setVisibility(GONE); + } contentBinding.riskFactorWaterUsedForDrinking.initializeSpinner(listDrinkingWaterSources); } @@ -146,6 +170,20 @@ private void setUpControlListeners(final FragmentCaseEditRiskfactorLayoutBinding dialog.setPositiveCallback(() -> addPatientSymptomsPrecedence(patientSymptomsPrecedence)); dialog.show(); }); + contentBinding.btnAddPatientTravelDetailsDuring.setOnClickListener(v -> { + final PatientTravelDetailsDuring patientTravelDetailsDuring = DatabaseHelper.getPatientTravelDetailsDuringDao().build(); + final PatientTravelDetailsDuringDialog dialog = + new PatientTravelDetailsDuringDialog(CaseEditActivity.getActiveActivity(), patientTravelDetailsDuring, getActivityRootData(), true); + dialog.setPositiveCallback(() -> addPatientTravelDetailsDuring(patientTravelDetailsDuring)); + dialog.show(); + }); + contentBinding.btnAddPatientTravelDetailsPrior.setOnClickListener(v -> { + final PatientTravelDetailsPrior patientTravelDetailsPrior = DatabaseHelper.getPatientTravelDetailsPriorDao().build(); + final PatientTravelDetailsPriorDialog dialog = + new PatientTravelDetailsPriorDialog(CaseEditActivity.getActiveActivity(), patientTravelDetailsPrior, getActivityRootData(), true); + dialog.setPositiveCallback(() -> addPatientTravelDetailsPrior(patientTravelDetailsPrior)); + dialog.show(); + }); contentBinding.riskFactorDuring3WeeksPatientContactWithSimilarSymptoms.addValueChangedListener(field -> { YesNo value = (YesNo) field.getValue(); contentBinding.patientSymptomsPrecedenceLayout.setVisibility(value == YesNo.YES ? VISIBLE : GONE); @@ -156,6 +194,25 @@ private void setUpControlListeners(final FragmentCaseEditRiskfactorLayoutBinding getContentBinding().riskFactorDuring3WeeksPatientContactWithSimilarSymptoms.setEnabled(getPatientSymptomsPrecedenceList().isEmpty()); }); + contentBinding.riskFactorPatientTravelledAnywhere3WeeksPrior.addValueChangedListener(field -> { + YesNo value = (YesNo) field.getValue(); + contentBinding.patientTravelDetailsPriorLayout.setVisibility(value == YesNo.YES ? VISIBLE : GONE); + if (value != YesNo.YES) { + clearPatientTravelDetailsPriors(); + } + + getContentBinding().riskFactorPatientTravelledAnywhere3WeeksPrior.setEnabled(getPatientTravelDetailsPriorList().isEmpty()); + }); + contentBinding.riskFactorPatientTravelledPeriodOfIllness.addValueChangedListener(field -> { + YesNo value = (YesNo) field.getValue(); + contentBinding.patientTravelDetailsDuringLayout.setVisibility(value == YesNo.YES ? VISIBLE : GONE); + if (value != YesNo.YES) { + clearPatientTravelDetailsDurings(); + } + + getContentBinding().riskFactorPatientTravelledPeriodOfIllness.setEnabled(getPatientTravelDetailsDuringList().isEmpty()); + }); + onPatientSymptomsPrecedenceItemClickListener = (v, item) -> { PatientSymptomsPrecedence patientSymptomsPrecedence = (PatientSymptomsPrecedence) item; final PatientSymptomsPrecedence patientSymptomsPrecedenceClone = (PatientSymptomsPrecedence) patientSymptomsPrecedence.clone(); @@ -176,6 +233,46 @@ private void setUpControlListeners(final FragmentCaseEditRiskfactorLayoutBinding dialog.show(); }; contentBinding.setPatientSymptomsPrecedenceItemClickCallback(onPatientSymptomsPrecedenceItemClickListener); + + onPatientTravelDetailsDuringItemClickListener = (v, item) -> { + PatientTravelDetailsDuring patientTravelDetailsDuring = (PatientTravelDetailsDuring) item; + final PatientTravelDetailsDuring patientTravelDetailsDuringClone = (PatientTravelDetailsDuring) patientTravelDetailsDuring.clone(); + final PatientTravelDetailsDuringDialog dialog = + new PatientTravelDetailsDuringDialog(CaseEditActivity.getActiveActivity(), patientTravelDetailsDuringClone, getActivityRootData(), false); + dialog.setPositiveCallback(() -> { + patientTravelDetailsDuring.setDateOfTravel(dialog.getData().getDateOfTravel()); + patientTravelDetailsDuring.setPlaceOfTravel(dialog.getData().getPlaceOfTravel()); + + record.getPatientTravelDetailsDurings().set(record.getPatientTravelDetailsDurings().indexOf(patientTravelDetailsDuring), patientTravelDetailsDuringClone); + updatePatientTravelDetailsDurings(); + }); + dialog.setDeleteCallback(() -> { + removePatientTravelDetailsDuring(patientTravelDetailsDuring); + dialog.dismiss(); + }); + dialog.show(); + }; + contentBinding.setPatientTravelDetailsDuringItemClickCallback(onPatientTravelDetailsDuringItemClickListener); + + onPatientTravelDetailsPriorItemClickListener = (v, item) -> { + PatientTravelDetailsPrior patientTravelDetailsPrior = (PatientTravelDetailsPrior) item; + final PatientTravelDetailsPrior patientTravelDetailsPriorClone = (PatientTravelDetailsPrior) patientTravelDetailsPrior.clone(); + final PatientTravelDetailsPriorDialog dialog = + new PatientTravelDetailsPriorDialog(CaseEditActivity.getActiveActivity(), patientTravelDetailsPriorClone, getActivityRootData(), false); + dialog.setPositiveCallback(() -> { + patientTravelDetailsPrior.setDateOfTravel(dialog.getData().getDateOfTravel()); + patientTravelDetailsPrior.setPlaceOfTravel(dialog.getData().getPlaceOfTravel()); + + record.getPatientTravelDetailsPriors().set(record.getPatientTravelDetailsPriors().indexOf(patientTravelDetailsPrior), patientTravelDetailsPriorClone); + updatePatientTravelDetailsPriors(); + }); + dialog.setDeleteCallback(() -> { + removePatientTravelDetailsPrior(patientTravelDetailsPrior); + dialog.dismiss(); + }); + dialog.show(); + }; + contentBinding.setPatientTravelDetailsPriorItemClickCallback(onPatientTravelDetailsPriorItemClickListener); } private void addPatientSymptomsPrecedence(PatientSymptomsPrecedence patientSymptomsPrecedence) { @@ -205,4 +302,62 @@ private ObservableArrayList getPatientSymptomsPrecede patientSymptomsPrecedence.addAll(record.getPatientSymptomsPrecedences()); return patientSymptomsPrecedence; } + + //during + private void addPatientTravelDetailsDuring(PatientTravelDetailsDuring patientTravelDetailsDuring) { + record.getPatientTravelDetailsDurings().add(0, patientTravelDetailsDuring); + updatePatientTravelDetailsDurings(); + } + private void updatePatientTravelDetailsDurings() { + getContentBinding().setPatientTravelDetailsDuringList(getPatientTravelDetailsDurings()); + } + private ObservableArrayList getPatientTravelDetailsDurings() { + ObservableArrayList patientTravelDetailsDurings = new ObservableArrayList<>(); + patientTravelDetailsDurings.addAll(record.getPatientTravelDetailsDurings()); + return patientTravelDetailsDurings; + } + private void removePatientTravelDetailsDuring(PatientTravelDetailsDuring patientTravelDetailsDuring) { + record.getPatientTravelDetailsDurings().remove(patientTravelDetailsDuring); + updatePatientTravelDetailsDurings(); + } + + private void clearPatientTravelDetailsDurings() { + record.getPatientTravelDetailsDurings().clear(); + updatePatientTravelDetailsDurings(); + } + + private ObservableArrayList getPatientTravelDetailsDuringList() { + ObservableArrayList patientTravelDetailsDuring = new ObservableArrayList<>(); + patientTravelDetailsDuring.addAll(record.getPatientTravelDetailsDurings()); + return patientTravelDetailsDuring; + } + + //prior + private void addPatientTravelDetailsPrior(PatientTravelDetailsPrior patientTravelDetailsPrior) { + record.getPatientTravelDetailsPriors().add(0, patientTravelDetailsPrior); + updatePatientTravelDetailsPriors(); + } + private void updatePatientTravelDetailsPriors() { + getContentBinding().setPatientTravelDetailsPriorList(getPatientTravelDetailsPriors()); + } + private ObservableArrayList getPatientTravelDetailsPriors() { + ObservableArrayList patientTravelDetailsPriors = new ObservableArrayList<>(); + patientTravelDetailsPriors.addAll(record.getPatientTravelDetailsPriors()); + return patientTravelDetailsPriors; + } + private void removePatientTravelDetailsPrior(PatientTravelDetailsPrior patientTravelDetailsPrior) { + record.getPatientTravelDetailsPriors().remove(patientTravelDetailsPrior); + updatePatientTravelDetailsPriors(); + } + + private void clearPatientTravelDetailsPriors() { + record.getPatientTravelDetailsPriors().clear(); + updatePatientTravelDetailsPriors(); + } + + private ObservableArrayList getPatientTravelDetailsPriorList() { + ObservableArrayList patientTravelDetailsPrior = new ObservableArrayList<>(); + patientTravelDetailsPrior.addAll(record.getPatientTravelDetailsPriors()); + return patientTravelDetailsPrior; + } } diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/riskfactor/PatientTravelDetailsDuringDialog.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/riskfactor/PatientTravelDetailsDuringDialog.java new file mode 100644 index 00000000000..4d8207064e7 --- /dev/null +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/riskfactor/PatientTravelDetailsDuringDialog.java @@ -0,0 +1,109 @@ +package de.symeda.sormas.app.riskfactor; + +import static de.symeda.sormas.app.core.notification.NotificationType.ERROR; +import static de.symeda.sormas.app.epidata.EpiDataFragmentHelper.getDiseaseOfCaseOrContact; + +import android.content.Context; + +import androidx.databinding.ViewDataBinding; +import androidx.fragment.app.FragmentActivity; + +import de.symeda.sormas.api.utils.TravelLocation; +import de.symeda.sormas.api.utils.ValidationException; +import de.symeda.sormas.api.utils.YesNoUnknown; +import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; +import de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers; +import de.symeda.sormas.app.BR; +import de.symeda.sormas.app.R; +import de.symeda.sormas.app.backend.common.PseudonymizableAdo; +import de.symeda.sormas.app.backend.config.ConfigProvider; +import de.symeda.sormas.app.backend.patienttraveldetailsduring.PatientTravelDetailsDuring; +import de.symeda.sormas.app.component.controls.ControlButtonType; +import de.symeda.sormas.app.component.dialog.FormDialog; +import de.symeda.sormas.app.component.validation.FragmentValidator; +import de.symeda.sormas.app.core.notification.NotificationHelper; +import de.symeda.sormas.app.databinding.DialogPatientTravelDetailsDuringEditLayoutBinding; + +public class PatientTravelDetailsDuringDialog extends FormDialog { + + private final PatientTravelDetailsDuring data; + private DialogPatientTravelDetailsDuringEditLayoutBinding contentBinding; + private final boolean create; + + public PatientTravelDetailsDuringDialog(final FragmentActivity activity, PatientTravelDetailsDuring patientTravelDetailsDuring, PseudonymizableAdo activityRootData, boolean create) { + super( + activity, + R.layout.dialog_root_layout, + R.layout.dialog_patient_travel_details_during_edit_layout, + R.layout.dialog_root_three_button_panel_layout, + R.string.heading_travel_information, + -1, + false, + UiFieldAccessCheckers.forSensitiveData(patientTravelDetailsDuring.isPseudonymized()), + FieldVisibilityCheckers.withDisease(getDiseaseOfCaseOrContact(activityRootData)).andWithCountry(ConfigProvider.getServerCountryCode())); + this.data = patientTravelDetailsDuring; + this.create = create; + } + + private void setUpHeadingVisibilities() { + } + + public PatientTravelDetailsDuring getData() { + return data; + } + + @Override + protected void setContentBinding(Context context, ViewDataBinding binding, String layoutName) { + contentBinding = (DialogPatientTravelDetailsDuringEditLayoutBinding) binding; + + binding.setVariable(BR.data, data); + } + + @Override + protected void initializeContentView(ViewDataBinding rootBinding, ViewDataBinding buttonPanelBinding) { + contentBinding.patientTravelDetailsDuringDateOfTravel.initializeDateField(getFragmentManager()); + contentBinding.setTravelClass(TravelLocation.class); + + if (data.getId() == null) { + setLiveValidationDisabled(true); + } + } + + @Override + protected void onPositiveClick() { + setLiveValidationDisabled(false); + try { + FragmentValidator.validate(getContext(), contentBinding); +// this.data.setDateOfTravel(contentBinding.patientTravelDetailsDuringDateOfTravel.getValue()); +// this.data.setPlaceOfTravel(contentBinding.patientTravelDetailsDuringPlaceOfTravel.getValue()); + } catch (ValidationException e) { + NotificationHelper.showDialogNotification(PatientTravelDetailsDuringDialog.this, ERROR, e.getMessage()); + return; + } + super.setCloseOnPositiveButtonClick(true); + super.onPositiveClick(); + } + + @Override + public boolean isDeleteButtonVisible() { + return !create; + } + @Override + public boolean isRounded() { + return true; + } + @Override + public ControlButtonType getNegativeButtonType() { + return ControlButtonType.LINE_SECONDARY; + } + @Override + public ControlButtonType getPositiveButtonType() { + return ControlButtonType.LINE_PRIMARY; + } + @Override + public ControlButtonType getDeleteButtonType() { + return ControlButtonType.LINE_DANGER; + } + + +} diff --git a/sormas-app/app/src/main/java/de/symeda/sormas/app/riskfactor/PatientTravelDetailsPriorDialog.java b/sormas-app/app/src/main/java/de/symeda/sormas/app/riskfactor/PatientTravelDetailsPriorDialog.java new file mode 100644 index 00000000000..769a0da3e73 --- /dev/null +++ b/sormas-app/app/src/main/java/de/symeda/sormas/app/riskfactor/PatientTravelDetailsPriorDialog.java @@ -0,0 +1,105 @@ +package de.symeda.sormas.app.riskfactor; + +import static de.symeda.sormas.app.core.notification.NotificationType.ERROR; +import static de.symeda.sormas.app.epidata.EpiDataFragmentHelper.getDiseaseOfCaseOrContact; + +import android.content.Context; + +import androidx.databinding.ViewDataBinding; +import androidx.fragment.app.FragmentActivity; + +import de.symeda.sormas.api.utils.TravelLocation; +import de.symeda.sormas.api.utils.ValidationException; +import de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers; +import de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers; +import de.symeda.sormas.app.BR; +import de.symeda.sormas.app.R; +import de.symeda.sormas.app.backend.common.PseudonymizableAdo; +import de.symeda.sormas.app.backend.config.ConfigProvider; +import de.symeda.sormas.app.backend.patienttraveldetailsprior.PatientTravelDetailsPrior; +import de.symeda.sormas.app.component.controls.ControlButtonType; +import de.symeda.sormas.app.component.dialog.FormDialog; +import de.symeda.sormas.app.component.validation.FragmentValidator; +import de.symeda.sormas.app.core.notification.NotificationHelper; +import de.symeda.sormas.app.databinding.DialogPatientTravelDetailsPriorEditLayoutBinding; + +public class PatientTravelDetailsPriorDialog extends FormDialog { + + private final PatientTravelDetailsPrior data; + private DialogPatientTravelDetailsPriorEditLayoutBinding contentBinding; + private final boolean create; + + public PatientTravelDetailsPriorDialog(final FragmentActivity activity, PatientTravelDetailsPrior patientTravelDetailsPrior, PseudonymizableAdo activityRootData, boolean create) { + super( + activity, + R.layout.dialog_root_layout, + R.layout.dialog_patient_travel_details_prior_edit_layout, + R.layout.dialog_root_three_button_panel_layout, + R.string.heading_travel_information, + -1, + false, + UiFieldAccessCheckers.forSensitiveData(patientTravelDetailsPrior.isPseudonymized()), + FieldVisibilityCheckers.withDisease(getDiseaseOfCaseOrContact(activityRootData)).andWithCountry(ConfigProvider.getServerCountryCode())); + this.data = patientTravelDetailsPrior; + this.create = create; + } + + private void setUpHeadingVisibilities() { + } + + public PatientTravelDetailsPrior getData() { + return data; + } + + @Override + protected void setContentBinding(Context context, ViewDataBinding binding, String layoutName) { + contentBinding = (DialogPatientTravelDetailsPriorEditLayoutBinding) binding; + binding.setVariable(BR.data, data); + } + + @Override + protected void initializeContentView(ViewDataBinding rootBinding, ViewDataBinding buttonPanelBinding) { + contentBinding.patientTravelDetailsPriorDateOfTravel.initializeDateField(getFragmentManager()); + contentBinding.setTravelClass(TravelLocation.class); + + if (data.getId() == null) { + setLiveValidationDisabled(true); + } + } + + @Override + protected void onPositiveClick() { + setLiveValidationDisabled(false); + try { + FragmentValidator.validate(getContext(), contentBinding); + } catch (ValidationException e) { + NotificationHelper.showDialogNotification(PatientTravelDetailsPriorDialog.this, ERROR, e.getMessage()); + return; + } + super.setCloseOnPositiveButtonClick(true); + super.onPositiveClick(); + } + + @Override + public boolean isDeleteButtonVisible() { + return !create; + } + @Override + public boolean isRounded() { + return true; + } + @Override + public ControlButtonType getNegativeButtonType() { + return ControlButtonType.LINE_SECONDARY; + } + @Override + public ControlButtonType getPositiveButtonType() { + return ControlButtonType.LINE_PRIMARY; + } + @Override + public ControlButtonType getDeleteButtonType() { + return ControlButtonType.LINE_DANGER; + } + + +} diff --git a/sormas-app/app/src/main/res/layout/dialog_patient_travel_details_during_edit_layout.xml b/sormas-app/app/src/main/res/layout/dialog_patient_travel_details_during_edit_layout.xml new file mode 100644 index 00000000000..a4613cc6d24 --- /dev/null +++ b/sormas-app/app/src/main/res/layout/dialog_patient_travel_details_during_edit_layout.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sormas-app/app/src/main/res/layout/dialog_patient_travel_details_prior_edit_layout.xml b/sormas-app/app/src/main/res/layout/dialog_patient_travel_details_prior_edit_layout.xml new file mode 100644 index 00000000000..e7264ff0306 --- /dev/null +++ b/sormas-app/app/src/main/res/layout/dialog_patient_travel_details_prior_edit_layout.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sormas-app/app/src/main/res/layout/fragment_case_edit_riskfactor_layout.xml b/sormas-app/app/src/main/res/layout/fragment_case_edit_riskfactor_layout.xml index 33c5a0f3362..d033084022c 100644 --- a/sormas-app/app/src/main/res/layout/fragment_case_edit_riskfactor_layout.xml +++ b/sormas-app/app/src/main/res/layout/fragment_case_edit_riskfactor_layout.xml @@ -41,6 +41,14 @@ + + + + + + + + - + style="@style/ControlSingleColumnStyle" />--> - + style="@style/ControlSingleColumnStyle" />--> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sormas-app/app/src/main/res/layout/fragment_case_read_riskfactor_layout.xml b/sormas-app/app/src/main/res/layout/fragment_case_read_riskfactor_layout.xml index ce637b77eb4..076f9e36caf 100644 --- a/sormas-app/app/src/main/res/layout/fragment_case_read_riskfactor_layout.xml +++ b/sormas-app/app/src/main/res/layout/fragment_case_read_riskfactor_layout.xml @@ -40,6 +40,14 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sormas-app/app/src/main/res/layout/row_epid_patient_travel_details_during_layout.xml b/sormas-app/app/src/main/res/layout/row_epid_patient_travel_details_during_layout.xml new file mode 100644 index 00000000000..66ae0b1f1ef --- /dev/null +++ b/sormas-app/app/src/main/res/layout/row_epid_patient_travel_details_during_layout.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sormas-app/app/src/main/res/layout/row_epid_patient_travel_details_prior_layout.xml b/sormas-app/app/src/main/res/layout/row_epid_patient_travel_details_prior_layout.xml new file mode 100644 index 00000000000..c551bbe8aae --- /dev/null +++ b/sormas-app/app/src/main/res/layout/row_epid_patient_travel_details_prior_layout.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sormas-app/app/src/main/res/layout/row_risk_factor_patient_travel_details_during_layout.xml b/sormas-app/app/src/main/res/layout/row_risk_factor_patient_travel_details_during_layout.xml new file mode 100644 index 00000000000..6afaec06545 --- /dev/null +++ b/sormas-app/app/src/main/res/layout/row_risk_factor_patient_travel_details_during_layout.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sormas-app/app/src/main/res/layout/row_risk_factor_patient_travel_details_prior_layout.xml b/sormas-app/app/src/main/res/layout/row_risk_factor_patient_travel_details_prior_layout.xml new file mode 100644 index 00000000000..c551bbe8aae --- /dev/null +++ b/sormas-app/app/src/main/res/layout/row_risk_factor_patient_travel_details_prior_layout.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sormas-app/app/src/main/res/values/strings.xml b/sormas-app/app/src/main/res/values/strings.xml index 637cb760060..732db554ede 100644 --- a/sormas-app/app/src/main/res/values/strings.xml +++ b/sormas-app/app/src/main/res/values/strings.xml @@ -482,6 +482,7 @@ Transfer Case Travel Patient Symptoms Precedence + Patient Travel Information Affected Person Details Travels Treatment diff --git a/sormas-backend/src/main/resources/sql/sormas_schema.sql b/sormas-backend/src/main/resources/sql/sormas_schema.sql index 06bed6b03cf..16b2fab1dd0 100644 --- a/sormas-backend/src/main/resources/sql/sormas_schema.sql +++ b/sormas-backend/src/main/resources/sql/sormas_schema.sql @@ -15206,4 +15206,25 @@ SET responsestatus = WHEN responsestatus = '2' THEN '1' ELSE responsestatus END; -INSERT INTO schema_version(version_number, comment) VALUES (721, 'removed not started enum'); \ No newline at end of file +INSERT INTO schema_version(version_number, comment) VALUES (721, 'removed not started enum'); + +ALTER TABLE afpimmunization DROP COLUMN IF EXISTS opvdoseatbirth; +ALTER TABLE afpimmunization DROP COLUMN IF EXISTS seconddose; +ALTER TABLE afpimmunization DROP COLUMN IF EXISTS fourthdose; +ALTER TABLE afpimmunization DROP COLUMN IF EXISTS firstdose; +ALTER TABLE afpimmunization DROP COLUMN IF EXISTS thirddose; +ALTER TABLE afpimmunization DROP COLUMN IF EXISTS lastdose; +ALTER TABLE afpimmunization DROP COLUMN IF EXISTS dateLastOpvDosesReceivedThroughSia; +ALTER TABLE afpimmunization DROP COLUMN IF EXISTS dateLastIpvDosesReceivedThroughSia; +ALTER TABLE afpimmunization DROP COLUMN IF EXISTS datelastipvreceivedthroughsia; + +ALTER TABLE afpimmunization ADD COLUMN opvdoseatbirth DATE; +ALTER TABLE afpimmunization ADD COLUMN seconddose DATE; +ALTER TABLE afpimmunization ADD COLUMN fourthdose DATE; +ALTER TABLE afpimmunization ADD COLUMN firstdose DATE; +ALTER TABLE afpimmunization ADD COLUMN thirddose DATE; +ALTER TABLE afpimmunization ADD COLUMN lastdose DATE; +ALTER TABLE afpimmunization ADD COLUMN dateLastOpvDosesReceivedThroughSia DATE; +ALTER TABLE afpimmunization ADD COLUMN dateLastIpvDosesReceivedThroughSia DATE; + +INSERT INTO schema_version(version_number, comment) VALUES (722, 'Dropped and added columns in afpimmunization to change types to date'); \ No newline at end of file diff --git a/sormas-ui/src/main/java/de/symeda/sormas/ui/riskfactor/RiskFactorFormConfiguration.java b/sormas-ui/src/main/java/de/symeda/sormas/ui/riskfactor/RiskFactorFormConfiguration.java index 8e72a8dd2cf..f1fa9e78e75 100644 --- a/sormas-ui/src/main/java/de/symeda/sormas/ui/riskfactor/RiskFactorFormConfiguration.java +++ b/sormas-ui/src/main/java/de/symeda/sormas/ui/riskfactor/RiskFactorFormConfiguration.java @@ -49,6 +49,9 @@ public class RiskFactorFormConfiguration { DISABLED_FIELDS_BY_DISEASE.put(RiskFactorDto.THREE_DAYS_PRIOR_TO_DISEASE_ATTEND_ANY_FUNERAL, new HashSet<>(Arrays.asList(Disease.MONKEYPOX))); DISABLED_FIELDS_BY_DISEASE.put(RiskFactorDto.THREE_DAYS_PRIOR_TO_DISEASE_ATTEND_ANY_SOCIAL_EVENT, new HashSet<>(Arrays.asList(Disease.MONKEYPOX))); DISABLED_FIELDS_BY_DISEASE.put(RiskFactorDto.OTHER_SOCIAL_EVENT_DETAILS, new HashSet<>(Arrays.asList(Disease.MONKEYPOX))); + DISABLED_FIELDS_BY_DISEASE.put(RiskFactorDto.PATIENT_SYMPTOMS_PRECEDENCE, new HashSet<>(Arrays.asList(Disease.CHOLERA))); + DISABLED_FIELDS_BY_DISEASE.put(RiskFactorDto.PATIENT_TRAVEL_DETAILS_PRIOR, new HashSet<>(Arrays.asList(Disease.CHOLERA))); + DISABLED_FIELDS_BY_DISEASE.put(RiskFactorDto.PATIENT_TRAVEL_DETAILS_DURING, new HashSet<>(Arrays.asList(Disease.CHOLERA))); }