Search in sources :

Example 1 with ContactProximity

use of de.symeda.sormas.api.contact.ContactProximity in project SORMAS-Project by hzi-braunschweig.

the class ContactService method updateFollowUpDetails.

/**
 * Calculates and sets the follow-up until date and status of the contact. If
 * the date has been overwritten by a user, only the status changes and
 * extensions of the follow-up until date based on missed visits are executed.
 * <ul>
 * <li>Disease with no follow-up: Leave empty and set follow-up status to "No
 * follow-up"</li>
 * <li>Others: Use follow-up duration of the disease. Reference for calculation
 * is the reporting date (since this is always later than the last contact date
 * and we can't be sure the last contact date is correct) If the last visit was
 * not cooperative and happened at the last date of contact tracing, we need to
 * do an additional visit.</li>
 * </ul>
 */
public void updateFollowUpDetails(Contact contact, boolean followUpStatusChangedByUser) {
    Disease disease = contact.getDisease();
    boolean changeStatus = contact.getFollowUpStatus() != FollowUpStatus.CANCELED && contact.getFollowUpStatus() != FollowUpStatus.LOST;
    boolean statusChangedBySystem = false;
    ContactProximity contactProximity = contact.getContactProximity();
    if (!diseaseConfigurationFacade.hasFollowUp(disease) || (contactProximity != null && !contactProximity.hasFollowUp())) {
        contact.setFollowUpUntil(null);
        contact.setOverwriteFollowUpUntil(false);
        if (changeStatus) {
            contact.setFollowUpStatus(FollowUpStatus.NO_FOLLOW_UP);
            statusChangedBySystem = true;
        }
    } else {
        ContactDto contactDto = contactFacade.toDto(contact);
        Date currentFollowUpUntil = contact.getFollowUpUntil();
        Date earliestSampleDate = null;
        for (Sample sample : contact.getSamples()) {
            if (sample.getPathogenTestResult() == PathogenTestResultType.POSITIVE && (earliestSampleDate == null || sample.getSampleDateTime().before(earliestSampleDate))) {
                earliestSampleDate = sample.getSampleDateTime();
            }
        }
        Date untilDate = ContactLogic.calculateFollowUpUntilDate(contactDto, ContactLogic.getFollowUpStartDate(contact.getLastContactDate(), contact.getReportDateTime(), earliestSampleDate), contact.getVisits().stream().map(visit -> visitFacade.toDto(visit)).collect(Collectors.toList()), diseaseConfigurationFacade.getFollowUpDuration(contact.getDisease()), false, featureConfigurationFacade.isPropertyValueTrue(FeatureType.CONTACT_TRACING, FeatureTypeProperty.ALLOW_FREE_FOLLOW_UP_OVERWRITE)).getFollowUpEndDate();
        contact.setFollowUpUntil(untilDate);
        if (DateHelper.getStartOfDay(currentFollowUpUntil).before(DateHelper.getStartOfDay(untilDate))) {
            contact.setOverwriteFollowUpUntil(false);
        }
        if (changeStatus) {
            Visit lastVisit = contact.getVisits().stream().max(Comparator.comparing(Visit::getVisitDateTime)).orElse(null);
            if (lastVisit != null && !DateHelper.getStartOfDay(lastVisit.getVisitDateTime()).before(DateHelper.getStartOfDay(untilDate))) {
                contact.setFollowUpStatus(FollowUpStatus.COMPLETED);
            } else {
                contact.setFollowUpStatus(FollowUpStatus.FOLLOW_UP);
            }
            if (contact.getFollowUpStatus() != FollowUpStatus.COMPLETED && contact.getContactStatus() == ContactStatus.CONVERTED) {
                // Cancel follow-up if the contact was converted to a case
                contact.setFollowUpStatus(FollowUpStatus.CANCELED);
                addToFollowUpStatusComment(contact, I18nProperties.getString(Strings.messageSystemFollowUpCanceled));
            }
            statusChangedBySystem = true;
        }
    }
    if (followUpStatusChangedByUser) {
        contact.setFollowUpStatusChangeDate(new Date());
        contact.setFollowUpStatusChangeUser(getCurrentUser());
    } else if (statusChangedBySystem) {
        contact.setFollowUpStatusChangeDate(null);
        contact.setFollowUpStatusChangeUser(null);
    }
    externalJournalService.handleExternalJournalPersonUpdateAsync(contact.getPerson().toReference());
    ensurePersisted(contact);
}
Also used : FollowUpStatus(de.symeda.sormas.api.contact.FollowUpStatus) Arrays(java.util.Arrays) VisitStatus(de.symeda.sormas.api.visit.VisitStatus) ExternalDataUpdateException(de.symeda.sormas.api.externaldata.ExternalDataUpdateException) StringUtils(org.apache.commons.lang3.StringUtils) Predicate(javax.persistence.criteria.Predicate) Map(java.util.Map) CriteriaBuilder(javax.persistence.criteria.CriteriaBuilder) JoinType(javax.persistence.criteria.JoinType) FeatureConfigurationFacadeEjb(de.symeda.sormas.backend.feature.FeatureConfigurationFacadeEjb) Visit(de.symeda.sormas.backend.visit.Visit) EpiData(de.symeda.sormas.backend.epidata.EpiData) From(javax.persistence.criteria.From) CriteriaQuery(javax.persistence.criteria.CriteriaQuery) EnumMap(java.util.EnumMap) Transactional(javax.transaction.Transactional) Set(java.util.Set) NotNull(javax.validation.constraints.NotNull) DashboardContactDto(de.symeda.sormas.api.dashboard.DashboardContactDto) UserService(de.symeda.sormas.backend.user.UserService) User(de.symeda.sormas.backend.user.User) PathogenTestResultType(de.symeda.sormas.api.sample.PathogenTestResultType) ExternalDataDto(de.symeda.sormas.api.externaldata.ExternalDataDto) JurisdictionHelper(de.symeda.sormas.backend.util.JurisdictionHelper) DeletableAdo(de.symeda.sormas.backend.common.DeletableAdo) SampleService(de.symeda.sormas.backend.sample.SampleService) Sample(de.symeda.sormas.backend.sample.Sample) EventParticipant(de.symeda.sormas.backend.event.EventParticipant) Community(de.symeda.sormas.backend.infrastructure.community.Community) CaseUserFilterCriteria(de.symeda.sormas.backend.caze.CaseUserFilterCriteria) MapContactDto(de.symeda.sormas.api.contact.MapContactDto) Selection(javax.persistence.criteria.Selection) Case(de.symeda.sormas.backend.caze.Case) LocalBean(javax.ejb.LocalBean) ContactListEntryDtoResultTransformer(de.symeda.sormas.backend.contact.transformers.ContactListEntryDtoResultTransformer) EJB(javax.ejb.EJB) Root(javax.persistence.criteria.Root) ChangeDateFilterBuilder(de.symeda.sormas.backend.common.ChangeDateFilterBuilder) TaskCriteria(de.symeda.sormas.api.task.TaskCriteria) DataHelper(de.symeda.sormas.api.utils.DataHelper) Task(de.symeda.sormas.backend.task.Task) ContactLogic(de.symeda.sormas.api.contact.ContactLogic) Disease(de.symeda.sormas.api.Disease) FollowUpLogic(de.symeda.sormas.api.followup.FollowUpLogic) HealthConditions(de.symeda.sormas.backend.clinicalcourse.HealthConditions) Subquery(javax.persistence.criteria.Subquery) FeatureTypeProperty(de.symeda.sormas.api.feature.FeatureTypeProperty) FeatureType(de.symeda.sormas.api.feature.FeatureType) VisitFacadeEjb(de.symeda.sormas.backend.visit.VisitFacadeEjb) ContactCriteria(de.symeda.sormas.api.contact.ContactCriteria) Join(javax.persistence.criteria.Join) AbstractDomainObject(de.symeda.sormas.backend.common.AbstractDomainObject) Date(java.util.Date) I18nProperties(de.symeda.sormas.api.i18n.I18nProperties) ChangeDateBuilder(de.symeda.sormas.backend.common.ChangeDateBuilder) AbstractCoreAdoService(de.symeda.sormas.backend.common.AbstractCoreAdoService) ContactProximity(de.symeda.sormas.api.contact.ContactProximity) ExposureService(de.symeda.sormas.backend.exposure.ExposureService) UserRole(de.symeda.sormas.api.user.UserRole) VaccinationStatus(de.symeda.sormas.api.caze.VaccinationStatus) Stateless(javax.ejb.Stateless) CaseService(de.symeda.sormas.backend.caze.CaseService) DiseaseConfigurationFacadeEjbLocal(de.symeda.sormas.backend.disease.DiseaseConfigurationFacadeEjb.DiseaseConfigurationFacadeEjbLocal) Person(de.symeda.sormas.backend.person.Person) Timestamp(java.sql.Timestamp) Region(de.symeda.sormas.backend.infrastructure.region.Region) District(de.symeda.sormas.backend.infrastructure.district.District) Collectors(java.util.stream.Collectors) ContactClassification(de.symeda.sormas.api.contact.ContactClassification) List(java.util.List) CoreAdo(de.symeda.sormas.backend.common.CoreAdo) ContactDto(de.symeda.sormas.api.contact.ContactDto) JurisdictionLevel(de.symeda.sormas.api.user.JurisdictionLevel) Location(de.symeda.sormas.backend.location.Location) SormasToSormasShareInfoService(de.symeda.sormas.backend.sormastosormas.share.shareinfo.SormasToSormasShareInfoService) TaskService(de.symeda.sormas.backend.task.TaskService) DateHelper(de.symeda.sormas.api.utils.DateHelper) EntityRelevanceStatus(de.symeda.sormas.api.EntityRelevanceStatus) ExternalDataUtil(de.symeda.sormas.backend.util.ExternalDataUtil) HashSet(java.util.HashSet) CriteriaUpdate(javax.persistence.criteria.CriteriaUpdate) CollectionUtils(org.apache.commons.collections.CollectionUtils) IterableHelper(de.symeda.sormas.backend.util.IterableHelper) CaseQueryContext(de.symeda.sormas.backend.caze.CaseQueryContext) Symptoms(de.symeda.sormas.backend.symptoms.Symptoms) SampleJoins(de.symeda.sormas.backend.sample.SampleJoins) LinkedList(java.util.LinkedList) NoSuchElementException(java.util.NoSuchElementException) Expression(javax.persistence.criteria.Expression) CriteriaBuilderHelper(de.symeda.sormas.backend.common.CriteriaBuilderHelper) ModelConstants(de.symeda.sormas.backend.util.ModelConstants) EpiDataService(de.symeda.sormas.backend.epidata.EpiDataService) ContactListEntryDto(de.symeda.sormas.api.contact.ContactListEntryDto) ContactStatus(de.symeda.sormas.api.contact.ContactStatus) Event(de.symeda.sormas.backend.event.Event) SormasToSormasShareInfo(de.symeda.sormas.backend.sormastosormas.share.shareinfo.SormasToSormasShareInfo) ExternalJournalService(de.symeda.sormas.backend.externaljournal.ExternalJournalService) ContactReferenceDto(de.symeda.sormas.api.contact.ContactReferenceDto) Comparator(java.util.Comparator) Strings(de.symeda.sormas.api.i18n.Strings) Collections(java.util.Collections) Disease(de.symeda.sormas.api.Disease) Sample(de.symeda.sormas.backend.sample.Sample) Visit(de.symeda.sormas.backend.visit.Visit) DashboardContactDto(de.symeda.sormas.api.dashboard.DashboardContactDto) MapContactDto(de.symeda.sormas.api.contact.MapContactDto) ContactDto(de.symeda.sormas.api.contact.ContactDto) Date(java.util.Date) ContactProximity(de.symeda.sormas.api.contact.ContactProximity)

