Allow supervisors to request improvements from final seminar opponents #78
@ -8,4 +8,6 @@ public interface FinalSeminarOppositionService extends GenericService<FinalSemin
|
|||||||
void delete(Long aLong);
|
void delete(Long aLong);
|
||||||
|
|
||||||
List<OppositionCriterion> getCriteriaForOpposition(FinalSeminarOpposition opposition);
|
List<OppositionCriterion> getCriteriaForOpposition(FinalSeminarOpposition opposition);
|
||||||
|
|
||||||
|
void gradeOpponent(FinalSeminarOpposition opposition, int points, String feedback);
|
||||||
}
|
}
|
||||||
|
@ -25,4 +25,11 @@ public class FinalSeminarOppositionServiceImpl
|
|||||||
public List<OppositionCriterion> getCriteriaForOpposition(FinalSeminarOpposition opposition) {
|
public List<OppositionCriterion> getCriteriaForOpposition(FinalSeminarOpposition opposition) {
|
||||||
return finalSeminarOppositionGrading.oppositionCriteria(opposition);
|
return finalSeminarOppositionGrading.oppositionCriteria(opposition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void gradeOpponent(FinalSeminarOpposition opposition, int points, String feedback) {
|
||||||
|
// TODO:
|
||||||
|
// * save assessment
|
||||||
|
// * post events
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package se.su.dsv.scipro.report;
|
|||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import se.su.dsv.scipro.finalseminar.FinalSeminarOpposition;
|
|
||||||
import se.su.dsv.scipro.grading.GradingBasis;
|
import se.su.dsv.scipro.grading.GradingBasis;
|
||||||
import se.su.dsv.scipro.project.Project;
|
import se.su.dsv.scipro.project.Project;
|
||||||
import se.su.dsv.scipro.system.User;
|
import se.su.dsv.scipro.system.User;
|
||||||
@ -19,8 +18,6 @@ public interface GradingReportService {
|
|||||||
SupervisorGradingReport supervisorGradingReport
|
SupervisorGradingReport supervisorGradingReport
|
||||||
);
|
);
|
||||||
|
|
||||||
boolean updateOppositionCriteria(SupervisorGradingReport report, FinalSeminarOpposition opposition);
|
|
||||||
|
|
||||||
GradingBasis getGradingBasis(Project project);
|
GradingBasis getGradingBasis(Project project);
|
||||||
|
|
||||||
GradingBasis updateGradingBasis(Project project, GradingBasis gradingBasis);
|
GradingBasis updateGradingBasis(Project project, GradingBasis gradingBasis);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package se.su.dsv.scipro.report;
|
package se.su.dsv.scipro.report;
|
||||||
|
|
||||||
import com.google.common.eventbus.EventBus;
|
import com.google.common.eventbus.EventBus;
|
||||||
|
import com.google.common.eventbus.Subscribe;
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import jakarta.transaction.Transactional;
|
import jakarta.transaction.Transactional;
|
||||||
import java.time.Clock;
|
import java.time.Clock;
|
||||||
@ -9,6 +10,7 @@ import java.time.LocalDate;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import se.su.dsv.scipro.finalseminar.FinalSeminarOpposition;
|
import se.su.dsv.scipro.finalseminar.FinalSeminarOpposition;
|
||||||
import se.su.dsv.scipro.finalseminar.FinalSeminarOppositionGrading;
|
import se.su.dsv.scipro.finalseminar.FinalSeminarOppositionGrading;
|
||||||
|
import se.su.dsv.scipro.finalseminar.OppositionApprovedEvent;
|
||||||
import se.su.dsv.scipro.finalseminar.OppositionCriterion;
|
import se.su.dsv.scipro.finalseminar.OppositionCriterion;
|
||||||
import se.su.dsv.scipro.grading.GradingBasis;
|
import se.su.dsv.scipro.grading.GradingBasis;
|
||||||
import se.su.dsv.scipro.grading.GradingReportTemplateService;
|
import se.su.dsv.scipro.grading.GradingReportTemplateService;
|
||||||
@ -47,11 +49,11 @@ public class GradingReportServiceImpl
|
|||||||
this.supervisorGradingReportRepository = supervisorGradingReportRepository;
|
this.supervisorGradingReportRepository = supervisorGradingReportRepository;
|
||||||
this.gradingReportTemplateRepo = gradingReportTemplateRepo;
|
this.gradingReportTemplateRepo = gradingReportTemplateRepo;
|
||||||
this.projectTypeService = projectTypeService;
|
this.projectTypeService = projectTypeService;
|
||||||
|
|
||||||
|
eventBus.register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private boolean updateOppositionCriteria(SupervisorGradingReport report, FinalSeminarOpposition opposition) {
|
||||||
@Transactional
|
|
||||||
public boolean updateOppositionCriteria(SupervisorGradingReport report, FinalSeminarOpposition opposition) {
|
|
||||||
for (GradingCriterion gradingCriterion : report.getIndividualCriteria()) {
|
for (GradingCriterion gradingCriterion : report.getIndividualCriteria()) {
|
||||||
boolean isOppositionCriterion = gradingCriterion.getFlag() == GradingCriterion.Flag.OPPOSITION;
|
boolean isOppositionCriterion = gradingCriterion.getFlag() == GradingCriterion.Flag.OPPOSITION;
|
||||||
boolean betterGrade =
|
boolean betterGrade =
|
||||||
@ -293,6 +295,12 @@ public class GradingReportServiceImpl
|
|||||||
return gradingReportTemplateRepo.createTemplate(projectType, update);
|
return gradingReportTemplateRepo.createTemplate(projectType, update);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void opponentApproved(OppositionApprovedEvent event) {
|
||||||
|
SupervisorGradingReport report = getSupervisorGradingReport(event.getProject(), event.getStudent());
|
||||||
|
updateOppositionCriteria(report, event.getOpposition());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public List<OppositionCriterion> oppositionCriteria(FinalSeminarOpposition opposition) {
|
public List<OppositionCriterion> oppositionCriteria(FinalSeminarOpposition opposition) {
|
||||||
|
@ -5,6 +5,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
|
|||||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
import com.google.common.eventbus.EventBus;
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.Month;
|
import java.time.Month;
|
||||||
@ -13,6 +14,7 @@ import org.junit.jupiter.api.BeforeEach;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import se.su.dsv.scipro.finalseminar.FinalSeminar;
|
import se.su.dsv.scipro.finalseminar.FinalSeminar;
|
||||||
import se.su.dsv.scipro.finalseminar.FinalSeminarOpposition;
|
import se.su.dsv.scipro.finalseminar.FinalSeminarOpposition;
|
||||||
|
import se.su.dsv.scipro.finalseminar.OppositionApprovedEvent;
|
||||||
import se.su.dsv.scipro.project.Project;
|
import se.su.dsv.scipro.project.Project;
|
||||||
import se.su.dsv.scipro.security.auth.roles.Roles;
|
import se.su.dsv.scipro.security.auth.roles.Roles;
|
||||||
import se.su.dsv.scipro.system.DegreeType;
|
import se.su.dsv.scipro.system.DegreeType;
|
||||||
@ -31,6 +33,9 @@ public class GradingReportServiceImplIntegrationTest extends IntegrationTest {
|
|||||||
@Inject
|
@Inject
|
||||||
private GradingReportServiceImpl gradingReportService;
|
private GradingReportServiceImpl gradingReportService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private EventBus eventBus;
|
||||||
|
|
||||||
private ProjectType projectType;
|
private ProjectType projectType;
|
||||||
private GradingReportTemplate gradingReportTemplate;
|
private GradingReportTemplate gradingReportTemplate;
|
||||||
private Project project;
|
private Project project;
|
||||||
@ -45,7 +50,6 @@ public class GradingReportServiceImplIntegrationTest extends IntegrationTest {
|
|||||||
project = createProject(projectType, 30);
|
project = createProject(projectType, 30);
|
||||||
gradingReportTemplate = createProjectGradingCriterion(gradingReportTemplate, 2);
|
gradingReportTemplate = createProjectGradingCriterion(gradingReportTemplate, 2);
|
||||||
gradingReportTemplate = createIndividualGradingCriterion(gradingReportTemplate, 2);
|
gradingReportTemplate = createIndividualGradingCriterion(gradingReportTemplate, 2);
|
||||||
gradingReport = createGradingReport(project, student);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -68,6 +72,7 @@ public class GradingReportServiceImplIntegrationTest extends IntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void submit_supervisor_grading_report_flags_report_as_submitted() {
|
public void submit_supervisor_grading_report_flags_report_as_submitted() {
|
||||||
|
gradingReport = createGradingReport(project, student);
|
||||||
assessAllCriteria(gradingReport);
|
assessAllCriteria(gradingReport);
|
||||||
Either<List<SubmissionError>, SupervisorGradingReport> result = gradingReportService.submitReport(
|
Either<List<SubmissionError>, SupervisorGradingReport> result = gradingReportService.submitReport(
|
||||||
gradingReport
|
gradingReport
|
||||||
@ -77,6 +82,7 @@ public class GradingReportServiceImplIntegrationTest extends IntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void submitting_supervisor_report_throws_exception_if_report_is_not_finished() {
|
public void submitting_supervisor_report_throws_exception_if_report_is_not_finished() {
|
||||||
|
gradingReport = createGradingReport(project, student);
|
||||||
Either<List<SubmissionError>, SupervisorGradingReport> result = gradingReportService.submitReport(
|
Either<List<SubmissionError>, SupervisorGradingReport> result = gradingReportService.submitReport(
|
||||||
gradingReport
|
gradingReport
|
||||||
);
|
);
|
||||||
@ -86,38 +92,35 @@ public class GradingReportServiceImplIntegrationTest extends IntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
public void update_opposition_criterion() {
|
public void update_opposition_criterion() {
|
||||||
addOppositionCriterion();
|
addOppositionCriterion();
|
||||||
boolean updated = updateOppositionCriterion();
|
updateOppositionCriterion();
|
||||||
|
|
||||||
GradingCriterion oppositionCriterion = findOppositionCriterion();
|
GradingCriterion oppositionCriterion = findOppositionCriterion();
|
||||||
assert oppositionCriterion != null;
|
assert oppositionCriterion != null;
|
||||||
assertEquals(FEEDBACK_ON_OPPOSITION, oppositionCriterion.getFeedback());
|
assertEquals(FEEDBACK_ON_OPPOSITION, oppositionCriterion.getFeedback());
|
||||||
assertEquals((Integer) OPPOSITION_CRITERION_POINTS, oppositionCriterion.getPoints());
|
assertEquals((Integer) OPPOSITION_CRITERION_POINTS, oppositionCriterion.getPoints());
|
||||||
assertTrue(updated);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void update_opposition_if_title_matches_english_title() {
|
public void update_opposition_if_title_matches_english_title() {
|
||||||
addOppositionCriterion();
|
addOppositionCriterion();
|
||||||
boolean updated = updateOppositionCriterion();
|
updateOppositionCriterion();
|
||||||
|
|
||||||
GradingCriterion oppositionCriterion = findEnglishOppositionCriterion("Ö1 Opposition report");
|
GradingCriterion oppositionCriterion = findEnglishOppositionCriterion("Ö1 Opposition report");
|
||||||
assert oppositionCriterion != null;
|
assert oppositionCriterion != null;
|
||||||
assertEquals(FEEDBACK_ON_OPPOSITION, oppositionCriterion.getFeedback());
|
assertEquals(FEEDBACK_ON_OPPOSITION, oppositionCriterion.getFeedback());
|
||||||
assertEquals((Integer) OPPOSITION_CRITERION_POINTS, oppositionCriterion.getPoints());
|
assertEquals((Integer) OPPOSITION_CRITERION_POINTS, oppositionCriterion.getPoints());
|
||||||
assertTrue(updated);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void updating_opposition_criterion_does_nothing_if_criterion_already_has_values() {
|
public void updating_opposition_criterion_does_nothing_if_criterion_already_has_values() {
|
||||||
addOppositionCriterion();
|
addOppositionCriterion();
|
||||||
assessAllCriteria(gradingReport);
|
assessAllCriteria(gradingReport);
|
||||||
boolean updated = updateOppositionCriterion();
|
updateOppositionCriterion();
|
||||||
|
|
||||||
GradingCriterion oppositionCriterion = findOppositionCriterion();
|
GradingCriterion oppositionCriterion = findOppositionCriterion();
|
||||||
assert oppositionCriterion != null;
|
assert oppositionCriterion != null;
|
||||||
assertEquals(FEEDBACK, oppositionCriterion.getFeedback());
|
assertEquals(FEEDBACK, oppositionCriterion.getFeedback());
|
||||||
assertEquals((Integer) oppositionCriterion.getMaxPoints(), oppositionCriterion.getPoints());
|
assertEquals((Integer) oppositionCriterion.getMaxPoints(), oppositionCriterion.getPoints());
|
||||||
assertFalse(updated);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -151,9 +154,9 @@ public class GradingReportServiceImplIntegrationTest extends IntegrationTest {
|
|||||||
gradingReport = createGradingReport(project, student);
|
gradingReport = createGradingReport(project, student);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean updateOppositionCriterion() {
|
private void updateOppositionCriterion() {
|
||||||
FinalSeminarOpposition opposition = createFinalSeminarOpposition();
|
FinalSeminarOpposition opposition = createFinalSeminarOpposition();
|
||||||
return gradingReportService.updateOppositionCriteria(gradingReport, opposition);
|
eventBus.post(new OppositionApprovedEvent(opposition));
|
||||||
}
|
}
|
||||||
|
|
||||||
private GradingCriterion findOppositionCriterion() {
|
private GradingCriterion findOppositionCriterion() {
|
||||||
@ -176,8 +179,8 @@ public class GradingReportServiceImplIntegrationTest extends IntegrationTest {
|
|||||||
|
|
||||||
private FinalSeminarOpposition createFinalSeminarOpposition() {
|
private FinalSeminarOpposition createFinalSeminarOpposition() {
|
||||||
FinalSeminarOpposition finalSeminarOpposition = new FinalSeminarOpposition();
|
FinalSeminarOpposition finalSeminarOpposition = new FinalSeminarOpposition();
|
||||||
finalSeminarOpposition.setProject(createProject(projectType, 30));
|
finalSeminarOpposition.setProject(project);
|
||||||
finalSeminarOpposition.setUser(createStudent());
|
finalSeminarOpposition.setUser(student);
|
||||||
finalSeminarOpposition.setFinalSeminar(createFinalSeminar());
|
finalSeminarOpposition.setFinalSeminar(createFinalSeminar());
|
||||||
|
|
||||||
finalSeminarOpposition.setFeedback(FEEDBACK_ON_OPPOSITION);
|
finalSeminarOpposition.setFeedback(FEEDBACK_ON_OPPOSITION);
|
||||||
|
@ -33,7 +33,6 @@ import se.su.dsv.scipro.components.StatelessModel;
|
|||||||
import se.su.dsv.scipro.profile.UserLinkPanel;
|
import se.su.dsv.scipro.profile.UserLinkPanel;
|
||||||
import se.su.dsv.scipro.report.GradingReportService;
|
import se.su.dsv.scipro.report.GradingReportService;
|
||||||
import se.su.dsv.scipro.report.OppositionReportService;
|
import se.su.dsv.scipro.report.OppositionReportService;
|
||||||
import se.su.dsv.scipro.report.SupervisorGradingReport;
|
|
||||||
import se.su.dsv.scipro.security.auth.roles.Roles;
|
import se.su.dsv.scipro.security.auth.roles.Roles;
|
||||||
import se.su.dsv.scipro.session.SciProSession;
|
import se.su.dsv.scipro.session.SciProSession;
|
||||||
import se.su.dsv.scipro.system.ProjectModule;
|
import se.su.dsv.scipro.system.ProjectModule;
|
||||||
@ -47,8 +46,6 @@ public class SeminarOppositionPanel extends Panel {
|
|||||||
public static final String REMOVE = "remove";
|
public static final String REMOVE = "remove";
|
||||||
public static final String FORM = "form";
|
public static final String FORM = "form";
|
||||||
public static final String POINTS = "points";
|
public static final String POINTS = "points";
|
||||||
public static final int MIN_POINTS = 0;
|
|
||||||
public static final int MAX_POINTS = 2;
|
|
||||||
public static final String GRADING_FEEDBACK = "gradingFeedback";
|
public static final String GRADING_FEEDBACK = "gradingFeedback";
|
||||||
public static final int FEEDBACK_MAX_LENGTH = 2000;
|
public static final int FEEDBACK_MAX_LENGTH = 2000;
|
||||||
public static final String SUBMIT = "submit";
|
public static final String SUBMIT = "submit";
|
||||||
@ -258,31 +255,12 @@ public class SeminarOppositionPanel extends Panel {
|
|||||||
new AjaxSubmitLink(SUBMIT) {
|
new AjaxSubmitLink(SUBMIT) {
|
||||||
@Override
|
@Override
|
||||||
protected void onSubmit(AjaxRequestTarget target) {
|
protected void onSubmit(AjaxRequestTarget target) {
|
||||||
if (getModelObject().getPoints().equals(0)) {
|
finalSeminarOppositionService.gradeOpponent(
|
||||||
finalSeminarOpposition.getObject().setGrade(FinalSeminarGrade.NOT_APPROVED);
|
finalSeminarOpposition.getObject(),
|
||||||
eventBus.post(new OppositionFailedEvent(finalSeminarOpposition.getObject()));
|
pointsModel.getObject().points(),
|
||||||
} else {
|
feedbackModel.getObject()
|
||||||
finalSeminarOpposition.getObject().setGrade(FinalSeminarGrade.APPROVED);
|
|
||||||
eventBus.post(new OppositionApprovedEvent(finalSeminarOpposition.getObject()));
|
|
||||||
}
|
|
||||||
finalSeminarOppositionService.save(finalSeminarOpposition.getObject());
|
|
||||||
boolean updated = true;
|
|
||||||
if (gradingModuleIsOnForProjectType()) {
|
|
||||||
SupervisorGradingReport report = gradingReportService.getSupervisorGradingReport(
|
|
||||||
finalSeminarOpposition.getObject().getProject(),
|
|
||||||
finalSeminarOpposition.getObject().getUser()
|
|
||||||
);
|
|
||||||
updated = gradingReportService.updateOppositionCriteria(
|
|
||||||
report,
|
|
||||||
finalSeminarOpposition.getObject()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
success(
|
|
||||||
getString(
|
|
||||||
updated ? "feedback.opponent.updated" : "feedback.opponent.not.updated",
|
|
||||||
finalSeminarOpposition
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
success(getString("feedback.opponent.updated", finalSeminarOpposition));
|
||||||
target.add(feedbackPanel);
|
target.add(feedbackPanel);
|
||||||
target.add(oppositionContainer);
|
target.add(oppositionContainer);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user