mejorar-detalles #77

Open
melina.gutierrez wants to merge 6 commits from mejorar-detalles into main
8 changed files with 336 additions and 180 deletions

View File

@ -4,7 +4,7 @@
"type": "module", "type": "module",
"dependencies": { "dependencies": {
"@f0rce/ace-widget": "1.0.2", "@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-component-factory/vcf-pdf-viewer": "2.0.1",
"@vaadin/bundles": "24.5.1", "@vaadin/bundles": "24.5.1",
"@vaadin/common-frontend": "0.0.19", "@vaadin/common-frontend": "0.0.19",
@ -19,29 +19,30 @@
"@vaadin/vaadin-usage-statistics": "2.1.3", "@vaadin/vaadin-usage-statistics": "2.1.3",
"construct-style-sheets-polyfill": "3.1.0", "construct-style-sheets-polyfill": "3.1.0",
"date-fns": "2.29.3", "date-fns": "2.29.3",
"lit": "3.1.4", "lit": "3.2.1",
"print-js": "1.6.0", "print-js": "1.6.0",
"proj4": "2.12.1", "proj4": "2.12.1",
"react": "18.3.1", "react": "18.3.1",
"react-dom": "18.3.1", "react-dom": "18.3.1",
"react-router-dom": "6.23.1" "react-router-dom": "6.26.2"
}, },
"devDependencies": { "devDependencies": {
"@babel/preset-react": "7.24.7", "@babel/preset-react": "7.25.7",
"@rollup/plugin-replace": "5.0.7", "@preact/signals-react-transform": "0.4.0",
"@rollup/pluginutils": "5.1.0", "@rollup/plugin-replace": "6.0.1",
"@types/react": "18.3.3", "@rollup/pluginutils": "5.1.2",
"@types/react-dom": "18.3.0", "@types/react": "18.3.11",
"@vitejs/plugin-react": "4.3.1", "@types/react-dom": "18.3.1",
"async": "3.2.5", "@vitejs/plugin-react": "4.3.3",
"glob": "10.4.1", "async": "3.2.6",
"glob": "10.4.5",
"rollup-plugin-brotli": "3.1.0", "rollup-plugin-brotli": "3.1.0",
"rollup-plugin-visualizer": "5.12.0", "rollup-plugin-visualizer": "5.12.0",
"strip-css-comments": "5.0.0", "strip-css-comments": "5.0.0",
"transform-ast": "2.4.4", "transform-ast": "2.4.4",
"typescript": "5.4.5", "typescript": "5.6.3",
"vite": "5.3.3", "vite": "5.4.9",
"vite-plugin-checker": "0.6.4", "vite-plugin-checker": "0.8.0",
"workbox-build": "7.1.1", "workbox-build": "7.1.1",
"workbox-core": "7.1.0", "workbox-core": "7.1.0",
"workbox-precaching": "7.1.0" "workbox-precaching": "7.1.0"
@ -49,7 +50,7 @@
"vaadin": { "vaadin": {
"dependencies": { "dependencies": {
"@f0rce/ace-widget": "1.0.2", "@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-component-factory/vcf-pdf-viewer": "2.0.1",
"@vaadin/bundles": "24.5.1", "@vaadin/bundles": "24.5.1",
"@vaadin/common-frontend": "0.0.19", "@vaadin/common-frontend": "0.0.19",
@ -64,34 +65,35 @@
"@vaadin/vaadin-usage-statistics": "2.1.3", "@vaadin/vaadin-usage-statistics": "2.1.3",
"construct-style-sheets-polyfill": "3.1.0", "construct-style-sheets-polyfill": "3.1.0",
"date-fns": "2.29.3", "date-fns": "2.29.3",
"lit": "3.1.4", "lit": "3.2.1",
"print-js": "1.6.0", "print-js": "1.6.0",
"proj4": "2.12.1", "proj4": "2.12.1",
"react": "18.3.1", "react": "18.3.1",
"react-dom": "18.3.1", "react-dom": "18.3.1",
"react-router-dom": "6.23.1" "react-router-dom": "6.26.2"
}, },
"devDependencies": { "devDependencies": {
"@babel/preset-react": "7.24.7", "@babel/preset-react": "7.25.7",
"@rollup/plugin-replace": "5.0.7", "@preact/signals-react-transform": "0.4.0",
"@rollup/pluginutils": "5.1.0", "@rollup/plugin-replace": "6.0.1",
"@types/react": "18.3.3", "@rollup/pluginutils": "5.1.2",
"@types/react-dom": "18.3.0", "@types/react": "18.3.11",
"@vitejs/plugin-react": "4.3.1", "@types/react-dom": "18.3.1",
"async": "3.2.5", "@vitejs/plugin-react": "4.3.3",
"glob": "10.4.1", "async": "3.2.6",
"glob": "10.4.5",
"rollup-plugin-brotli": "3.1.0", "rollup-plugin-brotli": "3.1.0",
"rollup-plugin-visualizer": "5.12.0", "rollup-plugin-visualizer": "5.12.0",
"strip-css-comments": "5.0.0", "strip-css-comments": "5.0.0",
"transform-ast": "2.4.4", "transform-ast": "2.4.4",
"typescript": "5.4.5", "typescript": "5.6.3",
"vite": "5.3.3", "vite": "5.4.9",
"vite-plugin-checker": "0.6.4", "vite-plugin-checker": "0.8.0",
"workbox-build": "7.1.1", "workbox-build": "7.1.1",
"workbox-core": "7.1.0", "workbox-core": "7.1.0",
"workbox-precaching": "7.1.0" "workbox-precaching": "7.1.0"
}, },
"hash": "1a0f17d48b329307b5862bc57499307d1b89f7d89260121c2b7189f76957c436" "hash": "2dc40a4f634ae025081ca2239cba00b14a35fe94ab78ac0a4dd3023d882081d5"
}, },
"overrides": { "overrides": {
"@vaadin/bundles": "$@vaadin/bundles", "@vaadin/bundles": "$@vaadin/bundles",

View File

@ -40,6 +40,10 @@ public class Employee extends BaseEntity implements UserDetails {
private String phoneNumber; private String phoneNumber;
@Email(message = "El correo personal no tiene un formato válido") @Email(message = "El correo personal no tiene un formato válido")
private String personalEmail; private String personalEmail;
@Pattern(regexp = "^[0-9]+$", message = "El número de teléfono debe contener solo números")
private String phoneNumberProfesional;
@Email(message = "El correo profesional no tiene un formato válido")
private String profesionalEmail;
@Pattern(regexp = "^[a-zA-Z ]+$", message = "El cargo solo debe contener letras") @Pattern(regexp = "^[a-zA-Z ]+$", message = "El cargo solo debe contener letras")
private String position; private String position;
@ -56,12 +60,8 @@ public class Employee extends BaseEntity implements UserDetails {
private String emergencyCPhone; private String emergencyCPhone;
@Email(message = "El correo de contacto de emergencia no tiene un formato válido") @Email(message = "El correo de contacto de emergencia no tiene un formato válido")
private String emergencyCEmail; private String emergencyCEmail;
@Max(value = 10, message = "El número de hijos no puede exceder a 10")
@Pattern(regexp = "^[0-9]+$", message = "La cantidad de hijos debe contener solo números")
private String numberOfChildren; private String numberOfChildren;
@Pattern(regexp = "^[a-zA-Z0-9]+$", message = "El CI debe contener solo letras y números")
@Pattern(regexp = "^[0-9]+$", message = "El CI debe contener solo números")
private String ci; private String ci;
private String issuedIn; private String issuedIn;
private String pTitle1; private String pTitle1;
@ -79,23 +79,24 @@ public class Employee extends BaseEntity implements UserDetails {
private String recognition; private String recognition;
private String achievements; private String achievements;
private String language; private String language1;
private String languageLevel; private String language1Level;
private String language2;
private String language2Level;
@Pattern(regexp = "^[A-Za-z0-9]+$", message = "El código debe contener solo letras y números") @Pattern(regexp = "^[A-Za-z0-9]+$", message = "El código debe contener solo letras y números")
private String cod; private String cod;
@Pattern(regexp = "^[a-zA-Z ]+$", message = "El lead manager solo debe contener letras") @Pattern(regexp = "^[a-zA-Z ]+$", message = "El lead manager solo debe contener letras")
private String leadManager; private String leadManager;
@Pattern(regexp = "^[a-zA-Z ]+$", message = "El proyecto solo debe contener letras")
private String project;
private LocalDate dateOfEntry; private LocalDate dateOfEntry;
private LocalDate dateOfExit; private LocalDate dateOfExit;
@Pattern(regexp = "^[a-zA-Z ]+$", message = "El tipo de contrato solo debe contener letras")
private String contractType;
@Pattern(regexp = "^[0-9]+$", message = "La antigüedad debe contener solo números")
private String seniority; private String seniority;
@Pattern(regexp = "^[0-9]+(\\.[0-9]{1,2})?$", message = "El salario debe ser un número con hasta dos decimales") @Pattern(regexp = "^[0-9]+(\\.[0-9]{1,2})?$", message = "El salario debe ser un número con hasta dos decimales")
private String salary; private String salarytotal;
private String salaryBasic;
private String bonoProfesional;
private String antiguedad;
@Pattern(regexp = "^[a-zA-Z ]+$", message = "El nombre del banco solo debe contener letras") @Pattern(regexp = "^[a-zA-Z ]+$", message = "El nombre del banco solo debe contener letras")
private String bankName; private String bankName;
@Pattern(regexp = "^[0-9]+$", message = "El número de cuenta debe contener solo números") @Pattern(regexp = "^[0-9]+$", message = "El número de cuenta debe contener solo números")
@ -104,8 +105,9 @@ public class Employee extends BaseEntity implements UserDetails {
private String gpss; private String gpss;
private String sss; private String sss;
@Pattern(regexp = "^[a-zA-Z ]+$", message = "Los derechohabientes solo deben contener letras") @Pattern(regexp = "^[a-zA-Z ]+$", message = "Los derechohabientes solo deben contener letras")
private String beneficiaries; private String beneficiarie1;
@Pattern(regexp = "^[a-zA-Z ]+$", message = "Los derechohabientes solo deben contener letras")
private String beneficiarie2;
@Column(columnDefinition = "TEXT") @Column(columnDefinition = "TEXT")
private String profileImage; private String profileImage;
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
@ -168,4 +170,20 @@ public class Employee extends BaseEntity implements UserDetails {
MALE, MALE,
FEMALE FEMALE
} }
}
@Enumerated(EnumType.STRING)
private ContractType contractType;
public enum ContractType {
CONTRATO_LABORAL,
CONTRATO_CIVIL_O_SERVICIOS,
CONTRATO_PLAZO_FIJO,
CONSULTORIA_INTERNA,
CONSULTORIA_EXTERNA,
MIXTO,
OTROS
}
@Size(max = 255, message = "El detalle del contrato no debe exceder 255 caracteres")
private String otherContractDetail;
}

View File

@ -28,15 +28,24 @@ public class HoursWorked extends BaseEntity {
private int weekNumber; private int weekNumber;
private LocalDate date; private LocalDate date;
private String actividad; private String actividad;
private String tareasEspecificas;
private double hours; private double hours;
private double horasTareasEspecificas;
private double horaspendientes; private double horaspendientes;
private double totalHours; private double totalHours;
private String tareaEspecifica;
public String getTareaEspecifica() {
return tareaEspecifica;
}
public void setTareaEspecifica(final String tareaEspecifica) {
this.tareaEspecifica = tareaEspecifica;
}
public static double calculateTotalHours(final List<HoursWorked> activities) { public static double calculateTotalHours(final List<HoursWorked> activities) {
return activities.stream() return activities.stream()
.mapToDouble(activity -> activity.hours + activity.horasTareasEspecificas) .mapToDouble(activity -> activity.hours)
.sum(); .sum();
} }
@ -105,21 +114,6 @@ public class HoursWorked extends BaseEntity {
this.team = team; this.team = team;
} }
public String getTareasEspecificas() {
return tareasEspecificas;
}
public void setTareasEspecificas(final String tareasEspecificas) {
this.tareasEspecificas = tareasEspecificas;
}
public double getHorasTareasEspecificas() {
return horasTareasEspecificas;
}
public void setHorasTareasEspecificas(final double horasTareasEspecificas) {
this.tareasEspecificas = tareasEspecificas;
}
public double getHoraspendientes() { public double getHoraspendientes() {
//double horasTrabajadas = this.getTotalHours() + this.getHorasTareasEspecificas(); //double horasTrabajadas = this.getTotalHours() + this.getHorasTareasEspecificas();
return 40; return 40;
@ -129,21 +123,4 @@ public class HoursWorked extends BaseEntity {
this.horaspendientes = horaspendientes; this.horaspendientes = horaspendientes;
} }
public double getHoursWorked() {
return hours;
}
public void setHoursWorked(final double hoursWorked) {
this.hours = hoursWorked;
}
public double getTotalHoursWorked() {
return totalHours;
}
public void setTotalHoursWorked(final double totalHoursWorked) {
this.totalHours = totalHoursWorked;
}
} }

View File

@ -11,7 +11,6 @@ public interface EmployeeRepository extends JpaRepository<Employee, UUID> {
Optional<Employee> findByUsername(String username); Optional<Employee> findByUsername(String username);
Optional<Employee> findByPersonalEmail(String personalEmail); Optional<Employee> findByPersonalEmail(String personalEmail);
Optional<Employee> findByTeamId(UUID teamId); Optional<Employee> findByTeamIdAndLeadManager(UUID teamId);
List<Employee> findByTeamName(String teamName); List<Employee> findByTeamName(String teamName);
} }

View File

@ -50,11 +50,12 @@ public class EmployeeService {
public String getTeamLeadName(final UUID teamId) { public String getTeamLeadName(final UUID teamId) {
// Encuentra al empleado con el rol de lead_manager en el equipo especificado // Encuentra al empleado con el rol de lead_manager en el equipo especificado
Optional<Employee> leadManager = employeeRepository.findByTeamId(teamId); Optional<Employee> leadManager = employeeRepository.findByTeamIdAndLeadManager(teamId);
return leadManager.map(employee -> employee.getFirstName() + " " + employee.getLastName()) return leadManager.map(employee -> employee.getFirstName() + " " + employee.getLastName())
.orElse("No asignado"); .orElse("No asignado");
} }
public List<Employee> findEmployees( public List<Employee> findEmployees(
final int start, final int pageSize, final String sortProperty, final boolean asc) { final int start, final int pageSize, final String sortProperty, final boolean asc) {
List<Employee> employees = employeeRepository.findAll(); List<Employee> employees = employeeRepository.findAll();

View File

@ -50,12 +50,10 @@ import java.util.UUID;
@PageTitle("Employee") @PageTitle("Employee")
@Route(value = "/employees/:employeeId?/:action?", layout = MainLayout.class) @Route(value = "/employees/:employeeId?/:action?", layout = MainLayout.class)
public class EmployeeView extends BeanValidationForm<Employee> implements HasUrlParameter<String> { public class EmployeeView extends BeanValidationForm<Employee> implements HasUrlParameter<String> {
private final EmployeeService employeeService; private final EmployeeService employeeService;
private final ReportService reportService; private final ReportService reportService;
private final TimeOffRequestService requestService; private final TimeOffRequestService requestService;
private final TeamService teamService; private final TeamService teamService;
// TODO: campo usado para registrar al empleado en LDAP. Este campo podria estar en otro form eventualmente. // TODO: campo usado para registrar al empleado en LDAP. Este campo podria estar en otro form eventualmente.
private final TextField username = createTextField("Username: ", 30, true); private final TextField username = createTextField("Username: ", 30, true);
private final TextField firstName = createTextField("Nombres: ", 30, true); private final TextField firstName = createTextField("Nombres: ", 30, true);
@ -70,21 +68,21 @@ public class EmployeeView extends BeanValidationForm<Employee> implements HasUrl
private final TextField localAddress = createTextField("Departamento y Provincia de Residencia " private final TextField localAddress = createTextField("Departamento y Provincia de Residencia "
+ " ejemplo: (Departamento-Provincia)", 30, false); + " ejemplo: (Departamento-Provincia)", 30, false);
private final ComboBox<Employee.MaritalStatus> maritalStatus = createMaritalStatusComboBox(); private final ComboBox<Employee.MaritalStatus> maritalStatus = createMaritalStatusComboBox();
private final TextField numberOfChildren = createTextField("Numero de Hijos", 2, false); private final TextField numberOfChildren = createTextField("Numero de Hijos", 1, false);
private final TextField ci = createTextField("CI", 10, false); private final TextField ci = createTextField("CI", 10, false);
private final TextField issuedIn = createTextField("Expedido en ", 10, false); private final TextField issuedIn = createTextField("Expedido en ", 10, false);
private final TextField phoneNumber = createTextField("Teléfono", 8, false); private final TextField phoneNumber = createTextField("Teléfono", 8, false);
private final EmailField personalEmail = createEmailField("E-mail ejemplo: (ejemplo@gmail.com)"); private final EmailField personalEmail = createEmailField("E-mail ejemplo: (ejemplo@gmail.com)");
private final TextField phoneNumberProfesional = createTextField("Teléfono Laboral", 8, false);
private final EmailField profesionalEmail = createEmailField("E-mail Laboral ejemplo: "
+ "(ejemplo@primerfactorsolutions.com)");
private final TextField emergencyCName = createTextField("Nombres y Apellidos de Contacto", 50, false); private final TextField emergencyCName = createTextField("Nombres y Apellidos de Contacto", 50, false);
private final TextField emergencyCAddress = createTextField("Dirección de Contacto", 50, false); private final TextField emergencyCAddress = createTextField("Dirección de Contacto", 50, false);
private final TextField emergencyCPhone = createTextField("Teléfono de Contacto", 8, false); private final TextField emergencyCPhone = createTextField("Teléfono de Contacto", 8, false);
private final EmailField emergencyCEmail = createEmailField("Email de Contacto ejemplo: (ejemplo@gmail.com)"); private final EmailField emergencyCEmail = createEmailField("Email de Contacto ejemplo: (ejemplo@gmail.com)");
private final MemoryBuffer buffer = new MemoryBuffer(); private final MemoryBuffer buffer = new MemoryBuffer();
private final Upload upload = new Upload(buffer); private final Upload upload = new Upload(buffer);
private final Image profileImagePreview = new Image(); private final Image profileImagePreview = new Image();
//INFORMACION PROFESIONAL
private final TextField pTitle1 = createTextField("Título 1", 30, false); private final TextField pTitle1 = createTextField("Título 1", 30, false);
private final TextField pTitle2 = createTextField("Título 2", 30, false); private final TextField pTitle2 = createTextField("Título 2", 30, false);
private final TextField pTitle3 = createTextField("Título 3", 30, false); private final TextField pTitle3 = createTextField("Título 3", 30, false);
@ -97,49 +95,46 @@ public class EmployeeView extends BeanValidationForm<Employee> implements HasUrl
private final TextField certification4 = createTextField("Certificación 4", 30, false); private final TextField certification4 = createTextField("Certificación 4", 30, false);
private final TextField recognition = createTextField("Reconocimientos", 30, false); private final TextField recognition = createTextField("Reconocimientos", 30, false);
private final TextField achievements = createTextField("Logros Profesionales", 30, false); private final TextField achievements = createTextField("Logros Profesionales", 30, false);
private final TextField language = createTextField("Idioma", 50, false); private final TextField language1 = createTextField("Idioma 1", 30, false);
private final TextField languageLevel = createTextField("Nivel de Idioma", 30, false); private final TextField language1Level = createTextField("Nivel de Idioma", 30, false);
private final TextField language2 = createTextField("Idioma 2", 30, false);
//INFORMACION ADMINISTRATIVA private final TextField language2Level = createTextField("Nivel de Idioma", 30, false);
private final TextField cod = createTextField("Codigo de Empleado", 20, false); private final TextField cod = createTextField("Codigo de Empleado", 20, false);
private final TextField position = createTextField("Cargo", 30, false); private final TextField position = createTextField("Cargo", 30, false);
private final ComboBox<Team> team = new ComboBox<>("Equipo"); private final ComboBox<Team> team = new ComboBox<>("Equipo");
private final TextField leadManager = createTextField("Lead/Manager", 30, false); private final TextField leadManager = createTextField("Lead/Manager", 30, false);
private final TextField project = createTextField("Proyecto", 30, false);
private final VDatePicker dateOfEntry = new VDatePicker("Fecha de Ingreso"); private final VDatePicker dateOfEntry = new VDatePicker("Fecha de Ingreso");
private final VDatePicker dateOfExit = new VDatePicker("Fecha de Retiro"); private final VDatePicker dateOfExit = new VDatePicker("Fecha de Retiro");
private final TextField contractType = createTextField("Tipo de Contratación", 30, false); private final ComboBox<Employee.ContractType> contractType = createContractTypeComboBox();
private final TextField seniority = createTextField("Antiguedad", 30, false); private final TextField seniority = createTextField("Antiguedad", 30, false);
private final TextField salary = createTextField("Salario", 30, false); private final TextField salaryTotal = createTextField("Salario Total", 10, false);
private final TextField salaryBasic = createTextField("Salario Basico", 10, false);
private final TextField antiguedad = createTextField("Descuento por Antiguedad", 10, false);
private final TextField bonoProfesional = createTextField("Bono Profesional", 30, false);
private final TextField bankName = createTextField("Banco", 30, false); private final TextField bankName = createTextField("Banco", 30, false);
private final TextField accountNumber = createTextField("Nro. de Cuenta", 30, false); private final TextField accountNumber = createTextField("Nro. de Cuenta", 30, false);
private final TextField gpss = createTextField("Código Único de Asegurado (GPSS)", 30, false); private final TextField gpss = createTextField("Código Único de Asegurado (GPSS)", 30, false);
private final TextField sss = createTextField("Matricula de Asegurado (SSS)", 30, false); private final TextField sss = createTextField("Matricula de Asegurado (SSS)", 30, false);
private final TextField beneficiaries = createTextField("Derechohabientes", 30, false); private final TextField beneficiarie1 = createTextField("Derechohabiente 1", 30, false);
private final TextField beneficiarie2 = createTextField("Derechohabiente 2", 30, false);
private static final String SAVE_BUTTON_TEXT = "Save"; private static final String SAVE_BUTTON_TEXT = "Save";
private static final String EDIT_BUTTON_TEXT = "Edit"; private static final String EDIT_BUTTON_TEXT = "Edit";
private static final String NOTIFICATION_SAVE_SUCCESS = "Employee saved successfully."; private static final String NOTIFICATION_SAVE_SUCCESS = "Employee saved successfully.";
private static final String NOTIFICATION_VALIDATE_ERROR = "Please complete the required fields correctly."; private static final String NOTIFICATION_VALIDATE_ERROR = "Please complete the required fields correctly.";
private static final String PHONE_NUMBER_ERROR_MESSAGE = "El teléfono debe contener solo números."; private static final String PHONE_NUMBER_ERROR_MESSAGE = "El teléfono debe contener solo números.";
private final Button saveButton = new Button(SAVE_BUTTON_TEXT, e -> saveEmployee()); private final Button saveButton = new Button(SAVE_BUTTON_TEXT, e -> saveEmployee());
private final Button editButton = new Button(EDIT_BUTTON_TEXT, e -> enableEditMode()); private final Button editButton = new Button(EDIT_BUTTON_TEXT, e -> enableEditMode());
private final Button reportButton = new Button("Generar Ficha"); private final Button reportButton = new Button("Generar Ficha");
private final Dialog dialog = new Dialog(); private final Dialog dialog = new Dialog();
private final PdfViewer pdfViewer = new PdfViewer(); private final PdfViewer pdfViewer = new PdfViewer();
//TITULOS PARA INFORMACION PERSONAL
private final H2 infoPer = new H2("Información Personal"); private final H2 infoPer = new H2("Información Personal");
private final H3 infoGenr = new H3("Información General"); private final H3 infoGenr = new H3("Información General");
private final H3 contEmerg = new H3("Contacto de Emergencia"); private final H3 contEmerg = new H3("Contacto de Emergencia");
//TITULOS PARA INFORMACIÓN PROFESIONAL
private final H2 infProf = new H2("Información Profesional"); private final H2 infProf = new H2("Información Profesional");
private final H3 titulos = new H3("Titulos Profesionales y Estudios Realizados"); private final H3 titulos = new H3("Titulos Profesionales y Estudios Realizados");
private final H3 certif = new H3("Certificaciones Profesionales"); private final H3 certif = new H3("Certificaciones Profesionales");
private final H3 logros = new H3("Otros Logros y Reconocimientos"); private final H3 logros = new H3("Otros Logros y Reconocimientos");
private final H3 idioma = new H3("Dominio de Idiomas"); private final H3 idioma = new H3("Dominio de Idiomas");
//TITULOS PARA INFORMACIÓN ADMINISTRATIVA
private final H2 infoAdm = new H2("Información Administrativa"); private final H2 infoAdm = new H2("Información Administrativa");
private final H3 infoCont = new H3("Información de Contratación"); private final H3 infoCont = new H3("Información de Contratación");
private final H3 datBanc = new H3("Datos Bancarios"); private final H3 datBanc = new H3("Datos Bancarios");
@ -155,32 +150,44 @@ public class EmployeeView extends BeanValidationForm<Employee> implements HasUrl
this.requestService = requestService; this.requestService = requestService;
this.teamService = teamService; this.teamService = teamService;
saveButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY); saveButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
configureComponents(); configureComponents();
addClassName("main-layout"); addClassName("main-layout");
} }
private void makeUpperCase(final TextField textField) {
textField.addValueChangeListener(event -> {
String value = event.getValue();
if (value != null) {
textField.setValue(value.toUpperCase());
}
});
}
private void configureComponents() { private void configureComponents() {
phoneNumber.setValueChangeMode(ValueChangeMode.EAGER); phoneNumber.setValueChangeMode(ValueChangeMode.EAGER);
phoneNumber.addValueChangeListener(e -> validatePhoneNumber(phoneNumber, e.getValue())); phoneNumber.addValueChangeListener(e -> validatePhoneNumber(phoneNumber, e.getValue()));
emergencyCPhone.setValueChangeMode(ValueChangeMode.EAGER); emergencyCPhone.setValueChangeMode(ValueChangeMode.EAGER);
emergencyCPhone.addValueChangeListener(e -> validatePhoneNumber(emergencyCPhone, e.getValue())); emergencyCPhone.addValueChangeListener(e -> validatePhoneNumber(emergencyCPhone, e.getValue()));
firstName.setValueChangeMode(ValueChangeMode.EAGER); firstName.setValueChangeMode(ValueChangeMode.EAGER);
firstName.addValueChangeListener(e -> validateNameField(firstName, e.getValue())); firstName.addValueChangeListener(e -> validateNameField(firstName, e.getValue()));
lastName.setValueChangeMode(ValueChangeMode.EAGER); lastName.setValueChangeMode(ValueChangeMode.EAGER);
lastName.addValueChangeListener(e -> validateNameField(lastName, e.getValue())); lastName.addValueChangeListener(e -> validateNameField(lastName, e.getValue()));
createTeamComboBox(); createTeamComboBox();
configureUpload(); configureUpload();
saveButton.setVisible(true); saveButton.setVisible(true);
editButton.setVisible(true); editButton.setVisible(true);
reportButton.setVisible(true); reportButton.setVisible(true);
birthday.addValueChangeListener(event -> calculateAge()); birthday.addValueChangeListener(event -> calculateAge());
birthday.setMax(java.time.LocalDate.now()); birthday.setMax(java.time.LocalDate.now().minusYears(18));
salaryTotal.addValueChangeListener(event -> calculateSalaryTotal());
dateOfEntry.addValueChangeListener(event -> calculateSeniority()); dateOfEntry.addValueChangeListener(event -> calculateSeniority());
dateOfEntry.addValueChangeListener(event -> calculateSeniority()); dateOfExit.addValueChangeListener(event -> {
if (event.getValue() != null) {
status.setValue(Employee.Status.INACTIVE);
} else {
status.setValue(Employee.Status.ACTIVE);
}
});
reportButton.addClickListener((ComponentEventListener<ClickEvent<Button>>) buttonClickEvent -> { reportButton.addClickListener((ComponentEventListener<ClickEvent<Button>>) buttonClickEvent -> {
var employee = getEntity(); var employee = getEntity();
byte[] pdfContent = reportService.writeAsPdf("ficha", employee); byte[] pdfContent = reportService.writeAsPdf("ficha", employee);
@ -189,6 +196,41 @@ public class EmployeeView extends BeanValidationForm<Employee> implements HasUrl
dialog.open(); dialog.open();
}); });
makeUpperCase(firstName);
makeUpperCase(lastName);
makeUpperCase(birthCity);
makeUpperCase(residenceAddress);
makeUpperCase(localAddress);
makeUpperCase(position);
makeUpperCase(emergencyCName);
makeUpperCase(emergencyCAddress);
makeUpperCase(ci);
makeUpperCase(issuedIn);
makeUpperCase(pTitle1);
makeUpperCase(pTitle2);
makeUpperCase(pTitle3);
makeUpperCase(pStudy1);
makeUpperCase(pStudy2);
makeUpperCase(pStudy3);
makeUpperCase(certification1);
makeUpperCase(certification2);
makeUpperCase(certification3);
makeUpperCase(certification4);
makeUpperCase(recognition);
makeUpperCase(achievements);
makeUpperCase(language1);
makeUpperCase(language1Level);
makeUpperCase(language2);
makeUpperCase(language2Level);
makeUpperCase(cod);
makeUpperCase(leadManager);
makeUpperCase(seniority);
makeUpperCase(bankName);
makeUpperCase(accountNumber);
makeUpperCase(gpss);
makeUpperCase(sss);
makeUpperCase(beneficiarie1);
makeUpperCase(beneficiarie2);
initDialog(); initDialog();
} }
@ -207,13 +249,7 @@ public class EmployeeView extends BeanValidationForm<Employee> implements HasUrl
int birthYear = birthday.getValue().getYear(); int birthYear = birthday.getValue().getYear();
int ages = currentYear - birthYear; int ages = currentYear - birthYear;
age.setValue(String.valueOf(ages)); age.setValue(String.valueOf(ages));
if (ages < 18) { birthday.setInvalid(ages < 18);
birthday.setInvalid(true);
birthday.setErrorMessage("La edad no puede ser menor a 18 años.");
Notification.show("La edad ingresada no es válida, debe ser mayor o igual a 18 años.");
} else {
birthday.setInvalid(false);
}
System.out.println(age); System.out.println(age);
} }
} }
@ -221,7 +257,6 @@ public class EmployeeView extends BeanValidationForm<Employee> implements HasUrl
private void calculateSeniority() { private void calculateSeniority() {
LocalDate entryDate = dateOfEntry.getValue(); LocalDate entryDate = dateOfEntry.getValue();
LocalDate exitDate = dateOfExit.getValue() != null ? dateOfExit.getValue() : LocalDate.now(); LocalDate exitDate = dateOfExit.getValue() != null ? dateOfExit.getValue() : LocalDate.now();
if (entryDate != null) { if (entryDate != null) {
long yearsOfService = ChronoUnit.YEARS.between(entryDate, exitDate); long yearsOfService = ChronoUnit.YEARS.between(entryDate, exitDate);
String seniorityValue = yearsOfService + " años "; String seniorityValue = yearsOfService + " años ";
@ -231,6 +266,44 @@ public class EmployeeView extends BeanValidationForm<Employee> implements HasUrl
} }
} }
private void calculateSalaryTotal() {
if (contractType.getValue() == Employee.ContractType.CONTRATO_LABORAL) {
salaryBasic.setVisible(true);
bonoProfesional.setVisible(true);
antiguedad.setVisible(true);
salaryTotal.setVisible(true);
salaryBasic.addValueChangeListener(event -> updateTotalSalary());
bonoProfesional.addValueChangeListener(event -> updateTotalSalary());
antiguedad.addValueChangeListener(event -> updateTotalSalary());
} else {
salaryBasic.setVisible(false);
bonoProfesional.setVisible(false);
antiguedad.setVisible(false);
salaryTotal.setVisible(true);
}
salaryTotal.getValue();
}
private void updateTotalSalary() {
try {
double basic = parseDoubleValue(salaryBasic.getValue());
double bonus = parseDoubleValue(bonoProfesional.getValue());
double seniorityBonus = parseDoubleValue(antiguedad.getValue());
double totalSalary = basic + bonus + seniorityBonus;
salaryTotal.setValue(String.valueOf(totalSalary));
} catch (Exception e) {
salaryTotal.setValue("0.0");
}
}
private double parseDoubleValue(final String value) {
try {
return value != null && !value.isEmpty() ? Double.parseDouble(value) : 0.0;
} catch (NumberFormatException e) {
return 0.0;
}
}
private void configureUpload() { private void configureUpload() {
upload.setAcceptedFileTypes("image/jpeg", "image/png"); upload.setAcceptedFileTypes("image/jpeg", "image/png");
upload.setMaxFileSize(1024 * 1024); upload.setMaxFileSize(1024 * 1024);
@ -239,9 +312,7 @@ public class EmployeeView extends BeanValidationForm<Employee> implements HasUrl
buffer.getInputStream().transferTo(outputStream); buffer.getInputStream().transferTo(outputStream);
byte[] imageBytes = outputStream.toByteArray(); byte[] imageBytes = outputStream.toByteArray();
String base64Image = Base64.getEncoder().encodeToString(imageBytes); String base64Image = Base64.getEncoder().encodeToString(imageBytes);
getEntity().setProfileImage(base64Image); getEntity().setProfileImage(base64Image);
profileImagePreview.setSrc("data:image/png;base64," + base64Image); profileImagePreview.setSrc("data:image/png;base64," + base64Image);
profileImagePreview.setMaxWidth("150px"); profileImagePreview.setMaxWidth("150px");
profileImagePreview.setMaxHeight("150px"); profileImagePreview.setMaxHeight("150px");
@ -266,11 +337,9 @@ public class EmployeeView extends BeanValidationForm<Employee> implements HasUrl
H2 headline = new H2("Ficha Empleado"); H2 headline = new H2("Ficha Empleado");
headline.getStyle().set("margin", "var(--lumo-space-m) 0 0 0") headline.getStyle().set("margin", "var(--lumo-space-m) 0 0 0")
.set("font-size", "1.5em").set("font-weight", "bold"); .set("font-size", "1.5em").set("font-weight", "bold");
final Button cancelDialogButton = new Button("Close", e -> dialog.close()); final Button cancelDialogButton = new Button("Close", e -> dialog.close());
final HorizontalLayout buttonLayout = new HorizontalLayout(cancelDialogButton); final HorizontalLayout buttonLayout = new HorizontalLayout(cancelDialogButton);
buttonLayout.setJustifyContentMode(FlexComponent.JustifyContentMode.END); buttonLayout.setJustifyContentMode(FlexComponent.JustifyContentMode.END);
final VerticalLayout dialogLayout = new VerticalLayout(headline, pdfViewer, buttonLayout); final VerticalLayout dialogLayout = new VerticalLayout(headline, pdfViewer, buttonLayout);
dialogLayout.getStyle().set("height", "100%"); dialogLayout.getStyle().set("height", "100%");
dialogLayout.getStyle().set("overflow", "hidden"); dialogLayout.getStyle().set("overflow", "hidden");
@ -280,7 +349,6 @@ public class EmployeeView extends BeanValidationForm<Employee> implements HasUrl
dialogLayout.setAlignItems(FlexComponent.Alignment.STRETCH); dialogLayout.setAlignItems(FlexComponent.Alignment.STRETCH);
dialogLayout.getStyle().set("width", "700px").set("max-width", "100%"); dialogLayout.getStyle().set("width", "700px").set("max-width", "100%");
dialogLayout.getStyle().set("height", "800px").set("max-height", "100%"); dialogLayout.getStyle().set("height", "800px").set("max-height", "100%");
dialog.add(dialogLayout); dialog.add(dialogLayout);
} }
@ -299,6 +367,16 @@ public class EmployeeView extends BeanValidationForm<Employee> implements HasUrl
return comboBox; return comboBox;
} }
private ComboBox<Employee.ContractType> createContractTypeComboBox() {
ComboBox<Employee.ContractType> comboBox = new ComboBox<>("Tipo de Contrato");
comboBox.setItems(Employee.ContractType.values());
comboBox.setItemLabelGenerator(Employee.ContractType::name);
comboBox.setRequiredIndicatorVisible(true);
comboBox.setWidth("300px");
comboBox.setMinWidth("200px");
return comboBox;
}
private VerticalLayout createContentLayout() { private VerticalLayout createContentLayout() {
VerticalLayout contentLayout = new VerticalLayout(); VerticalLayout contentLayout = new VerticalLayout();
contentLayout.setWidth("100%"); contentLayout.setWidth("100%");
@ -316,7 +394,7 @@ public class EmployeeView extends BeanValidationForm<Employee> implements HasUrl
private EmailField createEmailField(final String label) { private EmailField createEmailField(final String label) {
EmailField emailField = new EmailField(label); EmailField emailField = new EmailField(label);
emailField.setWidthFull(); emailField.setWidthFull();
emailField.setMaxLength(30); emailField.setMaxLength(50);
return emailField; return emailField;
} }
@ -372,7 +450,10 @@ public class EmployeeView extends BeanValidationForm<Employee> implements HasUrl
Employee employee = getEntity(); Employee employee = getEntity();
employee.setStatus(status.getValue()); employee.setStatus(status.getValue());
employee.setAge(age.getValue()); employee.setAge(age.getValue());
employee.setSalaryBasic(salaryBasic.getValue());
employee.setBonoProfesional(bonoProfesional.getValue());
employee.setAntiguedad(antiguedad.getValue());
employee.setSalarytotal((salaryTotal.getValue()));
employeeService.createOrUpdate(employee); employeeService.createOrUpdate(employee);
Notification.show(NOTIFICATION_SAVE_SUCCESS); Notification.show(NOTIFICATION_SAVE_SUCCESS);
getUI().ifPresent(ui -> ui.navigate(EmployeesListView.class)); getUI().ifPresent(ui -> ui.navigate(EmployeesListView.class));
@ -391,28 +472,33 @@ public class EmployeeView extends BeanValidationForm<Employee> implements HasUrl
public void setParameter(final BeforeEvent beforeEvent, final String action) { public void setParameter(final BeforeEvent beforeEvent, final String action) {
final RouteParameters params = beforeEvent.getRouteParameters(); final RouteParameters params = beforeEvent.getRouteParameters();
final String s = params.get("employeeId").orElse(null); final String s = params.get("employeeId").orElse(null);
if ("new".equals(action)) { if ("new".equals(action)) {
setEntityWithEnabledSave(new Employee()); setEntityWithEnabledSave(new Employee());
saveButton.setVisible(true); saveButton.setVisible(true);
editButton.setVisible(false); editButton.setVisible(false);
setFieldsEditable(); setFieldsEditable();
upload.setVisible(true);
salaryTotal.setValue(String.valueOf(true));
} else { } else {
UUID employeeId = UUID.fromString(s); UUID employeeId = UUID.fromString(s);
var employee = employeeService.getEmployee(employeeId); var employee = employeeService.getEmployee(employeeId);
setEntityWithEnabledSave(employee); setEntityWithEnabledSave(employee);
if ("edit".equals(action) && !s.isEmpty()) { if ("edit".equals(action) && !s.isEmpty()) {
saveButton.setVisible(true); saveButton.setVisible(true);
editButton.setVisible(false); editButton.setVisible(false);
status.setValue(employee.getStatus()); status.setValue(employee.getStatus());
setFieldsEditable(); setFieldsEditable();
upload.setVisible(true);
displayProfileImage(employee);
salaryTotal.setValue(employee.getSalarytotal());
} else if ("view".equals(action) && !s.isEmpty()) { } else if ("view".equals(action) && !s.isEmpty()) {
setFieldsReadOnly(); setFieldsReadOnly();
saveButton.setVisible(false); saveButton.setVisible(false);
editButton.setVisible(true); editButton.setVisible(true);
setFieldsReadOnly(); setFieldsReadOnly();
displayProfileImage(employee); displayProfileImage(employee);
upload.setVisible(true);
salaryTotal.setValue(employee.getSalarytotal());
} }
} }
} }
@ -423,7 +509,6 @@ public class EmployeeView extends BeanValidationForm<Employee> implements HasUrl
profileImagePreview.setVisible(true); profileImagePreview.setVisible(true);
profileImagePreview.setMaxWidth("250px"); profileImagePreview.setMaxWidth("250px");
profileImagePreview.setMaxHeight("250px"); profileImagePreview.setMaxHeight("250px");
upload.setVisible(true); upload.setVisible(true);
} else { } else {
profileImagePreview.setVisible(true); profileImagePreview.setVisible(true);
@ -432,7 +517,7 @@ public class EmployeeView extends BeanValidationForm<Employee> implements HasUrl
} }
private void setFieldsReadOnly() { private void setFieldsReadOnly() {
username.setReadOnly(false); username.setReadOnly(true);
firstName.setReadOnly(true); firstName.setReadOnly(true);
lastName.setReadOnly(true); lastName.setReadOnly(true);
status.setReadOnly(true); status.setReadOnly(true);
@ -444,6 +529,8 @@ public class EmployeeView extends BeanValidationForm<Employee> implements HasUrl
numberOfChildren.setReadOnly(true); numberOfChildren.setReadOnly(true);
phoneNumber.setReadOnly(true); phoneNumber.setReadOnly(true);
personalEmail.setReadOnly(true); personalEmail.setReadOnly(true);
phoneNumberProfesional.setReadOnly(true);
profesionalEmail.setReadOnly(true);
position.setReadOnly(true); position.setReadOnly(true);
team.setReadOnly(true); team.setReadOnly(true);
emergencyCName.setReadOnly(true); emergencyCName.setReadOnly(true);
@ -469,21 +556,26 @@ public class EmployeeView extends BeanValidationForm<Employee> implements HasUrl
certification4.setReadOnly(true); certification4.setReadOnly(true);
recognition.setReadOnly(true); recognition.setReadOnly(true);
achievements.setReadOnly(true); achievements.setReadOnly(true);
language.setReadOnly(true); language1.setReadOnly(true);
languageLevel.setReadOnly(true); language1Level.setReadOnly(true);
language2.setReadOnly(true);
language2Level.setReadOnly(true);
cod.setReadOnly(true); cod.setReadOnly(true);
leadManager.setReadOnly(true); leadManager.setReadOnly(true);
project.setReadOnly(true);
dateOfEntry.setReadOnly(true); dateOfEntry.setReadOnly(true);
dateOfExit.setReadOnly(true); dateOfExit.setReadOnly(true);
contractType.setReadOnly(true); contractType.setReadOnly(true);
seniority.setReadOnly(true); seniority.setReadOnly(true);
salary.setReadOnly(true); salaryTotal.setReadOnly(true);
salaryBasic.setReadOnly(true);
bonoProfesional.setReadOnly(true);
antiguedad.setReadOnly(true);
bankName.setReadOnly(true); bankName.setReadOnly(true);
accountNumber.setReadOnly(true); accountNumber.setReadOnly(true);
gpss.setReadOnly(true); gpss.setReadOnly(true);
sss.setReadOnly(true); sss.setReadOnly(true);
beneficiaries.setReadOnly(true); beneficiarie1.setReadOnly(true);
beneficiarie2.setReadOnly(true);
} }
private void setFieldsEditable() { private void setFieldsEditable() {
@ -499,6 +591,8 @@ public class EmployeeView extends BeanValidationForm<Employee> implements HasUrl
numberOfChildren.setReadOnly(false); numberOfChildren.setReadOnly(false);
phoneNumber.setReadOnly(false); phoneNumber.setReadOnly(false);
personalEmail.setReadOnly(false); personalEmail.setReadOnly(false);
phoneNumberProfesional.setReadOnly(false);
profesionalEmail.setReadOnly(false);
position.setReadOnly(false); position.setReadOnly(false);
team.setReadOnly(false); team.setReadOnly(false);
emergencyCName.setReadOnly(false); emergencyCName.setReadOnly(false);
@ -524,21 +618,26 @@ public class EmployeeView extends BeanValidationForm<Employee> implements HasUrl
certification4.setReadOnly(false); certification4.setReadOnly(false);
recognition.setReadOnly(false); recognition.setReadOnly(false);
achievements.setReadOnly(false); achievements.setReadOnly(false);
language.setReadOnly(false); language1.setReadOnly(false);
languageLevel.setReadOnly(false); language1Level.setReadOnly(false);
language2.setReadOnly(false);
language2Level.setReadOnly(false);
cod.setReadOnly(false); cod.setReadOnly(false);
leadManager.setReadOnly(false); leadManager.setReadOnly(false);
project.setReadOnly(false);
dateOfEntry.setReadOnly(false); dateOfEntry.setReadOnly(false);
dateOfExit.setReadOnly(false); dateOfExit.setReadOnly(false);
contractType.setReadOnly(false); contractType.setReadOnly(false);
seniority.setReadOnly(false); seniority.setReadOnly(false);
salary.setReadOnly(false); salaryTotal.setReadOnly(false);
salaryBasic.setReadOnly(false);
bonoProfesional.setReadOnly(false);
antiguedad.setReadOnly(false);
bankName.setReadOnly(false); bankName.setReadOnly(false);
accountNumber.setReadOnly(false); accountNumber.setReadOnly(false);
gpss.setReadOnly(false); gpss.setReadOnly(false);
sss.setReadOnly(false); sss.setReadOnly(false);
beneficiaries.setReadOnly(false); beneficiarie1.setReadOnly(false);
beneficiarie2.setReadOnly(false);
} }
@Override @Override
@ -553,18 +652,19 @@ public class EmployeeView extends BeanValidationForm<Employee> implements HasUrl
birthday, age, birthday, age,
birthCity, residenceAddress, localAddress, birthCity, residenceAddress, localAddress,
maritalStatus, ci, issuedIn, numberOfChildren, maritalStatus, ci, issuedIn, numberOfChildren,
phoneNumber, personalEmail, phoneNumber, personalEmail, phoneNumberProfesional, profesionalEmail,
contEmerg, emergencyCName, emergencyCAddress, emergencyCPhone, emergencyCEmail, contEmerg, emergencyCName, emergencyCAddress, emergencyCPhone, emergencyCEmail,
infProf, infProf,
titulos, pTitle1, pTitle2, pTitle3, pStudy1, pStudy2, pStudy3, titulos, pTitle1, pTitle2, pTitle3, pStudy1, pStudy2, pStudy3,
certif, certification1, certification2, certification3, certification4, certif, certification1, certification2, certification3, certification4,
logros, recognition, achievements, logros, recognition, achievements,
idioma, language, languageLevel, idioma, language1, language1Level, language2, language2Level,
infoAdm, infoAdm,
cod, position, team, leadManager, project, cod, position, team, leadManager,
infoCont, dateOfEntry, dateOfExit, contractType, seniority, salary, infoCont, dateOfEntry, dateOfExit, contractType, seniority,
salaryBasic, bonoProfesional, antiguedad, salaryTotal,
datBanc, bankName, accountNumber, datBanc, bankName, accountNumber,
datGest, gpss, sss, beneficiaries, datGest, gpss, sss, beneficiarie1, beneficiarie2,
saveButton, editButton, reportButton, dialog saveButton, editButton, reportButton, dialog
); );
} }