Example 2 with ContactProximity

use of de.symeda.sormas.api.contact.ContactProximity in project SORMAS-Project by hzi-braunschweig.

the class ContactCreateForm method updateContactProximity.

private void updateContactProximity() {
    ContactProximity value = (ContactProximity) contactProximity.getNullableValue();
    FieldHelper.updateEnumData(contactProximity, Arrays.asList(ContactProximity.getValues(disease, FacadeProvider.getConfigFacade().getCountryLocale())));
    contactProximity.setValue(value);
}
Also used : ContactProximity(de.symeda.sormas.api.contact.ContactProximity)

Example 3 with ContactProximity

use of de.symeda.sormas.api.contact.ContactProximity in project SORMAS-Project by hzi-braunschweig.

the class ContactEditFragment method onLayoutBinding.

@Override
public void onLayoutBinding(FragmentContactEditLayoutBinding contentBinding) {
    setUpControlListeners(contentBinding);
    contentBinding.setData(record);
    contentBinding.setCaze(sourceCase);
    contentBinding.setYesNoUnknownClass(YesNoUnknown.class);
    contentBinding.setVaccinationStatusClass(VaccinationStatus.class);
    InfrastructureFieldsDependencyHandler.instance.initializeRegionFields(contentBinding.contactRegion, initialRegions, record.getRegion(), contentBinding.contactDistrict, initialDistricts, record.getDistrict(), contentBinding.contactCommunity, initialCommunities, record.getCommunity());
    contentBinding.contactDisease.initializeSpinner(diseaseList);
    contentBinding.contactDisease.addValueChangedListener(e -> {
        contentBinding.contactContactProximity.setVisibility(e.getValue() == null ? GONE : VISIBLE);
        contentBinding.contactContactProximity.clear();
        contentBinding.contactContactProximity.setItems(DataUtils.toItems(Arrays.asList(ContactProximity.getValues((Disease) e.getValue(), ConfigProvider.getServerLocale()))));
    });
    contentBinding.contactFirstContactDate.addValueChangedListener(e -> contentBinding.contactLastContactDate.setRequired(e.getValue() != null));
    contentBinding.contactContactProximity.setItems(DataUtils.toItems(Arrays.asList(ContactProximity.getValues(record.getDisease(), ConfigProvider.getServerLocale()))));
    contentBinding.contactQuarantine.addValueChangedListener(e -> {
        boolean visible = QuarantineType.HOME.equals(contentBinding.contactQuarantine.getValue()) || QuarantineType.INSTITUTIONELL.equals(contentBinding.contactQuarantine.getValue());
        if (visible) {
            if (ConfigProvider.isConfiguredServer(CountryHelper.COUNTRY_CODE_GERMANY) || ConfigProvider.isConfiguredServer(CountryHelper.COUNTRY_CODE_SWITZERLAND)) {
                contentBinding.contactQuarantineOrderedVerbally.setVisibility(VISIBLE);
                contentBinding.contactQuarantineOrderedOfficialDocument.setVisibility(VISIBLE);
            }
        } else {
            contentBinding.contactQuarantineOrderedVerbally.setVisibility(GONE);
            contentBinding.contactQuarantineOrderedOfficialDocument.setVisibility(GONE);
            contentBinding.contactQuarantineExtended.setVisibility(GONE);
            contentBinding.contactQuarantineReduced.setVisibility(GONE);
        }
    });
    if (!ConfigProvider.isConfiguredServer(CountryHelper.COUNTRY_CODE_GERMANY) && !ConfigProvider.isConfiguredServer(CountryHelper.COUNTRY_CODE_SWITZERLAND)) {
        contentBinding.contactQuarantineOrderedVerbally.setVisibility(GONE);
        contentBinding.contactQuarantineOrderedVerballyDate.setVisibility(GONE);
        contentBinding.contactQuarantineOrderedOfficialDocument.setVisibility(GONE);
        contentBinding.contactQuarantineOrderedOfficialDocumentDate.setVisibility(GONE);
        contentBinding.contactQuarantineOfficialOrderSent.setVisibility(GONE);
        contentBinding.contactQuarantineOfficialOrderSentDate.setVisibility(GONE);
    }
    contentBinding.contactQuarantineExtended.setEnabled(false);
    contentBinding.contactQuarantineReduced.setEnabled(false);
    contentBinding.contactFollowUpUntil.setEnabled(false);
    contentBinding.contactQuarantineTo.addValueChangedListener(new ValueChangeListener() {

        private Date currentQuarantineTo = record.getQuarantineTo();

        private boolean currentQuarantineExtended = record.isQuarantineExtended();

        private boolean currentQuarantineReduced = record.isQuarantineReduced();

        @Override
        public void onChange(ControlPropertyField e) {
            Date newQuarantineTo = (Date) e.getValue();
            if (newQuarantineTo == null) {
                contentBinding.contactQuarantineExtended.setValue(false);
                contentBinding.contactQuarantineReduced.setValue(false);
            }
            if (currentQuarantineTo != null && newQuarantineTo != null && newQuarantineTo.after(currentQuarantineTo)) {
                extendQuarantine(newQuarantineTo);
            } else if (!currentQuarantineExtended) {
                contentBinding.contactQuarantineExtended.setValue(false);
            }
            if (currentQuarantineTo != null && newQuarantineTo != null && newQuarantineTo.before(currentQuarantineTo)) {
                reduceQuarantine();
            } else if (!currentQuarantineReduced) {
                contentBinding.contactQuarantineReduced.setValue(false);
            }
        }

        private void extendQuarantine(Date newQuarantineTo) {
            final ConfirmationDialog confirmationDialog = new ConfirmationDialog(getActivity(), R.string.heading_extend_quarantine, R.string.confirmation_extend_quarantine, R.string.yes, R.string.no);
            confirmationDialog.setPositiveCallback(() -> {
                contentBinding.contactQuarantineExtended.setValue(true);
                contentBinding.contactQuarantineReduced.setValue(false);
                if (record.getFollowUpUntil() != null) {
                    extendFollowUpPeriod(newQuarantineTo);
                }
            });
            confirmationDialog.setNegativeCallback(() -> contentBinding.contactQuarantineTo.setValue(currentQuarantineTo));
            confirmationDialog.show();
        }

        private void extendFollowUpPeriod(Date newQuarantineTo) {
            if (newQuarantineTo.after(record.getFollowUpUntil())) {
                final ConfirmationDialog confirmationDialog = new ConfirmationDialog(getActivity(), R.string.heading_extend_followup, R.string.confirmation_extend_followup, R.string.yes, R.string.no);
                confirmationDialog.setPositiveCallback(() -> {
                    contentBinding.contactFollowUpUntil.setValue(newQuarantineTo);
                });
                confirmationDialog.show();
            }
        }

        private void reduceQuarantine() {
            final ConfirmationDialog confirmationDialog = new ConfirmationDialog(getActivity(), R.string.heading_reduce_quarantine, R.string.confirmation_reduce_quarantine, R.string.yes, R.string.no);
            confirmationDialog.setPositiveCallback(() -> {
                contentBinding.contactQuarantineExtended.setValue(false);
                contentBinding.contactQuarantineReduced.setValue(true);
            });
            confirmationDialog.setNegativeCallback(() -> contentBinding.contactQuarantineTo.setValue(currentQuarantineTo));
            confirmationDialog.show();
        }
    });
    contentBinding.contactContactIdentificationSource.addValueChangedListener(e -> {
        if (ContactIdentificationSource.TRACING_APP.equals(e.getValue())) {
            contentBinding.contactTracingApp.setVisibility(VISIBLE);
        } else {
            contentBinding.contactTracingApp.setVisibility(GONE);
            contentBinding.contactTracingApp.setValue(null);
            contentBinding.contactTracingAppDetails.setVisibility(GONE);
            contentBinding.contactTracingAppDetails.setValue("");
        }
    });
    if (ConfigProvider.isConfiguredServer(CountryHelper.COUNTRY_CODE_GERMANY)) {
        contentBinding.contactContactProximity.addValueChangedListener(e -> updateContactCategory(contentBinding, (ContactProximity) contentBinding.contactContactProximity.getValue()));
    } else {
        contentBinding.contactContactIdentificationSource.setVisibility(GONE);
        contentBinding.contactContactProximityDetails.setVisibility(GONE);
        contentBinding.contactContactCategory.setVisibility(GONE);
    }
    if (record.getCaseUuid() != null) {
        contentBinding.contactDisease.setVisibility(GONE);
        contentBinding.contactCaseIdExternalSystem.setVisibility(GONE);
        contentBinding.contactCaseOrEventInformation.setVisibility(GONE);
    } else {
        contentBinding.contactDisease.setRequired(true);
        contentBinding.contactRegion.setRequired(true);
        contentBinding.contactDistrict.setRequired(true);
    }
    ContactValidator.initializeLastContactDateValidation(record, contentBinding);
    ContactValidator.initializeProhibitionToWorkIntervalValidator(contentBinding);
    // contentBinding.setContactProximityClass(ContactProximity.class);
    contentBinding.contactQuarantineExtended.addValueChangedListener(e -> contentBinding.contactQuarantineExtended.setVisibility(record.isQuarantineExtended() ? VISIBLE : GONE));
    contentBinding.contactQuarantineReduced.addValueChangedListener(e -> contentBinding.contactQuarantineReduced.setVisibility(record.isQuarantineReduced() ? VISIBLE : GONE));
}
Also used : ValueChangeListener(de.symeda.sormas.app.component.controls.ValueChangeListener) Disease(de.symeda.sormas.api.Disease) ControlPropertyField(de.symeda.sormas.app.component.controls.ControlPropertyField) Date(java.util.Date) ConfirmationDialog(de.symeda.sormas.app.component.dialog.ConfirmationDialog) ContactProximity(de.symeda.sormas.api.contact.ContactProximity)

