From afa8b59274ed54c554686bc2bdede4d3eba17018 Mon Sep 17 00:00:00 2001
From: Julian Dehne <julian.dehne@uni-potsdam.de>
Date: Tue, 10 Jul 2018 12:20:38 +0200
Subject: [PATCH] feat: implemented a central management class that allows for
 a project to be changed to a new phase

---
 gemeinsamforschen/pom.xml                     |   4 +
 .../gf/config/GFApplicationBinder.java        |  13 +-
 .../gf/config/GFDatabaseConfig.java           |   4 +-
 .../gf/core/management/ManagementImpl.java    |  17 +-
 .../gf/core/management/project/Project.java   |   2 +-
 .../gf/core/management/user/Menu.java         |   2 +
 .../management/user/UserService.java.orig     | 163 ------------------
 .../gf/core/states/DosserUploadTask.java      |  19 --
 .../gf/core/states/PeerAssessmentTask.java    |  21 ---
 .../gf/core/states/PeerFeedbackTask.java      |  22 ---
 .../unipotsdam/gf/core/states/PhasesImpl.java | 126 ++++++++++++++
 .../gf/core/states/ProjectPhase.java          |   7 +-
 .../unipotsdam/gf/core/states/States.java     |  35 ----
 .../java/unipotsdam/gf/core/states/Task.java  |  56 ------
 .../unipotsdam/gf/interfaces/Feedback.java    |   9 +
 .../gf/interfaces/ICommunication.java         |   5 +
 .../unipotsdam/gf/interfaces/IJournal.java    |  13 ++
 .../unipotsdam/gf/interfaces/IPhases.java     |  13 ++
 .../service/CommunicationDummyService.java    |   7 +
 .../gf/modules/journal/DummyJournalImpl.java  |  33 ++++
 .../gf/modules/journal/model/Journal.java     |   2 +-
 .../journal/model/ProjectDescription.java     |   2 +-
 .../peer2peerfeedback}/Category.java          |   2 +-
 .../peer2peerfeedback/DummyFeedback.java      |  43 +++++
 .../peer2peerfeedback/ExampleFeedback.java    |   1 -
 .../peer2peerfeedback/Peer2PeerFeedback.java  |   1 -
 .../utils => view}/MarkdownUtils.java         |   2 +-
 .../java/unipotsdam/gf/view/Messages.java     |  20 +++
 .../src/scripts/dbschema/fltrail.sql          |  20 ++-
 .../gf/interfaces/ManagementTest.java         |  17 +-
 .../unipotsdam/gf/interfaces/PhaseTest.java   |  83 +++++++++
 31 files changed, 419 insertions(+), 345 deletions(-)
 delete mode 100644 gemeinsamforschen/src/main/java/unipotsdam/gf/core/management/user/UserService.java.orig
 delete mode 100644 gemeinsamforschen/src/main/java/unipotsdam/gf/core/states/DosserUploadTask.java
 delete mode 100644 gemeinsamforschen/src/main/java/unipotsdam/gf/core/states/PeerAssessmentTask.java
 delete mode 100644 gemeinsamforschen/src/main/java/unipotsdam/gf/core/states/PeerFeedbackTask.java
 create mode 100644 gemeinsamforschen/src/main/java/unipotsdam/gf/core/states/PhasesImpl.java
 delete mode 100644 gemeinsamforschen/src/main/java/unipotsdam/gf/core/states/States.java
 delete mode 100644 gemeinsamforschen/src/main/java/unipotsdam/gf/core/states/Task.java
 create mode 100644 gemeinsamforschen/src/main/java/unipotsdam/gf/interfaces/IPhases.java
 create mode 100644 gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/DummyJournalImpl.java
 rename gemeinsamforschen/src/main/java/unipotsdam/gf/{core/management/utils => modules/peer2peerfeedback}/Category.java (82%)
 create mode 100644 gemeinsamforschen/src/main/java/unipotsdam/gf/modules/peer2peerfeedback/DummyFeedback.java
 rename gemeinsamforschen/src/main/java/unipotsdam/gf/{core/management/utils => view}/MarkdownUtils.java (93%)
 create mode 100644 gemeinsamforschen/src/main/java/unipotsdam/gf/view/Messages.java
 create mode 100644 gemeinsamforschen/src/test/java/unipotsdam/gf/interfaces/PhaseTest.java

diff --git a/gemeinsamforschen/pom.xml b/gemeinsamforschen/pom.xml
index e23a2999..52c20b79 100644
--- a/gemeinsamforschen/pom.xml
+++ b/gemeinsamforschen/pom.xml
@@ -170,6 +170,10 @@
             <artifactId>commonmark</artifactId>
             <version>0.11.0</version>
         </dependency>
+
+        <!-- state rules -->
+
+
     </dependencies>
 
 </project>
\ No newline at end of file
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/config/GFApplicationBinder.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/config/GFApplicationBinder.java
index 554cf050..b1e37de6 100644
--- a/gemeinsamforschen/src/main/java/unipotsdam/gf/config/GFApplicationBinder.java
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/config/GFApplicationBinder.java
@@ -3,13 +3,24 @@ package unipotsdam.gf.config;
 import org.glassfish.hk2.utilities.binding.AbstractBinder;
 import unipotsdam.gf.core.management.Management;
 import unipotsdam.gf.core.management.ManagementImpl;
