Skip to content

Commit

Permalink
Feature #13205 add information about legal guardian (#13255)
Browse files Browse the repository at this point in the history
* Customizable enums creation form - save returns an error #13221

* Add information about legal guardian for "minor / incapacitated" to person entity #13205

* #13205 - Add information about legal guardian for "minor / incapacitated" to person entity

* Add information about legal guardian for "minor / incapacitated" to person entity #13205

* Reverting on Sergiu sugestions. As only captions.properties needs to be affected and all others needs to be translated from this file.

* Fixed 2 issues and 1 rename found by Sergiu. 1. onEmancipatedChange in place of updateIsEmancipatedCheckBox, 2. currently: if a Legal guardian is added and then the user checks "Emancipated" the legal guardian remains in the UI and later on saved in database. -> how it should work: the "Legal guardian's name" should be removed once the "Emancipated" checkbox is checked".
3. when the person is less than 1 year old the emancipated checkbox is still shown

* canBeEmancipated change

* another adjustments.

* Fixed: There is the following unwanted behavior ocurring:
In a person is set to be emancipated. Then the age goes in the adult range. The emancipated checkbox disappears but the incapacitated checkbox should be shown unchecked. The incapacitated checkbox could be needed in the future even if the person is an adult.
+ rename of a variable.

* isEmancipatedVisible - 2nd place.

* fixing merge sormas_schema.sql

* Replaced one additonal method with another. Fixed the scenario where isIncapacitated is not more shown for interval where Emancipated checkbox is shown.

* Rearranging fields and another minor fixes

* #13205 - Add information about legal guardian for "minor / incapacitated" to person entity - fix hasGuardian not checked when refresh Person edit page

---------

Co-authored-by: Marin <[email protected]>
Co-authored-by: SergiuPacurariu <[email protected]>
  • Loading branch information