Example 4 with ContactProximity

use of de.symeda.sormas.api.contact.ContactProximity in project SORMAS-Project by hzi-braunschweig.

the class ContactDataForm method addFields.

@SuppressWarnings("deprecation")
@Override
protected void addFields() {
    if (viewMode == null) {
        return;
    }
    Label contactDataHeadingLabel = new Label(I18nProperties.getString(Strings.headingContactData));
    contactDataHeadingLabel.addStyleName(H3);
    getContent().addComponent(contactDataHeadingLabel, CONTACT_DATA_HEADING_LOC);
    Label followUpStausHeadingLabel = new Label(I18nProperties.getString(Strings.headingFollowUpStatus));
    followUpStausHeadingLabel.addStyleName(H3);
    getContent().addComponent(followUpStausHeadingLabel, FOLLOW_UP_STATUS_HEADING_LOC);
    addField(ContactDto.CONTACT_CLASSIFICATION, NullableOptionGroup.class);
    addField(ContactDto.CONTACT_STATUS, NullableOptionGroup.class);
    addField(ContactDto.UUID, TextField.class);
    addField(ContactDto.EXTERNAL_ID, TextField.class);
    TextField externalTokenField = addField(ContactDto.EXTERNAL_TOKEN, TextField.class);
    Label externalTokenWarningLabel = new Label(I18nProperties.getString(Strings.messageContactExternalTokenWarning));
    externalTokenWarningLabel.addStyleNames(VSPACE_3, LABEL_WHITE_SPACE_NORMAL);
    getContent().addComponent(externalTokenWarningLabel, EXTERNAL_TOKEN_WARNING_LOC);
    addField(ContactDto.INTERNAL_TOKEN, TextField.class);
    addField(ContactDto.REPORTING_USER, ComboBox.class);
    CheckBox multiDayContact = addField(ContactDto.MULTI_DAY_CONTACT, CheckBox.class);
    DateField firstContactDate = addDateField(ContactDto.FIRST_CONTACT_DATE, DateField.class, 0);
    DateField lastContactDate = addField(ContactDto.LAST_CONTACT_DATE, DateField.class);
    FieldHelper.setVisibleWhen(getFieldGroup(), ContactDto.FIRST_CONTACT_DATE, ContactDto.MULTI_DAY_CONTACT, Collections.singletonList(true), true);
    initContactDateValidation(firstContactDate, lastContactDate, multiDayContact);
    DateField reportDate = addField(ContactDto.REPORT_DATE_TIME, DateField.class);
    addInfrastructureField(ContactDto.REPORTING_DISTRICT).addItems(FacadeProvider.getDistrictFacade().getAllActiveAsReference());
    addField(ContactDto.CONTACT_IDENTIFICATION_SOURCE, ComboBox.class);
    TextField contactIdentificationSourceDetails = addField(ContactDto.CONTACT_IDENTIFICATION_SOURCE_DETAILS, TextField.class);
    contactIdentificationSourceDetails.setInputPrompt(I18nProperties.getString(Strings.pleaseSpecify));
    // contactIdentificationSourceDetails.setVisible(false);
    ComboBox tracingApp = addField(ContactDto.TRACING_APP, ComboBox.class);
    TextField tracingAppDetails = addField(ContactDto.TRACING_APP_DETAILS, TextField.class);
    tracingAppDetails.setInputPrompt(I18nProperties.getString(Strings.pleaseSpecify));
    // tracingAppDetails.setVisible(false);
    if (isConfiguredServer(CountryHelper.COUNTRY_CODE_GERMANY)) {
        FieldHelper.setVisibleWhen(getFieldGroup(), ContactDto.CONTACT_IDENTIFICATION_SOURCE_DETAILS, ContactDto.CONTACT_IDENTIFICATION_SOURCE, Arrays.asList(ContactIdentificationSource.OTHER), true);
        FieldHelper.setVisibleWhen(getFieldGroup(), ContactDto.TRACING_APP, ContactDto.CONTACT_IDENTIFICATION_SOURCE, Arrays.asList(ContactIdentificationSource.TRACING_APP), true);
        FieldHelper.setVisibleWhen(getFieldGroup(), ContactDto.TRACING_APP_DETAILS, ContactDto.TRACING_APP, Arrays.asList(TracingApp.OTHER), true);
    }
    contactProximity = addField(ContactDto.CONTACT_PROXIMITY, NullableOptionGroup.class);
    contactProximity.setCaption(I18nProperties.getCaption(Captions.Contact_contactProximityLongForm));
    contactProximity.removeStyleName(ValoTheme.OPTIONGROUP_HORIZONTAL);
    if (isConfiguredServer(CountryHelper.COUNTRY_CODE_GERMANY)) {
        addField(ContactDto.CONTACT_PROXIMITY_DETAILS, TextField.class);
        contactCategory = addField(ContactDto.CONTACT_CATEGORY, NullableOptionGroup.class);
        contactProximity.addValueChangeListener(e -> {
            if (getInternalValue().getContactProximity() != e.getProperty().getValue() || contactCategory.isModified()) {
                updateContactCategory((ContactProximity) contactProximity.getNullableValue());
            }
        });
    }
    ComboBox relationToCase = addField(ContactDto.RELATION_TO_CASE, ComboBox.class);
    addField(ContactDto.RELATION_DESCRIPTION, TextField.class);
    cbDisease = addDiseaseField(ContactDto.DISEASE, false);
    cbDisease.setNullSelectionAllowed(false);
    addField(ContactDto.DISEASE_DETAILS, TextField.class);
    addField(ContactDto.PROHIBITION_TO_WORK, NullableOptionGroup.class).addStyleName(ValoTheme.OPTIONGROUP_HORIZONTAL);
    DateField prohibitionToWorkFrom = addField(ContactDto.PROHIBITION_TO_WORK_FROM);
    DateField prohibitionToWorkUntil = addDateField(ContactDto.PROHIBITION_TO_WORK_UNTIL, DateField.class, -1);
    FieldHelper.setVisibleWhen(getFieldGroup(), Arrays.asList(ContactDto.PROHIBITION_TO_WORK_FROM, ContactDto.PROHIBITION_TO_WORK_UNTIL), ContactDto.PROHIBITION_TO_WORK, YesNoUnknown.YES, true);
    prohibitionToWorkFrom.addValidator(new DateComparisonValidator(prohibitionToWorkFrom, prohibitionToWorkUntil, true, false, I18nProperties.getValidationError(Validations.beforeDate, prohibitionToWorkFrom.getCaption(), prohibitionToWorkUntil.getCaption())));
    prohibitionToWorkUntil.addValidator(new DateComparisonValidator(prohibitionToWorkUntil, prohibitionToWorkFrom, false, false, I18nProperties.getValidationError(Validations.afterDate, prohibitionToWorkUntil.getCaption(), prohibitionToWorkFrom.getCaption())));
    quarantine = addField(ContactDto.QUARANTINE);
    quarantine.addValueChangeListener(e -> onQuarantineValueChange());
    quarantineFrom = addField(ContactDto.QUARANTINE_FROM, DateField.class);
    dfQuarantineTo = addDateField(ContactDto.QUARANTINE_TO, DateField.class, -1);
    quarantineFrom.addValidator(new DateComparisonValidator(quarantineFrom, dfQuarantineTo, true, false, I18nProperties.getValidationError(Validations.beforeDate, quarantineFrom.getCaption(), dfQuarantineTo.getCaption())));
    dfQuarantineTo.addValidator(new DateComparisonValidator(dfQuarantineTo, quarantineFrom, false, false, I18nProperties.getValidationError(Validations.afterDate, dfQuarantineTo.getCaption(), quarantineFrom.getCaption())));
    quarantineChangeComment = addField(ContactDto.QUARANTINE_CHANGE_COMMENT);
    dfPreviousQuarantineTo = addDateField(ContactDto.PREVIOUS_QUARANTINE_TO, DateField.class, -1);
    setReadOnly(true, ContactDto.PREVIOUS_QUARANTINE_TO);
    setVisible(false, ContactDto.QUARANTINE_CHANGE_COMMENT, ContactDto.PREVIOUS_QUARANTINE_TO);
    quarantineOrderedVerbally = addField(ContactDto.QUARANTINE_ORDERED_VERBALLY, CheckBox.class);
    CssStyles.style(quarantineOrderedVerbally, CssStyles.FORCE_CAPTION);
    addField(ContactDto.QUARANTINE_ORDERED_VERBALLY_DATE, DateField.class);
    quarantineOrderedOfficialDocument = addField(ContactDto.QUARANTINE_ORDERED_OFFICIAL_DOCUMENT, CheckBox.class);
    CssStyles.style(quarantineOrderedOfficialDocument, CssStyles.FORCE_CAPTION);
    addField(ContactDto.QUARANTINE_ORDERED_OFFICIAL_DOCUMENT_DATE, DateField.class);
    CheckBox quarantineOfficialOrderSent = addField(ContactDto.QUARANTINE_OFFICIAL_ORDER_SENT, CheckBox.class);
    CssStyles.style(quarantineOfficialOrderSent, FORCE_CAPTION);
    addField(ContactDto.QUARANTINE_OFFICIAL_ORDER_SENT_DATE, DateField.class);
    FieldHelper.setVisibleWhen(getFieldGroup(), ContactDto.QUARANTINE_OFFICIAL_ORDER_SENT, ContactDto.QUARANTINE_ORDERED_OFFICIAL_DOCUMENT, Collections.singletonList(Boolean.TRUE), true);
    cbQuarantineExtended = addField(ContactDto.QUARANTINE_EXTENDED, CheckBox.class);
    cbQuarantineExtended.setEnabled(false);
    cbQuarantineExtended.setVisible(false);
    CssStyles.style(cbQuarantineExtended, CssStyles.FORCE_CAPTION);
    cbQuarantineReduced = addField(ContactDto.QUARANTINE_REDUCED, CheckBox.class);
    cbQuarantineReduced.setEnabled(false);
    cbQuarantineReduced.setVisible(false);
    CssStyles.style(cbQuarantineReduced, CssStyles.FORCE_CAPTION);
    TextField quarantineHelpNeeded = addField(ContactDto.QUARANTINE_HELP_NEEDED, TextField.class);
    quarantineHelpNeeded.setInputPrompt(I18nProperties.getString(Strings.pleaseSpecify));
    TextField quarantineTypeDetails = addField(ContactDto.QUARANTINE_TYPE_DETAILS, TextField.class);
    quarantineTypeDetails.setInputPrompt(I18nProperties.getString(Strings.pleaseSpecify));
    addField(ContactDto.QUARANTINE_HOME_POSSIBLE, NullableOptionGroup.class);
    addField(ContactDto.QUARANTINE_HOME_POSSIBLE_COMMENT, TextField.class);
    addField(ContactDto.QUARANTINE_HOME_SUPPLY_ENSURED, NullableOptionGroup.class);
    addField(ContactDto.QUARANTINE_HOME_SUPPLY_ENSURED_COMMENT, TextField.class);
    FieldHelper.setVisibleWhen(getFieldGroup(), Arrays.asList(ContactDto.QUARANTINE_FROM, ContactDto.QUARANTINE_TO, ContactDto.QUARANTINE_HELP_NEEDED), ContactDto.QUARANTINE, QuarantineType.QUARANTINE_IN_EFFECT, true);
    if (isConfiguredServer(CountryHelper.COUNTRY_CODE_GERMANY) || isConfiguredServer(CountryHelper.COUNTRY_CODE_SWITZERLAND)) {
        FieldHelper.setVisibleWhen(getFieldGroup(), Arrays.asList(ContactDto.QUARANTINE_ORDERED_VERBALLY, ContactDto.QUARANTINE_ORDERED_OFFICIAL_DOCUMENT), ContactDto.QUARANTINE, QuarantineType.QUARANTINE_IN_EFFECT, true);
    }
    FieldHelper.setVisibleWhen(getFieldGroup(), ContactDto.QUARANTINE_HOME_POSSIBLE_COMMENT, ContactDto.QUARANTINE_HOME_POSSIBLE, Arrays.asList(YesNoUnknown.NO), true);
    FieldHelper.setVisibleWhen(getFieldGroup(), ContactDto.QUARANTINE_HOME_SUPPLY_ENSURED, ContactDto.QUARANTINE_HOME_POSSIBLE, Arrays.asList(YesNoUnknown.YES), true);
    FieldHelper.setVisibleWhen(getFieldGroup(), ContactDto.QUARANTINE_HOME_SUPPLY_ENSURED_COMMENT, ContactDto.QUARANTINE_HOME_SUPPLY_ENSURED, Arrays.asList(YesNoUnknown.NO), true);
    FieldHelper.setVisibleWhen(getFieldGroup(), ContactDto.QUARANTINE_TYPE_DETAILS, ContactDto.QUARANTINE, Arrays.asList(QuarantineType.OTHER), true);
    FieldHelper.setVisibleWhen(getFieldGroup(), ContactDto.QUARANTINE_ORDERED_VERBALLY_DATE, ContactDto.QUARANTINE_ORDERED_VERBALLY, Arrays.asList(Boolean.TRUE), true);
    FieldHelper.setVisibleWhen(getFieldGroup(), ContactDto.QUARANTINE_ORDERED_OFFICIAL_DOCUMENT_DATE, ContactDto.QUARANTINE_ORDERED_OFFICIAL_DOCUMENT, Arrays.asList(Boolean.TRUE), true);
    FieldHelper.setVisibleWhen(getFieldGroup(), ContactDto.QUARANTINE_OFFICIAL_ORDER_SENT_DATE, ContactDto.QUARANTINE_OFFICIAL_ORDER_SENT, Collections.singletonList(Boolean.TRUE), true);
    addField(ContactDto.DESCRIPTION, TextArea.class).setRows(6);
    addField(ContactDto.VACCINATION_STATUS);
    addField(ContactDto.RETURNING_TRAVELER, NullableOptionGroup.class);
    addField(ContactDto.CASE_ID_EXTERNAL_SYSTEM, TextField.class);
    addField(ContactDto.CASE_OR_EVENT_INFORMATION, TextArea.class).setRows(4);
    addField(ContactDto.FOLLOW_UP_STATUS, ComboBox.class);
    addField(ContactDto.FOLLOW_UP_STATUS_CHANGE_DATE);
    addField(ContactDto.FOLLOW_UP_STATUS_CHANGE_USER);
    addField(ContactDto.FOLLOW_UP_COMMENT, TextArea.class).setRows(3);
    dfFollowUpUntil = addDateField(ContactDto.FOLLOW_UP_UNTIL, DateField.class, -1);
    dfFollowUpUntil.addValueChangeListener(v -> onFollowUpUntilChanged(v, dfQuarantineTo, cbQuarantineExtended, cbQuarantineReduced));
    cbOverwriteFollowUpUntil = addField(ContactDto.OVERWRITE_FOLLOW_UP_UTIL, CheckBox.class);
    cbOverwriteFollowUpUntil.addValueChangeListener(e -> {
        if (!(Boolean) e.getProperty().getValue()) {
            dfFollowUpUntil.discard();
        }
    });
    dfQuarantineTo.addValueChangeListener(e -> onQuarantineEndChange());
    addValueChangeListener(e -> {
        ValidationUtils.initComponentErrorValidator(externalTokenField, getValue().getExternalToken(), Validations.duplicateExternalToken, externalTokenWarningLabel, (externalToken) -> FacadeProvider.getContactFacade().doesExternalTokenExist(externalToken, getValue().getUuid()));
        onQuarantineValueChange();
    });
    ComboBox contactOfficerField = addField(ContactDto.CONTACT_OFFICER, ComboBox.class);
    contactOfficerField.setNullSelectionAllowed(true);
    ComboBox region = addInfrastructureField(ContactDto.REGION);
    region.setDescription(I18nProperties.getPrefixDescription(ContactDto.I18N_PREFIX, ContactDto.REGION));
    ComboBox district = addInfrastructureField(ContactDto.DISTRICT);
    district.setDescription(I18nProperties.getPrefixDescription(ContactDto.I18N_PREFIX, ContactDto.DISTRICT));
    ComboBox community = addInfrastructureField(ContactDto.COMMUNITY);
    community.setDescription(I18nProperties.getPrefixDescription(ContactDto.I18N_PREFIX, ContactDto.COMMUNITY));
    region.addValueChangeListener(e -> {
        RegionReferenceDto regionDto = (RegionReferenceDto) e.getProperty().getValue();
        FieldHelper.updateItems(district, regionDto != null ? FacadeProvider.getDistrictFacade().getAllActiveByRegion(regionDto.getUuid()) : null);
    });
    district.addValueChangeListener(e -> {
        DistrictReferenceDto districtDto = (DistrictReferenceDto) e.getProperty().getValue();
        FieldHelper.updateItems(community, districtDto != null ? FacadeProvider.getCommunityFacade().getAllActiveByDistrict(districtDto.getUuid()) : null);
        List<DistrictReferenceDto> officerDistricts = new ArrayList<>();
        officerDistricts.add(districtDto);
        if (districtDto == null && getValue().getCaze() != null) {
            CaseDataDto caseDto = FacadeProvider.getCaseFacade().getCaseDataByUuid(getValue().getCaze().getUuid());
            FieldHelper.updateOfficersField(contactOfficerField, caseDto, UserRole.CONTACT_OFFICER);
        } else {
            FieldHelper.updateItems(contactOfficerField, districtDto != null ? FacadeProvider.getUserFacade().getUserRefsByDistrict(districtDto, false, UserRole.CONTACT_OFFICER) : null);
        }
    });
    region.addItems(FacadeProvider.getRegionFacade().getAllActiveByServerCountry());
    CheckBox cbHighPriority = addField(ContactDto.HIGH_PRIORITY, CheckBox.class);
    tfExpectedFollowUpUntilDate = new TextField();
    tfExpectedFollowUpUntilDate.setCaption(I18nProperties.getCaption(Captions.Contact_expectedFollowUpUntil));
    getContent().addComponent(tfExpectedFollowUpUntilDate, EXPECTED_FOLLOW_UP_UNTIL_DATE_LOC);
    NullableOptionGroup ogImmunosuppressiveTherapyBasicDisease = addField(ContactDto.IMMUNOSUPPRESSIVE_THERAPY_BASIC_DISEASE, NullableOptionGroup.class);
    addField(ContactDto.IMMUNOSUPPRESSIVE_THERAPY_BASIC_DISEASE_DETAILS, TextField.class);
    NullableOptionGroup ogCareForPeopleOver60 = addField(ContactDto.CARE_FOR_PEOPLE_OVER_60, NullableOptionGroup.class);
    cbDisease.addValueChangeListener(e -> updateDiseaseConfiguration((Disease) e.getProperty().getValue()));
    HealthConditionsForm clinicalCourseForm = addField(ContactDto.HEALTH_CONDITIONS, HealthConditionsForm.class);
    clinicalCourseForm.setCaption(null);
    Label generalCommentLabel = new Label(I18nProperties.getPrefixCaption(ContactDto.I18N_PREFIX, ContactDto.ADDITIONAL_DETAILS));
    generalCommentLabel.addStyleName(H3);
    getContent().addComponent(generalCommentLabel, GENERAL_COMMENT_LOC);
    TextArea additionalDetails = addField(ContactDto.ADDITIONAL_DETAILS, TextArea.class);
    additionalDetails.setRows(6);
    additionalDetails.setDescription(I18nProperties.getPrefixDescription(ContactDto.I18N_PREFIX, ContactDto.ADDITIONAL_DETAILS, "") + "\n" + I18nProperties.getDescription(Descriptions.descGdpr));
    CssStyles.style(additionalDetails, CssStyles.CAPTION_HIDDEN);
    addFields(ContactDto.END_OF_QUARANTINE_REASON, ContactDto.END_OF_QUARANTINE_REASON_DETAILS);
    FieldHelper.setVisibleWhen(getFieldGroup(), ContactDto.END_OF_QUARANTINE_REASON_DETAILS, ContactDto.END_OF_QUARANTINE_REASON, Collections.singletonList(EndOfQuarantineReason.OTHER), true);
    initializeVisibilitiesAndAllowedVisibilities();
    initializeAccessAndAllowedAccesses();
    setReadOnly(true, ContactDto.UUID, ContactDto.REPORTING_USER, ContactDto.CONTACT_STATUS, ContactDto.FOLLOW_UP_STATUS, ContactDto.FOLLOW_UP_STATUS_CHANGE_DATE, ContactDto.FOLLOW_UP_STATUS_CHANGE_USER);
    FieldHelper.setRequiredWhen(getFieldGroup(), ContactDto.FOLLOW_UP_STATUS, Arrays.asList(ContactDto.FOLLOW_UP_COMMENT), Arrays.asList(FollowUpStatus.CANCELED, FollowUpStatus.LOST));
    FieldHelper.setVisibleWhenSourceNotNull(getFieldGroup(), Arrays.asList(ContactDto.FOLLOW_UP_STATUS_CHANGE_DATE, ContactDto.FOLLOW_UP_STATUS_CHANGE_USER), ContactDto.FOLLOW_UP_STATUS_CHANGE_DATE, true);
    FieldHelper.setVisibleWhen(getFieldGroup(), ContactDto.RELATION_DESCRIPTION, ContactDto.RELATION_TO_CASE, Arrays.asList(ContactRelation.OTHER), true);
    FieldHelper.setVisibleWhen(getFieldGroup(), ContactDto.IMMUNOSUPPRESSIVE_THERAPY_BASIC_DISEASE_DETAILS, ContactDto.IMMUNOSUPPRESSIVE_THERAPY_BASIC_DISEASE, Arrays.asList(YesNoUnknown.YES), true);
    FieldHelper.setVisibleWhen(getFieldGroup(), ContactDto.DISEASE_DETAILS, ContactDto.DISEASE, Arrays.asList(Disease.OTHER), true);
    FieldHelper.setRequiredWhen(getFieldGroup(), ContactDto.DISEASE, Arrays.asList(ContactDto.DISEASE_DETAILS), Arrays.asList(Disease.OTHER));
    FieldHelper.setReadOnlyWhen(getFieldGroup(), Arrays.asList(ContactDto.FOLLOW_UP_UNTIL), ContactDto.OVERWRITE_FOLLOW_UP_UTIL, Arrays.asList(Boolean.FALSE), false, true);
    FieldHelper.setRequiredWhen(getFieldGroup(), ContactDto.OVERWRITE_FOLLOW_UP_UTIL, Arrays.asList(ContactDto.FOLLOW_UP_UNTIL), Arrays.asList(Boolean.TRUE));
    FieldHelper.setVisibleWhen(getFieldGroup(), Arrays.asList(ContactDto.FOLLOW_UP_UNTIL, ContactDto.OVERWRITE_FOLLOW_UP_UTIL), ContactDto.FOLLOW_UP_STATUS, Arrays.asList(FollowUpStatus.CANCELED, FollowUpStatus.COMPLETED, FollowUpStatus.FOLLOW_UP, FollowUpStatus.LOST), true);
    initializeVisibilitiesAndAllowedVisibilities();
    addValueChangeListener(e -> {
        if (getValue() != null) {
            CaseDataDto caseDto = null;
            if (getValue().getCaze() != null) {
                setVisible(false, ContactDto.DISEASE, ContactDto.CASE_ID_EXTERNAL_SYSTEM, ContactDto.CASE_OR_EVENT_INFORMATION);
                caseDto = FacadeProvider.getCaseFacade().getCaseDataByUuid(getValue().getCaze().getUuid());
            } else {
                setRequired(true, ContactDto.DISEASE, ContactDto.REGION, ContactDto.DISTRICT);
            }
            updateLastContactDateValidator();
            updateDiseaseConfiguration(getValue().getDisease());
            updateFollowUpStatusComponents();
            DistrictReferenceDto referenceDistrict = getValue().getDistrict() != null ? getValue().getDistrict() : caseDto != null ? caseDto.getDistrict() : null;
            if (referenceDistrict != null) {
                contactOfficerField.addItems(FacadeProvider.getUserFacade().getUserRefsByDistrict(referenceDistrict, false, UserRole.CONTACT_OFFICER));
            }
            getContent().removeComponent(TO_CASE_BTN_LOC);
            if (getValue().getResultingCase() != null) {
                // link to case
                Link linkToData = ControllerProvider.getCaseController().createLinkToData(getValue().getResultingCase().getUuid(), I18nProperties.getCaption(Captions.contactOpenContactCase));
                getContent().addComponent(linkToData, TO_CASE_BTN_LOC);
            } else if (!ContactClassification.NO_CONTACT.equals(getValue().getContactClassification())) {
                if (UserProvider.getCurrent().hasUserRight(UserRight.CONTACT_CONVERT)) {
                    Button toCaseButton = ButtonHelper.createButton(Captions.contactCreateContactCase, event -> {
                        if (!ContactClassification.CONFIRMED.equals(getValue().getContactClassification())) {
                            VaadinUiUtil.showSimplePopupWindow(I18nProperties.getString(Strings.headingContactConfirmationRequired), I18nProperties.getString(Strings.messageContactToCaseConfirmationRequired));
                        } else {
                            ControllerProvider.getCaseController().createFromContact(getValue());
                        }
                    }, ValoTheme.BUTTON_LINK);
                    getContent().addComponent(toCaseButton, TO_CASE_BTN_LOC);
                }
            }
            if (!isConfiguredServer(CountryHelper.COUNTRY_CODE_GERMANY)) {
                setVisible(false, ContactDto.IMMUNOSUPPRESSIVE_THERAPY_BASIC_DISEASE, ContactDto.IMMUNOSUPPRESSIVE_THERAPY_BASIC_DISEASE_DETAILS, ContactDto.CARE_FOR_PEOPLE_OVER_60);
            } else {
                ogImmunosuppressiveTherapyBasicDisease.addValueChangeListener(getHighPriorityValueChangeListener(cbHighPriority));
                ogCareForPeopleOver60.addValueChangeListener(getHighPriorityValueChangeListener(cbHighPriority));
            }
            // Add follow-up until validator
            FollowUpPeriodDto followUpPeriod = ContactLogic.getFollowUpStartDate(lastContactDate.getValue(), reportDate.getValue(), FacadeProvider.getSampleFacade().getByContactUuids(Collections.singletonList(getValue().getUuid())));
            Date minimumFollowUpUntilDate = FollowUpLogic.calculateFollowUpUntilDate(followUpPeriod, null, FacadeProvider.getVisitFacade().getVisitsByContact(new ContactReferenceDto(getValue().getUuid())), FacadeProvider.getDiseaseConfigurationFacade().getFollowUpDuration(getSelectedDisease()), FacadeProvider.getFeatureConfigurationFacade().isPropertyValueTrue(FeatureType.CONTACT_TRACING, FeatureTypeProperty.ALLOW_FREE_FOLLOW_UP_OVERWRITE)).getFollowUpEndDate();
            if (FacadeProvider.getFeatureConfigurationFacade().isPropertyValueTrue(FeatureType.CONTACT_TRACING, FeatureTypeProperty.ALLOW_FREE_FOLLOW_UP_OVERWRITE)) {
                dfFollowUpUntil.addValueChangeListener(valueChangeEvent -> {
                    if (DateHelper.getEndOfDay(dfFollowUpUntil.getValue()).before(minimumFollowUpUntilDate)) {
                        dfFollowUpUntil.setComponentError(new ErrorMessage() {

                            @Override
                            public ErrorLevel getErrorLevel() {
                                return ErrorLevel.INFO;
                            }

                            @Override
                            public String getFormattedHtmlMessage() {
                                return I18nProperties.getValidationError(Validations.contactFollowUpUntilDateSoftValidation, I18nProperties.getPrefixCaption(ContactDto.I18N_PREFIX, ContactDto.FOLLOW_UP_UNTIL));
                            }
                        });
                    }
                });
            } else {
                dfFollowUpUntil.addValidator(new DateRangeValidator(I18nProperties.getValidationError(Validations.contactFollowUpUntilDate), minimumFollowUpUntilDate, null, Resolution.DAY));
            }
        }
        // Overwrite visibility for quarantine fields
        if (!isConfiguredServer(CountryHelper.COUNTRY_CODE_GERMANY) && !isConfiguredServer(CountryHelper.COUNTRY_CODE_SWITZERLAND)) {
            setVisible(false, ContactDto.QUARANTINE_ORDERED_OFFICIAL_DOCUMENT, ContactDto.QUARANTINE_ORDERED_OFFICIAL_DOCUMENT_DATE, ContactDto.QUARANTINE_ORDERED_VERBALLY, ContactDto.QUARANTINE_ORDERED_VERBALLY_DATE, ContactDto.QUARANTINE_OFFICIAL_ORDER_SENT, ContactDto.QUARANTINE_OFFICIAL_ORDER_SENT_DATE);
        }
    });
    setRequired(true, ContactDto.CONTACT_CLASSIFICATION, ContactDto.CONTACT_STATUS, ContactDto.REPORT_DATE_TIME);
    FieldHelper.addSoftRequiredStyle(firstContactDate, lastContactDate, contactProximity, relationToCase);
}
Also used : FollowUpStatus(de.symeda.sormas.api.contact.FollowUpStatus) FeatureType(de.symeda.sormas.api.feature.FeatureType) HealthConditionsForm(de.symeda.sormas.ui.clinicalcourse.HealthConditionsForm) AbstractEditForm(de.symeda.sormas.ui.utils.AbstractEditForm) LAYOUT_COL_HIDE_INVSIBLE(de.symeda.sormas.ui.utils.CssStyles.LAYOUT_COL_HIDE_INVSIBLE) H3(de.symeda.sormas.ui.utils.CssStyles.H3) Arrays(java.util.Arrays) ContactRelation(de.symeda.sormas.api.contact.ContactRelation) ValidationUtils(de.symeda.sormas.ui.utils.ValidationUtils) Date(java.util.Date) CheckBox(com.vaadin.v7.ui.CheckBox) EndOfQuarantineReason(de.symeda.sormas.api.contact.EndOfQuarantineReason) I18nProperties(de.symeda.sormas.api.i18n.I18nProperties) TracingApp(de.symeda.sormas.api.contact.TracingApp) ContactProximity(de.symeda.sormas.api.contact.ContactProximity) ControllerProvider(de.symeda.sormas.ui.ControllerProvider) YesNoUnknown(de.symeda.sormas.api.utils.YesNoUnknown) CssStyles(de.symeda.sormas.ui.utils.CssStyles) VSPACE_3(de.symeda.sormas.ui.utils.CssStyles.VSPACE_3) UserRole(de.symeda.sormas.api.user.UserRole) FORCE_CAPTION(de.symeda.sormas.ui.utils.CssStyles.FORCE_CAPTION) UserProvider(de.symeda.sormas.ui.UserProvider) ValoTheme(com.vaadin.ui.themes.ValoTheme) Property(com.vaadin.v7.data.Property) ViewMode(de.symeda.sormas.ui.utils.ViewMode) Validator(com.vaadin.v7.data.Validator) ComboBox(com.vaadin.v7.ui.ComboBox) Link(com.vaadin.ui.Link) CaseDataDto(de.symeda.sormas.api.caze.CaseDataDto) Field(com.vaadin.v7.ui.Field) FieldHelper(de.symeda.sormas.ui.utils.FieldHelper) ContactClassification(de.symeda.sormas.api.contact.ContactClassification) Sets(com.google.common.collect.Sets) List(java.util.List) ContactDto(de.symeda.sormas.api.contact.ContactDto) TextField(com.vaadin.v7.ui.TextField) Descriptions(de.symeda.sormas.api.i18n.Descriptions) UiFieldAccessCheckers(de.symeda.sormas.api.utils.fieldaccess.UiFieldAccessCheckers) RegionReferenceDto(de.symeda.sormas.api.infrastructure.region.RegionReferenceDto) DateComparisonValidator(de.symeda.sormas.ui.utils.DateComparisonValidator) FollowUpPeriodDto(de.symeda.sormas.api.followup.FollowUpPeriodDto) VaadinUiUtil(de.symeda.sormas.ui.utils.VaadinUiUtil) LABEL_WHITE_SPACE_NORMAL(de.symeda.sormas.ui.utils.CssStyles.LABEL_WHITE_SPACE_NORMAL) FacadeProvider(de.symeda.sormas.api.FacadeProvider) DateHelper(de.symeda.sormas.api.utils.DateHelper) ErrorLevel(com.vaadin.shared.ui.ErrorLevel) Converter(com.vaadin.v7.data.util.converter.Converter) ArrayList(java.util.ArrayList) CaseReferenceDto(de.symeda.sormas.api.caze.CaseReferenceDto) QuarantineType(de.symeda.sormas.api.contact.QuarantineType) LayoutUtil.loc(de.symeda.sormas.ui.utils.LayoutUtil.loc) LayoutUtil.locCss(de.symeda.sormas.ui.utils.LayoutUtil.locCss) Resolution(com.vaadin.v7.shared.ui.datefield.Resolution) Label(com.vaadin.ui.Label) CountryHelper(de.symeda.sormas.api.CountryHelper) NullableOptionGroup(de.symeda.sormas.ui.utils.NullableOptionGroup) LayoutUtil.fluidRowLocs(de.symeda.sormas.ui.utils.LayoutUtil.fluidRowLocs) DateField(com.vaadin.v7.ui.DateField) ButtonHelper(de.symeda.sormas.ui.utils.ButtonHelper) ContactIdentificationSource(de.symeda.sormas.api.contact.ContactIdentificationSource) Validations(de.symeda.sormas.api.i18n.Validations) DistrictReferenceDto(de.symeda.sormas.api.infrastructure.district.DistrictReferenceDto) ContactLogic(de.symeda.sormas.api.contact.ContactLogic) ErrorMessage(com.vaadin.server.ErrorMessage) Captions(de.symeda.sormas.api.i18n.Captions) ExtendedReduced(de.symeda.sormas.api.utils.ExtendedReduced) LocalDate(org.joda.time.LocalDate) UserRight(de.symeda.sormas.api.user.UserRight) Button(com.vaadin.ui.Button) LayoutUtil(de.symeda.sormas.ui.utils.LayoutUtil) Disease(de.symeda.sormas.api.Disease) DateRangeValidator(com.vaadin.v7.data.validator.DateRangeValidator) TextArea(com.vaadin.v7.ui.TextArea) ContactCategory(de.symeda.sormas.api.contact.ContactCategory) FollowUpLogic(de.symeda.sormas.api.followup.FollowUpLogic) DiseasesConfiguration(de.symeda.sormas.api.utils.Diseases.DiseasesConfiguration) ContactReferenceDto(de.symeda.sormas.api.contact.ContactReferenceDto) FeatureTypeProperty(de.symeda.sormas.api.feature.FeatureTypeProperty) FieldVisibilityCheckers(de.symeda.sormas.api.utils.fieldvisibility.FieldVisibilityCheckers) Strings(de.symeda.sormas.api.i18n.Strings) Collections(java.util.Collections) Disease(de.symeda.sormas.api.Disease) TextArea(com.vaadin.v7.ui.TextArea) Label(com.vaadin.ui.Label) ArrayList(java.util.ArrayList) FollowUpPeriodDto(de.symeda.sormas.api.followup.FollowUpPeriodDto) HealthConditionsForm(de.symeda.sormas.ui.clinicalcourse.HealthConditionsForm) Button(com.vaadin.ui.Button) DateRangeValidator(com.vaadin.v7.data.validator.DateRangeValidator) TextField(com.vaadin.v7.ui.TextField) NullableOptionGroup(de.symeda.sormas.ui.utils.NullableOptionGroup) CaseDataDto(de.symeda.sormas.api.caze.CaseDataDto) ComboBox(com.vaadin.v7.ui.ComboBox) DistrictReferenceDto(de.symeda.sormas.api.infrastructure.district.DistrictReferenceDto) Date(java.util.Date) LocalDate(org.joda.time.LocalDate) DateComparisonValidator(de.symeda.sormas.ui.utils.DateComparisonValidator) RegionReferenceDto(de.symeda.sormas.api.infrastructure.region.RegionReferenceDto) CheckBox(com.vaadin.v7.ui.CheckBox) ContactReferenceDto(de.symeda.sormas.api.contact.ContactReferenceDto) ErrorLevel(com.vaadin.shared.ui.ErrorLevel) DateField(com.vaadin.v7.ui.DateField) ErrorMessage(com.vaadin.server.ErrorMessage) Link(com.vaadin.ui.Link)

