From 3e46b43f51cb632bccd3f7d5e69355e1c69f53f0 Mon Sep 17 00:00:00 2001
From: Tharre <tharre3@gmail.com>
Date: Thu, 24 May 2018 17:12:21 +0200
Subject: Change package structure/naming #25963

---
 .../groupphase/application/MainApplication.java    |   2 +-
 .../controller/ArchiveOperationController.java     | 127 +++++++
 .../controller/CreateOperationController.java      | 365 ++++++++++++++++++++
 .../controller/OperationDetailsController.java     | 162 +++++++++
 .../controller/VehiclePaneController.java          | 113 +++++++
 .../einsatzverwaltung/dao/DBOperationDAO.java      | 217 ------------
 .../einsatzverwaltung/dao/EmployeeDatabaseDAO.java | 196 +++++++++++
 .../einsatzverwaltung/dao/EmployeeDatabaseDao.java | 196 -----------
 .../dao/OperationDatabaseDAO.java                  | 218 ++++++++++++
 .../einsatzverwaltung/dao/VehicleDatabaseDAO.java  | 220 +++++++++++++
 .../einsatzverwaltung/dao/VehicleDatabaseDao.java  | 220 -------------
 .../ui/vehiclepane/VehiclePaneController.java      | 113 -------
 .../userInterface/ArchiveOperationController.java  | 127 -------
 .../userInterface/CreateOperationController.java   | 366 ---------------------
 .../userInterface/OperationDetailsController.java  | 162 ---------
 15 files changed, 1402 insertions(+), 1402 deletions(-)
 create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/ArchiveOperationController.java
 create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateOperationController.java
 create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/OperationDetailsController.java
 create 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/DBOperationDAO.java
 create 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/EmployeeDatabaseDao.java
 create mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDatabaseDAO.java
 create 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/dao/VehicleDatabaseDao.java
 delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/ui/vehiclepane/VehiclePaneController.java
 delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/userInterface/ArchiveOperationController.java
 delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/userInterface/CreateOperationController.java
 delete mode 100644 src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/userInterface/OperationDetailsController.java

