Improve supervisor change integration #114
@ -1,7 +1,10 @@
|
|||||||
package se.su.dsv.scipro.reusable;
|
package se.su.dsv.scipro.reusable;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.util.ArrayList;
|
||||||
import java.util.*;
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public final class SciProUtilities {
|
public final class SciProUtilities {
|
||||||
|
|
||||||
@ -75,15 +78,4 @@ public final class SciProUtilities {
|
|||||||
}
|
}
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Calendar toCalendar(final LocalDate localDate) {
|
|
||||||
if (localDate == null) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
final Calendar calendar = Calendar.getInstance();
|
|
||||||
calendar.clear();
|
|
||||||
calendar.set(localDate.getYear(), localDate.getMonthValue() - 1, localDate.getDayOfMonth());
|
|
||||||
return calendar;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,10 @@
|
|||||||
parseMethod="jakarta.xml.bind.DatatypeConverter.parseDateTime"
|
parseMethod="jakarta.xml.bind.DatatypeConverter.parseDateTime"
|
||||||
printMethod="jakarta.xml.bind.DatatypeConverter.printDateTime" />
|
printMethod="jakarta.xml.bind.DatatypeConverter.printDateTime" />
|
||||||
|
|
||||||
|
<jaxb:javaType name="java.time.LocalDate" xmlType="xs:date"
|
||||||
|
parseMethod="java.time.LocalDate.parse"
|
||||||
|
printMethod="java.time.format.DateTimeFormatter.ISO_LOCAL_DATE.format" />
|
||||||
|
|
||||||
<!-- Force all classes implements Serializable -->
|
<!-- Force all classes implements Serializable -->
|
||||||
<xjc:simple />
|
<xjc:simple />
|
||||||
<xjc:serializable uid="1" />
|
<xjc:serializable uid="1" />
|
||||||
|
@ -375,14 +375,16 @@
|
|||||||
</xs:element>
|
</xs:element>
|
||||||
<xs:element name="title_en" type="xs:string" minOccurs="0">
|
<xs:element name="title_en" type="xs:string" minOccurs="0">
|
||||||
</xs:element>
|
</xs:element>
|
||||||
<xs:element name="startDate" type="xs:dateTime" minOccurs="0">
|
<xs:element name="startDate" type="xs:date" minOccurs="0">
|
||||||
</xs:element>
|
</xs:element>
|
||||||
<xs:element name="endDate" type="xs:dateTime" minOccurs="0">
|
<xs:element name="endDate" type="xs:date" minOccurs="0">
|
||||||
</xs:element>
|
</xs:element>
|
||||||
<xs:element name="unit" type="serializableUnit" minOccurs="0">
|
<xs:element name="unit" type="serializableUnit" minOccurs="0">
|
||||||
</xs:element>
|
</xs:element>
|
||||||
<xs:element name="researchAreas" type="researchAreas" minOccurs="0">
|
<xs:element name="researchAreas" type="researchAreas" minOccurs="0">
|
||||||
</xs:element>
|
</xs:element>
|
||||||
|
<xs:element name="externalID" type="xs:string" minOccurs="0">
|
||||||
|
</xs:element>
|
||||||
</xs:sequence>
|
</xs:sequence>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
|
|
||||||
@ -390,13 +392,15 @@
|
|||||||
<xs:sequence>
|
<xs:sequence>
|
||||||
<xs:element name="title_en" type="xs:string" minOccurs="0">
|
<xs:element name="title_en" type="xs:string" minOccurs="0">
|
||||||
</xs:element>
|
</xs:element>
|
||||||
|
<xs:element name="externalID" type="xs:string" minOccurs="0">
|
||||||
|
</xs:element>
|
||||||
<xs:element name="aborted" type="xs:boolean" minOccurs="1">
|
<xs:element name="aborted" type="xs:boolean" minOccurs="1">
|
||||||
</xs:element>
|
</xs:element>
|
||||||
<xs:element name="level" type="educationalLevel" minOccurs="0">
|
<xs:element name="level" type="educationalLevel" minOccurs="0">
|
||||||
</xs:element>
|
</xs:element>
|
||||||
<xs:element name="title" type="xs:string" minOccurs="0">
|
<xs:element name="title" type="xs:string" minOccurs="0">
|
||||||
</xs:element>
|
</xs:element>
|
||||||
<xs:element name="endDate" type="xs:dateTime" minOccurs="0">
|
<xs:element name="endDate" type="xs:date" minOccurs="0">
|
||||||
</xs:element>
|
</xs:element>
|
||||||
<xs:element name="status" type="STATUS" minOccurs="0">
|
<xs:element name="status" type="STATUS" minOccurs="0">
|
||||||
</xs:element>
|
</xs:element>
|
||||||
@ -404,7 +408,7 @@
|
|||||||
</xs:element>
|
</xs:element>
|
||||||
<xs:element name="finished" type="xs:boolean" minOccurs="1">
|
<xs:element name="finished" type="xs:boolean" minOccurs="1">
|
||||||
</xs:element>
|
</xs:element>
|
||||||
<xs:element name="startDate" type="xs:dateTime" minOccurs="0">
|
<xs:element name="startDate" type="xs:date" minOccurs="0">
|
||||||
</xs:element>
|
</xs:element>
|
||||||
<xs:element name="id" type="xs:int" minOccurs="1">
|
<xs:element name="id" type="xs:int" minOccurs="1">
|
||||||
</xs:element>
|
</xs:element>
|
||||||
@ -475,9 +479,11 @@
|
|||||||
</xs:element>
|
</xs:element>
|
||||||
<xs:element name="title_en" type="xs:string" minOccurs="0">
|
<xs:element name="title_en" type="xs:string" minOccurs="0">
|
||||||
</xs:element>
|
</xs:element>
|
||||||
<xs:element name="startDate" type="xs:dateTime" minOccurs="0">
|
<xs:element name="externalID" type="xs:string" minOccurs="0">
|
||||||
</xs:element>
|
</xs:element>
|
||||||
<xs:element name="endDate" type="xs:dateTime" minOccurs="0">
|
<xs:element name="startDate" type="xs:date" minOccurs="0">
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="endDate" type="xs:date" minOccurs="0">
|
||||||
</xs:element>
|
</xs:element>
|
||||||
<xs:element name="aborted" type="xs:boolean" minOccurs="1">
|
<xs:element name="aborted" type="xs:boolean" minOccurs="1">
|
||||||
</xs:element>
|
</xs:element>
|
||||||
|
@ -4,10 +4,9 @@ import static com.querydsl.core.types.dsl.Expressions.anyOf;
|
|||||||
|
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import jakarta.inject.Named;
|
import jakarta.inject.Named;
|
||||||
import jakarta.ws.rs.core.Response;
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
import java.time.LocalDate;
|
||||||
import java.time.Period;
|
import java.time.Period;
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -38,7 +37,6 @@ import se.su.dsv.scipro.project.Project;
|
|||||||
import se.su.dsv.scipro.project.ProjectRepo;
|
import se.su.dsv.scipro.project.ProjectRepo;
|
||||||
import se.su.dsv.scipro.project.ProjectStatus;
|
import se.su.dsv.scipro.project.ProjectStatus;
|
||||||
import se.su.dsv.scipro.project.QProject;
|
import se.su.dsv.scipro.project.QProject;
|
||||||
import se.su.dsv.scipro.reusable.SciProUtilities;
|
|
||||||
import se.su.dsv.scipro.system.DegreeType;
|
import se.su.dsv.scipro.system.DegreeType;
|
||||||
import se.su.dsv.scipro.system.User;
|
import se.su.dsv.scipro.system.User;
|
||||||
import se.su.dsv.scipro.workerthreads.AbstractWorker;
|
import se.su.dsv.scipro.workerthreads.AbstractWorker;
|
||||||
@ -198,7 +196,7 @@ public class ProjectExporter extends AbstractWorker {
|
|||||||
UnitWithID unit = new UnitWithID();
|
UnitWithID unit = new UnitWithID();
|
||||||
unit.setId(project.getHeadSupervisor().getUnit().getIdentifier());
|
unit.setId(project.getHeadSupervisor().getUnit().getIdentifier());
|
||||||
|
|
||||||
Calendar startDate = SciProUtilities.toCalendar(project.getStartDate());
|
LocalDate startDate = project.getStartDate();
|
||||||
|
|
||||||
String title = finalThesis
|
String title = finalThesis
|
||||||
.map(FinalThesis::getSwedishTitle)
|
.map(FinalThesis::getSwedishTitle)
|
||||||
@ -211,7 +209,7 @@ public class ProjectExporter extends AbstractWorker {
|
|||||||
thesis.setUnit(unit);
|
thesis.setUnit(unit);
|
||||||
thesis.setAborted(project.getProjectStatus() == ProjectStatus.INACTIVE);
|
thesis.setAborted(project.getProjectStatus() == ProjectStatus.INACTIVE);
|
||||||
thesis.setStartDate(startDate);
|
thesis.setStartDate(startDate);
|
||||||
thesis.setEndDate(SciProUtilities.toCalendar(project.getExpectedEndDate()));
|
thesis.setEndDate(project.getExpectedEndDate());
|
||||||
final ResearchAreas researchAreas = new ResearchAreas();
|
final ResearchAreas researchAreas = new ResearchAreas();
|
||||||
if (project.getResearchArea() != null && project.getResearchArea().getIdentifier() != null) {
|
if (project.getResearchArea() != null && project.getResearchArea().getIdentifier() != null) {
|
||||||
final ResearchAreaWithID researchArea2 = new ResearchAreaWithID();
|
final ResearchAreaWithID researchArea2 = new ResearchAreaWithID();
|
||||||
@ -260,36 +258,14 @@ public class ProjectExporter extends AbstractWorker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateHeadSupervisor(Project project) throws ExternalExportException {
|
private void updateHeadSupervisor(Project project) throws ExternalExportException {
|
||||||
boolean toAdd = true;
|
boolean shouldChange = true;
|
||||||
Set<ProjectParticipant> contributors = daisyAPI.getContributors(project.getIdentifier());
|
Set<ProjectParticipant> contributors = daisyAPI.getContributors(project.getIdentifier());
|
||||||
for (ProjectParticipant contributor : contributors) {
|
for (ProjectParticipant contributor : contributors) {
|
||||||
if (contributor.getRole() == Role.SUPERVISOR) {
|
if (contributor.getRole() == Role.SUPERVISOR) {
|
||||||
if (contributor.getPerson().getId().equals(project.getHeadSupervisor().getIdentifier())) {
|
shouldChange = !contributor.getPerson().getId().equals(project.getHeadSupervisor().getIdentifier());
|
||||||
toAdd = false;
|
|
||||||
} else {
|
|
||||||
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 (shouldChange) {
|
||||||
}
|
|
||||||
if (toAdd) {
|
|
||||||
externalExporter.addContributorToProject(project, project.getHeadSupervisor(), Role.SUPERVISOR);
|
externalExporter.addContributorToProject(project, project.getHeadSupervisor(), Role.SUPERVISOR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package se.su.dsv.scipro.io.impl;
|
|||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import jakarta.ws.rs.core.Response;
|
import jakarta.ws.rs.core.Response;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.Calendar;
|
import java.time.LocalDate;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import se.su.dsv.scipro.daisyexternal.http.DaisyAPI;
|
import se.su.dsv.scipro.daisyexternal.http.DaisyAPI;
|
||||||
@ -21,7 +21,6 @@ import se.su.dsv.scipro.io.dto.ThesisToBeCreated;
|
|||||||
import se.su.dsv.scipro.io.dto.UnitWithID;
|
import se.su.dsv.scipro.io.dto.UnitWithID;
|
||||||
import se.su.dsv.scipro.io.exceptions.ExternalExportException;
|
import se.su.dsv.scipro.io.exceptions.ExternalExportException;
|
||||||
import se.su.dsv.scipro.project.Project;
|
import se.su.dsv.scipro.project.Project;
|
||||||
import se.su.dsv.scipro.reusable.SciProUtilities;
|
|
||||||
import se.su.dsv.scipro.system.Unit;
|
import se.su.dsv.scipro.system.Unit;
|
||||||
import se.su.dsv.scipro.system.User;
|
import se.su.dsv.scipro.system.User;
|
||||||
|
|
||||||
@ -46,9 +45,9 @@ public class ExternalExporterDaisyImpl implements ExternalExporter {
|
|||||||
|
|
||||||
ThesisToBeCreated exportProjectDTO = new ThesisToBeCreated();
|
ThesisToBeCreated exportProjectDTO = new ThesisToBeCreated();
|
||||||
exportProjectDTO.setTitle(truncate(project.getTitle()));
|
exportProjectDTO.setTitle(truncate(project.getTitle()));
|
||||||
Calendar startDate = SciProUtilities.toCalendar(project.getStartDate());
|
LocalDate startDate = project.getStartDate();
|
||||||
exportProjectDTO.setStartDate(startDate);
|
exportProjectDTO.setStartDate(startDate);
|
||||||
exportProjectDTO.setEndDate(SciProUtilities.toCalendar(project.getExpectedEndDate()));
|
exportProjectDTO.setEndDate(project.getExpectedEndDate());
|
||||||
exportProjectDTO.setUnit(unitDTO);
|
exportProjectDTO.setUnit(unitDTO);
|
||||||
final ResearchAreas researchAreas = new ResearchAreas();
|
final ResearchAreas researchAreas = new ResearchAreas();
|
||||||
if (project.getResearchArea() != null && project.getResearchArea().getIdentifier() != null) {
|
if (project.getResearchArea() != null && project.getResearchArea().getIdentifier() != null) {
|
||||||
|
@ -2,6 +2,7 @@ package se.su.dsv.scipro.integration.daisy.workers;
|
|||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.mockito.ArgumentMatchers.*;
|
import static org.mockito.ArgumentMatchers.*;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@ -144,22 +145,61 @@ public class ProjectExporterTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deletes_wrong_head_supervisor() {
|
public void change_head_supervisor() throws Exception {
|
||||||
Person person = new Person();
|
User newSupervisor = User.builder()
|
||||||
person.setId(234234);
|
.firstName("New")
|
||||||
|
.lastName("Supervisor")
|
||||||
|
.emailAddress("new@supervisor.com")
|
||||||
|
.build();
|
||||||
|
Unit unit = new Unit();
|
||||||
|
unit.setIdentifier(239478);
|
||||||
|
|
||||||
ProjectParticipant headSupervisor = new ProjectParticipant();
|
newSupervisor.setIdentifier(12345);
|
||||||
headSupervisor.setRole(Role.SUPERVISOR);
|
newSupervisor.setUnit(unit);
|
||||||
headSupervisor.setPerson(person);
|
exportedProject.setHeadSupervisor(newSupervisor);
|
||||||
|
|
||||||
Set<ProjectParticipant> contributors = new HashSet<>();
|
Set<ProjectParticipant> contributors = new HashSet<>();
|
||||||
contributors.add(headSupervisor);
|
ProjectParticipant oldSupervisor = new ProjectParticipant();
|
||||||
|
oldSupervisor.setRole(Role.SUPERVISOR);
|
||||||
|
Person oldPerson = new Person();
|
||||||
|
oldPerson.setId(SUPERVISOR_IDENTIFIER);
|
||||||
|
oldSupervisor.setPerson(oldPerson);
|
||||||
|
contributors.add(oldSupervisor);
|
||||||
|
|
||||||
when(daisyAPI.getContributors(exportedProject.getIdentifier())).thenReturn(contributors);
|
when(daisyAPI.getContributors(exportedProject.getIdentifier())).thenReturn(contributors);
|
||||||
|
|
||||||
projectExporter.run();
|
projectExporter.run();
|
||||||
|
|
||||||
verify(daisyAPI).deleteThesisPerson(exportedProject.getIdentifier(), person.getId());
|
verify(externalExporter).addContributorToProject(exportedProject, newSupervisor, Role.SUPERVISOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void should_not_change_head_supervisor_if_already_exists() throws Exception {
|
||||||
|
User newSupervisor = User.builder()
|
||||||
|
.firstName("New")
|
||||||
|
.lastName("Supervisor")
|
||||||
|
.emailAddress("new@supervisor.com")
|
||||||
|
.build();
|
||||||
|
Unit unit = new Unit();
|
||||||
|
unit.setIdentifier(239478);
|
||||||
|
|
||||||
|
newSupervisor.setIdentifier(SUPERVISOR_IDENTIFIER);
|
||||||
|
newSupervisor.setUnit(unit);
|
||||||
|
exportedProject.setHeadSupervisor(newSupervisor);
|
||||||
|
|
||||||
|
Set<ProjectParticipant> contributors = new HashSet<>();
|
||||||
|
ProjectParticipant oldSupervisor = new ProjectParticipant();
|
||||||
|
oldSupervisor.setRole(Role.SUPERVISOR);
|
||||||
|
Person oldPerson = new Person();
|
||||||
|
oldPerson.setId(SUPERVISOR_IDENTIFIER);
|
||||||
|
oldSupervisor.setPerson(oldPerson);
|
||||||
|
contributors.add(oldSupervisor);
|
||||||
|
|
||||||
|
when(daisyAPI.getContributors(exportedProject.getIdentifier())).thenReturn(contributors);
|
||||||
|
|
||||||
|
projectExporter.run();
|
||||||
|
|
||||||
|
verify(externalExporter, never()).addContributorToProject(exportedProject, newSupervisor, Role.SUPERVISOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -19,7 +19,6 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
|||||||
import se.su.dsv.scipro.daisyexternal.http.DaisyAPI;
|
import se.su.dsv.scipro.daisyexternal.http.DaisyAPI;
|
||||||
import se.su.dsv.scipro.io.dto.ThesisToBeCreated;
|
import se.su.dsv.scipro.io.dto.ThesisToBeCreated;
|
||||||
import se.su.dsv.scipro.project.Project;
|
import se.su.dsv.scipro.project.Project;
|
||||||
import se.su.dsv.scipro.reusable.SciProUtilities;
|
|
||||||
import se.su.dsv.scipro.system.DegreeType;
|
import se.su.dsv.scipro.system.DegreeType;
|
||||||
import se.su.dsv.scipro.system.ProjectType;
|
import se.su.dsv.scipro.system.ProjectType;
|
||||||
import se.su.dsv.scipro.system.Unit;
|
import se.su.dsv.scipro.system.Unit;
|
||||||
@ -71,6 +70,6 @@ public class ExternalExporterDaisyImplTest {
|
|||||||
ArgumentCaptor<ThesisToBeCreated> captor = ArgumentCaptor.forClass(ThesisToBeCreated.class);
|
ArgumentCaptor<ThesisToBeCreated> captor = ArgumentCaptor.forClass(ThesisToBeCreated.class);
|
||||||
verify(daisyAPI).createProject(captor.capture());
|
verify(daisyAPI).createProject(captor.capture());
|
||||||
|
|
||||||
assertEquals(captor.getValue().getStartDate(), SciProUtilities.toCalendar(daisyStartDate));
|
assertEquals(captor.getValue().getStartDate(), daisyStartDate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user