Example 5 with ContactProximity

use of de.symeda.sormas.api.contact.ContactProximity in project SORMAS-Project by hzi-braunschweig.

the class ContactCreateForm method addFields.

@Override
protected void addFields() {
    if (hasCaseRelation == null) {
        return;
    }
    addField(ContactDto.REPORT_DATE_TIME, DateField.class);
    ComboBox cbDisease = addDiseaseField(ContactDto.DISEASE, false, true);
    addField(ContactDto.DISEASE_DETAILS, TextField.class);
    TextField firstName = addCustomField(PersonDto.FIRST_NAME, String.class, TextField.class);
    TextField lastName = addCustomField(PersonDto.LAST_NAME, String.class, TextField.class);
    if (showPersonSearchButton) {
        searchPersonButton = createPersonSearchButton(PERSON_SEARCH_LOC);
        getContent().addComponent(searchPersonButton, PERSON_SEARCH_LOC);
    }
    TextField nationalHealthIdField = addCustomField(PersonDto.NATIONAL_HEALTH_ID, String.class, TextField.class);
    TextField passportNumberField = addCustomField(PersonDto.PASSPORT_NUMBER, String.class, TextField.class);
    if (CountryHelper.isCountry(FacadeProvider.getConfigFacade().getCountryLocale(), CountryHelper.COUNTRY_CODE_GERMANY)) {
        nationalHealthIdField.setVisible(false);
    }
    if (CountryHelper.isInCountries(FacadeProvider.getConfigFacade().getCountryLocale(), CountryHelper.COUNTRY_CODE_GERMANY, CountryHelper.COUNTRY_CODE_FRANCE)) {
        passportNumberField.setVisible(false);
    }
    TextField phone = addCustomField(PersonDto.PHONE, String.class, TextField.class);
    phone.setCaption(I18nProperties.getCaption(Captions.Person_phone));
    TextField email = addCustomField(PersonDto.EMAIL_ADDRESS, String.class, TextField.class);
    email.setCaption(I18nProperties.getCaption(Captions.Person_emailAddress));
    phone.addValidator(new PhoneNumberValidator(I18nProperties.getValidationError(Validations.validPhoneNumber, phone.getCaption())));
    email.addValidator(new EmailValidator(I18nProperties.getValidationError(Validations.validEmailAddress, email.getCaption())));
    addField(ContactDto.RETURNING_TRAVELER, NullableOptionGroup.class);
    ComboBox region = addInfrastructureField(ContactDto.REGION);
    ComboBox district = addInfrastructureField(ContactDto.DISTRICT);
    ComboBox community = addInfrastructureField(ContactDto.COMMUNITY);
    CheckBox multiDayContact = addField(ContactDto.MULTI_DAY_CONTACT, CheckBox.class);
    DateField firstContactDate = addField(ContactDto.FIRST_CONTACT_DATE, DateField.class);
    DateField lastContactDate = addField(ContactDto.LAST_CONTACT_DATE, DateField.class);
    FieldHelper.setVisibleWhen(getFieldGroup(), ContactDto.FIRST_CONTACT_DATE, ContactDto.MULTI_DAY_CONTACT, Collections.singletonList(true), true);
    initContactDateValidation(firstContactDate, lastContactDate, multiDayContact);
    contactProximity = addField(ContactDto.CONTACT_PROXIMITY, NullableOptionGroup.class);
    contactProximity.removeStyleName(ValoTheme.OPTIONGROUP_HORIZONTAL);
    if (isConfiguredServer(CountryHelper.COUNTRY_CODE_GERMANY)) {
        contactProximity.addValueChangeListener(e -> updateContactCategory((ContactProximity) contactProximity.getNullableValue()));
        contactProximityDetails = addField(ContactDto.CONTACT_PROXIMITY_DETAILS, TextField.class);
        contactCategory = addField(ContactDto.CONTACT_CATEGORY, NullableOptionGroup.class);
    }
    addField(ContactDto.DESCRIPTION, TextArea.class).setRows(4);
    ComboBox relationToCase = addField(ContactDto.RELATION_TO_CASE, ComboBox.class);
    addField(ContactDto.RELATION_DESCRIPTION, TextField.class);
    addField(ContactDto.CASE_ID_EXTERNAL_SYSTEM, TextField.class);
    addField(ContactDto.CASE_OR_EVENT_INFORMATION, TextArea.class).setRows(4);
    birthDateDay = addCustomField(PersonDto.BIRTH_DATE_DD, Integer.class, ComboBox.class);
    birthDateDay.addStyleName(FORCE_CAPTION);
    birthDateDay.setInputPrompt(I18nProperties.getString(Strings.day));
    ComboBox birthDateMonth = addCustomField(PersonDto.BIRTH_DATE_MM, Integer.class, ComboBox.class);
    birthDateMonth.addItems(DateHelper.getMonthsInYear());
    birthDateMonth.setPageLength(12);
    birthDateMonth.addStyleName(FORCE_CAPTION);
    birthDateMonth.setInputPrompt(I18nProperties.getString(Strings.month));
    setItemCaptionsForMonths(birthDateMonth);
    ComboBox birthDateYear = addCustomField(PersonDto.BIRTH_DATE_YYYY, Integer.class, ComboBox.class);
    birthDateYear.setCaption(I18nProperties.getPrefixCaption(PersonDto.I18N_PREFIX, PersonDto.BIRTH_DATE));
    birthDateYear.addItems(DateHelper.getYearsToNow());
    birthDateYear.setItemCaptionMode(ItemCaptionMode.ID_TOSTRING);
    birthDateYear.setInputPrompt(I18nProperties.getString(Strings.year));
    birthDateDay.addValidator(e -> ControllerProvider.getPersonController().validateBirthDate((Integer) birthDateYear.getValue(), (Integer) birthDateMonth.getValue(), (Integer) e));
    birthDateMonth.addValidator(e -> ControllerProvider.getPersonController().validateBirthDate((Integer) birthDateYear.getValue(), (Integer) e, (Integer) birthDateDay.getValue()));
    birthDateYear.addValidator(e -> ControllerProvider.getPersonController().validateBirthDate((Integer) e, (Integer) birthDateMonth.getValue(), (Integer) birthDateDay.getValue()));
    // Update the list of days according to the selected month and year
    birthDateYear.addValueChangeListener(e -> {
        updateListOfDays((Integer) e.getProperty().getValue(), (Integer) birthDateMonth.getValue());
        birthDateMonth.markAsDirty();
        birthDateDay.markAsDirty();
    });
    birthDateMonth.addValueChangeListener(e -> {
        updateListOfDays((Integer) birthDateYear.getValue(), (Integer) e.getProperty().getValue());
        birthDateYear.markAsDirty();
        birthDateDay.markAsDirty();
    });
    birthDateDay.addValueChangeListener(e -> {
        birthDateYear.markAsDirty();
        birthDateMonth.markAsDirty();
    });
    ComboBox sex = addCustomField(PersonDto.SEX, Sex.class, ComboBox.class);
    sex.setCaption(I18nProperties.getCaption(Captions.Person_sex));
    CssStyles.style(CssStyles.SOFT_REQUIRED, firstName, lastName, firstContactDate, lastContactDate, contactProximity, relationToCase);
    region.addValueChangeListener(e -> {
        RegionReferenceDto regionDto = (RegionReferenceDto) e.getProperty().getValue();
        FieldHelper.updateItems(district, regionDto != null ? FacadeProvider.getDistrictFacade().getAllActiveByRegion(regionDto.getUuid()) : null);
    });
    region.addItems(FacadeProvider.getRegionFacade().getAllActiveByServerCountry());
    district.addValueChangeListener(e -> {
        DistrictReferenceDto districtDto = (DistrictReferenceDto) e.getProperty().getValue();
        FieldHelper.updateItems(community, districtDto != null ? FacadeProvider.getCommunityFacade().getAllActiveByDistrict(districtDto.getUuid()) : null);
    });
    setRequired(true, PersonDto.FIRST_NAME, PersonDto.LAST_NAME, ContactDto.REPORT_DATE_TIME, PersonDto.SEX);
    FieldHelper.setVisibleWhen(getFieldGroup(), ContactDto.RELATION_DESCRIPTION, ContactDto.RELATION_TO_CASE, Arrays.asList(ContactRelation.OTHER), true);
    FieldHelper.setVisibleWhen(getFieldGroup(), ContactDto.DISEASE_DETAILS, ContactDto.DISEASE, Arrays.asList(Disease.OTHER), true);
    FieldHelper.setRequiredWhen(getFieldGroup(), ContactDto.DISEASE, Arrays.asList(ContactDto.DISEASE_DETAILS), Arrays.asList(Disease.OTHER));
    cbDisease.addValueChangeListener(e -> {
        disease = (Disease) e.getProperty().getValue();
        setVisible(disease != null, ContactDto.CONTACT_PROXIMITY);
        if (isConfiguredServer("de")) {
            contactCategory.setVisible(disease != null);
            contactProximityDetails.setVisible(disease != null);
        }
        updateContactProximity();
    });
    if (!hasCaseRelation) {
        Label caseInfoLabel = new Label(I18nProperties.getString(Strings.infoNoSourceCaseSelected), ContentMode.HTML);
        Button chooseCaseButton = ButtonHelper.createButton(Captions.contactChooseCase, null, ValoTheme.BUTTON_PRIMARY, CssStyles.VSPACE_2);
        Button removeCaseButton = ButtonHelper.createButton(Captions.contactRemoveCase, null, ValoTheme.BUTTON_LINK);
        CssStyles.style(caseInfoLabel, CssStyles.VSPACE_TOP_4);
        getContent().addComponent(caseInfoLabel, CASE_INFO_LOC);
        chooseCaseButton.addClickListener(e -> {
            ControllerProvider.getContactController().openSelectCaseForContactWindow((Disease) cbDisease.getValue(), selectedCase -> {
                if (selectedCase != null) {
                    caseInfoLabel.setValue(String.format(I18nProperties.getString(Strings.infoContactCreationSourceCase), selectedCase.getPersonFirstName() + " " + selectedCase.getPersonLastName() + " " + "(" + DataHelper.getShortUuid(selectedCase.getUuid()) + ")"));
                    caseInfoLabel.removeStyleName(CssStyles.VSPACE_TOP_4);
                    removeCaseButton.setVisible(true);
                    chooseCaseButton.setCaption(I18nProperties.getCaption(Captions.contactChangeCase));
                    getValue().setCaze(selectedCase.toReference());
                    cbDisease.setValue(selectedCase.getDisease());
                    updateFieldVisibilitiesByCase(true);
                }
            });
        });
        getContent().addComponent(chooseCaseButton, CHOOSE_CASE_LOC);
        removeCaseButton.addClickListener(e -> {
            getValue().setCaze(null);
            cbDisease.setValue(null);
            caseInfoLabel.setValue(I18nProperties.getString(Strings.infoNoSourceCaseSelected));
            caseInfoLabel.addStyleName(CssStyles.VSPACE_TOP_4);
            removeCaseButton.setVisible(false);
            chooseCaseButton.setCaption(I18nProperties.getCaption(Captions.contactChooseCase));
            updateFieldVisibilitiesByCase(false);
        });
        getContent().addComponent(removeCaseButton, REMOVE_CASE_LOC);
        removeCaseButton.setVisible(false);
    }
    if (asSourceContact) {
        setEnabled(false, ContactDto.DISEASE, ContactDto.DISEASE_DETAILS);
    }
    addValueChangeListener(e -> {
        updateFieldVisibilitiesByCase(hasCaseRelation);
        if (!hasCaseRelation && disease == null) {
            setVisible(false, ContactDto.CONTACT_PROXIMITY);
            if (isConfiguredServer("de")) {
                contactCategory.setVisible(false);
                contactProximityDetails.setVisible(false);
            }
        }
        updateContactProximity();
        if (asSourceContact) {
            setVisible(false, PersonDto.FIRST_NAME, PersonDto.LAST_NAME, PersonDto.BIRTH_DATE_DD, PersonDto.BIRTH_DATE_MM, PersonDto.BIRTH_DATE_YYYY, PersonDto.SEX, PersonDto.NATIONAL_HEALTH_ID, PersonDto.PASSPORT_NUMBER, PersonDto.PHONE, PersonDto.EMAIL_ADDRESS);
            setRequired(false, PersonDto.SEX);
            TextField personNameField = addCustomField(PERSON_NAME_LOC, String.class, TextField.class);
            personNameField.setCaption(I18nProperties.getPrefixCaption(ContactDto.I18N_PREFIX, ContactDto.PERSON));
            personNameField.setValue(getValue().getPerson().getCaption());
            personNameField.setReadOnly(true);
            searchPersonButton.setVisible(false);
        }
    });
}
Also used : NullableOptionGroup(de.symeda.sormas.ui.utils.NullableOptionGroup) EmailValidator(com.vaadin.v7.data.validator.EmailValidator) TextArea(com.vaadin.v7.ui.TextArea) ComboBox(com.vaadin.v7.ui.ComboBox) PhoneNumberValidator(de.symeda.sormas.ui.utils.PhoneNumberValidator) Label(com.vaadin.ui.Label) DistrictReferenceDto(de.symeda.sormas.api.infrastructure.district.DistrictReferenceDto) RegionReferenceDto(de.symeda.sormas.api.infrastructure.region.RegionReferenceDto) Button(com.vaadin.ui.Button) CheckBox(com.vaadin.v7.ui.CheckBox) TextField(com.vaadin.v7.ui.TextField) DateField(com.vaadin.v7.ui.DateField) ContactProximity(de.symeda.sormas.api.contact.ContactProximity)

