/**
* <a href="http://www.openolat.org">
* OpenOLAT - Online Learning and Training</a><br>
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at the
* <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Initial code contributed and copyrighted by<br>
* frentix GmbH, http://www.frentix.com
* <p>
*/
package org.olat.course.nodes.gta.ui;
import java.io.File;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import org.olat.NewControllerFactory;
import org.olat.basesecurity.GroupRoles;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.Component;
import org.olat.core.gui.components.link.Link;
import org.olat.core.gui.components.link.LinkFactory;
import org.olat.core.gui.components.text.TextFactory;
import org.olat.core.gui.components.velocity.VelocityContainer;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.Event;
import org.olat.core.gui.control.WindowControl;
import org.olat.core.gui.control.generic.closablewrapper.CloseableCalloutWindowController;
import org.olat.core.gui.control.generic.modal.DialogBoxController;
import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory;
import org.olat.core.id.Identity;
import org.olat.core.util.StringHelper;
import org.olat.core.util.coordinate.CoordinatorManager;
import org.olat.core.util.io.SystemFilenameFilter;
import org.olat.core.util.mail.MailBundle;
import org.olat.core.util.mail.MailContext;
import org.olat.core.util.mail.MailContextImpl;
import org.olat.core.util.mail.MailManager;
import org.olat.core.util.mail.MailTemplate;
import org.olat.core.util.mail.MailerResult;
import org.olat.core.util.vfs.VFSContainer;
import org.olat.course.nodes.GTACourseNode;
import org.olat.course.nodes.MSCourseNode;
import org.olat.course.nodes.gta.AssignmentResponse;
import org.olat.course.nodes.gta.GTAType;
import org.olat.course.nodes.gta.Task;
import org.olat.course.nodes.gta.TaskHelper;
import org.olat.course.nodes.gta.TaskHelper.FilesLocked;
import org.olat.course.nodes.gta.TaskProcess;
import org.olat.course.nodes.gta.model.TaskDefinition;
import org.olat.course.nodes.gta.ui.events.SubmitEvent;
import org.olat.course.nodes.gta.ui.events.TaskMultiUserEvent;
import org.olat.course.nodes.ms.MSCourseNodeRunController;
import org.olat.course.run.userview.UserCourseEnvironment;
import org.olat.group.BusinessGroup;
import org.springframework.beans.factory.annotation.Autowired;
/**
*
* Initial date: 23.02.2015<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
public class GTAParticipantController extends GTAAbstractController {
private Link submitButton, openGroupButton, changeGroupLink;
private MSCourseNodeRunController gradingCtrl;
private SubmitDocumentsController submitDocCtrl;
private DialogBoxController confirmSubmitDialog;
private GTAAssignedTaskController assignedTaskCtrl;
private GTAAvailableTaskController availableTaskCtrl;
private CloseableCalloutWindowController chooserCalloutCtrl;
private BusinessGroupChooserController businessGroupChooserCtrl;
private GTAParticipantRevisionAndCorrectionsController revisionDocumentsCtrl;
private DirectoryController submittedDocCtrl, correctionsCtrl, solutionsCtrl;
private List<BusinessGroup> myGroups;
@Autowired
private MailManager mailManager;
public GTAParticipantController(UserRequest ureq, WindowControl wControl,
GTACourseNode gtaNode, UserCourseEnvironment userCourseEnv) {
super(ureq, wControl, gtaNode, userCourseEnv.getCourseEnvironment(), userCourseEnv, true, true, true);
initContainer(ureq);
process(ureq);
}
@Override
protected void initContainer(UserRequest ureq) {
mainVC = createVelocityContainer("run");
putInitialPanel(mainVC);
initFlow() ;
}
protected final void initFlow() {
//this is an individual or a group task
String type = config.getStringValue(GTACourseNode.GTASK_TYPE);
if(GTAType.individual.name().equals(type)) {
assessedIdentity = getIdentity();
} else {
//this is a group task
myGroups = gtaManager.getParticipatingBusinessGroups(getIdentity(), gtaNode);
if(myGroups.size() == 0) {
//show error
mainVC.contextPut("noGroupError", Boolean.TRUE);
} else if(myGroups.size() == 1) {
setGroupWarning();
assessedGroup = myGroups.get(0);
setGroupHeaders(assessedGroup);
} else {
//show selection and first one
setGroupWarning();
setMultiGroupsSelection();
if(assessedGroup == null || !myGroups.contains(assessedGroup)) {
assessedGroup = myGroups.get(0);
}
setGroupHeaders(assessedGroup);
}
}
}
@Override
protected Task stepAssignment(UserRequest ureq, Task assignedTask) {
assignedTask = super.stepAssignment(ureq, assignedTask);
if(TaskHelper.inOrNull(assignedTask, TaskProcess.assignment)) {
mainVC.contextPut("assignmentCssClass", "o_active");
if(stepPreferences != null) {
//assignment is very important, open it always
stepPreferences.setAssignement(Boolean.TRUE);
}
//assignment open?
DueDate dueDate = getAssignementDueDate(assignedTask);
if(dueDate != null && dueDate.getDueDate() != null && dueDate.getDueDate().compareTo(new Date()) < 0) {
//assignment is closed
mainVC.contextPut("assignmentClosed", Boolean.TRUE);
} else if(userCourseEnv.isCourseReadOnly()) {
showAssignedTask(ureq, assignedTask);
} else {
List<TaskDefinition> availableTasks = gtaManager.getTaskDefinitions(courseEnv, gtaNode);
//assignment auto or manual
String assignmentType = config.getStringValue(GTACourseNode.GTASK_ASSIGNEMENT_TYPE);
if(GTACourseNode.GTASK_ASSIGNEMENT_TYPE_AUTO.equals(assignmentType)) {
AssignmentResponse response;
if(GTAType.group.name().equals(config.getStringValue(GTACourseNode.GTASK_TYPE))) {
response = gtaManager.assignTaskAutomatically(taskList, assessedGroup, courseEnv, gtaNode);
} else {
response = gtaManager.assignTaskAutomatically(taskList, assessedIdentity, courseEnv, gtaNode);
}
if(response == null || response.getStatus() == AssignmentResponse.Status.error) {
showError("task.assignment.error");
} else if(response == null || response.getStatus() == AssignmentResponse.Status.noMoreTasks) {
showError("error.nomoretasks");
} else if(response == null || response.getStatus() == AssignmentResponse.Status.ok) {
if(response != null) {
assignedTask = response.getTask();
}
showInfo("task.successfully.assigned");
showAssignedTask(ureq, assignedTask);
}
} else if(GTACourseNode.GTASK_ASSIGNEMENT_TYPE_MANUAL.equals(assignmentType)) {
availableTaskCtrl = new GTAAvailableTaskController(ureq, getWindowControl(), availableTasks,
taskList, assessedGroup, assessedIdentity, courseEnv, gtaNode);
listenTo(availableTaskCtrl);
mainVC.put("availableTasks", availableTaskCtrl.getInitialComponent());
}
}
} else {
mainVC.contextPut("assignmentCssClass", "o_done");
showAssignedTask(ureq, assignedTask);
}
return assignedTask;
}
private void showAssignedTask(UserRequest ureq, Task assignedTask) {
String message = gtaNode.getModuleConfiguration().getStringValue(GTACourseNode.GTASK_USERS_TEXT);
TaskDefinition taskDef = getTaskDefinition(assignedTask);
assignedTaskCtrl = new GTAAssignedTaskController(ureq, getWindowControl(), assignedTask,
taskDef, courseEnv, gtaNode,
"task.assigned.description", "warning.no.task.choosed", message);
listenTo(assignedTaskCtrl);
mainVC.put("myAssignedTask", assignedTaskCtrl.getInitialComponent());
}
@Override
protected Task stepSubmit(UserRequest ureq, Task assignedTask) {
assignedTask = super.stepSubmit(ureq, assignedTask);
boolean embedded = config.getBooleanSafe(GTACourseNode.GTASK_EMBBEDED_EDITOR);
boolean external = config.getBooleanSafe(GTACourseNode.GTASK_EXTERNAL_EDITOR);
if(embedded && external) {
mainVC.contextPut("sumbitWay", "all");
} else if(embedded) {
mainVC.contextPut("sumbitWay", "editor");
} else if(external) {
mainVC.contextPut("sumbitWay", "upload");
}
//calculate state
if(config.getBooleanSafe(GTACourseNode.GTASK_ASSIGNMENT)) {
if(assignedTask == null || assignedTask.getTaskStatus() == TaskProcess.assignment) {
mainVC.contextPut("submitCssClass", "");
} else if (assignedTask == null || assignedTask.getTaskStatus() == TaskProcess.submit) {
mainVC.contextPut("submitCssClass", "o_active");
if(userCourseEnv.isCourseReadOnly()) {
setSubmittedDocumentsController(ureq);
} else {
setSubmitController(ureq, assignedTask);
}
} else {
mainVC.contextPut("submitCssClass", "o_done");
setSubmittedDocumentsController(ureq);
}
} else if(assignedTask == null || assignedTask.getTaskStatus() == TaskProcess.submit) {
mainVC.contextPut("submitCssClass", "o_active");
if(userCourseEnv.isCourseReadOnly()) {
setSubmittedDocumentsController(ureq);
} else {
setSubmitController(ureq, assignedTask);
}
} else {
mainVC.contextPut("submitCssClass", "o_done");
setSubmittedDocumentsController(ureq);
}
return assignedTask;
}
private void setSubmitController(UserRequest ureq, Task task) {
File documentsDir;
VFSContainer documentsContainer;
if(GTAType.group.name().equals(config.getStringValue(GTACourseNode.GTASK_TYPE))) {
documentsDir = gtaManager.getSubmitDirectory(courseEnv, gtaNode, assessedGroup);
documentsContainer = gtaManager.getSubmitContainer(courseEnv, gtaNode, assessedGroup);
} else {
documentsDir = gtaManager.getSubmitDirectory(courseEnv, gtaNode, getIdentity());
documentsContainer = gtaManager.getSubmitContainer(courseEnv, gtaNode, getIdentity());
}
DueDate dueDate = getSubmissionDueDate(task);
Date deadline = dueDate == null ? null : dueDate.getDueDate();
int maxDocs = config.getIntegerSafe(GTACourseNode.GTASK_MAX_SUBMITTED_DOCS, -1);
submitDocCtrl = new SubmitDocumentsController(ureq, getWindowControl(), task, documentsDir, documentsContainer, maxDocs,
gtaNode, courseEnv, userCourseEnv.isCourseReadOnly(), deadline, "document");
listenTo(submitDocCtrl);
mainVC.put("submitDocs", submitDocCtrl.getInitialComponent());
submitButton = LinkFactory.createCustomLink("run.submit.button", "submit", "run.submit.button", Link.BUTTON, mainVC, this);
submitButton.setElementCssClass("o_sel_course_gta_submit_docs");
submitButton.setCustomEnabledLinkCSS(submitDocCtrl.hasUploadDocuments() ? "btn btn-primary" : "btn btn-default");
submitButton.setIconLeftCSS("o_icon o_icon_submit");
submitButton.setVisible(!userCourseEnv.isCourseReadOnly());
}
private void setSubmittedDocumentsController(UserRequest ureq) {
File documentsDir;
VFSContainer documentsContainer = null;
if(GTAType.group.name().equals(config.getStringValue(GTACourseNode.GTASK_TYPE))) {
documentsDir = gtaManager.getSubmitDirectory(courseEnv, gtaNode, assessedGroup);
documentsContainer = gtaManager.getSubmitContainer(courseEnv, gtaNode, assessedGroup);
} else {
documentsDir = gtaManager.getSubmitDirectory(courseEnv, gtaNode, getIdentity());
documentsContainer = gtaManager.getSubmitContainer(courseEnv, gtaNode, getIdentity());
}
boolean hasDocuments = TaskHelper.hasDocuments(documentsDir);
if(hasDocuments) {
submittedDocCtrl = new DirectoryController(ureq, getWindowControl(), documentsDir, documentsContainer,
"run.submitted.description");
listenTo(submittedDocCtrl);
mainVC.put("submittedDocs", submittedDocCtrl.getInitialComponent());
} else {
TextFactory.createTextComponentFromI18nKey("submittedDocs", "run.submitted.nofiles", getTranslator(), null, true, mainVC);
}
}
private void doConfirmSubmit(UserRequest ureq, Task task) {
String title = translate("run.submit.button");
String text;
File[] submittedDocuments;
VFSContainer documentsContainer;
if(GTAType.group.name().equals(config.getStringValue(GTACourseNode.GTASK_TYPE))) {
documentsContainer = gtaManager.getSubmitContainer(courseEnv, gtaNode, assessedGroup);
File documentsDir = gtaManager.getSubmitDirectory(courseEnv, gtaNode, assessedGroup);
submittedDocuments = documentsDir.listFiles(new SystemFilenameFilter(true, false));
if(submittedDocuments.length == 0) {
text = "<div class='o_warning'>" + translate("run.submit.confirm.warning.group", new String[]{ StringHelper.escapeHtml(assessedGroup.getName()) }) + "</div>";
} else {
text = translate("run.submit.confirm.group", new String[]{ StringHelper.escapeHtml(assessedGroup.getName()) });
}
} else {
documentsContainer = gtaManager.getSubmitContainer(courseEnv, gtaNode, getIdentity());
File documentsDir = gtaManager.getSubmitDirectory(courseEnv, gtaNode, getIdentity());
submittedDocuments = documentsDir.listFiles(new SystemFilenameFilter(true, false));
if(submittedDocuments.length == 0) {
text = "<div class='o_warning'>" + translate("run.submit.confirm.warning") + "</div>";
} else {
text = translate("run.submit.confirm");
}
}
FilesLocked lockedBy = TaskHelper.getDocumentsLocked(documentsContainer, submittedDocuments);
if(lockedBy != null) {
showWarning("warning.submit.documents.edited", new String[]{ lockedBy.getLockedBy(), lockedBy.getLockedFiles() });
} else {
confirmSubmitDialog = activateOkCancelDialog(ureq, title, text, confirmSubmitDialog);
confirmSubmitDialog.setUserObject(task);
}
}
private void doSubmitDocuments(UserRequest ureq, Task task) {
TaskProcess review = gtaManager.nextStep(TaskProcess.submit, gtaNode);
task = gtaManager.updateTask(task, review, gtaNode);
showInfo("run.documents.successfully.submitted");
TaskMultiUserEvent event = new TaskMultiUserEvent(TaskMultiUserEvent.SUMBIT_TASK,
assessedIdentity, assessedGroup, getIdentity());
CoordinatorManager.getInstance().getCoordinator().getEventBus()
.fireEventToListenersOf(event, taskListEventResource);
gtaManager.log("Submit", "submit documents", task, getIdentity(), assessedIdentity, assessedGroup, courseEnv, gtaNode);
cleanUpProcess();
process(ureq);
doUpdateAttempts();
//do send e-mail
if(config.getBooleanSafe(GTACourseNode.GTASK_SUBMISSION_MAIL_CONFIRMATION)) {
doSubmissionEmail();
}
}
private void doSubmissionEmail() {
String body = config.getStringValue(GTACourseNode.GTASK_SUBMISSION_TEXT);
if(StringHelper.containsNonWhitespace(body)) {
MailContext context = new MailContextImpl(getWindowControl().getBusinessControl().getAsString());
List<Identity> recipientsTO;
File submitDirectory;
if(GTAType.group.name().equals(config.getStringValue(GTACourseNode.GTASK_TYPE))) {
recipientsTO = businessGroupService.getMembers(assessedGroup, GroupRoles.participant.name());
submitDirectory = gtaManager.getSubmitDirectory(courseEnv, gtaNode, assessedGroup);
} else {
recipientsTO = Collections.singletonList(assessedIdentity);
submitDirectory = gtaManager.getSubmitDirectory(courseEnv, gtaNode, assessedIdentity);
}
String subject = translate("submission.mail.subject");
File[] files = TaskHelper.getDocuments(submitDirectory);
MailTemplate template = new GTAMailTemplate(subject, body, files, getIdentity(), getTranslator());
MailerResult result = new MailerResult();
MailBundle[] bundles = mailManager.makeMailBundles(context, recipientsTO, template, null, UUID.randomUUID().toString(), result);
mailManager.sendMessage(bundles);
}
}
@Override
protected Task stepReviewAndCorrection(UserRequest ureq, Task assignedTask) {
assignedTask = super.stepReviewAndCorrection(ureq, assignedTask);
mainVC.contextPut("review", Boolean.FALSE);
if(config.getBooleanSafe(GTACourseNode.GTASK_ASSIGNMENT)
|| config.getBooleanSafe(GTACourseNode.GTASK_SUBMIT)) {
if(assignedTask == null || assignedTask.getTaskStatus() == TaskProcess.assignment || assignedTask.getTaskStatus() == TaskProcess.submit) {
mainVC.contextPut("reviewCssClass", "");
} else if(assignedTask.getTaskStatus() == TaskProcess.review) {
mainVC.contextPut("reviewCssClass", "o_active");
setReviews(ureq, true, false);
} else {
mainVC.contextPut("reviewCssClass", "o_done");
setReviews(ureq, false, (assignedTask.getRevisionLoop() > 0));
}
} else if(assignedTask == null || assignedTask.getTaskStatus() == TaskProcess.review) {
mainVC.contextPut("reviewCssClass", "o_active");
setReviews(ureq, true, false);
} else {
mainVC.contextPut("reviewCssClass", "o_done");
setReviews(ureq, false, false);
}
return assignedTask;
}
private void setReviews(UserRequest ureq, boolean waiting, boolean hasRevisions) {
File documentsDir;
VFSContainer documentsContainer = null;
if(GTAType.group.name().equals(config.getStringValue(GTACourseNode.GTASK_TYPE))) {
documentsDir = gtaManager.getCorrectionDirectory(courseEnv, gtaNode, assessedGroup);
documentsContainer = gtaManager.getCorrectionContainer(courseEnv, gtaNode, assessedGroup);
} else {
documentsDir = gtaManager.getCorrectionDirectory(courseEnv, gtaNode, getIdentity());
documentsContainer = gtaManager.getCorrectionContainer(courseEnv, gtaNode, getIdentity());
}
if(TaskHelper.hasDocuments(documentsDir)) {
correctionsCtrl = new DirectoryController(ureq, getWindowControl(), documentsDir, documentsContainer,
"run.corrections.description", "bulk.review", "review");
listenTo(correctionsCtrl);
mainVC.put("corrections", correctionsCtrl.getInitialComponent());
}
String msg;
if (hasRevisions) {
msg = "<i class='o_icon o_icon_warn'> </i> " + translate("run.corrections.rejected");
} else if (waiting) {
msg = "<i class='o_icon o_icon_info'> </i> " + translate("run.review.waiting");
} else {
msg = "<i class='o_icon o_icon_ok'> </i> " + translate("run.review.closed");
}
mainVC.contextPut("reviewMessage", msg);
}
@Override
protected Task stepRevision(UserRequest ureq, Task assignedTask) {
assignedTask = super.stepRevision(ureq, assignedTask);
if(config.getBooleanSafe(GTACourseNode.GTASK_ASSIGNMENT)
|| config.getBooleanSafe(GTACourseNode.GTASK_SUBMIT)
|| config.getBooleanSafe(GTACourseNode.GTASK_REVIEW_AND_CORRECTION)) {
if(assignedTask == null || assignedTask.getTaskStatus() == TaskProcess.assignment || assignedTask.getTaskStatus() == TaskProcess.submit
|| assignedTask.getTaskStatus() == TaskProcess.review) {
mainVC.contextPut("revisionCssClass", "");
} else if(assignedTask.getTaskStatus() == TaskProcess.revision || assignedTask.getTaskStatus() == TaskProcess.correction) {
mainVC.contextPut("revisionCssClass", "o_active");
setRevisionsAndCorrections(ureq, assignedTask);
} else {
mainVC.contextPut("revisionCssClass", "o_done");
setRevisionsAndCorrections(ureq, assignedTask);
}
} else if(assignedTask == null || assignedTask.getTaskStatus() == TaskProcess.revision || assignedTask.getTaskStatus() == TaskProcess.correction) {
mainVC.contextPut("revisionCssClass", "o_active");
setRevisionsAndCorrections(ureq, assignedTask);
} else {
mainVC.contextPut("revisionCssClass", "o_done");
setRevisionsAndCorrections(ureq, assignedTask);
}
return assignedTask;
}
private void setRevisionsAndCorrections(UserRequest ureq, Task task) {
if(task.getRevisionLoop() > 0) {
revisionDocumentsCtrl = new GTAParticipantRevisionAndCorrectionsController(ureq, getWindowControl(),
userCourseEnv, task, gtaNode, assessedGroup, taskListEventResource);
listenTo(revisionDocumentsCtrl);
mainVC.put("revisionDocs", revisionDocumentsCtrl.getInitialComponent());
String msg = null;
if (task.getTaskStatus() == TaskProcess.revision) {
// message about rejected work is displayed in GTAParticipantRevisionAndCorrectionsController
} else if (task.getTaskStatus() == TaskProcess.correction) {
msg = "<i class='o_icon o_icon_info'> </i> " + translate("run.review.waiting");
} else {
msg = "<i class='o_icon o_icon_ok'> </i> " + translate("run.review.closed");
}
mainVC.contextPut("revisionMessage", msg);
} else {
TaskProcess status = task.getTaskStatus();
if (status == TaskProcess.solution || status == TaskProcess.grading || status == TaskProcess.graded) {
mainVC.contextPut("skipRevisions", Boolean.TRUE);
}
}
}
@Override
protected Task stepSolution(UserRequest ureq, Task assignedTask) {
assignedTask = super.stepSolution(ureq, assignedTask);
if(config.getBooleanSafe(GTACourseNode.GTASK_ASSIGNMENT)
|| config.getBooleanSafe(GTACourseNode.GTASK_SUBMIT)
|| config.getBooleanSafe(GTACourseNode.GTASK_REVIEW_AND_CORRECTION)
|| config.getBooleanSafe(GTACourseNode.GTASK_REVISION_PERIOD)) {
if(assignedTask == null || assignedTask.getTaskStatus() == TaskProcess.assignment || assignedTask.getTaskStatus() == TaskProcess.submit
|| assignedTask.getTaskStatus() == TaskProcess.review || assignedTask.getTaskStatus() == TaskProcess.correction
|| assignedTask.getTaskStatus() == TaskProcess.revision) {
mainVC.contextPut("solutionCssClass", "");
} else if(assignedTask.getTaskStatus() == TaskProcess.solution) {
mainVC.contextPut("solutionCssClass", "o_active");
setSolutions(ureq, assignedTask);
} else {
mainVC.contextPut("solutionCssClass", "o_done");
setSolutions(ureq, assignedTask);
}
} else if (assignedTask == null || assignedTask.getTaskStatus() == TaskProcess.solution){
mainVC.contextPut("solutionCssClass", "o_active");
setSolutions(ureq, assignedTask);
} else {
mainVC.contextPut("solutionCssClass", "o_done");
setSolutions(ureq, assignedTask);
}
return assignedTask;
}
private void setSolutions(UserRequest ureq, Task assignedTask) {
DueDate availableDate = getSolutionDueDate(assignedTask);
boolean visible = availableDate == null ||
(availableDate.getDueDate() != null && availableDate.getDueDate().compareTo(new Date()) <= 0);
if(visible) {
File documentsDir = gtaManager.getSolutionsDirectory(courseEnv, gtaNode);
VFSContainer documentsContainer = gtaManager.getSolutionsContainer(courseEnv, gtaNode);
if(TaskHelper.hasDocuments(documentsDir)) {
solutionsCtrl = new DirectoryController(ureq, getWindowControl(), documentsDir, documentsContainer, "run.solutions.description", "bulk.solutions", "solutions");
listenTo(solutionsCtrl);
mainVC.put("solutions", solutionsCtrl.getInitialComponent());
}
} else {
VelocityContainer waitVC = createVelocityContainer("wait_for_solutions");
mainVC.put("solutions", waitVC);
}
}
@Override
protected Task stepGrading(UserRequest ureq, Task assignedTask) {
assignedTask = super.stepGrading(ureq, assignedTask);
String infoTextUser = config.getStringValue(MSCourseNode.CONFIG_KEY_INFOTEXT_USER);
if(StringHelper.containsNonWhitespace(infoTextUser)) {
mainVC.contextPut("gradingInfoTextUser", StringHelper.xssScan(infoTextUser));
}
boolean showGrading = false;
MSCourseNodeRunController msCtrl = new MSCourseNodeRunController(ureq, getWindowControl(), userCourseEnv, gtaNode, false, false);
if(msCtrl.hasScore() || msCtrl.hasPassed() || msCtrl.hasComment()) {
showGrading = true;
} else if(config.getBooleanSafe(GTACourseNode.GTASK_ASSIGNMENT)
|| config.getBooleanSafe(GTACourseNode.GTASK_SUBMIT)
|| config.getBooleanSafe(GTACourseNode.GTASK_REVIEW_AND_CORRECTION)
|| config.getBooleanSafe(GTACourseNode.GTASK_REVISION_PERIOD)
|| config.getBooleanSafe(GTACourseNode.GTASK_GRADING)) {
if(assignedTask == null || assignedTask.getTaskStatus() == TaskProcess.assignment || assignedTask.getTaskStatus() == TaskProcess.submit
|| assignedTask.getTaskStatus() == TaskProcess.review || assignedTask.getTaskStatus() == TaskProcess.correction
|| assignedTask.getTaskStatus() == TaskProcess.revision || assignedTask.getTaskStatus() == TaskProcess.solution) {
mainVC.contextPut("gradingCssClass", "");
} else if(assignedTask.getTaskStatus() == TaskProcess.graded || assignedTask.getTaskStatus() == TaskProcess.grading) {
showGrading = true;
}
} else if (assignedTask == null || assignedTask.getTaskStatus() == TaskProcess.graded || assignedTask.getTaskStatus() == TaskProcess.grading){
showGrading = true;
}
if(showGrading) {
gradingCtrl = msCtrl;
listenTo(gradingCtrl);
if (assignedTask != null && assignedTask.getTaskStatus() == TaskProcess.graded) {
mainVC.contextPut("gradingCssClass", "o_done");
} else {
mainVC.contextPut("gradingCssClass", "o_active");
}
mainVC.put("grading", gradingCtrl.getInitialComponent());
stepPreferences.setGrading(Boolean.TRUE);
}
return assignedTask;
}
@Override
protected void nodeLog() {
if(businessGroupTask) {
String userLog = courseEnv.getAuditManager().getUserNodeLog(gtaNode, getIdentity());
if(StringHelper.containsNonWhitespace(userLog)) {
mainVC.contextPut("userLog", userLog);
} else {
mainVC.contextRemove("userLog");
}
} else {
super.nodeLog();
}
}
private TaskDefinition getTaskDefinition(Task task) {
if(task == null) return null;
TaskDefinition taskDef = null;
List<TaskDefinition> availableTasks = gtaManager.getTaskDefinitions(courseEnv, gtaNode);
for(TaskDefinition availableTask:availableTasks) {
if(availableTask.getFilename() != null && availableTask.getFilename().equals(task.getTaskName())) {
taskDef = availableTask;
break;
}
}
return taskDef;
}
private void setGroupWarning() {
mainVC.contextPut("groupWarning", Boolean.TRUE);
}
private void setGroupHeaders(BusinessGroup group) {
mainVC.contextPut("groupName", group.getName());
openGroupButton = LinkFactory.createButton("open.group", mainVC, this);
openGroupButton.setIconLeftCSS("o_icon o_icon_group");
}
private void setMultiGroupsSelection() {
changeGroupLink = LinkFactory.createLink("change.group", mainVC, this);
}
@Override
protected void doDispose() {
//
}
@Override
protected void processEvent(TaskMultiUserEvent event) {
if(TaskMultiUserEvent.SUMBIT_TASK.equals(event.getCommand())) {
if(submitDocCtrl != null) {
submitDocCtrl.close();
}
} else if(TaskMultiUserEvent.SUBMIT_REVISION.equals(event.getCommand())) {
if(revisionDocumentsCtrl != null) {
revisionDocumentsCtrl.close();
}
}
}
@Override
protected void event(UserRequest ureq, Component source, Event event) {
if(openGroupButton == source) {
doOpenBusinessGroup(ureq);
} else if(changeGroupLink == source) {
doChangeBusinessGroup(ureq);
} else if(submitButton == source) {
Task assignedTask = submitDocCtrl.getAssignedTask();
doConfirmSubmit(ureq, assignedTask);
}
super.event(ureq, source, event);
}
@Override
protected void event(UserRequest ureq, Controller source, Event event) {
if(availableTaskCtrl == source) {
if(event == Event.DONE_EVENT) {
cleanUpProcess();
resetDueDates();
process(ureq);
}
} else if(revisionDocumentsCtrl == source) {
if(event == Event.DONE_EVENT) {
cleanUpProcess();
process(ureq);
}
} else if(businessGroupChooserCtrl == source) {
if(event == Event.DONE_EVENT && businessGroupChooserCtrl.getSelectGroup() != null) {
cleanUpProcess();
resetDueDates();
assessedGroup = businessGroupChooserCtrl.getSelectGroup();
process(ureq);
}
chooserCalloutCtrl.deactivate();
cleanUpPopups();
} else if(chooserCalloutCtrl == source) {
cleanUpPopups();
} else if(confirmSubmitDialog == source) {
if(DialogBoxUIFactory.isOkEvent(event) || DialogBoxUIFactory.isYesEvent(event)) {
Task task = (Task)confirmSubmitDialog.getUserObject();
doSubmitDocuments(ureq, task);
}
cleanUpPopups();
} else if(submitDocCtrl == source) {
boolean hasUploadDocuments = submitDocCtrl.hasUploadDocuments();
if(event instanceof SubmitEvent) {
Task assignedTask = submitDocCtrl.getAssignedTask();
gtaManager.log("Submit", (SubmitEvent)event, assignedTask, getIdentity(), assessedIdentity, assessedGroup, courseEnv, gtaNode);
} else if(event == Event.DONE_EVENT) {
cleanUpProcess();
process(ureq);
}
if(submitButton != null) {
submitButton.setCustomEnabledLinkCSS(hasUploadDocuments ? "btn btn-primary" : "btn btn-default");
}
}
super.event(ureq, source, event);
}
/**
* Remove all the stuff in the main velocity template, discard all controllers
*/
private void cleanUpProcess() {
if(availableTaskCtrl != null) {
mainVC.remove(availableTaskCtrl.getInitialComponent());
}
if(submitDocCtrl != null) {
mainVC.remove(submitDocCtrl.getInitialComponent());
}
if(assignedTaskCtrl != null) {
mainVC.remove(assignedTaskCtrl.getInitialComponent());
}
if(correctionsCtrl != null) {
mainVC.remove(correctionsCtrl.getInitialComponent());
}
if(solutionsCtrl != null) {
mainVC.remove(solutionsCtrl.getInitialComponent());
}
if(gradingCtrl != null) {
mainVC.remove(gradingCtrl.getInitialComponent());
}
removeAsListenerAndDispose(availableTaskCtrl);
removeAsListenerAndDispose(assignedTaskCtrl);
removeAsListenerAndDispose(correctionsCtrl);
removeAsListenerAndDispose(solutionsCtrl);
removeAsListenerAndDispose(submitDocCtrl);
removeAsListenerAndDispose(gradingCtrl);
availableTaskCtrl = null;
assignedTaskCtrl = null;
correctionsCtrl = null;
solutionsCtrl = null;
submitDocCtrl = null;
gradingCtrl = null;
}
private void cleanUpPopups() {
removeAsListenerAndDispose(businessGroupChooserCtrl);
removeAsListenerAndDispose(confirmSubmitDialog);
removeAsListenerAndDispose(chooserCalloutCtrl);
businessGroupChooserCtrl = null;
confirmSubmitDialog = null;
chooserCalloutCtrl = null;
}
private void doOpenBusinessGroup(UserRequest ureq) {
String businessPath = "[BusinessGroup:" + assessedGroup.getKey() + "]";
NewControllerFactory.getInstance().launch(businessPath, ureq, getWindowControl());
}
private void doChangeBusinessGroup(UserRequest ureq) {
removeAsListenerAndDispose(businessGroupChooserCtrl);
removeAsListenerAndDispose(chooserCalloutCtrl);
businessGroupChooserCtrl = new BusinessGroupChooserController(ureq, getWindowControl(), myGroups);
listenTo(businessGroupChooserCtrl);
chooserCalloutCtrl = new CloseableCalloutWindowController(ureq, getWindowControl(),
businessGroupChooserCtrl.getInitialComponent(), changeGroupLink, "", true, "");
listenTo(chooserCalloutCtrl);
chooserCalloutCtrl.activate();
}
}