-import unipotsdam.gf.interfaces.ICommunication;
+import unipotsdam.gf.core.states.PhasesImpl;
+import unipotsdam.gf.interfaces.*;
+import unipotsdam.gf.modules.assessment.controller.service.PeerAssessment;
+import unipotsdam.gf.modules.assessment.controller.service.PeerAssessmentDummy;
 import unipotsdam.gf.modules.communication.service.CommunicationDummyService;
+import unipotsdam.gf.modules.journal.DummyJournalImpl;
+import unipotsdam.gf.modules.journal.model.Journal;
+import unipotsdam.gf.modules.journal.service.DummyJournalService;
+import unipotsdam.gf.modules.peer2peerfeedback.DummyFeedback;
 
 public class GFApplicationBinder extends AbstractBinder {
     @Override
     protected void configure() {
         bind(CommunicationDummyService.class).to(ICommunication.class);
         bind(ManagementImpl.class).to(Management.class);
+        bind(DummyFeedback.class).to(Feedback.class);
+        bind(DummyJournalImpl.class).to(IJournal.class);
+        bind(PeerAssessmentDummy.class).to(IPeerAssessment.class);
+        bind(PhasesImpl.class).to(IPhases.class);
     }
 }
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/config/GFDatabaseConfig.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/config/GFDatabaseConfig.java
index 25290510..cefe2e28 100644
--- a/gemeinsamforschen/src/main/java/unipotsdam/gf/config/GFDatabaseConfig.java
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/config/GFDatabaseConfig.java
@@ -7,7 +7,7 @@ public class GFDatabaseConfig {
     public static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
     public static final String DB_URL = "jdbc:mysql://localhost";
     //  Database credentials
-    public static final String USER = "root";
-    public static final String PASS = "";
+    public static final String USER = "root2";
+    public static final String PASS = "voyager2";
     public static final String DB_NAME = "fltrail";
 }
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/core/management/ManagementImpl.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/core/management/ManagementImpl.java
index 62744cc0..0bb16d84 100644
--- a/gemeinsamforschen/src/main/java/unipotsdam/gf/core/management/ManagementImpl.java
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/core/management/ManagementImpl.java
@@ -64,7 +64,8 @@ public class ManagementImpl implements Management {
                 "INSERT INTO projects (`id`, `password`, `active`, `timecreated`, `author`, "
                         + "`adminPassword`, `token`, `phase`) values (?,?,?,?,?,?,?,?)";
         connect.issueInsertOrDeleteStatement(mysqlRequest, project.getId(), project.getPassword(), project.isActive(),
-                project.getTimecreated(), project.getAuthor(), project.getAdminPassword(), token);
+                project.getTimecreated(), project.getAuthor(), project.getAdminPassword(), token, project.getPhase()
+                        == null ? ProjectPhase.CourseCreation : project.getPhase());
         connect.close();
     }
 
