Allow supervisors to request improvements from final seminar opponents #78

Merged
niat8586 merged 41 commits from opponent-completion into develop 2025-03-05 10:05:38 +01:00
8 changed files with 54 additions and 4 deletions
Showing only changes of commit 06c1e81978 - Show all commits

View File

@ -688,13 +688,15 @@ public class CoreConfig {
OppositionReportRepo oppositionReportRepository, OppositionReportRepo oppositionReportRepository,
GradingReportTemplateRepo gradingReportTemplateRepository, GradingReportTemplateRepo gradingReportTemplateRepository,
FileService fileService, FileService fileService,
FinalSeminarOppositionRepo finalSeminarOppositionRepository FinalSeminarOppositionRepo finalSeminarOppositionRepository,
EventBus eventBus
) { ) {
return new OppositionReportServiceImpl( return new OppositionReportServiceImpl(
oppositionReportRepository, oppositionReportRepository,
gradingReportTemplateRepository, gradingReportTemplateRepository,
fileService, fileService,
finalSeminarOppositionRepository finalSeminarOppositionRepository,
eventBus
); );
} }

View File

@ -13,6 +13,7 @@ import java.time.ZonedDateTime;
import java.util.*; import java.util.*;
import java.util.function.Function; import java.util.function.Function;
import se.su.dsv.scipro.checklist.ChecklistCategory; import se.su.dsv.scipro.checklist.ChecklistCategory;
import se.su.dsv.scipro.data.dataobjects.Member;
import se.su.dsv.scipro.file.FileReference; import se.su.dsv.scipro.file.FileReference;
import se.su.dsv.scipro.file.FileService; import se.su.dsv.scipro.file.FileService;
import se.su.dsv.scipro.file.FileUpload; import se.su.dsv.scipro.file.FileUpload;
@ -23,6 +24,9 @@ import se.su.dsv.scipro.match.Keyword;
import se.su.dsv.scipro.milestones.dataobjects.MilestoneActivityTemplate; import se.su.dsv.scipro.milestones.dataobjects.MilestoneActivityTemplate;
import se.su.dsv.scipro.milestones.dataobjects.MilestonePhaseTemplate; import se.su.dsv.scipro.milestones.dataobjects.MilestonePhaseTemplate;
import se.su.dsv.scipro.milestones.service.MilestoneActivityTemplateService; import se.su.dsv.scipro.milestones.service.MilestoneActivityTemplateService;
import se.su.dsv.scipro.notifications.dataobject.Notification;
import se.su.dsv.scipro.notifications.dataobject.SeminarEvent;
import se.su.dsv.scipro.notifications.settings.service.ReceiverConfigurationService;
import se.su.dsv.scipro.profiles.CurrentProfile; import se.su.dsv.scipro.profiles.CurrentProfile;
import se.su.dsv.scipro.profiles.Profiles; import se.su.dsv.scipro.profiles.Profiles;
import se.su.dsv.scipro.project.Project; import se.su.dsv.scipro.project.Project;
@ -57,6 +61,9 @@ public class DataInitializer implements Lifecycle {
@Inject @Inject
private Provider<EntityManager> em; private Provider<EntityManager> em;
@Inject
private ReceiverConfigurationService receiverConfigurationService;
private static final String MAIL = "@example.com"; private static final String MAIL = "@example.com";
private static final String ADMIN = "admin"; private static final String ADMIN = "admin";
@ -104,12 +111,22 @@ public class DataInitializer implements Lifecycle {
createUsers(); createUsers();
createProjects(); createProjects();
createPastFinalSeminar(); createPastFinalSeminar();
setUpNotifications();
} }
if (profile.getCurrentProfile() == Profiles.DEV && noAdminUser()) { if (profile.getCurrentProfile() == Profiles.DEV && noAdminUser()) {
createAdmin(); createAdmin();
} }
} }
private void setUpNotifications() {
receiverConfigurationService.setReceiving(
Notification.Type.FINAL_SEMINAR,
SeminarEvent.Event.OPPOSITION_REPORT_SUBMITTED,
Member.Type.SUPERVISOR,
true
);
}
private void createPastFinalSeminar() { private void createPastFinalSeminar() {
FileReference document = fileService.storeFile( FileReference document = fileService.storeFile(
new SimpleTextFile(sture_student, "document.txt", "Hello World") new SimpleTextFile(sture_student, "document.txt", "Hello World")

View File

@ -24,6 +24,7 @@ import se.su.dsv.scipro.project.ProjectActivatedEvent;
import se.su.dsv.scipro.project.ProjectCompletedEvent; import se.su.dsv.scipro.project.ProjectCompletedEvent;
import se.su.dsv.scipro.project.ProjectDeactivatedEvent; import se.su.dsv.scipro.project.ProjectDeactivatedEvent;
import se.su.dsv.scipro.project.ReviewerAssignedEvent; import se.su.dsv.scipro.project.ReviewerAssignedEvent;
import se.su.dsv.scipro.report.OppositionReportSubmittedEvent;
@Singleton @Singleton
public class Notifications { public class Notifications {
@ -183,6 +184,17 @@ public class Notifications {
); );
} }
@Subscribe
public void oppositionReportSubmitted(OppositionReportSubmittedEvent event) {
NotificationSource source = new NotificationSource();
source.setMessage(event.report().getAuthorName());
notificationController.notifySeminar(
event.finalSeminar(),
SeminarEvent.Event.OPPOSITION_REPORT_SUBMITTED,
source
);
}
@Subscribe @Subscribe
public void reviewersChanged(ReviewerAssignedEvent event) { public void reviewersChanged(ReviewerAssignedEvent event) {
notificationController.notifyProject( notificationController.notifyProject(

View File

@ -26,6 +26,7 @@ public class SeminarEvent extends NotificationEvent {
THESIS_DELETED, THESIS_DELETED,
THESIS_UPLOAD_REMIND, THESIS_UPLOAD_REMIND,
CANCELLED, CANCELLED,
OPPOSITION_REPORT_SUBMITTED,
} }
@Basic @Basic

View File

@ -144,6 +144,8 @@ FINAL_SEMINAR.THESIS_UPLOAD_REMIND.body = No final seminar thesis has been uploa
If no final thesis has been uploaded by {0}, the final seminar will be automatically cancelled. If no final thesis has been uploaded by {0}, the final seminar will be automatically cancelled.
FINAL_SEMINAR.CANCELLED.title = Final seminar for project {1} was cancelled FINAL_SEMINAR.CANCELLED.title = Final seminar for project {1} was cancelled
FINAL_SEMINAR.CANCELLED.body = The final seminar for project {0} was cancelled, supervisor must select a new date for the final seminar. FINAL_SEMINAR.CANCELLED.body = The final seminar for project {0} was cancelled, supervisor must select a new date for the final seminar.
FINAL_SEMINAR.OPPOSITION_REPORT_SUBMITTED.title=Opposition report submitted by {1} for the seminar on project {0}
FINAL_SEMINAR.OPPOSITION_REPORT_SUBMITTED.body=The opposition report from {0} has been submitted.
FINAL_SEMINAR.compilationSuffix = , project: {0} FINAL_SEMINAR.compilationSuffix = , project: {0}
PEER.REVIEW_COMPLETED.title = Peer review completed PEER.REVIEW_COMPLETED.title = Peer review completed

View File

@ -1,5 +1,6 @@
package se.su.dsv.scipro.report; package se.su.dsv.scipro.report;
import com.google.common.eventbus.EventBus;
import jakarta.inject.Inject; import jakarta.inject.Inject;
import jakarta.inject.Named; import jakarta.inject.Named;
import jakarta.transaction.Transactional; import jakarta.transaction.Transactional;
@ -17,18 +18,21 @@ public class OppositionReportServiceImpl implements OppositionReportService {
private GradingReportTemplateRepo gradingReportTemplateRepo; private GradingReportTemplateRepo gradingReportTemplateRepo;
private FileService fileService; private FileService fileService;
private FinalSeminarOppositionRepo finalSeminarOppositionRepo; private FinalSeminarOppositionRepo finalSeminarOppositionRepo;
private final EventBus eventBus;
@Inject @Inject
public OppositionReportServiceImpl( public OppositionReportServiceImpl(
OppositionReportRepo oppositionReportRepo, OppositionReportRepo oppositionReportRepo,
GradingReportTemplateRepo gradingReportTemplateRepo, GradingReportTemplateRepo gradingReportTemplateRepo,
FileService fileService, FileService fileService,
FinalSeminarOppositionRepo finalSeminarOppositionRepo FinalSeminarOppositionRepo finalSeminarOppositionRepo,
EventBus eventBus
) { ) {
this.oppositionReportRepo = oppositionReportRepo; this.oppositionReportRepo = oppositionReportRepo;
this.gradingReportTemplateRepo = gradingReportTemplateRepo; this.gradingReportTemplateRepo = gradingReportTemplateRepo;
this.fileService = fileService; this.fileService = fileService;
this.finalSeminarOppositionRepo = finalSeminarOppositionRepo; this.finalSeminarOppositionRepo = finalSeminarOppositionRepo;
this.eventBus = eventBus;
} }
@Override @Override
@ -81,7 +85,9 @@ public class OppositionReportServiceImpl implements OppositionReportService {
@Transactional @Transactional
public OppositionReport submit(OppositionReport report) { public OppositionReport submit(OppositionReport report) {
report.submit(); report.submit();
return oppositionReportRepo.save(report); OppositionReport submitted = oppositionReportRepo.save(report);
eventBus.post(new OppositionReportSubmittedEvent(submitted));
return submitted;
} }
@Override @Override

View File

@ -0,0 +1,9 @@
package se.su.dsv.scipro.report;
import se.su.dsv.scipro.finalseminar.FinalSeminar;
public record OppositionReportSubmittedEvent(OppositionReport report) {
public FinalSeminar finalSeminar() {
return report().getFinalSeminarOpposition().getFinalSeminar();
}
}

View File

@ -84,6 +84,7 @@ SeminarEvent.OPPOSITION_REPORT_UPLOADED = Opposition report created.
SeminarEvent.THESIS_DELETED = Final seminar thesis deleted. SeminarEvent.THESIS_DELETED = Final seminar thesis deleted.
SeminarEvent.THESIS_UPLOAD_REMIND = Authors reminded to upload final seminar thesis. SeminarEvent.THESIS_UPLOAD_REMIND = Authors reminded to upload final seminar thesis.
SeminarEvent.CANCELLED = Final seminar cancelled. SeminarEvent.CANCELLED = Final seminar cancelled.
SeminarEvent.OPPOSITION_REPORT_SUBMITTED = Opposition report submitted.
IdeaEvent.STATUS_CHANGE = Idea status changed. IdeaEvent.STATUS_CHANGE = Idea status changed.
IdeaEvent.PARTNER_ACCEPT = Partner (author) accepted partnering idea. IdeaEvent.PARTNER_ACCEPT = Partner (author) accepted partnering idea.