From 03ad12f4356e1c8d99aa2d59374b73354b9a20df Mon Sep 17 00:00:00 2001
From: Andreas Svanberg <andreass@dsv.su.se>
Date: Mon, 2 Dec 2024 11:28:37 +0100
Subject: [PATCH] Do not add duplicate supervisors in Daisy (#26)

Daisy's API does not support the function "change supervisor" and only what comes down to SQL INSERT and DELETE on a specific table. If the removal of the previous supervisor(s) failed the new one was still added. This change makes it so that if the removal of any (there is no limit in the API) current supervisor fails it will not attempt to add the new supervisor.

Fixes #39

## How to test
1. Configure the Daisy integration in SciPro
2. Enable it (Maven profile)
3. The only currently known way to make removing a supervisor fail is to use a project where they've sent the thesis to the examiner
4. Find one such project in the test server for Daisy (or send one for examination from SciPro)
5. Change the supervisor of the project in SciPro
6. Run the job "Export projects to daisy" (System / Maintenance)
7. See that it logs the failure and that no duplicate supervisors were added to Daisy

Reviewed-on: https://gitea.dsv.su.se/DMC/scipro/pulls/26
Reviewed-by: Tom Zhao <tom.zhao@dsv.su.se>
Co-authored-by: Andreas Svanberg <andreass@dsv.su.se>
Co-committed-by: Andreas Svanberg <andreass@dsv.su.se>
---
 .../scipro/daisyExternal/http/DaisyAPI.java   |  2 +-
 .../daisyExternal/http/DaisyAPIImpl.java      |  4 ++--
 .../daisy/workers/ProjectExporter.java        | 22 +++++++++++++++----
 3 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/core/src/main/java/se/su/dsv/scipro/daisyExternal/http/DaisyAPI.java b/core/src/main/java/se/su/dsv/scipro/daisyExternal/http/DaisyAPI.java
index a69b109f06..8c7fdf7b79 100644
--- a/core/src/main/java/se/su/dsv/scipro/daisyExternal/http/DaisyAPI.java
+++ b/core/src/main/java/se/su/dsv/scipro/daisyExternal/http/DaisyAPI.java
@@ -30,7 +30,7 @@ public interface DaisyAPI {
 
     Response addContributor(Integer projectId, ProjectParticipant contributor);
 
-    void deleteThesisPerson(Integer projectId, Integer personId);
+    Response deleteThesisPerson(Integer projectId, Integer personId);
 
     Response createProject(ThesisToBeCreated project);
 
diff --git a/core/src/main/java/se/su/dsv/scipro/daisyExternal/http/DaisyAPIImpl.java b/core/src/main/java/se/su/dsv/scipro/daisyExternal/http/DaisyAPIImpl.java
index 7c2f6a7142..393e5e66ed 100755
--- a/core/src/main/java/se/su/dsv/scipro/daisyExternal/http/DaisyAPIImpl.java
+++ b/core/src/main/java/se/su/dsv/scipro/daisyExternal/http/DaisyAPIImpl.java
@@ -157,8 +157,8 @@ public class DaisyAPIImpl implements DaisyAPI {
     }
 
     @Override
-    public void deleteThesisPerson(Integer projectId, Integer personId) {
-        thesis()
+    public Response deleteThesisPerson(Integer projectId, Integer personId) {
+        return thesis()
                 .path(String.valueOf(projectId))
                 .path(PERSON)
                 .path(String.valueOf(personId))
diff --git a/daisy-integration/src/main/java/se/su/dsv/scipro/integration/daisy/workers/ProjectExporter.java b/daisy-integration/src/main/java/se/su/dsv/scipro/integration/daisy/workers/ProjectExporter.java
index 063b799079..049b6c2e94 100644
--- a/daisy-integration/src/main/java/se/su/dsv/scipro/integration/daisy/workers/ProjectExporter.java
+++ b/daisy-integration/src/main/java/se/su/dsv/scipro/integration/daisy/workers/ProjectExporter.java
@@ -23,6 +23,7 @@ import se.su.dsv.scipro.workerthreads.AbstractWorker;
 
 import jakarta.inject.Inject;
 import jakarta.inject.Named;
+import jakarta.ws.rs.core.Response;
 import java.time.Instant;
 import java.time.Period;
 import java.util.Calendar;
@@ -240,18 +241,31 @@ public class ProjectExporter extends AbstractWorker {
     }
 
     private void updateHeadSupervisor(Project project) throws ExternalExportException {
-        boolean add = true;
+        boolean toAdd = true;
         Set<ProjectParticipant> contributors = daisyAPI.getContributors(project.getIdentifier());
         for (ProjectParticipant contributor : contributors) {
             if (contributor.getRole() == Role.SUPERVISOR) {
                 if (contributor.getPerson().getId().equals(project.getHeadSupervisor().getIdentifier())) {
-                    add = false;
+                    toAdd = false;
                 } else {
-                    daisyAPI.deleteThesisPerson(project.getIdentifier(), contributor.getPerson().getId());
+                    Response response = daisyAPI.deleteThesisPerson(project.getIdentifier(), contributor.getPerson().getId());
+                    if (response.getStatusInfo().getFamily() != Response.Status.Family.SUCCESSFUL) {
+                        LOG.warn("Failed to delete supervisor from project: {} (id: {} / {})",
+                                project.getTitle(),
+                                project.getId(),
+                                project.getIdentifier());
+
+                        // Card 3413
+                        // Do not attempt to add the new supervisor if the old one is still there to prevent
+                        // the project from having multiple supervisors.
+                        // Hopefully Daisy API will soon have support for the function "change supervisor"
+                        // rather than just INSERT and DELETE rows in a table.
+                        toAdd = false;
+                    }
                 }
             }
         }
-        if (add) {
+        if (toAdd) {
             externalExporter.addContributorToProject(project, project.getHeadSupervisor(), Role.SUPERVISOR);
         }
     }