2727
2828import java .util .Arrays ;
2929import java .util .Collections ;
30+ import java .util .Date ;
3031import java .util .List ;
3132import java .util .function .Consumer ;
3233import java .util .function .Supplier ;
3536import org .apache .commons .lang3 .StringUtils ;
3637
3738import com .vaadin .shared .ui .ContentMode ;
39+ import com .vaadin .ui .CustomLayout ;
40+ import com .vaadin .ui .Label ;
3841import com .vaadin .v7 .ui .ComboBox ;
3942import com .vaadin .v7 .ui .DateField ;
4043import com .vaadin .v7 .ui .Field ;
4750import de .symeda .sormas .api .caze .CaseDataDto ;
4851import de .symeda .sormas .api .contact .ContactDto ;
4952import de .symeda .sormas .api .contact .ContactReferenceDto ;
53+ import de .symeda .sormas .api .disease .DiseaseConfigurationDto ;
5054import de .symeda .sormas .api .epidata .ClusterType ;
5155import de .symeda .sormas .api .epidata .EpiDataDto ;
5256import de .symeda .sormas .api .exposure .InfectionSource ;
5357import de .symeda .sormas .api .exposure .ModeOfTransmission ;
5458import de .symeda .sormas .api .i18n .I18nProperties ;
5559import de .symeda .sormas .api .i18n .Strings ;
5660import de .symeda .sormas .api .infrastructure .country .CountryReferenceDto ;
61+ import de .symeda .sormas .api .utils .DateHelper ;
5762import de .symeda .sormas .api .utils .YesNoUnknown ;
5863import de .symeda .sormas .api .utils .fieldaccess .UiFieldAccessCheckers ;
5964import de .symeda .sormas .api .utils .fieldvisibility .FieldVisibilityCheckers ;
6065import de .symeda .sormas .api .utils .fieldvisibility .checkers .CountryFieldVisibilityChecker ;
6166import de .symeda .sormas .ui .ActivityAsCase .ActivityAsCaseField ;
6267import de .symeda .sormas .ui .exposure .ExposuresField ;
6368import de .symeda .sormas .ui .utils .AbstractEditForm ;
69+ import de .symeda .sormas .ui .utils .CssStyles ;
6470import de .symeda .sormas .ui .utils .FieldAccessHelper ;
6571import de .symeda .sormas .ui .utils .FieldHelper ;
6672import de .symeda .sormas .ui .utils .NullableOptionGroup ;
@@ -77,11 +83,13 @@ public class EpiDataForm extends AbstractEditForm<EpiDataDto> {
7783 private static final String LOC_SOURCE_CASE_CONTACTS_HEADING = "locSourceCaseContactsHeading" ;
7884 private static final String LOC_EPI_DATA_FIELDS_HINT = "locEpiDataFieldsHint" ;
7985 private static final String LOC_EXP_PERIOD_HEADING = "locExpPeriodHeading" ;
86+ private static final String EXPOSURE_DATES_LAYOUT =
87+ fluidRowLocs (3 , "EXPOSURE_START_DATE_LABEL" , 3 , "EXPOSURE_START_DATE_VALUE" , 3 , "EXPOSURE_END_DATE_LABEL" , 3 , "EXPOSURE_END_DATE_VALUE" );
8088
8189 //@formatter:off
8290 private static final String MAIN_HTML_LAYOUT =
8391 loc (LOC_EXPOSURE_INVESTIGATION_HEADING ) +
84- fluidRowLocs (6 , EpiDataDto . EXPOSURE_START_DATE , 6 , EpiDataDto . EXPOSURE_END_DATE ) +
92+ fluidRowLocs ("EXP_DATES_LAYOUT" ) +
8593 fluidRowLocs (6 ,EpiDataDto .CASE_IMPORTED_STATUS ,6 ,"" ) +
8694 loc (LOC_EXP_PERIOD_HEADING ) +
8795 loc (EpiDataDto .EXPOSURE_DETAILS_KNOWN ) +
@@ -110,14 +118,16 @@ public class EpiDataForm extends AbstractEditForm<EpiDataDto> {
110118 private final Class <? extends EntityDto > parentClass ;
111119 private final Consumer <Boolean > sourceContactsToggleCallback ;
112120 private final boolean isPseudonymized ;
121+ private final Date symptomOnsetDate ;
113122
114123 public EpiDataForm (
115124 Disease disease ,
116125 Class <? extends EntityDto > parentClass ,
117126 boolean isPseudonymized ,
118127 boolean inJurisdiction ,
119128 Consumer <Boolean > sourceContactsToggleCallback ,
120- boolean isEditAllowed ) {
129+ boolean isEditAllowed ,
130+ Date date ) {
121131 super (
122132 EpiDataDto .class ,
123133 EpiDataDto .I18N_PREFIX ,
@@ -129,6 +139,7 @@ public EpiDataForm(
129139 this .parentClass = parentClass ;
130140 this .sourceContactsToggleCallback = sourceContactsToggleCallback ;
131141 this .isPseudonymized = isPseudonymized ;
142+ this .symptomOnsetDate = date ;
132143 addFields ();
133144 }
134145
@@ -178,17 +189,13 @@ protected void addFields() {
178189 addField (EpiDataDto .MODE_OF_TRANSMISSION_TYPE );
179190 addField (EpiDataDto .INFECTION_SOURCE );
180191 addField (EpiDataDto .INFECTION_SOURCE_TEXT );
181- DateField exposureStartDate = addField (EpiDataDto .EXPOSURE_START_DATE );
182- exposureStartDate .setCaption (I18nProperties .getString (Strings .exposureStartDate ));
183- exposureStartDate .setEnabled (false );
184- DateField exposureEndDate = addField (EpiDataDto .EXPOSURE_END_DATE );
185- exposureEndDate .setCaption (I18nProperties .getString (Strings .exposureEndDate ));
186- exposureEndDate .setEnabled (false );
187192 addField (EpiDataDto .IMPORTED_CASE , NullableOptionGroup .class );
188193 List <CountryReferenceDto > countries = FacadeProvider .getCountryFacade ().getAllActiveAsReference ();
189194 ComboBox country = addInfrastructureField (EpiDataDto .COUNTRY );
190195 country .addItems (countries );
191196
197+ includeExposureDates (symptomOnsetDate , disease );
198+
192199 TextField clusterTypeTF = addField (EpiDataDto .CLUSTER_TYPE_TEXT );
193200 FieldHelper
194201 .setVisibleWhen (getFieldGroup (), EpiDataDto .CLUSTER_TYPE , EpiDataDto .CLUSTER_RELATED , Collections .singletonList (Boolean .TRUE ), true );
@@ -211,6 +218,54 @@ protected void addFields() {
211218 });
212219 }
213220
221+ /**
222+ * Include the exposire start and dates when symptomOnsetDate is present.
223+ * Disease incubation period is enabled with valid values.
224+ *
225+ * @param symptomOnsetDate
226+ * @param disease
227+ */
228+ private void includeExposureDates (Date symptomOnsetDate , Disease disease ) {
229+ // if symptomOnsetDate is null, return;
230+ if (symptomOnsetDate == null ) {
231+ return ;
232+ }
233+ DiseaseConfigurationDto diseaseConfigurationDto = FacadeProvider .getDiseaseConfigurationFacade ().getDiseaseConfiguration (disease );
234+ if (diseaseConfigurationDto == null ) {
235+ return ;
236+ }
237+ if (!diseaseConfigurationDto .getIncubationPeriodEnabled ()) {
238+ return ;
239+ }
240+ if (diseaseConfigurationDto .getMaxIncubationPeriod () == null || diseaseConfigurationDto .getMaxIncubationPeriod () == 0 ) {
241+ return ;
242+ }
243+ if (diseaseConfigurationDto .getMinIncubationPeriod () == null ) {
244+ return ;
245+ }
246+
247+ CustomLayout exposureDatesLayout = new CustomLayout ();
248+ exposureDatesLayout .setTemplateContents (EXPOSURE_DATES_LAYOUT );
249+ Label exposureStartLabel = new Label (I18nProperties .getString (Strings .exposureStartDate ));
250+ exposureStartLabel .addStyleNames (CssStyles .LABEL_BOLD , CssStyles .LABEL_UPPERCASE );
251+ exposureDatesLayout .addComponent (exposureStartLabel , "EXPOSURE_START_DATE_LABEL" );
252+
253+ DateField exposureStartDateValue = new DateField ();
254+ exposureStartDateValue .setValue (DateHelper .subtractDays (symptomOnsetDate , diseaseConfigurationDto .getMaxIncubationPeriod ()));
255+ exposureStartDateValue .setReadOnly (true );
256+ exposureDatesLayout .addComponent (exposureStartDateValue , "EXPOSURE_START_DATE_VALUE" );
257+
258+ Label exposureEndLabel = new Label (I18nProperties .getString (Strings .exposureEndDate ));
259+ exposureEndLabel .addStyleNames (CssStyles .LABEL_BOLD , CssStyles .LABEL_UPPERCASE );
260+ exposureDatesLayout .addComponent (exposureEndLabel , "EXPOSURE_END_DATE_LABEL" );
261+ DateField exposureEndDateValue = new DateField ();
262+ exposureEndDateValue .setValue (DateHelper .subtractDays (symptomOnsetDate , diseaseConfigurationDto .getMinIncubationPeriod ()));
263+ exposureEndDateValue .setReadOnly (true );
264+ exposureDatesLayout .addComponent (exposureEndDateValue , "EXPOSURE_END_DATE_VALUE" );
265+
266+ getContent ().addComponent (exposureDatesLayout , "EXP_DATES_LAYOUT" );
267+ }
268+
214269 private void addActivityAsCaseFields () {
215270
216271 getContent ().addComponent (
0 commit comments