3122 Stöd för manuell hantering av slutsem för handledare
This commit is contained in:
parent
9100e593a8
commit
5905308085
core/src
main/java/se/su/dsv/scipro
finalseminar
match
project
test/java/se/su/dsv/scipro/project
view/src
main
java/se/su/dsv/scipro
finalseminar
match
webapp/css
test/java/se/su/dsv/scipro/match
@ -274,9 +274,7 @@ public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, L
|
||||
@Override
|
||||
@Transactional
|
||||
public Either<OpposeError, FinalSeminarOpposition> attemptAddOppositionAsSupervisor(User student, FinalSeminar finalSeminar, Project project) {
|
||||
if (!project.isParticipant(student)) {
|
||||
return Either.left(OpposeError.NotAuthorOfSameProjectType);
|
||||
} else if (finalSeminar.getActiveParticipants().contains(student)) {
|
||||
if (finalSeminar.getActiveParticipants().contains(student)) {
|
||||
return Either.left(OpposeError.AlreadyParticipant);
|
||||
} else if (finalSeminar.getOpponents().contains(student)) {
|
||||
return Either.left(OpposeError.AlreadyOpponent);
|
||||
@ -305,9 +303,7 @@ public class FinalSeminarServiceImpl extends AbstractServiceImpl<FinalSeminar, L
|
||||
@Override
|
||||
@Transactional
|
||||
public Either<ParticipateError, FinalSeminarActiveParticipation> attemptAddActiveParticipationAsSupervisor(User student, FinalSeminar finalSeminar, Project project) {
|
||||
if (!project.isParticipant(student)) {
|
||||
return Either.left(ParticipateError.NotAuthorOfSameProjectType);
|
||||
} else if (finalSeminar.getActiveParticipants().contains(student)) {
|
||||
if (finalSeminar.getActiveParticipants().contains(student)) {
|
||||
return Either.left(ParticipateError.AlreadyParticipant);
|
||||
} else if (finalSeminar.getOpponents().contains(student)) {
|
||||
return Either.left(ParticipateError.AlreadyOpponent);
|
||||
|
@ -1,5 +1,5 @@
|
||||
package se.su.dsv.scipro.finalseminar;
|
||||
|
||||
public enum OpposeError {
|
||||
AlreadyOpponent, AlreadyParticipant, NotAuthorOfSameProjectType
|
||||
AlreadyOpponent, AlreadyParticipant
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
package se.su.dsv.scipro.finalseminar;
|
||||
|
||||
public enum ParticipateError {
|
||||
AlreadyOpponent, AlreadyParticipant, NotAuthorOfSameProjectType
|
||||
AlreadyOpponent, AlreadyParticipant
|
||||
}
|
@ -192,7 +192,7 @@ public class IdeaServiceImpl extends AbstractServiceImpl<Idea, Long> implements
|
||||
if (idea.getProjectType().getProjectTypeSettings().getMinAuthors() > 1 && coAuthor == null && !applicationPeriodService.hasIdeaSizeExemption(creator, ap)) {
|
||||
return new Pair<>(Boolean.FALSE, BACHELOR_NEED_PARTNER_ERROR);
|
||||
}
|
||||
if (!projectService.getActiveProjects(creator, idea.getProjectType()).isEmpty()) {
|
||||
if (!projectService.getActiveProjectsByUserAndProjectType(creator, idea.getProjectType()).isEmpty()) {
|
||||
return new Pair<>(Boolean.FALSE, MessageFormat.format(ALREADY_HAVE_AN_ACTIVE_PROJECT, generalSystemSettingsInstance.getActiveProjectIdeaSupportMail()));
|
||||
}
|
||||
if (coAuthor != null) {
|
||||
@ -205,7 +205,7 @@ public class IdeaServiceImpl extends AbstractServiceImpl<Idea, Long> implements
|
||||
if (coAuthor.getDegreeType() != ProjectType.UNKNOWN && coAuthor.getDegreeType() != idea.getProjectType().getDegreeType()) {
|
||||
return new Pair<>(Boolean.FALSE, WRONG_LEVEL_FOR_YOUR_PARTNER);
|
||||
}
|
||||
if (!projectService.getActiveProjects(coAuthor, idea.getProjectType()).isEmpty()) {
|
||||
if (!projectService.getActiveProjectsByUserAndProjectType(coAuthor, idea.getProjectType()).isEmpty()) {
|
||||
return new Pair<>(Boolean.FALSE, MessageFormat.format(PARTNER_ALREADY_HAS_ACTIVE_PROJECT, generalSystemSettingsInstance.getActiveProjectIdeaSupportMail()));
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,9 @@ public interface ProjectService extends GenericService<Project, Long>, FilteredS
|
||||
|
||||
Member.Type getMemberType(Project project, User user);
|
||||
|
||||
List<Project> getActiveProjects(User author, ProjectType pc);
|
||||
List<Project> getActiveProjectsByUserAndProjectType(User author, ProjectType pc);
|
||||
|
||||
List<Project> getActiveProjectsByUser(User author);
|
||||
|
||||
List<Project> findAll(Filter params);
|
||||
|
||||
|
@ -126,10 +126,15 @@ public class ProjectServiceImpl extends AbstractServiceImpl<Project, Long> imple
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Project> getActiveProjects(User author, ProjectType pc) {
|
||||
public List<Project> getActiveProjectsByUserAndProjectType(User author, ProjectType pc) {
|
||||
return findAll(hasStatus(ProjectStatus.ACTIVE).and(hasProjectType(pc)).and(isAuthor(author)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Project> getActiveProjectsByUser(User author) {
|
||||
return findAll(hasStatus(ProjectStatus.ACTIVE).and(isAuthor(author)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Project> findAll(Filter params) {
|
||||
return findAll(toPredicate(params));
|
||||
|
@ -137,7 +137,7 @@ public class ProjectServiceImplIntegrationTest extends IntegrationTest {
|
||||
project = save(project);
|
||||
List<Project> expectedList = Collections.singletonList(project);
|
||||
|
||||
assertEquals(expectedList, projectService.getActiveProjects(user, projectType));
|
||||
assertEquals(expectedList, projectService.getActiveProjectsByUserAndProjectType(user, projectType));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -187,9 +187,8 @@ public class SeminarCRUDPanel extends GenericPanel<FinalSeminar> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Optional<Project> getPotentialParticipantProject(User participant, ProjectType projectType) {
|
||||
List<Project> projects = projectService.getActiveProjects(participant, projectType);
|
||||
private Optional<Project> getPotentialParticipantProjectForUserAndType(User participant, ProjectType projectType) {
|
||||
List<Project> projects = projectService.getActiveProjectsByUserAndProjectType(participant, projectType);
|
||||
if (projects.size() == 1) {
|
||||
return Optional.of(projects.get(0));
|
||||
} else {
|
||||
@ -197,11 +196,28 @@ public class SeminarCRUDPanel extends GenericPanel<FinalSeminar> {
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<Project> getPotentialParticipantProjectForUser(User participant) {
|
||||
List<Project> projects = projectService.getActiveProjectsByUser(participant);
|
||||
projects.sort(Comparator.comparing(Project::getStartDate).reversed());
|
||||
if (!projects.isEmpty()) {
|
||||
return Optional.of(projects.get(0));
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
private void addActiveParticipants(FinalSeminar finalSeminar) {
|
||||
for (User potentialParticipant : activeParticipants.getModelObject()) {
|
||||
Optional<Project> maybeProject = getPotentialParticipantProject(potentialParticipant, finalSeminar.getProjectType());
|
||||
boolean authorHasActiveProject;
|
||||
Optional<Project> maybeProject = getPotentialParticipantProjectForUserAndType(potentialParticipant, finalSeminar.getProjectType());
|
||||
if (maybeProject.isEmpty()) {
|
||||
error(getString("opponent.no.project", Model.of(potentialParticipant)));
|
||||
maybeProject = getPotentialParticipantProjectForUser(potentialParticipant);
|
||||
authorHasActiveProject = false;
|
||||
} else {
|
||||
authorHasActiveProject = true;
|
||||
}
|
||||
if (maybeProject.isEmpty()) {
|
||||
error(getString("UserHasNoActiveProject", Model.of(potentialParticipant)));
|
||||
} else {
|
||||
final Project project = maybeProject.get();
|
||||
Either<ParticipateError, FinalSeminarActiveParticipation> result = seminarService.attemptAddActiveParticipationAsSupervisor(potentialParticipant, finalSeminar, project);
|
||||
@ -212,17 +228,16 @@ public class SeminarCRUDPanel extends GenericPanel<FinalSeminar> {
|
||||
error(potentialParticipant.getFullName() + " that you selected as an active participant is already an opponent");
|
||||
case AlreadyParticipant ->
|
||||
error(potentialParticipant.getFullName() + " that you selected as an active participant is already an active participant");
|
||||
case NotAuthorOfSameProjectType ->
|
||||
error("Failed to add " + potentialParticipant.getFullName() + " as an active participant: Not an author of a project of the same type");
|
||||
}
|
||||
return false;
|
||||
},
|
||||
success -> {
|
||||
success("Added " + potentialParticipant.getFullName() + " as an opponent");
|
||||
success("Added " + potentialParticipant.getFullName() + " as a participant." +
|
||||
(authorHasActiveProject ? "" : " Note! " + potentialParticipant.getFullName() + " doesn't have a project of the same type"));
|
||||
events.add(SeminarEvent.Event.PARTICIPATION_CHANGED);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}String test = authorHasActiveProject ? "test" : "test2";
|
||||
}
|
||||
activeParticipants.clearInput();
|
||||
activeParticipants.getModel().setObject(Collections.emptyList());
|
||||
@ -230,10 +245,16 @@ public class SeminarCRUDPanel extends GenericPanel<FinalSeminar> {
|
||||
|
||||
private void addOpponents(FinalSeminar finalSeminar) {
|
||||
for (User potentialOpponent : opponents.getModelObject()) {
|
||||
Optional<Project> maybeProject = getPotentialParticipantProject(potentialOpponent, finalSeminar.getProjectType());
|
||||
|
||||
boolean authorHasActiveProject;
|
||||
Optional<Project> maybeProject = getPotentialParticipantProjectForUserAndType(potentialOpponent, finalSeminar.getProjectType());
|
||||
if (maybeProject.isEmpty()) {
|
||||
error(getString("opponent.no.project", Model.of(potentialOpponent)));
|
||||
maybeProject = getPotentialParticipantProjectForUser(potentialOpponent);
|
||||
authorHasActiveProject = false;
|
||||
} else {
|
||||
authorHasActiveProject = true;
|
||||
}
|
||||
if (maybeProject.isEmpty()) {
|
||||
error(getString("UserHasNoActiveProject", Model.of(potentialOpponent)));
|
||||
} else {
|
||||
final Project project = maybeProject.get();
|
||||
Either<OpposeError, FinalSeminarOpposition> result = seminarService.attemptAddOppositionAsSupervisor(potentialOpponent, finalSeminar, project);
|
||||
@ -244,20 +265,19 @@ public class SeminarCRUDPanel extends GenericPanel<FinalSeminar> {
|
||||
error(potentialOpponent.getFullName() + " that you selected as an opponent is already an opponent");
|
||||
case AlreadyParticipant ->
|
||||
error(potentialOpponent.getFullName() + " that you selected as an opponent is already an active participant");
|
||||
case NotAuthorOfSameProjectType ->
|
||||
error("Failed to add " + potentialOpponent.getFullName() + ": Not an author of a project of the same type");
|
||||
}
|
||||
return false;
|
||||
},
|
||||
success -> {
|
||||
success("Added " + potentialOpponent.getFullName() + " as an opponent");
|
||||
success("Added " + potentialOpponent.getFullName() + " as an opponent." +
|
||||
(authorHasActiveProject ? "" : " Note! " + potentialOpponent.getFullName() + " doesn't have a project of the same type"));
|
||||
events.add(SeminarEvent.Event.OPPOSITION_CHANGED);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
opponents.clearInput();
|
||||
opponents.getModel().setObject(Collections.emptyList());
|
||||
}
|
||||
opponents.clearInput();
|
||||
opponents.getModel().setObject(Collections.emptyList());
|
||||
}
|
||||
|
||||
private void saveSeminar(FinalSeminarDetails finalSeminarDetails) {
|
||||
|
@ -4,7 +4,7 @@ maxOpponents.RangeValidator.minimum=The selected number of max oppositions may n
|
||||
FinalSeminarLanguage.SWEDISH=Swedish
|
||||
# suppress inspection "UnusedProperty"
|
||||
FinalSeminarLanguage.ENGLISH=English
|
||||
opponent.no.project=${fullName} does not have an active project of this project type.
|
||||
UserHasNoActiveProject=${fullName} does not have an active project.
|
||||
final.seminar.updated=Final seminar saved
|
||||
create= Create
|
||||
update= Update
|
||||
|
@ -101,7 +101,7 @@ public class CompleteIdeaDialogPanel extends GenericPanel<Idea> {
|
||||
final ProjectType selectedProjectType = getModelObject().getProjectType();
|
||||
final boolean partnerHasActiveProject = coAuthorChoice.getModelObject()
|
||||
.stream()
|
||||
.map(partner -> projectService.getActiveProjects(partner, selectedProjectType))
|
||||
.map(partner -> projectService.getActiveProjectsByUserAndProjectType(partner, selectedProjectType))
|
||||
.flatMap(Collection::stream)
|
||||
.findAny()
|
||||
.isPresent();
|
||||
@ -163,7 +163,7 @@ public class CompleteIdeaDialogPanel extends GenericPanel<Idea> {
|
||||
}
|
||||
final ProjectType projectType = getModelObject().getProjectType();
|
||||
for (User partner : partners) {
|
||||
if (!projectService.getActiveProjects(partner, projectType).isEmpty()) {
|
||||
if (!projectService.getActiveProjectsByUserAndProjectType(partner, projectType).isEmpty()) {
|
||||
error(getString("partner.already.has.an.active.project.on.this.level", Model.of(partner)));
|
||||
}
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ public class ProjectIdeaSubmissionPanel extends GenericPanel<Idea> {
|
||||
final ProjectType selectedProjectType = getModelObject().getProjectType();
|
||||
if (selectedProjectType != null) {
|
||||
final boolean hasActiveProject = !projectService
|
||||
.getActiveProjects(SciProSession.get().getUser(), selectedProjectType)
|
||||
.getActiveProjectsByUserAndProjectType(SciProSession.get().getUser(), selectedProjectType)
|
||||
.isEmpty();
|
||||
setVisible(hasActiveProject);
|
||||
}
|
||||
@ -202,7 +202,7 @@ public class ProjectIdeaSubmissionPanel extends GenericPanel<Idea> {
|
||||
if (selectedProjectType != null) {
|
||||
final boolean partnerHasActiveProject = coAuthorChoice.getModelObject()
|
||||
.stream()
|
||||
.map(partner -> projectService.getActiveProjects(partner, selectedProjectType))
|
||||
.map(partner -> projectService.getActiveProjectsByUserAndProjectType(partner, selectedProjectType))
|
||||
.flatMap(Collection::stream)
|
||||
.findAny()
|
||||
.isPresent();
|
||||
@ -354,11 +354,11 @@ public class ProjectIdeaSubmissionPanel extends GenericPanel<Idea> {
|
||||
}
|
||||
final ProjectType projectType = projectTypeChoice.getConvertedInput();
|
||||
if (projectType != null) {
|
||||
if (!projectService.getActiveProjects(SciProSession.get().getUser(), projectType).isEmpty()) {
|
||||
if (!projectService.getActiveProjectsByUserAndProjectType(SciProSession.get().getUser(), projectType).isEmpty()) {
|
||||
error(getString("you.already.have.an.active.project.on.this.level"));
|
||||
}
|
||||
for (User partner : partners) {
|
||||
if (!projectService.getActiveProjects(partner, projectType).isEmpty()) {
|
||||
if (!projectService.getActiveProjectsByUserAndProjectType(partner, projectType).isEmpty()) {
|
||||
error(getString("partner.already.has.an.active.project.on.this.level", Model.of(partner)));
|
||||
}
|
||||
}
|
||||
|
@ -121,8 +121,7 @@ footer a:hover { color: #d95e00;}
|
||||
border: 1px solid #fbeed5;
|
||||
}
|
||||
|
||||
.feedbackPanel li { padding: 2px;}
|
||||
.feedbackPanel span { padding-left: 10px;}
|
||||
.feedbackPanel li { padding: 2px 10px;}
|
||||
|
||||
.feedbackPanelERROR {
|
||||
color: #A94442;
|
||||
@ -134,14 +133,12 @@ footer a:hover { color: #d95e00;}
|
||||
color: #3C763D;
|
||||
background-color: #DFF0D8;
|
||||
border-color: #D6E9C6;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.feedbackPanelSUCCESS {
|
||||
color: #3C763D;
|
||||
background-color: #DFF0D8;
|
||||
border-color: #D6E9C6;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
/************************************************** MENUS ***********************************************************/
|
||||
|
@ -104,7 +104,7 @@ public class ProjectIdeaSubmissionPanelTest extends SciProTest {
|
||||
|
||||
@Test
|
||||
public void can_not_submit_idea_if_already_has_active_project() {
|
||||
when(projectService.getActiveProjects(eq(user), any(ProjectType.class))).thenReturn(Collections.singletonList(new Project()));
|
||||
when(projectService.getActiveProjectsByUserAndProjectType(eq(user), any(ProjectType.class))).thenReturn(Collections.singletonList(new Project()));
|
||||
startPanel(idea);
|
||||
fillInFormAndSubmit();
|
||||
tester.assertFeedback(path(panel, "feedback"), panel.getString("you.already.have.an.active.project.on.this.level"));
|
||||
@ -113,8 +113,8 @@ public class ProjectIdeaSubmissionPanelTest extends SciProTest {
|
||||
@Test
|
||||
public void can_not_submit_idea_if_co_author_has_active_project() {
|
||||
final User coAuthor = mockCoAuthor();
|
||||
when(projectService.getActiveProjects(eq(user), any(ProjectType.class))).thenReturn(List.of());
|
||||
when(projectService.getActiveProjects(eq(coAuthor), any(ProjectType.class))).thenReturn(Collections.singletonList(new Project()));
|
||||
when(projectService.getActiveProjectsByUserAndProjectType(eq(user), any(ProjectType.class))).thenReturn(List.of());
|
||||
when(projectService.getActiveProjectsByUserAndProjectType(eq(coAuthor), any(ProjectType.class))).thenReturn(Collections.singletonList(new Project()));
|
||||
startPanel(idea);
|
||||
fillInFormAndSubmit(coAuthor.getId(), true);
|
||||
tester.assertFeedback(path(panel, "feedback"), panel.getString("partner.already.has.an.active.project.on.this.level", Model.of(coAuthor)));
|
||||
|
Loading…
x
Reference in New Issue
Block a user