Aggregations

ContactProximity (de.symeda.sormas.api.contact.ContactProximity)6 Disease (de.symeda.sormas.api.Disease)4 Button (com.vaadin.ui.Button)2 Label (com.vaadin.ui.Label)2 CheckBox (com.vaadin.v7.ui.CheckBox)2 ComboBox (com.vaadin.v7.ui.ComboBox)2 DateField (com.vaadin.v7.ui.DateField)2 TextArea (com.vaadin.v7.ui.TextArea)2 TextField (com.vaadin.v7.ui.TextField)2 ContactClassification (de.symeda.sormas.api.contact.ContactClassification)2 ContactDto (de.symeda.sormas.api.contact.ContactDto)2 ContactLogic (de.symeda.sormas.api.contact.ContactLogic)2 ContactReferenceDto (de.symeda.sormas.api.contact.ContactReferenceDto)2 FollowUpStatus (de.symeda.sormas.api.contact.FollowUpStatus)2 DistrictReferenceDto (de.symeda.sormas.api.infrastructure.district.DistrictReferenceDto)2 RegionReferenceDto (de.symeda.sormas.api.infrastructure.region.RegionReferenceDto)2 NullableOptionGroup (de.symeda.sormas.ui.utils.NullableOptionGroup)2 Date (java.util.Date)2 Sets (com.google.common.collect.Sets)1 ErrorMessage (com.vaadin.server.ErrorMessage)1