@@ -136,11 +137,15 @@ public class ManagementImpl implements Management {
         connect.connect();
         VereinfachtesResultSet vereinfachtesResultSet = connect.issueSelectStatement(query, project.getId());
         while (!vereinfachtesResultSet.isLast()) {
-            vereinfachtesResultSet.next();
-            User user = getUserFromResultSet(vereinfachtesResultSet);
-            String token = vereinfachtesResultSet.getString("token");
-            user.setToken(token);
-            result.add(user);
+            Boolean next = vereinfachtesResultSet.next();
+            if (next) {
+                User user = getUserFromResultSet(vereinfachtesResultSet);
+                String token = vereinfachtesResultSet.getString("token");
+                user.setToken(token);
+                result.add(user);
+            } else {
+                break;
+            }
         }
         connect.close();
         return result;
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/core/management/project/Project.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/core/management/project/Project.java
index 0cdf93a1..06bd24d7 100644
--- a/gemeinsamforschen/src/main/java/unipotsdam/gf/core/management/project/Project.java
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/core/management/project/Project.java
@@ -32,7 +32,7 @@ public class Project {
         this.adminPassword = adminPassword;
         this.timecreated = Timestamp.valueOf(LocalDateTime.now(ZoneId.of("UTC")));
         // default starting at course creation if new
-        this.setPhase(ProjectPhase.CourseCreationPhase);
+        this.setPhase(ProjectPhase.CourseCreation);
     }
 
     public String getPhase() {
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/core/management/user/Menu.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/core/management/user/Menu.java
index f5ccb749..16e3f3ff 100644
--- a/gemeinsamforschen/src/main/java/unipotsdam/gf/core/management/user/Menu.java
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/core/management/user/Menu.java
@@ -9,6 +9,8 @@ import javax.servlet.jsp.PageContext;
 import javax.servlet.jsp.tagext.SimpleTagSupport;
 import java.io.IOException;
 
+
+// TODO: please move this to a view package at the top of the hierarchy as this is not part of the user package
 public class Menu extends SimpleTagSupport {
     public void doTag() throws JspException, IOException {
         PageContext pageContext = (PageContext) getJspContext();
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/core/management/user/UserService.java.orig b/gemeinsamforschen/src/main/java/unipotsdam/gf/core/management/user/UserService.java.orig
deleted file mode 100644
index 73d84e8f..00000000
--- a/gemeinsamforschen/src/main/java/unipotsdam/gf/core/management/user/UserService.java.orig
+++ /dev/null
@@ -1,163 +0,0 @@
-package unipotsdam.gf.core.management.user;
-
-import unipotsdam.gf.core.management.ManagementImpl;
-import unipotsdam.gf.interfaces.ICommunication;
-import unipotsdam.gf.modules.communication.service.CommunicationDummyService;
-
-import javax.annotation.ManagedBean;
-import javax.inject.Inject;
-import javax.ws.rs.FormParam;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import java.net.URI;
-import java.net.URISyntaxException;
-
-@Path("/user")
-@ManagedBean
-public class UserService {
-
-    @Inject
-    private ICommunication communicationService;
-
-    /**
-     * creates a user with given credentials
-     *
-     * @param name
-     * @param password
-     * @param email
-     * @param isStudent
-     * @return
-     * @throws URISyntaxException
-     */
-    // This method is called if HTML is request
-    @POST
-    @Produces(MediaType.TEXT_HTML)
-    @Path("/create")
-    public Response createUser(@FormParam("name") String name, @FormParam("password") String password,
-                               @FormParam("email") String email, @FormParam("isStudent") String isStudent)
-            throws URISyntaxException {
-
-        ManagementImpl management = new ManagementImpl();
-        User user = new User(name, password, email, isStudent == null);
-        return login(true, user);
-
-    }
-
-    /**
-     * checks if a user exists in order to log him in
-     *
-     * @param name
-     * @param password
-     * @param email
-     * @return
-     * @throws URISyntaxException
-     */
-    // This method is called if HTML is request
-    @POST
-    @Produces(MediaType.TEXT_HTML)
-    @Path("/exists")
-    public Response existsUser(@FormParam("name") String name, @FormParam("password") String password,
-                               @FormParam("email") String email)
-            throws URISyntaxException {
-
-        ManagementImpl management = new ManagementImpl();
-        User user = new User(name, password, email, null);
-        ICommunication iCommunication = new CommunicationDummyService();
-        boolean isLoggedIn = iCommunication.loginUser(user);
-        if (isLoggedIn) {
-            return login(false, user);
-        } else {
-            return loginError();
-        }
-
-
-    }
-
-    /**
-     * if create User is true, the user is created and logged in if he does not exist
-     *
-     * @param createUser
-     * @param user
-     * @return
-     * @throws URISyntaxException
-     */
-    protected Response login(boolean createUser, User user) throws URISyntaxException {
-        ManagementImpl management = new ManagementImpl();
-        if (management.exists(user)) {
-            if (!createUser) {
-<<<<<<< HEAD
-                ManagementImpl m = new ManagementImpl();
-                String token = m.getUserToken(user);
-                user = m.getUser(token);
-=======
-                boolean successfulLogin = communicationService.loginUser(user);
-                management.update(user);
-                if (!successfulLogin) {
-                    return loginError();
-                }
->>>>>>> 9bbae0ff75b2597ab35479a24d47c12e7a4cc0fd
-                return redirectToProjectPage(user, management);
-            }
-            String existsUrl = "../register.jsp?userExists=true";
-            return forwardToLocation(existsUrl);
-        } else {
-            if (createUser) {
-                boolean isRegisteredAndLoggedIn = communicationService.registerAndLoginUser(user);
-                if (!isRegisteredAndLoggedIn) {
-                    return registrationError();
-                }
-                management.create(user, null);
-            } else {
-                String existsUrl = "../index.jsp?userExists=false";
-                return forwardToLocation(existsUrl);
-            }
-            ManagementImpl m = new ManagementImpl();
-            String token = m.getUserToken(user);
-            user = m.getUser(token); //todo: write query to get user isStudent
-            return redirectToProjectPage(user, management);
-        }
-    }
-
-    private Response registrationError() throws URISyntaxException {
-        String existsUrl = "../register.jsp?registrationError=true";
-        return forwardToLocation(existsUrl);
-    }
-
-    private Response loginError() throws URISyntaxException {
-        String existsUrl = "../index.jsp?loginError=true";
-        return forwardToLocation(existsUrl);
-    }
-
-    /**
-     * helper function for redirecting to the right project page
-     *
-     * @param user
-     * @param management
-     * @return
-     * @throws URISyntaxException
-     */
-    private Response redirectToProjectPage(User user, ManagementImpl management) throws URISyntaxException {
-        String successUrl;
-        if (user.getStudent() != null && user.getStudent()) {
-            successUrl = "../pages/overview-student.html?token=";
-        } else {
-            successUrl = "../pages/overview-docent.html?token=";
-        }
-        successUrl += management.getUserToken(user);
-        return forwardToLocation(successUrl);
-    }
-
-    /**
-     * * helper function for redirecting to a new page
-     *
-     * @param existsUrl
-     * @return
-     * @throws URISyntaxException
-     */
-    private Response forwardToLocation(String existsUrl) throws URISyntaxException {
-        return Response.seeOther(new URI(existsUrl)).build();
-    }
-}
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/core/states/DosserUploadTask.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/core/states/DosserUploadTask.java
deleted file mode 100644
index 520f3a41..00000000
--- a/gemeinsamforschen/src/main/java/unipotsdam/gf/core/states/DosserUploadTask.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package unipotsdam.gf.core.states;
-
-import unipotsdam.gf.core.management.user.User;
-
-public class DosserUploadTask extends Task {
-    public DosserUploadTask(User owner) {
-        super(owner);
-    }
-
-    @Override
-    public String getTaskMessage() {
-        return null;
-    }
-
-    @Override
-    protected String getTaskUrl() {
-        return null;
-    }
-}
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/core/states/PeerAssessmentTask.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/core/states/PeerAssessmentTask.java
deleted file mode 100644
index 3808b6b3..00000000
--- a/gemeinsamforschen/src/main/java/unipotsdam/gf/core/states/PeerAssessmentTask.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package unipotsdam.gf.core.states;
-
-import unipotsdam.gf.core.management.user.User;
-
-public class PeerAssessmentTask extends Task {
-    public PeerAssessmentTask(User owner) {
-        super(owner);
-    }
-
-    @Override
-    public String getTaskMessage() {
-        return null;
-    }
-
-    @Override
-    protected String getTaskUrl() {
-        return null;
-    }
-
-
-}
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/core/states/PeerFeedbackTask.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/core/states/PeerFeedbackTask.java
deleted file mode 100644
index 283977e6..00000000
--- a/gemeinsamforschen/src/main/java/unipotsdam/gf/core/states/PeerFeedbackTask.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package unipotsdam.gf.core.states;
-
-import unipotsdam.gf.core.management.user.User;
-
-public class PeerFeedbackTask extends Task {
-    public PeerFeedbackTask(User owner) {
-        super(owner);
-    }
-
-    @Override
-    public String getTaskMessage() {
-        // TODO implement
-        return null;
-    }
-
-    @Override
-    protected String getTaskUrl() {
-        // TODO implement
-        return null;
-    }
-
-}
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/core/states/PhasesImpl.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/core/states/PhasesImpl.java
new file mode 100644
index 00000000..f41a8eee
--- /dev/null
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/core/states/PhasesImpl.java
@@ -0,0 +1,126 @@
+package unipotsdam.gf.core.states;
+
+import unipotsdam.gf.core.database.mysql.MysqlConnect;
+import unipotsdam.gf.core.management.project.Project;
+import unipotsdam.gf.interfaces.*;
+import unipotsdam.gf.view.Messages;
+
+import javax.annotation.ManagedBean;
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+/**
+ * Created by dehne on 31.05.2018.
+ * This class should be used to manage changing the phases in a central location
+ * it has dependencies to most modules, as they are required to check the constraints
+ * when changing between phases
+ */
+@ManagedBean
+public class PhasesImpl implements IPhases {
+
+    @Inject
+    private IPeerAssessment iPeerAssessment;
+
+    @Inject
+    private Feedback feedback;
+
+    @Inject
+    private ICommunication iCommunication;
+
+    @Inject
+    private IJournal iJournal;
+
+    public PhasesImpl() {
+    }
+
+    /**
+     * use this if you don't know how dependency injection works
+     * @param iPeerAssessment
+     * @param feedback
+     * @param iCommunication
+     * @param iJournal
+     */
+    public PhasesImpl(IPeerAssessment iPeerAssessment, Feedback feedback, ICommunication iCommunication, IJournal iJournal) {
+        this.iPeerAssessment = iPeerAssessment;
+        this.feedback = feedback;
+        this.iCommunication = iCommunication;
+        this.iJournal = iJournal;
+    }
+
+    @Override
+    public void endPhase(ProjectPhase currentPhase, Project project) {
+        switch (currentPhase) {
+            case CourseCreation:
+                // saving the state
+                saveState(project,getNextPhase(currentPhase));
+                break;
+            case GroupFormation:
+                // inform users about the formed groups, optionally giving them a hint on what happens next
+                iCommunication.sendMessageToUsers(project, Messages.GroupFormation(project));
+                saveState(project,getNextPhase(currentPhase));
+                break;
+            case DossierFeedback:
+                // check if everybody has uploaded a dossier
+                Boolean feedbacksGiven = feedback.checkFeedbackConstraints(project);
+                if (!feedbacksGiven) {
+                    feedback.assigningMissingFeedbackTasks(project);
+                } else {
+                    // send a message to the users informing them about the start of the new phase
+                    iCommunication.sendMessageToUsers(project, Messages.NewFeedbackTask(project));
+                    saveState(project,getNextPhase(currentPhase));
+                }
+                break;
+            case Execution:
+                // check if the portfolios have been prepared for evaluation (relevant entries selected)
+                Boolean portfoliosReady = iJournal.getPortfoliosForEvaluationPrepared(project);
+                if (portfoliosReady) {
+                    // inform users about the end of the phase
+                    iCommunication.sendMessageToUsers(project, Messages.AssessmentPhaseStarted(project));
+                    saveState(project,getNextPhase(currentPhase));
+                } else {
+                    iJournal.assignMissingPortfolioTasks(project);
+                }
+                break;
+            case Assessment:
+                closeProject();
+                break;
+        }
+    }
+
+    private void closeProject() {
+        // TODO implement
+    }
+
+    ProjectPhase getNextPhase(ProjectPhase projectPhase) {
+        switch (projectPhase) {
+            case CourseCreation:
+                return ProjectPhase.GroupFormation;
+            case GroupFormation:
+                return ProjectPhase.DossierFeedback;
+            case DossierFeedback:
+                return ProjectPhase.Execution;
+            case Execution:
+                return ProjectPhase.Assessment;
+            case Assessment:
+                return ProjectPhase.Projectfinished;
+        }
+        return null;
+    }
+
+    private void saveState(Project project, ProjectPhase currentPhase) {
+        assert project.getId() != null;
+        MysqlConnect connect = new MysqlConnect();
+        connect.connect();
+        String mysqlRequest = "UPDATE `projects` SET `phase`=? WHERE id=? LIMIT 1";
+        connect.issueUpdateStatement(mysqlRequest, currentPhase.name(), project.getId());
+        connect.close();
+    }
+
+
+
+
+
+
+
+}
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/core/states/ProjectPhase.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/core/states/ProjectPhase.java
index f17a652a..ba8bffad 100644
--- a/gemeinsamforschen/src/main/java/unipotsdam/gf/core/states/ProjectPhase.java
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/core/states/ProjectPhase.java
@@ -1,9 +1,6 @@
 package unipotsdam.gf.core.states;
 
 public enum ProjectPhase {
-    CourseCreationPhase,
-    GroupFormationPhase,
-    DossierFeedbackPhase,
-    ExecutionPhase,
-    AssessmentPhase
+    CourseCreation, GroupFormation, DossierFeedback, Execution, Assessment,
+    Projectfinished
 }
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/core/states/States.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/core/states/States.java
deleted file mode 100644
index 638cf52b..00000000
--- a/gemeinsamforschen/src/main/java/unipotsdam/gf/core/states/States.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package unipotsdam.gf.core.states;
-
-import unipotsdam.gf.core.management.user.User;
-import unipotsdam.gf.interfaces.ICommunication;
-import unipotsdam.gf.modules.communication.model.Message;
-
-import javax.inject.Inject;
-
-public class States {
-
-    @Inject
-    ICommunication iCommunication;
-
-
-    public void endPhase(ProjectPhase currentPhase) {
-        // TODO implement
-
-        // calculate reaction
-
-        // if no problem change phase
-
-        // if problem send message
-
-        // and start recovery process
-    }
-
-
-    private void sendProblemMessage(String message, User user) {
-        iCommunication.sendSingleMessage(new Message(null, message),user);
-    }
-
-
-
-
-}
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/core/states/Task.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/core/states/Task.java
deleted file mode 100644
index 821f480c..00000000
--- a/gemeinsamforschen/src/main/java/unipotsdam/gf/core/states/Task.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package unipotsdam.gf.core.states;
-
-import unipotsdam.gf.core.management.user.User;
-import unipotsdam.gf.interfaces.ICommunication;
-import unipotsdam.gf.modules.communication.model.Message;
-
-import javax.inject.Inject;
-
-public abstract class Task {
-
-    @Inject
-    ICommunication iCommunication;
-
-    // the user who has to do the task
-    protected User owner;
-
-    public Task(User owner) {
-        this.owner = owner;
-    }
-
-    public abstract String getTaskMessage();
-
-    public void start() {
-        sendTaskMessage();
-        save();
-    }
-
-    private void save() {
-        String name = getClass().getName(); // this returns the runtime name of the subclass i.e. PeerAssessmentTask
-        String url = getTaskUrl();
-
-    }
-
-    /**
-     * should be a relative path like
-     *  /dossiers/upload
-     *  /peerfeedback/{userId}/give
-     *  /peerassessment/{userId}/give
-     *  or similar
-     *
-     * @return
-     */
-    protected abstract String getTaskUrl();
-
-    public void sendTaskMessage() {
-        iCommunication.sendSingleMessage(new Message(null, getTaskMessage()), owner);
-    }
-
-    public User getOwner() {
-        return owner;
-    }
-
-    public void setOwner(User owner) {
-        this.owner = owner;
-    }
-}
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/interfaces/Feedback.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/interfaces/Feedback.java
index 6ba367ce..5a882917 100644
--- a/gemeinsamforschen/src/main/java/unipotsdam/gf/interfaces/Feedback.java
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/interfaces/Feedback.java
@@ -1,4 +1,5 @@
 package unipotsdam.gf.interfaces;
+import unipotsdam.gf.core.management.project.Project;
 import unipotsdam.gf.core.management.user.User;
 import unipotsdam.gf.modules.peer2peerfeedback.Peer2PeerFeedback;
 import java.*;
@@ -51,4 +52,12 @@ public interface Feedback {
 
     int countFeedback(User student);
 
+    /**
+     * TODO implement check in DB that everybody has given feedback
+     * @param project
+     * @return
+     */
+    Boolean checkFeedbackConstraints(Project project);
+
+    void assigningMissingFeedbackTasks(Project project);
 }
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/interfaces/ICommunication.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/interfaces/ICommunication.java
index d66970b8..3370fa65 100644
--- a/gemeinsamforschen/src/main/java/unipotsdam/gf/interfaces/ICommunication.java
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/interfaces/ICommunication.java
@@ -1,5 +1,6 @@
 package unipotsdam.gf.interfaces;
 
+import unipotsdam.gf.core.management.project.Project;
 import unipotsdam.gf.core.management.user.User;
 import unipotsdam.gf.modules.communication.model.Message;
 import unipotsdam.gf.modules.communication.model.chat.ChatMessage;
@@ -85,5 +86,9 @@ public interface ICommunication {
 
     String getChatRoomLink(String userToken, String projectToken, String groupToken);
 
+    // TODO implement as Email or whatever
     void sendSingleMessage(Message message, User user);
+
+    // TODO implement as Email or whatever
+    void sendMessageToUsers(Project project, String message);
 }
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/interfaces/IJournal.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/interfaces/IJournal.java
index 4da8b21c..869de710 100644
--- a/gemeinsamforschen/src/main/java/unipotsdam/gf/interfaces/IJournal.java
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/interfaces/IJournal.java
@@ -1,6 +1,7 @@
 package unipotsdam.gf.interfaces;
 
 
+import unipotsdam.gf.core.management.project.Project;
 import unipotsdam.gf.modules.assessment.controller.model.StudentIdentifier;
 
 /**
@@ -16,4 +17,16 @@ public interface IJournal {
      */
     String exportJournal (StudentIdentifier student);
 
+    /**
+     * check if all students have prepared their portfolios to be evaluated
+     * @return
+     * @param project
+     */
+    Boolean getPortfoliosForEvaluationPrepared(Project project);
+
+    /**
+     * find out, who hasn't prepared their portfolio for evaluation and send message or highlight in view
+     * @param project
+     */
+    void assignMissingPortfolioTasks(Project project);
 }
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/interfaces/IPhases.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/interfaces/IPhases.java
new file mode 100644
index 00000000..f98b67a9
--- /dev/null
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/interfaces/IPhases.java
@@ -0,0 +1,13 @@
+package unipotsdam.gf.interfaces;
+
+import unipotsdam.gf.core.management.project.Project;
+import unipotsdam.gf.core.states.ProjectPhase;
+
+public interface IPhases {
+    /**
+     * switch from one phase to the next
+     * @param projectPhase
+     * @param project
+     */
+    public void endPhase(ProjectPhase projectPhase, Project project);
+}
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/communication/service/CommunicationDummyService.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/communication/service/CommunicationDummyService.java
index 138e0d4a..c9c17f71 100644
--- a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/communication/service/CommunicationDummyService.java
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/communication/service/CommunicationDummyService.java
@@ -2,6 +2,7 @@ package unipotsdam.gf.modules.communication.service;
 
 import unipotsdam.gf.config.Constants;
 import unipotsdam.gf.core.management.Management;
+import unipotsdam.gf.core.management.project.Project;
 import unipotsdam.gf.core.management.user.User;
 import unipotsdam.gf.interfaces.ICommunication;
 import unipotsdam.gf.modules.communication.model.Message;
@@ -106,6 +107,12 @@ public class CommunicationDummyService implements ICommunication {
         System.out.println("sending email with message: "+ message.getMessage() + " to: "+ user.getEmail());
     }
 
+    @Override
+    public void sendMessageToUsers(Project project, String message) {
+        // TODO implement as email or directed message, popup after login or whatever
+        System.out.println("sending email with message: "+ message + " to: "+ project.getId());
+    }
+
     // TODO: remove after done implementing
     // just for postman testing
     public User getUser() {
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/DummyJournalImpl.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/DummyJournalImpl.java
new file mode 100644
index 00000000..469ac938
--- /dev/null
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/DummyJournalImpl.java
@@ -0,0 +1,33 @@
+package unipotsdam.gf.modules.journal;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import unipotsdam.gf.core.management.project.Project;
+import unipotsdam.gf.interfaces.IJournal;
+import unipotsdam.gf.modules.assessment.controller.model.StudentIdentifier;
+import unipotsdam.gf.modules.journal.service.DummyJournalService;
+
+public class DummyJournalImpl implements IJournal {
+
+
+    private Logger log = LoggerFactory.getLogger(DummyJournalImpl.class);
+
+    @Override
+    public String exportJournal(StudentIdentifier student) {
+        // TODO Impl was macht das hier?
+
+        return null;
+    }
+
+    @Override
+    public Boolean getPortfoliosForEvaluationPrepared(Project project) {
+
+        log.debug("checking fake constraints for the portfolio evaluation");
+        return false;
+    }
+
+    @Override
+    public void assignMissingPortfolioTasks(Project project) {
+        log.debug("assigning fake MissingPortfolioTasks");
+    }
+}
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/model/Journal.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/model/Journal.java
index 65a17d1f..16d31e35 100644
--- a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/model/Journal.java
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/model/Journal.java
@@ -3,7 +3,7 @@ package unipotsdam.gf.modules.journal.model;
 
 import unipotsdam.gf.modules.assessment.controller.model.StudentIdentifier;
 
-import static unipotsdam.gf.core.management.utils.MarkdownUtils.convertMarkdownToHtml;
+import static unipotsdam.gf.view.MarkdownUtils.convertMarkdownToHtml;
 
 /**
  * Model Class for the learnig journal of the e-portfolio
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/model/ProjectDescription.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/model/ProjectDescription.java
index 7c73443a..51f14b21 100644
--- a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/model/ProjectDescription.java
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/journal/model/ProjectDescription.java
@@ -5,7 +5,7 @@ import unipotsdam.gf.core.management.project.Project;
 import java.util.ArrayList;
 import java.util.Map;
 
-import static unipotsdam.gf.core.management.utils.MarkdownUtils.convertMarkdownToHtml;
+import static unipotsdam.gf.view.MarkdownUtils.convertMarkdownToHtml;
 
 /**
  * Model class for the project descriptionHTML of the e portfolio
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/core/management/utils/Category.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/peer2peerfeedback/Category.java
similarity index 82%
rename from gemeinsamforschen/src/main/java/unipotsdam/gf/core/management/utils/Category.java
rename to gemeinsamforschen/src/main/java/unipotsdam/gf/modules/peer2peerfeedback/Category.java
index 0929f342..d371d339 100644
--- a/gemeinsamforschen/src/main/java/unipotsdam/gf/core/management/utils/Category.java
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/peer2peerfeedback/Category.java
@@ -1,4 +1,4 @@
-package unipotsdam.gf.core.management.utils;
+package unipotsdam.gf.modules.peer2peerfeedback;
 
 /**
  Categories for feedback and documents
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/peer2peerfeedback/DummyFeedback.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/peer2peerfeedback/DummyFeedback.java
new file mode 100644
index 00000000..a8a2d0d1
--- /dev/null
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/peer2peerfeedback/DummyFeedback.java
@@ -0,0 +1,43 @@
+package unipotsdam.gf.modules.peer2peerfeedback;
+
+import unipotsdam.gf.core.management.project.Project;
+import unipotsdam.gf.core.management.user.User;
+import unipotsdam.gf.interfaces.Feedback;
+
+import java.io.File;
+import java.util.ArrayList;
+
+public class DummyFeedback implements Feedback {
+    @Override
+    public Peer2PeerFeedback createPeer2PeerFeedbackmask(
+            User feedbackuser, User selectedstudent, File document) {
+        return null;
+    }
+
+    @Override
+    public Boolean giveFeedback(Peer2PeerFeedback feedback, File document) {
+        return null;
+    }
+
+    @Override
+    public ArrayList<Peer2PeerFeedback> showFeedback(User student) {
+        return null;
+    }
+
+    @Override
+    public int countFeedback(User student) {
+        return 0;
+    }
+
+    @Override
+    public Boolean checkFeedbackConstraints(Project project) {
+        // TODO implement cornstaints
+        System.out.println("Checking fake constraints");
+        return true;
+    }
+
+    @Override
+    public void assigningMissingFeedbackTasks(Project project) {
+        System.out.println("assigning fake tasks");
+    }
+}
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/peer2peerfeedback/ExampleFeedback.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/peer2peerfeedback/ExampleFeedback.java
index bc040fad..9b44f2d2 100644
--- a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/peer2peerfeedback/ExampleFeedback.java
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/peer2peerfeedback/ExampleFeedback.java
@@ -1,7 +1,6 @@
 package unipotsdam.gf.modules.peer2peerfeedback;
 
 import unipotsdam.gf.core.management.user.User;
-import unipotsdam.gf.core.management.utils.Category;
 
 import java.io.File;
 
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/peer2peerfeedback/Peer2PeerFeedback.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/peer2peerfeedback/Peer2PeerFeedback.java
index d68e106f..55bd0e9d 100644
--- a/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/peer2peerfeedback/Peer2PeerFeedback.java
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/modules/peer2peerfeedback/Peer2PeerFeedback.java
@@ -1,7 +1,6 @@
 package unipotsdam.gf.modules.peer2peerfeedback;
 
 import unipotsdam.gf.core.management.user.User;
-import unipotsdam.gf.core.management.utils.Category;
 
 import java.io.File;
 
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/core/management/utils/MarkdownUtils.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/view/MarkdownUtils.java
similarity index 93%
rename from gemeinsamforschen/src/main/java/unipotsdam/gf/core/management/utils/MarkdownUtils.java
rename to gemeinsamforschen/src/main/java/unipotsdam/gf/view/MarkdownUtils.java
index 5d25997f..9f626e2c 100644
--- a/gemeinsamforschen/src/main/java/unipotsdam/gf/core/management/utils/MarkdownUtils.java
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/view/MarkdownUtils.java
@@ -1,4 +1,4 @@
-package unipotsdam.gf.core.management.utils;
+package unipotsdam.gf.view;
 
 import org.commonmark.node.Node;
 import org.commonmark.parser.Parser;
diff --git a/gemeinsamforschen/src/main/java/unipotsdam/gf/view/Messages.java b/gemeinsamforschen/src/main/java/unipotsdam/gf/view/Messages.java
new file mode 100644
index 00000000..986c7d74
--- /dev/null
+++ b/gemeinsamforschen/src/main/java/unipotsdam/gf/view/Messages.java
@@ -0,0 +1,20 @@
+package unipotsdam.gf.view;
+
+import unipotsdam.gf.core.management.project.Project;
+
+public class Messages {
+    public static String GroupFormation(Project project){
+        // TODO add link to site + markup
+        return "Die Gruppen wurden für den Kurs "+ project.getId() + " erstellt";
+    }
+
+    public static String NewFeedbackTask(Project project) {
+        // TODO add link to site + markup
+        return "Eine neue Feedbackaufgabe wurde für den Kurs "+ project.getId() + " erstellt";
+    }
+
+    public static String AssessmentPhaseStarted(Project project) {
+        // TODO add link to site + markup
+        return "Die Bewertungsphase hat begonnen. Bitte geht auf ... und macht ....";
+    }
+}
diff --git a/gemeinsamforschen/src/scripts/dbschema/fltrail.sql b/gemeinsamforschen/src/scripts/dbschema/fltrail.sql
index 906e40da..71f44c06 100644
--- a/gemeinsamforschen/src/scripts/dbschema/fltrail.sql
+++ b/gemeinsamforschen/src/scripts/dbschema/fltrail.sql
@@ -8,7 +8,7 @@ USE `fltrail`;
 
 CREATE TABLE if not exists `projects` (
 
-  `id`            varchar(400) NOT NULL,
+  `id`            varchar(100) NOT NULL,
 
   `password`      varchar(400) NOT NULL,
 
@@ -62,7 +62,7 @@ CREATE TABLE if not exists groupuser
 
 CREATE TABLE if not exists `tags` (
 
-  `projectId` varchar(400) NOT NULL,
+  `projectId` varchar(100) NOT NULL,
 
   `tag`       varchar(400) NOT NULL
 
@@ -74,7 +74,7 @@ CREATE TABLE if not exists `tags` (
 
 CREATE TABLE if not exists `users` (
 
-  `name`                varchar(400) NOT NULL,
+  `name`                varchar(100) NOT NULL,
 
   `password`            varchar(200) NOT NULL,
 
@@ -98,9 +98,9 @@ CREATE TABLE if not exists projectuser
 
 (
 
-  projectId varchar(400) NOT NULL,
+  projectId varchar(100) NOT NULL,
 
-  userId    varchar(400) NOT NULL
+  userId    varchar(100) NOT NULL
 
 )
 
@@ -124,7 +124,9 @@ CREATE TABLE if not exists projectuser
 
   PRIMARY KEY (`id`)
 
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;alter table users
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+alter table users
 
   add isStudent tinyint(1) default '1' null;
 
@@ -163,4 +165,8 @@ CREATE TABLE if not exists tasks
 
   ENGINE = InnoDB
 
-  DEFAULT CHARSET = utf8;
\ No newline at end of file
+  DEFAULT CHARSET = utf8;
+
+ALTER TABLE `projectuser` ADD INDEX( `projectId`, `userId`);
+ALTER TABLE `projectuser` ADD UNIQUE( `projectId`, `userId`);
+ALTER TABLE `projects` ADD UNIQUE( `id`);
\ No newline at end of file
diff --git a/gemeinsamforschen/src/test/java/unipotsdam/gf/interfaces/ManagementTest.java b/gemeinsamforschen/src/test/java/unipotsdam/gf/interfaces/ManagementTest.java
index 8e71c0dc..22b28226 100644
--- a/gemeinsamforschen/src/test/java/unipotsdam/gf/interfaces/ManagementTest.java
+++ b/gemeinsamforschen/src/test/java/unipotsdam/gf/interfaces/ManagementTest.java
@@ -1,6 +1,15 @@
 package unipotsdam.gf.interfaces;
 
+import javafx.application.Application;
+import org.glassfish.hk2.api.ServiceLocator;
+import org.glassfish.hk2.utilities.Binder;
+import org.glassfish.hk2.utilities.ServiceLocatorUtilities;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.Before;
 import org.junit.Test;
+import unipotsdam.gf.config.GFApplicationBinder;
+import unipotsdam.gf.config.GFResourceConfig;
 import unipotsdam.gf.core.management.ManagementImpl;
 import unipotsdam.gf.core.management.project.Project;
 import unipotsdam.gf.core.management.user.User;
@@ -14,7 +23,11 @@ import static org.junit.Assert.assertTrue;
 /**
  * Created by dehne on 01.06.2018.
  */
-public class ManagementTest {
+
+
+public class ManagementTest  {
+
+
 
     @Test
     public void testDelete() {
@@ -90,6 +103,8 @@ public class ManagementTest {
         management.create(project);
         management.register(user, project, null);
 
+        assertTrue(management.exists(project));
+
         User user2 = new User("julian2", "12345", "from2@stuff.com", true);
         management.create(user2, new UserProfile());
         assert management.exists(user2);
diff --git a/gemeinsamforschen/src/test/java/unipotsdam/gf/interfaces/PhaseTest.java b/gemeinsamforschen/src/test/java/unipotsdam/gf/interfaces/PhaseTest.java
new file mode 100644
index 00000000..a4f54632
--- /dev/null
+++ b/gemeinsamforschen/src/test/java/unipotsdam/gf/interfaces/PhaseTest.java
@@ -0,0 +1,83 @@
+package unipotsdam.gf.interfaces;
+
+import org.glassfish.hk2.api.ServiceLocator;
+import org.glassfish.hk2.utilities.Binder;
+import org.glassfish.hk2.utilities.ServiceLocatorUtilities;
+import org.glassfish.hk2.utilities.binding.AbstractBinder;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import unipotsdam.gf.config.GFApplicationBinder;
+import unipotsdam.gf.config.GFResourceConfig;
+import unipotsdam.gf.core.management.ManagementImpl;
+import unipotsdam.gf.core.management.project.Project;
+import unipotsdam.gf.core.management.user.User;
+import unipotsdam.gf.core.management.user.UserProfile;
+import unipotsdam.gf.core.states.PhasesImpl;
+import unipotsdam.gf.core.states.ProjectPhase;
+
+import javax.inject.Inject;
+import javax.ws.rs.core.Application;
+
+
+public class PhaseTest {
+
+    @Inject
+    private IPhases phases;
+
+
+    @Before
+    public void setUp() {
+        final ServiceLocator locator = ServiceLocatorUtilities.bind(new GFApplicationBinder());
+        locator.inject(this);
+    }
+
+    @BeforeClass
+    public static void prepareProject() {
+        ManagementImpl management = new ManagementImpl();
+        User user = new User("julian", "1234", "from@stuff.com", false);
+        management.create(user, new UserProfile());
+        assert management.exists(user);
+
+        Project project = new Project("Gemainsam Forschen", "1235", true, "me", "keins");
+        management.create(project);
+        management.register(user, project, null);
+    }
+
+    @Test
+    public void phase1() {
+        Project project = new Project();
+        project.setId("Gemainsam Forschen");
+        phases.endPhase(ProjectPhase.CourseCreation, project);
+    }
+
+    @Test
+    public void phase2() {
+        Project project = new Project();
+        project.setId("Gemainsam Forschen");
+        phases.endPhase(ProjectPhase.GroupFormation, project);
+    }
+
+    @Test
+    public void phase3() {
+        Project project = new Project();
+        project.setId("Gemainsam Forschen");
+        phases.endPhase(ProjectPhase.DossierFeedback, project);
+    }
+
+    @Test
+    public void phase4() {
+        Project project = new Project();
+        project.setId("Gemainsam Forschen");
+        phases.endPhase(ProjectPhase.Execution, project);
+    }
+
+    @Test
+    public void phase5() {
+        Project project = new Project();
+        project.setId("Gemainsam Forschen");
+        phases.endPhase(ProjectPhase.Assessment, project);
+    }
+}
-- 
GitLab