(limited to 'src/main/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 01c04d3..d8365a7 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.userInterface.CreateOperationController;
+import at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.controller.CreateOperationController;
 import at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader;
 import javafx.application.Application;
 import javafx.application.Platform;
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
new file mode 100644
index 0000000..80d9fc4
--- /dev/null
+++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/ArchiveOperationController.java
@@ -0,0 +1,127 @@
+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.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 java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.LinkedList;
+import java.util.Objects;
+import java.util.stream.Collectors;
+import javafx.fxml.FXML;
+import javafx.scene.control.Alert;
+import javafx.scene.control.Alert.AlertType;
+import javafx.scene.control.Button;
+import javafx.scene.control.Hyperlink;
+import javafx.scene.control.Label;
+import javafx.scene.layout.AnchorPane;
+import javafx.scene.layout.FlowPane;
+import org.springframework.stereotype.Controller;
+
+@Controller
+public class ArchiveOperationController {
+    @FXML private AnchorPane apDetails;
+    @FXML private Label lblCodeHeader;
+    @FXML private Hyperlink hypBack;
+    @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 LinkedList<Operation> list = new LinkedList<>();
+
+    public ArchiveOperationController(OperationService operationService) {
+        this.operationService = operationService;
+    }
+
+    @FXML
+    private void initialize() {
+        try {
+            list.addAll(operationService.list(EnumSet.of(Status.CANCELLED, Status.COMPLETED)));
+        } catch (ServiceException e) {
+            Alert alert = new Alert(AlertType.ERROR);
+            alert.setTitle("Fehler");
+            alert.setHeaderText("Fehler!");
+            alert.setContentText("Die Einsätze konnten nicht geladen werden!");
+            alert.showAndWait();
+        }
+        for (Operation operation : list) {
+            Button b = new Button();
+            b.setPrefHeight(200);
+            b.setPrefWidth(750 / 2);
+            b.setText(operation.opCode());
+            b.setOnAction(event -> buttonClicked(b));
+            archiveOperationFlowPane.getChildren().add(b);
+        }
+    }
+
+    private Operation detailOperation;
+
+    private void buttonClicked(Button button) {
+        int size = archiveOperationFlowPane.getChildren().size();
+        int index = 0;
+        for (int i = 0; i < size; i++) {
+            if (archiveOperationFlowPane.getChildren().get(i) == button) {
+                index = i;
+                break;
+            }
+        }
+        detailOperation = list.get(index);
+        setOperation();
+        setDetailsVisible(true);
+    }
+
+    private void setOperation() {
+        lblCodeHeader.setText(detailOperation.opCode());
+        String date = "am ";
+        if (detailOperation.created() != null) {
+            LocalDateTime myDateTime =
+                    LocalDateTime.ofInstant(
+                            Objects.requireNonNull(detailOperation.created()), ZoneOffset.UTC);
+            date +=
+                    myDateTime.getDayOfMonth()
+                            + "."
+                            + myDateTime.getMonth().getValue()
+                            + "."
+                            + myDateTime.getYear();
+            lblDate.setText(date);
+        } else {
+            lblDate.setText("---");
+        }
+
+        lblOpCode.setText(detailOperation.opCode());
+        Collection<String> elements =
+                detailOperation.vehicles().stream().map(Vehicle::name).collect(Collectors.toList());
+        String result = String.join(", ", elements);
+
+        lblVehicles.setText(result);
+        lblAddress.setText(detailOperation.destination());
+
+        for (Vehicle vehicle : detailOperation.vehicles()) {
+            Button b = new Button();
+            b.setPrefHeight(200);
+            b.setPrefWidth(600 / 2);
+            b.setText(vehicle.name());
+            fpVehicles.getChildren().add(b);
+        }
+    }
+
+    public void setListVisible(boolean b) {
+        archiveOperationFlowPane.setVisible(b);
+    }
+
+    private void setDetailsVisible(boolean b) {
+        apDetails.setVisible(b);
+    }
+
+    public void backClicked() {
+        fpVehicles.getChildren().clear();
+        setDetailsVisible(false);
+    }
+}
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
new file mode 100644
index 0000000..57759e3
--- /dev/null
+++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/CreateOperationController.java
@@ -0,0 +1,365 @@
+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.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 at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader;
+import java.io.IOException;
+import java.lang.invoke.MethodHandles;
+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.event.ActionEvent;
+import javafx.fxml.FXML;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.Alert;
+import javafx.scene.control.Alert.AlertType;
+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.stage.Stage;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Controller;
+
+@Controller
+public class CreateOperationController {
+
+    private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+    public AnchorPane apCreateOperation;
+    @FXML private TextField txtCode;
+    @FXML private TextField txtAddress;
+    @FXML private TextField txtNote;
+    @FXML private Button btnCreateOperation;
+    @FXML private ListView<Vehicle> lvVehicles;
+    @FXML private ListView<Operation> lvActiveOperations;
+    @FXML private Label lblChosenVehicles;
+    @FXML private AnchorPane apInvisible;
+    @FXML private OperationDetailsController operationDetailsController;
+    @FXML private FlowPane fpVehicles;
+
+    private LinkedList<Vehicle> chosenVehicles = new LinkedList<>();
+
+    private final OperationService operationService;
+    private final VehicleService vehicleService;
+    private final SpringFXMLLoader fxmlLoader;
+
+    public CreateOperationController(
+            OperationService operationService,
+            VehicleService vehicleService,
+            SpringFXMLLoader fxmlLoader) {
+        this.operationService = operationService;
+        this.vehicleService = vehicleService;
+        this.fxmlLoader = fxmlLoader;
+    }
+
+    @FXML
+    private void initialize() {
+        lblChosenVehicles.setText("keine ausgewählt");
+        lvActiveOperations.setCellFactory(
+                param ->
+                        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());
+                                }
+                            }
+                        });
+        lvActiveOperations.setOnMouseClicked(
+                event -> {
+                    if (event.getClickCount() == 2) {
+                        if (lvActiveOperations.getSelectionModel().getSelectedItem() == null) {
+                            return;
+                        }
+                        openDetailsWindow(lvActiveOperations.getSelectionModel().getSelectedItem());
+                    }
+                });
+    }
+
+    public void updateList() {
+        try {
+            fpVehicles.getChildren().clear();
+
+            // TODO: this should probably be handled differently
+            Set<Vehicle> 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);
+                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());
+                                        }
+                                    }
+                                });
+
+                fpVehicles.getChildren().add(controller.getRootElement());
+            }
+        } catch (ServiceException | IOException | InvalidOperationException e) {
+            LOG.error("Error while updating list.", e);
+
+            Alert alert = new Alert(Alert.AlertType.ERROR);
+            alert.setTitle("Fehler");
+            alert.setHeaderText("Fehler!");
+            alert.setContentText(e.getMessage());
+            alert.showAndWait();
+        }
+        try {
+            lvActiveOperations.setItems(
+                    FXCollections.observableArrayList(
+                            operationService.list(EnumSet.of(Status.ACTIVE))));
+        } catch (ServiceException e) {
+            Alert alert = new Alert(Alert.AlertType.ERROR);
+            alert.setTitle("Fehler - Einsätze");
+            alert.setHeaderText("Beim Holen der aktiven Einsätze ist ein Fehler aufgetreten.");
+            alert.setContentText(e.getMessage());
+            alert.showAndWait();
+        }
+    }
+
+    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 | ServiceException e) {
+                            LOG.error("Error while setting status.", e);
+                            Alert a = new Alert(AlertType.ERROR, e.getMessage());
+                            a.show();
+                        }
+                    });
+
+            menu.getItems().add(mi);
+        }
+
+        MenuItem abmelden = new MenuItem("abmelden");
+
+        abmelden.setOnAction(
+                event -> {
+                    try {
+                        List<Registration> registrations = data.registrations();
+                        assert registrations
+                                != null; // Otherwise the element shouldn't be in the list.
+
+                        List<Registration> 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 | ServiceException e) {
+                        LOG.error("Error while unregistering.", e);
+                        Alert a = new Alert(AlertType.ERROR, e.getMessage());
+                        a.show();
+                    }
+                });
+
+        menu.getItems().add(abmelden);
+        return menu;
+    }
+
+    @FXML
+    protected void createOperationClicked() {
+        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 | InvalidOperationException e) {
+            Alert alert = new Alert(Alert.AlertType.ERROR);
+            alert.setTitle("Fehler");
+            alert.setHeaderText("Fehler!");
+            alert.setContentText(e.getMessage());
+            alert.showAndWait();
+            return;
+        }
+        Alert alert = new Alert(AlertType.CONFIRMATION);
+        alert.setTitle("Erfolg");
+        alert.setHeaderText("Erfolgreich gespeichert");
+        alert.setContentText("Der Einsatz wurde erfolgreich gespeichert.");
+        alert.showAndWait();
+        updateList();
+        lblChosenVehicles.setText("keine ausgewählt");
+        txtAddress.setText("");
+        txtCode.setText("");
+        txtNote.setText("");
+        chosenVehicles = new LinkedList<>();
+    }
+
+    public void onRegistrationLinkClicked(ActionEvent actionEvent) {
+        openNewWindow("RegistrationWindow.fxml");
+    }
+
+    public void onEmployeeLinkClicked(ActionEvent actionEvent) {
+        openNewWindow("listEmployees.fxml");
+    }
+
+    public void onVehicleLinkClicked(ActionEvent actionEvent) {
+        openNewWindow("createCar.fxml");
+    }
+
+    public void onArchivLinkClicked() {
+        openNewArchivWindow();
+    }
+
+    private void openNewArchivWindow() {
+        Stage stage = new Stage();
+        try {
+            stage.setScene(
+                    new Scene(
+                            (Parent)
+                                    fxmlLoader.load(
+                                            getClass()
+                                                    .getResourceAsStream(
+                                                            "/fxml/ArchiveOperation.fxml"))));
+        } catch (IOException e) {
+            LOG.error("Could not open new window: {}", e);
+        }
+        stage.setTitle("Einsatz erstellen");
+        stage.centerOnScreen();
+        stage.show();
+        updateList();
+    }
+
+    private void openNewWindow(String fxmlFileName) {
+
+        Stage stage = new Stage();
+        try {
+            stage.setScene(
+                    new Scene(
+                            (Parent)
+                                    fxmlLoader.load(
+                                            getClass()
+                                                    .getResourceAsStream(
+                                                            "/fxml/" + fxmlFileName))));
+        } catch (IOException e) {
+            LOG.error("Could not open new window: {}", e);
+        }
+
+        stage.setTitle("Ressourcenverwaltung");
+        stage.centerOnScreen();
+        stage.showAndWait(); // important to call wait so that updateList is executed afterwards
+
+        updateList();
+    }
+
+    void setVisible(boolean b) {
+        apInvisible.setVisible(!b);
+    }
+
+    private void openDetailsWindow(Operation operation) {
+        operationDetailsController.initOperation(operation);
+        this.setVisible(false);
+    }
+
+    @FXML
+    public void onOperationCodeChanged(KeyEvent keyEvent) {
+        if (keyEvent.getCode() == KeyCode.ENTER) {
+            updateList();
+        }
+    }
+}
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
new file mode 100644
index 0000000..dc7e969
--- /dev/null
+++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/OperationDetailsController.java
@@ -0,0 +1,162 @@
+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.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.ServiceException;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.stream.Collectors;
+import javafx.collections.FXCollections;
+import javafx.fxml.FXML;
+import javafx.scene.control.Alert;
+import javafx.scene.control.Alert.AlertType;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.control.ListCell;
+import javafx.scene.control.ListView;
+import javafx.scene.layout.AnchorPane;
+import org.springframework.stereotype.Controller;
+
+@Controller
+public class OperationDetailsController {
+
+    public Operation operation;
+    private final OperationService operationService;
+    private final VehicleService vehicleService;
+    private final CreateOperationController createOperationController;
+    @FXML private ListView<Vehicle> lvVehicles;
+    @FXML private ListView<Operation> 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() {
+        lvVehicles.setCellFactory(
+                param ->
+                        new ListCell<>() {
+                            @Override
+                            protected void updateItem(Vehicle item, boolean empty) {
+                                super.updateItem(item, empty);
+
+                                if (empty || item == null || item.name() == null) {
+                                    setText(null);
+                                } else {
+                                    setText(item.name());
+                                }
+                            }
+                        });
+        lvActiveOperations.setCellFactory(
+                param ->
+                        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());
+                                }
+                            }
+                        });
+        lvActiveOperations.setOnMouseClicked(
+                event -> {
+                    if (event.getClickCount() == 2) {
+                        if (lvActiveOperations.getSelectionModel().getSelectedItem() == null) {
+                            return;
+                        }
+                        initOperation(lvActiveOperations.getSelectionModel().getSelectedItem());
+                    }
+                });
+    }
+
+    void initOperation(Operation operation) {
+        fillActiveList();
+        this.operation = operation;
+        lblCode.setText(operation.opCode());
+        Collection<String> 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());
+        lvVehicles.setItems(FXCollections.observableArrayList(operation.vehicles()));
+        operationDetailsAP.setVisible(true);
+    }
+
+    private void fillActiveList() {
+        try {
+            lvActiveOperations.setItems(
+                    FXCollections.observableArrayList(
+                            operationService.list(EnumSet.of(Status.ACTIVE))));
+        } catch (ServiceException e) {
+            Alert alert = new Alert(AlertType.ERROR);
+            alert.setTitle("Fehler");
+            alert.setHeaderText("Fehler!");
+            alert.setContentText(e.getMessage());
+            alert.showAndWait();
+        }
+    }
+
+    @FXML
+    public void closeOperationClicked() {
+        try {
+            operationService.complete(operation.id(), Status.COMPLETED);
+        } catch (InvalidOperationException | ServiceException e) {
+            Alert alert = new Alert(AlertType.ERROR);
+            alert.setTitle("Fehler");
+            alert.setHeaderText("Fehler!");
+            alert.setContentText(e.getMessage());
+            alert.showAndWait();
+            return;
+        }
+        Alert alert = new Alert(AlertType.CONFIRMATION);
+        alert.setTitle("Erfolg");
+        alert.setHeaderText("Erfolgreich aktualisiert");
+        alert.setContentText("Der Einsatz wurde erfolgreich aktualisiert.");
+        alert.showAndWait();
+        closeWindow();
+        createOperationController.updateList();
+    }
+
+    public void cancelOperationClicked() {
+        try {
+            operationService.complete(operation.id(), Status.CANCELLED);
+        } catch (InvalidOperationException | ServiceException e) {
+            Alert alert = new Alert(AlertType.ERROR);
+            alert.setTitle("Fehler");
+            alert.setHeaderText("Fehler!");
+            alert.setContentText(e.getMessage());
+            alert.showAndWait();
+            return;
+        }
+        Alert alert = new Alert(AlertType.CONFIRMATION);
+        alert.setTitle("Erfolg");
+        alert.setHeaderText("Erfolgreich aktualisiert");
+        alert.setContentText("Der Einsatz wurde erfolgreich aktualisiert.");
+        alert.showAndWait();
+        closeWindow();
+        createOperationController.updateList();
+    }
+
+    public void closeWindow() {
+        operationDetailsAP.setVisible(false);
+        this.createOperationController.setVisible(true);
+    }
+}
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
new file mode 100644
index 0000000..6c0932b
--- /dev/null
+++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/controller/VehiclePaneController.java
@@ -0,0 +1,113 @@
+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 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.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.text.Text;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class VehiclePaneController {
+
+    private static Logger LOG = LoggerFactory.getLogger(VehiclePaneController.class);
+
+    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 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;
+
+    private Node rootElement;
+    private Vehicle data;
+
+    public Node getRootElement() {
+        return rootElement;
+    }
+
+    public Vehicle getData() {
+        return data;
+    }
+
+    /**
+     * * Set the displayed data of this VehiclePane.
+     *
+     * @param vehicle The data to display.
+     * @param showQualification If true, the most recent registration of vehicle will be searched
+     *     for the highest qualification.
+     */
+    public void setData(Vehicle vehicle, boolean showQualification) {
+        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 (showQualification) {
+
+            Instant now = Instant.now();
+            List<Registration> regs = vehicle.registrations();
+
+            if (regs == null) {
+                return;
+            }
+
+            Optional<EducationLevel> 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);
+        }
+
+        this.data = vehicle;
+    }
+
+    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/dao/DBOperationDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/DBOperationDAO.java
deleted file mode 100644
index 0bb25b8..0000000
--- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/DBOperationDAO.java
+++ /dev/null
@@ -1,217 +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.sql.Timestamp;
-import java.util.EnumSet;
-import java.util.HashSet;
-import java.util.Objects;
-import java.util.Set;
-import java.util.stream.Collectors;
-import org.springframework.lang.NonNull;
-import org.springframework.stereotype.Repository;
-
-@Repository
-public class DBOperationDAO implements OperationDAO {
-
-    private JDBCConnectionManager jdbcConnectionManager;
-    private VehicleDAO vehicleDAO;
-
-    public DBOperationDAO(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.setTimestamp(3, Timestamp.from(Objects.requireNonNull(o.created())));
-                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<Long>) o.vehicles().stream().map(Vehicle::id)::iterator) {
-                    pstmt.setLong(1, id);
-                    pstmt.addBatch();
-                }
-
-                pstmt.executeBatch();
-            }
-            con.commit();
-            con.setAutoCommit(true);
-            return operationId;
-        } catch (SQLException e) {
-            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<Long>) o.vehicles().stream().map(Vehicle::id)::iterator) {
-                    pstmt.setLong(1, id);
-                    pstmt.addBatch();
-                }
-
-                pstmt.executeBatch();
-            }
-            con.commit();
-            con.setAutoCommit(true);
-        } catch (SQLException e) {
-            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<Operation> list(EnumSet<Status> 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.
-        String str =
-                statuses.stream()
-                        .map(Enum::name)
-                        .map(s -> "'" + s + "'")
-                        .collect(Collectors.joining(","));
-        String sql = "SELECT * FROM Operation WHERE status IN (" + str + ")";
-        Set<Operation> 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.getTimestamp("created").toInstant())
-                .destination(rs.getString("destination"))
-                .additionalInfo(rs.getString("additionalInfo"))
-                .build();
-    }
-
-    private Set<Vehicle> getVehiclesFromOperationId(long operationId) throws PersistenceException {
-        String sql = "SELECT vehicleId FROM VehicleOperation WHERE operationId = ?";
-        Set<Vehicle> 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/EmployeeDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/EmployeeDatabaseDAO.java
new file mode 100644
index 0000000..fd0add7
--- /dev/null
+++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/EmployeeDatabaseDAO.java
@@ -0,0 +1,196 @@
+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.lang.invoke.MethodHandles;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Savepoint;
+import java.sql.Statement;
+import java.sql.Timestamp;
+import java.util.HashSet;
+import java.util.Set;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class EmployeeDatabaseDAO implements EmployeeDAO {
+
+    private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+    private static final String INSERT_EMPLOYEE_VERSION =
+            "INSERT INTO EmployeeVersion(name, birthday, educationLevel, isDriver, isPilot) "
+                    + "VALUES(?, ?, ?, ?, ?)";
+    private static final String INSERT_EMPLOYEE = "INSERT INTO Employee(version) VALUES(?)";
+    private static final String LIST_EMPLOYEE =
+            "SELECT emp.id, v.name, v.birthday, v.educationLevel, v.isDriver, v.isPilot "
+                    + "FROM employee emp "
+                    + "JOIN EmployeeVersion v ON v.id = emp.version";
+    private static final String UPDATE_EMPLOYEE = "UPDATE Employee SET version = ? WHERE id = ?";
+
+    private final PreparedStatement insertEmployeeVersion,
+            insertEmployee,
+            listEmployee,
+            updateEmployee;
+
+    private final Connection connection;
+
+    public EmployeeDatabaseDAO(JDBCConnectionManager connectionManager)
+            throws PersistenceException {
+
+        try {
+
+            connection = connectionManager.getConnection();
+            insertEmployeeVersion =
+                    connection.prepareStatement(
+                            INSERT_EMPLOYEE_VERSION, Statement.RETURN_GENERATED_KEYS);
+            insertEmployee =
+                    connection.prepareStatement(INSERT_EMPLOYEE, Statement.RETURN_GENERATED_KEYS);
+
+            listEmployee = connection.prepareStatement(LIST_EMPLOYEE);
+
+            updateEmployee = connection.prepareStatement(UPDATE_EMPLOYEE);
+
+        } catch (SQLException e) {
+            throw new PersistenceException(e);
+        }
+    }
+
+    @Override
+    public long add(Employee employee) throws PersistenceException {
+
+        // Assumption: the given employee is already validated (from service)
+        Savepoint savepoint = null;
+        try {
+            savepoint = connection.setSavepoint();
+            connection.setAutoCommit(false);
+            insertEmployeeVersion.setString(1, employee.name());
+            insertEmployeeVersion.setTimestamp(
+                    2, Timestamp.valueOf(employee.birthday().atStartOfDay()));
+            insertEmployeeVersion.setString(3, employee.educationLevel().toString());
+            insertEmployeeVersion.setBoolean(4, employee.isDriver());
+            insertEmployeeVersion.setBoolean(5, employee.isPilot());
+            insertEmployeeVersion.executeUpdate();
+            ResultSet resultSetEmployeeVersion = insertEmployeeVersion.getGeneratedKeys();
+            if (resultSetEmployeeVersion.next()) {
+                long versionId = resultSetEmployeeVersion.getLong(1);
+
+                insertEmployee.setLong(1, versionId);
+                insertEmployee.executeUpdate();
+
+                ResultSet resultSetEmployee = insertEmployee.getGeneratedKeys();
+                if (resultSetEmployee.next()) {
+                    connection.commit();
+                    return resultSetEmployee.getLong(1);
+                }
+            }
+
+            throw new PersistenceException("Employee was not updated");
+
+        } catch (SQLException e) {
+            try {
+                if (savepoint != null) {
+                    connection.rollback(savepoint);
+                }
+            } catch (SQLException e1) {
+                throw new PersistenceException(e);
+            }
+            throw new PersistenceException(e);
+        } finally {
+            try {
+                connection.setAutoCommit(true);
+            } catch (SQLException e) {
+                throw new PersistenceException(e);
+            }
+        }
+    }
+
+    @Override
+    public void update(Employee employee) throws ElementNotFoundException, PersistenceException {
+
+        Savepoint savepoint = null;
+        try {
+            savepoint = connection.setSavepoint();
+            connection.setAutoCommit(false);
+
+            insertEmployeeVersion.setString(1, employee.name());
+            insertEmployeeVersion.setTimestamp(
+                    2, Timestamp.valueOf(employee.birthday().atStartOfDay()));
+            insertEmployeeVersion.setString(3, employee.educationLevel().toString());
+            insertEmployeeVersion.setBoolean(4, employee.isDriver());
+            insertEmployeeVersion.setBoolean(5, employee.isPilot());
+            insertEmployeeVersion.executeUpdate();
+            ResultSet resultSetEmployeeVersion = insertEmployeeVersion.getGeneratedKeys();
+
+            if (resultSetEmployeeVersion.next()) {
+                long versionId = resultSetEmployeeVersion.getLong(1);
+
+                updateEmployee.setLong(1, versionId);
+                updateEmployee.setLong(2, employee.id());
+                int affectedRows = updateEmployee.executeUpdate();
+
+                if (affectedRows == 1) {
+                    connection.commit();
+                } else {
+                    throw new ElementNotFoundException(
+                            "element not found with id: " + employee.id());
+                }
+            }
+
+        } catch (SQLException e) {
+            try {
+                if (savepoint != null) {
+                    connection.rollback(savepoint);
+                }
+            } catch (SQLException e1) {
+                throw new PersistenceException(e);
+            }
+            throw new PersistenceException(e);
+        } finally {
+            try {
+                connection.setAutoCommit(true);
+            } catch (SQLException e) {
+                throw new PersistenceException(e);
+            }
+        }
+    }
+
+    @Override
+    public Set<Employee> list() throws PersistenceException {
+
+        try {
+            ResultSet rs = listEmployee.executeQuery();
+
+            Set<Employee> employees = new HashSet<>();
+            while (rs.next()) {
+
+                Employee employee =
+                        Employee.builder()
+                                .id(rs.getLong(1))
+                                .name(rs.getString(2))
+                                .birthday(rs.getTimestamp(3).toLocalDateTime().toLocalDate())
+                                .educationLevel(EducationLevel.valueOf(rs.getString(4)))
+                                .isDriver(rs.getBoolean(5))
+                                .isPilot(rs.getBoolean(6))
+                                .build();
+
+                employees.add(employee);
+            }
+
+            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/EmployeeDatabaseDao.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/EmployeeDatabaseDao.java
deleted file mode 100644
index 40a9134..0000000
--- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/EmployeeDatabaseDao.java
+++ /dev/null
@@ -1,196 +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.lang.invoke.MethodHandles;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Savepoint;
-import java.sql.Statement;
-import java.sql.Timestamp;
-import java.util.HashSet;
-import java.util.Set;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Repository;
-
-@Repository
-public class EmployeeDatabaseDao implements EmployeeDAO {
-
-    private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-    private static final String INSERT_EMPLOYEE_VERSION =
-            "INSERT INTO EmployeeVersion(name, birthday, educationLevel, isDriver, isPilot) "
-                    + "VALUES(?, ?, ?, ?, ?)";
-    private static final String INSERT_EMPLOYEE = "INSERT INTO Employee(version) VALUES(?)";
-    private static final String LIST_EMPLOYEE =
-            "SELECT emp.id, v.name, v.birthday, v.educationLevel, v.isDriver, v.isPilot "
-                    + "FROM employee emp "
-                    + "JOIN EmployeeVersion v ON v.id = emp.version";
-    private static final String UPDATE_EMPLOYEE = "UPDATE Employee SET version = ? WHERE id = ?";
-
-    private final PreparedStatement insertEmployeeVersion,
-            insertEmployee,
-            listEmployee,
-            updateEmployee;
-
-    private final Connection connection;
-
-    public EmployeeDatabaseDao(JDBCConnectionManager connectionManager)
-            throws PersistenceException {
-
-        try {
-
-            connection = connectionManager.getConnection();
-            insertEmployeeVersion =
-                    connection.prepareStatement(
-                            INSERT_EMPLOYEE_VERSION, Statement.RETURN_GENERATED_KEYS);
-            insertEmployee =
-                    connection.prepareStatement(INSERT_EMPLOYEE, Statement.RETURN_GENERATED_KEYS);
-
-            listEmployee = connection.prepareStatement(LIST_EMPLOYEE);
-
-            updateEmployee = connection.prepareStatement(UPDATE_EMPLOYEE);
-
-        } catch (SQLException e) {
-            throw new PersistenceException(e);
-        }
-    }
-
-    @Override
-    public long add(Employee employee) throws PersistenceException {
-
-        // Assumption: the given employee is already validated (from service)
-        Savepoint savepoint = null;
-        try {
-            savepoint = connection.setSavepoint();
-            connection.setAutoCommit(false);
-            insertEmployeeVersion.setString(1, employee.name());
-            insertEmployeeVersion.setTimestamp(
-                    2, Timestamp.valueOf(employee.birthday().atStartOfDay()));
-            insertEmployeeVersion.setString(3, employee.educationLevel().toString());
-            insertEmployeeVersion.setBoolean(4, employee.isDriver());
-            insertEmployeeVersion.setBoolean(5, employee.isPilot());
-            insertEmployeeVersion.executeUpdate();
-            ResultSet resultSetEmployeeVersion = insertEmployeeVersion.getGeneratedKeys();
-            if (resultSetEmployeeVersion.next()) {
-                long versionId = resultSetEmployeeVersion.getLong(1);
-
-                insertEmployee.setLong(1, versionId);
-                insertEmployee.executeUpdate();
-
-                ResultSet resultSetEmployee = insertEmployee.getGeneratedKeys();
-                if (resultSetEmployee.next()) {
-                    connection.commit();
-                    return resultSetEmployee.getLong(1);
-                }
-            }
-
-            throw new PersistenceException("Employee was not updated");
-
-        } catch (SQLException e) {
-            try {
-                if (savepoint != null) {
-                    connection.rollback(savepoint);
-                }
-            } catch (SQLException e1) {
-                throw new PersistenceException(e);
-            }
-            throw new PersistenceException(e);
-        } finally {
-            try {
-                connection.setAutoCommit(true);
-            } catch (SQLException e) {
-                throw new PersistenceException(e);
-            }
-        }
-    }
-
-    @Override
-    public void update(Employee employee) throws ElementNotFoundException, PersistenceException {
-
-        Savepoint savepoint = null;
-        try {
-            savepoint = connection.setSavepoint();
-            connection.setAutoCommit(false);
-
-            insertEmployeeVersion.setString(1, employee.name());
-            insertEmployeeVersion.setTimestamp(
-                    2, Timestamp.valueOf(employee.birthday().atStartOfDay()));
-            insertEmployeeVersion.setString(3, employee.educationLevel().toString());
-            insertEmployeeVersion.setBoolean(4, employee.isDriver());
-            insertEmployeeVersion.setBoolean(5, employee.isPilot());
-            insertEmployeeVersion.executeUpdate();
-            ResultSet resultSetEmployeeVersion = insertEmployeeVersion.getGeneratedKeys();
-
-            if (resultSetEmployeeVersion.next()) {
-                long versionId = resultSetEmployeeVersion.getLong(1);
-
-                updateEmployee.setLong(1, versionId);
-                updateEmployee.setLong(2, employee.id());
-                int affectedRows = updateEmployee.executeUpdate();
-
-                if (affectedRows == 1) {
-                    connection.commit();
-                } else {
-                    throw new ElementNotFoundException(
-                            "element not found with id: " + employee.id());
-                }
-            }
-
-        } catch (SQLException e) {
-            try {
-                if (savepoint != null) {
-                    connection.rollback(savepoint);
-                }
-            } catch (SQLException e1) {
-                throw new PersistenceException(e);
-            }
-            throw new PersistenceException(e);
-        } finally {
-            try {
-                connection.setAutoCommit(true);
-            } catch (SQLException e) {
-                throw new PersistenceException(e);
-            }
-        }
-    }
-
-    @Override
-    public Set<Employee> list() throws PersistenceException {
-
-        try {
-            ResultSet rs = listEmployee.executeQuery();
-
-            Set<Employee> employees = new HashSet<>();
-            while (rs.next()) {
-
-                Employee employee =
-                        Employee.builder()
-                                .id(rs.getLong(1))
-                                .name(rs.getString(2))
-                                .birthday(rs.getTimestamp(3).toLocalDateTime().toLocalDate())
-                                .educationLevel(EducationLevel.valueOf(rs.getString(4)))
-                                .isDriver(rs.getBoolean(5))
-                                .isPilot(rs.getBoolean(6))
-                                .build();
-
-                employees.add(employee);
-            }
-
-            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/OperationDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDatabaseDAO.java
new file mode 100644
index 0000000..0a465f2
--- /dev/null
+++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/OperationDatabaseDAO.java
@@ -0,0 +1,218 @@
+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.sql.Timestamp;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.Objects;
+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.setTimestamp(3, Timestamp.from(Objects.requireNonNull(o.created())));
+                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<Long>) o.vehicles().stream().map(Vehicle::id)::iterator) {
+                    pstmt.setLong(1, id);
+                    pstmt.addBatch();
+                }
+
+                pstmt.executeBatch();
+            }
+            con.commit();
+            con.setAutoCommit(true);
+            return operationId;
+        } catch (SQLException e) {
+            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<Long>) o.vehicles().stream().map(Vehicle::id)::iterator) {
+                    pstmt.setLong(1, id);
+                    pstmt.addBatch();
+                }
+
+                pstmt.executeBatch();
+            }
+            con.commit();
+            con.setAutoCommit(true);
+        } catch (SQLException e) {
+            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<Operation> list(EnumSet<Status> 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.
+        String str =
+                statuses.stream()
+                        .map(Enum::name)
+                        .map(s -> "'" + s + "'")
+                        .collect(Collectors.joining(","));
+        String sql = "SELECT * FROM Operation WHERE status IN (" + str + ")";
+        Set<Operation> 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.getTimestamp("created").toInstant())
+                .destination(rs.getString("destination"))
+                .additionalInfo(rs.getString("additionalInfo"))
+                .build();
+    }
+
+    private Set<Vehicle> getVehiclesFromOperationId(long operationId) throws PersistenceException {
+        String sql = "SELECT vehicleId FROM VehicleOperation WHERE operationId = ?";
+        Set<Vehicle> 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/VehicleDatabaseDAO.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/VehicleDatabaseDAO.java
new file mode 100644
index 0000000..6d50588
--- /dev/null
+++ b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/VehicleDatabaseDAO.java
@@ -0,0 +1,220 @@
+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;
+    }
+
+    public long add(Vehicle vehicle) throws PersistenceException {
+        String query1 =
+                "INSERT INTO VehicleVersion (name,hasNef,constructionType,type) VALUES (?,?,?,?)";
+        String query2 = "INSERT INTO Vehicle (version,status) VALUES (?,?)";
+
+        String status = "ABGEMELDET";
+        String name = "";
+        int id = -1;
+        int version = -1;
+        try {
+            Connection connection = jdbcConnectionManager.getConnection();
+            connection.setAutoCommit(false);
+            try (PreparedStatement p1 =
+                    connection.prepareStatement(query1, PreparedStatement.RETURN_GENERATED_KEYS)) {
+
+                p1.setString(1, name);
+                p1.setBoolean(2, vehicle.hasNef());
+                p1.setString(3, vehicle.constructionType().name());
+
+                p1.setString(4, vehicle.type().name());
+
+                p1.executeUpdate();
+                try (ResultSet keyResultSet = p1.getGeneratedKeys()) {
+
+                    if (keyResultSet.next()) {
+                        version = keyResultSet.getInt(1);
+                    }
+                }
+            }
+            try (PreparedStatement p2 =
+                    connection.prepareStatement(query2, Statement.RETURN_GENERATED_KEYS)) {
+
+                p2.setInt(1, version);
+                p2.setString(2, status);
+                p2.executeUpdate();
+                try (ResultSet keyResultSet = p2.getGeneratedKeys()) {
+
+                    if (keyResultSet.next()) {
+                        id = keyResultSet.getInt(1);
+                    }
+                }
+
+                name = vehicle.type().name() + "-" + id;
+            }
+            query1 = "UPDATE VehicleVersion SET name=? WHERE id=?";
+            try (PreparedStatement p3 = connection.prepareStatement(query1)) {
+                p3.setString(1, name);
+                p3.setInt(2, version);
+                p3.executeUpdate();
+            }
+
+            connection.commit();
+            connection.setAutoCommit(true);
+        } catch (SQLException e) {
+            throw new PersistenceException(e);
+        }
+        return id;
+    }
+
+    @Override
+    public void update(Vehicle vehicle) throws ElementNotFoundException, PersistenceException {
+        String query = "SELECT * FROM vehicle WHERE id=?";
+
+        long vehicleID = -1;
+        long vehicleVersion = -1;
+        try {
+            Connection connection = jdbcConnectionManager.getConnection();
+            connection.setAutoCommit(false);
+            try (PreparedStatement p =
+                    connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS)) {
+
+                p.setLong(1, vehicle.id());
+                p.executeQuery();
+                try (ResultSet rs = p.getResultSet()) {
+                    while (rs.next()) {
+                        vehicleID = rs.getLong("id");
+                    }
+                }
+            }
+            if (vehicleID == -1) {
+                throw new ElementNotFoundException("Vehicle don´t found");
+            }
+
+            query =
+                    "INSERT INTO VehicleVersion (name,hasNef,constructionType,type) VALUES (?,?,?,?)";
+            String name = "";
+            try (PreparedStatement p =
+                    connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS)) {
+                p.setString(1, name);
+                p.setBoolean(2, vehicle.hasNef());
+                p.setString(3, vehicle.constructionType().name());
+
+                p.setString(4, vehicle.type().name());
+
+                p.executeUpdate();
+
+                try (ResultSet keyResultSet = p.getGeneratedKeys()) {
+
+                    if (keyResultSet.next()) {
+                        vehicleVersion = keyResultSet.getInt(1);
+                    }
+                }
+                if (vehicleVersion == -1) {
+                    throw new ElementNotFoundException("Vehicle don´t found");
+                }
+            }
+            name = vehicle.type().name() + "-" + vehicleID;
+
+            query = "UPDATE VehicleVersion SET name=? WHERE id=?";
+            try (PreparedStatement p = connection.prepareStatement(query)) {
+
+                p.setString(1, name);
+                p.setLong(2, vehicleVersion);
+                p.executeUpdate();
+            }
+            query = "UPDATE Vehicle SET version=? WHERE id=?";
+            try (PreparedStatement p = connection.prepareStatement(query)) {
+
+                p.setLong(1, vehicleVersion);
+                p.setLong(2, vehicleID);
+                p.executeUpdate();
+            }
+            connection.commit();
+            connection.setAutoCommit(true);
+        } catch (SQLException e) {
+            throw new PersistenceException(e);
+        }
+    }
+
+    @Override
+    public Set<Vehicle> list() throws PersistenceException {
+        Set<Vehicle> 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("Die Werte konnten nicht geladen werden.", 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 {}
+
+    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/dao/VehicleDatabaseDao.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/VehicleDatabaseDao.java
deleted file mode 100644
index 89a3aca..0000000
--- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/dao/VehicleDatabaseDao.java
+++ /dev/null
@@ -1,220 +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;
-    }
-
-    public long add(Vehicle vehicle) throws PersistenceException {
-        String query1 =
-                "INSERT INTO VehicleVersion (name,hasNef,constructionType,type) VALUES (?,?,?,?)";
-        String query2 = "INSERT INTO Vehicle (version,status) VALUES (?,?)";
-
-        String status = "ABGEMELDET";
-        String name = "";
-        int id = -1;
-        int version = -1;
-        try {
-            Connection connection = jdbcConnectionManager.getConnection();
-            connection.setAutoCommit(false);
-            try (PreparedStatement p1 =
-                    connection.prepareStatement(query1, PreparedStatement.RETURN_GENERATED_KEYS)) {
-
-                p1.setString(1, name);
-                p1.setBoolean(2, vehicle.hasNef());
-                p1.setString(3, vehicle.constructionType().name());
-
-                p1.setString(4, vehicle.type().name());
-
-                p1.executeUpdate();
-                try (ResultSet keyResultSet = p1.getGeneratedKeys()) {
-
-                    if (keyResultSet.next()) {
-                        version = keyResultSet.getInt(1);
-                    }
-                }
-            }
-            try (PreparedStatement p2 =
-                    connection.prepareStatement(query2, Statement.RETURN_GENERATED_KEYS)) {
-
-                p2.setInt(1, version);
-                p2.setString(2, status);
-                p2.executeUpdate();
-                try (ResultSet keyResultSet = p2.getGeneratedKeys()) {
-
-                    if (keyResultSet.next()) {
-                        id = keyResultSet.getInt(1);
-                    }
-                }
-
-                name = vehicle.type().name() + "-" + id;
-            }
-            query1 = "UPDATE VehicleVersion SET name=? WHERE id=?";
-            try (PreparedStatement p3 = connection.prepareStatement(query1)) {
-                p3.setString(1, name);
-                p3.setInt(2, version);
-                p3.executeUpdate();
-            }
-
-            connection.commit();
-            connection.setAutoCommit(true);
-        } catch (SQLException e) {
-            throw new PersistenceException(e);
-        }
-        return id;
-    }
-
-    @Override
-    public void update(Vehicle vehicle) throws ElementNotFoundException, PersistenceException {
-        String query = "SELECT * FROM vehicle WHERE id=?";
-
-        long vehicleID = -1;
-        long vehicleVersion = -1;
-        try {
-            Connection connection = jdbcConnectionManager.getConnection();
-            connection.setAutoCommit(false);
-            try (PreparedStatement p =
-                    connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS)) {
-
-                p.setLong(1, vehicle.id());
-                p.executeQuery();
-                try (ResultSet rs = p.getResultSet()) {
-                    while (rs.next()) {
-                        vehicleID = rs.getLong("id");
-                    }
-                }
-            }
-            if (vehicleID == -1) {
-                throw new ElementNotFoundException("Vehicle don´t found");
-            }
-
-            query =
-                    "INSERT INTO VehicleVersion (name,hasNef,constructionType,type) VALUES (?,?,?,?)";
-            String name = "";
-            try (PreparedStatement p =
-                    connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS)) {
-                p.setString(1, name);
-                p.setBoolean(2, vehicle.hasNef());
-                p.setString(3, vehicle.constructionType().name());
-
-                p.setString(4, vehicle.type().name());
-
-                p.executeUpdate();
-
-                try (ResultSet keyResultSet = p.getGeneratedKeys()) {
-
-                    if (keyResultSet.next()) {
-                        vehicleVersion = keyResultSet.getInt(1);
-                    }
-                }
-                if (vehicleVersion == -1) {
-                    throw new ElementNotFoundException("Vehicle don´t found");
-                }
-            }
-            name = vehicle.type().name() + "-" + vehicleID;
-
-            query = "UPDATE VehicleVersion SET name=? WHERE id=?";
-            try (PreparedStatement p = connection.prepareStatement(query)) {
-
-                p.setString(1, name);
-                p.setLong(2, vehicleVersion);
-                p.executeUpdate();
-            }
-            query = "UPDATE Vehicle SET version=? WHERE id=?";
-            try (PreparedStatement p = connection.prepareStatement(query)) {
-
-                p.setLong(1, vehicleVersion);
-                p.setLong(2, vehicleID);
-                p.executeUpdate();
-            }
-            connection.commit();
-            connection.setAutoCommit(true);
-        } catch (SQLException e) {
-            throw new PersistenceException(e);
-        }
-    }
-
-    @Override
-    public Set<Vehicle> list() throws PersistenceException {
-        Set<Vehicle> 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("Die Werte konnten nicht geladen werden.", 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 {}
-
-    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/ui/vehiclepane/VehiclePaneController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/ui/vehiclepane/VehiclePaneController.java
deleted file mode 100644
index e7a1cc0..0000000
--- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/ui/vehiclepane/VehiclePaneController.java
+++ /dev/null
@@ -1,113 +0,0 @@
-package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.ui.vehiclepane;
-
-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 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.image.Image;
-import javafx.scene.image.ImageView;
-import javafx.scene.text.Text;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class VehiclePaneController {
-
-    private static Logger LOG = LoggerFactory.getLogger(VehiclePaneController.class);
-
-    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 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;
-
-    private Node rootElement;
-    private Vehicle data;
-
-    public Node getRootElement() {
-        return rootElement;
-    }
-
-    public Vehicle getData() {
-        return data;
-    }
-
-    /**
-     * * Set the displayed data of this VehiclePane.
-     *
-     * @param vehicle The data to display.
-     * @param showQualification If true, the most recent registration of vehicle will be searched
-     *     for the highest qualification.
-     */
-    public void setData(Vehicle vehicle, boolean showQualification) {
-        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 (showQualification) {
-
-            Instant now = Instant.now();
-            List<Registration> regs = vehicle.registrations();
-
-            if (regs == null) {
-                return;
-            }
-
-            Optional<EducationLevel> 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);
-        }
-
-        this.data = vehicle;
-    }
-
-    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/userInterface/ArchiveOperationController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/userInterface/ArchiveOperationController.java
deleted file mode 100644
index 53e7067..0000000
--- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/userInterface/ArchiveOperationController.java
+++ /dev/null
@@ -1,127 +0,0 @@
-package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.userInterface;
-
-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 java.time.LocalDateTime;
-import java.time.ZoneOffset;
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.LinkedList;
-import java.util.Objects;
-import java.util.stream.Collectors;
-import javafx.fxml.FXML;
-import javafx.scene.control.Alert;
-import javafx.scene.control.Alert.AlertType;
-import javafx.scene.control.Button;
-import javafx.scene.control.Hyperlink;
-import javafx.scene.control.Label;
-import javafx.scene.layout.AnchorPane;
-import javafx.scene.layout.FlowPane;
-import org.springframework.stereotype.Controller;
-
-@Controller
-public class ArchiveOperationController {
-    @FXML private AnchorPane apDetails;
-    @FXML private Label lblCodeHeader;
-    @FXML private Hyperlink hypBack;
-    @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 LinkedList<Operation> list = new LinkedList<>();
-
-    public ArchiveOperationController(OperationService operationService) {
-        this.operationService = operationService;
-    }
-
-    @FXML
-    private void initialize() {
-        try {
-            list.addAll(operationService.list(EnumSet.of(Status.CANCELLED, Status.COMPLETED)));
-        } catch (ServiceException e) {
-            Alert alert = new Alert(AlertType.ERROR);
-            alert.setTitle("Fehler");
-            alert.setHeaderText("Fehler!");
-            alert.setContentText("Die Einsätze konnten nicht geladen werden!");
-            alert.showAndWait();
-        }
-        for (Operation operation : list) {
-            Button b = new Button();
-            b.setPrefHeight(200);
-            b.setPrefWidth(750 / 2);
-            b.setText(operation.opCode());
-            b.setOnAction(event -> buttonClicked(b));
-            archiveOperationFlowPane.getChildren().add(b);
-        }
-    }
-
-    private Operation detailOperation;
-
-    private void buttonClicked(Button button) {
-        int size = archiveOperationFlowPane.getChildren().size();
-        int index = 0;
-        for (int i = 0; i < size; i++) {
-            if (archiveOperationFlowPane.getChildren().get(i) == button) {
-                index = i;
-                break;
-            }
-        }
-        detailOperation = list.get(index);
-        setOperation();
-        setDetailsVisible(true);
-    }
-
-    private void setOperation() {
-        lblCodeHeader.setText(detailOperation.opCode());
-        String date = "am ";
-        if (detailOperation.created() != null) {
-            LocalDateTime myDateTime =
-                    LocalDateTime.ofInstant(
-                            Objects.requireNonNull(detailOperation.created()), ZoneOffset.UTC);
-            date +=
-                    myDateTime.getDayOfMonth()
-                            + "."
-                            + myDateTime.getMonth().getValue()
-                            + "."
-                            + myDateTime.getYear();
-            lblDate.setText(date);
-        } else {
-            lblDate.setText("---");
-        }
-
-        lblOpCode.setText(detailOperation.opCode());
-        Collection<String> elements =
-                detailOperation.vehicles().stream().map(Vehicle::name).collect(Collectors.toList());
-        String result = String.join(", ", elements);
-
-        lblVehicles.setText(result);
-        lblAddress.setText(detailOperation.destination());
-
-        for (Vehicle vehicle : detailOperation.vehicles()) {
-            Button b = new Button();
-            b.setPrefHeight(200);
-            b.setPrefWidth(600 / 2);
-            b.setText(vehicle.name());
-            fpVehicles.getChildren().add(b);
-        }
-    }
-
-    public void setListVisible(boolean b) {
-        archiveOperationFlowPane.setVisible(b);
-    }
-
-    private void setDetailsVisible(boolean b) {
-        apDetails.setVisible(b);
-    }
-
-    public void backClicked() {
-        fpVehicles.getChildren().clear();
-        setDetailsVisible(false);
-    }
-}
diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/userInterface/CreateOperationController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/userInterface/CreateOperationController.java
deleted file mode 100644
index 67c8807..0000000
--- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/userInterface/CreateOperationController.java
+++ /dev/null
@@ -1,366 +0,0 @@
-package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.userInterface;
-
-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.einsatzverwaltung.ui.vehiclepane.VehiclePaneController;
-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 at.ac.tuwien.sepm.assignment.groupphase.util.SpringFXMLLoader;
-import java.io.IOException;
-import java.lang.invoke.MethodHandles;
-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.event.ActionEvent;
-import javafx.fxml.FXML;
-import javafx.scene.Parent;
-import javafx.scene.Scene;
-import javafx.scene.control.Alert;
-import javafx.scene.control.Alert.AlertType;
-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.stage.Stage;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Controller;
-
-@Controller
-public class CreateOperationController {
-
-    private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
-    public AnchorPane apCreateOperation;
-    @FXML private TextField txtCode;
-    @FXML private TextField txtAddress;
-    @FXML private TextField txtNote;
-    @FXML private Button btnCreateOperation;
-    @FXML private ListView<Vehicle> lvVehicles;
-    @FXML private ListView<Operation> lvActiveOperations;
-    @FXML private Label lblChosenVehicles;
-    @FXML private AnchorPane apInvisible;
-    @FXML private OperationDetailsController operationDetailsController;
-    @FXML private FlowPane fpVehicles;
-
-    private LinkedList<Vehicle> chosenVehicles = new LinkedList<>();
-
-    private final OperationService operationService;
-    private final VehicleService vehicleService;
-    private final SpringFXMLLoader fxmlLoader;
-
-    public CreateOperationController(
-            OperationService operationService,
-            VehicleService vehicleService,
-            SpringFXMLLoader fxmlLoader) {
-        this.operationService = operationService;
-        this.vehicleService = vehicleService;
-        this.fxmlLoader = fxmlLoader;
-    }
-
-    @FXML
-    private void initialize() {
-        lblChosenVehicles.setText("keine ausgewählt");
-        lvActiveOperations.setCellFactory(
-                param ->
-                        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());
-                                }
-                            }
-                        });
-        lvActiveOperations.setOnMouseClicked(
-                event -> {
-                    if (event.getClickCount() == 2) {
-                        if (lvActiveOperations.getSelectionModel().getSelectedItem() == null) {
-                            return;
-                        }
-                        openDetailsWindow(lvActiveOperations.getSelectionModel().getSelectedItem());
-                    }
-                });
-    }
-
-    public void updateList() {
-        try {
-            fpVehicles.getChildren().clear();
-
-            // TODO: this should probably be handled differently
-            Set<Vehicle> 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);
-                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());
-                                        }
-                                    }
-                                });
-
-                fpVehicles.getChildren().add(controller.getRootElement());
-            }
-        } catch (ServiceException | IOException | InvalidOperationException e) {
-            LOG.error("Error while updating list.", e);
-
-            Alert alert = new Alert(Alert.AlertType.ERROR);
-            alert.setTitle("Fehler");
-            alert.setHeaderText("Fehler!");
-            alert.setContentText(e.getMessage());
-            alert.showAndWait();
-        }
-        try {
-            lvActiveOperations.setItems(
-                    FXCollections.observableArrayList(
-                            operationService.list(EnumSet.of(Status.ACTIVE))));
-        } catch (ServiceException e) {
-            Alert alert = new Alert(Alert.AlertType.ERROR);
-            alert.setTitle("Fehler - Einsätze");
-            alert.setHeaderText("Beim Holen der aktiven Einsätze ist ein Fehler aufgetreten.");
-            alert.setContentText(e.getMessage());
-            alert.showAndWait();
-        }
-    }
-
-    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 | ServiceException e) {
-                            LOG.error("Error while setting status.", e);
-                            Alert a = new Alert(AlertType.ERROR, e.getMessage());
-                            a.show();
-                        }
-                    });
-
-            menu.getItems().add(mi);
-        }
-
-        MenuItem abmelden = new MenuItem("abmelden");
-
-        abmelden.setOnAction(
-                event -> {
-                    try {
-                        List<Registration> registrations = data.registrations();
-                        assert registrations
-                                != null; // Otherwise the element shouldn't be in the list.
-
-                        List<Registration> 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 | ServiceException e) {
-                        LOG.error("Error while unregistering.", e);
-                        Alert a = new Alert(AlertType.ERROR, e.getMessage());
-                        a.show();
-                    }
-                });
-
-        menu.getItems().add(abmelden);
-        return menu;
-    }
-
-    @FXML
-    protected void createOperationClicked() {
-        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 | InvalidOperationException e) {
-            Alert alert = new Alert(Alert.AlertType.ERROR);
-            alert.setTitle("Fehler");
-            alert.setHeaderText("Fehler!");
-            alert.setContentText(e.getMessage());
-            alert.showAndWait();
-            return;
-        }
-        Alert alert = new Alert(AlertType.CONFIRMATION);
-        alert.setTitle("Erfolg");
-        alert.setHeaderText("Erfolgreich gespeichert");
-        alert.setContentText("Der Einsatz wurde erfolgreich gespeichert.");
-        alert.showAndWait();
-        updateList();
-        lblChosenVehicles.setText("keine ausgewählt");
-        txtAddress.setText("");
-        txtCode.setText("");
-        txtNote.setText("");
-        chosenVehicles = new LinkedList<>();
-    }
-
-    public void onRegistrationLinkClicked(ActionEvent actionEvent) {
-        openNewWindow("RegistrationWindow.fxml");
-    }
-
-    public void onEmployeeLinkClicked(ActionEvent actionEvent) {
-        openNewWindow("listEmployees.fxml");
-    }
-
-    public void onVehicleLinkClicked(ActionEvent actionEvent) {
-        openNewWindow("createCar.fxml");
-    }
-
-    public void onArchivLinkClicked() {
-        openNewArchivWindow();
-    }
-
-    private void openNewArchivWindow() {
-        Stage stage = new Stage();
-        try {
-            stage.setScene(
-                    new Scene(
-                            (Parent)
-                                    fxmlLoader.load(
-                                            getClass()
-                                                    .getResourceAsStream(
-                                                            "/fxml/ArchiveOperation.fxml"))));
-        } catch (IOException e) {
-            LOG.error("Could not open new window: {}", e);
-        }
-        stage.setTitle("Einsatz erstellen");
-        stage.centerOnScreen();
-        stage.show();
-        updateList();
-    }
-
-    private void openNewWindow(String fxmlFileName) {
-
-        Stage stage = new Stage();
-        try {
-            stage.setScene(
-                    new Scene(
-                            (Parent)
-                                    fxmlLoader.load(
-                                            getClass()
-                                                    .getResourceAsStream(
-                                                            "/fxml/" + fxmlFileName))));
-        } catch (IOException e) {
-            LOG.error("Could not open new window: {}", e);
-        }
-
-        stage.setTitle("Einsatz erstellen");
-        stage.centerOnScreen();
-        stage.showAndWait(); // important to call wait so that updateList is executed afterwards
-
-        updateList();
-    }
-
-    void setVisible(boolean b) {
-        apInvisible.setVisible(!b);
-    }
-
-    private void openDetailsWindow(Operation operation) {
-        operationDetailsController.initOperation(operation);
-        this.setVisible(false);
-    }
-
-    @FXML
-    public void onOperationCodeChanged(KeyEvent keyEvent) {
-        if (keyEvent.getCode() == KeyCode.ENTER) {
-            updateList();
-        }
-    }
-}
diff --git a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/userInterface/OperationDetailsController.java b/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/userInterface/OperationDetailsController.java
deleted file mode 100644
index 9c9eb28..0000000
--- a/src/main/java/at/ac/tuwien/sepm/assignment/groupphase/einsatzverwaltung/userInterface/OperationDetailsController.java
+++ /dev/null
@@ -1,162 +0,0 @@
-package at.ac.tuwien.sepm.assignment.groupphase.einsatzverwaltung.userInterface;
-
-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.ServiceException;
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.stream.Collectors;
-import javafx.collections.FXCollections;
-import javafx.fxml.FXML;
-import javafx.scene.control.Alert;
-import javafx.scene.control.Alert.AlertType;
-import javafx.scene.control.Button;
-import javafx.scene.control.Label;
-import javafx.scene.control.ListCell;
-import javafx.scene.control.ListView;
-import javafx.scene.layout.AnchorPane;
-import org.springframework.stereotype.Controller;
-
-@Controller
-public class OperationDetailsController {
-
-    public Operation operation;
-    private final OperationService operationService;
-    private final VehicleService vehicleService;
-    private final CreateOperationController createOperationController;
-    @FXML private ListView<Vehicle> lvVehicles;
-    @FXML private ListView<Operation> 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() {
-        lvVehicles.setCellFactory(
-                param ->
-                        new ListCell<>() {
-                            @Override
-                            protected void updateItem(Vehicle item, boolean empty) {
-                                super.updateItem(item, empty);
-
-                                if (empty || item == null || item.name() == null) {
-                                    setText(null);
-                                } else {
-                                    setText(item.name());
-                                }
-                            }
-                        });
-        lvActiveOperations.setCellFactory(
-                param ->
-                        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());
-                                }
-                            }
-                        });
-        lvActiveOperations.setOnMouseClicked(
-                event -> {
-                    if (event.getClickCount() == 2) {
-                        if (lvActiveOperations.getSelectionModel().getSelectedItem() == null) {
-                            return;
-                        }
-                        initOperation(lvActiveOperations.getSelectionModel().getSelectedItem());
-                    }
-                });
-    }
-
-    void initOperation(Operation operation) {
-        fillActiveList();
-        this.operation = operation;
-        lblCode.setText(operation.opCode());
-        Collection<String> 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());
-        lvVehicles.setItems(FXCollections.observableArrayList(operation.vehicles()));
-        operationDetailsAP.setVisible(true);
-    }
-
-    private void fillActiveList() {
-        try {
-            lvActiveOperations.setItems(
-                    FXCollections.observableArrayList(
-                            operationService.list(EnumSet.of(Status.ACTIVE))));
-        } catch (ServiceException e) {
-            Alert alert = new Alert(AlertType.ERROR);
-            alert.setTitle("Fehler");
-            alert.setHeaderText("Fehler!");
-            alert.setContentText(e.getMessage());
-            alert.showAndWait();
-        }
-    }
-
-    @FXML
-    public void closeOperationClicked() {
-        try {
-            operationService.complete(operation.id(), Status.COMPLETED);
-        } catch (InvalidOperationException | ServiceException e) {
-            Alert alert = new Alert(AlertType.ERROR);
-            alert.setTitle("Fehler");
-            alert.setHeaderText("Fehler!");
-            alert.setContentText(e.getMessage());
-            alert.showAndWait();
-            return;
-        }
-        Alert alert = new Alert(AlertType.CONFIRMATION);
-        alert.setTitle("Erfolg");
-        alert.setHeaderText("Erfolgreich aktualisiert");
-        alert.setContentText("Der Einsatz wurde erfolgreich aktualisiert.");
-        alert.showAndWait();
-        closeWindow();
-        createOperationController.updateList();
-    }
-
-    public void cancelOperationClicked() {
-        try {
-            operationService.complete(operation.id(), Status.CANCELLED);
-        } catch (InvalidOperationException | ServiceException e) {
-            Alert alert = new Alert(AlertType.ERROR);
-            alert.setTitle("Fehler");
-            alert.setHeaderText("Fehler!");
-            alert.setContentText(e.getMessage());
-            alert.showAndWait();
-            return;
-        }
-        Alert alert = new Alert(AlertType.CONFIRMATION);
-        alert.setTitle("Erfolg");
-        alert.setHeaderText("Erfolgreich aktualisiert");
-        alert.setContentText("Der Einsatz wurde erfolgreich aktualisiert.");
-        alert.showAndWait();
-        closeWindow();
-        createOperationController.updateList();
-    }
-
-    public void closeWindow() {
-        operationDetailsAP.setVisible(false);
-        this.createOperationController.setVisible(true);
-    }
-}
-- 
cgit v1.2.3-70-g09d2


