diff --git a/package.json b/package.json index 3395e11..209a580 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "type": "module", "dependencies": { "@f0rce/ace-widget": "1.0.2", - "@polymer/polymer": "3.5.1", + "@polymer/polymer": "3.5.2", "@vaadin-component-factory/vcf-pdf-viewer": "2.0.1", "@vaadin/bundles": "24.5.1", "@vaadin/common-frontend": "0.0.19", @@ -19,29 +19,30 @@ "@vaadin/vaadin-usage-statistics": "2.1.3", "construct-style-sheets-polyfill": "3.1.0", "date-fns": "2.29.3", - "lit": "3.1.4", + "lit": "3.2.1", "print-js": "1.6.0", "proj4": "2.12.1", "react": "18.3.1", "react-dom": "18.3.1", - "react-router-dom": "6.23.1" + "react-router-dom": "6.26.2" }, "devDependencies": { - "@babel/preset-react": "7.24.7", - "@rollup/plugin-replace": "5.0.7", - "@rollup/pluginutils": "5.1.0", - "@types/react": "18.3.3", - "@types/react-dom": "18.3.0", - "@vitejs/plugin-react": "4.3.1", - "async": "3.2.5", - "glob": "10.4.1", + "@babel/preset-react": "7.25.7", + "@preact/signals-react-transform": "0.4.0", + "@rollup/plugin-replace": "6.0.1", + "@rollup/pluginutils": "5.1.2", + "@types/react": "18.3.11", + "@types/react-dom": "18.3.1", + "@vitejs/plugin-react": "4.3.3", + "async": "3.2.6", + "glob": "10.4.5", "rollup-plugin-brotli": "3.1.0", "rollup-plugin-visualizer": "5.12.0", "strip-css-comments": "5.0.0", "transform-ast": "2.4.4", - "typescript": "5.4.5", - "vite": "5.3.3", - "vite-plugin-checker": "0.6.4", + "typescript": "5.6.3", + "vite": "5.4.9", + "vite-plugin-checker": "0.8.0", "workbox-build": "7.1.1", "workbox-core": "7.1.0", "workbox-precaching": "7.1.0" @@ -49,7 +50,7 @@ "vaadin": { "dependencies": { "@f0rce/ace-widget": "1.0.2", - "@polymer/polymer": "3.5.1", + "@polymer/polymer": "3.5.2", "@vaadin-component-factory/vcf-pdf-viewer": "2.0.1", "@vaadin/bundles": "24.5.1", "@vaadin/common-frontend": "0.0.19", @@ -64,34 +65,35 @@ "@vaadin/vaadin-usage-statistics": "2.1.3", "construct-style-sheets-polyfill": "3.1.0", "date-fns": "2.29.3", - "lit": "3.1.4", + "lit": "3.2.1", "print-js": "1.6.0", "proj4": "2.12.1", "react": "18.3.1", "react-dom": "18.3.1", - "react-router-dom": "6.23.1" + "react-router-dom": "6.26.2" }, "devDependencies": { - "@babel/preset-react": "7.24.7", - "@rollup/plugin-replace": "5.0.7", - "@rollup/pluginutils": "5.1.0", - "@types/react": "18.3.3", - "@types/react-dom": "18.3.0", - "@vitejs/plugin-react": "4.3.1", - "async": "3.2.5", - "glob": "10.4.1", + "@babel/preset-react": "7.25.7", + "@preact/signals-react-transform": "0.4.0", + "@rollup/plugin-replace": "6.0.1", + "@rollup/pluginutils": "5.1.2", + "@types/react": "18.3.11", + "@types/react-dom": "18.3.1", + "@vitejs/plugin-react": "4.3.3", + "async": "3.2.6", + "glob": "10.4.5", "rollup-plugin-brotli": "3.1.0", "rollup-plugin-visualizer": "5.12.0", "strip-css-comments": "5.0.0", "transform-ast": "2.4.4", - "typescript": "5.4.5", - "vite": "5.3.3", - "vite-plugin-checker": "0.6.4", + "typescript": "5.6.3", + "vite": "5.4.9", + "vite-plugin-checker": "0.8.0", "workbox-build": "7.1.1", "workbox-core": "7.1.0", "workbox-precaching": "7.1.0" }, - "hash": "1a0f17d48b329307b5862bc57499307d1b89f7d89260121c2b7189f76957c436" + "hash": "2dc40a4f634ae025081ca2239cba00b14a35fe94ab78ac0a4dd3023d882081d5" }, "overrides": { "@vaadin/bundles": "$@vaadin/bundles", diff --git a/src/main/java/com/primefactorsolutions/model/Employee.java b/src/main/java/com/primefactorsolutions/model/Employee.java index bc83005..83b9d42 100644 --- a/src/main/java/com/primefactorsolutions/model/Employee.java +++ b/src/main/java/com/primefactorsolutions/model/Employee.java @@ -27,6 +27,7 @@ public class Employee extends BaseEntity implements UserDetails { @NotNull(message = "El apellido no puede estar vacío") @Pattern(regexp = "^[a-zA-Z ]+$", message = "El apellido solo debe contener letras") private String lastName; + @MinAge(18) private LocalDate birthday; @Pattern(regexp = "^[a-zA-Z ,]+$", message = "La ciudad de nacimiento solo debe contener letras, espacios o comas") private String birthCity; diff --git a/src/main/java/com/primefactorsolutions/model/MinAge.java b/src/main/java/com/primefactorsolutions/model/MinAge.java new file mode 100644 index 0000000..41ad740 --- /dev/null +++ b/src/main/java/com/primefactorsolutions/model/MinAge.java @@ -0,0 +1,17 @@ +package com.primefactorsolutions.model; + +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + +import java.lang.annotation.*; + +@Documented +@Constraint(validatedBy = MinAgeValidator.class) +@Target({ ElementType.FIELD }) +@Retention(RetentionPolicy.RUNTIME) +public @interface MinAge { + String message() default "El empleado debe ser mayor de {value} años"; + Class[] groups() default {}; + Class[] payload() default {}; + int value(); +} diff --git a/src/main/java/com/primefactorsolutions/model/MinAgeValidator.java b/src/main/java/com/primefactorsolutions/model/MinAgeValidator.java new file mode 100644 index 0000000..980967a --- /dev/null +++ b/src/main/java/com/primefactorsolutions/model/MinAgeValidator.java @@ -0,0 +1,24 @@ +package com.primefactorsolutions.model; + +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; + +import java.time.LocalDate; +import java.time.temporal.ChronoUnit; + +public class MinAgeValidator implements ConstraintValidator { + private int minAge; + + @Override + public void initialize(MinAge constraintAnnotation) { + this.minAge = constraintAnnotation.value(); + } + + @Override + public boolean isValid(LocalDate birthday, ConstraintValidatorContext context) { + if (birthday == null) { + return true; + } + return ChronoUnit.YEARS.between(birthday, LocalDate.now()) >= minAge; + } +} diff --git a/src/main/java/com/primefactorsolutions/views/EmployeeView.java b/src/main/java/com/primefactorsolutions/views/EmployeeView.java index 642ef2f..fe3ca60 100644 --- a/src/main/java/com/primefactorsolutions/views/EmployeeView.java +++ b/src/main/java/com/primefactorsolutions/views/EmployeeView.java @@ -178,7 +178,17 @@ public class EmployeeView extends BeanValidationForm implements HasUrl editButton.setVisible(true); reportButton.setVisible(true); birthday.addValueChangeListener(event -> calculateAge()); - birthday.setMax(java.time.LocalDate.now().minusYears(18)); + birthday.setMin(LocalDate.now().minusYears(100)); + birthday.setMax(LocalDate.now().minusYears(18)); + birthday.addValueChangeListener(event -> { + LocalDate selectedDate = event.getValue(); + if (selectedDate != null && ChronoUnit.YEARS.between(selectedDate, LocalDate.now()) < 18) { + birthday.setInvalid(true); + birthday.setErrorMessage("El empleado debe ser mayor de 18 años"); + } else { + birthday.setInvalid(false); + } + }); salaryTotal.addValueChangeListener(event -> calculateSalaryTotal()); dateOfEntry.addValueChangeListener(event -> calculateSeniority()); dateOfExit.addValueChangeListener(event -> { @@ -478,7 +488,7 @@ public class EmployeeView extends BeanValidationForm implements HasUrl editButton.setVisible(false); setFieldsEditable(); upload.setVisible(true); - salaryTotal.setValue(String.valueOf(true)); + salaryTotal.setValue(String.valueOf(0.0)); } else { UUID employeeId = UUID.fromString(s); var employee = employeeService.getEmployee(employeeId);