View File

@ -114,7 +114,6 @@ public class HoursWorkedListView extends BaseView {
setupFilters(); setupFilters();
setupListHoursWorkedGrid(); setupListHoursWorkedGrid();
getCurrentPageLayout().add(hoursWorkedGrid); getCurrentPageLayout().add(hoursWorkedGrid);
getCurrentPageLayout().add(createActionButtons());
} }
private void setupFilters() { private void setupFilters() {
@ -137,11 +136,21 @@ public class HoursWorkedListView extends BaseView {
hoursWorkedGrid.addColumn(hw -> hw.getEmployee().getTeam() != null ? hw.getEmployee().getTeam() hoursWorkedGrid.addColumn(hw -> hw.getEmployee().getTeam() != null ? hw.getEmployee().getTeam()
.getName() : "Sin asignar") .getName() : "Sin asignar")
.setHeader("Equipo"); .setHeader("Equipo");
hoursWorkedGrid.addColumn(HoursWorked::getActividad).setHeader("Actividad"); hoursWorkedGrid.addColumn(hw -> {
hoursWorkedGrid.addColumn(HoursWorked::getHours).setHeader("Total Horas").setSortable(true); String actividad = hw.getActividad() != null ? hw.getActividad() : "Sin Actividad";
String tareaEspecifica = hw.getTareaEspecifica() != null ? hw.getTareaEspecifica() : "";
return !tareaEspecifica.isEmpty() ? tareaEspecifica : actividad;
}).setHeader("Actividad");
hoursWorkedGrid.addColumn(hw -> {
if (hw.getTareaEspecifica() != null && !hw.getTareaEspecifica().isEmpty()) {
return calcularHorasPorTareaEspecifica(hw);
} else {
return calcularHorasPorActividadGeneral(hw);
}
}).setHeader("Total Horas").setSortable(true);
hoursWorkedGrid.addColumn(hw -> hw.getHoraspendientes() - calcularTotal(hw)).setHeader("Horas Pendientes") hoursWorkedGrid.addColumn(hw -> hw.getHoraspendientes() - calcularTotal(hw)).setHeader("Horas Pendientes")
.setSortable(true); .setSortable(true);
hoursWorkedGrid.setPaginationBarMode(PagingGrid.PaginationBarMode.BOTTOM); hoursWorkedGrid.setPaginationBarMode(PagingGrid.PaginationBarMode.BOTTOM);
hoursWorkedGrid.setPageSize(PAGE_SIZE); hoursWorkedGrid.setPageSize(PAGE_SIZE);
hoursWorkedGrid.asSingleSelect().addValueChangeListener(event -> { hoursWorkedGrid.asSingleSelect().addValueChangeListener(event -> {
@ -152,6 +161,36 @@ public class HoursWorkedListView extends BaseView {
}); });
} }
private double calcularHorasPorTareaEspecifica(final HoursWorked hoursWorked) {
List<HoursWorked> tareas = hoursWorkedService.findListHoursWorkedEmployee(
hoursWorked.getEmployee().getId(), hoursWorked.getWeekNumber());
return tareas.stream()
.filter(hw -> Objects.equals(hw.getTareaEspecifica(), hoursWorked.getTareaEspecifica()))
.mapToDouble(HoursWorked::getHours)
.sum();
}
private double calcularHorasPorActividadGeneral(final HoursWorked hoursWorked) {
List<HoursWorked> actividades = hoursWorkedService.findListHoursWorkedEmployee(
hoursWorked.getEmployee().getId(), hoursWorked.getWeekNumber());
return actividades.stream()
.filter(hw -> Objects.equals(hw.getActividad(), hoursWorked.getActividad())
&& (hw.getTareaEspecifica() == null || hw.getTareaEspecifica().isEmpty()))
.mapToDouble(HoursWorked::getHours)
.sum();
}
private double calcularTotalHorasTareaEspecifica(final HoursWorked hoursWorked) {
List<HoursWorked> horasTareas = hoursWorkedService.findListHoursWorkedEmployee(
hoursWorked.getEmployee().getId(), hoursWorked.getWeekNumber());
return horasTareas.stream()
.filter(hw -> Objects.equals(hw.getTareaEspecifica(), hoursWorked.getTareaEspecifica()))
.mapToDouble(HoursWorked::getHours)
.sum();
}
private double calcularTotal(final HoursWorked hoursWorked) { private double calcularTotal(final HoursWorked hoursWorked) {
List<HoursWorked> listHoursworkedemploye = hoursWorkedService.findListHoursWorkedEmployee( List<HoursWorked> listHoursworkedemploye = hoursWorkedService.findListHoursWorkedEmployee(
hoursWorked.getEmployee().getId(), hoursWorked.getWeekNumber()); hoursWorked.getEmployee().getId(), hoursWorked.getWeekNumber());
@ -165,25 +204,6 @@ public class HoursWorkedListView extends BaseView {
.sum(); .sum();
} }
private HorizontalLayout createActionButtons() {
Button viewButton = new Button("Ver", event -> {
if (selectedEmployeeId != null) {
navigateToHoursWorkedView(selectedEmployeeId);
} else {
Notification.show("Seleccione una solicitud.", 3000, Notification.Position.MIDDLE);
}
});
Button closeButton = new Button("Salir", event -> navigateToListView());
return new HorizontalLayout(viewButton, closeButton);
}
private void navigateToListView() {
getUI().ifPresent(ui -> ui.navigate(MainView.class));
}
private void navigateToHoursWorkedView(final UUID idEmployee) {
getUI().ifPresent(ui -> ui.navigate("hours-worked-list/" + idEmployee.toString()));
}
private Button createButton(final String label, final Runnable onClickAction) { private Button createButton(final String label, final Runnable onClickAction) {
final Button button = new Button(label); final Button button = new Button(label);

View File

@ -108,7 +108,8 @@ public class HoursWorkedView extends BeanValidationForm<HoursWorked> implements
private void configureTareasEspecificas() { private void configureTareasEspecificas() {
tareasEspecificasDropdown.setItems("Entrevistas", "Reuniones", tareasEspecificasDropdown.setItems("Entrevistas", "Reuniones",
"Colaboraciones", "Aprendizajes", "Proyectos PFS", "Otros"); "Colaboraciones", "Aprendizajes", "Proyectos PFS",
"Consulta Medica", "Afiliación al Seguro", "Fallas Tecnicas", "Otros");
tareasEspecificasDropdown.setPlaceholder("Selecciona una tarea..."); tareasEspecificasDropdown.setPlaceholder("Selecciona una tarea...");
tareasEspecificasDropdown.addValueChangeListener(event -> { tareasEspecificasDropdown.addValueChangeListener(event -> {
@ -181,7 +182,8 @@ public class HoursWorkedView extends BeanValidationForm<HoursWorked> implements
LocalDate selectedDate = event.getValue(); LocalDate selectedDate = event.getValue();
if (selectedDate != null) { if (selectedDate != null) {
int weekNumber = selectedDate.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR); int weekNumber = selectedDate.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR);
Notification.show("Número de la semana: " + weekNumber, 3000, Notification.Position.BOTTOM_CENTER); Notification.show("Número de la semana: " + weekNumber,
3000, Notification.Position.BOTTOM_CENTER);
if (hoursWorked != null) { if (hoursWorked != null) {
hoursWorked.setWeekNumber(weekNumber); hoursWorked.setWeekNumber(weekNumber);
} }
@ -192,13 +194,43 @@ public class HoursWorkedView extends BeanValidationForm<HoursWorked> implements
private void saveHoursWorked() { private void saveHoursWorked() {
if (isFormValid()) { if (isFormValid()) {
HoursWorked hoursWorked = getEntity(); HoursWorked hoursWorked = getEntity();
String actividad = activityField.getValue();
String tareaEspecifica = tareasEspecificasDropdown.getValue();
if (actividad != null && !actividad.isEmpty() && tareaEspecifica != null) {
Notification.show("Solo puedes elegir una: actividad del proyecto o tarea de la empresa.",
3000, Notification.Position.BOTTOM_CENTER);
return;
}
if (actividad != null && !actividad.isEmpty()) {
hoursWorked.setActividad(actividad);
} else if (tareaEspecifica != null) {
if ("Otros".equals(tareaEspecifica)) {
// Validar que se ingresó una tarea específica en el campo de texto
String tareaEspecificaInputValue = tareaEspecificaInput.getValue();
if (tareaEspecificaInputValue == null || tareaEspecificaInputValue.isEmpty()) {
Notification.show("Por favor, ingresa una tarea específica.",
3000, Notification.Position.BOTTOM_CENTER);
return;
}
hoursWorked.setTareaEspecifica(tareaEspecificaInputValue);
} else {
hoursWorked.setTareaEspecifica(tareaEspecifica);
}
} else {
Notification.show("Por favor, selecciona una actividad o tarea para guardar.",
3000, Notification.Position.BOTTOM_CENTER);
return;
}
setFieldValues(hoursWorked); setFieldValues(hoursWorked);
hoursWorkedService.save(hoursWorked); hoursWorkedService.save(hoursWorked);
Notification.show("Horas trabajadas guardadas correctamente."); Notification.show("Horas trabajadas guardadas correctamente.",
3000, Notification.Position.BOTTOM_CENTER);
closeForm(); closeForm();
} }
} }
private void setFieldValues(final HoursWorked hoursWorked) { private void setFieldValues(final HoursWorked hoursWorked) {
hoursWorked.setDate(dateField.getValue()); hoursWorked.setDate(dateField.getValue());
hoursWorked.setTeam(teamField.getValue()); hoursWorked.setTeam(teamField.getValue());
@ -211,10 +243,10 @@ public class HoursWorkedView extends BeanValidationForm<HoursWorked> implements
Notification.show("Por favor, ingrese un número válido para las horas."); Notification.show("Por favor, ingrese un número válido para las horas.");
} }
if ("Otros".equals(tareasEspecificasDropdown.getValue())) { if ("Otros".equals(tareasEspecificasDropdown.getValue())) {
hoursWorked.setTareasEspecificas(tareaEspecificaInput.getValue()); hoursWorked.setActividad(tareaEspecificaInput.getValue());
try { try {
double horasEspecifica = Double.parseDouble(horasTareaEspecificaField.getValue()); double horasEspecifica = Double.parseDouble(horasTareaEspecificaField.getValue());
hoursWorked.setHorasTareasEspecificas(horasEspecifica); hoursWorked.setHours(horasEspecifica);
double totalHoras = hoursWorked.getHours() + horasEspecifica; double totalHoras = hoursWorked.getHours() + horasEspecifica;
hoursWorked.setTotalHours(totalHoras); hoursWorked.setTotalHours(totalHoras);
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
@ -224,20 +256,27 @@ public class HoursWorkedView extends BeanValidationForm<HoursWorked> implements
} }
private void closeForm() { private void closeForm() {
getUI().ifPresent(ui -> ui.navigate("hours-worked-list/" + hoursWorked.getId().toString())); if (hoursWorked != null) {
getUI().ifPresent(ui -> ui.navigate("hours-worked-list/" + hoursWorked.getId().toString()));
} else {
getUI().ifPresent(ui -> ui.navigate("hours-worked-list"));
}
} }
private boolean isFormValid() { private boolean isFormValid() {
boolean isTareaEspecificaValida = "Otros".equals(tareasEspecificasDropdown.getValue())
? !tareaEspecificaInput.isEmpty()
: tareasEspecificasDropdown.getValue() != null;
boolean isActividadValida = !activityField.isEmpty();
boolean isSoloUnaOpcionElegida = (isActividadValida && tareasEspecificasDropdown.isEmpty())
|| (!isActividadValida && isTareaEspecificaValida);
return dateField.getValue() != null return dateField.getValue() != null
&& && teamField.getValue() != null
teamField.getValue() != null && employeeField.getValue() != null
&& && isSoloUnaOpcionElegida;
employeeField.getValue() != null
&&
!activityField.isEmpty();
} }
private void configureViewOrEditAction(final String action) { private void configureViewOrEditAction(final String action) {
if ("edit".equals(action) && hoursWorked != null) { if ("edit".equals(action) && hoursWorked != null) {
setFieldsReadOnly(false); setFieldsReadOnly(false);
@ -253,4 +292,4 @@ public class HoursWorkedView extends BeanValidationForm<HoursWorked> implements
employeeField.setReadOnly(readOnly); employeeField.setReadOnly(readOnly);
activityField.setReadOnly(readOnly); activityField.setReadOnly(readOnly);
} }
} }