3 people authored Feb 4, 2025
1 parent e28777d commit b757fb9
Show file tree
Hide file tree
Showing 10 changed files with 193 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -163,4 +163,8 @@ public interface ConfigFacade {
boolean isAnyCaseClassificationCalculationEnabled();

Integer getNegaiveCovidTestsMaxAgeDays();

long getMinimumEmancipatedAge();

long getMinimumAdultAge();
}
Original file line number Diff line number Diff line change
Expand Up @@ -2220,12 +2220,15 @@ public interface Captions {
String Person_educationDetails = "Person.educationDetails";
String Person_educationType = "Person.educationType";
String Person_emailAddress = "Person.emailAddress";
String Person_emancipated = "Person.emancipated";
String Person_externalId = "Person.externalId";
String Person_externalToken = "Person.externalToken";
String Person_fathersName = "Person.fathersName";
String Person_generalPractitionerDetails = "Person.generalPractitionerDetails";
String Person_gestationAgeAtBirth = "Person.gestationAgeAtBirth";
String Person_hasCovidApp = "Person.hasCovidApp";
String Person_hasGuardian = "Person.hasGuardian";
String Person_incapacitated = "Person.incapacitated";
String Person_internalToken = "Person.internalToken";
String Person_lastDisease = "Person.lastDisease";
String Person_matchingCase = "Person.matchingCase";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ public class PersonDto extends PseudonymizableDto implements IsPerson {
public static final String BIRTH_COUNTRY = "birthCountry";
public static final String CITIZENSHIP = "citizenship";
public static final String ADDITIONAL_DETAILS = "additionalDetails";
public static final String IS_EMANCIPATED = "emancipated";
public static final String IS_INCAPACITATED = "incapacitated";
private static final long serialVersionUID = -8558187171374254398L;

// Fields are declared in the order they should appear in the import template
Expand Down Expand Up @@ -377,6 +379,9 @@ public class PersonDto extends PseudonymizableDto implements IsPerson {
@Size(max = FieldConstraints.CHARACTER_LIMIT_TEXT, message = Validations.textTooLong)
private String additionalDetails;

private boolean emancipated;
private boolean incapacitated;

@SuppressWarnings("serial")
public static class SeveralNonPrimaryContactDetailsException extends RuntimeException {

Expand Down Expand Up @@ -1031,6 +1036,22 @@ public void setAdditionalDetails(String additionalDetails) {
this.additionalDetails = additionalDetails;
}

public boolean isEmancipated() {
return emancipated;
}

public void setEmancipated(boolean emancipated) {
this.emancipated = emancipated;
}

public boolean isIncapacitated() {
return incapacitated;
}

public void setIncapacitated(boolean incapacitated) {
this.incapacitated = incapacitated;
}

@Override
public String buildCaption() {
return buildCaption(firstName, lastName);
Expand Down
5 changes: 4 additions & 1 deletion sormas-api/src/main/resources/captions.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1873,7 +1873,7 @@ Person.districtName=District
Person.educationType=Education
Person.educationDetails=Details
Person.fathersName=Father's name
Person.namesOfGuardians=Names of guardians
Person.namesOfGuardians=Legal guardian's name
Person.gestationAgeAtBirth=Gestation age at birth (weeks)
Person.lastDisease=Last disease
Person.matchingCase=Matching case
Expand Down Expand Up @@ -1916,6 +1916,9 @@ Person.otherSalutation=Other salutation
Person.birthName=Birth name
Person.birthCountry=Country of birth
Person.citizenship=Citizenship
Person.hasGuardian=Person has a legal guardian (i.e. in case of minors or incapacitated persons)
Person.incapacitated=Incapacitated (i.e. person will have a legal guardian after 18)
Person.emancipated=Emancipated (i.e. person is under 18 and does not have a guardian by law)
personContactDetailOwner=Owner
personContactDetailOwnerName=Owner name
personContactDetailThisPerson=This person
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,15 @@ public class ConfigFacadeEjb implements ConfigFacade {
private static final String DOCUMENT_UPLOAD_SIZE_LIMIT_MB = "documentUploadSizeLimitMb";
public static final int DEFAULT_DOCUMENT_UPLOAD_SIZE_LIMIT_MB = 20;
public static final String IMPORT_FILE_SIZE_LIMIT_MB = "importFileSizeLimitMb";
public static final int DEFAULT_IMPOR_FILE_SIZE_LIMIT_MB = 20;
public static final int DEFAULT_IMPORT_FILE_SIZE_LIMIT_MB = 20;
public static final String NEGATIVE_COVID_TESTS_MAX_AGE_DAYS = "negativeCovidTestsMaxAgeDays";

public static final String MINIMUM_EMANCIPATED_AGE = "minimumEmancipatedAge";
public static final int DEFAULT_MINIMUM_EMANCIPATED_AGE = 14;

public static final String MINIMUM_ADULT_AGE = "minimumAdultAge";
public static final int DEFAULT_MINIMUM_ADULT_AGE = 18;

private final Logger logger = LoggerFactory.getLogger(getClass());

@Resource(lookup = "sormas/Properties")
Expand Down Expand Up @@ -826,7 +832,7 @@ public long getDocumentUploadSizeLimitMb() {

@Override
public long getImportFileSizeLimitMb() {
return getLong(IMPORT_FILE_SIZE_LIMIT_MB, DEFAULT_IMPOR_FILE_SIZE_LIMIT_MB);
return getLong(IMPORT_FILE_SIZE_LIMIT_MB, DEFAULT_IMPORT_FILE_SIZE_LIMIT_MB);
}

@Override
Expand All @@ -844,6 +850,16 @@ public Integer getNegaiveCovidTestsMaxAgeDays() {
return parseProperty(NEGATIVE_COVID_TESTS_MAX_AGE_DAYS, null, Integer::parseInt);
}

@Override
public long getMinimumEmancipatedAge() {
return getLong(MINIMUM_EMANCIPATED_AGE, DEFAULT_MINIMUM_EMANCIPATED_AGE);
}

@Override
public long getMinimumAdultAge() {
return getLong(MINIMUM_ADULT_AGE, DEFAULT_MINIMUM_ADULT_AGE);
}

@LocalBean
@Stateless
public static class ConfigFacadeEjbLocal extends ConfigFacadeEjb {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ public class Person extends AbstractDomainObject implements IsPerson, HasExterna
public static final String IMMUNIZATIONS = "immunizations";
public static final String ADDITIONAL_DETAILS = "additionalDetails";
public static final String TRAVEL_ENTRIES = "travelEntries";
public static final String IS_INCAPACITATED = "isIncapacitated";
public static final String IS_EMANCIPATED = "emancipated";

private String firstName;
private String lastName;
Expand Down Expand Up @@ -211,6 +213,9 @@ public class Person extends AbstractDomainObject implements IsPerson, HasExterna
private Country citizenship;
private String additionalDetails;

private boolean isIncapacitated;
private boolean emancipated;

private List<Case> cases = new ArrayList<>();
private List<Contact> contacts = new ArrayList<>();
private List<EventParticipant> eventParticipants = new ArrayList<>();
Expand Down Expand Up @@ -660,6 +665,24 @@ public void setHasCovidApp(boolean hasCovidApp) {
this.hasCovidApp = hasCovidApp;
}

@Column
public boolean isIncapacitated() {
return isIncapacitated;
}

public void setIncapacitated(boolean incapacitated) {
isIncapacitated = incapacitated;
}

@Column
public boolean isEmancipated() {
return emancipated;
}

public void setEmancipated(boolean emancipated) {
this.emancipated = emancipated;
}

@Column
public boolean isCovidCodeDelivered() {
return covidCodeDelivered;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1030,6 +1030,8 @@ public static PersonDto toPersonDto(Person source) {
target.setBirthCountry(CountryFacadeEjb.toReferenceDto(source.getBirthCountry()));
target.setCitizenship(CountryFacadeEjb.toReferenceDto(source.getCitizenship()));
target.setAdditionalDetails(source.getAdditionalDetails());
target.setIncapacitated(source.isIncapacitated());
target.setEmancipated(source.isEmancipated());

return target;
}
Expand Down Expand Up @@ -1799,6 +1801,8 @@ public Person fillOrBuildEntity(@NotNull PersonDto source, Person target, boolea
target.setBirthCountry(countryService.getByReferenceDto(source.getBirthCountry()));
target.setCitizenship(countryService.getByReferenceDto(source.getCitizenship()));
target.setAdditionalDetails(source.getAdditionalDetails());
target.setIncapacitated(source.isIncapacitated());
target.setEmancipated(source.isEmancipated());

return target;
}
Expand Down
8 changes: 8 additions & 0 deletions sormas-backend/src/main/resources/sql/sormas_schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -13810,3 +13810,11 @@ INSERT INTO userroles_userrights (userrole_id, userright) SELECT id, 'SURVEY_TOK

INSERT INTO schema_version (version_number, comment) VALUES (557, 'Create Survey Tokens data structure #13250');
-- *** Insert new sql commands BEFORE this line. Remember to always consider _history tables. ***

-- 2025-01-10 Add information about legal guardian for "minor / incapacitated" to person entity #13205
ALTER TABLE person ADD column incapacitated boolean default false;
ALTER TABLE person ADD column emancipated boolean default false;
ALTER TABLE person_history ADD COLUMN incapacitated boolean default false;
ALTER TABLE person_history ADD COLUMN emancipated boolean default false;

INSERT INTO schema_version (version_number, comment) VALUES (558, 'Add information about legal guardian for "minor / incapacitated" to person entity #13205');
8 changes: 8 additions & 0 deletions sormas-base/setup/sormas.properties
Original file line number Diff line number Diff line change
Expand Up @@ -426,3 +426,11 @@ app.url=
# A list of allowed file types to be uploaded
# Default: .pdf,.txt,.doc,.docx,.odt,.xls,.xlsx,.ods,.ppt,.pptx,.odp,.jpg,.jpeg,.png,.gif,.msg,.html
#allowed.file.extensions=.pdf,.txt,.doc,.docx,.odt,.xls,.xlsx,.ods,.ppt,.pptx,.odp,.jpg,.jpeg,.png,.gif,.msg,.html

# Minimum emancipated age
# Default: 14 Years
#minimumEmancipatedAge = 14

# Minimum adult age
# Default: 18 Years
#minimumAdultAge = 18
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import static de.symeda.sormas.ui.utils.CssStyles.H3;
import static de.symeda.sormas.ui.utils.CssStyles.LABEL_WHITE_SPACE_NORMAL;
import static de.symeda.sormas.ui.utils.CssStyles.LAYOUT_COL_HIDE_INVSIBLE;
import static de.symeda.sormas.ui.utils.CssStyles.VSPACE_3;
import static de.symeda.sormas.ui.utils.LayoutUtil.divsCss;
import static de.symeda.sormas.ui.utils.LayoutUtil.fluidColumnLocCss;
Expand All @@ -36,6 +37,8 @@
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

import com.vaadin.v7.ui.CheckBox;
import de.symeda.sormas.ui.utils.LayoutUtil;
import org.apache.commons.lang3.StringUtils;

import com.vaadin.shared.ui.ErrorLevel;
Expand Down Expand Up @@ -110,6 +113,7 @@ public class PersonEditForm extends AbstractEditForm<PersonDto> {
private static final String EXTERNAL_TOKEN_WARNING_LOC = "externalTokenWarningLoc";
private static final String NATIONAL_HEALTH_ID_WARNING_LABEL = "nationalHealthIdWarningLoc";
private static final String GENERAL_COMMENT_LOC = "generalCommentLoc";
public static final String HAS_GUARDIAN = "hasGuardian";
//@formatter:off
private static final String HTML_LAYOUT =
loc(PERSON_INFORMATION_HEADING_LOC) +
Expand Down Expand Up @@ -165,6 +169,11 @@ public class PersonEditForm extends AbstractEditForm<PersonDto> {
fluidRowLocs(PersonDto.BIRTH_NAME, "") +
fluidRowLocs(PersonDto.NICKNAME, PersonDto.MOTHERS_MAIDEN_NAME) +
fluidRowLocs(PersonDto.MOTHERS_NAME, PersonDto.FATHERS_NAME) +
LayoutUtil.fluidRowLocs(PersonDto.IS_EMANCIPATED) +
LayoutUtil.fluidRowLocs(PersonDto.IS_INCAPACITATED) +
LayoutUtil.fluidRowLocs(HAS_GUARDIAN) +
LayoutUtil.fluidRow(
LayoutUtil.fluidColumnLocCss(LAYOUT_COL_HIDE_INVSIBLE, 6, 0, PersonDto.NAMES_OF_GUARDIANS)) +
fluidRowLocs(PersonDto.NAMES_OF_GUARDIANS) +
fluidRowLocs(PersonDto.BIRTH_COUNTRY, PersonDto.CITIZENSHIP) +
fluidRowLocs(PersonDto.PERSON_CONTACT_DETAILS)) +
Expand All @@ -189,6 +198,12 @@ public class PersonEditForm extends AbstractEditForm<PersonDto> {
private PresentConditionChangeListener presentConditionChangeListener;
private SormasTextField nationalHealthIdField;
private Window warningSimilarPersons;
private CheckBox isEmancipated;
private CheckBox isIncapacitated;
private CheckBox hasGuardian;
private TextField nameOfGuardians;
private long minimumAdultAge;
private long minimumEmancipatedAge;
//@formatter:on

public PersonEditForm(
Expand Down Expand Up @@ -291,7 +306,7 @@ protected void addFields() {
addField(PersonDto.NICKNAME, TextField.class);
addField(PersonDto.MOTHERS_MAIDEN_NAME, TextField.class);
addFields(PersonDto.MOTHERS_NAME, PersonDto.FATHERS_NAME);
addFields(PersonDto.NAMES_OF_GUARDIANS);
nameOfGuardians = addField(PersonDto.NAMES_OF_GUARDIANS, TextField.class);
ComboBox presentCondition = addField(PersonDto.PRESENT_CONDITION, ComboBox.class);
birthDateDay = addField(PersonDto.BIRTH_DATE_DD, ComboBox.class);
// @TODO: Done for nullselection Bug, fixed in Vaadin 7.7.3
Expand Down Expand Up @@ -504,6 +519,7 @@ protected void addFields() {
addFieldListeners(PersonDto.BIRTH_DATE_YYYY, e -> {
updateApproximateAge();
updateReadyOnlyApproximateAge();
updateIsIncapacitatedCheckBox(false);
});

addFieldListeners(PersonDto.DEATH_DATE, e -> updateApproximateAge());
Expand Down Expand Up @@ -631,6 +647,89 @@ protected void addFields() {
I18nProperties.getPrefixDescription(PersonDto.I18N_PREFIX, PersonDto.ADDITIONAL_DETAILS, "") + "\n"
+ I18nProperties.getDescription(Descriptions.descGdpr));
CssStyles.style(additionalDetails, CssStyles.CAPTION_HIDDEN);

hasGuardian = addCustomField(HAS_GUARDIAN, Boolean.class, CheckBox.class);

isIncapacitated = addField(PersonDto.IS_INCAPACITATED, CheckBox.class);
isIncapacitated.addValueChangeListener(e -> updateIsIncapacitatedCheckBox(true));

isEmancipated = addField(PersonDto.IS_EMANCIPATED, CheckBox.class);
isEmancipated.addValueChangeListener(e -> onEmancipatedChange());
hasGuardian.setEnabled(false);
minimumAdultAge = FacadeProvider.getConfigFacade().getMinimumAdultAge();//2 places
minimumEmancipatedAge = FacadeProvider.getConfigFacade().getMinimumEmancipatedAge();
}

private int getApproximateAgeInYears() {
Date birthDate = calcBirthDateValue();
if (birthDate != null) {
Pair<Integer, ApproximateAgeType> pair =
ApproximateAgeHelper.getApproximateAge(birthDate, (Date) getFieldGroup().getField(PersonDto.DEATH_DATE).getValue());
if ((pair.getElement0() != null) && (pair.getElement1() == ApproximateAgeType.YEARS)) {
return pair.getElement0();
}
}
return -1;
}

private void onEmancipatedChange() {
boolean isEmancipatedChecked = (isEmancipated != null) && (isEmancipated.getValue());
hasGuardian.setValue(!isEmancipatedChecked);
if(isEmancipatedChecked) {
nameOfGuardians.setValue("");
}
updateHasGuardianCheckBox();
}

private void updateIsIncapacitatedCheckBox(boolean isInitialized) {
boolean isIncapacitatedChecked = (isIncapacitated == null) || (isIncapacitated.getValue());
int approximateAge = getApproximateAgeInYears();
boolean canBeEmancipated;
if(approximateAge == -1) {
canBeEmancipated = false;
} else {
canBeEmancipated = approximateAge >= minimumEmancipatedAge && approximateAge < minimumAdultAge;
}
isEmancipated.setVisible(!isIncapacitatedChecked && canBeEmancipated);
hasGuardian.setValue(isIncapacitatedChecked || approximateAge < minimumAdultAge);
if(getApproximateAgeInYears() < minimumAdultAge) {
nameOfGuardians.setValue(getValue().getNamesOfGuardians());
}
updateHasGuardianCheckBox();
hardResetNameOfGuardians(isInitialized);
}

private void hardResetNameOfGuardians(boolean isInitialized) {
boolean isIncapacitatedChecked = (isIncapacitated != null) && (isIncapacitated.getValue());
if (getApproximateAgeInYears() != -1 && getApproximateAgeInYears() >= minimumAdultAge && !isIncapacitatedChecked && isInitialized) {
nameOfGuardians.setValue("");
}
}

private void updateHasGuardianCheckBox() {
boolean isIncapacitatedChecked = (isIncapacitated != null) && (isIncapacitated.getValue());
boolean isEmancipatedChecked = (isEmancipated != null) && (isEmancipated.getValue());
if((getApproximateAgeInYears() >= minimumAdultAge || (getApproximateAgeInYears() < minimumEmancipatedAge) && isEmancipatedChecked)) {
isEmancipatedChecked = false;
isEmancipated.setValue(Boolean.FALSE);
isIncapacitated.setVisible(true);
}
if(isEmancipatedChecked){
hasGuardian.setVisible(false);
nameOfGuardians.setVisible(false);
isIncapacitated.setVisible(false);
return;
} else {
isIncapacitated.setVisible(true);
hasGuardian.setValue(Boolean.TRUE);
}
Date birthDate = calcBirthDateValue();
boolean isChildOrUnknownDate = getApproximateAgeInYears() < minimumAdultAge;
nameOfGuardians.setVisible(isChildOrUnknownDate || isIncapacitatedChecked);
hasGuardian.setVisible(isChildOrUnknownDate || isIncapacitatedChecked);
if((birthDate == null) || isChildOrUnknownDate ){
hasGuardian.setValue(Boolean.TRUE);
}
}

@Override
Expand Down

0 comments on commit b757fb9

Please sign in to comment.