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",
"startDate",
"endDate",
"daysToBeTake",
"daysBalance"
);
"daysToBeTake");
requestGrid.setAllRowsVisible(true);
requestGrid.asSingleSelect().addValueChangeListener(event -> {
TimeOffRequest selectedRequest = event.getValue();

View File

@ -32,13 +32,13 @@ import java.util.UUID;
@Route(value = "/requests/new", layout = MainLayout.class)
public class RequestRegisterView extends VerticalLayout {
private final ComboBox<Employee> employeeComboBox = new ComboBox<>("Employee");
private final ComboBox<TimeOffRequestType> 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<Employee> employeeComboBox = new ComboBox<>("Empleado");
private final ComboBox<TimeOffRequestType> 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<TimeOffRequest> employeeRequests = requestService.findRequestsByEmployeeId(employee.getId());
List<TimeOffRequestType> allCategories = Arrays.asList(TimeOffRequestType.values());
List<TimeOffRequestType> 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<TimeOffRequest> employeeRequests,
final TimeOffRequestType category) {
List<TimeOffRequest> 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<TimeOffRequest> previousRequests
= requestService.findByEmployeeAndCategory(employeeId, vacation.getCategory());
List<TimeOffRequest> 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<TimeOffRequest> 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<TimeOffRequest> 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<TimeOffRequest> 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<TimeOffRequest> 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();
}
}