From 17556e5701442e9c2a7e219c5d93734812344ebe Mon Sep 17 00:00:00 2001 From: Dominic Rogetzer Date: Mon, 18 Jun 2018 20:13:05 +0200 Subject: Rename 'einsatzverwaltung' to 'missioncontrol' + remove TODO [#25963] --- .../groupphase/application/MainApplication.java | 4 +- .../controller/ArchiveOperationController.java | 213 ------------ .../controller/CreateCarController.java | 231 ------------- .../controller/CreateNewEmployeeController.java | 174 ---------- .../controller/CreateOperationController.java | 371 --------------------- .../controller/CustomListItemController.java | 24 -- .../DetailArchiveOperationController.java | 77 ----- .../controller/EmployeeListController.java | 133 -------- .../controller/EmployeeListItemController.java | 87 ----- .../controller/FilterEmployeesController.java | 65 ---- .../einsatzverwaltung/controller/Helper.java | 34 -- .../controller/ManageEmployeesController.java | 120 ------- .../controller/OperationDetailsController.java | 169 ---------- .../controller/OperationInArchiveController.java | 65 ---- .../controller/RegistrationWindowController.java | 279 ---------------- .../controller/VehiclePaneController.java | 118 ------- .../einsatzverwaltung/dao/EmployeeDAO.java | 44 --- .../einsatzverwaltung/dao/EmployeeDatabaseDAO.java | 144 -------- .../einsatzverwaltung/dao/OperationDAO.java | 48 --- .../dao/OperationDatabaseDAO.java | 221 ------------ .../einsatzverwaltung/dao/RegistrationDAO.java | 28 -- .../dao/RegistrationDatabaseDAO.java | 130 -------- .../einsatzverwaltung/dao/VehicleDAO.java | 54 --- .../einsatzverwaltung/dao/VehicleDatabaseDAO.java | 211 ------------ .../groupphase/einsatzverwaltung/dto/Employee.java | 51 --- .../einsatzverwaltung/dto/EmployeeValidator.java | 23 -- .../einsatzverwaltung/dto/Operation.java | 70 ---- .../einsatzverwaltung/dto/Registration.java | 34 -- .../dto/RegistrationValidator.java | 174 ---------- .../groupphase/einsatzverwaltung/dto/Vehicle.java | 73 ---- .../einsatzverwaltung/service/EmployeeService.java | 46 --- .../service/EmployeeServiceImpl.java | 59 ---- .../service/OperationService.java | 70 ---- .../service/OperationServiceImpl.java | 286 ---------------- .../service/RegistrationService.java | 32 -- .../service/RegistrationServiceImpl.java | 52 --- .../einsatzverwaltung/service/VehicleService.java | 49 --- .../service/VehicleServiceImpl.java | 116 ------- .../controller/ArchiveOperationController.java | 213 ++++++++++++ .../controller/CreateCarController.java | 231 +++++++++++++ .../controller/CreateNewEmployeeController.java | 174 ++++++++++ .../controller/CreateOperationController.java | 371 +++++++++++++++++++++ .../controller/CustomListItemController.java | 24 ++ .../DetailArchiveOperationController.java | 77 +++++ .../controller/EmployeeListController.java | 133 ++++++++ .../controller/EmployeeListItemController.java | 87 +++++ .../controller/FilterEmployeesController.java | 65 ++++ .../missioncontrol/controller/Helper.java | 34 ++ .../controller/ManageEmployeesController.java | 120 +++++++ .../controller/OperationDetailsController.java | 169 ++++++++++ .../controller/OperationInArchiveController.java | 65 ++++ .../controller/RegistrationWindowController.java | 279 ++++++++++++++++ .../controller/VehiclePaneController.java | 118 +++++++ .../groupphase/missioncontrol/dao/EmployeeDAO.java | 44 +++ .../missioncontrol/dao/EmployeeDatabaseDAO.java | 144 ++++++++ .../missioncontrol/dao/OperationDAO.java | 48 +++ .../missioncontrol/dao/OperationDatabaseDAO.java | 221 ++++++++++++ .../missioncontrol/dao/RegistrationDAO.java | 28 ++ .../dao/RegistrationDatabaseDAO.java | 130 ++++++++ .../groupphase/missioncontrol/dao/VehicleDAO.java | 54 +++ .../missioncontrol/dao/VehicleDatabaseDAO.java | 211 ++++++++++++ .../groupphase/missioncontrol/dto/Employee.java | 51 +++ .../missioncontrol/dto/EmployeeValidator.java | 23 ++ .../groupphase/missioncontrol/dto/Operation.java | 70 ++++ .../missioncontrol/dto/Registration.java | 34 ++ .../missioncontrol/dto/RegistrationValidator.java | 174 ++++++++++ .../groupphase/missioncontrol/dto/Vehicle.java | 73 ++++ .../missioncontrol/service/EmployeeService.java | 46 +++ .../service/EmployeeServiceImpl.java | 59 ++++ .../missioncontrol/service/OperationService.java | 70 ++++ .../service/OperationServiceImpl.java | 286 ++++++++++++++++ .../service/RegistrationService.java | 32 ++ .../service/RegistrationServiceImpl.java | 52 +++ .../missioncontrol/service/VehicleService.java | 49 +++ .../missioncontrol/service/VehicleServiceImpl.java | 116 +++++++ src/main/resources/fxml/ArchiveOperation.fxml | 2 +- .../resources/fxml/CreateOperationController.fxml | 2 +- .../resources/fxml/DetailArchiveOperation.fxml | 2 +- src/main/resources/fxml/OperationDetails.fxml | 2 +- src/main/resources/fxml/OperationInArchive.fxml | 2 +- src/main/resources/fxml/RegistrationWindow.fxml | 2 +- src/main/resources/fxml/createCar.fxml | 2 +- src/main/resources/fxml/createNewEmployee.fxml | 2 +- src/main/resources/fxml/employeeList.fxml | 2 +- src/main/resources/fxml/employeeListItem.fxml | 2 +- .../resources/fxml/filterEmployeesControl.fxml | 2 +- src/main/resources/fxml/manageEmployees.fxml | 2 +- src/main/resources/fxml/vehiclePane.fxml | 2 +- .../CreateNewEmployeeControllerTest.java | 87 ----- .../controller/CreateNewVehicleControllerTest.java | 81 ----- .../controller/GuiTestApplication.java | 101 ------ .../controller/RegistrationControllerTest.java | 22 -- .../einsatzverwaltung/dao/EmployeeDAOTest.java | 253 -------------- .../einsatzverwaltung/dao/OperationDAOTest.java | 197 ----------- .../einsatzverwaltung/dao/RegistrationDAOTest.java | 115 ------- .../einsatzverwaltung/dao/VehicleDAOTest.java | 161 --------- .../service/EmployeeServiceTest.java | 67 ---- .../service/OperationServiceIntegrationTest.java | 97 ------ .../service/OperationServiceTest.java | 205 ------------ .../RegistrationServiceIntegrationTest.java | 55 --- .../service/RegistrationServiceTest.java | 159 --------- .../CreateNewEmployeeControllerTest.java | 87 +++++ .../controller/CreateNewVehicleControllerTest.java | 81 +++++ .../controller/GuiTestApplication.java | 101 ++++++ .../controller/RegistrationControllerTest.java | 22 ++ .../missioncontrol/dao/EmployeeDAOTest.java | 253 ++++++++++++++ .../missioncontrol/dao/OperationDAOTest.java | 197 +++++++++++ .../missioncontrol/dao/RegistrationDAOTest.java | 115 +++++++ .../missioncontrol/dao/VehicleDAOTest.java | 161 +++++++++ .../service/EmployeeServiceTest.java | 67 ++++ .../service/OperationServiceIntegrationTest.java | 97 ++++++ .../service/OperationServiceTest.java | 205 ++++++++++++ .../RegistrationServiceIntegrationTest.java | 55 +++ .../service/RegistrationServiceTest.java | 159 +++++++++ 114 files changed, 5789 insertions(+), 5791 deletions(-) delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/ArchiveOperationController.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateCarController.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateNewEmployeeController.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateOperationController.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CustomListItemController.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/DetailArchiveOperationController.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/EmployeeListController.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/EmployeeListItemController.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/FilterEmployeesController.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/Helper.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/ManageEmployeesController.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/OperationDetailsController.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/OperationInArchiveController.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/RegistrationWindowController.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/VehiclePaneController.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/EmployeeDAO.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/EmployeeDatabaseDAO.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDAO.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDatabaseDAO.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/RegistrationDAO.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/RegistrationDatabaseDAO.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/VehicleDAO.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/VehicleDatabaseDAO.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/Employee.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/EmployeeValidator.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/Operation.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/Registration.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/RegistrationValidator.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/Vehicle.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/EmployeeService.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/EmployeeServiceImpl.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationService.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceImpl.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/RegistrationService.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/RegistrationServiceImpl.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/VehicleService.java delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/VehicleServiceImpl.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ArchiveOperationController.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateCarController.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateNewEmployeeController.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CustomListItemController.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/DetailArchiveOperationController.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/EmployeeListController.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/EmployeeListItemController.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/FilterEmployeesController.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/Helper.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ManageEmployeesController.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationDetailsController.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationInArchiveController.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/VehiclePaneController.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDAO.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDatabaseDAO.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDAO.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDatabaseDAO.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDAO.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDAO.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDatabaseDAO.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Employee.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/EmployeeValidator.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Operation.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Registration.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/RegistrationValidator.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Vehicle.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/EmployeeService.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/EmployeeServiceImpl.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationService.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationServiceImpl.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationService.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationServiceImpl.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/VehicleService.java create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/VehicleServiceImpl.java delete mode 100644 src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateNewEmployeeControllerTest.java delete mode 100644 src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateNewVehicleControllerTest.java delete mode 100644 src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/GuiTestApplication.java delete mode 100644 src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/RegistrationControllerTest.java delete mode 100644 src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/EmployeeDAOTest.java delete mode 100644 src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDAOTest.java delete mode 100644 src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/RegistrationDAOTest.java delete mode 100644 src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/VehicleDAOTest.java delete mode 100644 src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/EmployeeServiceTest.java delete mode 100644 src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceIntegrationTest.java delete mode 100644 src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceTest.java delete mode 100644 src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/RegistrationServiceIntegrationTest.java delete mode 100644 src/test/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/RegistrationServiceTest.java create mode 100644 src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateNewEmployeeControllerTest.java create mode 100644 src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateNewVehicleControllerTest.java create mode 100644 src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/GuiTestApplication.java create mode 100644 src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationControllerTest.java create mode 100644 src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDAOTest.java create mode 100644 src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDAOTest.java create mode 100644 src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDAOTest.java create mode 100644 src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDAOTest.java create mode 100644 src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/EmployeeServiceTest.java create mode 100644 src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationServiceIntegrationTest.java create mode 100644 src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationServiceTest.java create mode 100644 src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationServiceIntegrationTest.java create mode 100644 src/test/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationServiceTest.java diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/application/MainApplication.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/application/MainApplication.java index 87daea4..a6c0566 100644 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/application/MainApplication.java +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/application/MainApplication.java @@ -1,6 +1,6 @@ package at.ac.tuwien.sepm.assignment.groupphase.application; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller.CreateOperationController; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.CreateOperationController; import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; import javafx.application.Application; @@ -34,8 +34,6 @@ public class MainApplication extends Application { Platform.exit(); }); - // TODO: close connection on program exit (feedback) - configApplicationContext = new AnnotationConfigApplicationContext(MainApplication.class); final var fxmlLoader = configApplicationContext.getBean(SpringFXMLLoader.class); primaryStage.setScene( diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/ArchiveOperationController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/ArchiveOperationController.java deleted file mode 100644 index 9ac6a1a..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/ArchiveOperationController.java +++ /dev/null @@ -1,213 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller; - -import static at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller.Helper.showServiceExceptionAlertAndWait; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.OperationService; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; -import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; -import java.io.IOException; -import java.time.LocalDateTime; -import java.time.ZoneOffset; -import java.util.Arrays; -import java.util.Collection; -import java.util.EnumSet; -import java.util.HashSet; -import java.util.List; -import java.util.Objects; -import java.util.Set; -import java.util.stream.Collectors; -import javafx.fxml.FXML; -import javafx.scene.control.Label; -import javafx.scene.image.Image; -import javafx.scene.image.ImageView; -import javafx.scene.layout.AnchorPane; -import javafx.scene.layout.FlowPane; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Controller; - -@Controller -public class ArchiveOperationController { - - private static final Logger LOG = LoggerFactory.getLogger(ArchiveOperationController.class); - - @FXML private ImageView imvVehicleDetail; - @FXML private Label lblStatus; - @FXML private AnchorPane apMainDetails; - @FXML private Label lblOperations; - @FXML private Label lblCompleted; - @FXML private Label lblCancelled; - @FXML private AnchorPane backApMain; - @FXML private AnchorPane backApDetails; - @FXML private AnchorPane archiveOperationAP; - @FXML private AnchorPane apDetails; - @FXML private Label lblCodeHeader; - @FXML private Label lblOpCode; - @FXML private Label lblVehicles; - @FXML private Label lblDate; - @FXML private Label lblAddress; - @FXML private FlowPane fpVehicles; - private final OperationService operationService; - @FXML private FlowPane archiveOperationFlowPane; - private final CreateOperationController createOperationController; - private Set list = new HashSet<>(); - private final SpringFXMLLoader fxmlLoader; - - public ArchiveOperationController( - OperationService operationService, - CreateOperationController createOperationController, - SpringFXMLLoader fxmlLoader) { - this.operationService = operationService; - this.createOperationController = createOperationController; - this.fxmlLoader = fxmlLoader; - } - - @FXML - private void initialize() { - update(); - } - - public void update() { - archiveOperationFlowPane.getChildren().clear(); - list.clear(); - try { - list.addAll(operationService.list(EnumSet.of(Status.CANCELLED, Status.COMPLETED))); - long cancelledAmount = 0; - long completedAmount = 0; - for (Operation operation : list) { - if (operation.status() == Status.CANCELLED) cancelledAmount++; - else completedAmount++; - } - lblCancelled.setText("storniert: " + cancelledAmount); - lblCompleted.setText("abgeschlossen: " + completedAmount); - lblOperations.setText("Einsätze: " + list.size()); - } catch (ServiceException e) { - LOG.error("ServiceException in update().", e); - showServiceExceptionAlertAndWait("Die Einsätze konnten nicht geladen werden!"); - ; - } - setFlowPane(); - } - - private void setFlowPane() { - try { - archiveOperationFlowPane.getChildren().clear(); - for (Operation operation : sortSet(list)) { - OperationInArchiveController opInAController = - OperationInArchiveController.create(); - opInAController.set(operation); - opInAController - .getRoot() - .setOnMouseClicked( - event -> { - detailOperation = operation; - backApMain.setVisible(false); - apMainDetails.setVisible(false); - backApDetails.setVisible(true); - setOperation(); - setDetailsVisible(true); - imvVehicleDetail.setImage(new Image("/images/Vehicle.png")); - }); - archiveOperationFlowPane.getChildren().add(opInAController.getRoot()); - } - } catch (IOException e) { - LOG.error("IOException in setFlowPane(). ", e); - showServiceExceptionAlertAndWait("Die Elemente konnten nicht geladen werden!"); - } - } - - private Operation detailOperation; - - private List sortSet(Set operationsSet) { - Operation[] array = operationsSet.toArray(new Operation[operationsSet.size()]); - for (int i = array.length - 1; i > 0; i--) { - for (int j = 0; j < i; j++) { - LocalDateTime first = - LocalDateTime.ofInstant( - Objects.requireNonNull(array[j].created()), ZoneOffset.UTC); - LocalDateTime second = - LocalDateTime.ofInstant( - Objects.requireNonNull(array[j + 1].created()), ZoneOffset.UTC); - if (first.isBefore(second)) { - Operation help = array[j]; - array[j] = array[j + 1]; - array[j + 1] = help; - } - } - } - return Arrays.asList(array); - } - - private void setOperation() { - lblCodeHeader.setText(detailOperation.opCode()); - if (detailOperation.created() != null) { - LocalDateTime dateTime = - LocalDateTime.ofInstant( - Objects.requireNonNull(detailOperation.created()), ZoneOffset.UTC); - lblDate.setText( - "am " - + dateTime.getDayOfMonth() - + "." - + dateTime.getMonth().getValue() - + "." - + dateTime.getYear()); - } else { - lblDate.setText("---"); - } - lblStatus.setText( - "Status: " - + (detailOperation.status() == Status.CANCELLED - ? "storniert" - : "abgeschlossen")); - lblOpCode.setText(detailOperation.opCode()); - Collection elements = - detailOperation.vehicles().stream().map(Vehicle::name).collect(Collectors.toList()); - String result = String.join(", ", elements); - - lblVehicles.setText(result); - lblAddress.setText(detailOperation.destination()); - - fpVehicles.getChildren().clear(); - try { - for (Vehicle vehicle : detailOperation.vehicles()) { - DetailArchiveOperationController controller = null; - - controller = DetailArchiveOperationController.create(fxmlLoader); - - controller.set(vehicle); - fpVehicles.getChildren().add(controller.getRoot()); - } - } catch (IOException e) { - LOG.error("IOException in setOperation(). ", e); - showServiceExceptionAlertAndWait("Die Element konnte nicht geladen werden!"); - } - } - - private void setDetailsVisible(boolean b) { - apDetails.setVisible(b); - } - - public void backClicked() { - LOG.debug("Hyperlink \"Zurück\" in archive detail view clicked."); - fpVehicles.getChildren().clear(); - setDetailsVisible(false); - backApDetails.setVisible(false); - apMainDetails.setVisible(true); - backApMain.setVisible(true); - } - - public void backToMain() { - LOG.debug("Hyperlink \"Zurück\" in archive main view clicked."); - this.setVisible(false); - createOperationController.setVisible(true); - } - - void setVisible(boolean b) { - archiveOperationAP.setVisible(b); - backApMain.setVisible(b); - apMainDetails.setVisible(b); - } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateCarController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateCarController.java deleted file mode 100644 index 0734820..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateCarController.java +++ /dev/null @@ -1,231 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller; - -import static at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller.Helper.showServiceExceptionAlertAndWait; -import static at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller.Helper.showSuccessAlertAndWait; -import static at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller.Helper.showValidationErrorAlertAndWait; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.ConstructionType; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.Status; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.VehicleType; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.VehicleService; -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; -import java.io.IOException; -import java.util.EnumSet; -import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import javafx.collections.FXCollections; -import javafx.event.ActionEvent; -import javafx.fxml.FXML; -import javafx.scene.control.Button; -import javafx.scene.control.CheckBox; -import javafx.scene.control.ChoiceBox; -import javafx.scene.input.MouseButton; -import javafx.scene.layout.AnchorPane; -import javafx.scene.layout.FlowPane; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Controller; - -@Controller -public class CreateCarController { - - @FXML private AnchorPane createCarAP; - @FXML private ChoiceBox cmbCtype; - @FXML private ChoiceBox cmbTyp; - - @FXML private Button btnCreate; - @FXML private CheckBox cbxNEF; - @FXML private FlowPane fpVehicleList; - private final CreateOperationController createOperationController; - - private static final Logger LOG = LoggerFactory.getLogger(CreateCarController.class); - private final VehicleService vehicleService; - private boolean update = false; - private long vid = -1; - - private Vehicle chooseVehicle; - - public CreateCarController( - CreateOperationController createOperationController, VehicleService vehicleService) { - this.createOperationController = createOperationController; - this.vehicleService = vehicleService; - } - - @FXML - private void initialize() { - fpVehicleList.setHgap(5); - fpVehicleList.setVgap(5); - - cmbCtype.setItems( - FXCollections.observableArrayList( - Stream.of( - ConstructionType.NORMAL, - ConstructionType.MITTELHOCHDACH, - ConstructionType.HOCHDACH) - .map(Enum::toString) - .collect(Collectors.toList()))); - cmbCtype.setValue(ConstructionType.NORMAL.toString()); - cmbTyp.setItems( - FXCollections.observableArrayList( - Stream.of( - VehicleType.BKTW, - VehicleType.KTW_B, - VehicleType.KTW, - VehicleType.RTW, - VehicleType.NEF, - VehicleType.NAH) - .map(Enum::toString) - .collect(Collectors.toList()))); - cmbTyp.setValue(VehicleType.BKTW.toString()); - - updateVehiclePane(); - } - - @FXML - private void createCar(ActionEvent actionEvent) { - - if (!update) { - LOG.debug("Button \"Erstellen\" clicked."); - Vehicle vehicle = - Vehicle.builder() - .constructionType(parseConstructionType()) - .type(parseType()) - .name("") - .status(Status.ABGEMELDET) - .hasNef(cbxNEF.isSelected()) - .build(); - try { - vehicleService.add(vehicle); - setToStart(); - } catch (InvalidVehicleException e) { - LOG.debug("Validation of Vehicle failed"); - showValidationErrorAlertAndWait(e.getMessage()); - setToStart(); - return; - } catch (ServiceException e) { - LOG.error("ServiceException in createCar(). ", e); - showServiceExceptionAlertAndWait( - "Ein Fehler beim Erstellen des Fahrzeuges ist aufgetreten."); - setToStart(); - return; - } - showSuccessAlertAndWait("Auto wurde erfolgreich angelegt."); - } else { - LOG.debug("Button \"Speichern\" clicked."); - try { - Vehicle vehicle = - Vehicle.builder() - .id(vid) - .constructionType(parseConstructionType()) - .type(parseType()) - .name("") - .status(Status.ABGEMELDET) - .hasNef(cbxNEF.isSelected()) - .build(); - vehicleService.update(vehicle); - setToStart(); - chooseVehicle = null; - } catch (InvalidVehicleException e) { - LOG.debug("Validation of Vehicle failed"); - showValidationErrorAlertAndWait(e.getMessage()); - setToStart(); - return; - } catch (ServiceException e) { - LOG.error("ServiceException in createCar(). ", e); - showServiceExceptionAlertAndWait(e.getMessage()); - setToStart(); - return; - } - showSuccessAlertAndWait("Auto wurde erfolgreich bearbeitet."); - } - - updateVehiclePane(); - } - - private ConstructionType parseConstructionType() { - if (cmbCtype.getSelectionModel().getSelectedItem() == null) { - return ConstructionType.NORMAL; - } - return ConstructionType.valueOf(cmbCtype.getSelectionModel().getSelectedItem()); - } - - private VehicleType parseType() { - if (cmbTyp.getSelectionModel().getSelectedItem() == null) { - return VehicleType.BKTW; - } - return VehicleType.valueOf(cmbTyp.getSelectionModel().getSelectedItem()); - } - - private void setToStart() { - btnCreate.setText("Erstellen"); - cbxNEF.setSelected(false); - cmbTyp.setValue(VehicleType.BKTW.name()); - cmbCtype.setValue(ConstructionType.NORMAL.name()); - update = false; - } - - private void updateVehicle(Vehicle vehicle) { - - cmbCtype.setValue(vehicle.constructionType().name()); - cmbTyp.setValue(vehicle.type().name()); - cbxNEF.setSelected(vehicle.hasNef()); - btnCreate.setText("Speichern"); - vid = vehicle.id(); - update = true; - chooseVehicle = vehicle; - } - - public void setVisible(boolean b) { - createCarAP.setVisible(b); - } - - @FXML - private void backToMain() { - LOG.debug("Hyperlink \"zurück\" clicked."); - this.setVisible(false); - createOperationController.setVisible(true); - } - - private void updateVehiclePane() { - try { - fpVehicleList.getChildren().clear(); - - Set vehicles; - - vehicles = vehicleService.list(EnumSet.of(Status.ABGEMELDET)); - - for (Vehicle vehicle : vehicles) { - VehiclePaneController controller = VehiclePaneController.createVehiclePane(); - - controller.setData(vehicle, false, false); - controller - .getRootElement() - .setOnMouseClicked( - event -> { - if (event.getButton().equals(MouseButton.PRIMARY)) { - if (chooseVehicle == null || vehicle == chooseVehicle) { - if (update == false) { - chooseVehicle = vehicle; - updateVehicle(vehicle); - controller.setSelected(true); - } else { - setToStart(); - controller.setSelected(false); - - chooseVehicle = null; - } - } - } - }); - - fpVehicleList.getChildren().add(controller.getRootElement()); - } - } catch (ServiceException | IOException e) { - LOG.error("Exception in updateVehiclePane(). ", e); - showServiceExceptionAlertAndWait(e.getMessage()); - } - } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateNewEmployeeController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateNewEmployeeController.java deleted file mode 100644 index 5f0a8b2..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateNewEmployeeController.java +++ /dev/null @@ -1,174 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller; - -import static at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller.Helper.showServiceExceptionAlertAndWait; -import static at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller.Helper.showSuccessAlertAndWait; -import static at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller.Helper.showValidationErrorAlertAndWait; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee.EducationLevel; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.EmployeeService; -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidEmployeeException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; -import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; -import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader.FXMLWrapper; -import java.io.IOException; -import java.time.LocalDate; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import javafx.collections.FXCollections; -import javafx.fxml.FXML; -import javafx.scene.Node; -import javafx.scene.control.Button; -import javafx.scene.control.CheckBox; -import javafx.scene.control.ChoiceBox; -import javafx.scene.control.Label; -import javafx.scene.control.TextField; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Controller; - -@Controller -@Scope("prototype") -public class CreateNewEmployeeController { - - private static final Logger LOG = LoggerFactory.getLogger(CreateNewEmployeeController.class); - private final EmployeeService employeeService; - - @FXML private Label lblHeader; - @FXML private CheckBox inputIsDriver; - @FXML private CheckBox inputIsPilot; - @FXML private TextField inputName; - @FXML private ChoiceBox inputQualification; - @FXML private Button btnCreate; - - private Node rootElement; - private Employee employee; - private boolean isEdit; - - private Runnable consumerCancelClicked; - private Runnable consumerCreateClicked; - - public CreateNewEmployeeController(EmployeeService employeeService) { - this.employeeService = employeeService; - } - - @FXML - private void initialize() { - inputQualification.setItems( - FXCollections.observableArrayList( - Stream.of( - EducationLevel.RS, - EducationLevel.NFS, - EducationLevel.NKV, - EducationLevel.NKA, - EducationLevel.NKI, - EducationLevel.NA) - .map(Enum::toString) - .collect(Collectors.toList()))); - - inputQualification.setValue(EducationLevel.RS.toString()); - employee = - Employee.builder() - .name("") - .educationLevel(EducationLevel.RS) - .isDriver(false) - .isPilot(false) - .birthday(LocalDate.MIN) - .build(); - } - - @FXML - private void onCancelClicked() { - LOG.debug("Hyperlink \"abbrechen\" clicked."); - if (consumerCancelClicked != null) { - consumerCancelClicked.run(); - } - } - - @FXML - private void onCreateClicked() { - LOG.debug("Button {} clicked.", btnCreate.getText()); - - employee = - employee.toBuilder() - .name(inputName.getText()) - .educationLevel(parseEducationLevel()) - .birthday(LocalDate.MIN) // TODO: change UI to include birthday field - .isDriver(inputIsDriver.isSelected()) - .isPilot(inputIsPilot.isSelected()) - .build(); - - try { - if (isEdit) { - employeeService.update(employee); - } else { - employeeService.add(employee); - } - } catch (InvalidEmployeeException e) { - LOG.debug("Validation for Employee failed"); - showValidationErrorAlertAndWait(e.getMessage()); - return; - } catch (ServiceException e) { - LOG.error("ServiceException in onCreateClicked(). ", e); - showServiceExceptionAlertAndWait( - "Der Eintrag konnte nicht gespeichert werden. Bitte versuchen Sie es erneut."); - return; - } - - showSuccessAlertAndWait( - "Der/die MitarbeiterIn wurde erfolgreich angelegt und gespeichert!"); - - if (consumerCreateClicked != null) { - consumerCreateClicked.run(); - } - } - - private EducationLevel parseEducationLevel() { - if (inputQualification.getSelectionModel().getSelectedItem() == null) { - return EducationLevel.RS; - } - return EducationLevel.valueOf(inputQualification.getSelectionModel().getSelectedItem()); - } - - private void setData(Employee employee) { - isEdit = true; - this.employee = employee; - inputName.setText(employee.name()); - inputQualification.setValue(employee.educationLevel().name()); - inputIsDriver.setSelected(employee.isDriver()); - inputIsPilot.setSelected(employee.isPilot()); - lblHeader.setText("Person bearbeiten"); - btnCreate.setText("Speichern"); - } - - public static CreateNewEmployeeController createCreateNewEmployeeController( - SpringFXMLLoader fxmlLoader, Employee employee) throws IOException { - CreateNewEmployeeController controller = createCreateNewEmployeeController(fxmlLoader); - controller.setData(employee); - return controller; - } - - public static CreateNewEmployeeController createCreateNewEmployeeController( - SpringFXMLLoader fxmlLoader) throws IOException { - FXMLWrapper wrapper = - fxmlLoader.loadAndWrap( - "/fxml/createNewEmployee.fxml", CreateNewEmployeeController.class); - Node root = (Node) wrapper.getLoadedObject(); - CreateNewEmployeeController controller = wrapper.getController(); - controller.rootElement = root; - return controller; - } - - public Node getRootElement() { - return rootElement; - } - - public void setConsumerCancelClicked(Runnable consumerCancelClicked) { - this.consumerCancelClicked = consumerCancelClicked; - } - - public void setConsumerCreateClicked(Runnable consumerCreateClicked) { - this.consumerCreateClicked = consumerCreateClicked; - } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateOperationController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateOperationController.java deleted file mode 100644 index 19ed7bf..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateOperationController.java +++ /dev/null @@ -1,371 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller; - -import static at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller.Helper.showServiceExceptionAlertAndWait; -import static at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller.Helper.showSuccessAlertAndWait; -import static at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller.Helper.showValidationErrorAlertAndWait; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Registration; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.OperationService; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.VehicleService; -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidOperationException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; -import java.io.IOException; -import java.time.Instant; -import java.time.temporal.ChronoUnit; -import java.util.ArrayList; -import java.util.EnumSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; -import javafx.collections.FXCollections; -import javafx.fxml.FXML; -import javafx.scene.control.Button; -import javafx.scene.control.ContextMenu; -import javafx.scene.control.Label; -import javafx.scene.control.ListCell; -import javafx.scene.control.ListView; -import javafx.scene.control.MenuItem; -import javafx.scene.control.TextField; -import javafx.scene.input.KeyCode; -import javafx.scene.input.KeyEvent; -import javafx.scene.input.MouseButton; -import javafx.scene.layout.AnchorPane; -import javafx.scene.layout.FlowPane; -import javafx.scene.layout.GridPane; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Controller; - -@Controller -public class CreateOperationController { - - private static final Logger LOG = LoggerFactory.getLogger(CreateOperationController.class); - - public AnchorPane apCreateOperation; - @FXML private GridPane grdWindowContainer; - @FXML private TextField txtCode; - @FXML private TextField txtAddress; - @FXML private TextField txtNote; - @FXML private Button btnCreateOperation; - @FXML private ListView lvVehicles; - @FXML private ListView lvActiveOperations; - @FXML private Label lblChosenVehicles; - @FXML private AnchorPane apInvisible; - @FXML private OperationDetailsController operationDetailsController; - @FXML private ManageEmployeesController manageEmployeesController; - @FXML private CreateCarController createCarController; - @FXML private RegistrationWindowController registrationWindowController; - @FXML private ArchiveOperationController archiveOperationController; - @FXML private FlowPane fpVehicles; - - private LinkedList chosenVehicles = new LinkedList<>(); - - private final OperationService operationService; - private final VehicleService vehicleService; - - public CreateOperationController( - OperationService operationService, VehicleService vehicleService) { - this.operationService = operationService; - this.vehicleService = vehicleService; - } - - @FXML - private void initialize() { - - lblChosenVehicles.setText("keine ausgewählt"); - lvActiveOperations.setCellFactory(param -> generateOpCodeListItem()); - - lvActiveOperations.setOnMouseClicked( - event -> { - if (event.getClickCount() == 2) { - if (lvActiveOperations.getSelectionModel().getSelectedItem() == null) { - return; - } - openDetailsWindow(lvActiveOperations.getSelectionModel().getSelectedItem()); - } - }); - - setVisible(true); - createCarController.setVisible(false); - registrationWindowController.setVisible(false); - } - - public void updateList() { - try { - fpVehicles.getChildren().clear(); - - // TODO: this should probably be handled differently - Set vehicles; - if (txtCode.getText().isEmpty()) { - vehicles = - vehicleService.list( - EnumSet.complementOf(EnumSet.of(Vehicle.Status.ABGEMELDET))); - } else { - vehicles = operationService.rankVehicles(txtCode.getText()); - } - - for (Vehicle vehicle : vehicles) { - VehiclePaneController controller = VehiclePaneController.createVehiclePane(); - - controller.setData(vehicle, true, false); - controller - .getRootElement() - .setOnMouseClicked( - event -> { - if (event.getButton().equals(MouseButton.SECONDARY)) { - createContextMenu(vehicle, vehicleService) - .show( - controller.getRootElement(), - event.getScreenX(), - event.getScreenY()); - } else { - if (chosenVehicles.contains(vehicle)) { - chosenVehicles.remove(vehicle); - controller.setSelected(false); - } else { - chosenVehicles.add(vehicle); - controller.setSelected(true); - } - - StringBuilder result = new StringBuilder(); - for (int i = 0; i < chosenVehicles.size(); i++) { - if (i == chosenVehicles.size() - 1) { - result.append(chosenVehicles.get(i).name()); - } else { - result.append(chosenVehicles.get(i).name()) - .append(", "); - } - } - if (result.toString().equals("")) { - lblChosenVehicles.setText("keine ausgewählt"); - } else { - lblChosenVehicles.setText(result.toString()); - } - } - }); - - if (chosenVehicles.stream().anyMatch(v -> v.id() == vehicle.id())) - controller.setSelected(true); - - fpVehicles.getChildren().add(controller.getRootElement()); - } - } catch (ServiceException | IOException e) { - LOG.error("Exception in updateList(). ", e); - showServiceExceptionAlertAndWait( - "Beim Erstellen des Ranking ist ein Fehler aufgetreten."); - } catch (InvalidOperationException e) { - LOG.debug("Validation error in updateList(). ", e); - showValidationErrorAlertAndWait(e.getMessage()); - } - try { - lvActiveOperations.setItems( - FXCollections.observableArrayList( - operationService.list(EnumSet.of(Status.ACTIVE)))); - } catch (ServiceException e) { - LOG.error("ServiceException in updateList(). ", e); - showServiceExceptionAlertAndWait( - "Beim Holen der aktiven Einsätze ist ein Fehler aufgetreten"); - } - } - - private ContextMenu createContextMenu(Vehicle data, VehicleService vehicleService) { - ContextMenu menu = new ContextMenu(); - - for (Vehicle.Status status : Vehicle.Status.values()) { - if (status == Vehicle.Status.ABGEMELDET) { - continue; - } - - MenuItem mi = new MenuItem(status.name()); - - if (status == Vehicle.Status.FREI_FUNK || status == Vehicle.Status.FREI_WACHE) { - mi.getStyleClass().add("mi-free"); - } else { - mi.getStyleClass().add("mi-other"); - } - - mi.setOnAction( - event -> { - try { - vehicleService.update(data.toBuilder().status(status).build()); - this.updateList(); - } catch (InvalidVehicleException e) { - LOG.debug( - "Validation error in createContextMenu(). (mi.setOnAction) ", - e); - showValidationErrorAlertAndWait(e.getMessage()); - } catch (ServiceException e) { - LOG.error("Exception in createContextMenu(). (mi.setOnAction) ", e); - showServiceExceptionAlertAndWait( - "Beim Aktualisieren der Fahrzeuge ist ein Fehler aufgetreten."); - } - }); - - menu.getItems().add(mi); - } - - MenuItem abmelden = new MenuItem("abmelden"); - - abmelden.setOnAction( - event -> { - try { - List registrations = data.registrations(); - assert registrations - != null; // Otherwise the element shouldn't be in the list. - - List newRegistrations = new ArrayList<>(); - Instant now = Instant.now(); - - for (Registration registration : registrations) { - if (registration.start().isBefore(now) - && registration.end().isAfter(now)) { - newRegistrations.add( - registration - .toBuilder() - .end(Instant.now().minus(1, ChronoUnit.SECONDS)) - .build()); - } else newRegistrations.add(registration); - } - - vehicleService.update( - data.toBuilder() - .registrations(newRegistrations) - .status(Vehicle.Status.ABGEMELDET) - .build()); - - this.updateList(); - } catch (InvalidVehicleException e) { - LOG.debug( - "Validation error in createContextMenu(). (abmelden.setOnAction) ", - e); - showValidationErrorAlertAndWait(e.getMessage()); - } catch (ServiceException e) { - LOG.error("Exception in createContextMenu(). (abmelden.setOnAction) ", e); - showServiceExceptionAlertAndWait( - "Beim Aktualisieren der Fahrzeuge ist ein Fehler aufgetreten."); - } - }); - - menu.getItems().add(abmelden); - return menu; - } - - @FXML - protected void createOperationClicked() { - LOG.debug("Button \"Erstellen\" clicked."); - Vehicle[] vehicles = new Vehicle[chosenVehicles.size()]; - for (int i = 0; i < chosenVehicles.size(); i++) { - vehicles[i] = chosenVehicles.get(i); - } - Operation operation = - Operation.builder() - .additionalInfo(txtNote.getText()) - .destination(txtAddress.getText()) - .opCode(txtCode.getText()) - .status(Status.ACTIVE) - .vehicles(Set.of(vehicles)) - .build(); - try { - operationService.add(operation); - } catch (ServiceException e) { - LOG.error("Exception in createOperationClicked(). ", e); - showServiceExceptionAlertAndWait( - "Beim Erstellen des Einsatzes ist ein Fehler aufgetreten."); - return; - } catch (InvalidOperationException e) { - LOG.debug("Validation error in createOperationClicked(). ", e); - showValidationErrorAlertAndWait(e.getMessage()); - return; - } - showSuccessAlertAndWait("Der Einsatz wurde erfolgreich gespeichert."); - updateList(); - lblChosenVehicles.setText("keine ausgewählt"); - txtAddress.setText(""); - txtCode.setText(""); - txtNote.setText(""); - chosenVehicles = new LinkedList<>(); - } - - @FXML - private void onRegistrationLinkClicked() { - LOG.debug("Hyperlink \"Anmeldungen\" clicked."); - openRegistrationWindow(); - } - - @FXML - private void onEmployeeLinkClicked() { - LOG.debug("Hyperlink \"Personen\" clicked."); - openCreateNewEmployeeWindow(); - } - - @FXML - private void onVehicleLinkClicked() { - LOG.debug("Hyperlink \"Fahrzeuge\" clicked."); - openCreateCarWindow(); - } - - @FXML - private void onArchivLinkClicked() { - LOG.debug("Hyperlink \"Archiv\" clicked."); - archiveOperationController.update(); - openArchivWindow(); - } - - private void openArchivWindow() { - archiveOperationController.setVisible(true); - this.setVisible(false); - } - - void setVisible(boolean b) { - apInvisible.setVisible(!b); - grdWindowContainer.setVisible(!b); - - updateList(); - } - - private void openDetailsWindow(Operation operation) { - operationDetailsController.initOperation(operation); - this.setVisible(false); - } - - private void openCreateNewEmployeeWindow() { - this.setVisible(false); - manageEmployeesController.setVisible(true); - } - - private void openCreateCarWindow() { - this.setVisible(false); - createCarController.setVisible(true); - } - - private void openRegistrationWindow() { - this.setVisible(false); - registrationWindowController.setVisible(true); - } - - @FXML - private void onOperationCodeChanged(KeyEvent keyEvent) { - if (keyEvent.getCode() == KeyCode.ENTER) { - updateList(); - } - } - - static ListCell generateOpCodeListItem() { - return new ListCell<>() { - @Override - protected void updateItem(Operation item, boolean empty) { - super.updateItem(item, empty); - - if (empty || item == null || item.opCode() == null) { - setText(null); - } else { - setText(item.opCode()); - } - } - }; - } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CustomListItemController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CustomListItemController.java deleted file mode 100644 index 79cf243..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CustomListItemController.java +++ /dev/null @@ -1,24 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller; - -import javafx.scene.Node; - -public abstract class CustomListItemController { - - protected Node rootElement; - - public Node getRootElement() { - return rootElement; - } - - public void setSelected(boolean selected) { - rootElement.getStyleClass().clear(); - - if (selected) { - rootElement.getStyleClass().add("bg-yellow"); - rootElement.getStyleClass().add("shadowed"); - } else { - rootElement.getStyleClass().add("bg-white"); - rootElement.getStyleClass().add("shadowed"); - } - } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/DetailArchiveOperationController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/DetailArchiveOperationController.java deleted file mode 100644 index 41bd2a6..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/DetailArchiveOperationController.java +++ /dev/null @@ -1,77 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller; - -import static at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller.Helper.showServiceExceptionAlertAndWait; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; -import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader.FXMLWrapper; -import java.io.IOException; -import java.util.Objects; -import javafx.fxml.FXML; -import javafx.scene.Node; -import javafx.scene.layout.VBox; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Controller; - -@Controller -public class DetailArchiveOperationController { - private static final Logger LOG = - LoggerFactory.getLogger(DetailArchiveOperationController.class); - - @FXML private VBox vBoxVehicle; - @FXML private VBox vBoxPeople; - private final SpringFXMLLoader fxmlLoader; - - public DetailArchiveOperationController(SpringFXMLLoader fxmlLoader) { - this.fxmlLoader = fxmlLoader; - } - - static DetailArchiveOperationController create(SpringFXMLLoader fxmlLoader) throws IOException { - FXMLWrapper wrapper = - fxmlLoader.loadAndWrap( - "/fxml/DetailArchiveOperation.fxml", - DetailArchiveOperationController.class); - - Node root = (Node) wrapper.getLoadedObject(); - DetailArchiveOperationController result = wrapper.getController(); - result.rootElement = root; - - return result; - } - - public Node getRoot() { - return rootElement; - } - - private Node rootElement; - - public void set(Vehicle vehicle) { - VehiclePaneController controller; - try { - controller = VehiclePaneController.createVehiclePane(); - controller.setData(vehicle, false, false); - vBoxVehicle.getChildren().add(controller.getRootElement()); - } catch (IOException e) { - LOG.error("IOException in set(Vehicle). (vBoxVehicle) ", e); - showServiceExceptionAlertAndWait( - "Ein interner Fehler ist aufgetreten. Bitte wenden Sie sich an den/die SystemadministratorIn."); - } - try { - for (int i = 0; i < Objects.requireNonNull(vehicle.registrations()).size(); i++) { - Employee employee = - Objects.requireNonNull(vehicle.registrations()).get(i).employee(); - - EmployeeListItemController employeeListItemController = - EmployeeListItemController.createEmployeeListItemController( - fxmlLoader, employee); - vBoxPeople.getChildren().add(employeeListItemController.getRootElement()); - } - } catch (IOException e) { - LOG.error("IOException in set(Vehicle). (vBoxPeople) ", e); - showServiceExceptionAlertAndWait( - "Ein interner Fehler ist aufgetreten. Bitte wenden Sie sich an den/die SystemadministratorIn."); - } - } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/EmployeeListController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/EmployeeListController.java deleted file mode 100644 index 6e1159a..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/EmployeeListController.java +++ /dev/null @@ -1,133 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee; -import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; -import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader.FXMLWrapper; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import java.util.function.Consumer; -import javafx.fxml.FXML; -import javafx.geometry.Insets; -import javafx.scene.Node; -import javafx.scene.layout.FlowPane; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Controller; - -@Controller -@Scope("prototype") -public class EmployeeListController { - - private static final Logger LOG = LoggerFactory.getLogger(EmployeeListController.class); - - @FXML private FlowPane flowPaneEmployeeList; - - private Consumer onEmployeeClicked; - - private final SpringFXMLLoader fxmlLoader; - private Node rootElement; - private List employeeListItemControllers; - private Insets listItemMargins = new Insets(10, 5, 0, 5); - - public EmployeeListController(SpringFXMLLoader fxmlLoader) { - this.fxmlLoader = fxmlLoader; - this.employeeListItemControllers = new ArrayList<>(); - } - - public void setListItemMargins(Insets value) { - this.listItemMargins = value; - } - - public void setData(Set employeeList) { - setData(employeeList, null, null); - } - - public void setData(Set employeeList, Consumer onEmployeeClicked) { - setData(employeeList, onEmployeeClicked, null); - } - - public void setData( - Set employeeList, - Consumer onEmployeeClicked, - Consumer onEmployeeListItemClicked) { - - flowPaneEmployeeList.getChildren().clear(); - employeeListItemControllers.clear(); - employeeList.forEach( - employee -> - addEmployeeToFlowPane( - employee, onEmployeeClicked, onEmployeeListItemClicked)); - } - - private void addEmployeeToFlowPane( - Employee employee, - Consumer onEmployeeClicked, - Consumer onEmployeeListItemClicked) { - - try { - EmployeeListItemController controller = - EmployeeListItemController.createEmployeeListItemController( - fxmlLoader, employee); - Node rootElement = controller.getRootElement(); - flowPaneEmployeeList.getChildren().add(rootElement); - employeeListItemControllers.add(controller); - FlowPane.setMargin(rootElement, listItemMargins); - if (onEmployeeClicked != null) { - controller.setConsumerEmployeeClicked(onEmployeeClicked); - } - if (onEmployeeListItemClicked != null) { - controller.setConsumerEmployeeListItemClicked( - employeeListItemController -> { - onEmployeeListItemClicked.accept(employeeListItemController); - if (this.onEmployeeClicked != null) { - this.onEmployeeClicked.accept( - employeeListItemController.getEmployee()); - } - }); - } - } catch (IOException e) { - LOG.error("IOException in addEmployeeToFlowPane. ", e); - } - } - - private void setEmployeeSelected(Employee employee, boolean selected) { - employeeListItemControllers - .stream() - .filter(controller -> controller.getEmployee().equals(employee)) - .forEach(controller -> controller.setSelected(selected)); - } - - public void selectEmployee(Employee employee) { - setEmployeeSelected(employee, true); - } - - public void deselectEmployee(Employee employee) { - setEmployeeSelected(employee, false); - } - - public void deselectAllEmployees() { - employeeListItemControllers.forEach( - employeeListItemController -> employeeListItemController.setSelected(false)); - } - - public static EmployeeListController createEmployeeListController(SpringFXMLLoader loader) - throws IOException { - FXMLWrapper wrapper = - loader.loadAndWrap("/fxml/employeeList.fxml", EmployeeListController.class); - Node root = (Node) wrapper.getLoadedObject(); - EmployeeListController controller = wrapper.getController(); - controller.rootElement = root; - return controller; - } - - public Node getRootElement() { - return rootElement; - } - - public void setOnEmployeeClicked(Consumer onEmployeeClicked) { - this.onEmployeeClicked = onEmployeeClicked; - } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/EmployeeListItemController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/EmployeeListItemController.java deleted file mode 100644 index 7b5910a..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/EmployeeListItemController.java +++ /dev/null @@ -1,87 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee; -import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; -import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader.FXMLWrapper; -import java.io.IOException; -import java.util.function.Consumer; -import javafx.fxml.FXML; -import javafx.scene.Node; -import javafx.scene.control.Label; -import javafx.scene.image.Image; -import javafx.scene.image.ImageView; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Controller; - -@Controller -@Scope("prototype") -public class EmployeeListItemController extends CustomListItemController { - - @FXML private Label lblName; - @FXML private Label lblQualification; - @FXML private Label lblPilot; - @FXML private Label lblDriver; - @FXML private ImageView imgPilot; - @FXML private ImageView imgDriver; - @FXML private ImageView imgQualification; - - private Employee employee; - - private Consumer consumerEmployeeClicked; - private Consumer consumerEmployeeListItemClicked; - - @FXML - private void onEmployeeClicked() { - if (consumerEmployeeClicked != null) { - consumerEmployeeClicked.accept(employee); - } - if (consumerEmployeeListItemClicked != null) { - consumerEmployeeListItemClicked.accept(this); - } - } - - private void setData(Employee employee) { - this.employee = employee; - lblName.setText(employee.name()); - lblQualification.setText(employee.educationLevel().name()); - lblPilot.setText(String.format("%s Pilot", employee.isPilot() ? "ist" : "nicht")); - lblDriver.setText(String.format("%s Fahrer", employee.isDriver() ? "ist" : "nicht")); - imgQualification.setImage(new Image("/images/Qualification.png")); - String imgSrcPilot = - String.format("/images/%s", employee.isPilot() ? "Pilot.png" : "NotPilot.png"); - imgPilot.setImage(new Image(imgSrcPilot)); - String imgSrcDriver = - String.format("/images/%s", employee.isDriver() ? "Driver.png" : "NotDriver.png"); - imgDriver.setImage(new Image(imgSrcDriver)); - } - - public static EmployeeListItemController createEmployeeListItemController( - SpringFXMLLoader fxmlLoader, Employee employee) throws IOException { - EmployeeListItemController controller = createEmployeeListItemController(fxmlLoader); - controller.setData(employee); - return controller; - } - - public static EmployeeListItemController createEmployeeListItemController( - SpringFXMLLoader loader) throws IOException { - FXMLWrapper wrapper = - loader.loadAndWrap("/fxml/employeeListItem.fxml", EmployeeListItemController.class); - Node root = (Node) wrapper.getLoadedObject(); - EmployeeListItemController controller = wrapper.getController(); - controller.rootElement = root; - return controller; - } - - public Employee getEmployee() { - return employee; - } - - public void setConsumerEmployeeClicked(Consumer consumerEmployeeClicked) { - this.consumerEmployeeClicked = consumerEmployeeClicked; - } - - public void setConsumerEmployeeListItemClicked( - Consumer consumerEmployeeListItemClicked) { - this.consumerEmployeeListItemClicked = consumerEmployeeListItemClicked; - } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/FilterEmployeesController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/FilterEmployeesController.java deleted file mode 100644 index a1d1f70..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/FilterEmployeesController.java +++ /dev/null @@ -1,65 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller; - -import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; -import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader.FXMLWrapper; -import java.io.IOException; -import java.util.function.Consumer; -import javafx.fxml.FXML; -import javafx.scene.Node; -import javafx.scene.control.TextField; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Controller; - -@Controller -@Scope("prototype") -public class FilterEmployeesController { - private static final Logger LOG = LoggerFactory.getLogger(FilterEmployeesController.class); - - @FXML private TextField inputFilterString; - - private Consumer consumerFilterTextChanged; - private Runnable consumerAddEmployeeClicked; - - private Node rootElement; - - @FXML - private void onAddEmployeeClicked() { - LOG.debug("Button \"Person hinzufügen\" clicked."); - if (consumerAddEmployeeClicked != null) { - consumerAddEmployeeClicked.run(); - } - } - - @FXML - private void onFilterTextChanged() { - LOG.debug("Filter text changed."); - if (consumerFilterTextChanged != null) { - consumerFilterTextChanged.accept(inputFilterString.getText()); - } - } - - public void setOnFilterTextChangedListener(Consumer callback) { - this.consumerFilterTextChanged = callback; - } - - public void setOnAddEmployeeClickedListener(Runnable callback) { - this.consumerAddEmployeeClicked = callback; - } - - public static FilterEmployeesController createFilterEmployeesController( - SpringFXMLLoader fxmlLoader) throws IOException { - FXMLWrapper wrapper = - fxmlLoader.loadAndWrap( - "/fxml/filterEmployeesControl.fxml", FilterEmployeesController.class); - Node root = (Node) wrapper.getLoadedObject(); - FilterEmployeesController controller = wrapper.getController(); - controller.rootElement = root; - return controller; - } - - public Node getRootElement() { - return rootElement; - } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/Helper.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/Helper.java deleted file mode 100644 index 694c804..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/Helper.java +++ /dev/null @@ -1,34 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller; - -import javafx.scene.control.Alert; -import javafx.scene.control.Alert.AlertType; -import javafx.scene.control.ButtonType; - -public class Helper { - - static final String ALERT_TITLE_VALIDATION_ERROR = "Validierungsfehler"; - static final String ALERT_TITLE_SERVICE_EXCEPTION = "Fehler"; - static final String ALERT_TITLE_SUCCESS = "Erfolg"; - - private Helper() {} // SonarLint insisted to create a private constructor to hide the public one - - static void showValidationErrorAlertAndWait(String message) { - showAlertWithOkButtonAndWait(AlertType.ERROR, ALERT_TITLE_VALIDATION_ERROR, message); - } - - static void showServiceExceptionAlertAndWait(String message) { - showAlertWithOkButtonAndWait(AlertType.ERROR, ALERT_TITLE_SERVICE_EXCEPTION, message); - } - - static void showSuccessAlertAndWait(String message) { - showAlertWithOkButtonAndWait(AlertType.INFORMATION, ALERT_TITLE_SUCCESS, message); - } - - static void showAlertWithOkButtonAndWait( - AlertType alertType, String headerText, String contentText) { - Alert alert = new Alert(alertType, contentText, ButtonType.OK); - alert.setTitle(headerText); - alert.setHeaderText(headerText); - alert.showAndWait(); - } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/ManageEmployeesController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/ManageEmployeesController.java deleted file mode 100644 index 3aaf040..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/ManageEmployeesController.java +++ /dev/null @@ -1,120 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.EmployeeService; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; -import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; -import java.io.IOException; -import java.util.HashSet; -import java.util.stream.Collectors; -import javafx.fxml.FXML; -import javafx.scene.layout.AnchorPane; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Controller; - -@Controller -public class ManageEmployeesController { - - private static final Logger LOG = LoggerFactory.getLogger(ManageEmployeesController.class); - @FXML private AnchorPane listEmployeesAP; - @FXML private AnchorPane containerHeader; - @FXML private EmployeeListController employeeListController; - - private final EmployeeService employeeService; - private final SpringFXMLLoader fxmlLoader; - - private final CreateOperationController createOperationController; - - public ManageEmployeesController( - EmployeeService employeeService, - SpringFXMLLoader fxmlLoader, - CreateOperationController createOperationController) { - this.employeeService = employeeService; - this.fxmlLoader = fxmlLoader; - this.createOperationController = createOperationController; - } - - @FXML - private void initialize() { - openFilter(); - } - - private void openFilter() { - try { - FilterEmployeesController filterEmployeesController = - FilterEmployeesController.createFilterEmployeesController(fxmlLoader); - containerHeader.getChildren().clear(); - containerHeader.getChildren().add(filterEmployeesController.getRootElement()); - filterEmployeesController.setOnFilterTextChangedListener(this::updateEmployeeList); - filterEmployeesController.setOnAddEmployeeClickedListener(this::openAddEmployee); - updateEmployeeList(); - - } catch (IOException e) { - LOG.error("IOException in openFilter().", e); - } - } - - private void openAddEmployee() { - employeeListController.deselectAllEmployees(); - openEmployee(null); - } - - private void openEditEmployee(Employee employee) { - employeeListController.deselectAllEmployees(); - employeeListController.selectEmployee(employee); - openEmployee(employee); - } - - private void openEmployee(Employee employee) { - try { - CreateNewEmployeeController createNewEmployeeController = - employee == null - ? CreateNewEmployeeController.createCreateNewEmployeeController( - fxmlLoader) - : CreateNewEmployeeController.createCreateNewEmployeeController( - fxmlLoader, employee); - containerHeader.getChildren().clear(); - containerHeader.getChildren().add(createNewEmployeeController.getRootElement()); - createNewEmployeeController.setConsumerCancelClicked(this::openFilter); - createNewEmployeeController.setConsumerCreateClicked(this::openFilter); - } catch (IOException e) { - LOG.error("IOException in openEmployee(). ", e); - } - } - - private void updateEmployeeList() { - updateEmployeeList(""); - } - - private void updateEmployeeList(String searchString) { - - try { - employeeListController.setData( - employeeService - .list() - .stream() - .filter( - employee -> - searchString.trim().isEmpty() - || employee.name() - .toLowerCase() - .contains(searchString.toLowerCase())) - .collect(Collectors.toCollection(HashSet::new)), - this::openEditEmployee); - - } catch (ServiceException e) { - LOG.error("ServiceException in updateEmployeeList(). ", e); - } - } - - public void setVisible(boolean b) { - listEmployeesAP.setVisible(b); - } - - public void backToMain() { - LOG.debug("Hyperlink \"Zurück\" clicked."); - this.setVisible(false); - createOperationController.setVisible(true); - } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/OperationDetailsController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/OperationDetailsController.java deleted file mode 100644 index c0c68f3..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/OperationDetailsController.java +++ /dev/null @@ -1,169 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller; - -import static at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller.Helper.showAlertWithOkButtonAndWait; -import static at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller.Helper.showServiceExceptionAlertAndWait; -import static at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller.Helper.showSuccessAlertAndWait; -import static at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller.Helper.showValidationErrorAlertAndWait; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.OperationService; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.VehicleService; -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidOperationException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; -import java.io.IOException; -import java.util.Collection; -import java.util.EnumSet; -import java.util.Set; -import java.util.stream.Collectors; -import javafx.collections.FXCollections; -import javafx.fxml.FXML; -import javafx.scene.control.Alert.AlertType; -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.control.ListView; -import javafx.scene.layout.AnchorPane; -import javafx.scene.layout.FlowPane; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Controller; - -@Controller -public class OperationDetailsController { - private static final Logger LOG = LoggerFactory.getLogger(OperationDetailsController.class); - - public Operation operation; - private final OperationService operationService; - private final VehicleService vehicleService; - private final CreateOperationController createOperationController; - @FXML private FlowPane fpVehicles; - @FXML private ListView lvActiveOperations; - @FXML private Label lblChosenVehicles; - @FXML private Button btnCloseOperation; - @FXML private Button btnCancelOperation; - @FXML private Label lblCode, lblAdditionalInfo, lblAddress; - @FXML private AnchorPane operationDetailsAP; - - public OperationDetailsController( - OperationService operationService, - VehicleService vehicleService, - CreateOperationController createOperationController) { - this.operationService = operationService; - this.vehicleService = vehicleService; - this.createOperationController = createOperationController; - } - - @FXML - private void initialize() { - lvActiveOperations.setCellFactory( - param -> CreateOperationController.generateOpCodeListItem()); - lvActiveOperations.setOnMouseClicked( - event -> { - if (event.getClickCount() == 2) { - if (lvActiveOperations.getSelectionModel().getSelectedItem() == null) { - return; - } - initOperation(lvActiveOperations.getSelectionModel().getSelectedItem()); - } - }); - } - - private void updateFlowPane() { - try { - fpVehicles.getChildren().clear(); - for (Vehicle vehicle : operation.vehicles()) { - VehiclePaneController controller = VehiclePaneController.createVehiclePane(); - controller.setData(vehicle, true, true); - controller.getBtnRequest().setOnAction(e -> requestVehicleClicked(controller)); - fpVehicles.getChildren().add(controller.getRootElement()); - } - } catch (IOException e) { - LOG.error("Error while updating list.", e); - showServiceExceptionAlertAndWait("Error while updating list."); - } - } - - void initOperation(Operation operation) { - fillActiveList(); - this.operation = operation; - lblCode.setText(operation.opCode()); - Collection vehicleNames = - operation.vehicles().stream().map(Vehicle::name).collect(Collectors.toList()); - String result = String.join(", ", vehicleNames); - lblChosenVehicles.setText(result.toString()); - lblAdditionalInfo.setText(operation.additionalInfo()); - lblAddress.setText(operation.destination()); - updateFlowPane(); - operationDetailsAP.setVisible(true); - } - - private void fillActiveList() { - try { - lvActiveOperations.setItems( - FXCollections.observableArrayList( - operationService.list(EnumSet.of(Status.ACTIVE)))); - } catch (ServiceException e) { - LOG.error("ServiceException in fillActiveList(). ", e); - showServiceExceptionAlertAndWait(e.getMessage()); - } - } - - @FXML - public void closeOperationClicked() { - LOG.debug("Button \"Abschließen\" clicked."); - try { - operationService.complete(operation.id(), Status.COMPLETED); - } catch (InvalidOperationException e) { - LOG.debug("Validation error in closeOperationClicked(). ", e); - showAlertWithOkButtonAndWait(AlertType.ERROR, "Validierungsfehler", e.getMessage()); - return; - } catch (ServiceException e) { - LOG.error("Exception in closeOperationClicked(). ", e); - showServiceExceptionAlertAndWait(e.getMessage()); - return; - } - showSuccessAlertAndWait("Der Einsatz wurde erfolgreich aktualisiert"); - createOperationController.updateList(); - closeWindow(); - } - - public void cancelOperationClicked() { - LOG.debug("Button \"Stornieren\" clicked."); - try { - operationService.complete(operation.id(), Status.CANCELLED); - } catch (InvalidOperationException e) { - LOG.debug("Validation error in cancelOperationClicked(). ", e); - showValidationErrorAlertAndWait(e.getMessage()); - return; - } catch (ServiceException e) { - LOG.error("Exception in cancelOperationClicked(). ", e); - showServiceExceptionAlertAndWait(e.getMessage()); - return; - } - showSuccessAlertAndWait("Der Einsatz wurde erfolgreich aktualisiert"); - createOperationController.updateList(); - closeWindow(); - } - - private void requestVehicleClicked(VehiclePaneController v) { - LOG.debug("Button \"Nachfordern\" clicked."); - - try { - operationService.requestVehicles(operation.id(), Set.of(v.getData().id())); - } catch (ServiceException | InvalidOperationException | InvalidVehicleException e) { - LOG.error("Exception in requestVehicleClicked()", e); - showServiceExceptionAlertAndWait(e.getMessage()); - return; - } - showSuccessAlertAndWait("Das Fahrzeug wurde erfolgreich angefordert"); - createOperationController.updateList(); - } - - public void closeWindow() { - LOG.debug("Hyperlink \"Zurück\" clicked."); - operationDetailsAP.setVisible(false); - this.createOperationController.setVisible(true); - } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/OperationInArchiveController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/OperationInArchiveController.java deleted file mode 100644 index d1b325c..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/OperationInArchiveController.java +++ /dev/null @@ -1,65 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; -import java.io.IOException; -import java.time.LocalDateTime; -import java.time.ZoneOffset; -import java.util.Collection; -import java.util.Objects; -import java.util.stream.Collectors; -import javafx.fxml.FXML; -import javafx.fxml.FXMLLoader; -import javafx.scene.Node; -import javafx.scene.text.Text; - -public class OperationInArchiveController { - - @FXML private Text txtAddress; - @FXML private Text txtVehicles; - @FXML private Text txtDate; - @FXML private Text txtOpCode; - - static OperationInArchiveController create() throws IOException { - FXMLLoader fxmlLoader = - new FXMLLoader( - OperationInArchiveController.class.getResource( - "/fxml/OperationInArchive.fxml")); - Node root = fxmlLoader.load(); - OperationInArchiveController result = fxmlLoader.getController(); - result.rootElement = root; - - return result; - } - - public Node getRoot() { - return rootElement; - } - - private Node rootElement; - - public void set(Operation operation) { - txtAddress.setText(operation.destination()); - String date = "am "; - if (operation.created() != null) { - LocalDateTime myDateTime = - LocalDateTime.ofInstant( - Objects.requireNonNull(operation.created()), ZoneOffset.UTC); - date += - myDateTime.getDayOfMonth() - + "." - + myDateTime.getMonth().getValue() - + "." - + myDateTime.getYear(); - txtDate.setText(date); - } else { - txtDate.setText("---"); - } - txtOpCode.setText(operation.opCode()); - Collection elements = - operation.vehicles().stream().map(Vehicle::name).collect(Collectors.toList()); - String result = String.join(", ", elements); - - txtVehicles.setText(result); - } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/RegistrationWindowController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/RegistrationWindowController.java deleted file mode 100644 index ed5a12d..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/RegistrationWindowController.java +++ /dev/null @@ -1,279 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller; - -import static at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller.Helper.showServiceExceptionAlertAndWait; -import static at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller.Helper.showValidationErrorAlertAndWait; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Registration; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.Status; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.EmployeeService; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.RegistrationService; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service.VehicleService; -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidRegistrationException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; -import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; -import java.io.IOException; -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.time.LocalTime; -import java.time.OffsetDateTime; -import java.util.EnumSet; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; -import javafx.fxml.FXML; -import javafx.geometry.Insets; -import javafx.scene.Node; -import javafx.scene.control.ChoiceBox; -import javafx.scene.control.Label; -import javafx.scene.control.ScrollPane; -import javafx.scene.control.TextField; -import javafx.scene.input.KeyEvent; -import javafx.scene.input.MouseButton; -import javafx.scene.layout.GridPane; -import javafx.scene.layout.VBox; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Controller; - -@Controller -public class RegistrationWindowController { - - private static final Logger LOG = LoggerFactory.getLogger(RegistrationWindowController.class); - - private final EmployeeService employeeService; - private final VehicleService vehicleService; - private final RegistrationService registrationService; - private final CreateOperationController createOperationController; - private final SpringFXMLLoader fxmlLoader; - - @FXML private GridPane root; - @FXML private VBox vbVehicles; - @FXML private ScrollPane listEmployee; - @FXML private ChoiceBox cbStart; - @FXML private ChoiceBox cbEnd; - @FXML private Label lVehicles; - @FXML private Label lEmployees; - @FXML private TextField tfVehicleSearch; - @FXML private TextField tfEmployeeSearch; - private EmployeeListController employeeListController; - - private Vehicle chosenVehicle; - private List chosenEmployees = new LinkedList<>(); - - public RegistrationWindowController( - EmployeeService employeeService, - VehicleService vehicleService, - CreateOperationController createOperationController, - RegistrationService registrationService, - SpringFXMLLoader fxmlLoader) { - this.employeeService = employeeService; - this.vehicleService = vehicleService; - this.createOperationController = createOperationController; - this.registrationService = registrationService; - this.fxmlLoader = fxmlLoader; - } - - @FXML - private void initialize() throws IOException { - employeeListController = EmployeeListController.createEmployeeListController(fxmlLoader); - employeeListController.setListItemMargins(new Insets(10, 6, 0, 6)); - // listEmployee. .getChildren().add(employeeListController.getRootElement()); - Node emplList = employeeListController.getRootElement(); - // emplList.(360); - listEmployee.setContent(emplList); - - ObservableList hours = - FXCollections.observableArrayList( - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23); - cbStart.setItems(hours); - cbStart.setValue(0); - cbEnd.setItems(hours); - cbEnd.setValue(12); - - reset(); - } - - private void updateEmplList() { - employeeListController.deselectAllEmployees(); - - try { - Set employees = - employeeService - .list() - .stream() - .filter( - e -> - e.name() - .toLowerCase() - .contains( - tfEmployeeSearch - .getText() - .toLowerCase())) - .collect(Collectors.toCollection(HashSet::new)); - employeeListController.setData( - employees, - selection -> { - if (selection == null) { - return; - } else if (chosenEmployees.contains(selection)) { - chosenEmployees.remove(selection); - } else { - chosenEmployees.add(selection); - } - - StringBuilder text = new StringBuilder(); - boolean first = true; - for (Employee employee : chosenEmployees) { - if (!first) { - text.append(", "); - } - text.append(employee.name()); - first = false; - } - lEmployees.setText(text.toString()); - }, - contr -> contr.setSelected(chosenEmployees.contains(contr.getEmployee()))); - - employees.forEach( - e -> { - if (chosenEmployees.contains(e)) employeeListController.selectEmployee(e); - }); - } catch (ServiceException e) { - LOG.error("ServiceException in updateEmplList(). ", e); - showServiceExceptionAlertAndWait( - "Beim Auflisten des Personals ist ein Fehler aufgetreten."); - } - } - - private void updateVehList() { - vbVehicles.getChildren().clear(); - - try { - Set vehicles = vehicleService.list(EnumSet.of(Status.ABGEMELDET)); - - boolean anyMatch = false; - - for (Vehicle vehicle : vehicles) { - if (!vehicle.name().toLowerCase().contains(tfVehicleSearch.getText().toLowerCase())) - continue; - - anyMatch = true; - - VehiclePaneController vp = VehiclePaneController.createVehiclePane(); - vp.setData(vehicle, false, false); - vbVehicles.getChildren().add(vp.getRootElement()); - - vp.getRootElement() - .setOnMouseClicked( - event -> { - if (event.getButton() == MouseButton.PRIMARY) { - chosenVehicle = vehicle; - lVehicles.setText(chosenVehicle.name()); - updateVehList(); - } - }); - if (chosenVehicle != null && chosenVehicle.id() == vehicle.id()) - vp.setSelected(true); - } - - if (!anyMatch) { - // Kind of ugly, but best way to get the size of a VehiclePane - VehiclePaneController vp = VehiclePaneController.createVehiclePane(); - vp.getRootElement().setVisible(false); - vbVehicles.getChildren().add(vp.getRootElement()); - } - } catch (ServiceException e) { - LOG.error("ServiceException in updateVehList(). ", e); - showServiceExceptionAlertAndWait( - "Beim Auflisten der Fahrzeuge ist ein Fehler aufgetreten"); - } catch (IOException e) { - LOG.error("IOException in updateVehList(). ", e); - showServiceExceptionAlertAndWait("Beim Laden der Fahrzeuge ist ein Fehler aufgetreten"); - } - } - - public void cancel() { - LOG.debug("Hyperlink \"schließen\" clicked"); - reset(); - this.setVisible(false); - createOperationController.setVisible(true); - } - - private void reset() { - chosenEmployees.clear(); - chosenVehicle = null; - tfEmployeeSearch.setText(""); - tfVehicleSearch.setText(""); - lEmployees.setText("-"); - lVehicles.setText("-"); - updateVehList(); - updateEmplList(); - } - - public void create() { - LOG.debug("Button \"ERSTELLEN\" clicked"); - - Set registrations = new HashSet<>(); - try { - if (chosenVehicle == null) { - throw new InvalidVehicleException("no Vehicle"); - } - for (Employee employee : chosenEmployees) { - registrations.add( - Registration.builder() - .id(chosenVehicle.id()) - .employee(employee) - .start( - LocalDateTime.of( - LocalDate.now(), - LocalTime.of(cbStart.getValue(), 0)) - .toInstant(OffsetDateTime.now().getOffset())) - .end( - LocalDateTime.of( - LocalDate.now(), - LocalTime.of(cbEnd.getValue(), 0)) - .toInstant(OffsetDateTime.now().getOffset())) - .build()); - } - - registrationService.add(chosenVehicle.id(), registrations); - chosenEmployees.clear(); - // ((Stage) lVehicles.getScene().getWindow()).close(); - this.setVisible(false); - createOperationController.setVisible(true); - reset(); - } catch (InvalidVehicleException e) { - LOG.debug("Validation of Vehicle in Registration failed."); - showValidationErrorAlertAndWait("Das spezifizierte Fahrzeug ist nicht gültig."); - } catch (ServiceException e) { - LOG.error("ServiceException in create(). ", e); - showServiceExceptionAlertAndWait( - "Beim Erstellen der Anmeldung ist ein Fehler aufgetreten."); - } catch (InvalidRegistrationException e) { - LOG.debug("Validation of Registration failed."); - showValidationErrorAlertAndWait( - "Die gewählte Kombination von Fahrzeug und Personal ist nicht gültig!"); - } - } - - public void setVisible(boolean b) { - root.setVisible(b); - reset(); - } - - public void tfVehicleSearch_TextChanged(KeyEvent keyEvent) { - updateVehList(); - } - - public void tfEmployeeSearch_TextChanged(KeyEvent keyEvent) { - updateEmplList(); - } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/VehiclePaneController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/VehiclePaneController.java deleted file mode 100644 index b31228d..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/VehiclePaneController.java +++ /dev/null @@ -1,118 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee.EducationLevel; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Registration; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.Status; -import java.io.IOException; -import java.time.Instant; -import java.util.List; -import java.util.Optional; -import javafx.fxml.FXML; -import javafx.fxml.FXMLLoader; -import javafx.scene.Node; -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.image.Image; -import javafx.scene.image.ImageView; -import javafx.scene.text.Text; - -public class VehiclePaneController extends CustomListItemController { - - public static VehiclePaneController createVehiclePane() throws IOException { - FXMLLoader fxmlLoader = - new FXMLLoader(VehiclePaneController.class.getResource("/fxml/vehiclePane.fxml")); - Node root = fxmlLoader.load(); - VehiclePaneController result = fxmlLoader.getController(); - result.rootElement = root; - - return result; - } - - @FXML private Label txtStatus; - @FXML private Text txtType; - @FXML private Text txtNumber; - @FXML private ImageView ivNEF; - @FXML private Text txtNEF; - @FXML private ImageView ivQualification; - @FXML private Text txtQualification; - @FXML private Text txtRooftype; - @FXML private Button btnRequest; - - private Vehicle data; - - public Vehicle getData() { - return data; - } - - /** - * * Set the displayed data of this VehiclePane. - * - * @param vehicle The data to display. - * @param showStatusInfo If true, the highest qualification of the vehicle's active registration - * and the vehicle's status will be shown. - */ - public void setData(Vehicle vehicle, boolean showStatusInfo, boolean showRequestVehicle) { - txtType.setText(vehicle.type().name()); - String constrType = vehicle.constructionType().name(); - txtRooftype.setText( - constrType.substring(0, 1).toUpperCase() + constrType.substring(1).toLowerCase()); - txtNumber.setText("-" + vehicle.id()); - if (vehicle.hasNef()) { - ivNEF.setImage(new Image("images/NEF.png")); - txtNEF.setText("hat NEF-Halterung"); - } else { - ivNEF.setImage(new Image("images/NotNEF.png")); - txtNEF.setText("keine NEF-Halterung"); - } - - if (showRequestVehicle) { - btnRequest.setVisible(true); - btnRequest.setManaged(true); - } else { - btnRequest.setVisible(false); - btnRequest.setManaged(false); - } - - if (showStatusInfo) { - txtStatus.setText(vehicle.status().name()); - if (vehicle.status() == Status.FREI_FUNK || vehicle.status() == Status.FREI_WACHE) { - txtStatus.getStyleClass().add("bg-status-green"); - } else { - txtStatus.getStyleClass().add("bg-status-orange"); - } - - Instant now = Instant.now(); - List regs = vehicle.registrations(); - - if (regs == null) { - return; - } - - Optional edu = - regs.stream() - .filter(reg -> reg.start().isBefore(now) && reg.end().isAfter(now)) - .map(reg -> reg.employee().educationLevel()) - .max(EducationLevel::compareTo); - - if (!edu.isPresent()) { - return; - } - - txtQualification.setText(edu.get().name()); - } else { - txtQualification.setVisible(false); - txtQualification.setManaged(false); - ivQualification.setVisible(false); - ivQualification.setManaged(false); - - txtStatus.setVisible(false); - } - - this.data = vehicle; - } - - public Button getBtnRequest() { - return btnRequest; - } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/EmployeeDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/EmployeeDAO.java deleted file mode 100644 index 539a8e5..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/EmployeeDAO.java +++ /dev/null @@ -1,44 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; -import java.util.Set; - -public interface EmployeeDAO { - - /** - * Persist the given employee. - * - * @param employee that should be stored - * @return the id that was assigned - * @throws PersistenceException if the employee could not be persisted - */ - long add(Employee employee) throws PersistenceException; - - /** - * Update the given employee. - * - * @param employee that should be updated - * @throws ElementNotFoundException if no employee with the given id exists - * @throws PersistenceException if the employee could not be updated - */ - void update(Employee employee) throws ElementNotFoundException, PersistenceException; - - /** - * Get all stored employees. - * - * @return list containing all stored employees - * @throws PersistenceException if loading the stored employees failed - */ - Set list() throws PersistenceException; - - /** - * Remove employee with the given id from the store. - * - * @param id of the employee that should be removed - * @throws ElementNotFoundException if no employee with the given id exists - * @throws PersistenceException if the employee could not be removed - */ - void remove(long id) throws ElementNotFoundException, PersistenceException; -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/EmployeeDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/EmployeeDatabaseDAO.java deleted file mode 100644 index 1d8286b..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/EmployeeDatabaseDAO.java +++ /dev/null @@ -1,144 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee.EducationLevel; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; -import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.time.LocalDate; -import java.util.HashSet; -import java.util.Set; -import org.springframework.stereotype.Repository; - -@Repository -public class EmployeeDatabaseDAO implements EmployeeDAO { - - private JDBCConnectionManager jdbcConnectionManager; - - public EmployeeDatabaseDAO(JDBCConnectionManager jdbcConnectionManager) { - this.jdbcConnectionManager = jdbcConnectionManager; - } - - private long createEmployeeVersion(Connection con, Employee e) - throws PersistenceException, SQLException { - String sql = - "INSERT INTO EmployeeVersion(name, birthday, educationLevel, isDriver, isPilot) " - + "VALUES(?, ?, ?, ?, ?)"; - - try (PreparedStatement pstmt = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { - pstmt.setString(1, e.name()); - pstmt.setObject(2, e.birthday()); - pstmt.setInt(3, e.educationLevel().ordinal()); - pstmt.setBoolean(4, e.isDriver()); - pstmt.setBoolean(5, e.isPilot()); - pstmt.executeUpdate(); - - try (ResultSet rs = pstmt.getGeneratedKeys()) { - if (!rs.next()) throw new PersistenceException("Failed to insert EmployeeVersion"); - - return rs.getLong(1); - } - } - } - - @Override - public long add(Employee employee) throws PersistenceException { - String sql = "INSERT INTO Employee(version) VALUES(?)"; - - try { - Connection con = jdbcConnectionManager.getConnection(); - con.setAutoCommit(false); - - long versionId = createEmployeeVersion(con, employee); - - try (PreparedStatement pstmt = - con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { - pstmt.setLong(1, versionId); - pstmt.executeUpdate(); - - try (ResultSet rs = pstmt.getGeneratedKeys()) { - if (!rs.next()) { - con.rollback(); - throw new PersistenceException("Failed to insert Employee"); - } - - con.commit(); - return rs.getLong(1); - } - } - } catch (SQLException e) { - jdbcConnectionManager.rollbackConnection(); - throw new PersistenceException(e); - } - } - - @Override - public void update(Employee employee) throws ElementNotFoundException, PersistenceException { - String sql = "UPDATE Employee SET version = ? WHERE id = ?"; - - try { - Connection con = jdbcConnectionManager.getConnection(); - con.setAutoCommit(false); - - long versionId = createEmployeeVersion(con, employee); - - try (PreparedStatement pstmt = con.prepareStatement(sql)) { - pstmt.setLong(1, versionId); - pstmt.setLong(2, employee.id()); - - if (pstmt.executeUpdate() != 1) { - con.rollback(); - throw new ElementNotFoundException("No such employeeId exists"); - } - } - - con.commit(); - } catch (SQLException e) { - jdbcConnectionManager.rollbackConnection(); - throw new PersistenceException(e); - } - } - - @Override - public Set list() throws PersistenceException { - String sql = - "SELECT emp.id, v.name, v.birthday, v.educationLevel, v.isDriver, v.isPilot " - + "FROM employee emp " - + "JOIN EmployeeVersion v ON v.id = emp.version"; - - try { - Connection con = jdbcConnectionManager.getConnection(); - Set employees = new HashSet<>(); - - try (PreparedStatement pstmt = con.prepareStatement(sql)) { - try (ResultSet rs = pstmt.executeQuery()) { - while (rs.next()) { - employees.add( - Employee.builder() - .id(rs.getLong(1)) - .name(rs.getString(2)) - .birthday(rs.getObject(3, LocalDate.class)) - .educationLevel(EducationLevel.valueOf(rs.getString(4))) - .isDriver(rs.getBoolean(5)) - .isPilot(rs.getBoolean(6)) - .build()); - } - } - } - - return employees; - } catch (SQLException e) { - throw new PersistenceException(e); - } - } - - @Override - public void remove(long id) throws ElementNotFoundException, PersistenceException { - throw new UnsupportedOperationException(); - } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDAO.java deleted file mode 100644 index d82f768..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDAO.java +++ /dev/null @@ -1,48 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; -import java.util.EnumSet; -import java.util.Set; - -public interface OperationDAO { - - /** - * Persist the given operation. - * - * @param operation that should be stored - * @return the id that was assigned - * @throws PersistenceException if the operation could not be persisted - */ - long add(Operation operation) throws PersistenceException; - - /** - * Update the given operation. - * - * @param operation that should be updated - * @throws ElementNotFoundException if no operation with the given id exists - * @throws PersistenceException if the operation could not be updated - */ - void update(Operation operation) throws ElementNotFoundException, PersistenceException; - - /** - * Returns the operation with the given id. - * - * @param operationId id of the operation that should be returned - * @return operation with the given id - * @throws ElementNotFoundException if no operation with the given id exists - * @throws PersistenceException if the operation could not be loaded - */ - Operation get(long operationId) throws ElementNotFoundException, PersistenceException; - - /** - * Get all stored operations with matching status. - * - * @param statuses set containing all statuses that should be matched - * @return list containing all matched operations - * @throws PersistenceException if loading the stored operations failed - */ - Set list(EnumSet statuses) throws PersistenceException; -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDatabaseDAO.java deleted file mode 100644 index 0b6ce08..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDatabaseDAO.java +++ /dev/null @@ -1,221 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Severity; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; -import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.time.OffsetDateTime; -import java.time.ZoneId; -import java.util.EnumSet; -import java.util.HashSet; -import java.util.Set; -import java.util.stream.Collectors; -import org.springframework.lang.NonNull; -import org.springframework.stereotype.Repository; - -@Repository -public class OperationDatabaseDAO implements OperationDAO { - - private JDBCConnectionManager jdbcConnectionManager; - private VehicleDAO vehicleDAO; - - public OperationDatabaseDAO( - JDBCConnectionManager jdbcConnectionManager, VehicleDAO vehicleDAO) { - this.jdbcConnectionManager = jdbcConnectionManager; - this.vehicleDAO = vehicleDAO; - } - - @Override - public long add(@NonNull Operation o) throws PersistenceException { - String sql = - "INSERT INTO Operation(opCode, severity, created, destination, additionalInfo," - + " status) VALUES (?, ?, ?, ?, ?, ?)"; - String sql2 = "INSERT INTO VehicleOperation(vehicleId, operationId) VALUES (?, ?)"; - long operationId; - - try { - Connection con = jdbcConnectionManager.getConnection(); - con.setAutoCommit(false); - try (PreparedStatement pstmt = con.prepareStatement(sql)) { - pstmt.setString(1, o.opCode()); - pstmt.setInt(2, o.severity().ordinal()); - pstmt.setObject(3, OffsetDateTime.ofInstant(o.created(), ZoneId.systemDefault())); - pstmt.setString(4, o.destination()); - pstmt.setString(5, o.additionalInfo()); - pstmt.setInt(6, o.status().ordinal()); - pstmt.executeUpdate(); - - try (ResultSet rs = pstmt.getGeneratedKeys()) { - if (!rs.next()) throw new PersistenceException("Failed to persist operation"); - - operationId = rs.getLong(1); - } - } - - try (PreparedStatement pstmt = con.prepareStatement(sql2)) { - pstmt.setLong(2, operationId); - - for (long id : (Iterable) o.vehicles().stream().map(Vehicle::id)::iterator) { - pstmt.setLong(1, id); - pstmt.addBatch(); - } - - pstmt.executeBatch(); - } - con.commit(); - return operationId; - } catch (SQLException e) { - jdbcConnectionManager.rollbackConnection(); - throw new PersistenceException(e); - } - } - - @Override - public void update(@NonNull Operation o) throws ElementNotFoundException, PersistenceException { - // Note this will, by design, not update created - String sql = - "UPDATE Operation SET opCode = ?, severity = ?, destination = ?," - + " additionalInfo = ?, status = ? WHERE id = ?"; - String sql2 = "DELETE FROM VehicleOperation WHERE operationId = ?"; - String sql3 = "INSERT INTO VehicleOperation(vehicleId, operationId) VALUES (?, ?)"; - - try { - Connection con = jdbcConnectionManager.getConnection(); - con.setAutoCommit(false); - try (PreparedStatement pstmt = con.prepareStatement(sql)) { - pstmt.setString(1, o.opCode()); - pstmt.setInt(2, o.severity().ordinal()); - pstmt.setString(3, o.destination()); - pstmt.setString(4, o.additionalInfo()); - pstmt.setInt(5, o.status().ordinal()); - pstmt.setLong(6, o.id()); - - if (pstmt.executeUpdate() != 1) - throw new ElementNotFoundException("No such operationId exists"); - } - - try (PreparedStatement pstmt = con.prepareStatement(sql2)) { - pstmt.setLong(1, o.id()); - pstmt.executeUpdate(); - } - - try (PreparedStatement pstmt = con.prepareStatement(sql3)) { - pstmt.setLong(2, o.id()); - - for (long id : (Iterable) o.vehicles().stream().map(Vehicle::id)::iterator) { - pstmt.setLong(1, id); - pstmt.addBatch(); - } - - pstmt.executeBatch(); - } - con.commit(); - } catch (SQLException e) { - jdbcConnectionManager.rollbackConnection(); - throw new PersistenceException(e); - } - } - - @Override - public Operation get(long operationId) throws ElementNotFoundException, PersistenceException { - String sql = "Select * from operation where id = ?"; - - try { - Connection con = jdbcConnectionManager.getConnection(); - try (PreparedStatement pstmt = con.prepareStatement(sql)) { - pstmt.setLong(1, operationId); - pstmt.execute(); - - try (ResultSet rs = pstmt.getResultSet()) { - if (!rs.next()) - throw new ElementNotFoundException("No such element could be found"); - - return operationFromRS(rs); - } - } - } catch (SQLException e) { - throw new PersistenceException(e); - } - } - - @Override - public Set list(EnumSet statuses) throws PersistenceException { - // This hack exists because H2 currently has a bug that prevents IN (?) with an array of - // ids, i.e. pstmt.setArray(1, con.createArrayOf("INT", intarray) from working. See - // commented code below. - - // SELECT * FROM Operation WHERE status IN ('COMPLETED', 'CANCELLED') is BUGGED on H2! - // for this reason we use the ordinal values instead - String str = - statuses.stream() - .map(e -> Integer.toString(e.ordinal())) - .collect(Collectors.joining(",")); - - String sql = "SELECT * FROM Operation WHERE status IN (" + str + ")"; - Set operations = new HashSet<>(); - - try { - Connection con = jdbcConnectionManager.getConnection(); - - try (PreparedStatement pstmt = con.prepareStatement(sql)) { - // Object[] arr = statuses.stream().map(Enum::ordinal).toArray(); - // pstmt.setArray(1, con.createArrayOf("INT", arr)); - - try (ResultSet rs = pstmt.executeQuery()) { - while (rs.next()) operations.add(operationFromRS(rs)); - } - } - - return operations; - } catch (SQLException e) { - throw new PersistenceException(e); - } - } - - private Operation operationFromRS(ResultSet rs) throws PersistenceException, SQLException { - Long operationId = rs.getLong("id"); - - return Operation.builder() - .id(operationId) - .opCode(rs.getString("opCode")) - .severity(Severity.valueOf(rs.getString("severity"))) - .status(Status.valueOf(rs.getString("status"))) - .vehicles(getVehiclesFromOperationId(operationId)) - .created((rs.getObject("created", OffsetDateTime.class)).toInstant()) - .destination(rs.getString("destination")) - .additionalInfo(rs.getString("additionalInfo")) - .build(); - } - - private Set getVehiclesFromOperationId(long operationId) throws PersistenceException { - String sql = "SELECT vehicleId FROM VehicleOperation WHERE operationId = ?"; - Set vehicles = new HashSet<>(); - - try { - Connection con = jdbcConnectionManager.getConnection(); - try (PreparedStatement pstmt = con.prepareStatement(sql)) { - pstmt.setLong(1, operationId); - pstmt.execute(); - - try (ResultSet rs = pstmt.getResultSet()) { - while (rs.next()) { - vehicles.add(vehicleDAO.get(rs.getLong("vehicleId"))); - } - } - } - } catch (SQLException e) { - throw new PersistenceException(e); - } catch (ElementNotFoundException e) { - throw new PersistenceException("VehicleOperation contained nonexistent vehicle", e); - } - - return vehicles; - } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/RegistrationDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/RegistrationDAO.java deleted file mode 100644 index 36b6f1b..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/RegistrationDAO.java +++ /dev/null @@ -1,28 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Registration; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; -import java.util.Set; - -public interface RegistrationDAO { - - /** - * Persist the given registration. - * - * @param vehicleId the id of the target vehicle - * @param registrations that should be stored - * @return a list of the ids that were assigned - * @throws PersistenceException if the registration could not be persisted - */ - Set add(long vehicleId, Set registrations) throws PersistenceException; - - /** - * Make registration with the given id inactive. - * - * @param id of the registration that should be made inactive - * @throws ElementNotFoundException if no registration with the given id exists - * @throws PersistenceException if the registration could not be made inactive - */ - void remove(long id) throws ElementNotFoundException, PersistenceException; -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/RegistrationDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/RegistrationDatabaseDAO.java deleted file mode 100644 index 9f7ac84..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/RegistrationDatabaseDAO.java +++ /dev/null @@ -1,130 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Registration; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; -import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.time.OffsetDateTime; -import java.time.ZoneId; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Repository; - -@Repository -public class RegistrationDatabaseDAO implements RegistrationDAO { - - private JDBCConnectionManager jdbcConnectionManager; - private EmployeeDAO employeePersistence; - - @Autowired - public RegistrationDatabaseDAO( - JDBCConnectionManager jdbcConnectionManager, EmployeeDAO employeePersistence) { - this.jdbcConnectionManager = jdbcConnectionManager; - this.employeePersistence = employeePersistence; - } - - @Override - public Set add(long vehicleId, Set registrations) - throws PersistenceException { - String sql = - "INSERT INTO Registration (vehicleId, employeeId, start, end, active) VALUES (?,?,?,?,?)"; - String sql2 = "UPDATE Vehicle SET status = 'FREI_WACHE' WHERE id = ?;"; - - Set vehicleIds = new HashSet<>(); - - try { - Connection con = jdbcConnectionManager.getConnection(); - con.setAutoCommit(false); - - try (PreparedStatement pstmt = - con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { - pstmt.setLong(1, vehicleId); - - for (Registration r : registrations) { - pstmt.setLong(2, r.employee().id()); - pstmt.setObject(3, OffsetDateTime.ofInstant(r.start(), ZoneId.systemDefault())); - pstmt.setObject(4, OffsetDateTime.ofInstant(r.end(), ZoneId.systemDefault())); - pstmt.setBoolean(5, true); - pstmt.addBatch(); - } - - pstmt.executeBatch(); - - try (ResultSet rs = pstmt.getGeneratedKeys()) { - while (rs.next()) vehicleIds.add(rs.getLong(1)); - } - } - - try (PreparedStatement pstmt = con.prepareStatement(sql2)) { - pstmt.setLong(1, vehicleId); - if (pstmt.executeUpdate() != 1) { - con.rollback(); - throw new PersistenceException("Failed to persist registration"); - } - } - - con.commit(); - return vehicleIds; - } catch (SQLException e) { - jdbcConnectionManager.rollbackConnection(); - throw new PersistenceException(e); - } - } - - @Override - public void remove(long id) throws ElementNotFoundException, PersistenceException { - throw new UnsupportedOperationException(); - } - - protected List list(long vehicleId) throws PersistenceException { - String sql = "SELECT * FROM Registration WHERE vehicleId = ?"; - - List registrationList = new ArrayList<>(); - try { - Connection con = jdbcConnectionManager.getConnection(); - - try (PreparedStatement pstmt = con.prepareStatement(sql)) { - pstmt.setLong(1, vehicleId); - - try (ResultSet rs = pstmt.executeQuery()) { - while (rs.next()) { - long employeeId = rs.getLong("employeeId"); - // TODO: replace the following with employeePersistence.get once implemented - Employee emp = - employeePersistence - .list() - .stream() - .filter(employee -> employee.id() == employeeId) - .findAny() - .orElse(null); - Registration registration = - Registration.builder() - .id(rs.getLong("id")) - .start( - (rs.getObject("start", OffsetDateTime.class)) - .toInstant()) - .end( - (rs.getObject("end", OffsetDateTime.class)) - .toInstant()) - .employee(emp) - .build(); - registrationList.add(registration); - } - } - } - - return registrationList; - } catch (SQLException e) { - throw new PersistenceException(e); - } - } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/VehicleDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/VehicleDAO.java deleted file mode 100644 index 5782fd9..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/VehicleDAO.java +++ /dev/null @@ -1,54 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; -import java.util.Set; - -public interface VehicleDAO { - - /** - * Persist the given vehicle. - * - * @param vehicle that should be stored - * @return the id that was assigned - * @throws PersistenceException if the vehicle could not be persisted - */ - long add(Vehicle vehicle) throws PersistenceException; - - /** - * Update the given vehicle. - * - * @param vehicle that should be updated - * @throws ElementNotFoundException if no vehicle with the given id exists - * @throws PersistenceException if the vehicle could not be updated - */ - void update(Vehicle vehicle) throws ElementNotFoundException, PersistenceException; - - /** - * Get all stored vehicles. - * - * @return list containing all stored vehicles - * @throws PersistenceException if loading the stored vehicles failed - */ - Set list() throws PersistenceException; - - /** - * Returns the vehicle with the given id. - * - * @param vehicleId id of the vehicle that should be returned - * @return vehicle with the given id - * @throws ElementNotFoundException if no vehicle with the given id exists - * @throws PersistenceException if the vehicle could not be loaded - */ - Vehicle get(long vehicleId) throws ElementNotFoundException, PersistenceException; - - /** - * Remove vehicle with the given id from the store. - * - * @param id of the vehicle that should be removed - * @throws ElementNotFoundException if no vehicle with the given id exists - * @throws PersistenceException if the vehicle could not be removed - */ - void remove(long id) throws ElementNotFoundException, PersistenceException; -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/VehicleDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/VehicleDatabaseDAO.java deleted file mode 100644 index fcae6d3..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/VehicleDatabaseDAO.java +++ /dev/null @@ -1,211 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.ConstructionType; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.Status; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.VehicleType; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; -import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.HashSet; -import java.util.Set; -import org.springframework.stereotype.Repository; - -@Repository -public class VehicleDatabaseDAO implements VehicleDAO { - - private final JDBCConnectionManager jdbcConnectionManager; - private RegistrationDatabaseDAO registrationDatabaseDao; - - public VehicleDatabaseDAO( - JDBCConnectionManager j, RegistrationDatabaseDAO registrationDatabaseDao) { - jdbcConnectionManager = j; - this.registrationDatabaseDao = registrationDatabaseDao; - } - - @Override - public long add(Vehicle v) throws PersistenceException { - String sql = - "INSERT INTO VehicleVersion (name,hasNef,constructionType,type) VALUES (?,?,?,?)"; - String sql2 = "INSERT INTO Vehicle (version,status) VALUES (?,?)"; - String sql3 = "UPDATE VehicleVersion SET name=? WHERE id=?"; - - try { - Connection con = jdbcConnectionManager.getConnection(); - con.setAutoCommit(false); - String name = ""; - long version, id; - - try (PreparedStatement pstmt = - con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { - pstmt.setString(1, name); - pstmt.setBoolean(2, v.hasNef()); - pstmt.setInt(3, v.constructionType().ordinal()); - pstmt.setString(4, v.type().name()); - pstmt.executeUpdate(); - - try (ResultSet rs = pstmt.getGeneratedKeys()) { - if (!rs.next()) - throw new PersistenceException("Failed to insert into VehicleVersion"); - - version = rs.getLong(1); - } - } - - try (PreparedStatement pstmt = - con.prepareStatement(sql2, Statement.RETURN_GENERATED_KEYS)) { - pstmt.setLong(1, version); - pstmt.setInt(2, Status.ABGEMELDET.ordinal()); - pstmt.executeUpdate(); - - try (ResultSet rs = pstmt.getGeneratedKeys()) { - if (!rs.next()) { - con.rollback(); - throw new PersistenceException("Failed to insert into Vehicle"); - } - - id = rs.getLong(1); - } - - name = v.type().name() + "-" + id; - } - - try (PreparedStatement pstmt = con.prepareStatement(sql3)) { - pstmt.setString(1, name); - pstmt.setLong(2, version); - - if (pstmt.executeUpdate() != 1) { - con.rollback(); - throw new PersistenceException("Failed to update VehicleVersion"); - } - } - - con.commit(); - return id; - } catch (SQLException e) { - jdbcConnectionManager.rollbackConnection(); - throw new PersistenceException(e); - } - } - - @Override - public void update(Vehicle v) throws ElementNotFoundException, PersistenceException { - String sql = "SELECT version FROM Vehicle WHERE id = ?"; - String sql2 = - "MERGE INTO VehicleVersion(name, constructionType, type, hasNef)" - + " KEY(name, constructionType, type, hasNef) VALUES(?, ?, ?, ?)"; - String sql3 = "UPDATE Vehicle SET version = ?, status = ? WHERE id = ?"; - - long versionId; - - try { - Connection con = jdbcConnectionManager.getConnection(); - con.setAutoCommit(false); - try (PreparedStatement pstmt = con.prepareStatement(sql)) { - pstmt.setLong(1, v.id()); - - try (ResultSet rs = pstmt.executeQuery()) { - if (!rs.next()) throw new ElementNotFoundException("No such vehicleId exists"); - - versionId = rs.getLong(1); - } - } - - try (PreparedStatement pstmt = - con.prepareStatement(sql2, Statement.RETURN_GENERATED_KEYS)) { - pstmt.setString(1, v.type().name() + "-" + v.id()); - pstmt.setString(2, v.constructionType().name()); - pstmt.setString(3, v.type().name()); - pstmt.setBoolean(4, v.hasNef()); - pstmt.executeUpdate(); - - try (ResultSet rs = pstmt.getGeneratedKeys()) { - if (rs.next()) { - // version changed, update it - versionId = rs.getLong(1); - } - } - } - - try (PreparedStatement pstmt = con.prepareStatement(sql3)) { - pstmt.setLong(1, versionId); - pstmt.setString(2, v.status().name()); - pstmt.setLong(3, v.id()); - pstmt.executeUpdate(); - } - - con.commit(); - } catch (SQLException e) { - jdbcConnectionManager.rollbackConnection(); - throw new PersistenceException(e); - } - } - - @Override - public Set list() throws PersistenceException { - Set result = new HashSet<>(); - - String sql = - "Select * from VehicleVersion, Vehicle where VehicleVersion.id=Vehicle.version"; - - try (PreparedStatement pstmt = - jdbcConnectionManager.getConnection().prepareStatement(sql)) { - pstmt.executeQuery(); - try (ResultSet rs = pstmt.getResultSet()) { - while (rs.next()) { - result.add(vehicleFromRS(rs)); - } - } - } catch (SQLException e) { - throw new PersistenceException(e); - } - return result; - } - - @Override - public Vehicle get(long id) throws ElementNotFoundException, PersistenceException { - String sql = - "SELECT a.id, b.name, b.constructionType, b.type, a.status, b.hasNef" - + " FROM Vehicle a" - + " INNER JOIN VehicleVersion b" - + " ON version = b.id" - + " WHERE a.id = ?"; - - try { - Connection con = jdbcConnectionManager.getConnection(); - try (PreparedStatement pstmt = con.prepareStatement(sql)) { - pstmt.setLong(1, id); - - try (ResultSet rs = pstmt.executeQuery()) { - if (!rs.first()) throw new ElementNotFoundException("No such vehicle exists"); - - return vehicleFromRS(rs); - } - } - } catch (SQLException e) { - throw new PersistenceException(e); - } - } - - @Override - public void remove(long id) throws ElementNotFoundException, PersistenceException { - throw new UnsupportedOperationException(); - } - - private Vehicle vehicleFromRS(ResultSet rs) throws SQLException, PersistenceException { - return Vehicle.builder() - .id(rs.getLong("Vehicle.id")) - .name(rs.getString("name")) - .constructionType(ConstructionType.values()[rs.getInt("constructionType")]) - .type(VehicleType.valueOf(rs.getString("type"))) - .status(Status.values()[rs.getInt("status")]) - .hasNef(rs.getBoolean("hasNef")) - .registrations(registrationDatabaseDao.list(rs.getLong("id"))) - .build(); - } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/Employee.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/Employee.java deleted file mode 100644 index 583bf5b..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/Employee.java +++ /dev/null @@ -1,51 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto; - -import com.google.auto.value.AutoValue; -import java.time.LocalDate; - -@AutoValue -public abstract class Employee { - public enum EducationLevel { - RS, - NFS, - NKV, - NKA, - NKI, - NA - } - - public abstract long id(); - - public abstract String name(); - - public abstract LocalDate birthday(); - - public abstract EducationLevel educationLevel(); - - public abstract boolean isDriver(); - - public abstract boolean isPilot(); - - public static Builder builder() { - return new AutoValue_Employee.Builder().id(0); - } - - @AutoValue.Builder - public abstract static class Builder { - public abstract Builder id(long id); - - public abstract Builder name(String name); - - public abstract Builder birthday(LocalDate birthday); - - public abstract Builder educationLevel(EducationLevel educationLevel); - - public abstract Builder isDriver(boolean isDriver); - - public abstract Builder isPilot(boolean isPilot); - - public abstract Employee build(); - } - - public abstract Builder toBuilder(); -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/EmployeeValidator.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/EmployeeValidator.java deleted file mode 100644 index 36d8003..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/EmployeeValidator.java +++ /dev/null @@ -1,23 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto; - -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidEmployeeException; - -public class EmployeeValidator { - - public static boolean validate(Employee employee) throws InvalidEmployeeException { - - if (employee.name() == null || employee.name().trim().length() == 0) { - throw new InvalidEmployeeException("Name darf nicht leer sein!"); - } - - if (employee.birthday() == null) { - throw new InvalidEmployeeException("Geburtsdatum darf nicht leer sein!"); - } - - if (employee.educationLevel() == null) { - throw new InvalidEmployeeException("Ausbildungsgrad darf nicht leer sein!"); - } - - return true; - } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/Operation.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/Operation.java deleted file mode 100644 index 3a97dc7..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/Operation.java +++ /dev/null @@ -1,70 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto; - -import com.google.auto.value.AutoValue; -import java.time.Instant; -import java.util.Set; -import javax.annotation.Nullable; - -@AutoValue -public abstract class Operation { - public enum Severity { - A, - B, - C, - D, - E, - O, - } - - public enum Status { - ACTIVE, - COMPLETED, - CANCELLED, - } - - public abstract long id(); - - public abstract String opCode(); - - @Nullable - public abstract Severity severity(); - - public abstract Status status(); - - public abstract Set vehicles(); - - @Nullable - public abstract Instant created(); - - public abstract String destination(); - - @Nullable - public abstract String additionalInfo(); - - public static Builder builder() { - return new AutoValue_Operation.Builder().id(0); - } - - @AutoValue.Builder - public abstract static class Builder { - public abstract Builder id(long id); - - public abstract Builder opCode(String opCode); - - public abstract Builder severity(Severity severity); - - public abstract Builder status(Status status); - - public abstract Builder vehicles(Set vehicles); - - public abstract Builder created(Instant created); - - public abstract Builder destination(String destination); - - public abstract Builder additionalInfo(String additionalInfo); - - public abstract Operation build(); - } - - public abstract Builder toBuilder(); -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/Registration.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/Registration.java deleted file mode 100644 index 8551266..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/Registration.java +++ /dev/null @@ -1,34 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto; - -import com.google.auto.value.AutoValue; -import java.time.Instant; - -@AutoValue -public abstract class Registration { - public abstract long id(); - - public abstract Instant start(); - - public abstract Instant end(); - - public abstract Employee employee(); - - public static Builder builder() { - return new AutoValue_Registration.Builder().id(0); - } - - @AutoValue.Builder - public abstract static class Builder { - public abstract Builder id(long id); - - public abstract Builder start(Instant start); - - public abstract Builder end(Instant end); - - public abstract Builder employee(Employee employee); - - public abstract Registration build(); - } - - public abstract Builder toBuilder(); -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/RegistrationValidator.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/RegistrationValidator.java deleted file mode 100644 index 3456534..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/RegistrationValidator.java +++ /dev/null @@ -1,174 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee.EducationLevel; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.VehicleType; -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidRegistrationException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; - -public class RegistrationValidator { - - private RegistrationValidator() {} - - public static void validate(Vehicle vehicle, Set registrations) - throws InvalidVehicleException, InvalidRegistrationException { - /* - Vehicles and Employees are assumed to be valid. - They have been checked at creation, and for them to be checked again, access to - VehicleValidator and EmployeeValidator are needed, which are not available at this time. - */ - /* - The method used here goes as follows: All given employees are inspected in regards to their - qualifications, and added to the appropriate lists of the roles they could fill. - For example, an NFS, who is also a driver, would be added to the lists driverIds, nfsIds - and rsIds (because an NFS can always substitute an RS). - Afterwards, the number of people is checked according to the chosen vehicle type, and if - the number is okay, the program tries to find a valid combination of roles for the vehicle. - For example, for an RTW, first a driver is chosen, their ID marked as found in the aptly - titled HashMap, and then for the second RS, the list of RS is checked, excluding the chosen - driver. If no other valid RS is found, the next possible driver is chosen, and so on. If no - valid combination is found, an InvalidRegistrationException is thrown. - */ - List pilotIds = new LinkedList<>(); - List driverIds = new LinkedList<>(); - List naIds = new LinkedList<>(); - List nfsIds = new LinkedList<>(); - List rsIds = new LinkedList<>(); - HashMap found = - new HashMap<>(); // needed later in DFS, checks that no person is chosen twice - int total = 0; - for (Registration registration : registrations) { - total++; - if (found.put(registration.employee().id(), false) != null) { - throw new InvalidRegistrationException( - "Person mit der ID: " - + registration.employee().id() - + " wurde mehrmals hinzugefügt!"); - } - if (registration.employee().isPilot()) { - pilotIds.add(registration.employee().id()); - } - if (registration.employee().isDriver()) { - driverIds.add(registration.employee().id()); - } - if (registration.employee().educationLevel() == EducationLevel.NA) { - naIds.add(registration.employee().id()); - nfsIds.add(registration.employee().id()); - rsIds.add(registration.employee().id()); - } else if (isNFS(registration.employee())) { - nfsIds.add(registration.employee().id()); - rsIds.add(registration.employee().id()); - } else { // only RS left - rsIds.add(registration.employee().id()); - } - } - if (total <= 0) { - throw new InvalidRegistrationException("Kein Personal ausgewählt!"); - } - if (vehicle.type() == VehicleType.NAH) { - /* - NAH - 1 Pilot - 1 NFS - 1 NA - 3-4 Personen - */ - if (total < 3) { - throw new InvalidRegistrationException("Zu wenig Personal für NAH!"); - } else if (total > 4) { - throw new InvalidRegistrationException("Zu viel Personal für NAH!"); - } - for (long pilot_id : pilotIds) { - found.put(pilot_id, true); - for (long na_id : naIds) { - if (found.get(na_id)) continue; - found.put(na_id, true); - for (long nfs_id : nfsIds) { - if (found.get(nfs_id)) continue; - return; - } - found.put(na_id, false); - } - found.put(pilot_id, false); - } - throw new InvalidRegistrationException( - "Keine gültige Kombination von Personen für NAH!"); - } else if (vehicle.type() == VehicleType.NEF) { - /* - NEF - 1 Driver (has to be NFS) - 1 NA - */ - if (total < 2) { - throw new InvalidRegistrationException("Zu wenig Personal für NEF!"); - } else if (total > 3) { - throw new InvalidRegistrationException("Zu viel Personal für NEF!"); - } - for (long driver_id : driverIds) { - if (!nfsIds.contains(driver_id)) - continue; // if possible driver is not NFS, skip him - found.put(driver_id, true); - for (long na_id : naIds) { - if (found.get(na_id)) continue; - return; - } - found.put(driver_id, false); - } - throw new InvalidRegistrationException( - "Keine gültige Kombination von Personen für NEF!"); - } else if (vehicle.type() == VehicleType.BKTW) { - /* - BKTW - 1 Driver - */ - if (total > 3) { - throw new InvalidRegistrationException("Zu viel Personal für BKTW!"); - } - if (!driverIds.isEmpty()) { - return; - } - throw new InvalidRegistrationException("Kein Fahrer gefunden für BKTW!"); - } else { // KTW or RTW, both have the same requirements - /* - RTW/KTW - 1 Driver - 1 RS - */ - if (total < 2) { - throw new InvalidRegistrationException( - "Zu wenig Personal für " + vehicle.type().name() + "!"); - } else if (total > 4) { - throw new InvalidRegistrationException( - "Zu viel Persoanl für " + vehicle.type().name() + "!"); - } - for (long driver_id : driverIds) { // driver includes rs - found.put(driver_id, true); - for (long rs_id : rsIds) { - if (found.get(rs_id)) continue; - return; - } - } - throw new InvalidRegistrationException( - "Keine gültige Kombination von Personen für " + vehicle.type().name() + "!"); - } - } - - private static boolean isNFS(Employee employee) { - EducationLevel educationLevel = employee.educationLevel(); - switch (educationLevel) { - case NFS: - return true; - case NKA: - return true; - case NKI: - return true; - case NKV: - return true; - default: - return false; - } - } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/Vehicle.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/Vehicle.java deleted file mode 100644 index e81db0b..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dto/Vehicle.java +++ /dev/null @@ -1,73 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto; - -import com.google.auto.value.AutoValue; -import java.util.List; -import javax.annotation.Nullable; - -@AutoValue -public abstract class Vehicle { - public enum ConstructionType { - NORMAL, - HOCHDACH, - MITTELHOCHDACH, - } - - public enum VehicleType { - BKTW, - KTW_B, - KTW, - RTW, - NEF, - NAH, - } - - public enum Status { - ABGEMELDET, - FREI_WACHE, - FREI_FUNK, - ZUM_BERUFUNGSORT, - AM_BERUFUNGSORT, - ZUM_ZIELORT, - AM_ZIELORT, - } - - public abstract long id(); - - public abstract String name(); - - public abstract ConstructionType constructionType(); - - public abstract VehicleType type(); - - public abstract Status status(); - - public abstract boolean hasNef(); - - @Nullable - public abstract List registrations(); - - public static Builder builder() { - return new AutoValue_Vehicle.Builder().id(0); - } - - @AutoValue.Builder - public abstract static class Builder { - public abstract Builder id(long id); - - public abstract Builder name(String name); - - public abstract Builder constructionType(ConstructionType constructionType); - - public abstract Builder type(VehicleType type); - - public abstract Builder status(Status status); - - public abstract Builder hasNef(boolean hasNef); - - public abstract Builder registrations(List registrations); - - public abstract Vehicle build(); - } - - public abstract Builder toBuilder(); -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/EmployeeService.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/EmployeeService.java deleted file mode 100644 index f7f8e71..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/EmployeeService.java +++ /dev/null @@ -1,46 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee; -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidEmployeeException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; -import java.util.Set; - -public interface EmployeeService { - - /** - * Add given employee to the store. - * - * @param employee that should be added to the store - * @return the id that was assigned - * @throws InvalidEmployeeException if the employee is invalid - * @throws ServiceException if the employee could not be persisted - */ - long add(Employee employee) throws InvalidEmployeeException, ServiceException; - - /** - * Update the given employee. - * - * @param employee that should be updated - * @return the updated employee - * @throws InvalidEmployeeException if the employee is invalid - * @throws ServiceException if the updated employee could not be persisted - */ - Employee update(Employee employee) throws InvalidEmployeeException, ServiceException; - - /** - * Get all stored employees. - * - * @return list containing all stored employees - * @throws ServiceException if loading the stored employees failed - */ - Set list() throws ServiceException; - - /** - * Remove employee with the given id from the store. - * - * @param id of the employee that should be removed - * @throws InvalidEmployeeException if given employee id is invalid or does not exist - * @throws ServiceException if the employee could not be removed from the store - */ - void remove(long id) throws InvalidEmployeeException, ServiceException; -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/EmployeeServiceImpl.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/EmployeeServiceImpl.java deleted file mode 100644 index cf054c3..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/EmployeeServiceImpl.java +++ /dev/null @@ -1,59 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.EmployeeDAO; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Employee; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.EmployeeValidator; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidEmployeeException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; -import java.util.Set; -import org.springframework.stereotype.Service; - -@Service -public class EmployeeServiceImpl implements EmployeeService { - - private final EmployeeDAO employeePersistence; - - public EmployeeServiceImpl(EmployeeDAO employeePersistence) { - this.employeePersistence = employeePersistence; - } - - @Override - public long add(Employee employee) throws InvalidEmployeeException, ServiceException { - - EmployeeValidator.validate(employee); - try { - return employeePersistence.add(employee); - } catch (PersistenceException e) { - throw new ServiceException(e); - } - } - - @Override - public Employee update(Employee employee) throws InvalidEmployeeException, ServiceException { - - EmployeeValidator.validate(employee); - try { - employeePersistence.update(employee); - return employee; - } catch (ElementNotFoundException | PersistenceException e) { - throw new ServiceException(e); - } - } - - @Override - public Set list() throws ServiceException { - - try { - return employeePersistence.list(); - } catch (PersistenceException e) { - throw new ServiceException(e); - } - } - - @Override - public void remove(long id) throws InvalidEmployeeException, ServiceException { - throw new UnsupportedOperationException(); - } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationService.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationService.java deleted file mode 100644 index 4b7e630..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationService.java +++ /dev/null @@ -1,70 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidOperationException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; -import java.util.EnumSet; -import java.util.Set; -import java.util.SortedSet; - -public interface OperationService { - - /** - * Add given operation to the store. - * - * @param operation that should be added to the store - * @return the id that was assigned - * @throws InvalidOperationException if the operation is invalid - * @throws ServiceException if the operation could not be persisted - */ - long add(Operation operation) throws InvalidOperationException, ServiceException; - - /** - * Request new vehicles to the given operation. - * - * @param operationId id of the operation that the vehicles should be send to - * @param vehicleIds the ids of the vehicles that should be send to the given operation - * @throws InvalidOperationException if the operationId is invalid or does not exist - * @throws InvalidVehicleException if one of the vehicle ids is invalid or does not exist - * @throws ServiceException if the vehicles could not be loaded or the operation could not be - * persisted - */ - void requestVehicles(long operationId, Set vehicleIds) - throws InvalidOperationException, InvalidVehicleException, ServiceException; - - /** - * Completes the given operation with the specified status. - * - * @param operationId id of the operation that should be completed - * @param status of the completed operation, either {@link Status#COMPLETED} or {@link - * Status#CANCELLED} - * @throws InvalidOperationException if the operationId is invalid or does not exist - * @throws ServiceException if the operation could not be persisted - */ - void complete(long operationId, Status status) - throws InvalidOperationException, ServiceException; - - /** - * Get all available vehicles, sorted by how well they fit to the given opCode, starting with - * the best fitting. - * - * @param opCode the operation code that is used to determine the ranking - * @return a sorted list containing all available vehicles - * @throws InvalidOperationException if the opCode is invalid - * @throws ServiceException if loading the stored vehicles failed - */ - SortedSet rankVehicles(String opCode) - throws InvalidOperationException, ServiceException; - - /** - * Get all stored operations with matching status. - * - * @param statuses set containing all statuses that should be matched - * @return list containing all matched operations - * @throws ServiceException if loading the stored operations failed - */ - Set list(EnumSet statuses) throws ServiceException; -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceImpl.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceImpl.java deleted file mode 100644 index a83cf64..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/OperationServiceImpl.java +++ /dev/null @@ -1,286 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.OperationDAO; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.VehicleDAO; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Severity; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Operation.Status; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.VehicleType; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidOperationException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; -import java.time.Instant; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.EnumSet; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.SortedSet; -import java.util.TreeSet; -import java.util.function.Predicate; -import java.util.function.Supplier; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Service; - -@Service -public class OperationServiceImpl implements OperationService { - - private static final Logger LOG = LoggerFactory.getLogger(OperationServiceImpl.class); - - private final OperationDAO operationDAO; - private final VehicleDAO vehicleDAO; - private final VehicleService vehicleService; - - public OperationServiceImpl( - OperationDAO operationDAO, VehicleDAO vehicleDAO, VehicleService vehicleService) { - this.operationDAO = operationDAO; - this.vehicleDAO = vehicleDAO; - this.vehicleService = vehicleService; - } - - @Override - public long add(Operation o) throws InvalidOperationException, ServiceException { - if (o.created() != null) { - throw new InvalidOperationException("Erstellungszeitpunkt darf nicht gesetzt sein"); - } - - if (o.severity() != null) { - throw new InvalidOperationException("Der Schweregrad darf nicht gesetzt sein"); - } - - if (o.id() != 0) { - throw new InvalidOperationException("Einsatz-ID muss 0 sein"); - } - - if (o.status() != Status.ACTIVE) - LOG.info("Status was set but will be overridden"); // TODO: nullable instead?? - - try { - for (long id : (Iterable) o.vehicles().stream().map(Vehicle::id)::iterator) { - Vehicle v = vehicleDAO.get(id); - VehicleServiceImpl.validateVehicle(v); - - if (v.status() != Vehicle.Status.FREI_FUNK - && v.status() != Vehicle.Status.FREI_WACHE) - throw new InvalidOperationException("Fahrzeug nicht verfügbar: " + v.status()); - } - - validateOperation(o); - - return operationDAO.add( - o.toBuilder() - .created(Instant.now()) - .severity(extractSeverityFromOpCode(o.opCode())) - .status(Status.ACTIVE) - .build()); - } catch (PersistenceException e) { - throw new ServiceException(e); - } catch (InvalidVehicleException e) { - // already logged as invalid vehicle - throw new InvalidOperationException("Enthaltenes Fahrzeug ist ungültig", e); - } catch (ElementNotFoundException e) { - throw new InvalidOperationException("Enthaltenes Fahrzeug existiert nicht", e); - } - } - - @Override - public void requestVehicles(long operationId, Set vehicleIds) - throws InvalidOperationException, InvalidVehicleException, ServiceException { - Set vs = new HashSet<>(); - - try { - if (operationId <= 0) { - throw new InvalidOperationException("Einsatz-ID ist ungültig"); - } - Operation o = operationDAO.get(operationId); - validateOperation(o); - - if (o.opCode().trim().isEmpty() - || extractSeverityFromOpCode(o.opCode()) != o.severity()) { - throw new InvalidOperationException("Einsatzcode ist ungültig"); - } - - if (o.status() != Status.ACTIVE) { - throw new InvalidOperationException("Einsatz ist ungültig"); - } - - if (o.created() == null) { - throw new InvalidOperationException("Erstellungszeitpunkt darf nicht leer sein"); - } - - for (Long id : vehicleIds) { - if (id <= 0) { - throw new InvalidVehicleException("Fahrzeug-ID ist ungültig"); - } - - try { - Vehicle v = vehicleDAO.get(id); - VehicleServiceImpl.validateVehicle(v); - if (v.status() != Vehicle.Status.FREI_FUNK - && v.status() != Vehicle.Status.FREI_WACHE) - throw new InvalidOperationException( - "Fahrzeug nicht verfügbar: " + v.status()); - - vs.add(v); - } catch (ElementNotFoundException e) { - throw new InvalidVehicleException("VehicleId ist invalid"); - } - } - - vs.addAll(o.vehicles()); - if (vs.equals(o.vehicles())) return; - - operationDAO.update(o.toBuilder().vehicles(vs).build()); - } catch (ElementNotFoundException e) { - throw new InvalidOperationException("Kein Einsatz mit dieser ID existiert"); - } catch (PersistenceException e) { - throw new ServiceException(e); - } - } - - @Override - public void complete(long operationId, Status status) - throws InvalidOperationException, ServiceException { - try { - Operation o = operationDAO.get(operationId); - operationDAO.update(o.toBuilder().status(status).build()); - } catch (ElementNotFoundException e) { - throw new InvalidOperationException(e); - } catch (PersistenceException e) { - throw new ServiceException(e); - } - } - - @Override - public SortedSet rankVehicles(String opCode) - throws InvalidOperationException, ServiceException { - Set vehicles = - vehicleService.list(EnumSet.complementOf(EnumSet.of(Vehicle.Status.ABGEMELDET))); - - List> priorities = new ArrayList<>(); - Predicate ktw = v -> v.type() == VehicleType.KTW; - Predicate rtwNoNEF = v -> v.type() == VehicleType.RTW && !v.hasNef(); - Predicate rtwNEF = v -> v.type() == VehicleType.RTW && v.hasNef(); - Predicate nef = v -> v.type() == VehicleType.NEF; - Predicate nah = v -> v.type() == VehicleType.NAH; - - switch (extractSeverityFromOpCode(opCode)) { - case A: - // fallthrough - case B: - // fallthrough - case O: - priorities.add(ktw); - priorities.add(rtwNoNEF); - priorities.add(rtwNEF); - break; - case C: - priorities.add(rtwNEF); - priorities.add(rtwNoNEF); - priorities.add(ktw); - break; - case D: - priorities.add(rtwNEF); - priorities.add(nef); - priorities.add(nah); - priorities.add(rtwNoNEF); - priorities.add(ktw); - break; - case E: - priorities.add(nah); - priorities.add(nef); - priorities.add(rtwNEF); - priorities.add(rtwNoNEF); - priorities.add(ktw); - break; - } - - Comparator vehicleComparator = - (v1, v2) -> { - for (Predicate priority : priorities) { - if (priority.test(v1)) { - return -1; - } - if (priority.test(v2)) { - return +1; - } - } - return 0; - }; - - Supplier> supplier = () -> new TreeSet<>(vehicleComparator); - - return vehicles.stream().collect(Collectors.toCollection(supplier)); - } - - @Override - public Set list(EnumSet statuses) throws ServiceException { - try { - Set operations = operationDAO.list(statuses); - for (Operation o : operations) validateOperation(o); - - return operations; - } catch (PersistenceException e) { - throw new ServiceException(e); - } catch (InvalidOperationException e) { - // database returned invalid values - throw new ServiceException("DB returned invalid operation", e); - } - } - - private static void validateOperation(Operation o) throws InvalidOperationException { - if (o.vehicles().isEmpty()) { - throw new InvalidOperationException( - "Es muss mindestens ein Fahrzeug ausgewählt werden!"); - } - - for (Vehicle v : o.vehicles()) { - try { - VehicleServiceImpl.validateVehicle(v); - } catch (InvalidVehicleException e) { - throw new InvalidOperationException("Fahrzeug " + v.name() + " ist ungültig", e); - } - - // TODO: validate if NEF/RTW/NAH conditions? - } - - Instant created = o.created(); - if (created != null && created.isAfter(Instant.now())) { - throw new InvalidOperationException("Einsatz wurde in der Zukunft erstellt"); - } - - if (o.destination() == null || o.destination().trim().isEmpty()) { - throw new InvalidOperationException("Adresse darf nicht leer sein"); - } - - if (o.destination().length() > 100) { - throw new InvalidOperationException("Adresse darf 100 Zeichen nicht überschreiten"); - } - - if (o.additionalInfo() != null && o.additionalInfo().length() > 100) { - throw new InvalidOperationException("Anmerkung darf 100 Zeichen nicht überschreiten"); - } - } - - private static final Pattern opCodePattern = - Pattern.compile("(?:\\w{1,3}-\\d{0,2})([ABCDEO])(?:.*)"); - - private static Severity extractSeverityFromOpCode(String opCode) - throws InvalidOperationException { - Matcher m = opCodePattern.matcher(opCode); - - if (!m.matches()) { - throw new InvalidOperationException("Einsatzcode ist ungültig"); - } - - return Severity.valueOf(m.group(1)); - } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/RegistrationService.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/RegistrationService.java deleted file mode 100644 index b7d8eef..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/RegistrationService.java +++ /dev/null @@ -1,32 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Registration; -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidRegistrationException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; -import java.util.Set; - -public interface RegistrationService { - - /** - * Register employee to a vehicle. - * - * @param vehicleId the id of the target vehicle - * @param registrations that should be added to the vehicle - * @return the list of ids that were assigned - * @throws InvalidVehicleException if the vehicleId is invalid or does not exist - * @throws InvalidRegistrationException if the registration is invalid - * @throws ServiceException if the registration could not be persisted - */ - Set add(long vehicleId, Set registrations) - throws InvalidVehicleException, InvalidRegistrationException, ServiceException; - - /** - * Remove given registration from the store. - * - * @param registrationId the id of the registration that should be removed - * @throws InvalidRegistrationException if the registration is invalid or does not exist - * @throws ServiceException if the registration could not be removed from the store - */ - void remove(long registrationId) throws InvalidRegistrationException, ServiceException; -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/RegistrationServiceImpl.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/RegistrationServiceImpl.java deleted file mode 100644 index 1d92644..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/RegistrationServiceImpl.java +++ /dev/null @@ -1,52 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.RegistrationDAO; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.VehicleDAO; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Registration; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.RegistrationValidator; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidRegistrationException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; -import java.util.Set; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -@Service -public class RegistrationServiceImpl implements RegistrationService { - - private final RegistrationDAO registrationDAO; - private final VehicleDAO vehicleDAO; - - @Autowired - public RegistrationServiceImpl(RegistrationDAO registrationDAO, VehicleDAO vehicleDAO) { - this.registrationDAO = registrationDAO; - this.vehicleDAO = vehicleDAO; - } - - @Override - public Set add(long vehicleId, Set registrations) - throws InvalidVehicleException, InvalidRegistrationException, ServiceException { - - if (vehicleId <= 0) throw new InvalidVehicleException("VehicleId invalid"); - - try { - Vehicle vehicle = vehicleDAO.get(vehicleId); - - RegistrationValidator.validate(vehicle, registrations); - - return registrationDAO.add(vehicle.id(), registrations); - } catch (PersistenceException e) { - throw new ServiceException(e); - } catch (ElementNotFoundException e) { - throw new InvalidVehicleException(e); - } - } - - @Override - public void remove(long registrationId) throws InvalidRegistrationException, ServiceException { - throw new UnsupportedOperationException(); - } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/VehicleService.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/VehicleService.java deleted file mode 100644 index fe09ca1..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/VehicleService.java +++ /dev/null @@ -1,49 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.Status; -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; -import java.util.EnumSet; -import java.util.Set; - -public interface VehicleService { - - /** - * Add given vehicle to the store. - * - * @param vehicle that should be added to the store - * @return the id that was assigned - * @throws InvalidVehicleException if the vehicle is invalid - * @throws ServiceException if the vehicle could not be persisted - */ - long add(Vehicle vehicle) throws InvalidVehicleException, ServiceException; - - /** - * Update the given vehicle. - * - * @param vehicle that should be updated - * @return the updated vehicle - * @throws InvalidVehicleException if the vehicle is invalid - * @throws ServiceException if the updated vehicle could not be persisted - */ - Vehicle update(Vehicle vehicle) throws InvalidVehicleException, ServiceException; - - /** - * Get all stored vehicles with matching status. - * - * @param statuses set containing all statuses that should be matched - * @return list containing all stored vehicles - * @throws ServiceException if loading the stored vehicles failed - */ - Set list(EnumSet statuses) throws ServiceException; - - /** - * Remove vehicle with the given id from the store. - * - * @param id of the vehicle that should be removed - * @throws InvalidVehicleException if given vehicle id is invalid or does not exist - * @throws ServiceException if the vehicle could not be removed from the store - */ - void remove(long id) throws InvalidVehicleException, ServiceException; -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/VehicleServiceImpl.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/VehicleServiceImpl.java deleted file mode 100644 index 0bf4aa6..0000000 --- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/service/VehicleServiceImpl.java +++ /dev/null @@ -1,116 +0,0 @@ -package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.service; - -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dao.VehicleDAO; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.ConstructionType; -import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.dto.Vehicle.Status; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; -import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; -import java.util.EnumSet; -import java.util.Set; -import java.util.stream.Collectors; -import org.springframework.stereotype.Service; -import org.springframework.util.CollectionUtils; - -@Service -public class VehicleServiceImpl implements VehicleService { - - private VehicleDAO vehiclePersistence; - - public VehicleServiceImpl(VehicleDAO vehiclePersistence) { - this.vehiclePersistence = vehiclePersistence; - } - - public long add(Vehicle vehicle) throws InvalidVehicleException, ServiceException { - if (!CollectionUtils.isEmpty(vehicle.registrations())) { - throw new InvalidVehicleException( - "Fahrzeug kann nicht mit Anmeldungen erstellt werden"); - } - - validateVehicle(vehicle); - try { - vehiclePersistence.add(vehicle); - } catch (PersistenceException e) { - throw new ServiceException(e); - } - return 0; - } - - public Vehicle update(Vehicle vehicle) throws InvalidVehicleException, ServiceException { - validateVehicle(vehicle); - try { - vehiclePersistence.update(vehicle); - } catch (ElementNotFoundException e) { - throw new ServiceException("Element not found", e); - } catch (PersistenceException e) { - throw new ServiceException(e); - } - return vehicle; - } - - protected static void validateVehicle(Vehicle vehicle) throws InvalidVehicleException { - switch (vehicle.type()) { - case RTW: - if (vehicle.constructionType() == ConstructionType.NORMAL) { - throw new InvalidVehicleException("RTW darf kein Normales Dach haben"); - } else if (vehicle.constructionType() == ConstructionType.MITTELHOCHDACH) { - throw new InvalidVehicleException("RTW darf kein Mittelhochdach haben"); - } - break; - case KTW: - if (vehicle.constructionType() == ConstructionType.NORMAL) { - throw new InvalidVehicleException("KTW darf kein Normales Dach haben"); - } - break; - case KTW_B: - if (vehicle.constructionType() == ConstructionType.NORMAL) { - throw new InvalidVehicleException("KTW-B darf kein Normales Dach haben"); - } - break; - case NEF: - if (vehicle.constructionType() == ConstructionType.MITTELHOCHDACH) { - throw new InvalidVehicleException("NEF darf kein Mittelhochdach haben"); - } else if (vehicle.constructionType() == ConstructionType.HOCHDACH) { - throw new InvalidVehicleException("NEF darf kein Hochdach haben"); - } - break; - case NAH: - if (vehicle.constructionType() == ConstructionType.MITTELHOCHDACH) { - throw new InvalidVehicleException("NEF darf kein Mittelhochdach haben"); - } else if (vehicle.constructionType() == ConstructionType.HOCHDACH) { - throw new InvalidVehicleException("NEF darf kein Hochdach haben"); - } - break; - case BKTW: - break; - default: - throw new IllegalStateException("BUG: invalid vehicle type" + vehicle.type()); - } - } - - @Override - public Set list(EnumSet statuses) throws ServiceException { - if (statuses == null) { - throw new ServiceException("Statuses may not be null"); - } - - Set vehicles; - - try { - vehicles = vehiclePersistence.list(); - } catch (PersistenceException e) { - throw new ServiceException(e); - } - - return vehicles.stream() - .filter(vehicle -> statuses.contains(vehicle.status())) - .collect(Collectors.toSet()); - } - - @Override - public void remove(long id) throws InvalidVehicleException, ServiceException { - throw new UnsupportedOperationException(); - } -} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ArchiveOperationController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ArchiveOperationController.java new file mode 100644 index 0000000..6e0c89d --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ArchiveOperationController.java @@ -0,0 +1,213 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showServiceExceptionAlertAndWait; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.OperationService; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; +import java.io.IOException; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.util.Arrays; +import java.util.Collection; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; +import javafx.fxml.FXML; +import javafx.scene.control.Label; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.FlowPane; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; + +@Controller +public class ArchiveOperationController { + + private static final Logger LOG = LoggerFactory.getLogger(ArchiveOperationController.class); + + @FXML private ImageView imvVehicleDetail; + @FXML private Label lblStatus; + @FXML private AnchorPane apMainDetails; + @FXML private Label lblOperations; + @FXML private Label lblCompleted; + @FXML private Label lblCancelled; + @FXML private AnchorPane backApMain; + @FXML private AnchorPane backApDetails; + @FXML private AnchorPane archiveOperationAP; + @FXML private AnchorPane apDetails; + @FXML private Label lblCodeHeader; + @FXML private Label lblOpCode; + @FXML private Label lblVehicles; + @FXML private Label lblDate; + @FXML private Label lblAddress; + @FXML private FlowPane fpVehicles; + private final OperationService operationService; + @FXML private FlowPane archiveOperationFlowPane; + private final CreateOperationController createOperationController; + private Set list = new HashSet<>(); + private final SpringFXMLLoader fxmlLoader; + + public ArchiveOperationController( + OperationService operationService, + CreateOperationController createOperationController, + SpringFXMLLoader fxmlLoader) { + this.operationService = operationService; + this.createOperationController = createOperationController; + this.fxmlLoader = fxmlLoader; + } + + @FXML + private void initialize() { + update(); + } + + public void update() { + archiveOperationFlowPane.getChildren().clear(); + list.clear(); + try { + list.addAll(operationService.list(EnumSet.of(Status.CANCELLED, Status.COMPLETED))); + long cancelledAmount = 0; + long completedAmount = 0; + for (Operation operation : list) { + if (operation.status() == Status.CANCELLED) cancelledAmount++; + else completedAmount++; + } + lblCancelled.setText("storniert: " + cancelledAmount); + lblCompleted.setText("abgeschlossen: " + completedAmount); + lblOperations.setText("Einsätze: " + list.size()); + } catch (ServiceException e) { + LOG.error("ServiceException in update().", e); + showServiceExceptionAlertAndWait("Die Einsätze konnten nicht geladen werden!"); + ; + } + setFlowPane(); + } + + private void setFlowPane() { + try { + archiveOperationFlowPane.getChildren().clear(); + for (Operation operation : sortSet(list)) { + OperationInArchiveController opInAController = + OperationInArchiveController.create(); + opInAController.set(operation); + opInAController + .getRoot() + .setOnMouseClicked( + event -> { + detailOperation = operation; + backApMain.setVisible(false); + apMainDetails.setVisible(false); + backApDetails.setVisible(true); + setOperation(); + setDetailsVisible(true); + imvVehicleDetail.setImage(new Image("/images/Vehicle.png")); + }); + archiveOperationFlowPane.getChildren().add(opInAController.getRoot()); + } + } catch (IOException e) { + LOG.error("IOException in setFlowPane(). ", e); + showServiceExceptionAlertAndWait("Die Elemente konnten nicht geladen werden!"); + } + } + + private Operation detailOperation; + + private List sortSet(Set operationsSet) { + Operation[] array = operationsSet.toArray(new Operation[operationsSet.size()]); + for (int i = array.length - 1; i > 0; i--) { + for (int j = 0; j < i; j++) { + LocalDateTime first = + LocalDateTime.ofInstant( + Objects.requireNonNull(array[j].created()), ZoneOffset.UTC); + LocalDateTime second = + LocalDateTime.ofInstant( + Objects.requireNonNull(array[j + 1].created()), ZoneOffset.UTC); + if (first.isBefore(second)) { + Operation help = array[j]; + array[j] = array[j + 1]; + array[j + 1] = help; + } + } + } + return Arrays.asList(array); + } + + private void setOperation() { + lblCodeHeader.setText(detailOperation.opCode()); + if (detailOperation.created() != null) { + LocalDateTime dateTime = + LocalDateTime.ofInstant( + Objects.requireNonNull(detailOperation.created()), ZoneOffset.UTC); + lblDate.setText( + "am " + + dateTime.getDayOfMonth() + + "." + + dateTime.getMonth().getValue() + + "." + + dateTime.getYear()); + } else { + lblDate.setText("---"); + } + lblStatus.setText( + "Status: " + + (detailOperation.status() == Status.CANCELLED + ? "storniert" + : "abgeschlossen")); + lblOpCode.setText(detailOperation.opCode()); + Collection elements = + detailOperation.vehicles().stream().map(Vehicle::name).collect(Collectors.toList()); + String result = String.join(", ", elements); + + lblVehicles.setText(result); + lblAddress.setText(detailOperation.destination()); + + fpVehicles.getChildren().clear(); + try { + for (Vehicle vehicle : detailOperation.vehicles()) { + DetailArchiveOperationController controller = null; + + controller = DetailArchiveOperationController.create(fxmlLoader); + + controller.set(vehicle); + fpVehicles.getChildren().add(controller.getRoot()); + } + } catch (IOException e) { + LOG.error("IOException in setOperation(). ", e); + showServiceExceptionAlertAndWait("Die Element konnte nicht geladen werden!"); + } + } + + private void setDetailsVisible(boolean b) { + apDetails.setVisible(b); + } + + public void backClicked() { + LOG.debug("Hyperlink \"Zurück\" in archive detail view clicked."); + fpVehicles.getChildren().clear(); + setDetailsVisible(false); + backApDetails.setVisible(false); + apMainDetails.setVisible(true); + backApMain.setVisible(true); + } + + public void backToMain() { + LOG.debug("Hyperlink \"Zurück\" in archive main view clicked."); + this.setVisible(false); + createOperationController.setVisible(true); + } + + void setVisible(boolean b) { + archiveOperationAP.setVisible(b); + backApMain.setVisible(b); + apMainDetails.setVisible(b); + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateCarController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateCarController.java new file mode 100644 index 0000000..aa76535 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateCarController.java @@ -0,0 +1,231 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showServiceExceptionAlertAndWait; +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showSuccessAlertAndWait; +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showValidationErrorAlertAndWait; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.ConstructionType; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.Status; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.VehicleType; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.VehicleService; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import java.io.IOException; +import java.util.EnumSet; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javafx.collections.FXCollections; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.scene.control.Button; +import javafx.scene.control.CheckBox; +import javafx.scene.control.ChoiceBox; +import javafx.scene.input.MouseButton; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.FlowPane; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; + +@Controller +public class CreateCarController { + + @FXML private AnchorPane createCarAP; + @FXML private ChoiceBox cmbCtype; + @FXML private ChoiceBox cmbTyp; + + @FXML private Button btnCreate; + @FXML private CheckBox cbxNEF; + @FXML private FlowPane fpVehicleList; + private final CreateOperationController createOperationController; + + private static final Logger LOG = LoggerFactory.getLogger(CreateCarController.class); + private final VehicleService vehicleService; + private boolean update = false; + private long vid = -1; + + private Vehicle chooseVehicle; + + public CreateCarController( + CreateOperationController createOperationController, VehicleService vehicleService) { + this.createOperationController = createOperationController; + this.vehicleService = vehicleService; + } + + @FXML + private void initialize() { + fpVehicleList.setHgap(5); + fpVehicleList.setVgap(5); + + cmbCtype.setItems( + FXCollections.observableArrayList( + Stream.of( + ConstructionType.NORMAL, + ConstructionType.MITTELHOCHDACH, + ConstructionType.HOCHDACH) + .map(Enum::toString) + .collect(Collectors.toList()))); + cmbCtype.setValue(ConstructionType.NORMAL.toString()); + cmbTyp.setItems( + FXCollections.observableArrayList( + Stream.of( + VehicleType.BKTW, + VehicleType.KTW_B, + VehicleType.KTW, + VehicleType.RTW, + VehicleType.NEF, + VehicleType.NAH) + .map(Enum::toString) + .collect(Collectors.toList()))); + cmbTyp.setValue(VehicleType.BKTW.toString()); + + updateVehiclePane(); + } + + @FXML + private void createCar(ActionEvent actionEvent) { + + if (!update) { + LOG.debug("Button \"Erstellen\" clicked."); + Vehicle vehicle = + Vehicle.builder() + .constructionType(parseConstructionType()) + .type(parseType()) + .name("") + .status(Status.ABGEMELDET) + .hasNef(cbxNEF.isSelected()) + .build(); + try { + vehicleService.add(vehicle); + setToStart(); + } catch (InvalidVehicleException e) { + LOG.debug("Validation of Vehicle failed"); + showValidationErrorAlertAndWait(e.getMessage()); + setToStart(); + return; + } catch (ServiceException e) { + LOG.error("ServiceException in createCar(). ", e); + showServiceExceptionAlertAndWait( + "Ein Fehler beim Erstellen des Fahrzeuges ist aufgetreten."); + setToStart(); + return; + } + showSuccessAlertAndWait("Auto wurde erfolgreich angelegt."); + } else { + LOG.debug("Button \"Speichern\" clicked."); + try { + Vehicle vehicle = + Vehicle.builder() + .id(vid) + .constructionType(parseConstructionType()) + .type(parseType()) + .name("") + .status(Status.ABGEMELDET) + .hasNef(cbxNEF.isSelected()) + .build(); + vehicleService.update(vehicle); + setToStart(); + chooseVehicle = null; + } catch (InvalidVehicleException e) { + LOG.debug("Validation of Vehicle failed"); + showValidationErrorAlertAndWait(e.getMessage()); + setToStart(); + return; + } catch (ServiceException e) { + LOG.error("ServiceException in createCar(). ", e); + showServiceExceptionAlertAndWait(e.getMessage()); + setToStart(); + return; + } + showSuccessAlertAndWait("Auto wurde erfolgreich bearbeitet."); + } + + updateVehiclePane(); + } + + private ConstructionType parseConstructionType() { + if (cmbCtype.getSelectionModel().getSelectedItem() == null) { + return ConstructionType.NORMAL; + } + return ConstructionType.valueOf(cmbCtype.getSelectionModel().getSelectedItem()); + } + + private VehicleType parseType() { + if (cmbTyp.getSelectionModel().getSelectedItem() == null) { + return VehicleType.BKTW; + } + return VehicleType.valueOf(cmbTyp.getSelectionModel().getSelectedItem()); + } + + private void setToStart() { + btnCreate.setText("Erstellen"); + cbxNEF.setSelected(false); + cmbTyp.setValue(VehicleType.BKTW.name()); + cmbCtype.setValue(ConstructionType.NORMAL.name()); + update = false; + } + + private void updateVehicle(Vehicle vehicle) { + + cmbCtype.setValue(vehicle.constructionType().name()); + cmbTyp.setValue(vehicle.type().name()); + cbxNEF.setSelected(vehicle.hasNef()); + btnCreate.setText("Speichern"); + vid = vehicle.id(); + update = true; + chooseVehicle = vehicle; + } + + public void setVisible(boolean b) { + createCarAP.setVisible(b); + } + + @FXML + private void backToMain() { + LOG.debug("Hyperlink \"zurück\" clicked."); + this.setVisible(false); + createOperationController.setVisible(true); + } + + private void updateVehiclePane() { + try { + fpVehicleList.getChildren().clear(); + + Set vehicles; + + vehicles = vehicleService.list(EnumSet.of(Status.ABGEMELDET)); + + for (Vehicle vehicle : vehicles) { + VehiclePaneController controller = VehiclePaneController.createVehiclePane(); + + controller.setData(vehicle, false, false); + controller + .getRootElement() + .setOnMouseClicked( + event -> { + if (event.getButton().equals(MouseButton.PRIMARY)) { + if (chooseVehicle == null || vehicle == chooseVehicle) { + if (update == false) { + chooseVehicle = vehicle; + updateVehicle(vehicle); + controller.setSelected(true); + } else { + setToStart(); + controller.setSelected(false); + + chooseVehicle = null; + } + } + } + }); + + fpVehicleList.getChildren().add(controller.getRootElement()); + } + } catch (ServiceException | IOException e) { + LOG.error("Exception in updateVehiclePane(). ", e); + showServiceExceptionAlertAndWait(e.getMessage()); + } + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateNewEmployeeController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateNewEmployeeController.java new file mode 100644 index 0000000..433bfa6 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateNewEmployeeController.java @@ -0,0 +1,174 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showServiceExceptionAlertAndWait; +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showSuccessAlertAndWait; +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showValidationErrorAlertAndWait; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee.EducationLevel; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.EmployeeService; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidEmployeeException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader.FXMLWrapper; +import java.io.IOException; +import java.time.LocalDate; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javafx.collections.FXCollections; +import javafx.fxml.FXML; +import javafx.scene.Node; +import javafx.scene.control.Button; +import javafx.scene.control.CheckBox; +import javafx.scene.control.ChoiceBox; +import javafx.scene.control.Label; +import javafx.scene.control.TextField; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Controller; + +@Controller +@Scope("prototype") +public class CreateNewEmployeeController { + + private static final Logger LOG = LoggerFactory.getLogger(CreateNewEmployeeController.class); + private final EmployeeService employeeService; + + @FXML private Label lblHeader; + @FXML private CheckBox inputIsDriver; + @FXML private CheckBox inputIsPilot; + @FXML private TextField inputName; + @FXML private ChoiceBox inputQualification; + @FXML private Button btnCreate; + + private Node rootElement; + private Employee employee; + private boolean isEdit; + + private Runnable consumerCancelClicked; + private Runnable consumerCreateClicked; + + public CreateNewEmployeeController(EmployeeService employeeService) { + this.employeeService = employeeService; + } + + @FXML + private void initialize() { + inputQualification.setItems( + FXCollections.observableArrayList( + Stream.of( + EducationLevel.RS, + EducationLevel.NFS, + EducationLevel.NKV, + EducationLevel.NKA, + EducationLevel.NKI, + EducationLevel.NA) + .map(Enum::toString) + .collect(Collectors.toList()))); + + inputQualification.setValue(EducationLevel.RS.toString()); + employee = + Employee.builder() + .name("") + .educationLevel(EducationLevel.RS) + .isDriver(false) + .isPilot(false) + .birthday(LocalDate.MIN) + .build(); + } + + @FXML + private void onCancelClicked() { + LOG.debug("Hyperlink \"abbrechen\" clicked."); + if (consumerCancelClicked != null) { + consumerCancelClicked.run(); + } + } + + @FXML + private void onCreateClicked() { + LOG.debug("Button {} clicked.", btnCreate.getText()); + + employee = + employee.toBuilder() + .name(inputName.getText()) + .educationLevel(parseEducationLevel()) + .birthday(LocalDate.MIN) // TODO: change UI to include birthday field + .isDriver(inputIsDriver.isSelected()) + .isPilot(inputIsPilot.isSelected()) + .build(); + + try { + if (isEdit) { + employeeService.update(employee); + } else { + employeeService.add(employee); + } + } catch (InvalidEmployeeException e) { + LOG.debug("Validation for Employee failed"); + showValidationErrorAlertAndWait(e.getMessage()); + return; + } catch (ServiceException e) { + LOG.error("ServiceException in onCreateClicked(). ", e); + showServiceExceptionAlertAndWait( + "Der Eintrag konnte nicht gespeichert werden. Bitte versuchen Sie es erneut."); + return; + } + + showSuccessAlertAndWait( + "Der/die MitarbeiterIn wurde erfolgreich angelegt und gespeichert!"); + + if (consumerCreateClicked != null) { + consumerCreateClicked.run(); + } + } + + private EducationLevel parseEducationLevel() { + if (inputQualification.getSelectionModel().getSelectedItem() == null) { + return EducationLevel.RS; + } + return EducationLevel.valueOf(inputQualification.getSelectionModel().getSelectedItem()); + } + + private void setData(Employee employee) { + isEdit = true; + this.employee = employee; + inputName.setText(employee.name()); + inputQualification.setValue(employee.educationLevel().name()); + inputIsDriver.setSelected(employee.isDriver()); + inputIsPilot.setSelected(employee.isPilot()); + lblHeader.setText("Person bearbeiten"); + btnCreate.setText("Speichern"); + } + + public static CreateNewEmployeeController createCreateNewEmployeeController( + SpringFXMLLoader fxmlLoader, Employee employee) throws IOException { + CreateNewEmployeeController controller = createCreateNewEmployeeController(fxmlLoader); + controller.setData(employee); + return controller; + } + + public static CreateNewEmployeeController createCreateNewEmployeeController( + SpringFXMLLoader fxmlLoader) throws IOException { + FXMLWrapper wrapper = + fxmlLoader.loadAndWrap( + "/fxml/createNewEmployee.fxml", CreateNewEmployeeController.class); + Node root = (Node) wrapper.getLoadedObject(); + CreateNewEmployeeController controller = wrapper.getController(); + controller.rootElement = root; + return controller; + } + + public Node getRootElement() { + return rootElement; + } + + public void setConsumerCancelClicked(Runnable consumerCancelClicked) { + this.consumerCancelClicked = consumerCancelClicked; + } + + public void setConsumerCreateClicked(Runnable consumerCreateClicked) { + this.consumerCreateClicked = consumerCreateClicked; + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java new file mode 100644 index 0000000..b237265 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CreateOperationController.java @@ -0,0 +1,371 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showServiceExceptionAlertAndWait; +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showSuccessAlertAndWait; +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showValidationErrorAlertAndWait; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.OperationService; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.VehicleService; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidOperationException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import java.io.IOException; +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import javafx.collections.FXCollections; +import javafx.fxml.FXML; +import javafx.scene.control.Button; +import javafx.scene.control.ContextMenu; +import javafx.scene.control.Label; +import javafx.scene.control.ListCell; +import javafx.scene.control.ListView; +import javafx.scene.control.MenuItem; +import javafx.scene.control.TextField; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyEvent; +import javafx.scene.input.MouseButton; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.FlowPane; +import javafx.scene.layout.GridPane; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; + +@Controller +public class CreateOperationController { + + private static final Logger LOG = LoggerFactory.getLogger(CreateOperationController.class); + + public AnchorPane apCreateOperation; + @FXML private GridPane grdWindowContainer; + @FXML private TextField txtCode; + @FXML private TextField txtAddress; + @FXML private TextField txtNote; + @FXML private Button btnCreateOperation; + @FXML private ListView lvVehicles; + @FXML private ListView lvActiveOperations; + @FXML private Label lblChosenVehicles; + @FXML private AnchorPane apInvisible; + @FXML private OperationDetailsController operationDetailsController; + @FXML private ManageEmployeesController manageEmployeesController; + @FXML private CreateCarController createCarController; + @FXML private RegistrationWindowController registrationWindowController; + @FXML private ArchiveOperationController archiveOperationController; + @FXML private FlowPane fpVehicles; + + private LinkedList chosenVehicles = new LinkedList<>(); + + private final OperationService operationService; + private final VehicleService vehicleService; + + public CreateOperationController( + OperationService operationService, VehicleService vehicleService) { + this.operationService = operationService; + this.vehicleService = vehicleService; + } + + @FXML + private void initialize() { + + lblChosenVehicles.setText("keine ausgewählt"); + lvActiveOperations.setCellFactory(param -> generateOpCodeListItem()); + + lvActiveOperations.setOnMouseClicked( + event -> { + if (event.getClickCount() == 2) { + if (lvActiveOperations.getSelectionModel().getSelectedItem() == null) { + return; + } + openDetailsWindow(lvActiveOperations.getSelectionModel().getSelectedItem()); + } + }); + + setVisible(true); + createCarController.setVisible(false); + registrationWindowController.setVisible(false); + } + + public void updateList() { + try { + fpVehicles.getChildren().clear(); + + // TODO: this should probably be handled differently + Set vehicles; + if (txtCode.getText().isEmpty()) { + vehicles = + vehicleService.list( + EnumSet.complementOf(EnumSet.of(Vehicle.Status.ABGEMELDET))); + } else { + vehicles = operationService.rankVehicles(txtCode.getText()); + } + + for (Vehicle vehicle : vehicles) { + VehiclePaneController controller = VehiclePaneController.createVehiclePane(); + + controller.setData(vehicle, true, false); + controller + .getRootElement() + .setOnMouseClicked( + event -> { + if (event.getButton().equals(MouseButton.SECONDARY)) { + createContextMenu(vehicle, vehicleService) + .show( + controller.getRootElement(), + event.getScreenX(), + event.getScreenY()); + } else { + if (chosenVehicles.contains(vehicle)) { + chosenVehicles.remove(vehicle); + controller.setSelected(false); + } else { + chosenVehicles.add(vehicle); + controller.setSelected(true); + } + + StringBuilder result = new StringBuilder(); + for (int i = 0; i < chosenVehicles.size(); i++) { + if (i == chosenVehicles.size() - 1) { + result.append(chosenVehicles.get(i).name()); + } else { + result.append(chosenVehicles.get(i).name()) + .append(", "); + } + } + if (result.toString().equals("")) { + lblChosenVehicles.setText("keine ausgewählt"); + } else { + lblChosenVehicles.setText(result.toString()); + } + } + }); + + if (chosenVehicles.stream().anyMatch(v -> v.id() == vehicle.id())) + controller.setSelected(true); + + fpVehicles.getChildren().add(controller.getRootElement()); + } + } catch (ServiceException | IOException e) { + LOG.error("Exception in updateList(). ", e); + showServiceExceptionAlertAndWait( + "Beim Erstellen des Ranking ist ein Fehler aufgetreten."); + } catch (InvalidOperationException e) { + LOG.debug("Validation error in updateList(). ", e); + showValidationErrorAlertAndWait(e.getMessage()); + } + try { + lvActiveOperations.setItems( + FXCollections.observableArrayList( + operationService.list(EnumSet.of(Status.ACTIVE)))); + } catch (ServiceException e) { + LOG.error("ServiceException in updateList(). ", e); + showServiceExceptionAlertAndWait( + "Beim Holen der aktiven Einsätze ist ein Fehler aufgetreten"); + } + } + + private ContextMenu createContextMenu(Vehicle data, VehicleService vehicleService) { + ContextMenu menu = new ContextMenu(); + + for (Vehicle.Status status : Vehicle.Status.values()) { + if (status == Vehicle.Status.ABGEMELDET) { + continue; + } + + MenuItem mi = new MenuItem(status.name()); + + if (status == Vehicle.Status.FREI_FUNK || status == Vehicle.Status.FREI_WACHE) { + mi.getStyleClass().add("mi-free"); + } else { + mi.getStyleClass().add("mi-other"); + } + + mi.setOnAction( + event -> { + try { + vehicleService.update(data.toBuilder().status(status).build()); + this.updateList(); + } catch (InvalidVehicleException e) { + LOG.debug( + "Validation error in createContextMenu(). (mi.setOnAction) ", + e); + showValidationErrorAlertAndWait(e.getMessage()); + } catch (ServiceException e) { + LOG.error("Exception in createContextMenu(). (mi.setOnAction) ", e); + showServiceExceptionAlertAndWait( + "Beim Aktualisieren der Fahrzeuge ist ein Fehler aufgetreten."); + } + }); + + menu.getItems().add(mi); + } + + MenuItem abmelden = new MenuItem("abmelden"); + + abmelden.setOnAction( + event -> { + try { + List registrations = data.registrations(); + assert registrations + != null; // Otherwise the element shouldn't be in the list. + + List newRegistrations = new ArrayList<>(); + Instant now = Instant.now(); + + for (Registration registration : registrations) { + if (registration.start().isBefore(now) + && registration.end().isAfter(now)) { + newRegistrations.add( + registration + .toBuilder() + .end(Instant.now().minus(1, ChronoUnit.SECONDS)) + .build()); + } else newRegistrations.add(registration); + } + + vehicleService.update( + data.toBuilder() + .registrations(newRegistrations) + .status(Vehicle.Status.ABGEMELDET) + .build()); + + this.updateList(); + } catch (InvalidVehicleException e) { + LOG.debug( + "Validation error in createContextMenu(). (abmelden.setOnAction) ", + e); + showValidationErrorAlertAndWait(e.getMessage()); + } catch (ServiceException e) { + LOG.error("Exception in createContextMenu(). (abmelden.setOnAction) ", e); + showServiceExceptionAlertAndWait( + "Beim Aktualisieren der Fahrzeuge ist ein Fehler aufgetreten."); + } + }); + + menu.getItems().add(abmelden); + return menu; + } + + @FXML + protected void createOperationClicked() { + LOG.debug("Button \"Erstellen\" clicked."); + Vehicle[] vehicles = new Vehicle[chosenVehicles.size()]; + for (int i = 0; i < chosenVehicles.size(); i++) { + vehicles[i] = chosenVehicles.get(i); + } + Operation operation = + Operation.builder() + .additionalInfo(txtNote.getText()) + .destination(txtAddress.getText()) + .opCode(txtCode.getText()) + .status(Status.ACTIVE) + .vehicles(Set.of(vehicles)) + .build(); + try { + operationService.add(operation); + } catch (ServiceException e) { + LOG.error("Exception in createOperationClicked(). ", e); + showServiceExceptionAlertAndWait( + "Beim Erstellen des Einsatzes ist ein Fehler aufgetreten."); + return; + } catch (InvalidOperationException e) { + LOG.debug("Validation error in createOperationClicked(). ", e); + showValidationErrorAlertAndWait(e.getMessage()); + return; + } + showSuccessAlertAndWait("Der Einsatz wurde erfolgreich gespeichert."); + updateList(); + lblChosenVehicles.setText("keine ausgewählt"); + txtAddress.setText(""); + txtCode.setText(""); + txtNote.setText(""); + chosenVehicles = new LinkedList<>(); + } + + @FXML + private void onRegistrationLinkClicked() { + LOG.debug("Hyperlink \"Anmeldungen\" clicked."); + openRegistrationWindow(); + } + + @FXML + private void onEmployeeLinkClicked() { + LOG.debug("Hyperlink \"Personen\" clicked."); + openCreateNewEmployeeWindow(); + } + + @FXML + private void onVehicleLinkClicked() { + LOG.debug("Hyperlink \"Fahrzeuge\" clicked."); + openCreateCarWindow(); + } + + @FXML + private void onArchivLinkClicked() { + LOG.debug("Hyperlink \"Archiv\" clicked."); + archiveOperationController.update(); + openArchivWindow(); + } + + private void openArchivWindow() { + archiveOperationController.setVisible(true); + this.setVisible(false); + } + + void setVisible(boolean b) { + apInvisible.setVisible(!b); + grdWindowContainer.setVisible(!b); + + updateList(); + } + + private void openDetailsWindow(Operation operation) { + operationDetailsController.initOperation(operation); + this.setVisible(false); + } + + private void openCreateNewEmployeeWindow() { + this.setVisible(false); + manageEmployeesController.setVisible(true); + } + + private void openCreateCarWindow() { + this.setVisible(false); + createCarController.setVisible(true); + } + + private void openRegistrationWindow() { + this.setVisible(false); + registrationWindowController.setVisible(true); + } + + @FXML + private void onOperationCodeChanged(KeyEvent keyEvent) { + if (keyEvent.getCode() == KeyCode.ENTER) { + updateList(); + } + } + + static ListCell generateOpCodeListItem() { + return new ListCell<>() { + @Override + protected void updateItem(Operation item, boolean empty) { + super.updateItem(item, empty); + + if (empty || item == null || item.opCode() == null) { + setText(null); + } else { + setText(item.opCode()); + } + } + }; + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CustomListItemController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CustomListItemController.java new file mode 100644 index 0000000..ced0c10 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/CustomListItemController.java @@ -0,0 +1,24 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import javafx.scene.Node; + +public abstract class CustomListItemController { + + protected Node rootElement; + + public Node getRootElement() { + return rootElement; + } + + public void setSelected(boolean selected) { + rootElement.getStyleClass().clear(); + + if (selected) { + rootElement.getStyleClass().add("bg-yellow"); + rootElement.getStyleClass().add("shadowed"); + } else { + rootElement.getStyleClass().add("bg-white"); + rootElement.getStyleClass().add("shadowed"); + } + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/DetailArchiveOperationController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/DetailArchiveOperationController.java new file mode 100644 index 0000000..32630a5 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/DetailArchiveOperationController.java @@ -0,0 +1,77 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showServiceExceptionAlertAndWait; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader.FXMLWrapper; +import java.io.IOException; +import java.util.Objects; +import javafx.fxml.FXML; +import javafx.scene.Node; +import javafx.scene.layout.VBox; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; + +@Controller +public class DetailArchiveOperationController { + private static final Logger LOG = + LoggerFactory.getLogger(DetailArchiveOperationController.class); + + @FXML private VBox vBoxVehicle; + @FXML private VBox vBoxPeople; + private final SpringFXMLLoader fxmlLoader; + + public DetailArchiveOperationController(SpringFXMLLoader fxmlLoader) { + this.fxmlLoader = fxmlLoader; + } + + static DetailArchiveOperationController create(SpringFXMLLoader fxmlLoader) throws IOException { + FXMLWrapper wrapper = + fxmlLoader.loadAndWrap( + "/fxml/DetailArchiveOperation.fxml", + DetailArchiveOperationController.class); + + Node root = (Node) wrapper.getLoadedObject(); + DetailArchiveOperationController result = wrapper.getController(); + result.rootElement = root; + + return result; + } + + public Node getRoot() { + return rootElement; + } + + private Node rootElement; + + public void set(Vehicle vehicle) { + VehiclePaneController controller; + try { + controller = VehiclePaneController.createVehiclePane(); + controller.setData(vehicle, false, false); + vBoxVehicle.getChildren().add(controller.getRootElement()); + } catch (IOException e) { + LOG.error("IOException in set(Vehicle). (vBoxVehicle) ", e); + showServiceExceptionAlertAndWait( + "Ein interner Fehler ist aufgetreten. Bitte wenden Sie sich an den/die SystemadministratorIn."); + } + try { + for (int i = 0; i < Objects.requireNonNull(vehicle.registrations()).size(); i++) { + Employee employee = + Objects.requireNonNull(vehicle.registrations()).get(i).employee(); + + EmployeeListItemController employeeListItemController = + EmployeeListItemController.createEmployeeListItemController( + fxmlLoader, employee); + vBoxPeople.getChildren().add(employeeListItemController.getRootElement()); + } + } catch (IOException e) { + LOG.error("IOException in set(Vehicle). (vBoxPeople) ", e); + showServiceExceptionAlertAndWait( + "Ein interner Fehler ist aufgetreten. Bitte wenden Sie sich an den/die SystemadministratorIn."); + } + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/EmployeeListController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/EmployeeListController.java new file mode 100644 index 0000000..12f6bff --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/EmployeeListController.java @@ -0,0 +1,133 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader.FXMLWrapper; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.function.Consumer; +import javafx.fxml.FXML; +import javafx.geometry.Insets; +import javafx.scene.Node; +import javafx.scene.layout.FlowPane; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Controller; + +@Controller +@Scope("prototype") +public class EmployeeListController { + + private static final Logger LOG = LoggerFactory.getLogger(EmployeeListController.class); + + @FXML private FlowPane flowPaneEmployeeList; + + private Consumer onEmployeeClicked; + + private final SpringFXMLLoader fxmlLoader; + private Node rootElement; + private List employeeListItemControllers; + private Insets listItemMargins = new Insets(10, 5, 0, 5); + + public EmployeeListController(SpringFXMLLoader fxmlLoader) { + this.fxmlLoader = fxmlLoader; + this.employeeListItemControllers = new ArrayList<>(); + } + + public void setListItemMargins(Insets value) { + this.listItemMargins = value; + } + + public void setData(Set employeeList) { + setData(employeeList, null, null); + } + + public void setData(Set employeeList, Consumer onEmployeeClicked) { + setData(employeeList, onEmployeeClicked, null); + } + + public void setData( + Set employeeList, + Consumer onEmployeeClicked, + Consumer onEmployeeListItemClicked) { + + flowPaneEmployeeList.getChildren().clear(); + employeeListItemControllers.clear(); + employeeList.forEach( + employee -> + addEmployeeToFlowPane( + employee, onEmployeeClicked, onEmployeeListItemClicked)); + } + + private void addEmployeeToFlowPane( + Employee employee, + Consumer onEmployeeClicked, + Consumer onEmployeeListItemClicked) { + + try { + EmployeeListItemController controller = + EmployeeListItemController.createEmployeeListItemController( + fxmlLoader, employee); + Node rootElement = controller.getRootElement(); + flowPaneEmployeeList.getChildren().add(rootElement); + employeeListItemControllers.add(controller); + FlowPane.setMargin(rootElement, listItemMargins); + if (onEmployeeClicked != null) { + controller.setConsumerEmployeeClicked(onEmployeeClicked); + } + if (onEmployeeListItemClicked != null) { + controller.setConsumerEmployeeListItemClicked( + employeeListItemController -> { + onEmployeeListItemClicked.accept(employeeListItemController); + if (this.onEmployeeClicked != null) { + this.onEmployeeClicked.accept( + employeeListItemController.getEmployee()); + } + }); + } + } catch (IOException e) { + LOG.error("IOException in addEmployeeToFlowPane. ", e); + } + } + + private void setEmployeeSelected(Employee employee, boolean selected) { + employeeListItemControllers + .stream() + .filter(controller -> controller.getEmployee().equals(employee)) + .forEach(controller -> controller.setSelected(selected)); + } + + public void selectEmployee(Employee employee) { + setEmployeeSelected(employee, true); + } + + public void deselectEmployee(Employee employee) { + setEmployeeSelected(employee, false); + } + + public void deselectAllEmployees() { + employeeListItemControllers.forEach( + employeeListItemController -> employeeListItemController.setSelected(false)); + } + + public static EmployeeListController createEmployeeListController(SpringFXMLLoader loader) + throws IOException { + FXMLWrapper wrapper = + loader.loadAndWrap("/fxml/employeeList.fxml", EmployeeListController.class); + Node root = (Node) wrapper.getLoadedObject(); + EmployeeListController controller = wrapper.getController(); + controller.rootElement = root; + return controller; + } + + public Node getRootElement() { + return rootElement; + } + + public void setOnEmployeeClicked(Consumer onEmployeeClicked) { + this.onEmployeeClicked = onEmployeeClicked; + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/EmployeeListItemController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/EmployeeListItemController.java new file mode 100644 index 0000000..543fe0d --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/EmployeeListItemController.java @@ -0,0 +1,87 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader.FXMLWrapper; +import java.io.IOException; +import java.util.function.Consumer; +import javafx.fxml.FXML; +import javafx.scene.Node; +import javafx.scene.control.Label; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Controller; + +@Controller +@Scope("prototype") +public class EmployeeListItemController extends CustomListItemController { + + @FXML private Label lblName; + @FXML private Label lblQualification; + @FXML private Label lblPilot; + @FXML private Label lblDriver; + @FXML private ImageView imgPilot; + @FXML private ImageView imgDriver; + @FXML private ImageView imgQualification; + + private Employee employee; + + private Consumer consumerEmployeeClicked; + private Consumer consumerEmployeeListItemClicked; + + @FXML + private void onEmployeeClicked() { + if (consumerEmployeeClicked != null) { + consumerEmployeeClicked.accept(employee); + } + if (consumerEmployeeListItemClicked != null) { + consumerEmployeeListItemClicked.accept(this); + } + } + + private void setData(Employee employee) { + this.employee = employee; + lblName.setText(employee.name()); + lblQualification.setText(employee.educationLevel().name()); + lblPilot.setText(String.format("%s Pilot", employee.isPilot() ? "ist" : "nicht")); + lblDriver.setText(String.format("%s Fahrer", employee.isDriver() ? "ist" : "nicht")); + imgQualification.setImage(new Image("/images/Qualification.png")); + String imgSrcPilot = + String.format("/images/%s", employee.isPilot() ? "Pilot.png" : "NotPilot.png"); + imgPilot.setImage(new Image(imgSrcPilot)); + String imgSrcDriver = + String.format("/images/%s", employee.isDriver() ? "Driver.png" : "NotDriver.png"); + imgDriver.setImage(new Image(imgSrcDriver)); + } + + public static EmployeeListItemController createEmployeeListItemController( + SpringFXMLLoader fxmlLoader, Employee employee) throws IOException { + EmployeeListItemController controller = createEmployeeListItemController(fxmlLoader); + controller.setData(employee); + return controller; + } + + public static EmployeeListItemController createEmployeeListItemController( + SpringFXMLLoader loader) throws IOException { + FXMLWrapper wrapper = + loader.loadAndWrap("/fxml/employeeListItem.fxml", EmployeeListItemController.class); + Node root = (Node) wrapper.getLoadedObject(); + EmployeeListItemController controller = wrapper.getController(); + controller.rootElement = root; + return controller; + } + + public Employee getEmployee() { + return employee; + } + + public void setConsumerEmployeeClicked(Consumer consumerEmployeeClicked) { + this.consumerEmployeeClicked = consumerEmployeeClicked; + } + + public void setConsumerEmployeeListItemClicked( + Consumer consumerEmployeeListItemClicked) { + this.consumerEmployeeListItemClicked = consumerEmployeeListItemClicked; + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/FilterEmployeesController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/FilterEmployeesController.java new file mode 100644 index 0000000..a31c3e3 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/FilterEmployeesController.java @@ -0,0 +1,65 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader.FXMLWrapper; +import java.io.IOException; +import java.util.function.Consumer; +import javafx.fxml.FXML; +import javafx.scene.Node; +import javafx.scene.control.TextField; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Controller; + +@Controller +@Scope("prototype") +public class FilterEmployeesController { + private static final Logger LOG = LoggerFactory.getLogger(FilterEmployeesController.class); + + @FXML private TextField inputFilterString; + + private Consumer consumerFilterTextChanged; + private Runnable consumerAddEmployeeClicked; + + private Node rootElement; + + @FXML + private void onAddEmployeeClicked() { + LOG.debug("Button \"Person hinzufügen\" clicked."); + if (consumerAddEmployeeClicked != null) { + consumerAddEmployeeClicked.run(); + } + } + + @FXML + private void onFilterTextChanged() { + LOG.debug("Filter text changed."); + if (consumerFilterTextChanged != null) { + consumerFilterTextChanged.accept(inputFilterString.getText()); + } + } + + public void setOnFilterTextChangedListener(Consumer callback) { + this.consumerFilterTextChanged = callback; + } + + public void setOnAddEmployeeClickedListener(Runnable callback) { + this.consumerAddEmployeeClicked = callback; + } + + public static FilterEmployeesController createFilterEmployeesController( + SpringFXMLLoader fxmlLoader) throws IOException { + FXMLWrapper wrapper = + fxmlLoader.loadAndWrap( + "/fxml/filterEmployeesControl.fxml", FilterEmployeesController.class); + Node root = (Node) wrapper.getLoadedObject(); + FilterEmployeesController controller = wrapper.getController(); + controller.rootElement = root; + return controller; + } + + public Node getRootElement() { + return rootElement; + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/Helper.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/Helper.java new file mode 100644 index 0000000..f120eb6 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/Helper.java @@ -0,0 +1,34 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import javafx.scene.control.Alert; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.ButtonType; + +public class Helper { + + static final String ALERT_TITLE_VALIDATION_ERROR = "Validierungsfehler"; + static final String ALERT_TITLE_SERVICE_EXCEPTION = "Fehler"; + static final String ALERT_TITLE_SUCCESS = "Erfolg"; + + private Helper() {} // SonarLint insisted to create a private constructor to hide the public one + + static void showValidationErrorAlertAndWait(String message) { + showAlertWithOkButtonAndWait(AlertType.ERROR, ALERT_TITLE_VALIDATION_ERROR, message); + } + + static void showServiceExceptionAlertAndWait(String message) { + showAlertWithOkButtonAndWait(AlertType.ERROR, ALERT_TITLE_SERVICE_EXCEPTION, message); + } + + static void showSuccessAlertAndWait(String message) { + showAlertWithOkButtonAndWait(AlertType.INFORMATION, ALERT_TITLE_SUCCESS, message); + } + + static void showAlertWithOkButtonAndWait( + AlertType alertType, String headerText, String contentText) { + Alert alert = new Alert(alertType, contentText, ButtonType.OK); + alert.setTitle(headerText); + alert.setHeaderText(headerText); + alert.showAndWait(); + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ManageEmployeesController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ManageEmployeesController.java new file mode 100644 index 0000000..6138094 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/ManageEmployeesController.java @@ -0,0 +1,120 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.EmployeeService; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; +import java.io.IOException; +import java.util.HashSet; +import java.util.stream.Collectors; +import javafx.fxml.FXML; +import javafx.scene.layout.AnchorPane; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; + +@Controller +public class ManageEmployeesController { + + private static final Logger LOG = LoggerFactory.getLogger(ManageEmployeesController.class); + @FXML private AnchorPane listEmployeesAP; + @FXML private AnchorPane containerHeader; + @FXML private EmployeeListController employeeListController; + + private final EmployeeService employeeService; + private final SpringFXMLLoader fxmlLoader; + + private final CreateOperationController createOperationController; + + public ManageEmployeesController( + EmployeeService employeeService, + SpringFXMLLoader fxmlLoader, + CreateOperationController createOperationController) { + this.employeeService = employeeService; + this.fxmlLoader = fxmlLoader; + this.createOperationController = createOperationController; + } + + @FXML + private void initialize() { + openFilter(); + } + + private void openFilter() { + try { + FilterEmployeesController filterEmployeesController = + FilterEmployeesController.createFilterEmployeesController(fxmlLoader); + containerHeader.getChildren().clear(); + containerHeader.getChildren().add(filterEmployeesController.getRootElement()); + filterEmployeesController.setOnFilterTextChangedListener(this::updateEmployeeList); + filterEmployeesController.setOnAddEmployeeClickedListener(this::openAddEmployee); + updateEmployeeList(); + + } catch (IOException e) { + LOG.error("IOException in openFilter().", e); + } + } + + private void openAddEmployee() { + employeeListController.deselectAllEmployees(); + openEmployee(null); + } + + private void openEditEmployee(Employee employee) { + employeeListController.deselectAllEmployees(); + employeeListController.selectEmployee(employee); + openEmployee(employee); + } + + private void openEmployee(Employee employee) { + try { + CreateNewEmployeeController createNewEmployeeController = + employee == null + ? CreateNewEmployeeController.createCreateNewEmployeeController( + fxmlLoader) + : CreateNewEmployeeController.createCreateNewEmployeeController( + fxmlLoader, employee); + containerHeader.getChildren().clear(); + containerHeader.getChildren().add(createNewEmployeeController.getRootElement()); + createNewEmployeeController.setConsumerCancelClicked(this::openFilter); + createNewEmployeeController.setConsumerCreateClicked(this::openFilter); + } catch (IOException e) { + LOG.error("IOException in openEmployee(). ", e); + } + } + + private void updateEmployeeList() { + updateEmployeeList(""); + } + + private void updateEmployeeList(String searchString) { + + try { + employeeListController.setData( + employeeService + .list() + .stream() + .filter( + employee -> + searchString.trim().isEmpty() + || employee.name() + .toLowerCase() + .contains(searchString.toLowerCase())) + .collect(Collectors.toCollection(HashSet::new)), + this::openEditEmployee); + + } catch (ServiceException e) { + LOG.error("ServiceException in updateEmployeeList(). ", e); + } + } + + public void setVisible(boolean b) { + listEmployeesAP.setVisible(b); + } + + public void backToMain() { + LOG.debug("Hyperlink \"Zurück\" clicked."); + this.setVisible(false); + createOperationController.setVisible(true); + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationDetailsController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationDetailsController.java new file mode 100644 index 0000000..0476fc6 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationDetailsController.java @@ -0,0 +1,169 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showAlertWithOkButtonAndWait; +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showServiceExceptionAlertAndWait; +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showSuccessAlertAndWait; +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showValidationErrorAlertAndWait; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.OperationService; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.VehicleService; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidOperationException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import java.io.IOException; +import java.util.Collection; +import java.util.EnumSet; +import java.util.Set; +import java.util.stream.Collectors; +import javafx.collections.FXCollections; +import javafx.fxml.FXML; +import javafx.scene.control.Alert.AlertType; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.ListView; +import javafx.scene.layout.AnchorPane; +import javafx.scene.layout.FlowPane; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; + +@Controller +public class OperationDetailsController { + private static final Logger LOG = LoggerFactory.getLogger(OperationDetailsController.class); + + public Operation operation; + private final OperationService operationService; + private final VehicleService vehicleService; + private final CreateOperationController createOperationController; + @FXML private FlowPane fpVehicles; + @FXML private ListView lvActiveOperations; + @FXML private Label lblChosenVehicles; + @FXML private Button btnCloseOperation; + @FXML private Button btnCancelOperation; + @FXML private Label lblCode, lblAdditionalInfo, lblAddress; + @FXML private AnchorPane operationDetailsAP; + + public OperationDetailsController( + OperationService operationService, + VehicleService vehicleService, + CreateOperationController createOperationController) { + this.operationService = operationService; + this.vehicleService = vehicleService; + this.createOperationController = createOperationController; + } + + @FXML + private void initialize() { + lvActiveOperations.setCellFactory( + param -> CreateOperationController.generateOpCodeListItem()); + lvActiveOperations.setOnMouseClicked( + event -> { + if (event.getClickCount() == 2) { + if (lvActiveOperations.getSelectionModel().getSelectedItem() == null) { + return; + } + initOperation(lvActiveOperations.getSelectionModel().getSelectedItem()); + } + }); + } + + private void updateFlowPane() { + try { + fpVehicles.getChildren().clear(); + for (Vehicle vehicle : operation.vehicles()) { + VehiclePaneController controller = VehiclePaneController.createVehiclePane(); + controller.setData(vehicle, true, true); + controller.getBtnRequest().setOnAction(e -> requestVehicleClicked(controller)); + fpVehicles.getChildren().add(controller.getRootElement()); + } + } catch (IOException e) { + LOG.error("Error while updating list.", e); + showServiceExceptionAlertAndWait("Error while updating list."); + } + } + + void initOperation(Operation operation) { + fillActiveList(); + this.operation = operation; + lblCode.setText(operation.opCode()); + Collection vehicleNames = + operation.vehicles().stream().map(Vehicle::name).collect(Collectors.toList()); + String result = String.join(", ", vehicleNames); + lblChosenVehicles.setText(result.toString()); + lblAdditionalInfo.setText(operation.additionalInfo()); + lblAddress.setText(operation.destination()); + updateFlowPane(); + operationDetailsAP.setVisible(true); + } + + private void fillActiveList() { + try { + lvActiveOperations.setItems( + FXCollections.observableArrayList( + operationService.list(EnumSet.of(Status.ACTIVE)))); + } catch (ServiceException e) { + LOG.error("ServiceException in fillActiveList(). ", e); + showServiceExceptionAlertAndWait(e.getMessage()); + } + } + + @FXML + public void closeOperationClicked() { + LOG.debug("Button \"Abschließen\" clicked."); + try { + operationService.complete(operation.id(), Status.COMPLETED); + } catch (InvalidOperationException e) { + LOG.debug("Validation error in closeOperationClicked(). ", e); + showAlertWithOkButtonAndWait(AlertType.ERROR, "Validierungsfehler", e.getMessage()); + return; + } catch (ServiceException e) { + LOG.error("Exception in closeOperationClicked(). ", e); + showServiceExceptionAlertAndWait(e.getMessage()); + return; + } + showSuccessAlertAndWait("Der Einsatz wurde erfolgreich aktualisiert"); + createOperationController.updateList(); + closeWindow(); + } + + public void cancelOperationClicked() { + LOG.debug("Button \"Stornieren\" clicked."); + try { + operationService.complete(operation.id(), Status.CANCELLED); + } catch (InvalidOperationException e) { + LOG.debug("Validation error in cancelOperationClicked(). ", e); + showValidationErrorAlertAndWait(e.getMessage()); + return; + } catch (ServiceException e) { + LOG.error("Exception in cancelOperationClicked(). ", e); + showServiceExceptionAlertAndWait(e.getMessage()); + return; + } + showSuccessAlertAndWait("Der Einsatz wurde erfolgreich aktualisiert"); + createOperationController.updateList(); + closeWindow(); + } + + private void requestVehicleClicked(VehiclePaneController v) { + LOG.debug("Button \"Nachfordern\" clicked."); + + try { + operationService.requestVehicles(operation.id(), Set.of(v.getData().id())); + } catch (ServiceException | InvalidOperationException | InvalidVehicleException e) { + LOG.error("Exception in requestVehicleClicked()", e); + showServiceExceptionAlertAndWait(e.getMessage()); + return; + } + showSuccessAlertAndWait("Das Fahrzeug wurde erfolgreich angefordert"); + createOperationController.updateList(); + } + + public void closeWindow() { + LOG.debug("Hyperlink \"Zurück\" clicked."); + operationDetailsAP.setVisible(false); + this.createOperationController.setVisible(true); + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationInArchiveController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationInArchiveController.java new file mode 100644 index 0000000..17f0f55 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/OperationInArchiveController.java @@ -0,0 +1,65 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import java.io.IOException; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.util.Collection; +import java.util.Objects; +import java.util.stream.Collectors; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Node; +import javafx.scene.text.Text; + +public class OperationInArchiveController { + + @FXML private Text txtAddress; + @FXML private Text txtVehicles; + @FXML private Text txtDate; + @FXML private Text txtOpCode; + + static OperationInArchiveController create() throws IOException { + FXMLLoader fxmlLoader = + new FXMLLoader( + OperationInArchiveController.class.getResource( + "/fxml/OperationInArchive.fxml")); + Node root = fxmlLoader.load(); + OperationInArchiveController result = fxmlLoader.getController(); + result.rootElement = root; + + return result; + } + + public Node getRoot() { + return rootElement; + } + + private Node rootElement; + + public void set(Operation operation) { + txtAddress.setText(operation.destination()); + String date = "am "; + if (operation.created() != null) { + LocalDateTime myDateTime = + LocalDateTime.ofInstant( + Objects.requireNonNull(operation.created()), ZoneOffset.UTC); + date += + myDateTime.getDayOfMonth() + + "." + + myDateTime.getMonth().getValue() + + "." + + myDateTime.getYear(); + txtDate.setText(date); + } else { + txtDate.setText("---"); + } + txtOpCode.setText(operation.opCode()); + Collection elements = + operation.vehicles().stream().map(Vehicle::name).collect(Collectors.toList()); + String result = String.join(", ", elements); + + txtVehicles.setText(result); + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java new file mode 100644 index 0000000..9c47fe4 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/RegistrationWindowController.java @@ -0,0 +1,279 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showServiceExceptionAlertAndWait; +import static at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller.Helper.showValidationErrorAlertAndWait; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.Status; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.EmployeeService; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.RegistrationService; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service.VehicleService; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidRegistrationException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader; +import java.io.IOException; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.OffsetDateTime; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.fxml.FXML; +import javafx.geometry.Insets; +import javafx.scene.Node; +import javafx.scene.control.ChoiceBox; +import javafx.scene.control.Label; +import javafx.scene.control.ScrollPane; +import javafx.scene.control.TextField; +import javafx.scene.input.KeyEvent; +import javafx.scene.input.MouseButton; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.VBox; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; + +@Controller +public class RegistrationWindowController { + + private static final Logger LOG = LoggerFactory.getLogger(RegistrationWindowController.class); + + private final EmployeeService employeeService; + private final VehicleService vehicleService; + private final RegistrationService registrationService; + private final CreateOperationController createOperationController; + private final SpringFXMLLoader fxmlLoader; + + @FXML private GridPane root; + @FXML private VBox vbVehicles; + @FXML private ScrollPane listEmployee; + @FXML private ChoiceBox cbStart; + @FXML private ChoiceBox cbEnd; + @FXML private Label lVehicles; + @FXML private Label lEmployees; + @FXML private TextField tfVehicleSearch; + @FXML private TextField tfEmployeeSearch; + private EmployeeListController employeeListController; + + private Vehicle chosenVehicle; + private List chosenEmployees = new LinkedList<>(); + + public RegistrationWindowController( + EmployeeService employeeService, + VehicleService vehicleService, + CreateOperationController createOperationController, + RegistrationService registrationService, + SpringFXMLLoader fxmlLoader) { + this.employeeService = employeeService; + this.vehicleService = vehicleService; + this.createOperationController = createOperationController; + this.registrationService = registrationService; + this.fxmlLoader = fxmlLoader; + } + + @FXML + private void initialize() throws IOException { + employeeListController = EmployeeListController.createEmployeeListController(fxmlLoader); + employeeListController.setListItemMargins(new Insets(10, 6, 0, 6)); + // listEmployee. .getChildren().add(employeeListController.getRootElement()); + Node emplList = employeeListController.getRootElement(); + // emplList.(360); + listEmployee.setContent(emplList); + + ObservableList hours = + FXCollections.observableArrayList( + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23); + cbStart.setItems(hours); + cbStart.setValue(0); + cbEnd.setItems(hours); + cbEnd.setValue(12); + + reset(); + } + + private void updateEmplList() { + employeeListController.deselectAllEmployees(); + + try { + Set employees = + employeeService + .list() + .stream() + .filter( + e -> + e.name() + .toLowerCase() + .contains( + tfEmployeeSearch + .getText() + .toLowerCase())) + .collect(Collectors.toCollection(HashSet::new)); + employeeListController.setData( + employees, + selection -> { + if (selection == null) { + return; + } else if (chosenEmployees.contains(selection)) { + chosenEmployees.remove(selection); + } else { + chosenEmployees.add(selection); + } + + StringBuilder text = new StringBuilder(); + boolean first = true; + for (Employee employee : chosenEmployees) { + if (!first) { + text.append(", "); + } + text.append(employee.name()); + first = false; + } + lEmployees.setText(text.toString()); + }, + contr -> contr.setSelected(chosenEmployees.contains(contr.getEmployee()))); + + employees.forEach( + e -> { + if (chosenEmployees.contains(e)) employeeListController.selectEmployee(e); + }); + } catch (ServiceException e) { + LOG.error("ServiceException in updateEmplList(). ", e); + showServiceExceptionAlertAndWait( + "Beim Auflisten des Personals ist ein Fehler aufgetreten."); + } + } + + private void updateVehList() { + vbVehicles.getChildren().clear(); + + try { + Set vehicles = vehicleService.list(EnumSet.of(Status.ABGEMELDET)); + + boolean anyMatch = false; + + for (Vehicle vehicle : vehicles) { + if (!vehicle.name().toLowerCase().contains(tfVehicleSearch.getText().toLowerCase())) + continue; + + anyMatch = true; + + VehiclePaneController vp = VehiclePaneController.createVehiclePane(); + vp.setData(vehicle, false, false); + vbVehicles.getChildren().add(vp.getRootElement()); + + vp.getRootElement() + .setOnMouseClicked( + event -> { + if (event.getButton() == MouseButton.PRIMARY) { + chosenVehicle = vehicle; + lVehicles.setText(chosenVehicle.name()); + updateVehList(); + } + }); + if (chosenVehicle != null && chosenVehicle.id() == vehicle.id()) + vp.setSelected(true); + } + + if (!anyMatch) { + // Kind of ugly, but best way to get the size of a VehiclePane + VehiclePaneController vp = VehiclePaneController.createVehiclePane(); + vp.getRootElement().setVisible(false); + vbVehicles.getChildren().add(vp.getRootElement()); + } + } catch (ServiceException e) { + LOG.error("ServiceException in updateVehList(). ", e); + showServiceExceptionAlertAndWait( + "Beim Auflisten der Fahrzeuge ist ein Fehler aufgetreten"); + } catch (IOException e) { + LOG.error("IOException in updateVehList(). ", e); + showServiceExceptionAlertAndWait("Beim Laden der Fahrzeuge ist ein Fehler aufgetreten"); + } + } + + public void cancel() { + LOG.debug("Hyperlink \"schließen\" clicked"); + reset(); + this.setVisible(false); + createOperationController.setVisible(true); + } + + private void reset() { + chosenEmployees.clear(); + chosenVehicle = null; + tfEmployeeSearch.setText(""); + tfVehicleSearch.setText(""); + lEmployees.setText("-"); + lVehicles.setText("-"); + updateVehList(); + updateEmplList(); + } + + public void create() { + LOG.debug("Button \"ERSTELLEN\" clicked"); + + Set registrations = new HashSet<>(); + try { + if (chosenVehicle == null) { + throw new InvalidVehicleException("no Vehicle"); + } + for (Employee employee : chosenEmployees) { + registrations.add( + Registration.builder() + .id(chosenVehicle.id()) + .employee(employee) + .start( + LocalDateTime.of( + LocalDate.now(), + LocalTime.of(cbStart.getValue(), 0)) + .toInstant(OffsetDateTime.now().getOffset())) + .end( + LocalDateTime.of( + LocalDate.now(), + LocalTime.of(cbEnd.getValue(), 0)) + .toInstant(OffsetDateTime.now().getOffset())) + .build()); + } + + registrationService.add(chosenVehicle.id(), registrations); + chosenEmployees.clear(); + // ((Stage) lVehicles.getScene().getWindow()).close(); + this.setVisible(false); + createOperationController.setVisible(true); + reset(); + } catch (InvalidVehicleException e) { + LOG.debug("Validation of Vehicle in Registration failed."); + showValidationErrorAlertAndWait("Das spezifizierte Fahrzeug ist nicht gültig."); + } catch (ServiceException e) { + LOG.error("ServiceException in create(). ", e); + showServiceExceptionAlertAndWait( + "Beim Erstellen der Anmeldung ist ein Fehler aufgetreten."); + } catch (InvalidRegistrationException e) { + LOG.debug("Validation of Registration failed."); + showValidationErrorAlertAndWait( + "Die gewählte Kombination von Fahrzeug und Personal ist nicht gültig!"); + } + } + + public void setVisible(boolean b) { + root.setVisible(b); + reset(); + } + + public void tfVehicleSearch_TextChanged(KeyEvent keyEvent) { + updateVehList(); + } + + public void tfEmployeeSearch_TextChanged(KeyEvent keyEvent) { + updateEmplList(); + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/VehiclePaneController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/VehiclePaneController.java new file mode 100644 index 0000000..66b45d2 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/controller/VehiclePaneController.java @@ -0,0 +1,118 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.controller; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee.EducationLevel; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.Status; +import java.io.IOException; +import java.time.Instant; +import java.util.List; +import java.util.Optional; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Node; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.text.Text; + +public class VehiclePaneController extends CustomListItemController { + + public static VehiclePaneController createVehiclePane() throws IOException { + FXMLLoader fxmlLoader = + new FXMLLoader(VehiclePaneController.class.getResource("/fxml/vehiclePane.fxml")); + Node root = fxmlLoader.load(); + VehiclePaneController result = fxmlLoader.getController(); + result.rootElement = root; + + return result; + } + + @FXML private Label txtStatus; + @FXML private Text txtType; + @FXML private Text txtNumber; + @FXML private ImageView ivNEF; + @FXML private Text txtNEF; + @FXML private ImageView ivQualification; + @FXML private Text txtQualification; + @FXML private Text txtRooftype; + @FXML private Button btnRequest; + + private Vehicle data; + + public Vehicle getData() { + return data; + } + + /** + * * Set the displayed data of this VehiclePane. + * + * @param vehicle The data to display. + * @param showStatusInfo If true, the highest qualification of the vehicle's active registration + * and the vehicle's status will be shown. + */ + public void setData(Vehicle vehicle, boolean showStatusInfo, boolean showRequestVehicle) { + txtType.setText(vehicle.type().name()); + String constrType = vehicle.constructionType().name(); + txtRooftype.setText( + constrType.substring(0, 1).toUpperCase() + constrType.substring(1).toLowerCase()); + txtNumber.setText("-" + vehicle.id()); + if (vehicle.hasNef()) { + ivNEF.setImage(new Image("images/NEF.png")); + txtNEF.setText("hat NEF-Halterung"); + } else { + ivNEF.setImage(new Image("images/NotNEF.png")); + txtNEF.setText("keine NEF-Halterung"); + } + + if (showRequestVehicle) { + btnRequest.setVisible(true); + btnRequest.setManaged(true); + } else { + btnRequest.setVisible(false); + btnRequest.setManaged(false); + } + + if (showStatusInfo) { + txtStatus.setText(vehicle.status().name()); + if (vehicle.status() == Status.FREI_FUNK || vehicle.status() == Status.FREI_WACHE) { + txtStatus.getStyleClass().add("bg-status-green"); + } else { + txtStatus.getStyleClass().add("bg-status-orange"); + } + + Instant now = Instant.now(); + List regs = vehicle.registrations(); + + if (regs == null) { + return; + } + + Optional edu = + regs.stream() + .filter(reg -> reg.start().isBefore(now) && reg.end().isAfter(now)) + .map(reg -> reg.employee().educationLevel()) + .max(EducationLevel::compareTo); + + if (!edu.isPresent()) { + return; + } + + txtQualification.setText(edu.get().name()); + } else { + txtQualification.setVisible(false); + txtQualification.setManaged(false); + ivQualification.setVisible(false); + ivQualification.setManaged(false); + + txtStatus.setVisible(false); + } + + this.data = vehicle; + } + + public Button getBtnRequest() { + return btnRequest; + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDAO.java new file mode 100644 index 0000000..d8ac513 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDAO.java @@ -0,0 +1,44 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; +import java.util.Set; + +public interface EmployeeDAO { + + /** + * Persist the given employee. + * + * @param employee that should be stored + * @return the id that was assigned + * @throws PersistenceException if the employee could not be persisted + */ + long add(Employee employee) throws PersistenceException; + + /** + * Update the given employee. + * + * @param employee that should be updated + * @throws ElementNotFoundException if no employee with the given id exists + * @throws PersistenceException if the employee could not be updated + */ + void update(Employee employee) throws ElementNotFoundException, PersistenceException; + + /** + * Get all stored employees. + * + * @return list containing all stored employees + * @throws PersistenceException if loading the stored employees failed + */ + Set list() throws PersistenceException; + + /** + * Remove employee with the given id from the store. + * + * @param id of the employee that should be removed + * @throws ElementNotFoundException if no employee with the given id exists + * @throws PersistenceException if the employee could not be removed + */ + void remove(long id) throws ElementNotFoundException, PersistenceException; +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDatabaseDAO.java new file mode 100644 index 0000000..889b0fc --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/EmployeeDatabaseDAO.java @@ -0,0 +1,144 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee.EducationLevel; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; +import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.time.LocalDate; +import java.util.HashSet; +import java.util.Set; +import org.springframework.stereotype.Repository; + +@Repository +public class EmployeeDatabaseDAO implements EmployeeDAO { + + private JDBCConnectionManager jdbcConnectionManager; + + public EmployeeDatabaseDAO(JDBCConnectionManager jdbcConnectionManager) { + this.jdbcConnectionManager = jdbcConnectionManager; + } + + private long createEmployeeVersion(Connection con, Employee e) + throws PersistenceException, SQLException { + String sql = + "INSERT INTO EmployeeVersion(name, birthday, educationLevel, isDriver, isPilot) " + + "VALUES(?, ?, ?, ?, ?)"; + + try (PreparedStatement pstmt = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { + pstmt.setString(1, e.name()); + pstmt.setObject(2, e.birthday()); + pstmt.setInt(3, e.educationLevel().ordinal()); + pstmt.setBoolean(4, e.isDriver()); + pstmt.setBoolean(5, e.isPilot()); + pstmt.executeUpdate(); + + try (ResultSet rs = pstmt.getGeneratedKeys()) { + if (!rs.next()) throw new PersistenceException("Failed to insert EmployeeVersion"); + + return rs.getLong(1); + } + } + } + + @Override + public long add(Employee employee) throws PersistenceException { + String sql = "INSERT INTO Employee(version) VALUES(?)"; + + try { + Connection con = jdbcConnectionManager.getConnection(); + con.setAutoCommit(false); + + long versionId = createEmployeeVersion(con, employee); + + try (PreparedStatement pstmt = + con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { + pstmt.setLong(1, versionId); + pstmt.executeUpdate(); + + try (ResultSet rs = pstmt.getGeneratedKeys()) { + if (!rs.next()) { + con.rollback(); + throw new PersistenceException("Failed to insert Employee"); + } + + con.commit(); + return rs.getLong(1); + } + } + } catch (SQLException e) { + jdbcConnectionManager.rollbackConnection(); + throw new PersistenceException(e); + } + } + + @Override + public void update(Employee employee) throws ElementNotFoundException, PersistenceException { + String sql = "UPDATE Employee SET version = ? WHERE id = ?"; + + try { + Connection con = jdbcConnectionManager.getConnection(); + con.setAutoCommit(false); + + long versionId = createEmployeeVersion(con, employee); + + try (PreparedStatement pstmt = con.prepareStatement(sql)) { + pstmt.setLong(1, versionId); + pstmt.setLong(2, employee.id()); + + if (pstmt.executeUpdate() != 1) { + con.rollback(); + throw new ElementNotFoundException("No such employeeId exists"); + } + } + + con.commit(); + } catch (SQLException e) { + jdbcConnectionManager.rollbackConnection(); + throw new PersistenceException(e); + } + } + + @Override + public Set list() throws PersistenceException { + String sql = + "SELECT emp.id, v.name, v.birthday, v.educationLevel, v.isDriver, v.isPilot " + + "FROM employee emp " + + "JOIN EmployeeVersion v ON v.id = emp.version"; + + try { + Connection con = jdbcConnectionManager.getConnection(); + Set employees = new HashSet<>(); + + try (PreparedStatement pstmt = con.prepareStatement(sql)) { + try (ResultSet rs = pstmt.executeQuery()) { + while (rs.next()) { + employees.add( + Employee.builder() + .id(rs.getLong(1)) + .name(rs.getString(2)) + .birthday(rs.getObject(3, LocalDate.class)) + .educationLevel(EducationLevel.valueOf(rs.getString(4))) + .isDriver(rs.getBoolean(5)) + .isPilot(rs.getBoolean(6)) + .build()); + } + } + } + + return employees; + } catch (SQLException e) { + throw new PersistenceException(e); + } + } + + @Override + public void remove(long id) throws ElementNotFoundException, PersistenceException { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDAO.java new file mode 100644 index 0000000..c0ef5d4 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDAO.java @@ -0,0 +1,48 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; +import java.util.EnumSet; +import java.util.Set; + +public interface OperationDAO { + + /** + * Persist the given operation. + * + * @param operation that should be stored + * @return the id that was assigned + * @throws PersistenceException if the operation could not be persisted + */ + long add(Operation operation) throws PersistenceException; + + /** + * Update the given operation. + * + * @param operation that should be updated + * @throws ElementNotFoundException if no operation with the given id exists + * @throws PersistenceException if the operation could not be updated + */ + void update(Operation operation) throws ElementNotFoundException, PersistenceException; + + /** + * Returns the operation with the given id. + * + * @param operationId id of the operation that should be returned + * @return operation with the given id + * @throws ElementNotFoundException if no operation with the given id exists + * @throws PersistenceException if the operation could not be loaded + */ + Operation get(long operationId) throws ElementNotFoundException, PersistenceException; + + /** + * Get all stored operations with matching status. + * + * @param statuses set containing all statuses that should be matched + * @return list containing all matched operations + * @throws PersistenceException if loading the stored operations failed + */ + Set list(EnumSet statuses) throws PersistenceException; +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDatabaseDAO.java new file mode 100644 index 0000000..1641720 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/OperationDatabaseDAO.java @@ -0,0 +1,221 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Severity; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; +import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; +import org.springframework.lang.NonNull; +import org.springframework.stereotype.Repository; + +@Repository +public class OperationDatabaseDAO implements OperationDAO { + + private JDBCConnectionManager jdbcConnectionManager; + private VehicleDAO vehicleDAO; + + public OperationDatabaseDAO( + JDBCConnectionManager jdbcConnectionManager, VehicleDAO vehicleDAO) { + this.jdbcConnectionManager = jdbcConnectionManager; + this.vehicleDAO = vehicleDAO; + } + + @Override + public long add(@NonNull Operation o) throws PersistenceException { + String sql = + "INSERT INTO Operation(opCode, severity, created, destination, additionalInfo," + + " status) VALUES (?, ?, ?, ?, ?, ?)"; + String sql2 = "INSERT INTO VehicleOperation(vehicleId, operationId) VALUES (?, ?)"; + long operationId; + + try { + Connection con = jdbcConnectionManager.getConnection(); + con.setAutoCommit(false); + try (PreparedStatement pstmt = con.prepareStatement(sql)) { + pstmt.setString(1, o.opCode()); + pstmt.setInt(2, o.severity().ordinal()); + pstmt.setObject(3, OffsetDateTime.ofInstant(o.created(), ZoneId.systemDefault())); + pstmt.setString(4, o.destination()); + pstmt.setString(5, o.additionalInfo()); + pstmt.setInt(6, o.status().ordinal()); + pstmt.executeUpdate(); + + try (ResultSet rs = pstmt.getGeneratedKeys()) { + if (!rs.next()) throw new PersistenceException("Failed to persist operation"); + + operationId = rs.getLong(1); + } + } + + try (PreparedStatement pstmt = con.prepareStatement(sql2)) { + pstmt.setLong(2, operationId); + + for (long id : (Iterable) o.vehicles().stream().map(Vehicle::id)::iterator) { + pstmt.setLong(1, id); + pstmt.addBatch(); + } + + pstmt.executeBatch(); + } + con.commit(); + return operationId; + } catch (SQLException e) { + jdbcConnectionManager.rollbackConnection(); + throw new PersistenceException(e); + } + } + + @Override + public void update(@NonNull Operation o) throws ElementNotFoundException, PersistenceException { + // Note this will, by design, not update created + String sql = + "UPDATE Operation SET opCode = ?, severity = ?, destination = ?," + + " additionalInfo = ?, status = ? WHERE id = ?"; + String sql2 = "DELETE FROM VehicleOperation WHERE operationId = ?"; + String sql3 = "INSERT INTO VehicleOperation(vehicleId, operationId) VALUES (?, ?)"; + + try { + Connection con = jdbcConnectionManager.getConnection(); + con.setAutoCommit(false); + try (PreparedStatement pstmt = con.prepareStatement(sql)) { + pstmt.setString(1, o.opCode()); + pstmt.setInt(2, o.severity().ordinal()); + pstmt.setString(3, o.destination()); + pstmt.setString(4, o.additionalInfo()); + pstmt.setInt(5, o.status().ordinal()); + pstmt.setLong(6, o.id()); + + if (pstmt.executeUpdate() != 1) + throw new ElementNotFoundException("No such operationId exists"); + } + + try (PreparedStatement pstmt = con.prepareStatement(sql2)) { + pstmt.setLong(1, o.id()); + pstmt.executeUpdate(); + } + + try (PreparedStatement pstmt = con.prepareStatement(sql3)) { + pstmt.setLong(2, o.id()); + + for (long id : (Iterable) o.vehicles().stream().map(Vehicle::id)::iterator) { + pstmt.setLong(1, id); + pstmt.addBatch(); + } + + pstmt.executeBatch(); + } + con.commit(); + } catch (SQLException e) { + jdbcConnectionManager.rollbackConnection(); + throw new PersistenceException(e); + } + } + + @Override + public Operation get(long operationId) throws ElementNotFoundException, PersistenceException { + String sql = "Select * from operation where id = ?"; + + try { + Connection con = jdbcConnectionManager.getConnection(); + try (PreparedStatement pstmt = con.prepareStatement(sql)) { + pstmt.setLong(1, operationId); + pstmt.execute(); + + try (ResultSet rs = pstmt.getResultSet()) { + if (!rs.next()) + throw new ElementNotFoundException("No such element could be found"); + + return operationFromRS(rs); + } + } + } catch (SQLException e) { + throw new PersistenceException(e); + } + } + + @Override + public Set list(EnumSet statuses) throws PersistenceException { + // This hack exists because H2 currently has a bug that prevents IN (?) with an array of + // ids, i.e. pstmt.setArray(1, con.createArrayOf("INT", intarray) from working. See + // commented code below. + + // SELECT * FROM Operation WHERE status IN ('COMPLETED', 'CANCELLED') is BUGGED on H2! + // for this reason we use the ordinal values instead + String str = + statuses.stream() + .map(e -> Integer.toString(e.ordinal())) + .collect(Collectors.joining(",")); + + String sql = "SELECT * FROM Operation WHERE status IN (" + str + ")"; + Set operations = new HashSet<>(); + + try { + Connection con = jdbcConnectionManager.getConnection(); + + try (PreparedStatement pstmt = con.prepareStatement(sql)) { + // Object[] arr = statuses.stream().map(Enum::ordinal).toArray(); + // pstmt.setArray(1, con.createArrayOf("INT", arr)); + + try (ResultSet rs = pstmt.executeQuery()) { + while (rs.next()) operations.add(operationFromRS(rs)); + } + } + + return operations; + } catch (SQLException e) { + throw new PersistenceException(e); + } + } + + private Operation operationFromRS(ResultSet rs) throws PersistenceException, SQLException { + Long operationId = rs.getLong("id"); + + return Operation.builder() + .id(operationId) + .opCode(rs.getString("opCode")) + .severity(Severity.valueOf(rs.getString("severity"))) + .status(Status.valueOf(rs.getString("status"))) + .vehicles(getVehiclesFromOperationId(operationId)) + .created((rs.getObject("created", OffsetDateTime.class)).toInstant()) + .destination(rs.getString("destination")) + .additionalInfo(rs.getString("additionalInfo")) + .build(); + } + + private Set getVehiclesFromOperationId(long operationId) throws PersistenceException { + String sql = "SELECT vehicleId FROM VehicleOperation WHERE operationId = ?"; + Set vehicles = new HashSet<>(); + + try { + Connection con = jdbcConnectionManager.getConnection(); + try (PreparedStatement pstmt = con.prepareStatement(sql)) { + pstmt.setLong(1, operationId); + pstmt.execute(); + + try (ResultSet rs = pstmt.getResultSet()) { + while (rs.next()) { + vehicles.add(vehicleDAO.get(rs.getLong("vehicleId"))); + } + } + } + } catch (SQLException e) { + throw new PersistenceException(e); + } catch (ElementNotFoundException e) { + throw new PersistenceException("VehicleOperation contained nonexistent vehicle", e); + } + + return vehicles; + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDAO.java new file mode 100644 index 0000000..02e742c --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDAO.java @@ -0,0 +1,28 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; +import java.util.Set; + +public interface RegistrationDAO { + + /** + * Persist the given registration. + * + * @param vehicleId the id of the target vehicle + * @param registrations that should be stored + * @return a list of the ids that were assigned + * @throws PersistenceException if the registration could not be persisted + */ + Set add(long vehicleId, Set registrations) throws PersistenceException; + + /** + * Make registration with the given id inactive. + * + * @param id of the registration that should be made inactive + * @throws ElementNotFoundException if no registration with the given id exists + * @throws PersistenceException if the registration could not be made inactive + */ + void remove(long id) throws ElementNotFoundException, PersistenceException; +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java new file mode 100644 index 0000000..1006a33 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/RegistrationDatabaseDAO.java @@ -0,0 +1,130 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; +import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +@Repository +public class RegistrationDatabaseDAO implements RegistrationDAO { + + private JDBCConnectionManager jdbcConnectionManager; + private EmployeeDAO employeePersistence; + + @Autowired + public RegistrationDatabaseDAO( + JDBCConnectionManager jdbcConnectionManager, EmployeeDAO employeePersistence) { + this.jdbcConnectionManager = jdbcConnectionManager; + this.employeePersistence = employeePersistence; + } + + @Override + public Set add(long vehicleId, Set registrations) + throws PersistenceException { + String sql = + "INSERT INTO Registration (vehicleId, employeeId, start, end, active) VALUES (?,?,?,?,?)"; + String sql2 = "UPDATE Vehicle SET status = 'FREI_WACHE' WHERE id = ?;"; + + Set vehicleIds = new HashSet<>(); + + try { + Connection con = jdbcConnectionManager.getConnection(); + con.setAutoCommit(false); + + try (PreparedStatement pstmt = + con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { + pstmt.setLong(1, vehicleId); + + for (Registration r : registrations) { + pstmt.setLong(2, r.employee().id()); + pstmt.setObject(3, OffsetDateTime.ofInstant(r.start(), ZoneId.systemDefault())); + pstmt.setObject(4, OffsetDateTime.ofInstant(r.end(), ZoneId.systemDefault())); + pstmt.setBoolean(5, true); + pstmt.addBatch(); + } + + pstmt.executeBatch(); + + try (ResultSet rs = pstmt.getGeneratedKeys()) { + while (rs.next()) vehicleIds.add(rs.getLong(1)); + } + } + + try (PreparedStatement pstmt = con.prepareStatement(sql2)) { + pstmt.setLong(1, vehicleId); + if (pstmt.executeUpdate() != 1) { + con.rollback(); + throw new PersistenceException("Failed to persist registration"); + } + } + + con.commit(); + return vehicleIds; + } catch (SQLException e) { + jdbcConnectionManager.rollbackConnection(); + throw new PersistenceException(e); + } + } + + @Override + public void remove(long id) throws ElementNotFoundException, PersistenceException { + throw new UnsupportedOperationException(); + } + + protected List list(long vehicleId) throws PersistenceException { + String sql = "SELECT * FROM Registration WHERE vehicleId = ?"; + + List registrationList = new ArrayList<>(); + try { + Connection con = jdbcConnectionManager.getConnection(); + + try (PreparedStatement pstmt = con.prepareStatement(sql)) { + pstmt.setLong(1, vehicleId); + + try (ResultSet rs = pstmt.executeQuery()) { + while (rs.next()) { + long employeeId = rs.getLong("employeeId"); + // TODO: replace the following with employeePersistence.get once implemented + Employee emp = + employeePersistence + .list() + .stream() + .filter(employee -> employee.id() == employeeId) + .findAny() + .orElse(null); + Registration registration = + Registration.builder() + .id(rs.getLong("id")) + .start( + (rs.getObject("start", OffsetDateTime.class)) + .toInstant()) + .end( + (rs.getObject("end", OffsetDateTime.class)) + .toInstant()) + .employee(emp) + .build(); + registrationList.add(registration); + } + } + } + + return registrationList; + } catch (SQLException e) { + throw new PersistenceException(e); + } + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDAO.java new file mode 100644 index 0000000..ed24498 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDAO.java @@ -0,0 +1,54 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; +import java.util.Set; + +public interface VehicleDAO { + + /** + * Persist the given vehicle. + * + * @param vehicle that should be stored + * @return the id that was assigned + * @throws PersistenceException if the vehicle could not be persisted + */ + long add(Vehicle vehicle) throws PersistenceException; + + /** + * Update the given vehicle. + * + * @param vehicle that should be updated + * @throws ElementNotFoundException if no vehicle with the given id exists + * @throws PersistenceException if the vehicle could not be updated + */ + void update(Vehicle vehicle) throws ElementNotFoundException, PersistenceException; + + /** + * Get all stored vehicles. + * + * @return list containing all stored vehicles + * @throws PersistenceException if loading the stored vehicles failed + */ + Set list() throws PersistenceException; + + /** + * Returns the vehicle with the given id. + * + * @param vehicleId id of the vehicle that should be returned + * @return vehicle with the given id + * @throws ElementNotFoundException if no vehicle with the given id exists + * @throws PersistenceException if the vehicle could not be loaded + */ + Vehicle get(long vehicleId) throws ElementNotFoundException, PersistenceException; + + /** + * Remove vehicle with the given id from the store. + * + * @param id of the vehicle that should be removed + * @throws ElementNotFoundException if no vehicle with the given id exists + * @throws PersistenceException if the vehicle could not be removed + */ + void remove(long id) throws ElementNotFoundException, PersistenceException; +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDatabaseDAO.java new file mode 100644 index 0000000..dd7c0f2 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dao/VehicleDatabaseDAO.java @@ -0,0 +1,211 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.ConstructionType; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.Status; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.VehicleType; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; +import at.ac.tuwien.sepm.assignment.groupphase.util.JDBCConnectionManager; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.HashSet; +import java.util.Set; +import org.springframework.stereotype.Repository; + +@Repository +public class VehicleDatabaseDAO implements VehicleDAO { + + private final JDBCConnectionManager jdbcConnectionManager; + private RegistrationDatabaseDAO registrationDatabaseDao; + + public VehicleDatabaseDAO( + JDBCConnectionManager j, RegistrationDatabaseDAO registrationDatabaseDao) { + jdbcConnectionManager = j; + this.registrationDatabaseDao = registrationDatabaseDao; + } + + @Override + public long add(Vehicle v) throws PersistenceException { + String sql = + "INSERT INTO VehicleVersion (name,hasNef,constructionType,type) VALUES (?,?,?,?)"; + String sql2 = "INSERT INTO Vehicle (version,status) VALUES (?,?)"; + String sql3 = "UPDATE VehicleVersion SET name=? WHERE id=?"; + + try { + Connection con = jdbcConnectionManager.getConnection(); + con.setAutoCommit(false); + String name = ""; + long version, id; + + try (PreparedStatement pstmt = + con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { + pstmt.setString(1, name); + pstmt.setBoolean(2, v.hasNef()); + pstmt.setInt(3, v.constructionType().ordinal()); + pstmt.setString(4, v.type().name()); + pstmt.executeUpdate(); + + try (ResultSet rs = pstmt.getGeneratedKeys()) { + if (!rs.next()) + throw new PersistenceException("Failed to insert into VehicleVersion"); + + version = rs.getLong(1); + } + } + + try (PreparedStatement pstmt = + con.prepareStatement(sql2, Statement.RETURN_GENERATED_KEYS)) { + pstmt.setLong(1, version); + pstmt.setInt(2, Status.ABGEMELDET.ordinal()); + pstmt.executeUpdate(); + + try (ResultSet rs = pstmt.getGeneratedKeys()) { + if (!rs.next()) { + con.rollback(); + throw new PersistenceException("Failed to insert into Vehicle"); + } + + id = rs.getLong(1); + } + + name = v.type().name() + "-" + id; + } + + try (PreparedStatement pstmt = con.prepareStatement(sql3)) { + pstmt.setString(1, name); + pstmt.setLong(2, version); + + if (pstmt.executeUpdate() != 1) { + con.rollback(); + throw new PersistenceException("Failed to update VehicleVersion"); + } + } + + con.commit(); + return id; + } catch (SQLException e) { + jdbcConnectionManager.rollbackConnection(); + throw new PersistenceException(e); + } + } + + @Override + public void update(Vehicle v) throws ElementNotFoundException, PersistenceException { + String sql = "SELECT version FROM Vehicle WHERE id = ?"; + String sql2 = + "MERGE INTO VehicleVersion(name, constructionType, type, hasNef)" + + " KEY(name, constructionType, type, hasNef) VALUES(?, ?, ?, ?)"; + String sql3 = "UPDATE Vehicle SET version = ?, status = ? WHERE id = ?"; + + long versionId; + + try { + Connection con = jdbcConnectionManager.getConnection(); + con.setAutoCommit(false); + try (PreparedStatement pstmt = con.prepareStatement(sql)) { + pstmt.setLong(1, v.id()); + + try (ResultSet rs = pstmt.executeQuery()) { + if (!rs.next()) throw new ElementNotFoundException("No such vehicleId exists"); + + versionId = rs.getLong(1); + } + } + + try (PreparedStatement pstmt = + con.prepareStatement(sql2, Statement.RETURN_GENERATED_KEYS)) { + pstmt.setString(1, v.type().name() + "-" + v.id()); + pstmt.setString(2, v.constructionType().name()); + pstmt.setString(3, v.type().name()); + pstmt.setBoolean(4, v.hasNef()); + pstmt.executeUpdate(); + + try (ResultSet rs = pstmt.getGeneratedKeys()) { + if (rs.next()) { + // version changed, update it + versionId = rs.getLong(1); + } + } + } + + try (PreparedStatement pstmt = con.prepareStatement(sql3)) { + pstmt.setLong(1, versionId); + pstmt.setString(2, v.status().name()); + pstmt.setLong(3, v.id()); + pstmt.executeUpdate(); + } + + con.commit(); + } catch (SQLException e) { + jdbcConnectionManager.rollbackConnection(); + throw new PersistenceException(e); + } + } + + @Override + public Set list() throws PersistenceException { + Set result = new HashSet<>(); + + String sql = + "Select * from VehicleVersion, Vehicle where VehicleVersion.id=Vehicle.version"; + + try (PreparedStatement pstmt = + jdbcConnectionManager.getConnection().prepareStatement(sql)) { + pstmt.executeQuery(); + try (ResultSet rs = pstmt.getResultSet()) { + while (rs.next()) { + result.add(vehicleFromRS(rs)); + } + } + } catch (SQLException e) { + throw new PersistenceException(e); + } + return result; + } + + @Override + public Vehicle get(long id) throws ElementNotFoundException, PersistenceException { + String sql = + "SELECT a.id, b.name, b.constructionType, b.type, a.status, b.hasNef" + + " FROM Vehicle a" + + " INNER JOIN VehicleVersion b" + + " ON version = b.id" + + " WHERE a.id = ?"; + + try { + Connection con = jdbcConnectionManager.getConnection(); + try (PreparedStatement pstmt = con.prepareStatement(sql)) { + pstmt.setLong(1, id); + + try (ResultSet rs = pstmt.executeQuery()) { + if (!rs.first()) throw new ElementNotFoundException("No such vehicle exists"); + + return vehicleFromRS(rs); + } + } + } catch (SQLException e) { + throw new PersistenceException(e); + } + } + + @Override + public void remove(long id) throws ElementNotFoundException, PersistenceException { + throw new UnsupportedOperationException(); + } + + private Vehicle vehicleFromRS(ResultSet rs) throws SQLException, PersistenceException { + return Vehicle.builder() + .id(rs.getLong("Vehicle.id")) + .name(rs.getString("name")) + .constructionType(ConstructionType.values()[rs.getInt("constructionType")]) + .type(VehicleType.valueOf(rs.getString("type"))) + .status(Status.values()[rs.getInt("status")]) + .hasNef(rs.getBoolean("hasNef")) + .registrations(registrationDatabaseDao.list(rs.getLong("id"))) + .build(); + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Employee.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Employee.java new file mode 100644 index 0000000..f45550e --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Employee.java @@ -0,0 +1,51 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto; + +import com.google.auto.value.AutoValue; +import java.time.LocalDate; + +@AutoValue +public abstract class Employee { + public enum EducationLevel { + RS, + NFS, + NKV, + NKA, + NKI, + NA + } + + public abstract long id(); + + public abstract String name(); + + public abstract LocalDate birthday(); + + public abstract EducationLevel educationLevel(); + + public abstract boolean isDriver(); + + public abstract boolean isPilot(); + + public static Builder builder() { + return new AutoValue_Employee.Builder().id(0); + } + + @AutoValue.Builder + public abstract static class Builder { + public abstract Builder id(long id); + + public abstract Builder name(String name); + + public abstract Builder birthday(LocalDate birthday); + + public abstract Builder educationLevel(EducationLevel educationLevel); + + public abstract Builder isDriver(boolean isDriver); + + public abstract Builder isPilot(boolean isPilot); + + public abstract Employee build(); + } + + public abstract Builder toBuilder(); +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/EmployeeValidator.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/EmployeeValidator.java new file mode 100644 index 0000000..b03fa04 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/EmployeeValidator.java @@ -0,0 +1,23 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto; + +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidEmployeeException; + +public class EmployeeValidator { + + public static boolean validate(Employee employee) throws InvalidEmployeeException { + + if (employee.name() == null || employee.name().trim().length() == 0) { + throw new InvalidEmployeeException("Name darf nicht leer sein!"); + } + + if (employee.birthday() == null) { + throw new InvalidEmployeeException("Geburtsdatum darf nicht leer sein!"); + } + + if (employee.educationLevel() == null) { + throw new InvalidEmployeeException("Ausbildungsgrad darf nicht leer sein!"); + } + + return true; + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Operation.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Operation.java new file mode 100644 index 0000000..e119622 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Operation.java @@ -0,0 +1,70 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto; + +import com.google.auto.value.AutoValue; +import java.time.Instant; +import java.util.Set; +import javax.annotation.Nullable; + +@AutoValue +public abstract class Operation { + public enum Severity { + A, + B, + C, + D, + E, + O, + } + + public enum Status { + ACTIVE, + COMPLETED, + CANCELLED, + } + + public abstract long id(); + + public abstract String opCode(); + + @Nullable + public abstract Severity severity(); + + public abstract Status status(); + + public abstract Set vehicles(); + + @Nullable + public abstract Instant created(); + + public abstract String destination(); + + @Nullable + public abstract String additionalInfo(); + + public static Builder builder() { + return new AutoValue_Operation.Builder().id(0); + } + + @AutoValue.Builder + public abstract static class Builder { + public abstract Builder id(long id); + + public abstract Builder opCode(String opCode); + + public abstract Builder severity(Severity severity); + + public abstract Builder status(Status status); + + public abstract Builder vehicles(Set vehicles); + + public abstract Builder created(Instant created); + + public abstract Builder destination(String destination); + + public abstract Builder additionalInfo(String additionalInfo); + + public abstract Operation build(); + } + + public abstract Builder toBuilder(); +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Registration.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Registration.java new file mode 100644 index 0000000..a12c038 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Registration.java @@ -0,0 +1,34 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto; + +import com.google.auto.value.AutoValue; +import java.time.Instant; + +@AutoValue +public abstract class Registration { + public abstract long id(); + + public abstract Instant start(); + + public abstract Instant end(); + + public abstract Employee employee(); + + public static Builder builder() { + return new AutoValue_Registration.Builder().id(0); + } + + @AutoValue.Builder + public abstract static class Builder { + public abstract Builder id(long id); + + public abstract Builder start(Instant start); + + public abstract Builder end(Instant end); + + public abstract Builder employee(Employee employee); + + public abstract Registration build(); + } + + public abstract Builder toBuilder(); +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/RegistrationValidator.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/RegistrationValidator.java new file mode 100644 index 0000000..9512f64 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/RegistrationValidator.java @@ -0,0 +1,174 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee.EducationLevel; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.VehicleType; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidRegistrationException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +public class RegistrationValidator { + + private RegistrationValidator() {} + + public static void validate(Vehicle vehicle, Set registrations) + throws InvalidVehicleException, InvalidRegistrationException { + /* + Vehicles and Employees are assumed to be valid. + They have been checked at creation, and for them to be checked again, access to + VehicleValidator and EmployeeValidator are needed, which are not available at this time. + */ + /* + The method used here goes as follows: All given employees are inspected in regards to their + qualifications, and added to the appropriate lists of the roles they could fill. + For example, an NFS, who is also a driver, would be added to the lists driverIds, nfsIds + and rsIds (because an NFS can always substitute an RS). + Afterwards, the number of people is checked according to the chosen vehicle type, and if + the number is okay, the program tries to find a valid combination of roles for the vehicle. + For example, for an RTW, first a driver is chosen, their ID marked as found in the aptly + titled HashMap, and then for the second RS, the list of RS is checked, excluding the chosen + driver. If no other valid RS is found, the next possible driver is chosen, and so on. If no + valid combination is found, an InvalidRegistrationException is thrown. + */ + List pilotIds = new LinkedList<>(); + List driverIds = new LinkedList<>(); + List naIds = new LinkedList<>(); + List nfsIds = new LinkedList<>(); + List rsIds = new LinkedList<>(); + HashMap found = + new HashMap<>(); // needed later in DFS, checks that no person is chosen twice + int total = 0; + for (Registration registration : registrations) { + total++; + if (found.put(registration.employee().id(), false) != null) { + throw new InvalidRegistrationException( + "Person mit der ID: " + + registration.employee().id() + + " wurde mehrmals hinzugefügt!"); + } + if (registration.employee().isPilot()) { + pilotIds.add(registration.employee().id()); + } + if (registration.employee().isDriver()) { + driverIds.add(registration.employee().id()); + } + if (registration.employee().educationLevel() == EducationLevel.NA) { + naIds.add(registration.employee().id()); + nfsIds.add(registration.employee().id()); + rsIds.add(registration.employee().id()); + } else if (isNFS(registration.employee())) { + nfsIds.add(registration.employee().id()); + rsIds.add(registration.employee().id()); + } else { // only RS left + rsIds.add(registration.employee().id()); + } + } + if (total <= 0) { + throw new InvalidRegistrationException("Kein Personal ausgewählt!"); + } + if (vehicle.type() == VehicleType.NAH) { + /* + NAH + 1 Pilot + 1 NFS + 1 NA + 3-4 Personen + */ + if (total < 3) { + throw new InvalidRegistrationException("Zu wenig Personal für NAH!"); + } else if (total > 4) { + throw new InvalidRegistrationException("Zu viel Personal für NAH!"); + } + for (long pilot_id : pilotIds) { + found.put(pilot_id, true); + for (long na_id : naIds) { + if (found.get(na_id)) continue; + found.put(na_id, true); + for (long nfs_id : nfsIds) { + if (found.get(nfs_id)) continue; + return; + } + found.put(na_id, false); + } + found.put(pilot_id, false); + } + throw new InvalidRegistrationException( + "Keine gültige Kombination von Personen für NAH!"); + } else if (vehicle.type() == VehicleType.NEF) { + /* + NEF + 1 Driver (has to be NFS) + 1 NA + */ + if (total < 2) { + throw new InvalidRegistrationException("Zu wenig Personal für NEF!"); + } else if (total > 3) { + throw new InvalidRegistrationException("Zu viel Personal für NEF!"); + } + for (long driver_id : driverIds) { + if (!nfsIds.contains(driver_id)) + continue; // if possible driver is not NFS, skip him + found.put(driver_id, true); + for (long na_id : naIds) { + if (found.get(na_id)) continue; + return; + } + found.put(driver_id, false); + } + throw new InvalidRegistrationException( + "Keine gültige Kombination von Personen für NEF!"); + } else if (vehicle.type() == VehicleType.BKTW) { + /* + BKTW + 1 Driver + */ + if (total > 3) { + throw new InvalidRegistrationException("Zu viel Personal für BKTW!"); + } + if (!driverIds.isEmpty()) { + return; + } + throw new InvalidRegistrationException("Kein Fahrer gefunden für BKTW!"); + } else { // KTW or RTW, both have the same requirements + /* + RTW/KTW + 1 Driver + 1 RS + */ + if (total < 2) { + throw new InvalidRegistrationException( + "Zu wenig Personal für " + vehicle.type().name() + "!"); + } else if (total > 4) { + throw new InvalidRegistrationException( + "Zu viel Persoanl für " + vehicle.type().name() + "!"); + } + for (long driver_id : driverIds) { // driver includes rs + found.put(driver_id, true); + for (long rs_id : rsIds) { + if (found.get(rs_id)) continue; + return; + } + } + throw new InvalidRegistrationException( + "Keine gültige Kombination von Personen für " + vehicle.type().name() + "!"); + } + } + + private static boolean isNFS(Employee employee) { + EducationLevel educationLevel = employee.educationLevel(); + switch (educationLevel) { + case NFS: + return true; + case NKA: + return true; + case NKI: + return true; + case NKV: + return true; + default: + return false; + } + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Vehicle.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Vehicle.java new file mode 100644 index 0000000..c2033f5 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/dto/Vehicle.java @@ -0,0 +1,73 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto; + +import com.google.auto.value.AutoValue; +import java.util.List; +import javax.annotation.Nullable; + +@AutoValue +public abstract class Vehicle { + public enum ConstructionType { + NORMAL, + HOCHDACH, + MITTELHOCHDACH, + } + + public enum VehicleType { + BKTW, + KTW_B, + KTW, + RTW, + NEF, + NAH, + } + + public enum Status { + ABGEMELDET, + FREI_WACHE, + FREI_FUNK, + ZUM_BERUFUNGSORT, + AM_BERUFUNGSORT, + ZUM_ZIELORT, + AM_ZIELORT, + } + + public abstract long id(); + + public abstract String name(); + + public abstract ConstructionType constructionType(); + + public abstract VehicleType type(); + + public abstract Status status(); + + public abstract boolean hasNef(); + + @Nullable + public abstract List registrations(); + + public static Builder builder() { + return new AutoValue_Vehicle.Builder().id(0); + } + + @AutoValue.Builder + public abstract static class Builder { + public abstract Builder id(long id); + + public abstract Builder name(String name); + + public abstract Builder constructionType(ConstructionType constructionType); + + public abstract Builder type(VehicleType type); + + public abstract Builder status(Status status); + + public abstract Builder hasNef(boolean hasNef); + + public abstract Builder registrations(List registrations); + + public abstract Vehicle build(); + } + + public abstract Builder toBuilder(); +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/EmployeeService.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/EmployeeService.java new file mode 100644 index 0000000..fa4d0e6 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/EmployeeService.java @@ -0,0 +1,46 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidEmployeeException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import java.util.Set; + +public interface EmployeeService { + + /** + * Add given employee to the store. + * + * @param employee that should be added to the store + * @return the id that was assigned + * @throws InvalidEmployeeException if the employee is invalid + * @throws ServiceException if the employee could not be persisted + */ + long add(Employee employee) throws InvalidEmployeeException, ServiceException; + + /** + * Update the given employee. + * + * @param employee that should be updated + * @return the updated employee + * @throws InvalidEmployeeException if the employee is invalid + * @throws ServiceException if the updated employee could not be persisted + */ + Employee update(Employee employee) throws InvalidEmployeeException, ServiceException; + + /** + * Get all stored employees. + * + * @return list containing all stored employees + * @throws ServiceException if loading the stored employees failed + */ + Set list() throws ServiceException; + + /** + * Remove employee with the given id from the store. + * + * @param id of the employee that should be removed + * @throws InvalidEmployeeException if given employee id is invalid or does not exist + * @throws ServiceException if the employee could not be removed from the store + */ + void remove(long id) throws InvalidEmployeeException, ServiceException; +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/EmployeeServiceImpl.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/EmployeeServiceImpl.java new file mode 100644 index 0000000..945fb49 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/EmployeeServiceImpl.java @@ -0,0 +1,59 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.EmployeeDAO; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Employee; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.EmployeeValidator; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidEmployeeException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import java.util.Set; +import org.springframework.stereotype.Service; + +@Service +public class EmployeeServiceImpl implements EmployeeService { + + private final EmployeeDAO employeePersistence; + + public EmployeeServiceImpl(EmployeeDAO employeePersistence) { + this.employeePersistence = employeePersistence; + } + + @Override + public long add(Employee employee) throws InvalidEmployeeException, ServiceException { + + EmployeeValidator.validate(employee); + try { + return employeePersistence.add(employee); + } catch (PersistenceException e) { + throw new ServiceException(e); + } + } + + @Override + public Employee update(Employee employee) throws InvalidEmployeeException, ServiceException { + + EmployeeValidator.validate(employee); + try { + employeePersistence.update(employee); + return employee; + } catch (ElementNotFoundException | PersistenceException e) { + throw new ServiceException(e); + } + } + + @Override + public Set list() throws ServiceException { + + try { + return employeePersistence.list(); + } catch (PersistenceException e) { + throw new ServiceException(e); + } + } + + @Override + public void remove(long id) throws InvalidEmployeeException, ServiceException { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationService.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationService.java new file mode 100644 index 0000000..ca1dce9 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationService.java @@ -0,0 +1,70 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidOperationException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import java.util.EnumSet; +import java.util.Set; +import java.util.SortedSet; + +public interface OperationService { + + /** + * Add given operation to the store. + * + * @param operation that should be added to the store + * @return the id that was assigned + * @throws InvalidOperationException if the operation is invalid + * @throws ServiceException if the operation could not be persisted + */ + long add(Operation operation) throws InvalidOperationException, ServiceException; + + /** + * Request new vehicles to the given operation. + * + * @param operationId id of the operation that the vehicles should be send to + * @param vehicleIds the ids of the vehicles that should be send to the given operation + * @throws InvalidOperationException if the operationId is invalid or does not exist + * @throws InvalidVehicleException if one of the vehicle ids is invalid or does not exist + * @throws ServiceException if the vehicles could not be loaded or the operation could not be + * persisted + */ + void requestVehicles(long operationId, Set vehicleIds) + throws InvalidOperationException, InvalidVehicleException, ServiceException; + + /** + * Completes the given operation with the specified status. + * + * @param operationId id of the operation that should be completed + * @param status of the completed operation, either {@link Status#COMPLETED} or {@link + * Status#CANCELLED} + * @throws InvalidOperationException if the operationId is invalid or does not exist + * @throws ServiceException if the operation could not be persisted + */ + void complete(long operationId, Status status) + throws InvalidOperationException, ServiceException; + + /** + * Get all available vehicles, sorted by how well they fit to the given opCode, starting with + * the best fitting. + * + * @param opCode the operation code that is used to determine the ranking + * @return a sorted list containing all available vehicles + * @throws InvalidOperationException if the opCode is invalid + * @throws ServiceException if loading the stored vehicles failed + */ + SortedSet rankVehicles(String opCode) + throws InvalidOperationException, ServiceException; + + /** + * Get all stored operations with matching status. + * + * @param statuses set containing all statuses that should be matched + * @return list containing all matched operations + * @throws ServiceException if loading the stored operations failed + */ + Set list(EnumSet statuses) throws ServiceException; +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationServiceImpl.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationServiceImpl.java new file mode 100644 index 0000000..baae598 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/OperationServiceImpl.java @@ -0,0 +1,286 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.OperationDAO; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.VehicleDAO; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Severity; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Operation.Status; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.VehicleType; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidOperationException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import java.time.Instant; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +@Service +public class OperationServiceImpl implements OperationService { + + private static final Logger LOG = LoggerFactory.getLogger(OperationServiceImpl.class); + + private final OperationDAO operationDAO; + private final VehicleDAO vehicleDAO; + private final VehicleService vehicleService; + + public OperationServiceImpl( + OperationDAO operationDAO, VehicleDAO vehicleDAO, VehicleService vehicleService) { + this.operationDAO = operationDAO; + this.vehicleDAO = vehicleDAO; + this.vehicleService = vehicleService; + } + + @Override + public long add(Operation o) throws InvalidOperationException, ServiceException { + if (o.created() != null) { + throw new InvalidOperationException("Erstellungszeitpunkt darf nicht gesetzt sein"); + } + + if (o.severity() != null) { + throw new InvalidOperationException("Der Schweregrad darf nicht gesetzt sein"); + } + + if (o.id() != 0) { + throw new InvalidOperationException("Einsatz-ID muss 0 sein"); + } + + if (o.status() != Status.ACTIVE) + LOG.info("Status was set but will be overridden"); // TODO: nullable instead?? + + try { + for (long id : (Iterable) o.vehicles().stream().map(Vehicle::id)::iterator) { + Vehicle v = vehicleDAO.get(id); + VehicleServiceImpl.validateVehicle(v); + + if (v.status() != Vehicle.Status.FREI_FUNK + && v.status() != Vehicle.Status.FREI_WACHE) + throw new InvalidOperationException("Fahrzeug nicht verfügbar: " + v.status()); + } + + validateOperation(o); + + return operationDAO.add( + o.toBuilder() + .created(Instant.now()) + .severity(extractSeverityFromOpCode(o.opCode())) + .status(Status.ACTIVE) + .build()); + } catch (PersistenceException e) { + throw new ServiceException(e); + } catch (InvalidVehicleException e) { + // already logged as invalid vehicle + throw new InvalidOperationException("Enthaltenes Fahrzeug ist ungültig", e); + } catch (ElementNotFoundException e) { + throw new InvalidOperationException("Enthaltenes Fahrzeug existiert nicht", e); + } + } + + @Override + public void requestVehicles(long operationId, Set vehicleIds) + throws InvalidOperationException, InvalidVehicleException, ServiceException { + Set vs = new HashSet<>(); + + try { + if (operationId <= 0) { + throw new InvalidOperationException("Einsatz-ID ist ungültig"); + } + Operation o = operationDAO.get(operationId); + validateOperation(o); + + if (o.opCode().trim().isEmpty() + || extractSeverityFromOpCode(o.opCode()) != o.severity()) { + throw new InvalidOperationException("Einsatzcode ist ungültig"); + } + + if (o.status() != Status.ACTIVE) { + throw new InvalidOperationException("Einsatz ist ungültig"); + } + + if (o.created() == null) { + throw new InvalidOperationException("Erstellungszeitpunkt darf nicht leer sein"); + } + + for (Long id : vehicleIds) { + if (id <= 0) { + throw new InvalidVehicleException("Fahrzeug-ID ist ungültig"); + } + + try { + Vehicle v = vehicleDAO.get(id); + VehicleServiceImpl.validateVehicle(v); + if (v.status() != Vehicle.Status.FREI_FUNK + && v.status() != Vehicle.Status.FREI_WACHE) + throw new InvalidOperationException( + "Fahrzeug nicht verfügbar: " + v.status()); + + vs.add(v); + } catch (ElementNotFoundException e) { + throw new InvalidVehicleException("VehicleId ist invalid"); + } + } + + vs.addAll(o.vehicles()); + if (vs.equals(o.vehicles())) return; + + operationDAO.update(o.toBuilder().vehicles(vs).build()); + } catch (ElementNotFoundException e) { + throw new InvalidOperationException("Kein Einsatz mit dieser ID existiert"); + } catch (PersistenceException e) { + throw new ServiceException(e); + } + } + + @Override + public void complete(long operationId, Status status) + throws InvalidOperationException, ServiceException { + try { + Operation o = operationDAO.get(operationId); + operationDAO.update(o.toBuilder().status(status).build()); + } catch (ElementNotFoundException e) { + throw new InvalidOperationException(e); + } catch (PersistenceException e) { + throw new ServiceException(e); + } + } + + @Override + public SortedSet rankVehicles(String opCode) + throws InvalidOperationException, ServiceException { + Set vehicles = + vehicleService.list(EnumSet.complementOf(EnumSet.of(Vehicle.Status.ABGEMELDET))); + + List> priorities = new ArrayList<>(); + Predicate ktw = v -> v.type() == VehicleType.KTW; + Predicate rtwNoNEF = v -> v.type() == VehicleType.RTW && !v.hasNef(); + Predicate rtwNEF = v -> v.type() == VehicleType.RTW && v.hasNef(); + Predicate nef = v -> v.type() == VehicleType.NEF; + Predicate nah = v -> v.type() == VehicleType.NAH; + + switch (extractSeverityFromOpCode(opCode)) { + case A: + // fallthrough + case B: + // fallthrough + case O: + priorities.add(ktw); + priorities.add(rtwNoNEF); + priorities.add(rtwNEF); + break; + case C: + priorities.add(rtwNEF); + priorities.add(rtwNoNEF); + priorities.add(ktw); + break; + case D: + priorities.add(rtwNEF); + priorities.add(nef); + priorities.add(nah); + priorities.add(rtwNoNEF); + priorities.add(ktw); + break; + case E: + priorities.add(nah); + priorities.add(nef); + priorities.add(rtwNEF); + priorities.add(rtwNoNEF); + priorities.add(ktw); + break; + } + + Comparator vehicleComparator = + (v1, v2) -> { + for (Predicate priority : priorities) { + if (priority.test(v1)) { + return -1; + } + if (priority.test(v2)) { + return +1; + } + } + return 0; + }; + + Supplier> supplier = () -> new TreeSet<>(vehicleComparator); + + return vehicles.stream().collect(Collectors.toCollection(supplier)); + } + + @Override + public Set list(EnumSet statuses) throws ServiceException { + try { + Set operations = operationDAO.list(statuses); + for (Operation o : operations) validateOperation(o); + + return operations; + } catch (PersistenceException e) { + throw new ServiceException(e); + } catch (InvalidOperationException e) { + // database returned invalid values + throw new ServiceException("DB returned invalid operation", e); + } + } + + private static void validateOperation(Operation o) throws InvalidOperationException { + if (o.vehicles().isEmpty()) { + throw new InvalidOperationException( + "Es muss mindestens ein Fahrzeug ausgewählt werden!"); + } + + for (Vehicle v : o.vehicles()) { + try { + VehicleServiceImpl.validateVehicle(v); + } catch (InvalidVehicleException e) { + throw new InvalidOperationException("Fahrzeug " + v.name() + " ist ungültig", e); + } + + // TODO: validate if NEF/RTW/NAH conditions? + } + + Instant created = o.created(); + if (created != null && created.isAfter(Instant.now())) { + throw new InvalidOperationException("Einsatz wurde in der Zukunft erstellt"); + } + + if (o.destination() == null || o.destination().trim().isEmpty()) { + throw new InvalidOperationException("Adresse darf nicht leer sein"); + } + + if (o.destination().length() > 100) { + throw new InvalidOperationException("Adresse darf 100 Zeichen nicht überschreiten"); + } + + if (o.additionalInfo() != null && o.additionalInfo().length() > 100) { + throw new InvalidOperationException("Anmerkung darf 100 Zeichen nicht überschreiten"); + } + } + + private static final Pattern opCodePattern = + Pattern.compile("(?:\\w{1,3}-\\d{0,2})([ABCDEO])(?:.*)"); + + private static Severity extractSeverityFromOpCode(String opCode) + throws InvalidOperationException { + Matcher m = opCodePattern.matcher(opCode); + + if (!m.matches()) { + throw new InvalidOperationException("Einsatzcode ist ungültig"); + } + + return Severity.valueOf(m.group(1)); + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationService.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationService.java new file mode 100644 index 0000000..027417f --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationService.java @@ -0,0 +1,32 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidRegistrationException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import java.util.Set; + +public interface RegistrationService { + + /** + * Register employee to a vehicle. + * + * @param vehicleId the id of the target vehicle + * @param registrations that should be added to the vehicle + * @return the list of ids that were assigned + * @throws InvalidVehicleException if the vehicleId is invalid or does not exist + * @throws InvalidRegistrationException if the registration is invalid + * @throws ServiceException if the registration could not be persisted + */ + Set add(long vehicleId, Set registrations) + throws InvalidVehicleException, InvalidRegistrationException, ServiceException; + + /** + * Remove given registration from the store. + * + * @param registrationId the id of the registration that should be removed + * @throws InvalidRegistrationException if the registration is invalid or does not exist + * @throws ServiceException if the registration could not be removed from the store + */ + void remove(long registrationId) throws InvalidRegistrationException, ServiceException; +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationServiceImpl.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationServiceImpl.java new file mode 100644 index 0000000..3ec69e7 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/RegistrationServiceImpl.java @@ -0,0 +1,52 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.RegistrationDAO; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.VehicleDAO; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Registration; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.RegistrationValidator; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidRegistrationException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import java.util.Set; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class RegistrationServiceImpl implements RegistrationService { + + private final RegistrationDAO registrationDAO; + private final VehicleDAO vehicleDAO; + + @Autowired + public RegistrationServiceImpl(RegistrationDAO registrationDAO, VehicleDAO vehicleDAO) { + this.registrationDAO = registrationDAO; + this.vehicleDAO = vehicleDAO; + } + + @Override + public Set add(long vehicleId, Set registrations) + throws InvalidVehicleException, InvalidRegistrationException, ServiceException { + + if (vehicleId <= 0) throw new InvalidVehicleException("VehicleId invalid"); + + try { + Vehicle vehicle = vehicleDAO.get(vehicleId); + + RegistrationValidator.validate(vehicle, registrations); + + return registrationDAO.add(vehicle.id(), registrations); + } catch (PersistenceException e) { + throw new ServiceException(e); + } catch (ElementNotFoundException e) { + throw new InvalidVehicleException(e); + } + } + + @Override + public void remove(long registrationId) throws InvalidRegistrationException, ServiceException { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/VehicleService.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/VehicleService.java new file mode 100644 index 0000000..d96dfb7 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/VehicleService.java @@ -0,0 +1,49 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.Status; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import java.util.EnumSet; +import java.util.Set; + +public interface VehicleService { + + /** + * Add given vehicle to the store. + * + * @param vehicle that should be added to the store + * @return the id that was assigned + * @throws InvalidVehicleException if the vehicle is invalid + * @throws ServiceException if the vehicle could not be persisted + */ + long add(Vehicle vehicle) throws InvalidVehicleException, ServiceException; + + /** + * Update the given vehicle. + * + * @param vehicle that should be updated + * @return the updated vehicle + * @throws InvalidVehicleException if the vehicle is invalid + * @throws ServiceException if the updated vehicle could not be persisted + */ + Vehicle update(Vehicle vehicle) throws InvalidVehicleException, ServiceException; + + /** + * Get all stored vehicles with matching status. + * + * @param statuses set containing all statuses that should be matched + * @return list containing all stored vehicles + * @throws ServiceException if loading the stored vehicles failed + */ + Set list(EnumSet statuses) throws ServiceException; + + /** + * Remove vehicle with the given id from the store. + * + * @param id of the vehicle that should be removed + * @throws InvalidVehicleException if given vehicle id is invalid or does not exist + * @throws ServiceException if the vehicle could not be removed from the store + */ + void remove(long id) throws InvalidVehicleException, ServiceException; +} diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/VehicleServiceImpl.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/VehicleServiceImpl.java new file mode 100644 index 0000000..6a035c6 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/missioncontrol/service/VehicleServiceImpl.java @@ -0,0 +1,116 @@ +package at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.service; + +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dao.VehicleDAO; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.ConstructionType; +import at.ac.tuwien.sepm.assignment.groupphase.missioncontrol.dto.Vehicle.Status; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ElementNotFoundException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.InvalidVehicleException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.PersistenceException; +import at.ac.tuwien.sepm.assignment.groupphase.exception.ServiceException; +import java.util.EnumSet; +import java.util.Set; +import java.util.stream.Collectors; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +@Service +public class VehicleServiceImpl implements VehicleService { + + private VehicleDAO vehiclePersistence; + + public VehicleServiceImpl(VehicleDAO vehiclePersistence) { + this.vehiclePersistence = vehiclePersistence; + } + + public long add(Vehicle vehicle) throws InvalidVehicleException, ServiceException { + if (!CollectionUtils.isEmpty(vehicle.registrations())) { + throw new InvalidVehicleException( + "Fahrzeug kann nicht mit Anmeldungen erstellt werden"); + } + + validateVehicle(vehicle); + try { + vehiclePersistence.add(vehicle); + } catch (PersistenceException e) { + throw new ServiceException(e); + } + return 0; + } + + public Vehicle update(Vehicle vehicle) throws InvalidVehicleException, ServiceException { + validateVehicle(vehicle); + try { + vehiclePersistence.update(vehicle); + } catch (ElementNotFoundException e) { + throw new ServiceException("Element not found", e); + } catch (PersistenceException e) { + throw new ServiceException(e); + } + return vehicle; + } + + protected static void validateVehicle(Vehicle vehicle) throws InvalidVehicleException { + switch (vehicle.type()) { + case RTW: + if (vehicle.constructionType() == ConstructionType.NORMAL) { + throw new InvalidVehicleException("RTW darf kein Normales Dach haben"); + } else if (vehicle.constructionType() == ConstructionType.MITTELHOCHDACH) { + throw new InvalidVehicleException("RTW darf kein Mittelhochdach haben"); + } + break; + case KTW: + if (vehicle.constructionType() == ConstructionType.NORMAL) { + throw new InvalidVehicleException("KTW darf kein Normales Dach haben"); + } + break; + case KTW_B: + if (vehicle.constructionType() == ConstructionType.NORMAL) { + throw new InvalidVehicleException("KTW-B darf kein Normales Dach haben"); + } + break; + case NEF: + if (vehicle.constructionType() == ConstructionType.MITTELHOCHDACH) { + throw new InvalidVehicleException("NEF darf kein Mittelhochdach haben"); + } else if (vehicle.constructionType() == ConstructionType.HOCHDACH) { + throw new InvalidVehicleException("NEF darf kein Hochdach haben"); + } + break; + case NAH: + if (vehicle.constructionType() == ConstructionType.MITTELHOCHDACH) { + throw new InvalidVehicleException("NEF darf kein Mittelhochdach haben"); + } else if (vehicle.constructionType() == ConstructionType.HOCHDACH) { + throw new InvalidVehicleException("NEF darf kein Hochdach haben"); + } + break; + case BKTW: + break; + default: + throw new IllegalStateException("BUG: invalid vehicle type" + vehicle.type()); + } + } + + @Override + public Set list(EnumSet statuses) throws ServiceException { + if (statuses == null) { + throw new ServiceException("Statuses may not be null"); + } + + Set vehicles; + + try { + vehicles = vehiclePersistence.list(); + } catch (PersistenceException e) { + throw new ServiceException(e); + } + + return vehicles.stream() + .filter(vehicle -> statuses.contains(vehicle.status())) + .collect(Collectors.toSet()); + } + + @Override + public void remove(long id) throws InvalidVehicleException, ServiceException { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/resources/fxml/ArchiveOperation.fxml b/src/main/resources/fxml/ArchiveOperation.fxml index 0150d81..e9549ae 100644 --- a/src/main/resources/fxml/ArchiveOperation.fxml +++ b/src/main/resources/fxml/ArchiveOperation.fxml @@ -12,7 +12,7 @@ - + diff --git a/src/main/resources/fxml/CreateOperationController.fxml b/src/main/resources/fxml/CreateOperationController.fxml index 0c82e29..56e0c90 100644 --- a/src/main/resources/fxml/CreateOperationController.fxml +++ b/src/main/resources/fxml/CreateOperationController.fxml @@ -14,7 +14,7 @@ - +