diff --git a/src/main/java/com/primefactorsolutions/service/VacationService.java b/src/main/java/com/primefactorsolutions/service/VacationService.java index 056b73c..15db4b0 100644 --- a/src/main/java/com/primefactorsolutions/service/VacationService.java +++ b/src/main/java/com/primefactorsolutions/service/VacationService.java @@ -11,7 +11,7 @@ import org.springframework.stereotype.Service; public class VacationService { private final VacationRepository vacationRepository; - public Vacation findVacation(final TimeOffRequestType category) { + public Vacation findVacationByCategory(final TimeOffRequestType category) { return vacationRepository.findByCategory(category); } diff --git a/src/main/java/com/primefactorsolutions/views/RequestRegisterView.java b/src/main/java/com/primefactorsolutions/views/RequestRegisterView.java index 0a5f32b..3dcd9c3 100644 --- a/src/main/java/com/primefactorsolutions/views/RequestRegisterView.java +++ b/src/main/java/com/primefactorsolutions/views/RequestRegisterView.java @@ -3,6 +3,7 @@ package com.primefactorsolutions.views; import com.primefactorsolutions.model.*; import com.primefactorsolutions.service.EmployeeService; import com.primefactorsolutions.service.TimeOffRequestService; +import com.primefactorsolutions.service.VacationService; import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.combobox.ComboBox; import com.vaadin.flow.component.datepicker.DatePicker; @@ -17,6 +18,7 @@ import com.vaadin.flow.spring.annotation.SpringComponent; import jakarta.annotation.security.PermitAll; import org.springframework.context.annotation.Scope; +import java.time.LocalDate; import java.util.List; @SpringComponent @@ -36,15 +38,20 @@ public class RequestRegisterView extends VerticalLayout { private final TimeOffRequestService requestService; private final EmployeeService employeeService; + private final VacationService vacationService; + private final Binder binder; + private LocalDate endDate; private Button saveButton; private Button closeButton; public RequestRegisterView(final TimeOffRequestService requestService, - final EmployeeService employeeService) { + final EmployeeService employeeService, + final VacationService vacationService) { this.requestService = requestService; this.employeeService = employeeService; + this.vacationService = vacationService; this.binder = new Binder<>(TimeOffRequest.class); configureFormFields(); @@ -58,6 +65,71 @@ public class RequestRegisterView extends VerticalLayout { employeeComboBox.setItems(employees); employeeComboBox.setItemLabelGenerator(emp -> emp.getFirstName() + " " + emp.getLastName()); categoryComboBox.setItems(TimeOffRequestType.values()); + categoryComboBox.addValueChangeListener(event -> updateAvailableDays(event.getValue())); + startDatePicker.addValueChangeListener(event -> updateDatePickerMinValues()); + endDatePicker.addValueChangeListener(event -> calculateDays()); + availableDaysField.setReadOnly(true); + daysToBeTakenField.setReadOnly(true); + balanceDaysField.setReadOnly(true); + } + + private void updateAvailableDays(TimeOffRequestType selectedCategory) { + if (selectedCategory != null) { + Vacation vacation = vacationService.findVacationByCategory(selectedCategory); + if (vacation != null) { + availableDaysField.setValue(vacation.getDuration()); + setDatePickerLimits(vacation); + } + } + } + + private void setDatePickerLimits(Vacation vacation) { + LocalDate startDate = vacation.getVacationDate(); + endDate = startDate.plusDays(vacation.getExpiration().intValue() - 1); + startDatePicker.setMin(startDate); + startDatePicker.setMax(endDate); + endDatePicker.setMin(startDate); + endDatePicker.setMax(endDate); + + startDatePicker.clear(); + endDatePicker.clear(); + getUI().ifPresent(ui -> ui.access(() -> { + startDatePicker.setInitialPosition(startDate); + })); + } + + private void updateDatePickerMinValues() { + LocalDate startDate = startDatePicker.getValue(); + if (startDate != null) { + endDatePicker.setMin(startDate); + endDatePicker.setInitialPosition(startDate); + calculateDays(); + } + } + + private void calculateDays() { + LocalDate startDate = startDatePicker.getValue(); + LocalDate endDate = endDatePicker.getValue(); + Double availableDays = availableDaysField.getValue(); + + if (startDate != null && endDate != null) { + if (startDate.isAfter(endDate)) { + endDatePicker.clear(); + return; + } + + long daysToBeTaken = java.time.temporal.ChronoUnit.DAYS.between(startDate, endDate) + 1; + daysToBeTakenField.setValue((double) daysToBeTaken); + + double balanceDays = availableDays - daysToBeTaken; + if (balanceDays < 0) { + endDatePicker.clear(); + daysToBeTakenField.clear(); + balanceDaysField.clear(); + } else { + balanceDaysField.setValue(balanceDays); + } + } } private void configureButtons() { @@ -74,6 +146,9 @@ public class RequestRegisterView extends VerticalLayout { .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); @@ -83,11 +158,9 @@ public class RequestRegisterView extends VerticalLayout { .bind(TimeOffRequest::getEndDate, TimeOffRequest::setEndDate); binder.forField(daysToBeTakenField) - .asRequired("Days to be taken is required") .bind(TimeOffRequest::getDaysToBeTake, TimeOffRequest::setDaysToBeTake); binder.forField(balanceDaysField) - .asRequired("Balance days is required") .bind(TimeOffRequest::getDaysBalance, TimeOffRequest::setDaysBalance); binder.setBean(new TimeOffRequest()); @@ -98,9 +171,9 @@ public class RequestRegisterView extends VerticalLayout { new H3("Add Vacation Request"), employeeComboBox, categoryComboBox, + availableDaysField, startDatePicker, endDatePicker, - availableDaysField, daysToBeTakenField, balanceDaysField, new HorizontalLayout(saveButton, closeButton) @@ -110,6 +183,8 @@ public class RequestRegisterView extends VerticalLayout { private void saveRequest() { if (binder.validate().isOk()) { TimeOffRequest request = binder.getBean(); + request.setExpiration(endDate); + request.setState(TimeOffRequestStatus.REQUESTED); requestService.saveTimeOffRequest(request); Notification.show("Request saved successfully."); closeForm(); diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index 82b4fbb..39efdb3 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -16,13 +16,13 @@ INSERT INTO team (id, version, name) VALUES ('c3a8a7b1-f2d9-48c0-86ea-f215c2e6b3 INSERT INTO team (id, version, name) VALUES ('8f6b61e7-efb2-4de7-b8ed-7438c9d8babe', 1, 'GHI'); -INSERT INTO vacation (id, version, category, vacation_date, duration, expiration, type) VALUES ('123e4567-e89b-12d3-a456-426614174000', 1, 'NEW_YEAR', '2024-01-01', 1, 0, 'FIXED'); -INSERT INTO vacation (id, version, category, vacation_date, duration, expiration, type) VALUES ('223e4567-e89b-12d3-a456-426614174001', 1, 'MONDAY_CARNIVAL', '2024-02-12', 1, 0, 'FIXED'); -INSERT INTO vacation (id, version, category, vacation_date, duration, expiration, type) VALUES ('323e4567-e89b-12d3-a456-426614174002', 1, 'TUESDAY_CARNIVAL', '2024-02-13', 1, 0, 'FIXED'); -INSERT INTO vacation (id, version, category, vacation_date, duration, expiration, type) VALUES ('423e4567-e89b-12d3-a456-426614174003', 1, 'GOOD_FRIDAY', '2024-03-29', 1, 0, 'FIXED'); -INSERT INTO vacation (id, version, category, vacation_date, duration, expiration, type) VALUES ('523e4567-e89b-12d3-a456-426614174004', 1, 'LABOR_DAY', '2024-05-01', 1, 0, 'FIXED'); -INSERT INTO vacation (id, version, category, vacation_date, duration, expiration, type) VALUES ('623e4567-e89b-12d3-a456-426614174005', 1, 'INDEPENDENCE_DAY', '2024-08-06', 1, 0, 'FIXED'); -INSERT INTO vacation (id, version, category, vacation_date, duration, expiration, type) VALUES ('723e4567-e89b-12d3-a456-426614174006', 1, 'CHRISTMAS', '2024-12-25', 1, 0, 'FIXED'); +INSERT INTO vacation (id, version, category, vacation_date, duration, expiration, type) VALUES ('123e4567-e89b-12d3-a456-426614174000', 1, 'NEW_YEAR', '2024-01-01', 1, 1, 'FIXED'); +INSERT INTO vacation (id, version, category, vacation_date, duration, expiration, type) VALUES ('223e4567-e89b-12d3-a456-426614174001', 1, 'MONDAY_CARNIVAL', '2024-02-12', 1, 1, 'FIXED'); +INSERT INTO vacation (id, version, category, vacation_date, duration, expiration, type) VALUES ('323e4567-e89b-12d3-a456-426614174002', 1, 'TUESDAY_CARNIVAL', '2024-02-13', 1, 1, 'FIXED'); +INSERT INTO vacation (id, version, category, vacation_date, duration, expiration, type) VALUES ('423e4567-e89b-12d3-a456-426614174003', 1, 'GOOD_FRIDAY', '2024-03-29', 1, 1, 'FIXED'); +INSERT INTO vacation (id, version, category, vacation_date, duration, expiration, type) VALUES ('523e4567-e89b-12d3-a456-426614174004', 1, 'LABOR_DAY', '2024-05-01', 1, 1, 'FIXED'); +INSERT INTO vacation (id, version, category, vacation_date, duration, expiration, type) VALUES ('623e4567-e89b-12d3-a456-426614174005', 1, 'INDEPENDENCE_DAY', '2024-08-06', 1, 1, 'FIXED'); +INSERT INTO vacation (id, version, category, vacation_date, duration, expiration, type) VALUES ('723e4567-e89b-12d3-a456-426614174006', 1, 'CHRISTMAS', '2024-12-25', 1, 1, 'FIXED'); INSERT INTO vacation (id, version, category, vacation_date, duration, expiration, type) VALUES ('823e4567-e89b-12d3-a456-426614174007', 1, 'PRURINATIONAL_STATE_DAY', '2024-01-21', 1, 30, 'MOVABLE');