2934 PO Report all pass/fail examinations when approving phase two

This commit is contained in:
Andreas Svanberg 2023-10-11 12:32:24 +02:00
parent 1dd5997870
commit 4a27718711
5 changed files with 48 additions and 71 deletions

@ -1,37 +0,0 @@
package se.su.dsv.scipro.reviewer;
import org.apache.wicket.model.IDetachable;
import org.apache.wicket.model.IModel;
import se.su.dsv.scipro.grading.Examination;
import se.su.dsv.scipro.system.User;
import java.util.HashMap;
import java.util.Map;
public class AuthorExaminations implements IDetachable {
private transient Map<User, Examination> selected = new HashMap<>();
@Override
public void detach() {
selected.clear();
}
public IModel<Examination> forAuthor(IModel<User> author) {
return new IModel<>() {
@Override
public Examination getObject() {
return selected.get(author.getObject());
}
@Override
public void setObject(Examination object) {
selected.put(author.getObject(), object);
}
};
}
public Examination forAuthor(User author) {
return selected.get(author);
}
}

@ -10,9 +10,7 @@ import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.EnumLabel;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.LambdaChoiceRenderer;
import org.apache.wicket.markup.html.form.TextArea;
import org.apache.wicket.markup.html.form.upload.FileUploadField;
import org.apache.wicket.markup.html.list.ListItem;
@ -23,12 +21,14 @@ import org.apache.wicket.model.Model;
import org.apache.wicket.model.ResourceModel;
import org.apache.wicket.request.flow.RedirectToUrlException;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import se.su.dsv.scipro.components.AutoHidingListView;
import se.su.dsv.scipro.components.InfoPanel;
import se.su.dsv.scipro.files.WicketFileUpload;
import se.su.dsv.scipro.forum.panels.threaded.SubmitForumReplyPanel;
import se.su.dsv.scipro.grading.Examination;
import se.su.dsv.scipro.grading.Grade;
import se.su.dsv.scipro.grading.GradingService;
import se.su.dsv.scipro.grading.Name;
import se.su.dsv.scipro.grading.ReportGradeError;
import se.su.dsv.scipro.oauth.OAuth;
import se.su.dsv.scipro.oauth.OAuthService;
@ -173,38 +173,26 @@ public class RoughDraftApprovalDecisionPage extends ReviewerPage {
private class ApproveAndGrade extends WebMarkupContainer {
private AuthorExaminations selectedExaminations = new AuthorExaminations();
public ApproveAndGrade(String id) {
super(id);
IModel<List<User>> authors = approval.map(ReviewerApproval::getProject)
.map(Project::getProjectParticipants)
.map(ArrayList::new);
add(new Label("examination_date", this::getExaminationDate));
ListView<User> listView = new ListView<>("authors", authors) {
@Override
protected void populateItem(ListItem<User> item) {
item.add(new UserLabel("name", item.getModel()));
IModel<List<Examination>> examinations = LoadableDetachableModel.of(() ->
getPassFailExaminations(item.getModel()));
DropDownChoice<Examination> examination = new DropDownChoice<>(
"examination",
selectedExaminations.forAuthor(item.getModel()),
examinations,
new LambdaChoiceRenderer<>(e -> e.name().english(), Examination::id));
examination.setLabel(item.getModel().map(User::getFullName));
examination.setRequired(true);
item.add(examination);
}
private List<Examination> getPassFailExaminations(IModel<User> author) {
return gradingService.getExaminations(
getSession().getMetaData(OAuth.TOKEN),
approval.getObject().getProject().getIdentifier(),
author.getObject().getIdentifier())
.stream()
.filter(Predicate.not(Examination::hasManyPassingGrades))
.toList();
getPassFailExaminations(item.getModelObject()));
item.add(new AutoHidingListView<>("examinations", examinations) {
@Override
protected void populateItem(ListItem<Examination> item) {
item.add(new Label("name", item.getModel().map(Examination::name).map(Name::english)));
item.add(new Label("points", item.getModel().map(Examination::points)));
}
});
}
};
listView.setReuseItems(true);
@ -235,8 +223,24 @@ public class RoughDraftApprovalDecisionPage extends ReviewerPage {
});
}
private List<Examination> getPassFailExaminations(User author) {
return gradingService.getExaminations(
getSession().getMetaData(OAuth.TOKEN),
approval.getObject().getProject().getIdentifier(),
author.getIdentifier())
.stream()
.filter(Predicate.not(Examination::hasManyPassingGrades))
.toList();
}
private void reportGrade(User author, Project project) {
Examination examination = selectedExaminations.forAuthor(author);
List<Examination> examinations = getPassFailExaminations(author);
for (Examination examination : examinations) {
reportGrade(author, project, examination);
}
}
private void reportGrade(User author, Project project, Examination examination) {
Grade passingGrade = getPassingGrade(examination);
Either<ReportGradeError, Void> reported = gradingService.reportGrade(
getSession().getMetaData(OAuth.TOKEN),
@ -288,7 +292,6 @@ public class RoughDraftApprovalDecisionPage extends ReviewerPage {
@Override
protected void onDetach() {
super.onDetach();
selectedExaminations.detach();
}
}
}

@ -5,7 +5,7 @@ interact.with.supervisor= Interact with supervisor
approve=Approve
reject=Improvements are needed
examination.Required=Examination for ${label} must be set
report_halfway_explanation=When approving a project for phase two review you should also report the halfway \
examination. Please select the appropriate examination below for each author before approving.
failed_to_report_phase_two_grade=Could not report the grade, please contact the supervisor and let them know \
report_halfway_explanation=When approving a project for phase two review you are also reporting, possibly multiple, \
passing grades for all the involved authors, see below for details.
failed_to_report_phase_two_grade=Could not report all the grades, please contact the supervisor and let them know \
they will have to report it themselves.

@ -38,14 +38,26 @@
</div>
<div wicket:id="approve_and_grade">
<p class="mb-3"><wicket:message key="report_halfway_explanation">
<p class="mb-3 alert alert-info"><wicket:message key="report_halfway_explanation">
[When approving a project for phase two review you should also report the halfway examination.
Please select the appropriate examination below for each author before approving.]
</wicket:message></p>
<div class="mb-3" wicket:id="authors">
<label class="form-label" wicket:id="name">[Author name]</label>
<select class="form-select" wicket:id="examination"></select>
</div>
<dl>
<dt>Examination date</dt>
<dd wicket:id="examination_date"></dd>
<wicket:container wicket:id="authors">
<dt wicket:id="name"></dt>
<dd>
<ul>
<li wicket:id="examinations">
<span wicket:id="name"></span>
(<span wicket:id="points"></span> hec)
</li>
</ul>
</dd>
</wicket:container>
</dl>
<button type="submit" class="btn btn-success btn-sm" wicket:id="approve">
Approve
</button>

@ -96,7 +96,6 @@ public class RoughDraftApprovalDecisionPageTest extends SciProTest {
FormTester formTester = tester.newFormTester("decision");
formTester.setValue("feedback", feedback);
formTester.setFile("attachment", attachment, "application/pdf");
formTester.setValue(path("approve_and_grade", "authors", 0, "examination"), "614");
formTester.submit(path("approve_and_grade", "approve"));
tester.assertNoErrorMessage();