Compare commits

..

No commits in common. "bdfaa7da8516aae1916272e858a1450455c69059" and "3b0e5833f8531065456c4f7cf13fd658cfc655c9" have entirely different histories.

9 changed files with 101 additions and 337 deletions

View File

@ -4,6 +4,7 @@ import com.vaadin.flow.component.page.AppShellConfigurator;
import com.vaadin.flow.theme.Theme; import com.vaadin.flow.theme.Theme;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
/** /**
* The entry point of the Spring Boot application. * The entry point of the Spring Boot application.
* *

View File

@ -3,14 +3,13 @@ package com.primefactorsolutions.model;
public enum TimeOffRequestStatus { public enum TimeOffRequestStatus {
TODOS, TODOS,
TOMADO, TOMADO,
SOLICITADO,
APROBADO, APROBADO,
EN_USO, EN_USO,
EN_REVISION,
PENDIENTE, PENDIENTE,
RECHAZADO, RECHAZADO,
VENCIDO,
SOLICITADO,
EN_REVISION,
COMPLETADO, COMPLETADO,
CANCELADO, CANCELADO,
VENCIDO
} }

View File

@ -5,7 +5,6 @@ import com.primefactorsolutions.repositories.TimeOffRequestRepository;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.Optional; import java.util.Optional;
@ -51,32 +50,4 @@ public class TimeOffRequestService {
public List<TimeOffRequest> findByEmployeeAndCategory(final UUID employeeId, final TimeOffRequestType category) { public List<TimeOffRequest> findByEmployeeAndCategory(final UUID employeeId, final TimeOffRequestType category) {
return timeOffRequestRepository.findByEmployeeIdAndCategory(employeeId, category); return timeOffRequestRepository.findByEmployeeIdAndCategory(employeeId, category);
} }
public void updateRequestStatuses() {
List<TimeOffRequest> requests = findAllTimeOffRequests();
LocalDate now = LocalDate.now();
LocalDate startOfYear = LocalDate.of(now.getYear(), 1, 1);
requests.removeIf(request -> request.getCategory() == TimeOffRequestType.VACACION_GESTION_ANTERIOR);
for (TimeOffRequest request : requests) {
if (request.getCategory() == TimeOffRequestType.VACACION_GESTION_ACTUAL && now.isEqual(startOfYear)) {
request.setCategory(TimeOffRequestType.VACACION_GESTION_ANTERIOR);
}
if (request.getState() == TimeOffRequestStatus.APROBADO
|| request.getState() == TimeOffRequestStatus.EN_USO) {
LocalDate startDate = request.getStartDate();
LocalDate endDate = request.getEndDate();
if (now.isAfter(endDate)) {
request.setState(TimeOffRequestStatus.TOMADO);
} else if (now.isEqual(startDate) || (now.isAfter(startDate) && now.isBefore(endDate))) {
request.setState(TimeOffRequestStatus.EN_USO);
}
}
}
saveAll(requests);
}
} }

View File

@ -1,5 +1,7 @@
package com.primefactorsolutions.views; package com.primefactorsolutions.views;
import com.primefactorsolutions.model.TimeOffRequest;
import com.primefactorsolutions.model.TimeOffRequestStatus;
import com.primefactorsolutions.service.TimeOffRequestService; import com.primefactorsolutions.service.TimeOffRequestService;
import com.vaadin.flow.component.Text; import com.vaadin.flow.component.Text;
import com.vaadin.flow.component.html.Main; import com.vaadin.flow.component.html.Main;
@ -7,12 +9,42 @@ import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route; import com.vaadin.flow.router.Route;
import jakarta.annotation.security.PermitAll; import jakarta.annotation.security.PermitAll;
import java.time.LocalDate;
import java.util.List;
@PageTitle("Home") @PageTitle("Home")
@Route(value = "", layout = MainLayout.class) @Route(value = "", layout = MainLayout.class)
@PermitAll @PermitAll
public class MainView extends Main { public class MainView extends Main {
private final TimeOffRequestService requestService;
public MainView(final TimeOffRequestService requestService) { public MainView(final TimeOffRequestService requestService) {
this.requestService = requestService;
add(new Text("Welcome")); add(new Text("Welcome"));
updateRequestStatuses();
}
private void updateRequestStatuses() {
List<TimeOffRequest> requests = requestService.findAllTimeOffRequests();
LocalDate now = LocalDate.now();
for (TimeOffRequest request : requests) {
if (request.getState() == TimeOffRequestStatus.APROBADO) {
LocalDate expirationDate = request.getExpiration();
LocalDate startDate = request.getStartDate();
LocalDate endDate = request.getEndDate();
if (now.isAfter(expirationDate)) {
request.setState(TimeOffRequestStatus.VENCIDO);
} else if (now.isAfter(endDate) && now.isBefore(expirationDate)) {
request.setState(TimeOffRequestStatus.TOMADO);
} else if (now.isEqual(startDate) || now.isAfter(startDate) && now.isBefore(endDate)) {
request.setState(TimeOffRequestStatus.EN_USO);
}
}
}
requestService.saveAll(requests);
} }
} }

View File

@ -113,7 +113,7 @@ public class PendingRequestsListView extends Main {
final Team team, final Team team,
final TimeOffRequestType category) { final TimeOffRequestType category) {
List<TimeOffRequest> filteredPendingRequests List<TimeOffRequest> filteredPendingRequests
= requestService.findRequestsByState(TimeOffRequestStatus.SOLICITADO); = requestService.findRequestsByState(TimeOffRequestStatus.PENDIENTE);
if (employee != null && !"TODOS".equals(employee.getFirstName())) { if (employee != null && !"TODOS".equals(employee.getFirstName())) {
filteredPendingRequests = filteredPendingRequests.stream() filteredPendingRequests = filteredPendingRequests.stream()

View File

@ -23,7 +23,9 @@ import org.vaadin.firitin.components.grid.PagingGrid;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.Period; import java.time.Period;
import java.util.*; import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@SpringComponent @SpringComponent
@ -52,7 +54,6 @@ public class RequestEmployeeView extends Div implements HasUrlParameter<String>
} }
private void initializeView() { private void initializeView() {
requestService.updateRequestStatuses();
setupFilters(); setupFilters();
setupGrid(); setupGrid();
add(requestGrid, createActionButtons(), createSummaryLayout()); add(requestGrid, createActionButtons(), createSummaryLayout());
@ -105,98 +106,29 @@ public class RequestEmployeeView extends Div implements HasUrlParameter<String>
}); });
} }
private Set<TimeOffRequestType> getStandardExclusions() {
return Set.of(
TimeOffRequestType.MATERNIDAD,
TimeOffRequestType.PATERNIDAD,
TimeOffRequestType.MATRIMONIO,
TimeOffRequestType.DUELO_1ER_GRADO,
TimeOffRequestType.DUELO_2ER_GRADO,
TimeOffRequestType.DIA_DEL_PADRE,
TimeOffRequestType.DIA_DE_LA_MADRE
);
}
private Set<TimeOffRequestType> getMaleSpecificExclusions() {
return Set.of(
TimeOffRequestType.DIA_DE_LA_MUJER_INTERNACIONAL,
TimeOffRequestType.DIA_DE_LA_MUJER_NACIONAL
);
}
private VerticalLayout createSummaryLayout() { private VerticalLayout createSummaryLayout() {
Employee employee = employeeService.getEmployee(employeeId); double totalHoliday = requests.stream()
boolean isMale = employee.getGender() == Employee.Gender.MALE; .filter(this::verificationIsHoliday)
int currentYear = LocalDate.now().getYear(); .mapToDouble(TimeOffRequest::getAvailableDays)
.sum();
double totalVacations = calculateVacationDays(employeeService.getEmployee(employeeId));
double totalPersonalDays = requests.stream()
.filter(req -> !verificationIsHoliday(req))
.filter(req -> !req.getCategory().name().startsWith("VACACION"))
.mapToDouble(TimeOffRequest::getAvailableDays)
.sum();
List<Vacation> vacations = vacationService.findVacations(); double totalAvailableDays = totalHoliday + totalVacations + totalPersonalDays;
double healthLicence = 2;
List<TimeOffRequest> healthRequests = requestService
.findByEmployeeAndCategory(employeeId, TimeOffRequestType.PERMISOS_DE_SALUD);
if (healthRequests != null && !healthRequests.isEmpty()) {
healthLicence = healthRequests.getLast().getDaysBalance();
}
double totalFixedAndMovableHolidays = calculateHolidayDays(vacations);
double totalPersonalDays = calculatePersonalDays(vacations, isMale);
List<Double> vacationDays = calculateVacationDays(employee);
double utilizedVacationCurrentDays = vacationDays.get(1);
List<TimeOffRequest> vacationCurrentRequests = requestService
.findByEmployeeAndCategory(employeeId, TimeOffRequestType.VACACION_GESTION_ACTUAL);
if (vacationCurrentRequests != null && !vacationCurrentRequests.isEmpty()) {
utilizedVacationCurrentDays = vacationCurrentRequests.getLast().getDaysBalance();
}
double totalVacationCurrentDays = vacationDays.get(1) - (vacationDays.get(1) - utilizedVacationCurrentDays);
double utilizedVacationPreviousDays = vacationDays.get(0);
List<TimeOffRequest> vacationPreviousRequests = requestService
.findByEmployeeAndCategory(employeeId, TimeOffRequestType.VACACION_GESTION_ANTERIOR);
if (vacationPreviousRequests != null && !vacationPreviousRequests.isEmpty()) {
utilizedVacationPreviousDays = vacationPreviousRequests.getLast().getDaysBalance();
}
double totalVacationPreviousDays = vacationDays.getFirst()
- (vacationDays.getFirst() - utilizedVacationPreviousDays);
double utilizedFixedAndMovableHolidays = calculateHolidayUtilizedDays(currentYear);
double utilizedPersonalDays = calculatePersonalDaysUtilized(isMale, currentYear);
double remainingHolidayDays = totalFixedAndMovableHolidays - utilizedFixedAndMovableHolidays;
double remainingPersonalDays = (totalPersonalDays - utilizedPersonalDays) + healthLicence;
double remainingVacationDays = totalVacationCurrentDays + totalVacationPreviousDays;
double totalAvailableDays = remainingHolidayDays + remainingPersonalDays + remainingVacationDays;
return new VerticalLayout( return new VerticalLayout(
new Span("Total feriados fijos y movibles: " + remainingHolidayDays), new Span("Total feriados: " + totalHoliday),
new Span("Total días libres personales: " + remainingPersonalDays), new Span("Total vacaciones: " + totalVacations),
new Span("Total vacaciones pendientes de uso: " + remainingVacationDays), new Span("Total días personales: " + totalPersonalDays),
new Span("TOTAL GENERAL DE DÍAS DISPONIBLES: " + totalAvailableDays) new Span("Total general: " + totalAvailableDays)
); );
} }
private double calculateHolidayDays(final List<Vacation> vacations) { private double calculateVacationDays(final Employee employee) {
return vacations.stream()
.filter(req -> req.getType() != Vacation.Type.OTHER)
.mapToDouble(Vacation::getDuration)
.sum();
}
private double calculatePersonalDays(final List<Vacation> vacations, final boolean isMale) {
return vacations.stream()
.filter(req -> req.getType() == Vacation.Type.OTHER)
.filter(req -> !getStandardExclusions().contains(req.getCategory()))
.filter(req -> !(isMale && getMaleSpecificExclusions().contains(req.getCategory())))
.filter(req -> !req.getCategory().name().startsWith("VACACION"))
.filter(req -> req.getCategory() != TimeOffRequestType.PERMISOS_DE_SALUD)
.mapToDouble(Vacation::getDuration)
.sum();
}
private List<Double> calculateVacationDays(final Employee employee) {
List<Double> vacationDays = new ArrayList<>();
if (employee.getDateOfEntry() != null) { if (employee.getDateOfEntry() != null) {
LocalDate entryDate = employee.getDateOfEntry(); LocalDate entryDate = employee.getDateOfEntry();
LocalDate today = LocalDate.now(); LocalDate today = LocalDate.now();
@ -232,48 +164,11 @@ public class RequestEmployeeView extends Div implements HasUrlParameter<String>
); );
} }
vacationDays.add(calculateVacationDaysSinceEntry(entryDate, previousVacationYearDate)); return calculateVacationDaysSinceEntry(entryDate, previousVacationYearDate)
vacationDays.add(calculateVacationDaysSinceEntry(entryDate, currentVacationYearDate)); + calculateVacationDaysSinceEntry(entryDate, currentVacationYearDate);
} else { } else {
vacationDays.add(0.0); return 0.0;
vacationDays.add(0.0);
} }
return vacationDays;
}
private double calculateHolidayUtilizedDays(final int year) {
return requests.stream()
.filter(this::verificationIsHoliday)
.filter(req -> getStartDateYear(req) == year)
.mapToDouble(TimeOffRequest::getDaysToBeTake)
.sum();
}
private double calculateVacationUtilizedDays(final int year) {
return requests.stream()
.filter(req -> req.getCategory().name().startsWith("VACACION"))
.filter(req -> getStartDateYear(req) == year || getStartDateYear(req) == year - 1)
.mapToDouble(TimeOffRequest::getDaysBalance)
.sum();
}
private double calculatePersonalDaysUtilized(final boolean isMale, final int year) {
return requests.stream()
.filter(req -> !verificationIsHoliday(req))
.filter(req -> !getStandardExclusions().contains(req.getCategory()))
.filter(req -> !(isMale && getMaleSpecificExclusions().contains(req.getCategory())))
.filter(req -> !req.getCategory().name().startsWith("VACACION"))
.filter(req -> req.getCategory() != TimeOffRequestType.PERMISOS_DE_SALUD)
.filter(req -> getStartDateYear(req) == year)
.mapToDouble(TimeOffRequest::getDaysToBeTake)
.sum();
}
private int getStartDateYear(final TimeOffRequest request) {
if (request.getStartDate() != null) {
return request.getStartDate().getYear();
}
return 0;
} }
private double calculateVacationDaysSinceEntry(final LocalDate dateOfEntry, final LocalDate date) { private double calculateVacationDaysSinceEntry(final LocalDate dateOfEntry, final LocalDate date) {
@ -341,9 +236,7 @@ public class RequestEmployeeView extends Div implements HasUrlParameter<String>
final int pageSize, final int pageSize,
final TimeOffRequestType category, final TimeOffRequestType category,
final TimeOffRequestStatus state) { final TimeOffRequestStatus state) {
requests = requestService.findRequestsByEmployeeId(employeeId); requests = requestService.findRequestsByEmployeeId(employeeId);
generateRequests();
if (category != null && !"TODOS".equals(category.name())) { if (category != null && !"TODOS".equals(category.name())) {
requests = requests.stream() requests = requests.stream()
.filter(req -> req.getCategory().equals(category)) .filter(req -> req.getCategory().equals(category))
@ -358,58 +251,6 @@ public class RequestEmployeeView extends Div implements HasUrlParameter<String>
return requests.subList(start, end); return requests.subList(start, end);
} }
public void generateRequests() {
boolean isMale = isEmployeeMale();
for (TimeOffRequestType type : TimeOffRequestType.values()) {
if (shouldIncludeRequest(type) && isValidRequestType(type, isMale)) {
TimeOffRequest request = createRequest(type);
if (isVacationExpired(request)) {
request.setState(TimeOffRequestStatus.VENCIDO);
} else {
request.setState(TimeOffRequestStatus.PENDIENTE);
}
requests.add(request);
}
}
}
private boolean isEmployeeMale() {
return employeeService.getEmployee(employeeId).getGender() == Employee.Gender.MALE;
}
private boolean isValidRequestType(final TimeOffRequestType type, final boolean isMale) {
return !getStandardExclusions().contains(type)
&& !(isMale && getMaleSpecificExclusions().contains(type))
&& type != TimeOffRequestType.TODOS;
}
private TimeOffRequest createRequest(final TimeOffRequestType type) {
TimeOffRequest request = new TimeOffRequest();
request.setCategory(type);
return request;
}
private boolean isVacationExpired(final TimeOffRequest request) {
Vacation vacation = vacationService.findVacationByCategory(request.getCategory());
if (vacation != null && vacation.getMonthOfYear() != null && vacation.getDayOfMonth() != null) {
int vacationMonth = vacation.getMonthOfYear();
int vacationDay = vacation.getDayOfMonth();
int currentMonth = LocalDate.now().getMonthValue();
int currentDay = LocalDate.now().getDayOfMonth();
return vacationMonth < currentMonth || (vacationMonth == currentMonth && vacationDay < currentDay);
}
return false;
}
private boolean shouldIncludeRequest(final TimeOffRequestType type) {
List<TimeOffRequest> existingRequest = requestService.findByEmployeeAndCategory(employeeId, type);
return existingRequest.isEmpty();
}
@Override @Override
public void setParameter(final BeforeEvent event, final String parameter) { public void setParameter(final BeforeEvent event, final String parameter) {
employeeId = UUID.fromString(parameter); employeeId = UUID.fromString(parameter);

View File

@ -63,7 +63,6 @@ public class RequestRegisterView extends VerticalLayout {
} }
private void initializeView() { private void initializeView() {
requestService.updateRequestStatuses();
configureFormFields(); configureFormFields();
configureButtons(); configureButtons();
configureBinder(); configureBinder();
@ -85,6 +84,8 @@ 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();
System.out.println("Clearing form..." + employee);
handleEmployeeSelection(event.getValue()); handleEmployeeSelection(event.getValue());
}); });
categoryComboBox.addValueChangeListener(event -> { categoryComboBox.addValueChangeListener(event -> {
@ -135,15 +136,15 @@ public class RequestRegisterView extends VerticalLayout {
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.TODOS) .filter(category -> category != TimeOffRequestType.VACACION_GESTION_ANTERIOR
&& category != TimeOffRequestType.TODOS)
.toList(); .toList();
categoryComboBox.setItems(availableCategories); categoryComboBox.setItems(availableCategories);
} }
private void onCategoryChange(final TimeOffRequestType selectedCategory) { private void onCategoryChange(final TimeOffRequestType selectedCategory) {
if (selectedCategory == TimeOffRequestType.VACACION_GESTION_ACTUAL if (selectedCategory == TimeOffRequestType.VACACION_GESTION_ACTUAL) {
|| selectedCategory == TimeOffRequestType.VACACION_GESTION_ANTERIOR) {
startDatePicker.setEnabled(true); startDatePicker.setEnabled(true);
endDatePicker.setEnabled(true); endDatePicker.setEnabled(true);
} else { } else {
@ -166,21 +167,13 @@ public class RequestRegisterView extends VerticalLayout {
.max(Comparator.comparing(TimeOffRequest::getStartDate)) .max(Comparator.comparing(TimeOffRequest::getStartDate))
.orElse(null); .orElse(null);
boolean isSpecialCategory = category == TimeOffRequestType.PERMISOS_DE_SALUD if (category == TimeOffRequestType.PERMISOS_DE_SALUD
|| category == TimeOffRequestType.VACACION_GESTION_ACTUAL || category == TimeOffRequestType.VACACION_GESTION_ACTUAL
|| category == TimeOffRequestType.VACACION_GESTION_ANTERIOR; || category == TimeOffRequestType.VACACION_GESTION_ANTERIOR) {
return latestRequest.getState() == TimeOffRequestStatus.VENCIDO
if (isSpecialCategory) { || (latestRequest.getState() == TimeOffRequestStatus.TOMADO && latestRequest.getDaysBalance() > 0);
return (latestRequest.getState() == TimeOffRequestStatus.TOMADO
&& latestRequest.getDaysBalance() > 0)
|| latestRequest.getState() == TimeOffRequestStatus.RECHAZADO
|| (latestRequest.getState() == TimeOffRequestStatus.TOMADO
&& latestRequest.getDaysBalance() == 0
&& latestRequest.getExpiration().isBefore(LocalDate.now()));
} else { } else {
return (latestRequest.getState() == TimeOffRequestStatus.TOMADO return latestRequest.getState() == TimeOffRequestStatus.VENCIDO;
&& latestRequest.getExpiration().isBefore(LocalDate.now()))
|| latestRequest.getState() == TimeOffRequestStatus.RECHAZADO;
} }
} }
@ -206,40 +199,30 @@ public class RequestRegisterView extends VerticalLayout {
vacation = vacationService.findVacationByCategory(selectedCategory); vacation = vacationService.findVacationByCategory(selectedCategory);
UUID employeeId = employeeComboBox.getValue().getId(); UUID employeeId = employeeComboBox.getValue().getId();
List<TimeOffRequest> requests = requestService.findByEmployeeAndCategory(employeeId, selectedCategory); List<TimeOffRequest> requests = requestService.findByEmployeeAndCategory(employeeId, selectedCategory);
if (vacation != null) { if (vacation != null) {
TimeOffRequest requestWithBalance = requests.stream() TimeOffRequest requestWithBalance = requests.stream()
.filter(request -> request.getDaysBalance() > 0 .filter(request -> request.getDaysBalance() > 0
&& request.getState() != TimeOffRequestStatus.VENCIDO && request.getState() != TimeOffRequestStatus.VENCIDO)
&& request.getState() != TimeOffRequestStatus.RECHAZADO)
.max(Comparator.comparing(TimeOffRequest::getStartDate)) .max(Comparator.comparing(TimeOffRequest::getStartDate))
.orElse(null); .orElse(null);
if (requestWithBalance != null) { if (requestWithBalance != null) {
if (requestWithBalance.getState() == TimeOffRequestStatus.TOMADO if (requestWithBalance.getState() == TimeOffRequestStatus.TOMADO) {
&& requestWithBalance.getDaysBalance() > 0) {
availableDaysField.setValue(requestWithBalance.getDaysBalance()); availableDaysField.setValue(requestWithBalance.getDaysBalance());
} else { } else if (requestWithBalance.getState() == TimeOffRequestStatus.VENCIDO) {
availableDaysField.setValue(vacation.getDuration()); availableDaysField.setValue(vacation.getDuration());
} }
} else if (selectedCategory == TimeOffRequestType.VACACION_GESTION_ACTUAL } else if (vacation.getCategory() == TimeOffRequestType.VACACION_GESTION_ACTUAL) {
|| selectedCategory == TimeOffRequestType.VACACION_GESTION_ANTERIOR) {
LocalDate dateOfEntry = employeeComboBox.getValue().getDateOfEntry(); LocalDate dateOfEntry = employeeComboBox.getValue().getDateOfEntry();
LocalDate currentDate = LocalDate.now(); LocalDate currentDate = LocalDate.now();
long yearsOfService = ChronoUnit.YEARS.between(dateOfEntry, currentDate); long yearsOfService = ChronoUnit.YEARS.between(dateOfEntry, currentDate);
if (selectedCategory == TimeOffRequestType.VACACION_GESTION_ANTERIOR) {
yearsOfService -= 1;
}
if (yearsOfService > 10) { if (yearsOfService > 10) {
availableDaysField.setValue(30.0); availableDaysField.setValue((double) 30);
} else if (yearsOfService > 5) { } else if (yearsOfService > 5) {
availableDaysField.setValue(20.0); availableDaysField.setValue((double) 20);
} else if (yearsOfService > 1) { } else if (yearsOfService > 1) {
availableDaysField.setValue(15.0); availableDaysField.setValue((double) 15);
} else { } else {
availableDaysField.setValue(0.0); availableDaysField.setValue((double) 0);
} }
} else { } else {
availableDaysField.setValue(vacation.getDuration()); availableDaysField.setValue(vacation.getDuration());
@ -265,11 +248,7 @@ public class RequestRegisterView extends VerticalLayout {
} }
if (startDate != null) { if (startDate != null) {
if (vacation.getExpiration() != null) {
endDate = startDate.plusDays(vacation.getExpiration().intValue() - 1); endDate = startDate.plusDays(vacation.getExpiration().intValue() - 1);
} else {
endDate = LocalDate.of(startDate.getYear(), 12, 31);
}
} else { } else {
startDate = LocalDate.now(); startDate = LocalDate.now();
} }
@ -288,23 +267,19 @@ public class RequestRegisterView extends VerticalLayout {
.map(request -> request.getStartDate().getYear()) .map(request -> request.getStartDate().getYear())
.orElse(LocalDate.now().getYear()); .orElse(LocalDate.now().getYear());
if (previousRequests.getLast().getState() != TimeOffRequestStatus.RECHAZADO) {
lastRequestYear = lastRequestYear + 1;
}
int currentYear = LocalDate.now().getYear(); int currentYear = LocalDate.now().getYear();
return Math.max(lastRequestYear, currentYear); return Math.max(lastRequestYear + 1, currentYear);
} }
private LocalDate determineStartDate(final Vacation vacation, final int startYear) { private LocalDate determineStartDate(final Vacation vacation, final int startYear) {
if (vacation.getCategory() == TimeOffRequestType.CUMPLEAÑOS && employee.getBirthday() != null) {
return LocalDate.of(startYear, employee.getBirthday().getMonth(), employee.getBirthday().getDayOfMonth());
}
if (vacation.getMonthOfYear() != null && vacation.getDayOfMonth() != null) { if (vacation.getMonthOfYear() != null && vacation.getDayOfMonth() != null) {
return LocalDate.of(startYear, vacation.getMonthOfYear().intValue(), vacation.getDayOfMonth().intValue()); 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) { if (vacation.getCategory() == TimeOffRequestType.PERMISOS_DE_SALUD) {
return LocalDate.now(); return LocalDate.now();
} }
@ -316,9 +291,7 @@ public class RequestRegisterView extends VerticalLayout {
startDatePicker.setValue(startDate); startDatePicker.setValue(startDate);
if ((vacation.getDuration() != null && vacation.getDuration() == 0.5) if ((vacation.getDuration() != null && vacation.getDuration() == 0.5)
|| vacation.getCategory() == TimeOffRequestType.PERMISOS_DE_SALUD || vacation.getCategory() == TimeOffRequestType.PERMISOS_DE_SALUD) {
|| vacation.getCategory() == TimeOffRequestType.CUMPLEAÑOS) {
endDatePicker.setValue(startDate); endDatePicker.setValue(startDate);
} else { } else {
int durationDays = (vacation.getDuration() != null ? vacation.getDuration().intValue() - 1 : 0); int durationDays = (vacation.getDuration() != null ? vacation.getDuration().intValue() - 1 : 0);
@ -357,7 +330,7 @@ public class RequestRegisterView extends VerticalLayout {
double balanceDays = calculateBalanceDays(availableDays, daysToBeTakenField.getValue()); double balanceDays = calculateBalanceDays(availableDays, daysToBeTakenField.getValue());
balanceDaysField.setValue(balanceDays); balanceDaysField.setValue(balanceDays);
if (balanceDays < 0.0) { if (balanceDays < 0) {
clearFields(); clearFields();
} }
} }
@ -372,12 +345,7 @@ public class RequestRegisterView extends VerticalLayout {
} }
private void setDaysToBeTakenField(final double daysToBeTaken) { private void setDaysToBeTakenField(final double daysToBeTaken) {
if (vacation.getCategory() == TimeOffRequestType.PERMISOS_DE_SALUD if (vacation.getCategory() == TimeOffRequestType.PERMISOS_DE_SALUD) {
|| vacation.getCategory() == TimeOffRequestType.CUMPLEAÑOS
|| vacation.getCategory() == TimeOffRequestType.DIA_DEL_PADRE
|| vacation.getCategory() == TimeOffRequestType.DIA_DE_LA_MADRE
|| vacation.getCategory() == TimeOffRequestType.DIA_DE_LA_MUJER_INTERNACIONAL
|| vacation.getCategory() == TimeOffRequestType.DIA_DE_LA_MUJER_NACIONAL) {
daysToBeTakenField.setValue(0.5); daysToBeTakenField.setValue(0.5);
} else { } else {
daysToBeTakenField.setValue(daysToBeTaken); daysToBeTakenField.setValue(daysToBeTaken);
@ -442,7 +410,7 @@ public class RequestRegisterView extends VerticalLayout {
request.setStartDate(startDatePicker.getValue()); request.setStartDate(startDatePicker.getValue());
request.setAvailableDays(availableDaysField.getValue()); request.setAvailableDays(availableDaysField.getValue());
request.setExpiration(endDate != null ? endDate : endDatePicker.getValue()); request.setExpiration(endDate != null ? endDate : endDatePicker.getValue());
request.setState(TimeOffRequestStatus.SOLICITADO); request.setState(TimeOffRequestStatus.PENDIENTE);
return request; return request;
} }
@ -450,10 +418,7 @@ public class RequestRegisterView extends VerticalLayout {
List<TimeOffRequest> existingRequests = List<TimeOffRequest> existingRequests =
requestService.findByEmployeeAndCategory(employee.getId(), request.getCategory()); requestService.findByEmployeeAndCategory(employee.getId(), request.getCategory());
int maxRequests = request.getCategory() != TimeOffRequestType.PERMISOS_DE_SALUD int maxRequests = request.getCategory() == TimeOffRequestType.PERMISOS_DE_SALUD ? 4 : 2;
&& !request.getCategory().name().startsWith("VACACION")
&& request.getCategory() != TimeOffRequestType.CUMPLEAÑOS
? 2 : 1;
if (existingRequests.size() >= maxRequests) { if (existingRequests.size() >= maxRequests) {
existingRequests.stream() existingRequests.stream()

View File

@ -57,7 +57,6 @@ public class RequestsListView extends Main {
} }
private void initializeView() { private void initializeView() {
requestService.updateRequestStatuses();
setupFilters(); setupFilters();
setupRequestGrid(); setupRequestGrid();
add(requestGrid); add(requestGrid);
@ -164,29 +163,8 @@ public class RequestsListView extends Main {
private String getGeneralTotal(final Employee employee) { private String getGeneralTotal(final Employee employee) {
List<TimeOffRequest> employeeRequests = requestService.findRequestsByEmployeeId(employee.getId()); List<TimeOffRequest> employeeRequests = requestService.findRequestsByEmployeeId(employee.getId());
List<Vacation> vacations = vacationService.findVacations(); List<Vacation> vacations = vacationService.findVacations();
List<Double> vacationDays = calculateVacationDays(employee);
double utilizedVacationCurrentDays = vacationDays.get(1);
List<TimeOffRequest> vacationCurrentRequests = requestService
.findByEmployeeAndCategory(employee.getId(), TimeOffRequestType.VACACION_GESTION_ACTUAL);
if (vacationCurrentRequests != null && !vacationCurrentRequests.isEmpty()) {
utilizedVacationCurrentDays = vacationCurrentRequests.getLast().getDaysBalance();
}
double totalVacationCurrentDays = vacationDays.get(1) - (vacationDays.get(1) - utilizedVacationCurrentDays);
double utilizedVacationPreviousDays = vacationDays.get(0);
List<TimeOffRequest> vacationPreviousRequests = requestService
.findByEmployeeAndCategory(employee.getId(), TimeOffRequestType.VACACION_GESTION_ANTERIOR);
if (vacationPreviousRequests != null && !vacationPreviousRequests.isEmpty()) {
utilizedVacationPreviousDays = vacationPreviousRequests.getLast().getDaysBalance();
}
double totalVacationPreviousDays = vacationDays.getFirst()
- (vacationDays.getFirst() - utilizedVacationPreviousDays);
double totalUtilized = calculateTotalUtilized(employeeRequests); double totalUtilized = calculateTotalUtilized(employeeRequests);
double totalVacations = totalVacationCurrentDays + totalVacationPreviousDays; double totalVacations = calculateVacationDays(employee);
double totalAvailable = calculateTotalAvailable(vacations, employeeRequests, employee); double totalAvailable = calculateTotalAvailable(vacations, employeeRequests, employee);
double generalTotal = totalAvailable + totalVacations - totalUtilized; double generalTotal = totalAvailable + totalVacations - totalUtilized;
@ -213,24 +191,13 @@ public class RequestsListView extends Main {
} }
private double calculateTotalUtilized(final List<TimeOffRequest> employeeRequests) { private double calculateTotalUtilized(final List<TimeOffRequest> employeeRequests) {
int currentYear = LocalDate.now().getYear();
return employeeRequests.stream() return employeeRequests.stream()
.filter(Objects::nonNull) .filter(Objects::nonNull)
.filter(request -> request.getCategory() != TimeOffRequestType.PERMISOS_DE_SALUD)
.filter(request -> request.getCategory() != TimeOffRequestType.VACACION_GESTION_ACTUAL)
.filter(request -> request.getCategory() != TimeOffRequestType.VACACION_GESTION_ANTERIOR)
.filter(request -> request.getStartDate() != null && (
request.getStartDate().getYear() == currentYear
|| (request.getCategory().name().startsWith("VACACION")
&& request.getStartDate().getYear() == currentYear - 1)
))
.mapToDouble(request -> request.getDaysToBeTake() != null ? request.getDaysToBeTake() : 0.0) .mapToDouble(request -> request.getDaysToBeTake() != null ? request.getDaysToBeTake() : 0.0)
.sum(); .sum();
} }
private List<Double> calculateVacationDays(final Employee employee) { private double calculateVacationDays(final Employee employee) {
List<Double> vacationDays = new ArrayList<>();
if (employee.getDateOfEntry() != null) { if (employee.getDateOfEntry() != null) {
LocalDate entryDate = employee.getDateOfEntry(); LocalDate entryDate = employee.getDateOfEntry();
LocalDate today = LocalDate.now(); LocalDate today = LocalDate.now();
@ -266,13 +233,11 @@ public class RequestsListView extends Main {
); );
} }
vacationDays.add(calculateVacationDaysSinceEntry(entryDate, previousVacationYearDate)); return calculateVacationDaysSinceEntry(entryDate, previousVacationYearDate)
vacationDays.add(calculateVacationDaysSinceEntry(entryDate, currentVacationYearDate)); + calculateVacationDaysSinceEntry(entryDate, currentVacationYearDate);
} else { } else {
vacationDays.add(0.0); return 0.0;
vacationDays.add(0.0);
} }
return vacationDays;
} }
private double calculateTotalAvailable(final List<Vacation> vacations, final List<TimeOffRequest> employeeRequests, private double calculateTotalAvailable(final List<Vacation> vacations, final List<TimeOffRequest> employeeRequests,
@ -283,16 +248,8 @@ public class RequestsListView extends Main {
.map(TimeOffRequest::getCategory) .map(TimeOffRequest::getCategory)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
double healthLicence = 2; return vacations.stream()
List<TimeOffRequest> healthRequests = requestService
.findByEmployeeAndCategory(employee.getId(), TimeOffRequestType.PERMISOS_DE_SALUD);
if (healthRequests != null && !healthRequests.isEmpty()) {
healthLicence = healthRequests.getLast().getDaysBalance();
}
double totalAvailable = vacations.stream()
.filter(Objects::nonNull) .filter(Objects::nonNull)
.filter(vacation -> vacation.getCategory() != TimeOffRequestType.PERMISOS_DE_SALUD)
.filter(vacation -> shouldIncludeVacation( .filter(vacation -> shouldIncludeVacation(
vacation, vacation,
excludedCategories, excludedCategories,
@ -301,8 +258,6 @@ public class RequestsListView extends Main {
)) ))
.mapToDouble(vacation -> vacation.getDuration() != null ? vacation.getDuration() : 0.0) .mapToDouble(vacation -> vacation.getDuration() != null ? vacation.getDuration() : 0.0)
.sum(); .sum();
return totalAvailable + healthLicence;
} }
private double calculateVacationDaysSinceEntry(final LocalDate dateOfEntry, final LocalDate date) { private double calculateVacationDaysSinceEntry(final LocalDate dateOfEntry, final LocalDate date) {

View File

@ -32,7 +32,7 @@ INSERT INTO vacation (id, version, category, month_of_year, day_of_month, durati
INSERT INTO vacation (id, version, category, month_of_year, day_of_month, duration, expiration, type) VALUES ('c23e4567-e89b-12d3-a456-42661417400b', 1, 'DIA_DE_TODOS_LOS_DIFUNTOS', 11, 2, 1, 30, 'MOVABLE'); INSERT INTO vacation (id, version, category, month_of_year, day_of_month, duration, expiration, type) VALUES ('c23e4567-e89b-12d3-a456-42661417400b', 1, 'DIA_DE_TODOS_LOS_DIFUNTOS', 11, 2, 1, 30, 'MOVABLE');
INSERT INTO vacation (id, version, category, month_of_year, day_of_month, duration, type) VALUES ('c23e4567-e89b-12d3-a456-42661417400c', 1, 'CUMPLEAÑOS', 12, 31, 0.5, 'OTHER'); INSERT INTO vacation (id, version, category, duration, expiration, type) VALUES ('c23e4567-e89b-12d3-a456-42661417400c', 1, 'CUMPLEAÑOS', 0.5, 365, 'OTHER');
INSERT INTO vacation (id, version, category, duration, expiration, type) VALUES ('c23e4567-e89b-12d3-a456-42661417400d', 1, 'MATERNIDAD', 90, 90, 'OTHER'); INSERT INTO vacation (id, version, category, duration, expiration, type) VALUES ('c23e4567-e89b-12d3-a456-42661417400d', 1, 'MATERNIDAD', 90, 90, 'OTHER');
INSERT INTO vacation (id, version, category, duration, expiration, type) VALUES ('c23e4567-e89b-12d3-a456-42661417400e', 1, 'PATERNIDAD', 3, 3, 'OTHER'); INSERT INTO vacation (id, version, category, duration, expiration, type) VALUES ('c23e4567-e89b-12d3-a456-42661417400e', 1, 'PATERNIDAD', 3, 3, 'OTHER');
INSERT INTO vacation (id, version, category, duration, expiration, type) VALUES ('c23e4567-e89b-12d3-a456-42661417400f', 1, 'MATRIMONIO', 3, 3, 'OTHER'); INSERT INTO vacation (id, version, category, duration, expiration, type) VALUES ('c23e4567-e89b-12d3-a456-42661417400f', 1, 'MATRIMONIO', 3, 3, 'OTHER');
@ -68,25 +68,25 @@ insert into employee (id, version, username, first_name, last_name, status, team
insert into time_off_request (id, version, employee_id, category, state, available_days, expiration, start_date, end_date, days_to_be_take, days_balance) insert into time_off_request (id, version, employee_id, category, state, available_days, expiration, start_date, end_date, days_to_be_take, days_balance)
values ('9d6f12ba-e341-4e7a-b8a6-cab0982bd8c1', 1, '5c6f11fe-c341-4be7-a9a6-bba0081ad7c6', 'PATERNIDAD', 'APROBADO', 3, '2024-10-03', '2024-10-01', '2024-10-03', 3, 0); values ('9d6f12ba-e341-4e7a-b8a6-cab0982bd8c1', 1, '5c6f11fe-c341-4be7-a9a6-bba0081ad7c6', 'PATERNIDAD', 'VENCIDO', 3, '2024-10-03', '2024-10-01', '2024-10-03', 3, 0);
insert into time_off_request (id, version, employee_id, category, state, available_days, expiration, start_date, end_date, days_to_be_take, days_balance) insert into time_off_request (id, version, employee_id, category, state, available_days, expiration, start_date, end_date, days_to_be_take, days_balance)
values ('9a6f12ba-e111-4e7a-b8a6-caa0982bd8a1', 1, '5c6f11fe-c341-4be7-a9a6-bba0081ad7c6', 'AÑO_NUEVO', 'APROBADO', 1, '2024-01-01', '2024-01-01', '2024-01-01', 1, 0); values ('9a6f12ba-e111-4e7a-b8a6-caa0982bd8a1', 1, '5c6f11fe-c341-4be7-a9a6-bba0081ad7c6', 'AÑO_NUEVO', 'VENCIDO', 1, '2024-01-01', '2024-01-01', '2024-01-01', 1, 0);
insert into time_off_request (id, version, employee_id, category, state, available_days, expiration, start_date, end_date, days_to_be_take, days_balance) insert into time_off_request (id, version, employee_id, category, state, available_days, expiration, start_date, end_date, days_to_be_take, days_balance)
values ('9b6f12ba-e222-4e7a-b8a6-caa0982bd8b2', 1, '5c6f11fe-c341-4be7-a9a6-bba0081ad7c6', 'LUNES_CARNAVAL', 'APROBADO', 1, '2025-02-12', '2025-02-12', '2025-02-12', 1, 0); values ('9b6f12ba-e222-4e7a-b8a6-caa0982bd8b2', 1, '5c6f11fe-c341-4be7-a9a6-bba0081ad7c6', 'LUNES_CARNAVAL', 'APROBADO', 1, '2025-02-12', '2025-02-12', '2025-02-12', 1, 0);
insert into time_off_request (id, version, employee_id, category, state, available_days, expiration, start_date, end_date, days_to_be_take, days_balance) insert into time_off_request (id, version, employee_id, category, state, available_days, expiration, start_date, end_date, days_to_be_take, days_balance)
values ('9c6f12ba-e333-4e7a-b8a6-caa0982bd8c3', 1, '5c6f11fe-c341-4be7-a9a6-bba0081ad7c6', 'MARTES_CARNAVAL', 'SOLICITADO', 1, '2025-02-13', '2025-02-13', '2025-02-13', 1, 0); values ('9c6f12ba-e333-4e7a-b8a6-caa0982bd8c3', 1, '5c6f11fe-c341-4be7-a9a6-bba0081ad7c6', 'MARTES_CARNAVAL', 'EN_REVISION', 1, '2025-02-13', '2025-02-13', '2025-02-13', 1, 0);
insert into time_off_request (id, version, employee_id, category, state, available_days, expiration, start_date, end_date, days_to_be_take, days_balance) insert into time_off_request (id, version, employee_id, category, state, available_days, expiration, start_date, end_date, days_to_be_take, days_balance)
values ('9d6f12ba-e444-4e7a-b8a6-caa0982bd8d4', 1, '5c6f11fe-c341-4be7-a9a6-bba0081ad7c6', 'VIERNES_SANTO', 'APROBADO', 1, '2024-03-29', '2024-03-29', '2024-03-29', 1, 0); values ('9d6f12ba-e444-4e7a-b8a6-caa0982bd8d4', 1, '5c6f11fe-c341-4be7-a9a6-bba0081ad7c6', 'VIERNES_SANTO', 'APROBADO', 1, '2024-03-29', '2024-03-29', '2024-03-29', 1, 0);
insert into time_off_request (id, version, employee_id, category, state, available_days, expiration, start_date, end_date, days_to_be_take, days_balance) insert into time_off_request (id, version, employee_id, category, state, available_days, expiration, start_date, end_date, days_to_be_take, days_balance)
values ('9e6f12ba-e555-4e7a-b8a6-caa0982bd8e5', 1, '5c6f11fe-c341-4be7-a9a6-bba0081ad7c6', 'VACACION_GESTION_ACTUAL', 'APROBADO', 30, '2025-11-01', '2023-11-01', '2023-11-30', 30, 0); values ('9e6f12ba-e555-4e7a-b8a6-caa0982bd8e5', 1, '5c6f11fe-c341-4be7-a9a6-bba0081ad7c6', 'VACACION_GESTION_ACTUAL', 'APROBADO', 30, '2024-11-01', '2022-11-01', '2022-11-30', 30, 0);
insert into time_off_request (id, version, employee_id, category, state, available_days, expiration, start_date, end_date, days_to_be_take, days_balance) insert into time_off_request (id, version, employee_id, category, state, available_days, expiration, start_date, end_date, days_to_be_take, days_balance)
values ('8c653f2a-f9a3-4d67-b3b6-12ad98fe0983', 1, 'f6ab3c6d-7078-45f6-9b22-4e37637bfec6', 'DIA_DEL_TRABAJADOR', 'APROBADO', 1, '2024-05-01', '2024-05-01', '2024-05-01', 1, 0); values ('8c653f2a-f9a3-4d67-b3b6-12ad98fe0983', 1, 'f6ab3c6d-7078-45f6-9b22-4e37637bfec6', 'DIA_DEL_TRABAJADOR', 'APROBADO', 1, '2024-05-01', '2024-05-01', '2024-05-01', 1, 0);
insert into time_off_request (id, version, employee_id, category, state, available_days, expiration, start_date, end_date, days_to_be_take, days_balance) insert into time_off_request (id, version, employee_id, category, state, available_days, expiration, start_date, end_date, days_to_be_take, days_balance)
values ('fb9d9d75-b2ab-4ea4-b8b3-0a8f89e5c123', 1, '2e2293b1-3f9a-4f3d-abc8-32639b0a5e15', 'DIA_DE_LA_INDEPENDENCIA', 'APROBADO', 1, '2024-08-06', '2024-08-06', '2024-08-06', 1, 0); values ('fb9d9d75-b2ab-4ea4-b8b3-0a8f89e5c123', 1, '2e2293b1-3f9a-4f3d-abc8-32639b0a5e15', 'DIA_DE_LA_INDEPENDENCIA', 'APROBADO', 1, '2024-08-06', '2024-08-06', '2024-08-06', 1, 0);
insert into time_off_request (id, version, employee_id, category, state, available_days, expiration, start_date, end_date, days_to_be_take, days_balance) insert into time_off_request (id, version, employee_id, category, state, available_days, expiration, start_date, end_date, days_to_be_take, days_balance)
values ('6fdc47a8-127b-41c4-8d12-7fc12098ab12', 1, 'b2436b82-7b9f-4f0d-9463-f2c3173a45c3', 'DIA_DE_TODOS_LOS_DIFUNTOS', 'SOLICITADO', 1, '2025-12-01', '2025-11-02', '2025-11-02', 1, 0); values ('6fdc47a8-127b-41c4-8d12-7fc12098ab12', 1, 'b2436b82-7b9f-4f0d-9463-f2c3173a45c3', 'DIA_DE_TODOS_LOS_DIFUNTOS', 'PENDIENTE', 1, '2025-12-01', '2025-11-02', '2025-11-02', 1, 0);
insert into time_off_request (id, version, employee_id, category, state, available_days, expiration, start_date, end_date, days_to_be_take, days_balance) insert into time_off_request (id, version, employee_id, category, state, available_days, expiration, start_date, end_date, days_to_be_take, days_balance)
values ('12ec8b74-983d-4a17-b67e-134f45ae904c', 1, '5c1a7b82-832d-4f24-8377-54b77b91b6a8', 'AÑO_NUEVO', 'SOLICITADO', 1, '2025-01-01', '2025-01-01', '2025-01-01', 1, 0); values ('12ec8b74-983d-4a17-b67e-134f45ae904c', 1, '5c1a7b82-832d-4f24-8377-54b77b91b6a8', 'AÑO_NUEVO', 'PENDIENTE', 1, '2025-01-01', '2025-01-01', '2025-01-01', 1, 0);
insert into time_off_request (id, version, employee_id, category, state, available_days, expiration, start_date, end_date, days_to_be_take, days_balance) insert into time_off_request (id, version, employee_id, category, state, available_days, expiration, start_date, end_date, days_to_be_take, days_balance)
values ('89bc4b2a-943f-487c-a9f3-bacf78145e67', 1, 'cba3efb7-32bc-44be-9fdc-fc5e4f211254', 'LUNES_CARNAVAL', 'APROBADO', 1, '2024-02-12', '2024-02-12', '2024-02-12', 1, 0); values ('89bc4b2a-943f-487c-a9f3-bacf78145e67', 1, 'cba3efb7-32bc-44be-9fdc-fc5e4f211254', 'LUNES_CARNAVAL', 'APROBADO', 1, '2024-02-12', '2024-02-12', '2024-02-12', 1, 0);