diff --git a/src/main/java/com/primefactorsolutions/views/RequestEmployeeView.java b/src/main/java/com/primefactorsolutions/views/RequestEmployeeView.java index ba59a9a..275bb6f 100644 --- a/src/main/java/com/primefactorsolutions/views/RequestEmployeeView.java +++ b/src/main/java/com/primefactorsolutions/views/RequestEmployeeView.java @@ -87,9 +87,7 @@ public class RequestEmployeeView extends Div implements HasUrlParameter "state", "startDate", "endDate", - "daysToBeTake", - "daysBalance" - ); + "daysToBeTake"); requestGrid.setAllRowsVisible(true); requestGrid.asSingleSelect().addValueChangeListener(event -> { TimeOffRequest selectedRequest = event.getValue(); diff --git a/src/main/java/com/primefactorsolutions/views/RequestRegisterView.java b/src/main/java/com/primefactorsolutions/views/RequestRegisterView.java index fcb1d66..41f37d1 100644 --- a/src/main/java/com/primefactorsolutions/views/RequestRegisterView.java +++ b/src/main/java/com/primefactorsolutions/views/RequestRegisterView.java @@ -32,13 +32,13 @@ import java.util.UUID; @Route(value = "/requests/new", layout = MainLayout.class) public class RequestRegisterView extends VerticalLayout { - private final ComboBox employeeComboBox = new ComboBox<>("Employee"); - private final ComboBox categoryComboBox = new ComboBox<>("Category"); - private final NumberField availableDaysField = new NumberField("Available Days"); - private final DatePicker startDatePicker = new DatePicker("Start Date"); - private final DatePicker endDatePicker = new DatePicker("End Date"); - private final NumberField daysToBeTakenField = new NumberField("Days To Be Taken"); - private final NumberField balanceDaysField = new NumberField("Balance Days"); + private final ComboBox employeeComboBox = new ComboBox<>("Empleado"); + private final ComboBox categoryComboBox = new ComboBox<>("Categoría"); + private final NumberField availableDaysField = new NumberField("Días disponibles"); + private final DatePicker startDatePicker = new DatePicker("Fecha de inicio"); + private final DatePicker endDatePicker = new DatePicker("Fecha final"); + private final NumberField daysToBeTakenField = new NumberField("Días a tomar"); + private final NumberField balanceDaysField = new NumberField("Días de saldo"); private final TimeOffRequestService requestService; private final EmployeeService employeeService; @@ -59,11 +59,24 @@ public class RequestRegisterView extends VerticalLayout { this.employeeService = employeeService; this.vacationService = vacationService; this.binder = new Binder<>(TimeOffRequest.class); + initializeView(); + } + private void initializeView() { configureFormFields(); configureButtons(); configureBinder(); setupFormLayout(); + configureInitialFieldStates(); + } + + private void configureInitialFieldStates() { + categoryComboBox.setEnabled(false); + startDatePicker.setEnabled(false); + endDatePicker.setEnabled(false); + availableDaysField.setReadOnly(true); + daysToBeTakenField.setReadOnly(true); + balanceDaysField.setReadOnly(true); } private void configureFormFields() { @@ -71,66 +84,74 @@ public class RequestRegisterView extends VerticalLayout { employeeComboBox.setItemLabelGenerator(emp -> emp.getFirstName() + " " + emp.getLastName()); employeeComboBox.addValueChangeListener(event -> { employee = event.getValue(); - handleEmployeeSelection(employee); + System.out.println("Clearing form..." + employee); + + handleEmployeeSelection(event.getValue()); + }); + categoryComboBox.addValueChangeListener(event -> { + onCategoryChange(event.getValue()); + handleCategorySelection(event.getValue()); }); - categoryComboBox.setEnabled(false); - startDatePicker.setEnabled(false); - endDatePicker.setEnabled(false); - categoryComboBox.addValueChangeListener(event -> handleCategorySelection(event.getValue())); startDatePicker.addValueChangeListener(event -> updateDatePickerMinValues()); endDatePicker.addValueChangeListener(event -> calculateDays()); - availableDaysField.setReadOnly(true); - daysToBeTakenField.setReadOnly(true); - balanceDaysField.setReadOnly(true); } private void configureBinder() { binder.forField(employeeComboBox) - .asRequired("Employee is required") .bind(TimeOffRequest::getEmployee, TimeOffRequest::setEmployee); - binder.forField(categoryComboBox) - .asRequired("Category is required") .bind(TimeOffRequest::getCategory, TimeOffRequest::setCategory); - binder.forField(availableDaysField) .bind(TimeOffRequest::getAvailableDays, TimeOffRequest::setAvailableDays); - binder.forField(startDatePicker) - .asRequired("Start date is required") .bind(TimeOffRequest::getStartDate, TimeOffRequest::setStartDate); - binder.forField(endDatePicker) - .asRequired("End date is required") .bind(TimeOffRequest::getEndDate, TimeOffRequest::setEndDate); - binder.forField(daysToBeTakenField) .bind(TimeOffRequest::getDaysToBeTake, TimeOffRequest::setDaysToBeTake); - binder.forField(balanceDaysField) .bind(TimeOffRequest::getDaysBalance, TimeOffRequest::setDaysBalance); - binder.setBean(new TimeOffRequest()); } private void handleEmployeeSelection(final Employee selectedEmployee) { - clearForm(); if (selectedEmployee != null) { + categoryComboBox.clear(); + availableDaysField.clear(); + startDatePicker.clear(); + endDatePicker.clear(); + daysToBeTakenField.clear(); + balanceDaysField.clear(); categoryComboBox.setEnabled(true); + startDatePicker.setEnabled(false); + endDatePicker.setEnabled(false); filterCategories(selectedEmployee); } } private void filterCategories(final Employee employee) { + categoryComboBox.clear(); List employeeRequests = requestService.findRequestsByEmployeeId(employee.getId()); List allCategories = Arrays.asList(TimeOffRequestType.values()); List availableCategories = allCategories.stream() .filter(category -> isCategoryAvailable(employeeRequests, category)) .filter(category -> isCategoryAllowedByGender(category, employee.getGender())) + .filter(category -> category != TimeOffRequestType.VACACION_GESTION_ANTERIOR && category != TimeOffRequestType.TODOS) .toList(); + categoryComboBox.setItems(availableCategories); } + private void onCategoryChange(final TimeOffRequestType selectedCategory) { + if (selectedCategory == TimeOffRequestType.VACACION_GESTION_ACTUAL) { + startDatePicker.setEnabled(true); + endDatePicker.setEnabled(true); + } else { + startDatePicker.setEnabled(true); + endDatePicker.setEnabled(false); + } + } + private boolean isCategoryAvailable(final List employeeRequests, final TimeOffRequestType category) { List requestsByCategory = employeeRequests.stream() @@ -170,7 +191,6 @@ public class RequestRegisterView extends VerticalLayout { private void handleCategorySelection(final TimeOffRequestType selectedCategory) { if (selectedCategory != null) { updateAvailableDays(selectedCategory); - startDatePicker.setEnabled(true); } } @@ -215,48 +235,52 @@ public class RequestRegisterView extends VerticalLayout { endDate = null; UUID employeeId = employee.getId(); - List previousRequests - = requestService.findByEmployeeAndCategory(employeeId, vacation.getCategory()); + List previousRequests = requestService.findByEmployeeAndCategory(employeeId, vacation.getCategory()); - int startYear; - if (previousRequests.isEmpty()) { - startYear = LocalDate.now().getYear(); - } else { - int lastRequestYear = previousRequests.stream() - .max(Comparator.comparing(TimeOffRequest::getStartDate)) - .map(request -> request.getStartDate().getYear()) - .orElse(LocalDate.now().getYear()); + int startYear = calculateStartYear(previousRequests); - int proposedYear = lastRequestYear + 1; - int currentYear = LocalDate.now().getYear(); - - if (proposedYear < currentYear) { - startYear = currentYear; - } else { - startYear = proposedYear; - } - } - - if (vacation.getMonthOfYear() != null && vacation.getDayOfMonth() != null) { - startDate = LocalDate.of( - startYear, - vacation.getMonthOfYear().intValue(), - vacation.getDayOfMonth().intValue()); + startDate = determineStartDate(vacation, startYear); + if (startDate != null) { endDate = startDate.plusDays(vacation.getExpiration().intValue() - 1); } else { - if (vacation.getCategory() == TimeOffRequestType.CUMPLEAÑOS && employee.getBirthday() != null) { - startDate = LocalDate.of( - startYear, - employee.getBirthday().getMonth(), - employee.getBirthday().getDayOfMonth()); - endDate = startDate.plusDays(vacation.getExpiration().intValue() - 1); - } else if (vacation.getCategory() == TimeOffRequestType.PERMISOS_DE_SALUD) { - startDate = LocalDate.now(); - endDate = LocalDate.of(startYear, 12, 31); - } else { - startDate = LocalDate.now(); - } + startDate = LocalDate.now(); } + + setPickerValues(vacation, startDate); + setPickerLimits(startDate, endDate); + } + + private int calculateStartYear(final List previousRequests) { + if (previousRequests.isEmpty()) { + return LocalDate.now().getYear(); + } + + int lastRequestYear = previousRequests.stream() + .max(Comparator.comparing(TimeOffRequest::getStartDate)) + .map(request -> request.getStartDate().getYear()) + .orElse(LocalDate.now().getYear()); + + int currentYear = LocalDate.now().getYear(); + return Math.max(lastRequestYear + 1, currentYear); + } + + private LocalDate determineStartDate(final Vacation vacation, final int startYear) { + if (vacation.getMonthOfYear() != null && vacation.getDayOfMonth() != null) { + return LocalDate.of(startYear, vacation.getMonthOfYear().intValue(), vacation.getDayOfMonth().intValue()); + } + + if (vacation.getCategory() == TimeOffRequestType.CUMPLEAÑOS && employee.getBirthday() != null) { + return LocalDate.of(startYear, employee.getBirthday().getMonth(), employee.getBirthday().getDayOfMonth()); + } + + if (vacation.getCategory() == TimeOffRequestType.PERMISOS_DE_SALUD) { + return LocalDate.now(); + } + + return LocalDate.now(); + } + + private void setPickerValues(final Vacation vacation, final LocalDate startDate) { startDatePicker.setValue(startDate); if ((vacation.getDuration() != null && vacation.getDuration() == 0.5) @@ -266,22 +290,25 @@ public class RequestRegisterView extends VerticalLayout { int durationDays = (vacation.getDuration() != null ? vacation.getDuration().intValue() - 1 : 0); endDatePicker.setValue(startDate.plusDays(durationDays)); } + } + private void setPickerLimits(final LocalDate startDate, final LocalDate endDate) { startDatePicker.setMin(startDate); startDatePicker.setMax(endDate); endDatePicker.setMin(startDate); endDatePicker.setMax(endDate); } - private void updateDatePickerMinValues() { LocalDate startDate = startDatePicker.getValue(); - if (vacation.getDuration() == 0.5) { - endDatePicker.setValue(startDate.plusDays(0)); - } else { - endDatePicker.setValue(startDate.plusDays(vacation.getDuration().intValue() - 1)); + if (availableDaysField.getValue() != null) { + if (availableDaysField.getValue() == 0.5) { + endDatePicker.setValue(startDate.plusDays(0)); + } else { + endDatePicker.setValue(startDate.plusDays(availableDaysField.getValue().intValue() - 1)); + } + calculateDays(); } - calculateDays(); } private void calculateDays() { @@ -289,26 +316,53 @@ public class RequestRegisterView extends VerticalLayout { LocalDate endDate = endDatePicker.getValue(); Double availableDays = availableDaysField.getValue(); - if (startDate != null && endDate != null) { - double daysToBeTaken = java.time.temporal.ChronoUnit.DAYS.between(startDate, endDate) + 1; - if (vacation.getCategory() == TimeOffRequestType.PERMISOS_DE_SALUD || vacation.getDuration() == 0.5) { - daysToBeTakenField.setValue(0.5); - } else { - daysToBeTakenField.setValue(daysToBeTaken); - } - double balanceDays = availableDays - daysToBeTakenField.getValue(); + if (areDatesValid(startDate, endDate)) { + double daysToBeTaken = calculateDaysBetween(startDate, endDate); + setDaysToBeTakenField(daysToBeTaken); + + double balanceDays = calculateBalanceDays(availableDays, daysToBeTakenField.getValue()); balanceDaysField.setValue(balanceDays); + + if (balanceDays < 0) { + clearFields(); + } } } + private boolean areDatesValid(final LocalDate startDate, final LocalDate endDate) { + return startDate != null && endDate != null; + } + + private double calculateDaysBetween(final LocalDate startDate, final LocalDate endDate) { + return java.time.temporal.ChronoUnit.DAYS.between(startDate, endDate) + 1; + } + + private void setDaysToBeTakenField(final double daysToBeTaken) { + if (vacation.getCategory() == TimeOffRequestType.PERMISOS_DE_SALUD) { + daysToBeTakenField.setValue(0.5); + } else { + daysToBeTakenField.setValue(daysToBeTaken); + } + } + + private double calculateBalanceDays(final double availableDays, final double daysToBeTaken) { + return availableDays - daysToBeTaken; + } + + private void clearFields() { + daysToBeTakenField.clear(); + balanceDaysField.clear(); + endDatePicker.clear(); + } + private void configureButtons() { - saveButton = new Button("Save", event -> saveRequest()); - closeButton = new Button("Close", event -> closeForm()); + saveButton = new Button("Guardar", event -> saveRequest()); + closeButton = new Button("Salir", event -> closeForm()); } private void setupFormLayout() { add( - new H3("Add Vacation Request"), + new H3("Añadir solicitud de vacaciones"), employeeComboBox, categoryComboBox, availableDaysField, @@ -321,59 +375,54 @@ public class RequestRegisterView extends VerticalLayout { } private void saveRequest() { - if (binder.validate().isOk()) { - TimeOffRequest request = binder.getBean(); - request.setStartDate(startDatePicker.getValue()); - request.setAvailableDays(availableDaysField.getValue()); - if (endDate == null) { - request.setExpiration(endDatePicker.getValue()); - } else { - request.setExpiration(endDate); - } - request.setState(TimeOffRequestStatus.SOLICITADO); + if (!binder.validate().isOk()) { + Notification.show("Rellene correctamente todos los campos obligatorios."); + return; + } - List existingRequests = - requestService.findByEmployeeAndCategory(employee.getId(), request.getCategory()); + if (!validateForm()) { + Notification.show("Por favor, complete los campos antes de guardar"); + return; + } - int maxRequests = request.getCategory() == TimeOffRequestType.PERMISOS_DE_SALUD ? 4 : 2; + TimeOffRequest request = prepareRequest(); + handleExistingRequests(request); + requestService.saveTimeOffRequest(request); - if (existingRequests.size() >= maxRequests) { - existingRequests.stream() - .min(Comparator.comparing(TimeOffRequest::getStartDate)) - .ifPresent(oldestRequest -> requestService.deleteTimeOffRequest(oldestRequest.getId())); - } + Notification.show("Solicitud guardada correctamente."); + closeForm(); + } - requestService.saveTimeOffRequest(request); - Notification.show("Request saved successfully."); - closeForm(); - } else { - Notification.show("Please fill all required fields correctly."); + private TimeOffRequest prepareRequest() { + TimeOffRequest request = binder.getBean(); + request.setStartDate(startDatePicker.getValue()); + request.setAvailableDays(availableDaysField.getValue()); + request.setExpiration(endDate != null ? endDate : endDatePicker.getValue()); + request.setState(TimeOffRequestStatus.PENDIENTE); + return request; + } + + private void handleExistingRequests(final TimeOffRequest request) { + List existingRequests = + requestService.findByEmployeeAndCategory(employee.getId(), request.getCategory()); + + int maxRequests = request.getCategory() == TimeOffRequestType.PERMISOS_DE_SALUD ? 4 : 2; + + if (existingRequests.size() >= maxRequests) { + existingRequests.stream() + .min(Comparator.comparing(TimeOffRequest::getStartDate)) + .ifPresent(oldestRequest -> requestService.deleteTimeOffRequest(oldestRequest.getId())); } } - private void updateBalanceForCategory(final TimeOffRequest newRequest) { - List requests = requestService.findByEmployeeAndCategory( - newRequest.getEmployee().getId(), newRequest.getCategory()); - - if (vacation.getCategory() == TimeOffRequestType.PERMISOS_DE_SALUD - && vacation.getCategory() == TimeOffRequestType.VACACION_GESTION_ACTUAL) { - for (TimeOffRequest request : requests) { - double newBalance = request.getDaysBalance() - newRequest.getDaysToBeTake(); - request.setDaysBalance(newBalance); - requestService.saveTimeOffRequest(request); - } - } + private boolean validateForm() { + return employeeComboBox.getValue() != null + && categoryComboBox.getValue() != null + && startDatePicker.getValue() != null + && endDatePicker.getValue() != null; } private void closeForm() { getUI().ifPresent(ui -> ui.navigate(RequestsListView.class)); } - - private void clearForm() { - availableDaysField.clear(); - startDatePicker.clear(); - endDatePicker.clear(); - daysToBeTakenField.clear(); - balanceDaysField.clear(); - } }