Vacaciones #64

Merged
jesus.pelaez merged 11 commits from Vacaciones into En-desarrollo 2024-11-04 04:25:22 +00:00
2 changed files with 175 additions and 128 deletions
Showing only changes of commit 4421c6fe45 - Show all commits

View File

@ -87,9 +87,7 @@ public class RequestEmployeeView extends Div implements HasUrlParameter<String>
"state", "state",
"startDate", "startDate",
"endDate", "endDate",
"daysToBeTake", "daysToBeTake");
"daysBalance"
);
requestGrid.setAllRowsVisible(true); requestGrid.setAllRowsVisible(true);
requestGrid.asSingleSelect().addValueChangeListener(event -> { requestGrid.asSingleSelect().addValueChangeListener(event -> {
TimeOffRequest selectedRequest = event.getValue(); TimeOffRequest selectedRequest = event.getValue();

View File

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