From 74cb995f0dd1d90b33125d290dfed865df795aa2 Mon Sep 17 00:00:00 2001
From: Tharre <tharre3@gmail.com>
Date: Thu, 24 May 2018 17:14:51 +0200
Subject: Use try-with-res. in EmployeeDatabaseDAO #25963

---
 .../einsatzverwaltung/dao/EmployeeDatabaseDAO.java | 81 ++++++++++++----------
 1 file changed, 43 insertions(+), 38 deletions(-)

(limited to 'src/main/java')

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
index fd0add7..43a5c9d 100644
--- 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
@@ -76,17 +76,19 @@ public class EmployeeDatabaseDAO implements EmployeeDAO {
             insertEmployeeVersion.setBoolean(4, employee.isDriver());
             insertEmployeeVersion.setBoolean(5, employee.isPilot());
             insertEmployeeVersion.executeUpdate();
-            ResultSet resultSetEmployeeVersion = insertEmployeeVersion.getGeneratedKeys();
-            if (resultSetEmployeeVersion.next()) {
-                long versionId = resultSetEmployeeVersion.getLong(1);
-
-                insertEmployee.setLong(1, versionId);
-                insertEmployee.executeUpdate();
-
-                ResultSet resultSetEmployee = insertEmployee.getGeneratedKeys();
-                if (resultSetEmployee.next()) {
-                    connection.commit();
-                    return resultSetEmployee.getLong(1);
+            try (ResultSet resultSetEmployeeVersion = insertEmployeeVersion.getGeneratedKeys()) {
+                if (resultSetEmployeeVersion.next()) {
+                    long versionId = resultSetEmployeeVersion.getLong(1);
+
+                    insertEmployee.setLong(1, versionId);
+                    insertEmployee.executeUpdate();
+
+                    try (ResultSet resultSetEmployee = insertEmployee.getGeneratedKeys()) {
+                        if (resultSetEmployee.next()) {
+                            connection.commit();
+                            return resultSetEmployee.getLong(1);
+                        }
+                    }
                 }
             }
 
@@ -125,20 +127,21 @@ public class EmployeeDatabaseDAO implements EmployeeDAO {
             insertEmployeeVersion.setBoolean(4, employee.isDriver());
             insertEmployeeVersion.setBoolean(5, employee.isPilot());
             insertEmployeeVersion.executeUpdate();
-            ResultSet resultSetEmployeeVersion = insertEmployeeVersion.getGeneratedKeys();
+            try (ResultSet resultSetEmployeeVersion = insertEmployeeVersion.getGeneratedKeys()) {
 
-            if (resultSetEmployeeVersion.next()) {
-                long versionId = resultSetEmployeeVersion.getLong(1);
+                if (resultSetEmployeeVersion.next()) {
+                    long versionId = resultSetEmployeeVersion.getLong(1);
 
-                updateEmployee.setLong(1, versionId);
-                updateEmployee.setLong(2, employee.id());
-                int affectedRows = updateEmployee.executeUpdate();
+                    updateEmployee.setLong(1, versionId);
+                    updateEmployee.setLong(2, employee.id());
+                    int affectedRows = updateEmployee.executeUpdate();
 
-                if (affectedRows == 1) {
-                    connection.commit();
-                } else {
-                    throw new ElementNotFoundException(
-                            "element not found with id: " + employee.id());
+                    if (affectedRows == 1) {
+                        connection.commit();
+                    } else {
+                        throw new ElementNotFoundException(
+                                "element not found with id: " + employee.id());
+                    }
                 }
             }
 
@@ -164,22 +167,24 @@ public class EmployeeDatabaseDAO implements EmployeeDAO {
     public Set<Employee> list() throws PersistenceException {
 
         try {
-            ResultSet rs = listEmployee.executeQuery();
-
-            Set<Employee> employees = new HashSet<>();
-            while (rs.next()) {
-
-                Employee employee =
-                        Employee.builder()
-                                .id(rs.getLong(1))
-                                .name(rs.getString(2))
-                                .birthday(rs.getTimestamp(3).toLocalDateTime().toLocalDate())
-                                .educationLevel(EducationLevel.valueOf(rs.getString(4)))
-                                .isDriver(rs.getBoolean(5))
-                                .isPilot(rs.getBoolean(6))
-                                .build();
-
-                employees.add(employee);
+            Set<Employee> employees;
+            try (ResultSet rs = listEmployee.executeQuery()) {
+
+                employees = new HashSet<>();
+                while (rs.next()) {
+
+                    Employee employee =
+                            Employee.builder()
+                                    .id(rs.getLong(1))
+                                    .name(rs.getString(2))
+                                    .birthday(rs.getTimestamp(3).toLocalDateTime().toLocalDate())
+                                    .educationLevel(EducationLevel.valueOf(rs.getString(4)))
+                                    .isDriver(rs.getBoolean(5))
+                                    .isPilot(rs.getBoolean(6))
+                                    .build();
+
+                    employees.add(employee);
+                }
             }
 
             return employees;
-- 
cgit v1.2.3-70-g09d2


From 716bf9fd75aff4d22ee6055961b2d0c4cae2fb11 Mon Sep 17 00:00:00 2001
From: Tharre <tharre3@gmail.com>
Date: Thu, 24 May 2018 17:41:40 +0200
Subject: Fix IllegalArgumentException with opCode #25963

RE-021E4 causes IllegalArgumentException
---
 .../groupphase/einsatzverwaltung/service/OperationServiceImpl.java     | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'src/main/java')

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
index 396d62c..d07f46f 100644
--- 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
@@ -250,7 +250,8 @@ public class OperationServiceImpl implements OperationService {
             throw new InvalidOperationException("Adresse darf nicht leer sein");
     }
 
-    private static final Pattern opCodePattern = Pattern.compile("(?:\\w{1,3}-\\d{0,2})(.)(?:.*)");
+    private static final Pattern opCodePattern =
+            Pattern.compile("(?:\\w{1,3}-\\d{0,2})([ABCDEO])(?:.*)");
 
     private static Severity extractSeverityFromOpCode(String opCode)
             throws InvalidOperationException {
-- 
cgit v1.2.3-70-g09d2