diff --git a/src/main/java/de/bps/onyx/plugin/OnyxResultManager.java b/src/main/java/de/bps/onyx/plugin/OnyxResultManager.java index 554afe0087f39fed67ac1be4c0d673163d6d1c24..d025cd096e1e9a7f363f44d0bfad5614a0604511 100644 --- a/src/main/java/de/bps/onyx/plugin/OnyxResultManager.java +++ b/src/main/java/de/bps/onyx/plugin/OnyxResultManager.java @@ -53,6 +53,7 @@ import org.olat.course.run.scoring.ScoreEvaluation; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.course.run.userview.UserCourseEnvironmentImpl; import org.olat.ims.qti.QTIResultSet; +import org.olat.modules.assessment.Role; import org.olat.repository.RepositoryEntry; import de.bps.webservices.clients.onyxreporter.OnyxReporterConnector; @@ -194,7 +195,7 @@ public class OnyxResultManager { ScoreEvaluation sc = OnyxModule.getUserScoreEvaluationFromQtiResult(userCourseEnvironment.getCourseEnvironment().getCourseResourceableId(), node, bestResultConfigured, qtiResultSet.getIdentity()); if(node instanceof AssessableCourseNode){ - ((AssessableCourseNode) node).updateUserScoreEvaluation(sc, userCourseEnvironment, qtiResultSet.getIdentity(), false); + ((AssessableCourseNode) node).updateUserScoreEvaluation(sc, userCourseEnvironment, qtiResultSet.getIdentity(), false, Role.coach); } } else { diff --git a/src/main/java/de/bps/onyx/plugin/run/OnyxRunController.java b/src/main/java/de/bps/onyx/plugin/run/OnyxRunController.java index 8e03bf8b5f4b17f06efb17b6a375e688f48886f2..0ffbba6e302d5ef1b03836a4f934c0787d1d14a3 100644 --- a/src/main/java/de/bps/onyx/plugin/run/OnyxRunController.java +++ b/src/main/java/de/bps/onyx/plugin/run/OnyxRunController.java @@ -72,6 +72,7 @@ import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.fileresource.FileResourceManager; import org.olat.ims.qti.QTIResultSet; import org.olat.modules.ModuleConfiguration; +import org.olat.modules.assessment.Role; import org.olat.repository.RepositoryEntry; import de.bps.onyx.plugin.OnyxModule; @@ -569,7 +570,7 @@ public class OnyxRunController extends BasicController { //now increase attempts; if an exception occurred before, this will be not reached if (currentState != TestState.CANCELED) { AssessmentManager am = course.getCourseEnvironment().getAssessmentManager(); - am.incrementNodeAttempts(courseNode, student, userCourseEnv); + am.incrementNodeAttempts(courseNode, student, userCourseEnv, Role.user); } } else { assessmentId = resultSet.getAssessmentID(); diff --git a/src/main/java/de/bps/onyx/plugin/wsserver/ReturnWSService.java b/src/main/java/de/bps/onyx/plugin/wsserver/ReturnWSService.java index 96e00d5e33b572ae874bea287d78f67247af3b49..0a2177e53a2bcc3c61456eaef23be61545ce67fb 100644 --- a/src/main/java/de/bps/onyx/plugin/wsserver/ReturnWSService.java +++ b/src/main/java/de/bps/onyx/plugin/wsserver/ReturnWSService.java @@ -51,6 +51,7 @@ import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.course.run.userview.UserCourseEnvironmentImpl; import org.olat.ims.qti.QTIResultManager; import org.olat.ims.qti.QTIResultSet; +import org.olat.modules.assessment.Role; import org.olat.modules.assessment.model.AssessmentEntryStatus; import de.bps.onyx.plugin.OnyxResultManager; @@ -221,7 +222,7 @@ public class ReturnWSService { } ScoreEvaluation scoreEvaluation = new ScoreEvaluation(qtiResultSet.getScore(), qtiResultSet.getIsPassed(), status, Boolean.TRUE, qtiResultSet.getFullyAssessed(), qtiResultSet.getAssessmentID()); - am.saveScoreEvaluation((AssessableCourseNode)courseNode, null, assessedIdentity, scoreEvaluation, userCourseEnvironment, false); + am.saveScoreEvaluation((AssessableCourseNode)courseNode, null, assessedIdentity, scoreEvaluation, userCourseEnvironment, false, Role.coach); CoreSpringFactory.getImpl(AssessmentNotificationsHandler.class).markPublisherNews(assessedIdentity, resourceId); } diff --git a/src/main/java/org/olat/course/assessment/AssessmentHelper.java b/src/main/java/org/olat/course/assessment/AssessmentHelper.java index 6ec0b0f8d96cfc9b1600eb2b8c95c99a614fa8ed..2331d773c3147eb2356651c2f071a6c1d17f3c81 100644 --- a/src/main/java/org/olat/course/assessment/AssessmentHelper.java +++ b/src/main/java/org/olat/course/assessment/AssessmentHelper.java @@ -48,6 +48,7 @@ import org.olat.core.util.tree.TreeVisitor; import org.olat.core.util.tree.Visitor; import org.olat.course.ICourse; import org.olat.course.assessment.model.AssessmentNodeData; +import org.olat.course.assessment.model.AssessmentNodesLastModified; import org.olat.course.nodes.AssessableCourseNode; import org.olat.course.nodes.CourseNode; import org.olat.course.nodes.CourseNodeConfiguration; @@ -93,6 +94,8 @@ public class AssessmentHelper { public static final String KEY_TOTAL_NODES = "totalNodes"; public static final String KEY_ATTEMPTED_NODES = "attemptedNodes"; public static final String KEY_PASSED_NODES = "attemptedNodes"; + public static final String KEY_LAST_USER_MODIFIED = "lastUserModified"; + public static final String KEY_LAST_COACH_MODIFIED = "lastCoachModified"; /** * String to symbolize 'not available' or 'not assigned' in assessments @@ -432,12 +435,13 @@ public class AssessmentHelper { * @return list of object arrays or null if empty */ public static List<AssessmentNodeData> getAssessmentNodeDataList(UserCourseEnvironment userCourseEnv, + AssessmentNodesLastModified lastModifications, boolean followUserVisibility, boolean discardEmptyNodes, boolean discardComments) { List<AssessmentNodeData> data = new ArrayList<AssessmentNodeData>(50); ScoreAccounting scoreAccounting = userCourseEnv.getScoreAccounting(); scoreAccounting.evaluateAll(); getAssessmentNodeDataList(0, userCourseEnv.getCourseEnvironment().getRunStructure().getRootNode(), - scoreAccounting, userCourseEnv, followUserVisibility, discardEmptyNodes, discardComments, data); + scoreAccounting, userCourseEnv, followUserVisibility, discardEmptyNodes, discardComments, data, lastModifications); return data; } @@ -455,13 +459,14 @@ public class AssessmentHelper { boolean followUserVisibility, boolean discardEmptyNodes, boolean discardComments) { List<AssessmentNodeData> data = new ArrayList<AssessmentNodeData>(50); getAssessmentNodeDataList(0, userCourseEnv.getCourseEnvironment().getRunStructure().getRootNode(), - evaluatedScoreAccounting, userCourseEnv, followUserVisibility, discardEmptyNodes, discardComments, data); + evaluatedScoreAccounting, userCourseEnv, followUserVisibility, discardEmptyNodes, discardComments, data, null); return data; } public static int getAssessmentNodeDataList(int recursionLevel, CourseNode courseNode, ScoreAccounting scoreAccounting, - UserCourseEnvironment userCourseEnv, boolean followUserVisibility, boolean discardEmptyNodes, boolean discardComments, List<AssessmentNodeData> data) { + UserCourseEnvironment userCourseEnv, boolean followUserVisibility, boolean discardEmptyNodes, boolean discardComments, + List<AssessmentNodeData> data, AssessmentNodesLastModified lastModifications) { // 1) Get list of children data using recursion of this method AssessmentNodeData assessmentNodeData = new AssessmentNodeData(recursionLevel, courseNode); data.add(assessmentNodeData); @@ -470,7 +475,7 @@ public class AssessmentHelper { for (int i = 0; i < courseNode.getChildCount(); i++) { CourseNode child = (CourseNode) courseNode.getChildAt(i); numOfChildren += getAssessmentNodeDataList(recursionLevel + 1, child, scoreAccounting, - userCourseEnv, followUserVisibility, discardEmptyNodes, discardComments, data); + userCourseEnv, followUserVisibility, discardEmptyNodes, discardComments, data, lastModifications); } // 2) Get data of this node only if @@ -490,6 +495,14 @@ public class AssessmentHelper { assessmentNodeData.setNumOfAssessmentDocs(scoreEvaluation.getNumOfAssessmentDocs()); } assessmentNodeData.setUserVisibility(scoreEvaluation.getUserVisible()); + assessmentNodeData.setLastModified(scoreEvaluation.getLastModified()); + assessmentNodeData.setLastUserModified(scoreEvaluation.getLastUserModified()); + assessmentNodeData.setLastCoachModified(scoreEvaluation.getLastCoachModified()); + if(lastModifications != null) { + lastModifications.addLastModified(scoreEvaluation.getLastModified()); + lastModifications.addLastUserModified(scoreEvaluation.getLastUserModified()); + lastModifications.addLastCoachModified(scoreEvaluation.getLastCoachModified()); + } if(!followUserVisibility || scoreEvaluation.getUserVisible() == null || scoreEvaluation.getUserVisible().booleanValue()) { // details diff --git a/src/main/java/org/olat/course/assessment/AssessmentManager.java b/src/main/java/org/olat/course/assessment/AssessmentManager.java index 629abda4af4590d1415e93bec7ffd271760b17fc..167b56f6adef5d4f103d09a4ef903eb9f6b2d70a 100644 --- a/src/main/java/org/olat/course/assessment/AssessmentManager.java +++ b/src/main/java/org/olat/course/assessment/AssessmentManager.java @@ -38,6 +38,7 @@ import org.olat.course.run.scoring.ScoreEvaluation; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.group.BusinessGroup; import org.olat.modules.assessment.AssessmentEntry; +import org.olat.modules.assessment.Role; import org.olat.modules.assessment.model.AssessmentEntryStatus; /** @@ -64,7 +65,17 @@ public interface AssessmentManager { * @param assessedIdentity The user whose score is changed * @param attempts The new attempts */ - public void saveNodeAttempts(CourseNode courseNode, Identity identity, Identity assessedIdentity, Integer attempts); + public void saveNodeAttempts(CourseNode courseNode, Identity identity, Identity assessedIdentity, Integer attempts, Role by); + + /** + * Change the last modification dates. + * + * @param courseNode The course node + * @param identity The identity which does the action + * @param assessedIdentity The assessed identity + * @param by The role of the identity which does the action. + */ + public void updateLastModifications(CourseNode courseNode, Identity assessedIdentity, UserCourseEnvironment userCourseEnvironment, Role by); /** * Save an assessment comment for this node for a user. If there is already a comment property available, @@ -111,7 +122,7 @@ public interface AssessmentManager { * @param courseNode * @param identity */ - public void incrementNodeAttempts(CourseNode courseNode, Identity identity, UserCourseEnvironment userCourseEnvironment); + public void incrementNodeAttempts(CourseNode courseNode, Identity identity, UserCourseEnvironment userCourseEnvironment, Role by); /** * Increment the users attempts for this course node, but without logging (aimed at background job). @@ -212,7 +223,8 @@ public interface AssessmentManager { */ public void saveScoreEvaluation(AssessableCourseNode courseNode, Identity identity, Identity assessedIdentity, - ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnvironment, boolean incrementUserAttempts); + ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnvironment, + boolean incrementUserAttempts, Role by); /** * Provides an OLATResourceable for locking (of score/passed etc.) purposes (if doInSync is called on score/passed data) diff --git a/src/main/java/org/olat/course/assessment/EfficiencyStatement.java b/src/main/java/org/olat/course/assessment/EfficiencyStatement.java index 229030fd83d57b7e6b146a26e671ab1100d4ef7a..7003844f7a8e26fd340e758cd58937a4168de069 100644 --- a/src/main/java/org/olat/course/assessment/EfficiencyStatement.java +++ b/src/main/java/org/olat/course/assessment/EfficiencyStatement.java @@ -45,34 +45,62 @@ public class EfficiencyStatement { private Long courseRepoEntryKey; private String displayableUserInfo; private long lastUpdated; + private long lastUserModified; + private long lastCoachModified; public long getLastUpdated() { return lastUpdated; } + public void setLastUpdated(long lastUpdated) { this.lastUpdated = lastUpdated; } + + public long getLastUserModified() { + return lastUserModified; + } + + public void setLastUserModified(long lastUserModified) { + this.lastUserModified = lastUserModified; + } + + public long getLastCoachModified() { + return lastCoachModified; + } + + public void setLastCoachModified(long lastCoachModified) { + this.lastCoachModified = lastCoachModified; + } + public List<Map<String,Object>> getAssessmentNodes() { return assessmentNodes; } + public void setAssessmentNodes(List<Map<String,Object>> assessmentNodes) { this.assessmentNodes = assessmentNodes; } + public Long getCourseRepoEntryKey() { return courseRepoEntryKey; } + public void setCourseRepoEntryKey(Long courseRepoEntryKey) { this.courseRepoEntryKey = courseRepoEntryKey; } + public String getCourseTitle() { return courseTitle; } + public void setCourseTitle(String courseTitle) { this.courseTitle = courseTitle; } + public String getDisplayableUserInfo() { return displayableUserInfo; } + + public void setDisplayableUserInfo(String displayableUserInfo) { this.displayableUserInfo = displayableUserInfo; } diff --git a/src/main/java/org/olat/course/assessment/UserEfficiencyStatement.java b/src/main/java/org/olat/course/assessment/UserEfficiencyStatement.java index 2a9a9f53cab2918bffeb7b0d484d0f989e8b3ebc..226ba10359ce0fddacc45e3f8b96d80d18a7cb3f 100644 --- a/src/main/java/org/olat/course/assessment/UserEfficiencyStatement.java +++ b/src/main/java/org/olat/course/assessment/UserEfficiencyStatement.java @@ -41,6 +41,10 @@ public interface UserEfficiencyStatement { public Date getLastModified(); + public Date getLastUserModified(); + + public Date getLastCoachModified(); + public Date getCreationDate(); public Long getCourseRepoKey(); diff --git a/src/main/java/org/olat/course/assessment/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/assessment/_i18n/LocalStrings_de.properties index 547238d3953c8ec999a681c123897807a6377b44..8f0cfd61c5ac2a4a3f9048e1204483411643f9cc 100644 --- a/src/main/java/org/olat/course/assessment/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/course/assessment/_i18n/LocalStrings_de.properties @@ -152,6 +152,8 @@ table.header.status=Status table.header.type=Typ table.header.initialLaunchDate=Erster Kursstart table.header.lastScoreDate=Letzte Aktualisierung +table.header.lastUserModificationDate=Letzte Benutzer Aktualisierung +table.header.lastCoachModificationDate=Letzte Betreuer Aktualisierung notifications.title=Kurs "{0}" notifications.header=Neue Testresultate in Kurs "{0}" notifications.entry={3}: "{0}" ausgef\u00FChrt von {1} mit {2} Punkten diff --git a/src/main/java/org/olat/course/assessment/bulk/DataStepForm.java b/src/main/java/org/olat/course/assessment/bulk/DataStepForm.java index 9d74870fe85315946d6a67550dce20ced3daaeac..2a43b3170378376f70f3f0bb1ed579ec06927070 100644 --- a/src/main/java/org/olat/course/assessment/bulk/DataStepForm.java +++ b/src/main/java/org/olat/course/assessment/bulk/DataStepForm.java @@ -119,7 +119,7 @@ public class DataStepForm extends StepFormBasicController { OlatRootFileImpl file = new OlatRootFileImpl(savedDatas.getDataBackupFile(), null); InputStream in = file.getInputStream(); try { - dataVal = IOUtils.toString(in); + dataVal = IOUtils.toString(in, "UTF-8"); } catch (IOException e) { logError("", e); } finally { @@ -238,7 +238,7 @@ public class DataStepForm extends StepFormBasicController { OutputStream out = inputFile.getOutputStream(false); try { - IOUtils.write(val, out); + IOUtils.write(val, out, "UTF-8"); datas.setDataBackupFile(inputFile.getRelPath()); } catch (IOException e) { logError("", e); diff --git a/src/main/java/org/olat/course/assessment/manager/BulkAssessmentTask.java b/src/main/java/org/olat/course/assessment/manager/BulkAssessmentTask.java index 7105185a05b9d713f0827905a40266702a4fd6be..52bb19b95700db90a396bf12ba164627cf6bbc18 100644 --- a/src/main/java/org/olat/course/assessment/manager/BulkAssessmentTask.java +++ b/src/main/java/org/olat/course/assessment/manager/BulkAssessmentTask.java @@ -93,6 +93,7 @@ import org.olat.course.run.environment.CourseEnvironment; import org.olat.course.run.scoring.ScoreEvaluation; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.course.run.userview.UserCourseEnvironmentImpl; +import org.olat.modules.assessment.Role; import org.olat.repository.RepositoryEntry; import org.olat.user.UserManager; import org.olat.util.logging.activity.LoggingResourceable; @@ -387,7 +388,7 @@ public class BulkAssessmentTask implements LongRunnable, TaskAwareRunnable, Sequ } // Update score,passed properties in db, and the user's efficiency statement - courseNode.updateUserScoreEvaluation(se, uce, coachIdentity, false); + courseNode.updateUserScoreEvaluation(se, uce, coachIdentity, false, Role.auto); } } @@ -398,7 +399,7 @@ public class BulkAssessmentTask implements LongRunnable, TaskAwareRunnable, Sequ ScoreEvaluation se = new ScoreEvaluation(oldScore, passed); // Update score,passed properties in db, and the user's efficiency statement boolean incrementAttempts = false; - courseNode.updateUserScoreEvaluation(se, uce, coachIdentity, incrementAttempts); + courseNode.updateUserScoreEvaluation(se, uce, coachIdentity, incrementAttempts, Role.auto); } boolean identityHasReturnFile = false; diff --git a/src/main/java/org/olat/course/assessment/manager/CourseAssessmentManagerImpl.java b/src/main/java/org/olat/course/assessment/manager/CourseAssessmentManagerImpl.java index 5f6b5f31b626e45ae650ca0baa064b32b0091d49..98877b30c3e9e13ce352eaea536384f6ff344bb6 100644 --- a/src/main/java/org/olat/course/assessment/manager/CourseAssessmentManagerImpl.java +++ b/src/main/java/org/olat/course/assessment/manager/CourseAssessmentManagerImpl.java @@ -52,6 +52,7 @@ import org.olat.course.assessment.AssessmentHelper; import org.olat.course.assessment.AssessmentLoggingAction; import org.olat.course.assessment.AssessmentManager; import org.olat.course.assessment.model.AssessmentNodeData; +import org.olat.course.assessment.model.AssessmentNodesLastModified; import org.olat.course.auditing.UserNodeAuditManager; import org.olat.course.certificate.CertificateTemplate; import org.olat.course.certificate.CertificatesManager; @@ -60,12 +61,14 @@ import org.olat.course.groupsandrights.CourseGroupManager; import org.olat.course.nodes.AssessableCourseNode; import org.olat.course.nodes.CourseNode; import org.olat.course.run.environment.CourseEnvironment; +import org.olat.course.run.scoring.AssessmentEvaluation; import org.olat.course.run.scoring.ScoreAccounting; import org.olat.course.run.scoring.ScoreEvaluation; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.group.BusinessGroup; import org.olat.modules.assessment.AssessmentEntry; import org.olat.modules.assessment.AssessmentService; +import org.olat.modules.assessment.Role; import org.olat.modules.assessment.model.AssessmentEntryStatus; import org.olat.repository.RepositoryEntry; import org.olat.util.logging.activity.LoggingResourceable; @@ -138,12 +141,20 @@ public class CourseAssessmentManagerImpl implements AssessmentManager { } Float score = null; Boolean passed = null; + Date lastUserModified = null; + Date lastCoachModified = null; if(scoreEvaluation != null) { score = scoreEvaluation.getScore(); passed = scoreEvaluation.getPassed(); } + if(scoreEvaluation instanceof AssessmentEvaluation) { + AssessmentEvaluation eval = (AssessmentEvaluation)scoreEvaluation; + lastCoachModified = eval.getLastCoachModified(); + lastUserModified = eval.getLastUserModified(); + } return assessmentService - .createAssessmentEntry(assessedIdentity, null, cgm.getCourseEntry(), courseNode.getIdent(), referenceEntry, score, passed); + .createAssessmentEntry(assessedIdentity, null, cgm.getCourseEntry(), courseNode.getIdent(), referenceEntry, + score, passed, lastUserModified, lastCoachModified); } @Override @@ -152,10 +163,15 @@ public class CourseAssessmentManagerImpl implements AssessmentManager { } @Override - public void saveNodeAttempts(CourseNode courseNode, Identity identity, Identity assessedIdentity, Integer attempts) { + public void saveNodeAttempts(CourseNode courseNode, Identity identity, Identity assessedIdentity, Integer attempts, Role by) { ICourse course = CourseFactory.loadCourse(cgm.getCourseEntry()); AssessmentEntry nodeAssessment = getOrCreate(assessedIdentity, courseNode); + if(by == Role.coach) { + nodeAssessment.setLastCoachModified(new Date()); + } else if(by == Role.user) { + nodeAssessment.setLastUserModified(new Date()); + } nodeAssessment.setAttempts(attempts); assessmentService.updateAssessmentEntry(nodeAssessment); @@ -281,13 +297,21 @@ public class CourseAssessmentManagerImpl implements AssessmentManager { } @Override - public void incrementNodeAttempts(CourseNode courseNode, Identity assessedIdentity, UserCourseEnvironment userCourseEnv) { + public void incrementNodeAttempts(CourseNode courseNode, Identity assessedIdentity, UserCourseEnvironment userCourseEnv, Role by) { ICourse course = CourseFactory.loadCourse(cgm.getCourseEntry()); AssessmentEntry nodeAssessment = getOrCreate(assessedIdentity, courseNode); int attempts = nodeAssessment.getAttempts() == null ? 1 :nodeAssessment.getAttempts().intValue() + 1; nodeAssessment.setAttempts(attempts); + if(by == Role.coach) { + nodeAssessment.setLastCoachModified(new Date()); + } else if(by == Role.user) { + nodeAssessment.setLastUserModified(new Date()); + } assessmentService.updateAssessmentEntry(nodeAssessment); + DBFactory.getInstance().commit(); + userCourseEnv.getScoreAccounting().evaluateAll(true); + DBFactory.getInstance().commit(); if(courseNode instanceof AssessableCourseNode) { // Update users efficiency statement efficiencyStatementManager.updateUserEfficiencyStatement(userCourseEnv); @@ -322,10 +346,27 @@ public class CourseAssessmentManagerImpl implements AssessmentManager { CoordinatorManager.getInstance().getCoordinator().getEventBus().fireEventToListenersOf(ace, course); } + @Override + public void updateLastModifications(CourseNode courseNode, Identity assessedIdentity, UserCourseEnvironment userCourseEnv, Role by) { + AssessmentEntry nodeAssessment = getOrCreate(assessedIdentity, courseNode); + if(by == Role.coach) { + nodeAssessment.setLastCoachModified(new Date()); + } else if(by == Role.user) { + nodeAssessment.setLastUserModified(new Date()); + } + assessmentService.updateAssessmentEntry(nodeAssessment); + DBFactory.getInstance().commit(); + userCourseEnv.getScoreAccounting().evaluateAll(true); + if(courseNode instanceof AssessableCourseNode) { + // Update users efficiency statement + efficiencyStatementManager.updateUserEfficiencyStatement(userCourseEnv); + } + } + @Override public void saveScoreEvaluation(AssessableCourseNode courseNode, Identity identity, Identity assessedIdentity, ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnv, - boolean incrementUserAttempts) { + boolean incrementUserAttempts, Role by) { final ICourse course = CourseFactory.loadCourse(cgm.getCourseEntry()); final CourseEnvironment courseEnv = userCourseEnv.getCourseEnvironment(); @@ -339,6 +380,11 @@ public class CourseAssessmentManagerImpl implements AssessmentManager { if(referenceEntry != null && !referenceEntry.equals(assessmentEntry.getReferenceEntry())) { assessmentEntry.setReferenceEntry(referenceEntry); } + if(by == Role.coach) { + assessmentEntry.setLastCoachModified(new Date()); + } else if(by == Role.user) { + assessmentEntry.setLastUserModified(new Date()); + } if(score == null) { assessmentEntry.setScore(null); } else { @@ -413,9 +459,10 @@ public class CourseAssessmentManagerImpl implements AssessmentManager { // write only when enabled for this course if (courseEnv.getCourseConfig().isEfficencyStatementEnabled()) { List<AssessmentNodeData> data = new ArrayList<AssessmentNodeData>(50); + AssessmentNodesLastModified lastModifications = new AssessmentNodesLastModified(); AssessmentHelper.getAssessmentNodeDataList(0, courseEnv.getRunStructure().getRootNode(), - scoreAccounting, userCourseEnv, true, true, true, data); - efficiencyStatementManager.updateUserEfficiencyStatement(assessedIdentity, courseEnv, data, cgm.getCourseEntry()); + scoreAccounting, userCourseEnv, true, true, true, data, lastModifications); + efficiencyStatementManager.updateUserEfficiencyStatement(assessedIdentity, courseEnv, data, lastModifications, cgm.getCourseEntry()); } if(course.getCourseConfig().isAutomaticCertificationEnabled()) { diff --git a/src/main/java/org/olat/course/assessment/manager/EfficiencyStatementManager.java b/src/main/java/org/olat/course/assessment/manager/EfficiencyStatementManager.java index b3eea997c07ed9e5650b84ed82a32ee56b71d4b8..037474f02dbe102ea3af825b6ca308f77953ce69 100644 --- a/src/main/java/org/olat/course/assessment/manager/EfficiencyStatementManager.java +++ b/src/main/java/org/olat/course/assessment/manager/EfficiencyStatementManager.java @@ -54,6 +54,7 @@ import org.olat.course.assessment.EfficiencyStatement; import org.olat.course.assessment.EfficiencyStatementArchiver; import org.olat.course.assessment.UserEfficiencyStatement; import org.olat.course.assessment.model.AssessmentNodeData; +import org.olat.course.assessment.model.AssessmentNodesLastModified; import org.olat.course.assessment.model.UserEfficiencyStatementImpl; import org.olat.course.assessment.model.UserEfficiencyStatementLight; import org.olat.course.assessment.model.UserEfficiencyStatementStandalone; @@ -166,15 +167,17 @@ public class EfficiencyStatementManager implements UserDataDeletable { CourseConfig cc = userCourseEnv.getCourseEnvironment().getCourseConfig(); // write only when enabled for this course if (cc.isEfficencyStatementEnabled()) { - Identity identity = userCourseEnv.getIdentityEnvironment().getIdentity(); - List<AssessmentNodeData> assessmentNodeList = AssessmentHelper.getAssessmentNodeDataList(userCourseEnv, true, true, true); - updateUserEfficiencyStatement(identity, userCourseEnv.getCourseEnvironment(), assessmentNodeList, repoEntry); + Identity identity = userCourseEnv.getIdentityEnvironment().getIdentity(); + AssessmentNodesLastModified lastModifications = new AssessmentNodesLastModified(); + List<AssessmentNodeData> assessmentNodeList = AssessmentHelper.getAssessmentNodeDataList(userCourseEnv, lastModifications, true, true, true); + updateUserEfficiencyStatement(identity, userCourseEnv.getCourseEnvironment(), assessmentNodeList, lastModifications, repoEntry); } } - public void updateUserEfficiencyStatement(Identity assessedIdentity, final CourseEnvironment courseEnv, List<AssessmentNodeData> assessmentNodeList, final RepositoryEntry repoEntry) { + public void updateUserEfficiencyStatement(Identity assessedIdentity, final CourseEnvironment courseEnv, + List<AssessmentNodeData> assessmentNodeList, AssessmentNodesLastModified lastModifications, final RepositoryEntry repoEntry) { List<Map<String,Object>> assessmentNodes = AssessmentHelper.assessmentNodeDataListToMap(assessmentNodeList); - + EfficiencyStatement efficiencyStatement = new EfficiencyStatement(); efficiencyStatement.setAssessmentNodes(assessmentNodes); efficiencyStatement.setCourseTitle(courseEnv.getCourseTitle()); @@ -182,6 +185,14 @@ public class EfficiencyStatementManager implements UserDataDeletable { String userInfos = userManager.getUserDisplayName(assessedIdentity); efficiencyStatement.setDisplayableUserInfo(userInfos); efficiencyStatement.setLastUpdated(System.currentTimeMillis()); + if(lastModifications != null) { + if(lastModifications.getLastUserModified() != null) { + efficiencyStatement.setLastUserModified(lastModifications.getLastUserModified().getTime()); + } + if(lastModifications.getLastCoachModified() != null) { + efficiencyStatement.setLastCoachModified(lastModifications.getLastCoachModified().getTime()); + } + } boolean debug = log.isDebug(); UserEfficiencyStatementImpl efficiencyProperty = getUserEfficiencyStatementFull(repoEntry, assessedIdentity); @@ -196,7 +207,7 @@ public class EfficiencyStatementManager implements UserDataDeletable { efficiencyProperty.setCourseRepoKey(repoEntry.getKey()); } - fillEfficiencyStatement(efficiencyStatement, efficiencyProperty); + fillEfficiencyStatement(efficiencyStatement, lastModifications, efficiencyProperty); dbInstance.getCurrentEntityManager().persist(efficiencyProperty); if (debug) { log.debug("creating new efficiency statement property::" + efficiencyProperty.getKey() + " for id::" + assessedIdentity.getName() + " repoEntry::" + repoEntry.getKey()); @@ -206,7 +217,7 @@ public class EfficiencyStatementManager implements UserDataDeletable { if (debug) { log.debug("updating efficiency statement property::" + efficiencyProperty.getKey() + " for id::" + assessedIdentity.getName() + " repoEntry::" + repoEntry.getKey()); } - fillEfficiencyStatement(efficiencyStatement, efficiencyProperty); + fillEfficiencyStatement(efficiencyStatement, lastModifications, efficiencyProperty); dbInstance.getCurrentEntityManager().merge(efficiencyProperty); } } else { @@ -226,7 +237,18 @@ public class EfficiencyStatementManager implements UserDataDeletable { CoordinatorManager.getInstance().getCoordinator().getEventBus().fireEventToListenersOf(ace, courseOres); } - public void fillEfficiencyStatement(EfficiencyStatement efficiencyStatement, UserEfficiencyStatementImpl efficiencyProperty) { + public void fillEfficiencyStatement(EfficiencyStatement efficiencyStatement, AssessmentNodesLastModified lastModifications, UserEfficiencyStatementImpl efficiencyProperty) { + if(lastModifications != null) { + if(lastModifications.getLastUserModified() != null + && (efficiencyProperty.getLastUserModified() == null || efficiencyProperty.getLastUserModified().before(lastModifications.getLastUserModified()))) { + efficiencyProperty.setLastUserModified(lastModifications.getLastUserModified()); + } + if(lastModifications.getLastCoachModified() != null + && (efficiencyProperty.getLastCoachModified() == null || efficiencyProperty.getLastCoachModified().before(lastModifications.getLastCoachModified()))) { + efficiencyProperty.setLastCoachModified(lastModifications.getLastCoachModified()); + } + } + List<Map<String,Object>> nodeData = efficiencyStatement.getAssessmentNodes(); if(!nodeData.isEmpty()) { Map<String,Object> rootNode = nodeData.get(0); @@ -264,6 +286,21 @@ public class EfficiencyStatementManager implements UserDataDeletable { int passedNodes = getPassedNodes(nodeData); efficiencyProperty.setPassedNodes(passedNodes); + + for(Map<String,Object> node:nodeData) { + Date lastUserModified = (Date)node.get(AssessmentHelper.KEY_LAST_USER_MODIFIED); + if(lastUserModified != null) { + if(efficiencyProperty.getLastUserModified() == null || efficiencyProperty.getLastUserModified().before(lastUserModified)) { + efficiencyProperty.setLastUserModified(lastUserModified); + } + } + Date lastCoachModified = (Date)node.get(AssessmentHelper.KEY_LAST_COACH_MODIFIED); + if(lastCoachModified != null) { + if(efficiencyProperty.getLastCoachModified() == null || efficiencyProperty.getLastCoachModified().before(lastCoachModified)) { + efficiencyProperty.setLastCoachModified(lastCoachModified); + } + } + } } efficiencyProperty.setLastModified(new Date()); @@ -599,6 +636,10 @@ public class EfficiencyStatementManager implements UserDataDeletable { .getResultList(); } + public List<Identity> findIdentitiesWithEfficiencyStatements(RepositoryEntryRef repoEntry) { + return findIdentitiesWithEfficiencyStatements(repoEntry.getKey()); + } + /** * Find all identities who have an efficiency statement for this course repository entry * @param courseRepoEntryKey diff --git a/src/main/java/org/olat/course/assessment/model/AssessmentNodeData.java b/src/main/java/org/olat/course/assessment/model/AssessmentNodeData.java index ef84de8e3dbe23b01f7d283d615e79b385c1d980..b05a6f58569ba8b9fa191420f60099a3c294d931 100644 --- a/src/main/java/org/olat/course/assessment/model/AssessmentNodeData.java +++ b/src/main/java/org/olat/course/assessment/model/AssessmentNodeData.java @@ -23,6 +23,8 @@ import static org.olat.course.assessment.AssessmentHelper.KEY_ATTEMPTS; import static org.olat.course.assessment.AssessmentHelper.KEY_DETAILS; import static org.olat.course.assessment.AssessmentHelper.KEY_IDENTIFYER; import static org.olat.course.assessment.AssessmentHelper.KEY_INDENT; +import static org.olat.course.assessment.AssessmentHelper.KEY_LAST_COACH_MODIFIED; +import static org.olat.course.assessment.AssessmentHelper.KEY_LAST_USER_MODIFIED; import static org.olat.course.assessment.AssessmentHelper.KEY_MAX; import static org.olat.course.assessment.AssessmentHelper.KEY_MIN; import static org.olat.course.assessment.AssessmentHelper.KEY_PASSED; @@ -33,6 +35,7 @@ import static org.olat.course.assessment.AssessmentHelper.KEY_TITLE_LONG; import static org.olat.course.assessment.AssessmentHelper.KEY_TITLE_SHORT; import static org.olat.course.assessment.AssessmentHelper.KEY_TYPE; +import java.util.Date; import java.util.HashMap; import java.util.Map; @@ -72,6 +75,10 @@ public class AssessmentNodeData { private int numOfAssessmentDocs; + private Date lastModified; + private Date lastUserModified; + private Date lastCoachModified; + private boolean selectable; private boolean onyx = false; @@ -215,6 +222,30 @@ public class AssessmentNodeData { this.numOfAssessmentDocs = numOfAssessmentDocs; } + public Date getLastModified() { + return lastModified; + } + + public void setLastModified(Date lastModified) { + this.lastModified = lastModified; + } + + public Date getLastUserModified() { + return lastUserModified; + } + + public void setLastUserModified(Date lastUserModified) { + this.lastUserModified = lastUserModified; + } + + public Date getLastCoachModified() { + return lastCoachModified; + } + + public void setLastCoachModified(Date lastCoachModified) { + this.lastCoachModified = lastCoachModified; + } + public boolean isOnyx() { return onyx; } @@ -258,6 +289,12 @@ public class AssessmentNodeData { if (passed != null) { nodeData.put(KEY_PASSED, passed); } + if(lastUserModified != null) { + nodeData.put(KEY_LAST_USER_MODIFIED, lastUserModified); + } + if(lastCoachModified != null) { + nodeData.put(KEY_LAST_COACH_MODIFIED, lastCoachModified); + } nodeData.put(KEY_SELECTABLE, selectable ? Boolean.TRUE : Boolean.FALSE); return nodeData; } @@ -280,6 +317,13 @@ public class AssessmentNodeData { if(nodeData.get(KEY_SELECTABLE) instanceof Boolean) { selectable = ((Boolean)nodeData.get(KEY_SELECTABLE)).booleanValue(); } + if(nodeData.get(KEY_LAST_USER_MODIFIED) instanceof Date) { + lastUserModified = ((Date)nodeData.get(KEY_LAST_USER_MODIFIED)); + } + if(nodeData.get(KEY_LAST_COACH_MODIFIED) instanceof Date) { + lastCoachModified = ((Date)nodeData.get(KEY_LAST_COACH_MODIFIED)); + } + } @Override diff --git a/src/main/java/org/olat/course/assessment/model/AssessmentNodesLastModified.java b/src/main/java/org/olat/course/assessment/model/AssessmentNodesLastModified.java new file mode 100644 index 0000000000000000000000000000000000000000..159015f85a63d4f348815f16c209b6601f676b6e --- /dev/null +++ b/src/main/java/org/olat/course/assessment/model/AssessmentNodesLastModified.java @@ -0,0 +1,77 @@ +/** + * <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.assessment.model; + +import java.util.Date; + +/** + * + * Initial date: 14 août 2017<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class AssessmentNodesLastModified { + + private Date lastModified; + private Date lastUserModified; + private Date lastCoachModified; + + public Date getLastModified() { + return lastModified; + } + + public void addLastModified(Date date) { + if(date == null) return; + + if(lastModified == null) { + lastModified = date; + } else if(lastModified != null && lastModified.before(date)) { + lastModified = date; + } + } + + public Date getLastUserModified() { + return lastUserModified; + } + + public void addLastUserModified(Date date) { + if(date == null) return; + + if(lastUserModified == null) { + lastUserModified = date; + } else if(lastUserModified != null && lastUserModified.before(date)) { + lastUserModified = date; + } + } + + public Date getLastCoachModified() { + return lastCoachModified; + } + + public void addLastCoachModified(Date date) { + if(date == null) return; + + if(lastCoachModified == null) { + lastCoachModified = date; + } else if(lastCoachModified != null && lastCoachModified.before(date)) { + lastCoachModified = date; + } + } +} diff --git a/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementImpl.hbm.xml b/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementImpl.hbm.xml index d17e726464a5bcd4df31095373b690eab44752b2..49c302f498f529ba4a4a4d10b468fca726280fa4 100644 --- a/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementImpl.hbm.xml +++ b/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementImpl.hbm.xml @@ -20,6 +20,8 @@ <version name="version" access="field" column="version" type="int"/> <property name="creationDate" column="creationdate" type="timestamp" /> <property name="lastModified" column="lastmodified" type="timestamp" /> + <property name="lastUserModified" column="lastusermodified" type="timestamp" /> + <property name="lastCoachModified" column="lastcoachmodified" type="timestamp" /> <property name="score" column="score" type="float" /> <property name="passed" column="passed" type="boolean" /> @@ -66,6 +68,8 @@ <version name="version" access="field" column="version" type="int"/> <property name="creationDate" column="creationdate" type="timestamp" /> <property name="lastModified" column="lastmodified" type="timestamp" /> + <property name="lastUserModified" column="lastusermodified" type="timestamp" /> + <property name="lastCoachModified" column="lastcoachmodified" type="timestamp" /> <property name="score" column="score" type="float" /> <property name="passed" column="passed" type="boolean" /> @@ -104,6 +108,8 @@ <version name="version" access="field" column="version" type="int"/> <property name="creationDate" column="creationdate" type="timestamp" /> <property name="lastModified" column="lastmodified" type="timestamp" /> + <property name="lastUserModified" column="lastusermodified" type="timestamp" /> + <property name="lastCoachModified" column="lastcoachmodified" type="timestamp" /> <property name="score" column="score" type="float" /> <property name="passed" column="passed" type="boolean" /> diff --git a/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementImpl.java b/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementImpl.java index 40865dcd4786222bb6985928b5822720774beadb..2b4838673ec4864bb6e3d2dd420e147e2126469e 100644 --- a/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementImpl.java +++ b/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementImpl.java @@ -51,6 +51,12 @@ public class UserEfficiencyStatementImpl extends PersistentObject implements Use private String statementXml; private Date lastModified; + private Date lastUserModified; + private Date lastCoachModified; + + public UserEfficiencyStatementImpl() { + // + } @Override public Date getLastModified() { @@ -62,6 +68,22 @@ public class UserEfficiencyStatementImpl extends PersistentObject implements Use this.lastModified = lastModified; } + public Date getLastUserModified() { + return lastUserModified; + } + + public void setLastUserModified(Date lastUserModified) { + this.lastUserModified = lastUserModified; + } + + public Date getLastCoachModified() { + return lastCoachModified; + } + + public void setLastCoachModified(Date lastCoachModified) { + this.lastCoachModified = lastCoachModified; + } + @Override public Float getScore() { return score; diff --git a/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementLight.java b/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementLight.java index bfd22f56b16c3553103e6da2a99e4c47b8e008d6..f256aacf073ae3a4f13d09d77f9267a3def4492b 100644 --- a/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementLight.java +++ b/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementLight.java @@ -53,6 +53,8 @@ public class UserEfficiencyStatementLight extends PersistentObject implements Us private Long archivedResourceKey; private Date lastModified; + private Date lastUserModified; + private Date lastCoachModified; @Override public Date getLastModified() { @@ -64,6 +66,22 @@ public class UserEfficiencyStatementLight extends PersistentObject implements Us this.lastModified = lastModified; } + public Date getLastUserModified() { + return lastUserModified; + } + + public void setLastUserModified(Date lastUserModified) { + this.lastUserModified = lastUserModified; + } + + public Date getLastCoachModified() { + return lastCoachModified; + } + + public void setLastCoachModified(Date lastCoachModified) { + this.lastCoachModified = lastCoachModified; + } + @Override public Float getScore() { return score; diff --git a/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementStandalone.java b/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementStandalone.java index 1a3d2a9c3e546d6f482a01d4d01fdb411ab0d0d9..3effbfee69654c221d02a500ff3d0c9f9bd2e0f1 100644 --- a/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementStandalone.java +++ b/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementStandalone.java @@ -53,6 +53,8 @@ public class UserEfficiencyStatementStandalone extends PersistentObject implemen private String statementXml; private Date lastModified; + private Date lastUserModified; + private Date lastCoachModified; @Override public Date getLastModified() { @@ -64,6 +66,22 @@ public class UserEfficiencyStatementStandalone extends PersistentObject implemen this.lastModified = lastModified; } + public Date getLastUserModified() { + return lastUserModified; + } + + public void setLastUserModified(Date lastUserModified) { + this.lastUserModified = lastUserModified; + } + + public Date getLastCoachModified() { + return lastCoachModified; + } + + public void setLastCoachModified(Date lastCoachModified) { + this.lastCoachModified = lastCoachModified; + } + @Override public Float getScore() { return score; diff --git a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentForm.java b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentForm.java index d626b3fbf31eec0ab5f23521791cfb5fd6999427..f975473b8ffaa56e50ab984c6640130b1ca4979e 100644 --- a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentForm.java +++ b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentForm.java @@ -63,6 +63,7 @@ import org.olat.course.nodes.AssessableCourseNode; import org.olat.course.run.scoring.ScoreAccounting; import org.olat.course.run.scoring.ScoreEvaluation; import org.olat.course.run.userview.UserCourseEnvironment; +import org.olat.modules.assessment.Role; import org.olat.modules.assessment.model.AssessmentEntryStatus; import org.olat.modules.assessment.ui.event.AssessmentFormEvent; @@ -315,7 +316,7 @@ public class AssessmentForm extends FormBasicController { ScoreEvaluation reopenedEval = new ScoreEvaluation(scoreEval.getScore(), scoreEval.getPassed(), AssessmentEntryStatus.inReview, scoreEval.getUserVisible(), scoreEval.getFullyAssessed(), scoreEval.getAssessmentID()); - assessableCourseNode.updateUserScoreEvaluation(reopenedEval, assessedUserCourseEnv, getIdentity(), false); + assessableCourseNode.updateUserScoreEvaluation(reopenedEval, assessedUserCourseEnv, getIdentity(), false, Role.coach); updateStatus(reopenedEval); } } @@ -337,7 +338,7 @@ public class AssessmentForm extends FormBasicController { Boolean updatedPassed = null; if (isHasAttempts() && isAttemptsDirty()) { - assessableCourseNode.updateUserAttempts(new Integer(getAttempts()), assessedUserCourseEnv, getIdentity()); + assessableCourseNode.updateUserAttempts(new Integer(getAttempts()), assessedUserCourseEnv, getIdentity(), Role.coach); } if (isHasScore()) { @@ -368,7 +369,7 @@ public class AssessmentForm extends FormBasicController { } else { scoreEval = new ScoreEvaluation(updatedScore, updatedPassed, null, visibility, null, null); } - assessableCourseNode.updateUserScoreEvaluation(scoreEval, assessedUserCourseEnv, getIdentity(), false); + assessableCourseNode.updateUserScoreEvaluation(scoreEval, assessedUserCourseEnv, getIdentity(), false, Role.coach); if (isHasComment() && isUserCommentDirty()) { String newComment = getUserComment().getValue(); diff --git a/src/main/java/org/olat/course/assessment/ui/tool/IdentityAssessmentOverviewController.java b/src/main/java/org/olat/course/assessment/ui/tool/IdentityAssessmentOverviewController.java index aa51bff7267effcc204fe81297a317dc48a7c6e1..ac6eb53e4e0a10a387e37603b17bc2e5a0485236 100644 --- a/src/main/java/org/olat/course/assessment/ui/tool/IdentityAssessmentOverviewController.java +++ b/src/main/java/org/olat/course/assessment/ui/tool/IdentityAssessmentOverviewController.java @@ -242,6 +242,10 @@ public class IdentityAssessmentOverviewController extends FormBasicController im columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(NodeCols.passed, new PassedCellRenderer())); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(NodeCols.numOfAssessmentDocs)); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(NodeCols.status, new AssessmentStatusCellRenderer(getLocale()))); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, NodeCols.lastModified)); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(NodeCols.lastUserModified)); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, NodeCols.lastCoachModified)); + if(nodesSelectable) { DefaultFlexiColumnModel selectCol = new DefaultFlexiColumnModel("select", NodeCols.select.ordinal(), CMD_SELECT_NODE, new BooleanCellRenderer(new StaticFlexiCellRenderer(translate("select"), CMD_SELECT_NODE), null)); @@ -278,7 +282,7 @@ public class IdentityAssessmentOverviewController extends FormBasicController im List<AssessmentNodeData> nodesTableList; if (loadNodesFromCourse) { // get list of course node and user data and populate table data model - nodesTableList = AssessmentHelper.getAssessmentNodeDataList(userCourseEnvironment, followUserResultsVisibility, discardEmptyNodes, true); + nodesTableList = AssessmentHelper.getAssessmentNodeDataList(userCourseEnvironment, null, followUserResultsVisibility, discardEmptyNodes, true); } else { // use list from efficiency statement nodesTableList = preloadedNodesList; diff --git a/src/main/java/org/olat/course/assessment/ui/tool/IdentityAssessmentOverviewTableModel.java b/src/main/java/org/olat/course/assessment/ui/tool/IdentityAssessmentOverviewTableModel.java index 64aa05045ed9a3425b61af9f5ba699c35036e366..f344f864c65604a3b68900297256dd933c9dae79 100644 --- a/src/main/java/org/olat/course/assessment/ui/tool/IdentityAssessmentOverviewTableModel.java +++ b/src/main/java/org/olat/course/assessment/ui/tool/IdentityAssessmentOverviewTableModel.java @@ -109,6 +109,9 @@ public class IdentityAssessmentOverviewTableModel extends DefaultFlexiTableDataM return nodeData.getNumOfAssessmentDocs(); } case select: return nodeData.isSelectable(); + case lastModified: return nodeData.getLastModified(); + case lastUserModified: return nodeData.getLastUserModified(); + case lastCoachModified: return nodeData.getLastCoachModified(); default: return "ERROR"; } } @@ -136,7 +139,10 @@ public class IdentityAssessmentOverviewTableModel extends DefaultFlexiTableDataM status("table.header.status", true), passed("table.header.passed", true), select("table.action.select", false), - numOfAssessmentDocs("table.header.num.assessmentDocs", true); + numOfAssessmentDocs("table.header.num.assessmentDocs", true), + lastModified("table.header.lastScoreDate", true), + lastUserModified("table.header.lastUserModificationDate", true), + lastCoachModified("table.header.lastCoachModificationDate", true); private final String i18nKey; private final boolean sortable; diff --git a/src/main/java/org/olat/course/assessment/ui/tool/IdentityListCourseNodeController.java b/src/main/java/org/olat/course/assessment/ui/tool/IdentityListCourseNodeController.java index 2168f49f35903f184bbed68bba698321a5436690..d5c96424fef0f3655620cb1fbdc6a2d6f8321f3d 100644 --- a/src/main/java/org/olat/course/assessment/ui/tool/IdentityListCourseNodeController.java +++ b/src/main/java/org/olat/course/assessment/ui/tool/IdentityListCourseNodeController.java @@ -91,6 +91,7 @@ import org.olat.course.run.userview.UserCourseEnvironmentImpl; import org.olat.group.BusinessGroup; import org.olat.modules.assessment.AssessmentEntry; import org.olat.modules.assessment.AssessmentToolOptions; +import org.olat.modules.assessment.Role; import org.olat.modules.assessment.model.AssessmentEntryStatus; import org.olat.modules.assessment.ui.AssessedIdentityController; import org.olat.modules.assessment.ui.AssessedIdentityElementRow; @@ -251,8 +252,13 @@ public class IdentityListCourseNodeController extends FormBasicController implem } columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.assessmentStatus, new AssessmentStatusCellRenderer(getLocale()))); - columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.initialLaunchDate, select)); - columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.lastScoreUpdate, select)); + if(courseNode.getParent() == null) { + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.initialLaunchDate, select)); + } + + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, IdentityCourseElementCols.lastModified, select)); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.lastUserModified, select)); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, IdentityCourseElementCols.lastCoachModified, select)); if(course.getCourseConfig().isCertificateEnabled()) { columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.certificate, new DownloadCertificateCellRenderer())); @@ -646,7 +652,7 @@ public class IdentityListCourseNodeController extends FormBasicController implem ScoreEvaluation scoreEval = assessableCourseNode.getUserScoreEvaluation(assessedUserCourseEnv); ScoreEvaluation doneEval = new ScoreEvaluation(scoreEval.getScore(), scoreEval.getPassed(), scoreEval.getAssessmentStatus(), visibility, scoreEval.getFullyAssessed(), scoreEval.getAssessmentID()); - assessableCourseNode.updateUserScoreEvaluation(doneEval, assessedUserCourseEnv, getIdentity(), false); + assessableCourseNode.updateUserScoreEvaluation(doneEval, assessedUserCourseEnv, getIdentity(), false, Role.coach); } updateModel(ureq, null, null, null); } @@ -679,7 +685,7 @@ public class IdentityListCourseNodeController extends FormBasicController implem ScoreEvaluation scoreEval = assessableCourseNode.getUserScoreEvaluation(assessedUserCourseEnv); ScoreEvaluation doneEval = new ScoreEvaluation(scoreEval.getScore(), scoreEval.getPassed(), AssessmentEntryStatus.done, null, scoreEval.getFullyAssessed(), scoreEval.getAssessmentID()); - assessableCourseNode.updateUserScoreEvaluation(doneEval, assessedUserCourseEnv, getIdentity(), false); + assessableCourseNode.updateUserScoreEvaluation(doneEval, assessedUserCourseEnv, getIdentity(), false, Role.coach); } updateModel(ureq, null, null, null); diff --git a/src/main/java/org/olat/course/assessment/ui/tool/IdentityListCourseNodeTableModel.java b/src/main/java/org/olat/course/assessment/ui/tool/IdentityListCourseNodeTableModel.java index bc25f7d5ea063c511027c856468e22c807eeeee4..80cb2d4c12e8305103904c1f4450efc4af18d679 100644 --- a/src/main/java/org/olat/course/assessment/ui/tool/IdentityListCourseNodeTableModel.java +++ b/src/main/java/org/olat/course/assessment/ui/tool/IdentityListCourseNodeTableModel.java @@ -147,7 +147,9 @@ public class IdentityListCourseNodeTableModel extends DefaultFlexiTableDataModel return certificate == null ? null : certificate.getNextRecertificationDate(); } case initialLaunchDate: return row.getInitialCourseLaunchDate(); - case lastScoreUpdate: return row.getLastModified(); + case lastModified: return row.getLastModified(); + case lastUserModified: return row.getLastUserModified(); + case lastCoachModified: return row.getLastCoachModified(); } } int propPos = col - AssessmentToolConstants.USER_PROPS_OFFSET; @@ -172,7 +174,9 @@ public class IdentityListCourseNodeTableModel extends DefaultFlexiTableDataModel certificate("table.header.certificate"), recertification("table.header.recertification"), initialLaunchDate("table.header.initialLaunchDate"), - lastScoreUpdate("table.header.lastScoreDate"), + lastModified("table.header.lastScoreDate"), + lastUserModified("table.header.lastUserModificationDate"), + lastCoachModified("table.header.lastCoachModificationDate"), numOfAssessmentDocs("table.header.num.assessmentDocs"); private final String i18nKey; diff --git a/src/main/java/org/olat/course/certificate/ui/CertificateAndEfficiencyStatementController.java b/src/main/java/org/olat/course/certificate/ui/CertificateAndEfficiencyStatementController.java index a82259ee52be5dc96ea17944ed28fea0f284a852..b9f6f16c34dfbba06075c59915b0707d6951c45d 100644 --- a/src/main/java/org/olat/course/certificate/ui/CertificateAndEfficiencyStatementController.java +++ b/src/main/java/org/olat/course/certificate/ui/CertificateAndEfficiencyStatementController.java @@ -233,7 +233,14 @@ public class CertificateAndEfficiencyStatementController extends BasicController private void populateAssessedIdentityInfos(UserRequest ureq, RepositoryEntry courseRepo, BusinessGroup group, boolean links) { if(efficiencyStatement != null) { mainVC.contextPut("courseTitle", StringHelper.escapeHtml(efficiencyStatement.getCourseTitle())); - mainVC.contextPut("date", StringHelper.formatLocaleDateTime(efficiencyStatement.getLastUpdated(), ureq.getLocale())); + + long lastModified; + if(efficiencyStatement.getLastUserModified() > 0) { + lastModified = efficiencyStatement.getLastUserModified(); + } else { + lastModified = efficiencyStatement.getLastUpdated(); + } + mainVC.contextPut("date", StringHelper.formatLocaleDateTime(lastModified, getLocale())); } else if(courseRepo != null) { mainVC.contextPut("courseTitle", StringHelper.escapeHtml(courseRepo.getDisplayname())); } diff --git a/src/main/java/org/olat/course/nodes/AssessableCourseNode.java b/src/main/java/org/olat/course/nodes/AssessableCourseNode.java index 96b40f918ec3871c26001549f1c06870bb65327d..cc9b95237d11ff763aec20a31268088fad021183 100644 --- a/src/main/java/org/olat/course/nodes/AssessableCourseNode.java +++ b/src/main/java/org/olat/course/nodes/AssessableCourseNode.java @@ -1,4 +1,5 @@ /** + * OLAT - Online Learning and Training<br> * http://www.olat.org * <p> @@ -38,6 +39,7 @@ import org.olat.course.run.scoring.AssessmentEvaluation; import org.olat.course.run.scoring.ScoreEvaluation; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.modules.assessment.AssessmentToolOptions; +import org.olat.modules.assessment.Role; /** @@ -183,7 +185,7 @@ public interface AssessableCourseNode extends CourseNode { * @param userCourseEnvironment * @param coachingIdentity */ - public void updateUserScoreEvaluation(ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity, boolean incrementAttempts); + public void updateUserScoreEvaluation(ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity, boolean incrementAttempts, Role doneBy); /** * Updates the user comment for this node and this user. This comment is visible to the user. * @param userComment @@ -214,14 +216,23 @@ public interface AssessableCourseNode extends CourseNode { * Increments the users attempts for this node and this user + 1. * @param userCourseEnvironment */ - public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment); + public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment, Role doneBy); /** * Updates the users attempts for this node and this user. * @param userAttempts * @param userCourseEnvironment * @param coachingIdentity */ - public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity); + public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity, Role doneBy); + + /** + * + * @param userCourseEnvironment The user course environment of the assessed identity + * @param identity The identity which do the action + * @param doneBy The role of the identity which do the action + */ + public void updateLastModifications(UserCourseEnvironment userCourseEnvironment, Identity identity, Role doneBy); + /** * Updates the coach comment for this node and this user. This comment is not visible to the user. * @param coachComment @@ -234,5 +245,4 @@ public interface AssessableCourseNode extends CourseNode { */ public boolean hasStatusConfigured(); - } diff --git a/src/main/java/org/olat/course/nodes/BasicLTICourseNode.java b/src/main/java/org/olat/course/nodes/BasicLTICourseNode.java index 729a0342cb83a56b3961ea98aaefcb76bd38c260..834bfa711e3b8f8baba498f1cdb0408f94d9f055 100644 --- a/src/main/java/org/olat/course/nodes/BasicLTICourseNode.java +++ b/src/main/java/org/olat/course/nodes/BasicLTICourseNode.java @@ -61,6 +61,7 @@ import org.olat.ims.lti.LTIManager; import org.olat.ims.lti.ui.LTIResultDetailsController; import org.olat.modules.ModuleConfiguration; import org.olat.modules.assessment.AssessmentEntry; +import org.olat.modules.assessment.Role; import org.olat.repository.RepositoryEntry; import org.olat.resource.OLATResource; @@ -126,7 +127,6 @@ public class BasicLTICourseNode extends AbstractAccessableCourseNode implements UserCourseEnvironment userCourseEnv, NodeEvaluation ne, String nodecmd) { updateModuleConfigDefaults(false); - ModuleConfiguration config = getModuleConfiguration(); Controller runCtrl; if(userCourseEnv.isCourseReadOnly()) { Translator trans = Util.createPackageTranslator(BasicLTICourseNode.class, ureq.getLocale()); @@ -436,11 +436,11 @@ public class BasicLTICourseNode extends AbstractAccessableCourseNode implements @Override public void updateUserScoreEvaluation(ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnvironment, - Identity coachingIdentity, boolean incrementAttempts) { + Identity coachingIdentity, boolean incrementAttempts, Role by) { AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity(); - am.saveScoreEvaluation(this, coachingIdentity, mySelf, new ScoreEvaluation(scoreEvaluation), userCourseEnvironment, incrementAttempts); + am.saveScoreEvaluation(this, coachingIdentity, mySelf, new ScoreEvaluation(scoreEvaluation), userCourseEnvironment, incrementAttempts, by); } @Override @@ -471,20 +471,27 @@ public class BasicLTICourseNode extends AbstractAccessableCourseNode implements } @Override - public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment) { + public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment, Role by) { AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity(); - am.incrementNodeAttempts(this, mySelf, userCourseEnvironment); + am.incrementNodeAttempts(this, mySelf, userCourseEnvironment, by); } @Override - public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity) { + public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity, Role by) { if (userAttempts != null) { AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity(); - am.saveNodeAttempts(this, coachingIdentity, mySelf, userAttempts); + am.saveNodeAttempts(this, coachingIdentity, mySelf, userAttempts, by); } } + + @Override + public void updateLastModifications(UserCourseEnvironment userCourseEnvironment, Identity identity, Role by) { + AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); + Identity assessedIdentity = userCourseEnvironment.getIdentityEnvironment().getIdentity(); + am.updateLastModifications(this, assessedIdentity, userCourseEnvironment, by); + } @Override public void updateUserCoachComment(String coachComment, UserCourseEnvironment userCourseEnvironment) { diff --git a/src/main/java/org/olat/course/nodes/CheckListCourseNode.java b/src/main/java/org/olat/course/nodes/CheckListCourseNode.java index 1b9dfde7da6e7c24f597a61f70f6fe51e6cee419..b703c36ee03ce9b7baaca193463ec1c8ca227f61 100644 --- a/src/main/java/org/olat/course/nodes/CheckListCourseNode.java +++ b/src/main/java/org/olat/course/nodes/CheckListCourseNode.java @@ -77,6 +77,7 @@ import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.course.run.userview.UserCourseEnvironmentImpl; import org.olat.modules.ModuleConfiguration; import org.olat.modules.assessment.AssessmentEntry; +import org.olat.modules.assessment.Role; import org.olat.repository.RepositoryEntry; /** @@ -396,10 +397,10 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements */ @Override public void updateUserScoreEvaluation(ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnvironment, - Identity coachingIdentity, boolean incrementAttempts) { + Identity coachingIdentity, boolean incrementAttempts, Role by) { AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity(); - am.saveScoreEvaluation(this, coachingIdentity, mySelf, new ScoreEvaluation(scoreEvaluation), userCourseEnvironment, incrementAttempts); + am.saveScoreEvaluation(this, coachingIdentity, mySelf, new ScoreEvaluation(scoreEvaluation), userCourseEnvironment, incrementAttempts, by); } /** @@ -456,7 +457,7 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements * org.olat.core.id.Identity) */ @Override - public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity) { + public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity, Role by) { throw new OLATRuntimeException(CheckListCourseNode.class, "Attempts variable can't be updated in ST nodes", null); } @@ -464,9 +465,16 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements * @see org.olat.course.nodes.AssessableCourseNode#incrementUserAttempts(org.olat.course.run.userview.UserCourseEnvironment) */ @Override - public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment) { + public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment, Role by) { throw new OLATRuntimeException(CheckListCourseNode.class, "Attempts variable can't be updated in ST nodes", null); } + + @Override + public void updateLastModifications(UserCourseEnvironment userCourseEnvironment, Identity identity, Role by) { + AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); + Identity assessedIdentity = userCourseEnvironment.getIdentityEnvironment().getIdentity(); + am.updateLastModifications(this, assessedIdentity, userCourseEnvironment, by); + } /** * @see org.olat.course.nodes.AssessableCourseNode#getDetailsEditController(org.olat.core.gui.UserRequest, @@ -588,22 +596,25 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements * @param userCourseEnv * @param assessedIdentity */ - public void updateScoreEvaluation(Identity identity, UserCourseEnvironment assessedUserCourseEnv, Identity assessedIdentity) { + public void updateScoreEvaluation(Identity identity, UserCourseEnvironment assessedUserCourseEnv, Identity assessedIdentity, Role by) { ModuleConfiguration config = getModuleConfiguration(); Boolean sum = (Boolean)config.get(CheckListCourseNode.CONFIG_KEY_PASSED_SUM_CHECKBOX); Float cutValue = (Float)config.get(MSCourseNode.CONFIG_KEY_PASSED_CUT_VALUE); Float maxScore = (Float)config.get(MSCourseNode.CONFIG_KEY_SCORE_MAX); Boolean manualCorrection = (Boolean)config.get(CheckListCourseNode.CONFIG_KEY_PASSED_MANUAL_CORRECTION); if(cutValue != null) { - doUpdateAssessment(cutValue, maxScore, identity, assessedUserCourseEnv, assessedIdentity); + doUpdateAssessment(cutValue, maxScore, identity, assessedUserCourseEnv, assessedIdentity, by); } else if(sum != null && sum.booleanValue()) { - doUpdateAssessmentBySum(identity, assessedUserCourseEnv, assessedIdentity); + doUpdateAssessmentBySum(identity, assessedUserCourseEnv, assessedIdentity, by); } else if(manualCorrection != null && manualCorrection.booleanValue()) { - doUpdateManualAssessment(maxScore, identity, assessedUserCourseEnv, assessedIdentity); + doUpdateManualAssessment(maxScore, identity, assessedUserCourseEnv, assessedIdentity, by); + } else { + AssessmentManager am = assessedUserCourseEnv.getCourseEnvironment().getAssessmentManager(); + am.updateLastModifications(this, assessedIdentity, assessedUserCourseEnv, by); } } - private void doUpdateAssessment(Float cutValue, Float maxScore, Identity identity, UserCourseEnvironment assessedUserCourseEnv, Identity assessedIdentity) { + private void doUpdateAssessment(Float cutValue, Float maxScore, Identity identity, UserCourseEnvironment assessedUserCourseEnv, Identity assessedIdentity, Role by) { OLATResourceable courseOres = OresHelper .createOLATResourceableInstance("CourseModule", assessedUserCourseEnv.getCourseEnvironment().getCourseResourceableId()); @@ -621,10 +632,10 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements ScoreEvaluation sceval = new ScoreEvaluation(new Float(score), passed); AssessmentManager am = assessedUserCourseEnv.getCourseEnvironment().getAssessmentManager(); - am.saveScoreEvaluation(this, identity, assessedIdentity, sceval, assessedUserCourseEnv, false); + am.saveScoreEvaluation(this, identity, assessedIdentity, sceval, assessedUserCourseEnv, false, by); } - private void doUpdateAssessmentBySum(Identity identity, UserCourseEnvironment assessedUserCourseEnv, Identity assessedIdentity) { + private void doUpdateAssessmentBySum(Identity identity, UserCourseEnvironment assessedUserCourseEnv, Identity assessedIdentity, Role by) { OLATResourceable courseOres = OresHelper .createOLATResourceableInstance("CourseModule", assessedUserCourseEnv.getCourseEnvironment().getCourseResourceableId()); @@ -651,10 +662,10 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements ScoreEvaluation sceval = new ScoreEvaluation(score, new Boolean(passed)); AssessmentManager am = assessedUserCourseEnv.getCourseEnvironment().getAssessmentManager(); - am.saveScoreEvaluation(this, identity, assessedIdentity, sceval, assessedUserCourseEnv, false); + am.saveScoreEvaluation(this, identity, assessedIdentity, sceval, assessedUserCourseEnv, false, by); } - private void doUpdateManualAssessment(Float maxScore, Identity identity, UserCourseEnvironment assessedUserCourseEnv, Identity assessedIdentity) { + private void doUpdateManualAssessment(Float maxScore, Identity identity, UserCourseEnvironment assessedUserCourseEnv, Identity assessedIdentity, Role by) { OLATResourceable courseOres = OresHelper .createOLATResourceableInstance("CourseModule", assessedUserCourseEnv.getCourseEnvironment().getCourseResourceableId()); @@ -667,7 +678,7 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements AssessmentManager am = assessedUserCourseEnv.getCourseEnvironment().getAssessmentManager(); ScoreEvaluation currentEval = getUserScoreEvaluation(am.getAssessmentEntry(this, assessedIdentity)); ScoreEvaluation sceval = new ScoreEvaluation(new Float(score), currentEval.getPassed()); - am.saveScoreEvaluation(this, identity, assessedIdentity, sceval, assessedUserCourseEnv, false); + am.saveScoreEvaluation(this, identity, assessedIdentity, sceval, assessedUserCourseEnv, false, by); } @Override @@ -812,7 +823,7 @@ public class CheckListCourseNode extends AbstractAccessableCourseNode implements ScoreEvaluation scoreEval = new ScoreEvaluation(updatedScore, updatedPassed); IdentityEnvironment identityEnv = new IdentityEnvironment(assessedIdentity, null); UserCourseEnvironment uce = new UserCourseEnvironmentImpl(identityEnv, course.getCourseEnvironment()); - am.saveScoreEvaluation(this, coachIdentity, assessedIdentity, scoreEval, uce, false); + am.saveScoreEvaluation(this, coachIdentity, assessedIdentity, scoreEval, uce, false, Role.coach); } } diff --git a/src/main/java/org/olat/course/nodes/GTACourseNode.java b/src/main/java/org/olat/course/nodes/GTACourseNode.java index e4d75eb9e96a01bd884d86da4b114849650b2087..5213e08b5eebc738960dbc1e00f9f53f86ee57af 100644 --- a/src/main/java/org/olat/course/nodes/GTACourseNode.java +++ b/src/main/java/org/olat/course/nodes/GTACourseNode.java @@ -91,6 +91,7 @@ import org.olat.group.BusinessGroup; import org.olat.modules.ModuleConfiguration; import org.olat.modules.assessment.AssessmentEntry; import org.olat.modules.assessment.AssessmentToolOptions; +import org.olat.modules.assessment.Role; import org.olat.repository.RepositoryEntry; import org.olat.user.UserManager; @@ -952,10 +953,10 @@ public class GTACourseNode extends AbstractAccessableCourseNode implements Persi @Override public void updateUserScoreEvaluation(ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnv, - Identity coachingIdentity, boolean incrementAttempts) { + Identity coachingIdentity, boolean incrementAttempts, Role by) { AssessmentManager am = userCourseEnv.getCourseEnvironment().getAssessmentManager(); Identity assessedIdentity = userCourseEnv.getIdentityEnvironment().getIdentity(); - am.saveScoreEvaluation(this, coachingIdentity, assessedIdentity, new ScoreEvaluation(scoreEvaluation), userCourseEnv, incrementAttempts); + am.saveScoreEvaluation(this, coachingIdentity, assessedIdentity, new ScoreEvaluation(scoreEvaluation), userCourseEnv, incrementAttempts, by); } @Override @@ -986,20 +987,27 @@ public class GTACourseNode extends AbstractAccessableCourseNode implements Persi } @Override - public void incrementUserAttempts(UserCourseEnvironment userCourseEnv) { + public void incrementUserAttempts(UserCourseEnvironment userCourseEnv, Role by) { AssessmentManager am = userCourseEnv.getCourseEnvironment().getAssessmentManager(); Identity assessedIdentity = userCourseEnv.getIdentityEnvironment().getIdentity(); - am.incrementNodeAttempts(this, assessedIdentity, userCourseEnv); + am.updateLastModifications(this, assessedIdentity, userCourseEnv, by); } @Override - public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnv, Identity coachingIdentity) { + public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnv, Identity coachingIdentity, Role by) { if (userAttempts != null) { AssessmentManager am = userCourseEnv.getCourseEnvironment().getAssessmentManager(); Identity assessedIdentity = userCourseEnv.getIdentityEnvironment().getIdentity(); - am.saveNodeAttempts(this, coachingIdentity, assessedIdentity, userAttempts); + am.saveNodeAttempts(this, coachingIdentity, assessedIdentity, userAttempts, by); } } + + @Override + public void updateLastModifications(UserCourseEnvironment userCourseEnvironment, Identity identity, Role by) { + AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); + Identity assessedIdentity = userCourseEnvironment.getIdentityEnvironment().getIdentity(); + am.updateLastModifications(this, assessedIdentity, userCourseEnvironment, by); + } @Override public void updateUserCoachComment(String coachComment, UserCourseEnvironment userCourseEnv) { diff --git a/src/main/java/org/olat/course/nodes/IQSELFCourseNode.java b/src/main/java/org/olat/course/nodes/IQSELFCourseNode.java index 52f880d66bdd534002f411e0af0f8ccf81ae13dc..7ea094166ff01f906c28f8b7057214863e44e126 100644 --- a/src/main/java/org/olat/course/nodes/IQSELFCourseNode.java +++ b/src/main/java/org/olat/course/nodes/IQSELFCourseNode.java @@ -77,6 +77,7 @@ import org.olat.ims.qti21.manager.AssessmentTestSessionDAO; import org.olat.ims.qti21.manager.archive.QTI21ArchiveFormat; import org.olat.ims.qti21.model.QTI21StatisticSearchParams; import org.olat.modules.ModuleConfiguration; +import org.olat.modules.assessment.Role; import org.olat.modules.iq.IQManager; import org.olat.modules.iq.IQSecurityCallback; import org.olat.repository.RepositoryEntry; @@ -393,10 +394,10 @@ public class IQSELFCourseNode extends AbstractAccessableCourseNode implements Se * @see org.olat.course.nodes.AssessableCourseNode#incrementUserAttempts(org.olat.course.run.userview.UserCourseEnvironment) */ @Override - public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment) { + public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment, Role by) { AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity(); - am.incrementNodeAttempts(this, mySelf, userCourseEnvironment); + am.incrementNodeAttempts(this, mySelf, userCourseEnvironment, by); } } diff --git a/src/main/java/org/olat/course/nodes/IQSURVCourseNode.java b/src/main/java/org/olat/course/nodes/IQSURVCourseNode.java index 2b1d272d404c08d020e92e14dfcdcaa7908532a7..f8bba28e13e59c963f02bdfdddb8741478ec1b45 100644 --- a/src/main/java/org/olat/course/nodes/IQSURVCourseNode.java +++ b/src/main/java/org/olat/course/nodes/IQSURVCourseNode.java @@ -83,6 +83,7 @@ import org.olat.ims.qti21.ui.statistics.QTI21StatisticResourceResult; import org.olat.ims.qti21.ui.statistics.QTI21StatisticsSecurityCallback; import org.olat.modules.ModuleConfiguration; import org.olat.modules.assessment.AssessmentToolOptions; +import org.olat.modules.assessment.Role; import org.olat.modules.iq.IQSecurityCallback; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryEntryImportExport; @@ -375,6 +376,7 @@ public class IQSURVCourseNode extends AbstractAccessableCourseNode implements QT * from previous node configuration version, set default to maintain * previous behaviour */ + @Override public void updateModuleConfigDefaults(boolean isNewNode) { ModuleConfiguration config = getModuleConfiguration(); if (isNewNode) { @@ -400,6 +402,7 @@ public class IQSURVCourseNode extends AbstractAccessableCourseNode implements QT /** * @see org.olat.course.nodes.AssessableCourseNode#hasAttemptsConfigured() */ + @Override public boolean hasAttemptsConfigured() { return true; } @@ -409,21 +412,21 @@ public class IQSURVCourseNode extends AbstractAccessableCourseNode implements QT * org.olat.course.run.userview.UserCourseEnvironment, * org.olat.core.id.Identity) */ - public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity) { + public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity, Role by) { if (userAttempts != null) { AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity(); - am.saveNodeAttempts(this, coachingIdentity, mySelf, userAttempts); + am.saveNodeAttempts(this, coachingIdentity, mySelf, userAttempts, by); } } /** * @see org.olat.course.nodes.AssessableCourseNode#incrementUserAttempts(org.olat.course.run.userview.UserCourseEnvironment) */ - public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment) { + public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment, Role by) { AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity(); - am.incrementNodeAttempts(this, mySelf, userCourseEnvironment); + am.incrementNodeAttempts(this, mySelf, userCourseEnvironment, by); } } diff --git a/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java b/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java index cad785f0ba37b1c2827062a3da81a69dbf9f1bf0..ed1be9d6c260185cf808efec404e7efdf0521f45 100644 --- a/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java +++ b/src/main/java/org/olat/course/nodes/IQTESTCourseNode.java @@ -120,6 +120,7 @@ import org.olat.ims.qti21.ui.statistics.QTI21StatisticsToolController; import org.olat.modules.ModuleConfiguration; import org.olat.modules.assessment.AssessmentEntry; import org.olat.modules.assessment.AssessmentToolOptions; +import org.olat.modules.assessment.Role; import org.olat.modules.iq.IQSecurityCallback; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryEntryImportExport; @@ -524,11 +525,11 @@ public class IQTESTCourseNode extends AbstractAccessableCourseNode implements Pe */ @Override public void updateUserScoreEvaluation(ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnvironment, - Identity coachingIdentity, boolean incrementAttempts) { + Identity coachingIdentity, boolean incrementAttempts, Role by) { AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity(); try { - am.saveScoreEvaluation(this, coachingIdentity, mySelf, scoreEvaluation, userCourseEnvironment, incrementAttempts); + am.saveScoreEvaluation(this, coachingIdentity, mySelf, scoreEvaluation, userCourseEnvironment, incrementAttempts, by); } catch(DBRuntimeException ex) { throw new KnownIssueException("DBRuntimeException - Row was updated or deleted...", 3570, ex); } @@ -791,11 +792,11 @@ public class IQTESTCourseNode extends AbstractAccessableCourseNode implements Pe * org.olat.core.id.Identity) */ @Override - public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity) { + public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity, Role by) { if (userAttempts != null) { AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity(); - am.saveNodeAttempts(this, coachingIdentity, mySelf, userAttempts); + am.saveNodeAttempts(this, coachingIdentity, mySelf, userAttempts, by); } } @@ -803,10 +804,17 @@ public class IQTESTCourseNode extends AbstractAccessableCourseNode implements Pe * @see org.olat.course.nodes.AssessableCourseNode#incrementUserAttempts(org.olat.course.run.userview.UserCourseEnvironment) */ @Override - public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment) { + public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment, Role by) { AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity(); - am.incrementNodeAttempts(this, mySelf, userCourseEnvironment); + am.incrementNodeAttempts(this, mySelf, userCourseEnvironment, by); + } + + @Override + public void updateLastModifications(UserCourseEnvironment userCourseEnvironment, Identity identity, Role by) { + AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); + Identity assessedIdentity = userCourseEnvironment.getIdentityEnvironment().getIdentity(); + am.updateLastModifications(this, assessedIdentity, userCourseEnvironment, by); } /** diff --git a/src/main/java/org/olat/course/nodes/MSCourseNode.java b/src/main/java/org/olat/course/nodes/MSCourseNode.java index 1ae833a55b7fe787f3063474b7bea28d94ed8214..97a74ca364e46bc53eee3c0bf1ed39464ce40970 100644 --- a/src/main/java/org/olat/course/nodes/MSCourseNode.java +++ b/src/main/java/org/olat/course/nodes/MSCourseNode.java @@ -66,6 +66,7 @@ import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.modules.ModuleConfiguration; import org.olat.modules.assessment.AssessmentEntry; import org.olat.modules.assessment.AssessmentToolOptions; +import org.olat.modules.assessment.Role; import org.olat.properties.Property; import org.olat.repository.RepositoryEntry; import org.olat.resource.OLATResource; @@ -413,10 +414,10 @@ public class MSCourseNode extends AbstractAccessableCourseNode implements Persis */ @Override public void updateUserScoreEvaluation(ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnvironment, - Identity coachingIdentity, boolean incrementAttempts) { + Identity coachingIdentity, boolean incrementAttempts, Role by) { AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity(); - am.saveScoreEvaluation(this, coachingIdentity, mySelf, new ScoreEvaluation(scoreEvaluation), userCourseEnvironment, incrementAttempts); + am.saveScoreEvaluation(this, coachingIdentity, mySelf, new ScoreEvaluation(scoreEvaluation), userCourseEnvironment, incrementAttempts, by); } /** @@ -474,7 +475,7 @@ public class MSCourseNode extends AbstractAccessableCourseNode implements Persis * org.olat.core.id.Identity) */ @Override - public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity) { + public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity, Role by) { throw new OLATRuntimeException(MSCourseNode.class, "Attempts variable can't be updated in MS nodes", null); } @@ -482,9 +483,16 @@ public class MSCourseNode extends AbstractAccessableCourseNode implements Persis * @see org.olat.course.nodes.AssessableCourseNode#incrementUserAttempts(org.olat.course.run.userview.UserCourseEnvironment) */ @Override - public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment) { + public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment, Role by) { throw new OLATRuntimeException(MSCourseNode.class, "Attempts variable can't be updated in MS nodes", null); } + + @Override + public void updateLastModifications(UserCourseEnvironment userCourseEnvironment, Identity identity, Role by) { + AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); + Identity assessedIdentity = userCourseEnvironment.getIdentityEnvironment().getIdentity(); + am.updateLastModifications(this, assessedIdentity, userCourseEnvironment, by); + } /** * @see org.olat.course.nodes.AssessableCourseNode#getDetailsEditController(org.olat.core.gui.UserRequest, diff --git a/src/main/java/org/olat/course/nodes/PortfolioCourseNode.java b/src/main/java/org/olat/course/nodes/PortfolioCourseNode.java index 9ed76d2b34050a7d9dda6842e7b45a13b22916d7..b3886893015cab8e6a7db928279dc300b8fa6d26 100644 --- a/src/main/java/org/olat/course/nodes/PortfolioCourseNode.java +++ b/src/main/java/org/olat/course/nodes/PortfolioCourseNode.java @@ -63,6 +63,7 @@ import org.olat.course.run.userview.NodeEvaluation; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.modules.ModuleConfiguration; import org.olat.modules.assessment.AssessmentEntry; +import org.olat.modules.assessment.Role; import org.olat.modules.portfolio.handler.BinderTemplateResource; import org.olat.modules.portfolio.ui.PortfolioAssessmentDetailsController; import org.olat.portfolio.EPTemplateMapResource; @@ -462,10 +463,10 @@ public class PortfolioCourseNode extends AbstractAccessableCourseNode implements @Override public void updateUserScoreEvaluation(ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnvironment, - Identity coachingIdentity, boolean incrementAttempts) { + Identity coachingIdentity, boolean incrementAttempts, Role by) { AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity(); - am.saveScoreEvaluation(this, coachingIdentity, mySelf, new ScoreEvaluation(scoreEvaluation), userCourseEnvironment, incrementAttempts); + am.saveScoreEvaluation(this, coachingIdentity, mySelf, new ScoreEvaluation(scoreEvaluation), userCourseEnvironment, incrementAttempts, by); } @Override @@ -496,21 +497,28 @@ public class PortfolioCourseNode extends AbstractAccessableCourseNode implements } @Override - public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment) { + public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment, Role by) { AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity(); - am.incrementNodeAttempts(this, mySelf, userCourseEnvironment); + am.incrementNodeAttempts(this, mySelf, userCourseEnvironment, by); } @Override - public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity) { + public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity, Role by) { if (userAttempts != null) { AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity(); - am.saveNodeAttempts(this, coachingIdentity, mySelf, userAttempts); + am.saveNodeAttempts(this, coachingIdentity, mySelf, userAttempts, by); } } + @Override + public void updateLastModifications(UserCourseEnvironment userCourseEnvironment, Identity identity, Role by) { + AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); + Identity assessedIdentity = userCourseEnvironment.getIdentityEnvironment().getIdentity(); + am.updateLastModifications(this, assessedIdentity, userCourseEnvironment, by); + } + @Override public void updateUserCoachComment(String coachComment, UserCourseEnvironment userCourseEnvironment) { AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); diff --git a/src/main/java/org/olat/course/nodes/ProjectBrokerCourseNode.java b/src/main/java/org/olat/course/nodes/ProjectBrokerCourseNode.java index c97c9589e4fccbbd165a8aa091478065da0f0373..80fb43e1c22d771fd765e73ccc68de9f51643b23 100644 --- a/src/main/java/org/olat/course/nodes/ProjectBrokerCourseNode.java +++ b/src/main/java/org/olat/course/nodes/ProjectBrokerCourseNode.java @@ -113,6 +113,7 @@ import org.olat.group.model.BusinessGroupReference; import org.olat.modules.ModuleConfiguration; import org.olat.modules.assessment.AssessmentEntry; import org.olat.modules.assessment.AssessmentToolOptions; +import org.olat.modules.assessment.Role; import org.olat.properties.Property; import org.olat.repository.RepositoryEntry; import org.olat.resource.OLATResource; @@ -623,10 +624,10 @@ public class ProjectBrokerCourseNode extends GenericCourseNode implements Persis */ @Override public void updateUserScoreEvaluation(ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnvironment, - Identity coachingIdentity, boolean incrementAttempts) { + Identity coachingIdentity, boolean incrementAttempts, Role by) { AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity(); - am.saveScoreEvaluation(this, coachingIdentity, mySelf, new ScoreEvaluation(scoreEvaluation), userCourseEnvironment, incrementAttempts); + am.saveScoreEvaluation(this, coachingIdentity, mySelf, new ScoreEvaluation(scoreEvaluation), userCourseEnvironment, incrementAttempts, by); } /** @@ -687,11 +688,11 @@ public class ProjectBrokerCourseNode extends GenericCourseNode implements Persis * org.olat.core.id.Identity) */ @Override - public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity) { + public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity, Role by) { if (userAttempts != null) { AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity(); - am.saveNodeAttempts(this, coachingIdentity, mySelf, userAttempts); + am.saveNodeAttempts(this, coachingIdentity, mySelf, userAttempts, by); } } @@ -699,10 +700,17 @@ public class ProjectBrokerCourseNode extends GenericCourseNode implements Persis * @see org.olat.course.nodes.AssessableCourseNode#incrementUserAttempts(org.olat.course.run.userview.UserCourseEnvironment) */ @Override - public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment) { + public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment, Role by) { AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity(); - am.incrementNodeAttempts(this, mySelf, userCourseEnvironment); + am.incrementNodeAttempts(this, mySelf, userCourseEnvironment, by); + } + + @Override + public void updateLastModifications(UserCourseEnvironment userCourseEnvironment, Identity identity, Role by) { + AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); + Identity assessedIdentity = userCourseEnvironment.getIdentityEnvironment().getIdentity(); + am.updateLastModifications(this, assessedIdentity, userCourseEnvironment, by); } /** @@ -943,7 +951,7 @@ public class ProjectBrokerCourseNode extends GenericCourseNode implements Persis String projectBrokerTableExport = ProjectBrokerExportGenerator.createCourseResultsOverviewTable(this, course, locale); String tableExportFileName = ExportUtil.createFileNameWithTimeStamp(getShortTitle() + "-projectbroker_overview", "xls"); exportStream.putNextEntry(new ZipEntry(exportDirName + "/" + tableExportFileName)); - IOUtils.write(projectBrokerTableExport, exportStream); + IOUtils.write(projectBrokerTableExport, exportStream, "UTF-8"); exportStream.closeEntry(); } catch (IOException e) { log.error("", e); diff --git a/src/main/java/org/olat/course/nodes/STCourseNode.java b/src/main/java/org/olat/course/nodes/STCourseNode.java index 8b04afdd3d75ed4d711af09f33eb42df47329845..331a215f7eec5ba6c019154b0984006c97ebf54c 100644 --- a/src/main/java/org/olat/course/nodes/STCourseNode.java +++ b/src/main/java/org/olat/course/nodes/STCourseNode.java @@ -81,6 +81,7 @@ import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.course.tree.CourseInternalLinkTreeModel; import org.olat.modules.ModuleConfiguration; import org.olat.modules.assessment.AssessmentEntry; +import org.olat.modules.assessment.Role; import org.olat.repository.RepositoryEntry; import org.olat.util.logging.activity.LoggingResourceable; @@ -546,7 +547,7 @@ public class STCourseNode extends AbstractAccessableCourseNode implements Calcul */ @Override public void updateUserScoreEvaluation(ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnvironment, - Identity coachingIdentity, boolean incrementAttempts) { + Identity coachingIdentity, boolean incrementAttempts, Role by) { throw new OLATRuntimeException(STCourseNode.class, "Score variable can't be updated in ST nodes", null); } @@ -593,7 +594,7 @@ public class STCourseNode extends AbstractAccessableCourseNode implements Calcul * org.olat.core.id.Identity) */ @Override - public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity) { + public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity, Role by) { throw new OLATRuntimeException(STCourseNode.class, "Attempts variable can't be updated in ST nodes", null); } @@ -601,10 +602,15 @@ public class STCourseNode extends AbstractAccessableCourseNode implements Calcul * @see org.olat.course.nodes.AssessableCourseNode#incrementUserAttempts(org.olat.course.run.userview.UserCourseEnvironment) */ @Override - public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment) { + public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment, Role by) { throw new OLATRuntimeException(STCourseNode.class, "Attempts variable can't be updated in ST nodes", null); } + @Override + public void updateLastModifications(UserCourseEnvironment userCourseEnvironment, Identity identity, Role doneBy) { + //do nothing + } + /** * @see org.olat.course.nodes.AssessableCourseNode#getDetailsEditController(org.olat.core.gui.UserRequest, * org.olat.core.gui.control.WindowControl, diff --git a/src/main/java/org/olat/course/nodes/ScormCourseNode.java b/src/main/java/org/olat/course/nodes/ScormCourseNode.java index 23fda397e0089c4c78a08bf29a8750ca8b1e4004..ba6840066a3b01eb436bcc3d8a5c348589cbcbea 100644 --- a/src/main/java/org/olat/course/nodes/ScormCourseNode.java +++ b/src/main/java/org/olat/course/nodes/ScormCourseNode.java @@ -65,6 +65,7 @@ import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.fileresource.types.ScormCPFileResource; import org.olat.modules.ModuleConfiguration; import org.olat.modules.assessment.AssessmentEntry; +import org.olat.modules.assessment.Role; import org.olat.modules.scorm.ScormMainManager; import org.olat.modules.scorm.ScormPackageConfig; import org.olat.modules.scorm.archiver.ScormExportManager; @@ -489,10 +490,10 @@ public class ScormCourseNode extends AbstractAccessableCourseNode implements Per */ @Override public void updateUserScoreEvaluation(ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnvironment, - Identity coachingIdentity, boolean incrementAttempts) { + Identity coachingIdentity, boolean incrementAttempts, Role by) { AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity(); - am.saveScoreEvaluation(this, coachingIdentity, mySelf, new ScoreEvaluation(scoreEvaluation), userCourseEnvironment, incrementAttempts); + am.saveScoreEvaluation(this, coachingIdentity, mySelf, new ScoreEvaluation(scoreEvaluation), userCourseEnvironment, incrementAttempts, by); } /** @@ -591,11 +592,11 @@ public class ScormCourseNode extends AbstractAccessableCourseNode implements Per * org.olat.core.id.Identity) */ @Override - public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity) { + public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity, Role by) { if (userAttempts != null) { AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity(); - am.saveNodeAttempts(this, coachingIdentity, mySelf, userAttempts); + am.saveNodeAttempts(this, coachingIdentity, mySelf, userAttempts, by); } } @@ -603,10 +604,17 @@ public class ScormCourseNode extends AbstractAccessableCourseNode implements Per * @see org.olat.course.nodes.AssessableCourseNode#incrementUserAttempts(org.olat.course.run.userview.UserCourseEnvironment) */ @Override - public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment) { + public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment, Role by) { AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity(); - am.incrementNodeAttempts(this, mySelf, userCourseEnvironment); + am.incrementNodeAttempts(this, mySelf, userCourseEnvironment, by); + } + + @Override + public void updateLastModifications(UserCourseEnvironment userCourseEnvironment, Identity identity, Role by) { + AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); + Identity assessedIdentity = userCourseEnvironment.getIdentityEnvironment().getIdentity(); + am.updateLastModifications(this, assessedIdentity, userCourseEnvironment, by); } /** diff --git a/src/main/java/org/olat/course/nodes/SelfAssessableCourseNode.java b/src/main/java/org/olat/course/nodes/SelfAssessableCourseNode.java index 5e9a0957567daed1ff49a388298835857d8b1c20..f2332b4da5f26f10804388bd33fba9c4b92dbf6c 100644 --- a/src/main/java/org/olat/course/nodes/SelfAssessableCourseNode.java +++ b/src/main/java/org/olat/course/nodes/SelfAssessableCourseNode.java @@ -26,6 +26,7 @@ package org.olat.course.nodes; import org.olat.course.run.scoring.ScoreEvaluation; import org.olat.course.run.userview.UserCourseEnvironment; +import org.olat.modules.assessment.Role; /** * @@ -56,6 +57,6 @@ public interface SelfAssessableCourseNode extends CourseNode { * Increments the users attempts for this node and this user + 1. * @param userCourseEnvironment */ - public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment); + public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment, Role by); } diff --git a/src/main/java/org/olat/course/nodes/TACourseNode.java b/src/main/java/org/olat/course/nodes/TACourseNode.java index b84f5a0fe4c81b2b79abd277632c6ccb585843d3..9219eae6a9e93b72a6c902d62d001ee1d4f4bffe 100644 --- a/src/main/java/org/olat/course/nodes/TACourseNode.java +++ b/src/main/java/org/olat/course/nodes/TACourseNode.java @@ -97,6 +97,7 @@ import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.modules.ModuleConfiguration; import org.olat.modules.assessment.AssessmentEntry; import org.olat.modules.assessment.AssessmentToolOptions; +import org.olat.modules.assessment.Role; import org.olat.properties.Property; import org.olat.repository.RepositoryEntry; import org.olat.resource.OLATResource; @@ -669,11 +670,11 @@ public class TACourseNode extends GenericCourseNode implements PersistentAssessa */ @Override public void updateUserScoreEvaluation(ScoreEvaluation scoreEval, UserCourseEnvironment userCourseEnvironment, - Identity coachingIdentity, boolean incrementAttempts) { + Identity coachingIdentity, boolean incrementAttempts, Role by) { AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity(); ScoreEvaluation newScoreEval = new ScoreEvaluation(scoreEval.getScore(), scoreEval.getPassed(), scoreEval.getAssessmentStatus(), scoreEval.getUserVisible(), null, null); - am.saveScoreEvaluation(this, coachingIdentity, mySelf, newScoreEval, userCourseEnvironment, incrementAttempts); + am.saveScoreEvaluation(this, coachingIdentity, mySelf, newScoreEval, userCourseEnvironment, incrementAttempts, by); } /** @@ -726,11 +727,11 @@ public class TACourseNode extends GenericCourseNode implements PersistentAssessa * org.olat.core.id.Identity) */ @Override - public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity) { + public void updateUserAttempts(Integer userAttempts, UserCourseEnvironment userCourseEnvironment, Identity coachingIdentity, Role by) { if (userAttempts != null) { AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity(); - am.saveNodeAttempts(this, coachingIdentity, mySelf, userAttempts); + am.saveNodeAttempts(this, coachingIdentity, mySelf, userAttempts, by); } } @@ -738,10 +739,17 @@ public class TACourseNode extends GenericCourseNode implements PersistentAssessa * @see org.olat.course.nodes.AssessableCourseNode#incrementUserAttempts(org.olat.course.run.userview.UserCourseEnvironment) */ @Override - public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment) { + public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment, Role by) { AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity(); - am.incrementNodeAttempts(this, mySelf, userCourseEnvironment); + am.incrementNodeAttempts(this, mySelf, userCourseEnvironment, by); + } + + @Override + public void updateLastModifications(UserCourseEnvironment userCourseEnvironment, Identity identity, Role by) { + AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); + Identity assessedIdentity = userCourseEnvironment.getIdentityEnvironment().getIdentity(); + am.updateLastModifications(this, assessedIdentity, userCourseEnvironment, by); } /** diff --git a/src/main/java/org/olat/course/nodes/basiclti/CourseNodeOutcomeMapper.java b/src/main/java/org/olat/course/nodes/basiclti/CourseNodeOutcomeMapper.java index 9f216eaa9f290de0547f3b44b2f3405e162e04c5..1f70305942157562131820139941213ad8c5e6e1 100644 --- a/src/main/java/org/olat/course/nodes/basiclti/CourseNodeOutcomeMapper.java +++ b/src/main/java/org/olat/course/nodes/basiclti/CourseNodeOutcomeMapper.java @@ -39,6 +39,7 @@ import org.olat.course.run.scoring.ScoreEvaluation; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.course.run.userview.UserCourseEnvironmentImpl; import org.olat.ims.lti.ui.OutcomeMapper; +import org.olat.modules.assessment.Role; import org.olat.resource.OLATResource; import org.olat.util.logging.activity.LoggingResourceable; @@ -101,7 +102,7 @@ public class CourseNodeOutcomeMapper extends OutcomeMapper { ScoreEvaluation eval = new ScoreEvaluation(scaledScore, passed); UserCourseEnvironment userCourseEnv = getUserCourseEnvironment(course); - ltiNode.updateUserScoreEvaluation(eval, userCourseEnv, assessedId, false); + ltiNode.updateUserScoreEvaluation(eval, userCourseEnv, assessedId, false, Role.user); } return super.doUpdateResult(score); @@ -116,7 +117,7 @@ public class CourseNodeOutcomeMapper extends OutcomeMapper { Identity assessedId = getIdentity(); ScoreEvaluation eval = new ScoreEvaluation(0.0f, false); UserCourseEnvironment userCourseEnv = getUserCourseEnvironment(course); - ltiNode.updateUserScoreEvaluation(eval, userCourseEnv, assessedId, false); + ltiNode.updateUserScoreEvaluation(eval, userCourseEnv, assessedId, false, Role.user); } return super.doDeleteResult(); diff --git a/src/main/java/org/olat/course/nodes/basiclti/LTIRunController.java b/src/main/java/org/olat/course/nodes/basiclti/LTIRunController.java index cc9bb39db9fcd28fd083df64ffe157c9def349e0..911c792b9f3aca14f96b74f57758e96f28a9fae1 100644 --- a/src/main/java/org/olat/course/nodes/basiclti/LTIRunController.java +++ b/src/main/java/org/olat/course/nodes/basiclti/LTIRunController.java @@ -68,6 +68,7 @@ import org.olat.ims.lti.LTIManager; import org.olat.ims.lti.ui.PostDataMapper; import org.olat.ims.lti.ui.TalkBackMapper; import org.olat.modules.ModuleConfiguration; +import org.olat.modules.assessment.Role; import org.olat.properties.Property; import org.olat.resource.OLATResource; @@ -394,7 +395,7 @@ public class LTIRunController extends BasicController { @Override public void event(UserRequest ureq, Component source, Event event) { if(source == startButton) { - courseNode.incrementUserAttempts(userCourseEnv); + courseNode.incrementUserAttempts(userCourseEnv, Role.user); openBasicLTIContent(ureq); } else if (source == acceptLink) { storeDataExchangeAcceptance(); diff --git a/src/main/java/org/olat/course/nodes/cl/ui/AssessedIdentityCheckListController.java b/src/main/java/org/olat/course/nodes/cl/ui/AssessedIdentityCheckListController.java index fa630349f8ccef208d520e2f7c09431ecbc70c8e..21c13f09fb739240c4e8fa55b6c7d43ff1dc7779 100644 --- a/src/main/java/org/olat/course/nodes/cl/ui/AssessedIdentityCheckListController.java +++ b/src/main/java/org/olat/course/nodes/cl/ui/AssessedIdentityCheckListController.java @@ -53,6 +53,7 @@ import org.olat.course.nodes.cl.model.DBCheck; import org.olat.course.nodes.cl.model.DBCheckbox; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.modules.ModuleConfiguration; +import org.olat.modules.assessment.Role; import org.springframework.beans.factory.annotation.Autowired; /** @@ -284,7 +285,7 @@ public class AssessedIdentityCheckListController extends FormBasicController { } checkboxManager.check(courseOres, courseNode.getIdent(), batchElements); - courseNode.updateScoreEvaluation(getIdentity(), assessedUserCourseEnv, assessedIdentity); + courseNode.updateScoreEvaluation(getIdentity(), assessedUserCourseEnv, assessedIdentity, Role.coach); } private void doUpdateCheck(CheckboxWrapper wrapper, boolean check) { diff --git a/src/main/java/org/olat/course/nodes/cl/ui/CheckListAssessmentController.java b/src/main/java/org/olat/course/nodes/cl/ui/CheckListAssessmentController.java index db6a2dd96d378c5b13b1750f3b7d603531722456..c2a03d1090886de02b31c03761bbb612a8d96671 100644 --- a/src/main/java/org/olat/course/nodes/cl/ui/CheckListAssessmentController.java +++ b/src/main/java/org/olat/course/nodes/cl/ui/CheckListAssessmentController.java @@ -89,6 +89,7 @@ import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupMembership; import org.olat.group.BusinessGroupService; import org.olat.modules.ModuleConfiguration; +import org.olat.modules.assessment.Role; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryManager; import org.olat.repository.RepositoryService; @@ -587,7 +588,7 @@ public class CheckListAssessmentController extends FormBasicController implement List<Identity> assessedIdentities = securityManager.loadIdentityByKeys(assessedIdentityToUpdate); for(Identity assessedIdentity:assessedIdentities) { UserCourseEnvironment assessedUserCourseEnv = AssessmentHelper.createAndInitUserCourseEnvironment(assessedIdentity, course); - courseNode.updateScoreEvaluation(getIdentity(), assessedUserCourseEnv, assessedIdentity); + courseNode.updateScoreEvaluation(getIdentity(), assessedUserCourseEnv, assessedIdentity, Role.coach); } } diff --git a/src/main/java/org/olat/course/nodes/cl/ui/CheckListRunController.java b/src/main/java/org/olat/course/nodes/cl/ui/CheckListRunController.java index 0859355a9947deb12c6639cd51cdb5b7af1c21cb..951a2bfd56a3bfa1d7c72358405ff7be33f4aaac 100644 --- a/src/main/java/org/olat/course/nodes/cl/ui/CheckListRunController.java +++ b/src/main/java/org/olat/course/nodes/cl/ui/CheckListRunController.java @@ -68,6 +68,7 @@ import org.olat.course.nodes.ms.DocumentsMapper; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.modules.ModuleConfiguration; import org.olat.modules.assessment.AssessmentEntry; +import org.olat.modules.assessment.Role; import org.olat.util.logging.activity.LoggingResourceable; import org.springframework.beans.factory.annotation.Autowired; @@ -324,7 +325,7 @@ public class CheckListRunController extends FormBasicController implements Contr //make sure all results is on the database before calculating some scores //manager commit already DBFactory.getInstance().commit(); - courseNode.updateScoreEvaluation(getIdentity(), userCourseEnv, getIdentity()); + courseNode.updateScoreEvaluation(getIdentity(), userCourseEnv, getIdentity(), Role.user); Checkbox checkbox = wrapper.getCheckbox(); logUpdateCheck(checkbox.getCheckboxId(), checkbox.getTitle()); diff --git a/src/main/java/org/olat/course/nodes/cl/ui/CheckboxAssessmentController.java b/src/main/java/org/olat/course/nodes/cl/ui/CheckboxAssessmentController.java index 940cf1297817f80ea662d19804f70c4cc9f1d55a..6464e8061583d80e844001cda6aa46a58d1f9d16 100644 --- a/src/main/java/org/olat/course/nodes/cl/ui/CheckboxAssessmentController.java +++ b/src/main/java/org/olat/course/nodes/cl/ui/CheckboxAssessmentController.java @@ -67,6 +67,7 @@ import org.olat.course.nodes.cl.model.CheckboxList; import org.olat.course.nodes.cl.ui.CheckboxAssessmentDataModel.Cols; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.modules.ModuleConfiguration; +import org.olat.modules.assessment.Role; import org.olat.user.UserManager; import org.olat.user.propertyhandlers.UserPropertyHandler; @@ -385,7 +386,7 @@ public class CheckboxAssessmentController extends FormBasicController { List<Identity> assessedIdentities = securityManager.loadIdentityByKeys(assessedIdentityToUpdate); for(Identity assessedIdentity:assessedIdentities) { UserCourseEnvironment assessedUserCourseEnv = AssessmentHelper.createAndInitUserCourseEnvironment(assessedIdentity, course); - courseNode.updateScoreEvaluation(getIdentity(), assessedUserCourseEnv, assessedIdentity); + courseNode.updateScoreEvaluation(getIdentity(), assessedUserCourseEnv, assessedIdentity, Role.coach); } } diff --git a/src/main/java/org/olat/course/nodes/gta/GTAManager.java b/src/main/java/org/olat/course/nodes/gta/GTAManager.java index 6eaef96a4c5b0b90f108a1cec77c5d3b7c78fe6a..eebc0e9c90591dc9da9d7e1b3de8805363d343b6 100644 --- a/src/main/java/org/olat/course/nodes/gta/GTAManager.java +++ b/src/main/java/org/olat/course/nodes/gta/GTAManager.java @@ -36,6 +36,7 @@ import org.olat.course.nodes.gta.ui.events.SubmitEvent; import org.olat.course.run.environment.CourseEnvironment; import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupRef; +import org.olat.modules.assessment.Role; import org.olat.modules.assessment.model.AssessmentEntryStatus; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryEntryRef; @@ -264,7 +265,7 @@ public interface GTAManager { public Task createAndPersistTask(String taskName, TaskList taskList, TaskProcess status, BusinessGroup assessedGroup, Identity assessedIdentity, GTACourseNode cNode); - public Task nextStep(Task task, GTACourseNode cNode); + public Task nextStep(Task task, GTACourseNode cNode, Role by); @@ -336,15 +337,15 @@ public interface GTAManager { */ public Task reviewedTask(Task task, GTACourseNode cNode); - public Task updateTask(Task task, TaskProcess newStatus, GTACourseNode cNode); + public Task updateTask(Task task, TaskProcess newStatus, GTACourseNode cNode, Role by); public TaskDueDate updateTaskDueDate(TaskDueDate taskDueDate); - public Task submitTask(Task task, GTACourseNode cNode, int numOfDocs); + public Task submitTask(Task task, GTACourseNode cNode, int numOfDocs, Role by); - public Task submitRevisions(Task task, GTACourseNode cNode, int numOfDocs); + public Task submitRevisions(Task task, GTACourseNode cNode, int numOfDocs, Role by); - public Task updateTask(Task task, TaskProcess newStatus, int iteration, GTACourseNode cNode); + public Task updateTask(Task task, TaskProcess newStatus, int iteration, GTACourseNode cNode, Role by); public Task allowResetTask(Task task, Identity allower, GTACourseNode cNode); diff --git a/src/main/java/org/olat/course/nodes/gta/manager/GTAManagerImpl.java b/src/main/java/org/olat/course/nodes/gta/manager/GTAManagerImpl.java index 2f6bda7f5bc1924c50af68ccf8d115282c0b39cc..d5ec967011298193ffed8b3c51387ca877a72599 100644 --- a/src/main/java/org/olat/course/nodes/gta/manager/GTAManagerImpl.java +++ b/src/main/java/org/olat/course/nodes/gta/manager/GTAManagerImpl.java @@ -55,6 +55,9 @@ import org.olat.core.util.vfs.VFSContainer; import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.vfs.VFSManager; import org.olat.core.util.xml.XStreamHelper; +import org.olat.course.CourseFactory; +import org.olat.course.ICourse; +import org.olat.course.assessment.AssessmentHelper; import org.olat.course.assessment.manager.UserCourseInformationsManager; import org.olat.course.nodes.GTACourseNode; import org.olat.course.nodes.gta.AssignmentResponse; @@ -81,6 +84,7 @@ import org.olat.course.nodes.gta.model.TaskListImpl; import org.olat.course.nodes.gta.model.TaskRevisionDateImpl; import org.olat.course.nodes.gta.ui.events.SubmitEvent; import org.olat.course.run.environment.CourseEnvironment; +import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupRef; import org.olat.group.BusinessGroupService; @@ -90,6 +94,7 @@ import org.olat.group.manager.BusinessGroupRelationDAO; import org.olat.group.model.BusinessGroupRefImpl; import org.olat.modules.ModuleConfiguration; import org.olat.modules.assessment.AssessmentService; +import org.olat.modules.assessment.Role; import org.olat.modules.assessment.model.AssessmentEntryStatus; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryEntryRef; @@ -923,7 +928,7 @@ public class GTAManagerImpl implements GTAManager, DeletableGroupData { task.setAssignmentDate(new Date()); dbInstance.getCurrentEntityManager().persist(task); dbInstance.commit(); - syncAssessmentEntry((TaskImpl)currentTask, cNode); + syncAssessmentEntry((TaskImpl)currentTask, cNode, Role.user); response = new AssignmentResponse(task, Status.ok); } } else { @@ -931,7 +936,7 @@ public class GTAManagerImpl implements GTAManager, DeletableGroupData { ((TaskImpl)currentTask).setTaskStatus(TaskProcess.submit); } currentTask = dbInstance.getCurrentEntityManager().merge(currentTask); - syncAssessmentEntry((TaskImpl)currentTask, cNode); + syncAssessmentEntry((TaskImpl)currentTask, cNode, Role.user); response = new AssignmentResponse(currentTask, Status.ok); } @@ -1054,6 +1059,7 @@ public class GTAManagerImpl implements GTAManager, DeletableGroupData { TaskImpl task = createTask(taskName, reloadedTasks, nextStep, businessGroup, identity, cNode); task.setAssignmentDate(new Date()); dbInstance.getCurrentEntityManager().persist(task); + syncAssessmentEntry(task, cNode, Role.user); response = new AssignmentResponse(task, Status.ok); } dbInstance.commit(); @@ -1066,7 +1072,7 @@ public class GTAManagerImpl implements GTAManager, DeletableGroupData { } } currentTask = dbInstance.getCurrentEntityManager().merge(currentTask); - syncAssessmentEntry((TaskImpl)currentTask, cNode); + syncAssessmentEntry((TaskImpl)currentTask, cNode, Role.user); response = new AssignmentResponse(currentTask, Status.ok); } return response; @@ -1264,7 +1270,7 @@ public class GTAManagerImpl implements GTAManager, DeletableGroupData { } @Override - public Task nextStep(Task task, GTACourseNode cNode) { + public Task nextStep(Task task, GTACourseNode cNode, Role by) { TaskImpl taskImpl = (TaskImpl)task; TaskProcess currentStep = taskImpl.getTaskStatus(); //cascade through the possible steps @@ -1272,7 +1278,7 @@ public class GTAManagerImpl implements GTAManager, DeletableGroupData { taskImpl.setTaskStatus(nextStep); TaskImpl mergedTask = dbInstance.getCurrentEntityManager().merge(taskImpl); dbInstance.commit();//make the thing definitiv - syncAssessmentEntry(mergedTask, cNode); + syncAssessmentEntry(mergedTask, cNode, by); return mergedTask; } @@ -1428,16 +1434,16 @@ public class GTAManagerImpl implements GTAManager, DeletableGroupData { TaskImpl taskImpl = (TaskImpl)task; taskImpl.setCollectionDate(new Date()); taskImpl.setCollectionNumOfDocs(numOfDocs); - return updateTask(task, review, cNode); + return updateTask(task, review, cNode, Role.coach); } @Override - public Task submitTask(Task task, GTACourseNode cNode, int numOfDocs) { + public Task submitTask(Task task, GTACourseNode cNode, int numOfDocs, Role by) { TaskProcess review = nextStep(TaskProcess.submit, cNode); TaskImpl taskImpl = (TaskImpl)task; taskImpl.setSubmissionDate(new Date()); taskImpl.setSubmissionNumOfDocs(numOfDocs); - return updateTask(task, review, cNode); + return updateTask(task, review, cNode, by); } @Override @@ -1445,7 +1451,7 @@ public class GTAManagerImpl implements GTAManager, DeletableGroupData { TaskImpl taskImpl = (TaskImpl)task; taskImpl.setAllowResetDate(new Date()); taskImpl.setAllowResetIdentity(allower); - return updateTask(task, task.getTaskStatus(), cNode); + return updateTask(task, task.getTaskStatus(), cNode, Role.coach); } @Override @@ -1453,7 +1459,7 @@ public class GTAManagerImpl implements GTAManager, DeletableGroupData { TaskImpl taskImpl = (TaskImpl)task; taskImpl.setTaskName(null); taskImpl.setAllowResetDate(null); - Task updatedTask = updateTask(task, TaskProcess.assignment, cNode); + Task updatedTask = updateTask(task, TaskProcess.assignment, cNode, Role.user); File submissionDir = null; if(updatedTask.getBusinessGroup() != null) { @@ -1472,17 +1478,17 @@ public class GTAManagerImpl implements GTAManager, DeletableGroupData { TaskImpl taskImpl = (TaskImpl)task; taskImpl.setAllowResetDate(null); taskImpl.setAllowResetIdentity(null); - return updateTask(task, task.getTaskStatus(), cNode); + return updateTask(task, task.getTaskStatus(), cNode, Role.user); } @Override - public Task submitRevisions(Task task, GTACourseNode cNode, int numOfDocs) { + public Task submitRevisions(Task task, GTACourseNode cNode, int numOfDocs, Role by) { TaskImpl taskImpl = (TaskImpl)task; taskImpl.setSubmissionRevisionsDate(new Date()); taskImpl.setSubmissionRevisionsNumOfDocs(numOfDocs); //log the date createAndPersistTaskRevisionDate(taskImpl, taskImpl.getRevisionLoop(), TaskProcess.correction); - return updateTask(taskImpl, TaskProcess.correction, cNode); + return updateTask(taskImpl, TaskProcess.correction, cNode, by); } @Override @@ -1490,16 +1496,16 @@ public class GTAManagerImpl implements GTAManager, DeletableGroupData { TaskProcess solution = nextStep(TaskProcess.correction, cNode); TaskImpl taskImpl = (TaskImpl)task; taskImpl.setAcceptationDate(new Date()); - return updateTask(taskImpl, solution, cNode); + return updateTask(taskImpl, solution, cNode, Role.coach); } @Override - public Task updateTask(Task task, TaskProcess newStatus, GTACourseNode cNode) { + public Task updateTask(Task task, TaskProcess newStatus, GTACourseNode cNode, Role by) { TaskImpl taskImpl = (TaskImpl)task; taskImpl.setTaskStatus(newStatus); syncDates(taskImpl, newStatus); taskImpl = dbInstance.getCurrentEntityManager().merge(taskImpl); - syncAssessmentEntry(taskImpl, cNode); + syncAssessmentEntry(taskImpl, cNode, by); //update OLATResource resource = taskImpl.getTaskList().getEntry().getOlatResource(); @@ -1543,14 +1549,14 @@ public class GTAManagerImpl implements GTAManager, DeletableGroupData { } @Override - public Task updateTask(Task task, TaskProcess newStatus, int iteration, GTACourseNode cNode) { + public Task updateTask(Task task, TaskProcess newStatus, int iteration, GTACourseNode cNode, Role by) { TaskImpl taskImpl = (TaskImpl)task; taskImpl.setTaskStatus(newStatus); taskImpl.setRevisionLoop(iteration); taskImpl = dbInstance.getCurrentEntityManager().merge(taskImpl); //log date createAndPersistTaskRevisionDate(taskImpl, iteration, newStatus); - syncAssessmentEntry(taskImpl, cNode); + syncAssessmentEntry(taskImpl, cNode, by); return taskImpl; } @@ -1572,7 +1578,7 @@ public class GTAManagerImpl implements GTAManager, DeletableGroupData { return assessmentStatus; } - private void syncAssessmentEntry(TaskImpl taskImpl, GTACourseNode cNode) { + private void syncAssessmentEntry(TaskImpl taskImpl, GTACourseNode cNode, Role by) { if(taskImpl == null || taskImpl.getTaskStatus() == null || cNode == null) return; RepositoryEntry courseRepoEntry = taskImpl.getTaskList().getEntry(); @@ -1581,8 +1587,14 @@ public class GTAManagerImpl implements GTAManager, DeletableGroupData { //update whole group assessmentService.updateAssessmentEntries(taskImpl.getBusinessGroup(), courseRepoEntry, cNode.getIdent(), null, assessmentStatus); } else { - assessmentService.updateAssessmentEntry(taskImpl.getIdentity(), courseRepoEntry, cNode.getIdent(), null, assessmentStatus); - } + Identity assessedIdentity = taskImpl.getIdentity(); + assessmentService.updateAssessmentEntry(assessedIdentity, courseRepoEntry, cNode.getIdent(), null, assessmentStatus); + dbInstance.commit(); + + ICourse course = CourseFactory.loadCourse(courseRepoEntry); + UserCourseEnvironment userCourseEnv = AssessmentHelper.createAndInitUserCourseEnvironment(assessedIdentity, course); + cNode.updateLastModifications(userCourseEnv, taskImpl.getIdentity(), by); + } } private TaskList loadForUpdate(TaskList tasks) { diff --git a/src/main/java/org/olat/course/nodes/gta/manager/GTANotifications.java b/src/main/java/org/olat/course/nodes/gta/manager/GTANotifications.java index 040523079b050d87b47dea90a1e2d72d46a987c0..d40f9536f44e9a4483220a0bbc38c411f893e319 100644 --- a/src/main/java/org/olat/course/nodes/gta/manager/GTANotifications.java +++ b/src/main/java/org/olat/course/nodes/gta/manager/GTANotifications.java @@ -65,6 +65,7 @@ import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupService; import org.olat.group.model.SearchBusinessGroupParams; import org.olat.modules.assessment.AssessmentEntry; +import org.olat.modules.assessment.Role; import org.olat.modules.assessment.manager.AssessmentEntryDAO; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryService; @@ -666,7 +667,7 @@ class GTANotifications { DueDate dueDate = gtaManager.getSubmissionDueDate(task, assessedIdentity, assessedGroup, gtaNode, re, true); if(dueDate != null && dueDate.getDueDate() != null && dueDate.getDueDate().before(new Date())) { int numOfDocs = getNumberOfSubmittedDocuments(assessedIdentity, assessedGroup); - task = gtaManager.submitTask(task, gtaNode, numOfDocs); + task = gtaManager.submitTask(task, gtaNode, numOfDocs, Role.auto); doUpdateAttempts(assessedIdentity, assessedGroup); } } @@ -721,7 +722,7 @@ class GTANotifications { && task.getRevisionsDueDate() != null && task.getRevisionsDueDate().compareTo(new Date()) < 0) { //push to the next step - task = gtaManager.nextStep(task, gtaNode); + task = gtaManager.nextStep(task, gtaNode, Role.auto); doUpdateAttempts(assessedIdentity, assessedGroup); } } @@ -756,12 +757,12 @@ class GTANotifications { List<Identity> identities = businessGroupService.getMembers(assessedGroup, GroupRoles.participant.name()); for(Identity identity:identities) { UserCourseEnvironment uce = AssessmentHelper.createAndInitUserCourseEnvironment(identity, course); - gtaNode.incrementUserAttempts(uce); + gtaNode.incrementUserAttempts(uce, Role.auto); } } else { UserCourseEnvironment assessedUserCourseEnv = AssessmentHelper .createAndInitUserCourseEnvironment(assessedIdentity, course); - gtaNode.incrementUserAttempts(assessedUserCourseEnv); + gtaNode.incrementUserAttempts(assessedUserCourseEnv, Role.auto); } } diff --git a/src/main/java/org/olat/course/nodes/gta/ui/ConfirmResetTaskController.java b/src/main/java/org/olat/course/nodes/gta/ui/ConfirmResetTaskController.java index e6b488731a4947562384b8b58dfa6704dcfaf9ca..c4d21b509731b48f773acf655232a1a6007f5b91 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/ConfirmResetTaskController.java +++ b/src/main/java/org/olat/course/nodes/gta/ui/ConfirmResetTaskController.java @@ -1,3 +1,22 @@ +/** + * <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 org.olat.core.gui.UserRequest; diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTAAbstractController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTAAbstractController.java index 6a479fe9753092cb0db7125b4e314e6ff04a351c..5f45a1b6e671dd74663f9919cf54e419ba90d1a5 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/GTAAbstractController.java +++ b/src/main/java/org/olat/course/nodes/gta/ui/GTAAbstractController.java @@ -60,6 +60,7 @@ import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupService; import org.olat.modules.ModuleConfiguration; +import org.olat.modules.assessment.Role; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryService; import org.springframework.beans.factory.annotation.Autowired; @@ -211,7 +212,7 @@ public abstract class GTAAbstractController extends BasicController implements G if(submit) { task = stepSubmit(ureq, task); } else if(task != null && task.getTaskStatus() == TaskProcess.submit) { - task = gtaManager.nextStep(task, gtaNode); + task = gtaManager.nextStep(task, gtaNode, Role.auto); } boolean reviewAndCorrection = config.getBooleanSafe(GTACourseNode.GTASK_REVIEW_AND_CORRECTION); @@ -219,7 +220,7 @@ public abstract class GTAAbstractController extends BasicController implements G if(reviewAndCorrection) { task = stepReviewAndCorrection(ureq, task); } else if(task != null && task.getTaskStatus() == TaskProcess.review) { - task = gtaManager.nextStep(task, gtaNode); + task = gtaManager.nextStep(task, gtaNode, Role.auto); } boolean revision = config.getBooleanSafe(GTACourseNode.GTASK_REVISION_PERIOD); @@ -227,7 +228,7 @@ public abstract class GTAAbstractController extends BasicController implements G if(reviewAndCorrection && revision) { task = stepRevision(ureq, task); } else if(task != null && (task.getTaskStatus() == TaskProcess.revision || task.getTaskStatus() == TaskProcess.correction)) { - task = gtaManager.nextStep(task, gtaNode); + task = gtaManager.nextStep(task, gtaNode, Role.auto); } boolean solution = config.getBooleanSafe(GTACourseNode.GTASK_SAMPLE_SOLUTION); @@ -235,7 +236,7 @@ public abstract class GTAAbstractController extends BasicController implements G if(solution) { stepSolution(ureq, task); } else if(task != null && task.getTaskStatus() == TaskProcess.solution) { - task = gtaManager.nextStep(task, gtaNode); + task = gtaManager.nextStep(task, gtaNode, Role.auto); } boolean grading = config.getBooleanSafe(GTACourseNode.GTASK_GRADING); @@ -243,7 +244,7 @@ public abstract class GTAAbstractController extends BasicController implements G if(grading) { stepGrading(ureq, task); } else if(task != null && task.getTaskStatus() == TaskProcess.grading) { - task = gtaManager.nextStep(task, gtaNode); + task = gtaManager.nextStep(task, gtaNode, Role.auto); } mainVC.contextPut("changelogconfig", courseModule.isDisplayChangeLog()); @@ -302,7 +303,7 @@ public abstract class GTAAbstractController extends BasicController implements G if(assignedTask != null && StringHelper.containsNonWhitespace(assignedTask.getTaskName()) && assignedTask.getTaskStatus() == TaskProcess.assignment && date.compareTo(new Date()) < 0) { //push to the next step if the task is blocked in assignment (it's a security) - assignedTask = gtaManager.nextStep(assignedTask, gtaNode); + assignedTask = gtaManager.nextStep(assignedTask, gtaNode, Role.auto); } } else if(dueDate.getMessageKey() != null) { mainVC.contextPut("assignmentDueDateMsg", translate(dueDate.getMessageKey(), dueDate.getMessageArg())); @@ -363,7 +364,7 @@ public abstract class GTAAbstractController extends BasicController implements G && date.compareTo(new Date()) < 0) { //push to the next step int numOfDocs = getNumberOfSubmittedDocuments(); - assignedTask = gtaManager.submitTask(assignedTask, gtaNode, numOfDocs); + assignedTask = gtaManager.submitTask(assignedTask, gtaNode, numOfDocs, Role.auto); doUpdateAttempts(); } } else if(dueDate.getMessageKey() != null) { @@ -408,7 +409,7 @@ public abstract class GTAAbstractController extends BasicController implements G && date.compareTo(new Date()) < 0) { //push to the next step int numOfDocs = getNumberOfRevisionDocuments(assignedTask); - assignedTask = gtaManager.submitRevisions(assignedTask, gtaNode, numOfDocs); + assignedTask = gtaManager.submitRevisions(assignedTask, gtaNode, numOfDocs, Role.auto); doUpdateAttempts(); } } @@ -473,16 +474,17 @@ public abstract class GTAAbstractController extends BasicController implements G } protected void doUpdateAttempts() { + Role by = getDoer(); if(businessGroupTask) { List<Identity> identities = businessGroupService.getMembers(assessedGroup, GroupRoles.participant.name()); ICourse course = CourseFactory.loadCourse(courseEnv.getCourseGroupManager().getCourseEntry()); for(Identity identity:identities) { UserCourseEnvironment uce = AssessmentHelper.createAndInitUserCourseEnvironment(identity, course); - gtaNode.incrementUserAttempts(uce); + gtaNode.incrementUserAttempts(uce, by); } } else { UserCourseEnvironment assessedUserCourseEnv = getAssessedUserCourseEnvironment(); - gtaNode.incrementUserAttempts(assessedUserCourseEnv); + gtaNode.incrementUserAttempts(assessedUserCourseEnv, by); } } @@ -528,4 +530,6 @@ public abstract class GTAAbstractController extends BasicController implements G ureq.getUserSession().getGuiPreferences() .putAndSave(GTAStepPreferences.class, taskList.getKey().toString(), stepPreferences); } + + protected abstract Role getDoer(); } \ No newline at end of file diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachController.java index 3d610f840454eb462a46e1730dcc173ce047f9d1..17eb6a3076567cd053399fc2f1b266e2c842d697 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachController.java +++ b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachController.java @@ -60,6 +60,7 @@ import org.olat.course.nodes.gta.ui.events.TaskMultiUserEvent; import org.olat.course.run.environment.CourseEnvironment; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.group.BusinessGroup; +import org.olat.modules.assessment.Role; import org.olat.modules.co.ContactFormController; import org.olat.resource.OLATResource; import org.olat.user.DisplayPortraitController; @@ -487,7 +488,7 @@ public class GTACoachController extends GTAAbstractController implements Assessm task = gtaManager.getTask(assessedIdentity, taskList); } if(task != null) { - task = gtaManager.updateTask(task, TaskProcess.graded, gtaNode); + task = gtaManager.updateTask(task, TaskProcess.graded, gtaNode, Role.coach); cleanUpProcess(); process(ureq); } @@ -502,7 +503,7 @@ public class GTACoachController extends GTAAbstractController implements Assessm task = gtaManager.getTask(assessedIdentity, taskList); } if(task != null && task.getTaskStatus() == TaskProcess.graded) { - task = gtaManager.updateTask(task, TaskProcess.grading, gtaNode); + task = gtaManager.updateTask(task, TaskProcess.grading, gtaNode, Role.coach); cleanUpProcess(); process(ureq); } @@ -674,7 +675,7 @@ public class GTACoachController extends GTAAbstractController implements Assessm } private void doRevisions(UserRequest ureq, Task task) { - gtaManager.updateTask(task, TaskProcess.revision, 1, gtaNode); + gtaManager.updateTask(task, TaskProcess.revision, 1, gtaNode, Role.coach); gtaManager.log("Review", "need revision", task, getIdentity(), assessedIdentity, assessedGroup, courseEnv, gtaNode); cleanUpProcess(); @@ -759,7 +760,7 @@ public class GTACoachController extends GTAAbstractController implements Assessm private void doBackToSubmission(UserRequest ureq, Task task) { TaskProcess submit = gtaManager.previousStep(TaskProcess.review, gtaNode);//only submit allowed if(submit == TaskProcess.submit) { - task = gtaManager.updateTask(task, submit, gtaNode); + task = gtaManager.updateTask(task, submit, gtaNode, Role.coach); gtaManager.log("Back to submission", "revert status of task back to submission", task, getIdentity(), assessedIdentity, assessedGroup, courseEnv, gtaNode); @@ -845,5 +846,9 @@ public class GTACoachController extends GTAAbstractController implements Assessm } return taskDef; } - + + @Override + protected Role getDoer() { + return Role.coach; + } } diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachRevisionAndCorrectionsController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachRevisionAndCorrectionsController.java index 7b18c1776b2e5385565ad33c5de67283e7a38469..c249466d6428afcc21b852c8061d75017b3da9a7 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachRevisionAndCorrectionsController.java +++ b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachRevisionAndCorrectionsController.java @@ -63,6 +63,7 @@ import org.olat.course.run.environment.CourseEnvironment; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupService; +import org.olat.modules.assessment.Role; import org.olat.user.UserManager; import org.springframework.beans.factory.annotation.Autowired; @@ -374,7 +375,7 @@ public class GTACoachRevisionAndCorrectionsController extends BasicController im } private void doCollect() { - assignedTask = gtaManager.updateTask(assignedTask, TaskProcess.correction, gtaNode); + assignedTask = gtaManager.updateTask(assignedTask, TaskProcess.correction, gtaNode, Role.coach); gtaManager.log("Collect revision", "revision collected", assignedTask, getIdentity(), assessedIdentity, assessedGroup, courseEnv, gtaNode); ICourse course = CourseFactory.loadCourse(courseEnv.getCourseResourceableId()); @@ -382,10 +383,10 @@ public class GTACoachRevisionAndCorrectionsController extends BasicController im List<Identity> identities = businessGroupService.getMembers(assessedGroup, GroupRoles.participant.name()); for(Identity identity:identities) { UserCourseEnvironment userCourseEnv = AssessmentHelper.createAndInitUserCourseEnvironment(identity, course); - gtaNode.incrementUserAttempts(userCourseEnv); + gtaNode.incrementUserAttempts(userCourseEnv, Role.coach); } } else { - gtaNode.incrementUserAttempts(assessedUserCourseEnv); + gtaNode.incrementUserAttempts(assessedUserCourseEnv, Role.coach); } TaskMultiUserEvent event = new TaskMultiUserEvent(TaskMultiUserEvent.SUBMIT_REVISION, @@ -395,7 +396,7 @@ public class GTACoachRevisionAndCorrectionsController extends BasicController im } private void doReturnToRevisions(Task task) { - assignedTask = gtaManager.updateTask(task, TaskProcess.revision, currentIteration + 1, gtaNode); + assignedTask = gtaManager.updateTask(task, TaskProcess.revision, currentIteration + 1, gtaNode, Role.coach); gtaManager.log("Revision", "need another revision", assignedTask, getIdentity(), assessedIdentity, assessedGroup, courseEnv, gtaNode); } diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedGroupGradingController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedGroupGradingController.java index 597e2e4faf22c75510d11f1cc2be44091eebdd7d..0e83fbaef726e5525be575cab87c1432fcbd7012 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedGroupGradingController.java +++ b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedGroupGradingController.java @@ -72,6 +72,7 @@ import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupService; import org.olat.modules.ModuleConfiguration; import org.olat.modules.assessment.AssessmentEntry; +import org.olat.modules.assessment.Role; import org.olat.user.UserManager; import org.olat.user.propertyhandlers.UserPropertyHandler; import org.springframework.beans.factory.annotation.Autowired; @@ -317,12 +318,12 @@ public class GTACoachedGroupGradingController extends FormBasicController { if(assignedTask == null) { assignedTask = gtaManager.createTask(null, taskList, TaskProcess.graded, assessedGroup, null, gtaNode); } else { - assignedTask = gtaManager.updateTask(assignedTask, TaskProcess.graded, gtaNode); + assignedTask = gtaManager.updateTask(assignedTask, TaskProcess.graded, gtaNode, Role.coach); } } private void doReopenAssessment(UserRequest ureq) { - assignedTask = gtaManager.updateTask(assignedTask, TaskProcess.grading, gtaNode); + assignedTask = gtaManager.updateTask(assignedTask, TaskProcess.grading, gtaNode, Role.coach); fireEvent(ureq, Event.CHANGED_EVENT); } diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedParticipantGradingController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedParticipantGradingController.java index 1449359418bd2e36491436edbfcb9ec93c447160..ae4bff8a729421151398b2685098e17828894286 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedParticipantGradingController.java +++ b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedParticipantGradingController.java @@ -44,6 +44,7 @@ import org.olat.course.nodes.gta.TaskProcess; import org.olat.course.nodes.ms.MSCourseNodeRunController; import org.olat.course.run.scoring.AssessmentEvaluation; import org.olat.course.run.userview.UserCourseEnvironment; +import org.olat.modules.assessment.Role; import org.olat.modules.assessment.model.AssessmentEntryStatus; import org.olat.modules.assessment.ui.event.AssessmentFormEvent; import org.olat.repository.RepositoryEntry; @@ -147,7 +148,7 @@ public class GTACoachedParticipantGradingController extends BasicController { } private void doReopenAssessment(UserRequest ureq) { - assignedTask = gtaManager.updateTask(assignedTask, TaskProcess.grading, gtaNode); + assignedTask = gtaManager.updateTask(assignedTask, TaskProcess.grading, gtaNode, Role.coach); fireEvent(ureq, Event.CHANGED_EVENT); } @@ -164,7 +165,7 @@ public class GTACoachedParticipantGradingController extends BasicController { TaskList taskList = gtaManager.createIfNotExists(courseEntry, gtaNode); assignedTask = gtaManager.createTask(null, taskList, TaskProcess.graded, null, assessedIdentity, gtaNode); } else { - assignedTask = gtaManager.updateTask(assignedTask, TaskProcess.graded, gtaNode); + assignedTask = gtaManager.updateTask(assignedTask, TaskProcess.graded, gtaNode, Role.coach); } fireEvent(ureq, Event.CHANGED_EVENT); } diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTAParticipantController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTAParticipantController.java index 0326400ca2c959f6537c69bf07c15c66283dcc11..fcc500d7f4f2bc7cd1a23b02c67430ebc00ad3ac 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/GTAParticipantController.java +++ b/src/main/java/org/olat/course/nodes/gta/ui/GTAParticipantController.java @@ -69,6 +69,7 @@ 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.olat.modules.assessment.Role; import org.springframework.beans.factory.annotation.Autowired; /** @@ -338,7 +339,7 @@ public class GTAParticipantController extends GTAAbstractController implements A private void doSubmitDocuments(UserRequest ureq, Task task) { int numOfDocs = getNumberOfSubmittedDocuments(); - task = gtaManager.submitTask(task, gtaNode, numOfDocs); + task = gtaManager.submitTask(task, gtaNode, numOfDocs, Role.user); showInfo("run.documents.successfully.submitted"); TaskMultiUserEvent event = new TaskMultiUserEvent(TaskMultiUserEvent.SUMBIT_TASK, @@ -843,4 +844,9 @@ public class GTAParticipantController extends GTAAbstractController implements A listenTo(chooserCalloutCtrl); chooserCalloutCtrl.activate(); } + + @Override + protected Role getDoer() { + return Role.user; + } } \ No newline at end of file diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTAParticipantRevisionAndCorrectionsController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTAParticipantRevisionAndCorrectionsController.java index 82b213f79af11a7d6f03bcb32c11db58c24201b6..1ba44f5b0f3d7cbb4d2bc7dd97d17d1bf19e2717 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/GTAParticipantRevisionAndCorrectionsController.java +++ b/src/main/java/org/olat/course/nodes/gta/ui/GTAParticipantRevisionAndCorrectionsController.java @@ -63,6 +63,7 @@ import org.olat.course.run.environment.CourseEnvironment; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupService; +import org.olat.modules.assessment.Role; import org.springframework.beans.factory.annotation.Autowired; /** @@ -323,7 +324,7 @@ public class GTAParticipantRevisionAndCorrectionsController extends BasicControl } int numOfDocs = submittedDocuments == null ? 0 : submittedDocuments.length; - assignedTask = gtaManager.submitRevisions(assignedTask, gtaNode, numOfDocs); + assignedTask = gtaManager.submitRevisions(assignedTask, gtaNode, numOfDocs, Role.user); gtaManager.log("Revision", "revision submitted", assignedTask, getIdentity(), getIdentity(), assessedGroup, courseEnv, gtaNode); TaskMultiUserEvent event = new TaskMultiUserEvent(TaskMultiUserEvent.SUBMIT_REVISION, @@ -337,10 +338,10 @@ public class GTAParticipantRevisionAndCorrectionsController extends BasicControl for(Identity identity:identities) { UserCourseEnvironment userCourseEnv = AssessmentHelper.createAndInitUserCourseEnvironment(identity, course); - gtaNode.incrementUserAttempts(userCourseEnv); + gtaNode.incrementUserAttempts(userCourseEnv, Role.user); } } else { - gtaNode.incrementUserAttempts(assessedUserCourseEnv); + gtaNode.incrementUserAttempts(assessedUserCourseEnv, Role.user); } } } diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GroupAssessmentController.java b/src/main/java/org/olat/course/nodes/gta/ui/GroupAssessmentController.java index ce49553f89856e6d5a37310104862e677250450c..f46f057445557a375af94c49587dd60921f11330 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/GroupAssessmentController.java +++ b/src/main/java/org/olat/course/nodes/gta/ui/GroupAssessmentController.java @@ -67,6 +67,7 @@ import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupService; import org.olat.modules.assessment.AssessmentEntry; +import org.olat.modules.assessment.Role; import org.olat.modules.assessment.model.AssessmentEntryStatus; import org.olat.user.UserManager; import org.olat.user.propertyhandlers.UserPropertyHandler; @@ -519,11 +520,11 @@ public class GroupAssessmentController extends FormBasicController { if(applyToAllEl.isAtLeastSelected(1)) { applyChangesForTheWholeGroup(rows, setAsDone, userVisible); } else { - applyChangesForEvenryMemberGroup(rows, setAsDone, userVisible); + applyChangesForEveryMemberGroup(rows, setAsDone, userVisible); } } - private void applyChangesForEvenryMemberGroup(List<AssessmentRow> rows, boolean setAsDone, boolean userVisible) { + private void applyChangesForEveryMemberGroup(List<AssessmentRow> rows, boolean setAsDone, boolean userVisible) { ICourse course = CourseFactory.loadCourse(courseEnv.getCourseResourceableId()); for(AssessmentRow row:rows) { @@ -552,7 +553,7 @@ public class GroupAssessmentController extends FormBasicController { } else { newScoreEval = new ScoreEvaluation(score, passed, null, userVisible, null, null); } - gtaNode.updateUserScoreEvaluation(newScoreEval, userCourseEnv, getIdentity(), false); + gtaNode.updateUserScoreEvaluation(newScoreEval, userCourseEnv, getIdentity(), false, Role.coach); if(withComment) { String comment = row.getComment(); @@ -591,7 +592,7 @@ public class GroupAssessmentController extends FormBasicController { } else { newScoreEval = new ScoreEvaluation(score, passed, null, userVisible, null, null); } - gtaNode.updateUserScoreEvaluation(newScoreEval, userCourseEnv, getIdentity(), false); + gtaNode.updateUserScoreEvaluation(newScoreEval, userCourseEnv, getIdentity(), false, Role.coach); } if(withComment) { diff --git a/src/main/java/org/olat/course/nodes/iq/IQPreviewController.java b/src/main/java/org/olat/course/nodes/iq/IQPreviewController.java index cc285dbc592c2ae88c9cd222d2c92104f111d666..b451ca60f6ce4c30e974be94e1c82360ad2a5667 100644 --- a/src/main/java/org/olat/course/nodes/iq/IQPreviewController.java +++ b/src/main/java/org/olat/course/nodes/iq/IQPreviewController.java @@ -34,6 +34,7 @@ import org.olat.core.gui.control.controller.BasicController; import org.olat.course.nodes.IQTESTCourseNode; import org.olat.course.run.scoring.ScoreEvaluation; import org.olat.course.run.userview.UserCourseEnvironment; +import org.olat.modules.assessment.Role; /** * Description: <br> @@ -79,7 +80,7 @@ public class IQPreviewController extends BasicController { boolean passed = score >= (cutValue == null ? 0 : cutValue.floatValue()); ScoreEvaluation sceval = new ScoreEvaluation(new Float(score), new Boolean(passed)); boolean incrementUserAttempts = true; - cn.updateUserScoreEvaluation(sceval, userCourseEnv, ureq.getIdentity(), incrementUserAttempts); + cn.updateUserScoreEvaluation(sceval, userCourseEnv, ureq.getIdentity(), incrementUserAttempts, Role.user); getWindowControl().setInfo(translate("preview.points.set")); } } diff --git a/src/main/java/org/olat/course/nodes/iq/IQRunController.java b/src/main/java/org/olat/course/nodes/iq/IQRunController.java index 6182d38a1c2900f60a3b9c5a552590f618293e00..6a3e4c56d52cbaee9d280b389c5874225c164411 100644 --- a/src/main/java/org/olat/course/nodes/iq/IQRunController.java +++ b/src/main/java/org/olat/course/nodes/iq/IQRunController.java @@ -92,6 +92,7 @@ import org.olat.ims.qti.process.ImsRepositoryResolver; import org.olat.instantMessaging.InstantMessagingService; import org.olat.modules.ModuleConfiguration; import org.olat.modules.assessment.AssessmentEntry; +import org.olat.modules.assessment.Role; import org.olat.modules.assessment.model.AssessmentEntryStatus; import org.olat.modules.iq.IQDisplayController; import org.olat.modules.iq.IQManager; @@ -518,7 +519,7 @@ public class IQRunController extends BasicController implements GenericEventList ScoreEvaluation sceval = new ScoreEvaluation(ac.getScore(), ac.isPassed(), assessmentStatus, userVisibility, fullyAssed, ai.getAssessID()); AssessableCourseNode acn = (AssessableCourseNode)courseNode; // assessment nodes are assessable - acn.updateUserScoreEvaluation(sceval, userCourseEnv, getIdentity(), true); + acn.updateUserScoreEvaluation(sceval, userCourseEnv, getIdentity(), true, Role.user); // Mark publisher for notifications Long courseId = userCourseEnv.getCourseEnvironment().getCourseResourceableId(); @@ -534,10 +535,10 @@ public class IQRunController extends BasicController implements GenericEventList // although this is not an assessable node we still use the assessment // manager since this one uses caching AssessmentManager am = userCourseEnv.getCourseEnvironment().getAssessmentManager(); - am.incrementNodeAttempts(courseNode, getIdentity(), userCourseEnv); + am.incrementNodeAttempts(courseNode, getIdentity(), userCourseEnv, Role.user); } else if(type.equals(AssessmentInstance.QMD_ENTRY_TYPE_SELF)){ AssessmentManager am = userCourseEnv.getCourseEnvironment().getAssessmentManager(); - am.incrementNodeAttempts(courseNode, getIdentity(), userCourseEnv); + am.incrementNodeAttempts(courseNode, getIdentity(), userCourseEnv, Role.user); } } diff --git a/src/main/java/org/olat/course/nodes/iq/QTI21AssessmentRunController.java b/src/main/java/org/olat/course/nodes/iq/QTI21AssessmentRunController.java index b6fc424ca34dff7c8fe1e857315c2c94e463f477..9e7538794fc1c06e23c0dc52c059b590859c6d14 100644 --- a/src/main/java/org/olat/course/nodes/iq/QTI21AssessmentRunController.java +++ b/src/main/java/org/olat/course/nodes/iq/QTI21AssessmentRunController.java @@ -89,6 +89,7 @@ import org.olat.ims.qti21.ui.ResourcesMapper; import org.olat.instantMessaging.InstantMessagingService; import org.olat.modules.ModuleConfiguration; import org.olat.modules.assessment.AssessmentEntry; +import org.olat.modules.assessment.Role; import org.olat.modules.assessment.model.AssessmentEntryStatus; import org.olat.repository.RepositoryEntry; import org.olat.user.UserManager; @@ -727,7 +728,7 @@ public class QTI21AssessmentRunController extends BasicController implements Gen ScoreEvaluation sceval = new ScoreEvaluation(score, pass, assessmentStatus, visibility, Boolean.TRUE, assessmentId); boolean increment = incrementAttempts.getAndSet(false); - ((IQTESTCourseNode)courseNode).updateUserScoreEvaluation(sceval, userCourseEnv, getIdentity(), increment); + ((IQTESTCourseNode)courseNode).updateUserScoreEvaluation(sceval, userCourseEnv, getIdentity(), increment, Role.user); if(increment) { ThreadLocalUserActivityLogger.log(QTI21LoggingAction.QTI_CLOSE_IN_COURSE, getClass()); } @@ -736,7 +737,7 @@ public class QTI21AssessmentRunController extends BasicController implements Gen } else if(courseNode instanceof SelfAssessableCourseNode) { boolean increment = incrementAttempts.getAndSet(false); if(increment) { - ((SelfAssessableCourseNode)courseNode).incrementUserAttempts(userCourseEnv); + ((SelfAssessableCourseNode)courseNode).incrementUserAttempts(userCourseEnv, Role.user); } } } diff --git a/src/main/java/org/olat/course/nodes/scorm/ScormRunController.java b/src/main/java/org/olat/course/nodes/scorm/ScormRunController.java index 868359e658a5a0c0749eb2c9f8f3f3760900f848..ba1c5bb94d4cd5d1276d3a7372b254f8e2948bad 100644 --- a/src/main/java/org/olat/course/nodes/scorm/ScormRunController.java +++ b/src/main/java/org/olat/course/nodes/scorm/ScormRunController.java @@ -63,6 +63,7 @@ import org.olat.fileresource.FileResourceManager; import org.olat.instantMessaging.CloseInstantMessagingEvent; import org.olat.instantMessaging.InstantMessagingService; import org.olat.modules.ModuleConfiguration; +import org.olat.modules.assessment.Role; import org.olat.modules.scorm.ScormAPICallback; import org.olat.modules.scorm.ScormAPIandDisplayController; import org.olat.modules.scorm.ScormCPManifestTreeModel; @@ -315,7 +316,7 @@ public class ScormRunController extends BasicController implements ScormAPICallb //increment user attempts only once! if(!config.getBooleanSafe(ScormEditController.CONFIG_ADVANCESCORE, true) || !config.getBooleanSafe(ScormEditController.CONFIG_ATTEMPTSDEPENDONSCORE, false)) { - scormNode.incrementUserAttempts(userCourseEnv); + scormNode.incrementUserAttempts(userCourseEnv, Role.user); attemptsIncremented = true; } diff --git a/src/main/java/org/olat/course/nodes/ta/ConvertToGTACourseNode.java b/src/main/java/org/olat/course/nodes/ta/ConvertToGTACourseNode.java index 9c880aac7ded874f16f5c9bc801c9ce4395e974d..5bd7ee684b5dd20f25e9bc8c2b12b0da5fe46947 100644 --- a/src/main/java/org/olat/course/nodes/ta/ConvertToGTACourseNode.java +++ b/src/main/java/org/olat/course/nodes/ta/ConvertToGTACourseNode.java @@ -64,6 +64,7 @@ import org.olat.course.run.scoring.ScoreEvaluation; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.modules.ModuleConfiguration; import org.olat.modules.assessment.AssessmentEntry; +import org.olat.modules.assessment.Role; import org.olat.properties.Property; /** @@ -240,19 +241,19 @@ public class ConvertToGTACourseNode { UserCourseEnvironment userCourseEnv = AssessmentHelper.createAndInitUserCourseEnvironment(assessedIdentity, course); Float score = assessmentData.getScore() == null ? null : assessmentData.getScore().floatValue(); ScoreEvaluation scoreEval = new ScoreEvaluation(score, assessmentData.getPassed()); - assessmentMgr.saveScoreEvaluation(gtaNode, null, assessedIdentity, scoreEval, userCourseEnv, false); + assessmentMgr.saveScoreEvaluation(gtaNode, null, assessedIdentity, scoreEval, userCourseEnv, false, Role.auto); //set graded Task task = gtaManager.getTask(assessedIdentity, taskList); if(task == null) { gtaManager.createTask(null, taskList, TaskProcess.graded, null, assessedIdentity, gtaNode); } else { - gtaManager.updateTask(task, TaskProcess.graded, gtaNode); + gtaManager.updateTask(task, TaskProcess.graded, gtaNode, Role.auto); } } if(assessmentData.getAttempts() != null) { - assessmentMgr.saveNodeAttempts(gtaNode, null, assessedIdentity, assessmentData.getAttempts().intValue()); + assessmentMgr.saveNodeAttempts(gtaNode, null, assessedIdentity, assessmentData.getAttempts().intValue(), Role.auto); } if(StringHelper.containsNonWhitespace(assessmentData.getCoachComment())) { @@ -366,7 +367,7 @@ public class ConvertToGTACourseNode { if(task == null) { gtaManager.createTask(null, taskList, process, null, assessedIdentity, gtaNode); } else { - gtaManager.updateTask(task, process, gtaNode); + gtaManager.updateTask(task, process, gtaNode, Role.auto); } } diff --git a/src/main/java/org/olat/course/nodes/ta/DropboxController.java b/src/main/java/org/olat/course/nodes/ta/DropboxController.java index 22e7892d212ea58d922ac12278d925149bff339f..0e4e4b9794c4fa51664ff01672d2719527047f39 100644 --- a/src/main/java/org/olat/course/nodes/ta/DropboxController.java +++ b/src/main/java/org/olat/course/nodes/ta/DropboxController.java @@ -81,6 +81,7 @@ import org.olat.course.nodes.TACourseNode; import org.olat.course.run.environment.CourseEnvironment; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.modules.ModuleConfiguration; +import org.olat.modules.assessment.Role; /** * Initial Date: 02.09.2004 @@ -361,14 +362,7 @@ public class DropboxController extends BasicController { // update attempts counter for this user: one file - one attempts AssessableCourseNode acn = (AssessableCourseNode) node; - /*AssessmentEvaluation eval = acn.getUserScoreEvaluation(userCourseEnv); - if(eval.getAssessmentStatus() == null || eval.getAssessmentStatus() == AssessmentEntryStatus.notStarted) { - eval = new AssessmentEvaluation(eval, AssessmentEntryStatus.inProgress); - acn.updateUserScoreEvaluation(eval, userCourseEnv, getIdentity(), true); - } else { - acn.incrementUserAttempts(userCourseEnv); - }*/ - acn.incrementUserAttempts(userCourseEnv); + acn.incrementUserAttempts(userCourseEnv, Role.user); // log entry for this file UserNodeAuditManager am = userCourseEnv.getCourseEnvironment().getAuditManager(); diff --git a/src/main/java/org/olat/course/nodes/ta/DropboxScoringViewController.java b/src/main/java/org/olat/course/nodes/ta/DropboxScoringViewController.java index a23dc5fa6b1995990bff15fd852faf6b71f21f84..fdd08ceae773a451f8937dd5e95d282e5eecfa44 100644 --- a/src/main/java/org/olat/course/nodes/ta/DropboxScoringViewController.java +++ b/src/main/java/org/olat/course/nodes/ta/DropboxScoringViewController.java @@ -80,6 +80,7 @@ import org.olat.course.properties.CoursePropertyManager; import org.olat.course.run.scoring.AssessmentEvaluation; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.modules.ModuleConfiguration; +import org.olat.modules.assessment.Role; import org.olat.modules.assessment.model.AssessmentEntryStatus; import org.olat.properties.Property; import org.olat.user.UserManager; @@ -300,7 +301,7 @@ public class DropboxScoringViewController extends BasicController { AssessmentEvaluation eval = acn.getUserScoreEvaluation(userCourseEnv); if(eval.getAssessmentStatus() == null || eval.getAssessmentStatus() == AssessmentEntryStatus.notStarted) { eval = new AssessmentEvaluation(eval, AssessmentEntryStatus.inProgress); - acn.updateUserScoreEvaluation(eval, userCourseEnv, coach, false); + acn.updateUserScoreEvaluation(eval, userCourseEnv, coach, false, Role.coach); } } @@ -339,7 +340,7 @@ public class DropboxScoringViewController extends BasicController { } if(eval.getAssessmentStatus() == null || eval.getAssessmentStatus() == AssessmentEntryStatus.notStarted) { eval = new AssessmentEvaluation(eval, AssessmentEntryStatus.inProgress); - acn.updateUserScoreEvaluation(eval, userCourseEnv, getIdentity(), false); + acn.updateUserScoreEvaluation(eval, userCourseEnv, getIdentity(), false, Role.coach); fireEvent(ureq, Event.CHANGED_EVENT); } } diff --git a/src/main/java/org/olat/course/nodes/ta/TaskController.java b/src/main/java/org/olat/course/nodes/ta/TaskController.java index 994143f34ce0d395749cb7046749844207f5771c..24c4b58a902c381e21d395b3a6c42088e0b08e2e 100644 --- a/src/main/java/org/olat/course/nodes/ta/TaskController.java +++ b/src/main/java/org/olat/course/nodes/ta/TaskController.java @@ -66,6 +66,7 @@ import org.olat.course.run.environment.CourseEnvironment; import org.olat.course.run.scoring.AssessmentEvaluation; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.modules.ModuleConfiguration; +import org.olat.modules.assessment.Role; import org.olat.modules.assessment.model.AssessmentEntryStatus; import org.olat.properties.Property; @@ -352,7 +353,7 @@ public class TaskController extends BasicController { AssessmentEvaluation eval = node.getUserScoreEvaluation(userCourseEnv); if(eval.getAssessmentStatus() == null || eval.getAssessmentStatus() == AssessmentEntryStatus.notStarted) { eval = new AssessmentEvaluation(eval, AssessmentEntryStatus.inProgress); - node.updateUserScoreEvaluation(eval, userCourseEnv, getIdentity(), false); + node.updateUserScoreEvaluation(eval, userCourseEnv, getIdentity(), false, Role.user); } } diff --git a/src/main/java/org/olat/course/run/preview/PreviewAssessmentManager.java b/src/main/java/org/olat/course/run/preview/PreviewAssessmentManager.java index b165328516dc155de304b12df1c393d4f2891125..3397f8f13a36c2e77b3739decc7b412d7994b789 100644 --- a/src/main/java/org/olat/course/run/preview/PreviewAssessmentManager.java +++ b/src/main/java/org/olat/course/run/preview/PreviewAssessmentManager.java @@ -44,6 +44,7 @@ import org.olat.course.run.scoring.ScoreEvaluation; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.group.BusinessGroup; import org.olat.modules.assessment.AssessmentEntry; +import org.olat.modules.assessment.Role; import org.olat.modules.assessment.model.AssessmentEntryStatus; /** @@ -103,7 +104,7 @@ final class PreviewAssessmentManager extends BasicManager implements AssessmentM * @see org.olat.course.assessment.AssessmentManager#saveNodeAttempts(org.olat.course.nodes.CourseNode, org.olat.core.id.Identity, org.olat.core.id.Identity, java.lang.Integer) */ @Override - public void saveNodeAttempts(CourseNode courseNode, Identity identity, Identity assessedIdentity, Integer attempts) { + public void saveNodeAttempts(CourseNode courseNode, Identity identity, Identity assessedIdentity, Integer attempts, Role by) { nodeAttempts.put(courseNode.getIdent(), attempts); } @@ -150,7 +151,7 @@ final class PreviewAssessmentManager extends BasicManager implements AssessmentM * @see org.olat.course.assessment.AssessmentManager#incrementNodeAttempts(org.olat.course.nodes.CourseNode, org.olat.core.id.Identity) */ @Override - public void incrementNodeAttempts(CourseNode courseNode, Identity identity, UserCourseEnvironment userCourseEnvironment) { + public void incrementNodeAttempts(CourseNode courseNode, Identity identity, UserCourseEnvironment userCourseEnvironment, Role by) { Integer attempts = nodeAttempts.get(courseNode.getIdent()); if (attempts == null) attempts = new Integer(0); int iAttempts = attempts.intValue(); @@ -164,7 +165,12 @@ final class PreviewAssessmentManager extends BasicManager implements AssessmentM */ @Override public void incrementNodeAttemptsInBackground(CourseNode courseNode, Identity identity, UserCourseEnvironment userCourseEnvironment) { - incrementNodeAttempts(courseNode, identity, userCourseEnvironment); + incrementNodeAttempts(courseNode, identity, userCourseEnvironment, Role.auto); + } + + @Override + public void updateLastModifications(CourseNode courseNode, Identity assessedIdentity, UserCourseEnvironment userCourseEnvironment, Role by) { + // } /** @@ -263,13 +269,13 @@ final class PreviewAssessmentManager extends BasicManager implements AssessmentM */ @Override public void saveScoreEvaluation(AssessableCourseNode courseNode, Identity identity, Identity assessedIdentity, ScoreEvaluation scoreEvaluation, - UserCourseEnvironment userCourseEnvironment, boolean incrementUserAttempts) { + UserCourseEnvironment userCourseEnvironment, boolean incrementUserAttempts, Role by) { saveNodeScore(courseNode, scoreEvaluation.getScore()); saveNodePassed(courseNode, scoreEvaluation.getPassed()); saveAssessmentID(courseNode, scoreEvaluation.getAssessmentID()); if(incrementUserAttempts) { - incrementNodeAttempts(courseNode, identity, userCourseEnvironment); + incrementNodeAttempts(courseNode, identity, userCourseEnvironment, by); } } diff --git a/src/main/java/org/olat/course/run/scoring/AssessmentEvaluation.java b/src/main/java/org/olat/course/run/scoring/AssessmentEvaluation.java index 984c19141be6559b6af67770c9a896834217f70c..ca43e06edac7b3f66bf0e7760fb0ee57b1bd8f03 100644 --- a/src/main/java/org/olat/course/run/scoring/AssessmentEvaluation.java +++ b/src/main/java/org/olat/course/run/scoring/AssessmentEvaluation.java @@ -19,6 +19,8 @@ */ package org.olat.course.run.scoring; +import java.util.Date; + import org.olat.course.nodes.AssessableCourseNode; import org.olat.modules.assessment.AssessmentEntry; import org.olat.modules.assessment.model.AssessmentEntryStatus; @@ -37,6 +39,11 @@ public class AssessmentEvaluation extends ScoreEvaluation { private final String comment; private final String coachComment; private final int numOfAssessmentDocs; + + private final Date lastModified; + private final Date lastUserModified; + private final Date lastCoachModified; + public AssessmentEvaluation(Float score, Boolean passed) { this(score, passed, null, null); @@ -47,16 +54,24 @@ public class AssessmentEvaluation extends ScoreEvaluation { } public AssessmentEvaluation(Float score, Boolean passed, Boolean fullyAssessed, Long assessmentID) { - this(score, passed, null, null, null, fullyAssessed, assessmentID, null, null, -1); + this(score, passed, null, null, null, fullyAssessed, assessmentID, null, null, -1, null, null, null); + } + + public AssessmentEvaluation(Date lastModified, Date lastUserModified, Date lastCoachModified) { + this(null, null, null, null, null, null, null, null, null, -1, lastModified, lastUserModified, lastCoachModified); } public AssessmentEvaluation(Float score, Boolean passed, Integer attempts, AssessmentEntryStatus assessmentStatus, Boolean userVisibility, - Boolean fullyAssessed, Long assessmentID, String comment, String coachComment, int numOfAssessmentDocs) { + Boolean fullyAssessed, Long assessmentID, String comment, String coachComment, int numOfAssessmentDocs, + Date lastModified, Date lastUserModified, Date lastCoachModified) { super(score, passed, assessmentStatus, userVisibility, fullyAssessed, assessmentID); this.attempts = attempts; this.comment = comment; this.coachComment = coachComment; this.numOfAssessmentDocs = numOfAssessmentDocs; + this.lastModified = lastModified; + this.lastUserModified = lastUserModified; + this.lastCoachModified = lastCoachModified; } /** @@ -67,7 +82,8 @@ public class AssessmentEvaluation extends ScoreEvaluation { */ public AssessmentEvaluation(AssessmentEvaluation eval, AssessmentEntryStatus assessmentStatus) { this(eval.getScore(), eval.getPassed(), eval.getAttempts(), assessmentStatus, eval.getUserVisible(), - eval.getFullyAssessed(), eval.getAssessmentID(), eval.getComment(), eval.getCoachComment(), -1); + eval.getFullyAssessed(), eval.getAssessmentID(), eval.getComment(), eval.getCoachComment(), -1, + eval.getLastModified(), eval.getLastUserModified(), eval.getLastCoachModified()); } public Integer getAttempts() { @@ -86,6 +102,18 @@ public class AssessmentEvaluation extends ScoreEvaluation { return numOfAssessmentDocs; } + public Date getLastModified() { + return lastModified; + } + + public Date getLastUserModified() { + return lastUserModified; + } + + public Date getLastCoachModified() { + return lastCoachModified; + } + public static final AssessmentEvaluation toAssessmentEvalutation(AssessmentEntry entry, AssessableCourseNode node) { if(entry == null) { return AssessmentEvaluation.EMPTY_EVAL; @@ -111,6 +139,7 @@ public class AssessmentEvaluation extends ScoreEvaluation { comment = entry.getComment(); } return new AssessmentEvaluation(score, passed, attempts, entry.getAssessmentStatus(), entry.getUserVisibility(), - entry.getFullyAssessed(), entry.getAssessmentId(), comment, entry.getCoachComment(), entry.getNumberOfAssessmentDocuments()); + entry.getFullyAssessed(), entry.getAssessmentId(), comment, entry.getCoachComment(), entry.getNumberOfAssessmentDocuments(), + entry.getLastModified(), entry.getLastUserModified(), entry.getLastCoachModified()); } } \ No newline at end of file diff --git a/src/main/java/org/olat/course/run/scoring/ScoreAccounting.java b/src/main/java/org/olat/course/run/scoring/ScoreAccounting.java index 1d2697f1a3d892b3bbabf5819d8b9823f9f8d388..970379d59091b60ba6020a58d32bb9724fb322a9 100644 --- a/src/main/java/org/olat/course/run/scoring/ScoreAccounting.java +++ b/src/main/java/org/olat/course/run/scoring/ScoreAccounting.java @@ -177,6 +177,18 @@ public class ScoreAccounting { return se; } + private void updateLastModified(CourseNode cNode, LastModifications lastModifications) { + AssessmentEvaluation eval = cachedScoreEvals.get(cNode); + if(eval != null) { + lastModifications.addLastUserModified(eval.getLastUserModified()); + lastModifications.addLastCoachModified(eval.getLastCoachModified()); + } + + for(int i=cNode.getChildCount(); i-->0; ) { + updateLastModified((CourseNode)cNode.getChildAt(i), lastModifications); + } + } + /** * Recalculate the score of structure nodes. * @@ -196,6 +208,8 @@ public class ScoreAccounting { Boolean userVisibility = entry == null ? null : entry.getUserVisibility(); Long assessmendId = entry == null ? null : entry.getAssessmentId(); int numOfAssessmentDocs = entry == null ? -1 : entry.getNumberOfAssessmentDocuments(); + Date lastModified = entry == null ? null : entry.getLastModified(); + AssessmentEntryStatus assessmentStatus = AssessmentEntryStatus.inProgress; ConditionInterpreter ci = userCourseEnvironment.getConditionInterpreter(); if (cNode.hasScoreConfigured() && scoreExpressionStr != null) { @@ -221,7 +235,11 @@ public class ScoreAccounting { } } } - se = new AssessmentEvaluation(score, passed, null, assessmentStatus, userVisibility, null, assessmendId, null, null, numOfAssessmentDocs); + + LastModifications lastModifications = new LastModifications(); + updateLastModified(cNode, lastModifications); + se = new AssessmentEvaluation(score, passed, null, assessmentStatus, userVisibility, null, assessmendId, null, null, numOfAssessmentDocs, + lastModified, lastModifications.getLastUserModified(), lastModifications.getLastCoachModified()); if(entry == null) { Identity assessedIdentity = userCourseEnvironment.getIdentityEnvironment().getIdentity(); @@ -235,11 +253,49 @@ public class ScoreAccounting { entry.setScore(null); } entry.setPassed(passed); + if(lastModifications.getLastCoachModified() != null + && (entry.getLastCoachModified() == null || (entry.getLastCoachModified() != null && entry.getLastCoachModified().before(lastModifications.getLastCoachModified())))) { + entry.setLastCoachModified(lastModifications.getLastCoachModified()); + } + if(lastModifications.getLastUserModified() != null + && (entry.getLastUserModified() == null || (entry.getLastUserModified() != null && entry.getLastUserModified().before(lastModifications.getLastUserModified())))) { + entry.setLastUserModified(lastModifications.getLastUserModified()); + } entry = userCourseEnvironment.getCourseEnvironment().getAssessmentManager().updateAssessmentEntry(entry); identToEntries.put(cNode.getIdent(), entry); changes = true; } } else { + //only update the last modifications dates + LastModifications lastModifications = new LastModifications(); + updateLastModified(cNode, lastModifications); + if(entry == null) { + if(lastModifications.getLastCoachModified() != null || lastModifications.getLastUserModified() != null) { + se = new AssessmentEvaluation(new Date(), lastModifications.getLastUserModified(), lastModifications.getLastCoachModified()); + Identity assessedIdentity = userCourseEnvironment.getIdentityEnvironment().getIdentity(); + userCourseEnvironment.getCourseEnvironment().getAssessmentManager() + .createAssessmentEntry(cNode, assessedIdentity, se); + changes = true; + } + } else { + boolean updated = false; + if(lastModifications.getLastCoachModified() != null + && (entry.getLastCoachModified() == null || (entry.getLastCoachModified() != null && entry.getLastCoachModified().before(lastModifications.getLastCoachModified())))) { + entry.setLastCoachModified(lastModifications.getLastCoachModified()); + updated = true; + } + if(lastModifications.getLastUserModified() != null + && (entry.getLastUserModified() == null || (entry.getLastUserModified() != null && entry.getLastUserModified().before(lastModifications.getLastUserModified())))) { + entry.setLastUserModified(lastModifications.getLastUserModified()); + updated = true; + } + if(updated) { + entry = userCourseEnvironment.getCourseEnvironment().getAssessmentManager().updateAssessmentEntry(entry); + identToEntries.put(cNode.getIdent(), entry); + changes = true; + } + } + se = AssessmentEvaluation.EMPTY_EVAL; } return se; @@ -278,6 +334,18 @@ public class ScoreAccounting { same &= false; } + if((entry.getLastUserModified() == null && se.getLastUserModified() != null) + || (se.getLastUserModified() != null && entry.getLastUserModified() != null + && se.getLastUserModified().after(entry.getLastUserModified()))) { + same &= false; + } + + if((entry.getLastCoachModified() == null && se.getLastCoachModified() != null) + || (se.getLastCoachModified() != null && entry.getLastCoachModified() != null + && se.getLastCoachModified().after(entry.getLastCoachModified()))) { + same &= false; + } + return same; } } @@ -389,5 +457,31 @@ public class ScoreAccounting { public boolean isError() { return error; } + + private static class LastModifications { + + private Date lastUserModified; + private Date lastCoachModified; + + public Date getLastUserModified() { + return lastUserModified; + } + + public void addLastUserModified(Date date) { + if(date != null && (lastUserModified == null || lastUserModified.before(date))) { + lastUserModified = date; + } + } + + public Date getLastCoachModified() { + return lastCoachModified; + } + + public void addLastCoachModified(Date date) { + if(date != null && (lastCoachModified == null || lastCoachModified.before(date))) { + lastCoachModified = date; + } + } + } } diff --git a/src/main/java/org/olat/ims/qti/QTI12ResultDetailsController.java b/src/main/java/org/olat/ims/qti/QTI12ResultDetailsController.java index da10dac2560e8cdf126279f5b1193d4366285a46..dcf627e99aa0b8142e19cd400ade5fb19d3319cb 100644 --- a/src/main/java/org/olat/ims/qti/QTI12ResultDetailsController.java +++ b/src/main/java/org/olat/ims/qti/QTI12ResultDetailsController.java @@ -65,6 +65,7 @@ import org.olat.ims.qti.process.AssessmentInstance; import org.olat.ims.qti.process.FilePersister; import org.olat.ims.qti.process.Persister; import org.olat.modules.ModuleConfiguration; +import org.olat.modules.assessment.Role; import org.olat.modules.iq.IQManager; import org.olat.modules.iq.IQRetrievedEvent; import org.olat.repository.RepositoryEntry; @@ -262,7 +263,7 @@ public class QTI12ResultDetailsController extends BasicController { Boolean passed = new Boolean(ac.isPassed()); ScoreEvaluation sceval = new ScoreEvaluation(score, passed, Boolean.FALSE, new Long(ai.getAssessID())); UserCourseEnvironment userCourseEnv = AssessmentHelper.createAndInitUserCourseEnvironment(assessedIdentity, course); - testNode.updateUserScoreEvaluation(sceval, userCourseEnv, assessedIdentity, true); + testNode.updateUserScoreEvaluation(sceval, userCourseEnv, assessedIdentity, true, Role.coach); //cleanup ai.cleanUp(); diff --git a/src/main/java/org/olat/ims/qti/statistics/ui/QTI12PullTestsToolController.java b/src/main/java/org/olat/ims/qti/statistics/ui/QTI12PullTestsToolController.java index 8a5109464d91aee8b06b5a58d0371db12a5dd397..900258218640013818ddb9509e95aea7a058668e 100644 --- a/src/main/java/org/olat/ims/qti/statistics/ui/QTI12PullTestsToolController.java +++ b/src/main/java/org/olat/ims/qti/statistics/ui/QTI12PullTestsToolController.java @@ -58,6 +58,7 @@ import org.olat.ims.qti.process.AssessmentInstance; import org.olat.ims.qti.process.FilePersister; import org.olat.modules.ModuleConfiguration; import org.olat.modules.assessment.AssessmentToolOptions; +import org.olat.modules.assessment.Role; import org.olat.modules.iq.IQManager; import org.olat.modules.iq.IQRetrievedEvent; import org.olat.user.UserManager; @@ -216,7 +217,7 @@ public class QTI12PullTestsToolController extends BasicController implements Act Boolean passed = new Boolean(ac.isPassed()); ScoreEvaluation sceval = new ScoreEvaluation(score, passed, Boolean.FALSE, new Long(ai.getAssessID())); UserCourseEnvironment userCourseEnv = AssessmentHelper.createAndInitUserCourseEnvironment(assessedIdentity, course); - courseNode.updateUserScoreEvaluation(sceval, userCourseEnv, assessedIdentity, true); + courseNode.updateUserScoreEvaluation(sceval, userCourseEnv, assessedIdentity, true, Role.coach); //cleanup ai.cleanUp(); diff --git a/src/main/java/org/olat/ims/qti21/ui/QTI21AssessmentDetailsController.java b/src/main/java/org/olat/ims/qti21/ui/QTI21AssessmentDetailsController.java index 6cbf6f56dc01a635354553e7302ac3b30945c444..b752b90a0964a392acaeabd033ddfba50a655227 100644 --- a/src/main/java/org/olat/ims/qti21/ui/QTI21AssessmentDetailsController.java +++ b/src/main/java/org/olat/ims/qti21/ui/QTI21AssessmentDetailsController.java @@ -77,6 +77,7 @@ import org.olat.modules.ModuleConfiguration; import org.olat.modules.assessment.AssessmentEntry; import org.olat.modules.assessment.AssessmentService; import org.olat.modules.assessment.AssessmentToolOptions; +import org.olat.modules.assessment.Role; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryManager; import org.olat.repository.model.RepositoryEntrySecurity; @@ -367,7 +368,7 @@ public class QTI21AssessmentDetailsController extends FormBasicController { Float score = finalScore == null ? null : finalScore.floatValue(); ScoreEvaluation manualScoreEval = new ScoreEvaluation(score, scoreEval.getPassed(), scoreEval.getAssessmentStatus(), null, scoreEval.getFullyAssessed(), session.getKey()); - courseNode.updateUserScoreEvaluation(manualScoreEval, assessedUserCourseEnv, getIdentity(), false); + courseNode.updateUserScoreEvaluation(manualScoreEval, assessedUserCourseEnv, getIdentity(), false, Role.coach); } private void doUpdateEntry(AssessmentTestSession session) { diff --git a/src/main/java/org/olat/ims/qti21/ui/QTI21ResetToolController.java b/src/main/java/org/olat/ims/qti21/ui/QTI21ResetToolController.java index 2353e8c1cd9223ba3595a13364b3e90270b4ab7c..99ab6726ce9bffbc021edbb810ea3ee37db2a40c 100644 --- a/src/main/java/org/olat/ims/qti21/ui/QTI21ResetToolController.java +++ b/src/main/java/org/olat/ims/qti21/ui/QTI21ResetToolController.java @@ -63,6 +63,7 @@ import org.olat.ims.qti21.QTI21Service; import org.olat.ims.qti21.manager.archive.QTI21ArchiveFormat; import org.olat.ims.qti21.model.QTI21StatisticSearchParams; import org.olat.modules.assessment.AssessmentToolOptions; +import org.olat.modules.assessment.Role; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryService; import org.springframework.beans.factory.annotation.Autowired; @@ -200,7 +201,7 @@ public class QTI21ResetToolController extends BasicController { ScoreEvaluation scoreEval = new ScoreEvaluation(null, null); IdentityEnvironment ienv = new IdentityEnvironment(identity, studentRoles); UserCourseEnvironment uce = new UserCourseEnvironmentImpl(ienv, courseEnv); - testCourseNode.updateUserScoreEvaluation(scoreEval, uce, getIdentity(), false); + testCourseNode.updateUserScoreEvaluation(scoreEval, uce, getIdentity(), false, Role.coach); } } else if(assessedEntry != null) { archiveData(assessedEntry); diff --git a/src/main/java/org/olat/ims/qti21/ui/assessment/QTI21CorrectionToolController.java b/src/main/java/org/olat/ims/qti21/ui/assessment/QTI21CorrectionToolController.java index d288a34f8f7ac2b13ca1c1d3a03b994a96e24934..4f9369b4f2568534f88db56a394cba0a7fd2204d 100644 --- a/src/main/java/org/olat/ims/qti21/ui/assessment/QTI21CorrectionToolController.java +++ b/src/main/java/org/olat/ims/qti21/ui/assessment/QTI21CorrectionToolController.java @@ -40,6 +40,7 @@ import org.olat.course.run.scoring.ScoreEvaluation; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.ims.qti21.AssessmentTestSession; import org.olat.modules.assessment.AssessmentToolOptions; +import org.olat.modules.assessment.Role; import org.olat.modules.assessment.ui.event.CompleteAssessmentTestSessionEvent; /** @@ -138,7 +139,7 @@ public class QTI21CorrectionToolController extends BasicController { Float score = finalScore == null ? null : finalScore.floatValue(); ScoreEvaluation manualScoreEval = new ScoreEvaluation(score, scoreEval.getPassed(), scoreEval.getAssessmentStatus(), scoreEval.getUserVisible(), scoreEval.getFullyAssessed(), testSession.getKey()); - courseNode.updateUserScoreEvaluation(manualScoreEval, assessedUserCourseEnv, getIdentity(), false); + courseNode.updateUserScoreEvaluation(manualScoreEval, assessedUserCourseEnv, getIdentity(), false, Role.coach); } } } diff --git a/src/main/java/org/olat/modules/assessment/AssessmentEntry.java b/src/main/java/org/olat/modules/assessment/AssessmentEntry.java index 9370b4bcf31aeb62bf091f74b5cf84f8d241bcf1..5228d513d1c4f92abb35fef5e34fd9c6ec078340 100644 --- a/src/main/java/org/olat/modules/assessment/AssessmentEntry.java +++ b/src/main/java/org/olat/modules/assessment/AssessmentEntry.java @@ -40,6 +40,14 @@ public interface AssessmentEntry extends AssessmentEntryLight { public Date getLastModified(); + public Date getLastCoachModified(); + + public void setLastCoachModified(Date date); + + public Date getLastUserModified(); + + public void setLastUserModified(Date date); + public Long getAssessmentId(); public void setAssessmentId(Long assessmentId); diff --git a/src/main/java/org/olat/modules/assessment/AssessmentService.java b/src/main/java/org/olat/modules/assessment/AssessmentService.java index f9b386b069adb0e516ce4b2743b69865bbb588a3..d977c118d2fdf84a0a387713c1423d850ad16f3b 100644 --- a/src/main/java/org/olat/modules/assessment/AssessmentService.java +++ b/src/main/java/org/olat/modules/assessment/AssessmentService.java @@ -19,6 +19,7 @@ */ package org.olat.modules.assessment; +import java.util.Date; import java.util.List; import org.olat.core.id.Identity; @@ -46,7 +47,7 @@ public interface AssessmentService { * @return */ public AssessmentEntry createAssessmentEntry(Identity assessedIdentity, String anonymousIdentifier, - RepositoryEntry entry, String subIdent, RepositoryEntry referenceEntry, Float score, Boolean passed); + RepositoryEntry entry, String subIdent, RepositoryEntry referenceEntry, Float score, Boolean passed, Date lastUserModified, Date lastCoachModified); /** * diff --git a/src/main/java/org/olat/modules/assessment/Role.java b/src/main/java/org/olat/modules/assessment/Role.java new file mode 100644 index 0000000000000000000000000000000000000000..a7cf4ef15bbd1ddedbecf39dabe2f1b089cd2f30 --- /dev/null +++ b/src/main/java/org/olat/modules/assessment/Role.java @@ -0,0 +1,34 @@ +/** + * <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.modules.assessment; + +/** + * Say who has done the changes. + * + * Initial date: 14 août 2017<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public enum Role { + coach, + user, + auto + +} diff --git a/src/main/java/org/olat/modules/assessment/manager/AssessmentEntryDAO.java b/src/main/java/org/olat/modules/assessment/manager/AssessmentEntryDAO.java index 9f5e28d17581aa4e3f9d29a55908e9758c663bb7..298e4564923ecadbcf3c10d5ccdbcf8958d37eb7 100644 --- a/src/main/java/org/olat/modules/assessment/manager/AssessmentEntryDAO.java +++ b/src/main/java/org/olat/modules/assessment/manager/AssessmentEntryDAO.java @@ -68,11 +68,13 @@ public class AssessmentEntryDAO { public AssessmentEntry createAssessmentEntry(Identity assessedIdentity, String anonymousIdentifier, RepositoryEntry entry, String subIdent, RepositoryEntry referenceEntry, - Float score, Boolean passed) { + Float score, Boolean passed, Date lastUserModified, Date lastCoachModified) { AssessmentEntryImpl data = new AssessmentEntryImpl(); data.setCreationDate(new Date()); data.setLastModified(data.getCreationDate()); + data.setLastUserModified(lastUserModified); + data.setLastCoachModified(lastCoachModified); data.setIdentity(assessedIdentity); data.setAnonymousIdentifier(anonymousIdentifier); data.setRepositoryEntry(entry); diff --git a/src/main/java/org/olat/modules/assessment/manager/AssessmentServiceImpl.java b/src/main/java/org/olat/modules/assessment/manager/AssessmentServiceImpl.java index f9f5890f1d6411a2dc44a7305d6f11858d134252..915da459e073a8122b56350b23225b3f46c7c928 100644 --- a/src/main/java/org/olat/modules/assessment/manager/AssessmentServiceImpl.java +++ b/src/main/java/org/olat/modules/assessment/manager/AssessmentServiceImpl.java @@ -21,6 +21,7 @@ package org.olat.modules.assessment.manager; import java.io.File; import java.util.Collections; +import java.util.Date; import java.util.List; import org.olat.core.commons.persistence.DB; @@ -51,8 +52,10 @@ public class AssessmentServiceImpl implements AssessmentService, UserDataDeletab @Override public AssessmentEntry createAssessmentEntry(Identity assessedIdentity, String anonymousIdentifier, - RepositoryEntry entry, String subIdent, RepositoryEntry referenceEntry, Float score, Boolean passed) { - return assessmentEntryDao.createAssessmentEntry(assessedIdentity, anonymousIdentifier, entry, subIdent, referenceEntry, score, passed); + RepositoryEntry entry, String subIdent, RepositoryEntry referenceEntry, + Float score, Boolean passed, Date lastUserModified, Date lastCoachModified) { + return assessmentEntryDao.createAssessmentEntry(assessedIdentity, anonymousIdentifier, entry, subIdent, referenceEntry, + score, passed, lastUserModified, lastCoachModified); } @Override diff --git a/src/main/java/org/olat/modules/assessment/model/AssessmentEntryImpl.java b/src/main/java/org/olat/modules/assessment/model/AssessmentEntryImpl.java index ad69459e5be157e630a71b18b73598c267f14c84..85a223f96ae774f678c940a6ca984c87a646e9a5 100644 --- a/src/main/java/org/olat/modules/assessment/model/AssessmentEntryImpl.java +++ b/src/main/java/org/olat/modules/assessment/model/AssessmentEntryImpl.java @@ -74,6 +74,11 @@ public class AssessmentEntryImpl implements Persistable, ModifiedInfo, CreateInf @Temporal(TemporalType.TIMESTAMP) @Column(name="lastmodified", nullable=false, insertable=true, updatable=true) private Date lastModified; + + @Column(name="lastcoachmodified", nullable=true, insertable=true, updatable=true) + private Date lastCoachModified; + @Column(name="lastusermodified", nullable=true, insertable=true, updatable=true) + private Date lastUserModified; @Column(name="a_attemtps", nullable=true, insertable=true, updatable=true) private Integer attempts; @@ -150,6 +155,24 @@ public class AssessmentEntryImpl implements Persistable, ModifiedInfo, CreateInf this.lastModified = lastModified; } + @Override + public Date getLastCoachModified() { + return lastCoachModified; + } + + public void setLastCoachModified(Date lastCoachModified) { + this.lastCoachModified = lastCoachModified; + } + + @Override + public Date getLastUserModified() { + return lastUserModified; + } + + public void setLastUserModified(Date lastUserModified) { + this.lastUserModified = lastUserModified; + } + @Override public Integer getAttempts() { return attempts; diff --git a/src/main/java/org/olat/modules/assessment/ui/AssessedIdentityElementRow.java b/src/main/java/org/olat/modules/assessment/ui/AssessedIdentityElementRow.java index 603127f241ee8f3a289ea418deb131713766bbbf..133b11cb9d5843bbd083ff10889024cf2cb51be2 100644 --- a/src/main/java/org/olat/modules/assessment/ui/AssessedIdentityElementRow.java +++ b/src/main/java/org/olat/modules/assessment/ui/AssessedIdentityElementRow.java @@ -43,7 +43,7 @@ public class AssessedIdentityElementRow extends UserPropertiesRow { private final BigDecimal score; private final Boolean passed; private final Date initialCourseLaunchDate; - private final Date lastModified; + private final Date lastModified, lastUserModified, lastCoachModified; private final int numOfAssessmentDocs; private final AssessmentEntryStatus status; @@ -57,6 +57,8 @@ public class AssessedIdentityElementRow extends UserPropertiesRow { passed = entry.getPassed(); userVisibility = entry.getUserVisibility(); lastModified = entry.getLastModified(); + lastUserModified = entry.getLastUserModified(); + lastCoachModified = entry.getLastCoachModified(); status = entry.getAssessmentStatus(); numOfAssessmentDocs = entry.getNumberOfAssessmentDocuments(); } else { @@ -64,7 +66,7 @@ public class AssessedIdentityElementRow extends UserPropertiesRow { score = null; passed = null; userVisibility = null; - lastModified = null; + lastModified = lastUserModified = lastCoachModified = null; status = null; numOfAssessmentDocs = 0; } @@ -90,6 +92,14 @@ public class AssessedIdentityElementRow extends UserPropertiesRow { public Date getLastModified() { return lastModified; } + + public Date getLastUserModified() { + return lastUserModified; + } + + public Date getLastCoachModified() { + return lastCoachModified; + } public int getNumOfAssessmentDocs() { return numOfAssessmentDocs; diff --git a/src/main/java/org/olat/modules/assessment/ui/AssessedIdentityListController.java b/src/main/java/org/olat/modules/assessment/ui/AssessedIdentityListController.java index f20d7030d75bd18ac6163ff5b58fcc56f3f08ada..9cc4aafad116dd3b3591bd4f0c30b21429db6859 100644 --- a/src/main/java/org/olat/modules/assessment/ui/AssessedIdentityListController.java +++ b/src/main/java/org/olat/modules/assessment/ui/AssessedIdentityListController.java @@ -172,9 +172,10 @@ public class AssessedIdentityListController extends FormBasicController implemen columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.assessmentStatus, new AssessmentStatusCellRenderer(getLocale()))); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.initialLaunchDate, "select")); - columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.lastScoreUpdate, "select")); - //columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.certificate, new DownloadCertificateCellRenderer())); - + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, IdentityCourseElementCols.lastModified, "select")); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(IdentityCourseElementCols.lastUserModified, "select")); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, IdentityCourseElementCols.lastCoachModified, "select")); + usersTableModel = new AssessedIdentityListTableModel(columnsModel, element); usersTableModel.setCertificateMap(new ConcurrentHashMap<>()); tableEl = uifactory.addTableElement(getWindowControl(), "table", usersTableModel, 20, false, getTranslator(), formLayout); diff --git a/src/main/java/org/olat/modules/assessment/ui/AssessedIdentityListTableModel.java b/src/main/java/org/olat/modules/assessment/ui/AssessedIdentityListTableModel.java index 2c264bb907d5a72def7e5e14c6b39cf07a9c6e44..fb80cfbef5266f1b2d968d608081e50f0ac79070 100644 --- a/src/main/java/org/olat/modules/assessment/ui/AssessedIdentityListTableModel.java +++ b/src/main/java/org/olat/modules/assessment/ui/AssessedIdentityListTableModel.java @@ -137,7 +137,9 @@ public class AssessedIdentityListTableModel extends DefaultFlexiTableDataModel<A return certificateMap.get(row.getIdentityKey()); } case initialLaunchDate: return row.getInitialCourseLaunchDate(); - case lastScoreUpdate: return row.getLastModified(); + case lastModified: return row.getLastModified(); + case lastUserModified: return row.getLastUserModified(); + case lastCoachModified: return row.getLastCoachModified(); } } int propPos = col - AssessmentToolConstants.USER_PROPS_OFFSET; @@ -160,7 +162,9 @@ public class AssessedIdentityListTableModel extends DefaultFlexiTableDataModel<A assessmentStatus("table.header.assessmentStatus"), certificate("table.header.certificate"), initialLaunchDate("table.header.initialLaunchDate"), - lastScoreUpdate("table.header.lastScoreDate"); + lastModified("table.header.lastScoreDate"), + lastUserModified("table.header.lastUserModificationDate"), + lastCoachModified("table.header.lastCoachModificationDate"); private final String i18nKey; diff --git a/src/main/java/org/olat/modules/coach/ui/CourseController.java b/src/main/java/org/olat/modules/coach/ui/CourseController.java index 0e32abda85f61be9f9599e0c39d8385730f38962..9b7f5c422945371dc2a337d2ff186a3ad7cdbb5b 100644 --- a/src/main/java/org/olat/modules/coach/ui/CourseController.java +++ b/src/main/java/org/olat/modules/coach/ui/CourseController.java @@ -200,7 +200,9 @@ public class CourseController extends FormBasicController implements Activateabl columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Columns.recertification, new DateFlexiCellRenderer(getLocale()))); } } - columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Columns.lastModification)); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, Columns.lastModification)); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Columns.lastUserModified)); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, Columns.lastCoachModified)); model = new EfficiencyStatementEntryTableDataModel(columnsModel); tableEl = uifactory.addTableElement(getWindowControl(), "table", model, 20, false, getTranslator(), formLayout); diff --git a/src/main/java/org/olat/modules/coach/ui/EfficiencyStatementEntryTableDataModel.java b/src/main/java/org/olat/modules/coach/ui/EfficiencyStatementEntryTableDataModel.java index e798b68171539a53cccc1b886ca33dd97ca50f53..dd91320d55aa50b0df42eab353ba0139a71dcc4a 100644 --- a/src/main/java/org/olat/modules/coach/ui/EfficiencyStatementEntryTableDataModel.java +++ b/src/main/java/org/olat/modules/coach/ui/EfficiencyStatementEntryTableDataModel.java @@ -119,6 +119,14 @@ public class EfficiencyStatementEntryTableDataModel extends DefaultFlexiTableDat UserEfficiencyStatement s = entry.getUserEfficencyStatement(); return s == null ? null : s.getLastModified(); } + case lastUserModified: { + UserEfficiencyStatement s = entry.getUserEfficencyStatement(); + return s == null ? null : s.getLastUserModified(); + } + case lastCoachModified: { + UserEfficiencyStatement s = entry.getUserEfficencyStatement(); + return s == null ? null : s.getLastCoachModified(); + } case plannedLectures: { LectureBlockStatistics statistics = getLectureBlockStatistics(entry); return statistics == null ? null : statistics.getTotalPersonalPlannedLectures(); @@ -184,6 +192,8 @@ public class EfficiencyStatementEntryTableDataModel extends DefaultFlexiTableDat recertification("table.header.recertification"), progress("table.header.progress"), lastModification("table.header.lastScoreDate"), + lastUserModified("table.header.lastUserModificationDate"), + lastCoachModified("table.header.lastCoachModificationDate"), plannedLectures("table.header.planned.lectures"), attendedLectures("table.header.attended.lectures"), absentLectures("table.header.absent.lectures"), diff --git a/src/main/java/org/olat/modules/coach/ui/GroupController.java b/src/main/java/org/olat/modules/coach/ui/GroupController.java index 8a7d81863e9d16c6b39feb3854e1c8d52b090ad3..34627732203bb1c13e05b2997e542f8185012667 100644 --- a/src/main/java/org/olat/modules/coach/ui/GroupController.java +++ b/src/main/java/org/olat/modules/coach/ui/GroupController.java @@ -192,7 +192,9 @@ public class GroupController extends FormBasicController implements Activateable columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Columns.score, new ScoreCellRenderer())); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Columns.certificate, new DownloadCertificateCellRenderer())); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Columns.recertification, new DateFlexiCellRenderer(getLocale()))); - columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Columns.lastModification)); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, Columns.lastModification)); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Columns.lastUserModified)); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, Columns.lastCoachModified)); model = new EfficiencyStatementEntryTableDataModel(columnsModel); tableEl = uifactory.addTableElement(getWindowControl(), "table", model, 20, false, getTranslator(), formLayout); diff --git a/src/main/java/org/olat/modules/coach/ui/StudentCoursesController.java b/src/main/java/org/olat/modules/coach/ui/StudentCoursesController.java index 1803bf62ab2cfc022376a9f54f9235d7ca1338ac..d4564cc9b1fcd82baf69cf4e8c7cece616d6209e 100644 --- a/src/main/java/org/olat/modules/coach/ui/StudentCoursesController.java +++ b/src/main/java/org/olat/modules/coach/ui/StudentCoursesController.java @@ -216,7 +216,9 @@ public class StudentCoursesController extends FormBasicController implements Act columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Columns.authorizedAbsenceLectures)); } } - columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Columns.lastModification)); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, Columns.lastModification)); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Columns.lastUserModified)); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, Columns.lastCoachModified)); model = new EfficiencyStatementEntryTableDataModel(columnsModel); tableEl = uifactory.addTableElement(getWindowControl(), "table", model, 20, false, getTranslator(), formLayout); diff --git a/src/main/java/org/olat/modules/coach/ui/UserEfficiencyStatementTableDataModel.java b/src/main/java/org/olat/modules/coach/ui/UserEfficiencyStatementTableDataModel.java index a63784518862f8e5e1aec1620f67c5e6c1425d42..a5f39cd2291bc595136a613bc6a7e18793c9a368 100644 --- a/src/main/java/org/olat/modules/coach/ui/UserEfficiencyStatementTableDataModel.java +++ b/src/main/java/org/olat/modules/coach/ui/UserEfficiencyStatementTableDataModel.java @@ -24,7 +24,6 @@ import java.util.List; import org.olat.core.gui.components.table.TableDataModel; import org.olat.course.assessment.UserEfficiencyStatement; -import org.olat.modules.coach.model.EfficiencyStatementEntry; /** * @@ -94,10 +93,6 @@ public class UserEfficiencyStatementTableDataModel implements TableDataModel<Use public UserEfficiencyStatement getObject(int row) { return group.get(row); } - - public int indexOf(EfficiencyStatementEntry obj) { - return group.indexOf(obj); - } @Override public void setObjects(List<UserEfficiencyStatement> objects) { diff --git a/src/main/java/org/olat/modules/coach/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/coach/ui/_i18n/LocalStrings_de.properties index 47ddc78431e1b3fb5d30f72c4a47db1ce6c5f4b0..564727e7aa63b25973e4eab268fc613fb5cb4a28 100644 --- a/src/main/java/org/olat/modules/coach/ui/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/modules/coach/ui/_i18n/LocalStrings_de.properties @@ -54,6 +54,8 @@ table.header.countCourses=# Kurs table.header.countStudents=# Teilnehmer table.header.course.name=Kurs table.header.lastScoreDate=$org.olat.course.assessment\:table.header.lastScoreDate +table.header.lastUserModificationDate=$org.olat.course.assessment\:table.header.lastUserModificationDate +table.header.lastCoachModificationDate=$org.olat.course.assessment\:table.header.lastCoachModificationDate table.header.login=Eingeloggt table.header.passed=$org.olat.course.assessment\:table.header.passed table.header.progress=Fortschritt diff --git a/src/main/java/org/olat/modules/portfolio/BinderSecurityCallback.java b/src/main/java/org/olat/modules/portfolio/BinderSecurityCallback.java index 4ad46daca880590aaa052c8f92827ac40a1e760a..26300b8d25c15b6c4ca6abc1d0304788d46784e4 100644 --- a/src/main/java/org/olat/modules/portfolio/BinderSecurityCallback.java +++ b/src/main/java/org/olat/modules/portfolio/BinderSecurityCallback.java @@ -21,6 +21,8 @@ package org.olat.modules.portfolio; import java.util.List; +import org.olat.modules.assessment.Role; + /** * * Initial date: 15.06.2016<br> @@ -117,6 +119,9 @@ public interface BinderSecurityCallback { public boolean canViewAssess(PortfolioElement element); public boolean canViewAssessment(); + + + public Role getRole(); } diff --git a/src/main/java/org/olat/modules/portfolio/BinderSecurityCallbackFactory.java b/src/main/java/org/olat/modules/portfolio/BinderSecurityCallbackFactory.java index 62c9a07f850ee4de555742f8d61d36f8abe69f1c..d153850d5c7459c551df07f6dea1cc9fa390eb8f 100644 --- a/src/main/java/org/olat/modules/portfolio/BinderSecurityCallbackFactory.java +++ b/src/main/java/org/olat/modules/portfolio/BinderSecurityCallbackFactory.java @@ -23,6 +23,7 @@ import java.util.Collections; import java.util.List; import org.olat.core.CoreSpringFactory; +import org.olat.modules.assessment.Role; import org.olat.modules.portfolio.model.AccessRights; import org.olat.repository.model.RepositoryEntrySecurity; @@ -102,7 +103,12 @@ public class BinderSecurityCallbackFactory { public boolean canRestorePage(Page page) { return page.getPageStatus() == PageStatus.deleted; } - + + @Override + public Role getRole() { + return Role.user; + } + } private static class BinderSecurityCallbackForDeletedBinder extends DefaultBinderSecurityCallback { @@ -680,6 +686,11 @@ public class BinderSecurityCallbackFactory { } return false; } + + @Override + public Role getRole() { + return owner ? Role.user : Role.coach; + } } private static class DefaultBinderSecurityCallback implements BinderSecurityCallback { @@ -842,6 +853,11 @@ public class BinderSecurityCallbackFactory { @Override public boolean canViewAssessment() { return false; - } + } + + @Override + public Role getRole() { + return Role.coach; + } } } \ No newline at end of file diff --git a/src/main/java/org/olat/modules/portfolio/PortfolioService.java b/src/main/java/org/olat/modules/portfolio/PortfolioService.java index 2d2e632c2ae86f4b73618de959419c17cda46e09..09f5a4e6a1e61079916c92debda50457a4129c08 100644 --- a/src/main/java/org/olat/modules/portfolio/PortfolioService.java +++ b/src/main/java/org/olat/modules/portfolio/PortfolioService.java @@ -28,6 +28,7 @@ import java.util.Map; import org.olat.basesecurity.IdentityRef; import org.olat.core.id.Identity; import org.olat.core.util.vfs.VFSLeaf; +import org.olat.modules.assessment.Role; import org.olat.modules.assessment.model.AssessmentEntryStatus; import org.olat.modules.portfolio.model.AccessRightChange; import org.olat.modules.portfolio.model.AccessRights; @@ -544,9 +545,11 @@ public interface PortfolioService { * Change the status of the page. * @param page * @param status + * @param identity The user which does the change + * @param by The role of the user which does the change * @return */ - public Page changePageStatus(Page page, PageStatus status); + public Page changePageStatus(Page page, PageStatus status, Identity identity, Role by); /** * Close the section diff --git a/src/main/java/org/olat/modules/portfolio/manager/PortfolioServiceImpl.java b/src/main/java/org/olat/modules/portfolio/manager/PortfolioServiceImpl.java index 18de9c42d1512561ab8b263d925b9c7476a75dd8..7e5a0667a7baf211ebed69b8c77880a059ef0838 100644 --- a/src/main/java/org/olat/modules/portfolio/manager/PortfolioServiceImpl.java +++ b/src/main/java/org/olat/modules/portfolio/manager/PortfolioServiceImpl.java @@ -61,6 +61,7 @@ import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.fileresource.FileResourceManager; import org.olat.modules.assessment.AssessmentEntry; import org.olat.modules.assessment.AssessmentService; +import org.olat.modules.assessment.Role; import org.olat.modules.assessment.model.AssessmentEntryStatus; import org.olat.modules.forms.EvaluationFormSessionStatus; import org.olat.modules.forms.manager.EvaluationFormSessionDAO; @@ -1030,7 +1031,7 @@ public class PortfolioServiceImpl implements PortfolioService { } @Override - public Page changePageStatus(Page page, PageStatus status) { + public Page changePageStatus(Page page, PageStatus status, Identity identity, Role by) { PageStatus currentStatus = page.getPageStatus(); Page reloadedPage = pageDao.loadByKey(page.getKey()); ((PageImpl)reloadedPage).setPageStatus(status); @@ -1069,6 +1070,11 @@ public class PortfolioServiceImpl implements PortfolioService { } } } + if(reloadedPage.getSection() != null && reloadedPage.getSection().getBinder() != null) { + Binder binder = reloadedPage.getSection().getBinder(); + updateAssessmentEntryLastModification(binder, identity, by); + } + return pageDao.updatePage(reloadedPage); } @@ -1117,6 +1123,39 @@ public class PortfolioServiceImpl implements PortfolioService { reloadedSection = binderDao.updateSection(reloadedSection); return reloadedSection; } + + private void updateAssessmentEntryLastModification(Binder binder, Identity doer, Role by) { + if(binder.getEntry() == null) return; + + RepositoryEntry entry = binder.getEntry(); + List<Identity> assessedIdentities = getMembers(binder, PortfolioRoles.owner.name()); + + //order status from the entry / section + if("CourseModule".equals(entry.getOlatResource().getResourceableTypeName())) { + ICourse course = CourseFactory.loadCourse(entry); + CourseNode courseNode = course.getRunStructure().getNode(binder.getSubIdent()); + if(courseNode instanceof PortfolioCourseNode) { + PortfolioCourseNode pfNode = (PortfolioCourseNode)courseNode; + for(Identity assessedIdentity:assessedIdentities) { + UserCourseEnvironment userCourseEnv = AssessmentHelper.createAndInitUserCourseEnvironment(assessedIdentity, course); + pfNode.updateLastModifications(userCourseEnv, doer, by); + } + } + } else { + OLATResource resource = ((BinderImpl)binder.getTemplate()).getOlatResource(); + RepositoryEntry referenceEntry = repositoryService.loadByResourceKey(resource.getKey()); + for(Identity assessedIdentity:assessedIdentities) { + AssessmentEntry assessmentEntry = assessmentService + .getOrCreateAssessmentEntry(assessedIdentity, null, binder.getEntry(), binder.getSubIdent(), referenceEntry); + if(by == Role.coach) { + assessmentEntry.setLastCoachModified(new Date()); + } else if(by == Role.user) { + assessmentEntry.setLastUserModified(new Date()); + } + assessmentService.updateAssessmentEntry(assessmentEntry); + } + } + } @Override public List<AssessmentSection> getAssessmentSections(BinderRef binder, Identity coach) { @@ -1212,7 +1251,7 @@ public class PortfolioServiceImpl implements PortfolioService { PortfolioCourseNode pfNode = (PortfolioCourseNode)courseNode; ScoreEvaluation scoreEval= new ScoreEvaluation(totalScore.floatValue(), totalPassed, binderStatus, true, true, binder.getKey()); UserCourseEnvironment userCourseEnv = AssessmentHelper.createAndInitUserCourseEnvironment(assessedIdentity, course); - pfNode.updateUserScoreEvaluation(scoreEval, userCourseEnv, coachingIdentity, false); + pfNode.updateUserScoreEvaluation(scoreEval, userCourseEnv, coachingIdentity, false, Role.coach); } } else { OLATResource resource = ((BinderImpl)binder.getTemplate()).getOlatResource(); @@ -1268,7 +1307,7 @@ public class PortfolioServiceImpl implements PortfolioService { AssessmentEvaluation eval = pfNode.getUserScoreEvaluation(userCourseEnv); ScoreEvaluation scoreEval= new ScoreEvaluation(eval.getScore(), eval.getPassed(), status, true, fullyAssessed, binder.getKey()); - pfNode.updateUserScoreEvaluation(scoreEval, userCourseEnv, coachingIdentity, false); + pfNode.updateUserScoreEvaluation(scoreEval, userCourseEnv, coachingIdentity, false, Role.coach); } } else { OLATResource resource = ((BinderImpl)binder.getTemplate()).getOlatResource(); diff --git a/src/main/java/org/olat/modules/portfolio/ui/BinderListController.java b/src/main/java/org/olat/modules/portfolio/ui/BinderListController.java index 6e6327a8d2448322c378a4aff39b352a51c611da..74295bb0d76d5fa5491959bf7e1bc8c7f73bae5e 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/BinderListController.java +++ b/src/main/java/org/olat/modules/portfolio/ui/BinderListController.java @@ -397,12 +397,12 @@ public class BinderListController extends FormBasicController if(binder.isChanged()) { showInfo("warning.binder.synched"); } - BinderController binderCtrl = doOpenBinder(ureq, binder.getBinder()); + BinderController selectedBinderCtrl = doOpenBinder(ureq, binder.getBinder()); if(row instanceof BinderRow) { VFSLeaf image = portfolioService.getPosterImageLeaf(binder.getBinder()); ((BinderRow)row).setBackgroundImage(image); } - return binderCtrl; + return selectedBinderCtrl; } protected BinderController doOpenBinder(UserRequest ureq, Binder binder) { diff --git a/src/main/java/org/olat/modules/portfolio/ui/PageRunController.java b/src/main/java/org/olat/modules/portfolio/ui/PageRunController.java index 8396e02beb44eacacf2e0e22459193fba40ce586..918f95d3573457c0fa4eae74cb5a632b486b7b3d 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/PageRunController.java +++ b/src/main/java/org/olat/modules/portfolio/ui/PageRunController.java @@ -396,7 +396,7 @@ public class PageRunController extends BasicController implements TooledControll } private void doPublish(UserRequest ureq) { - page = portfolioService.changePageStatus(page, PageStatus.published); + page = portfolioService.changePageStatus(page, PageStatus.published, getIdentity(), secCallback.getRole()); stackPanel.popUpToController(this); loadMeta(ureq); loadModel(ureq, false); @@ -412,7 +412,7 @@ public class PageRunController extends BasicController implements TooledControll } private void doRevision(UserRequest ureq) { - page = portfolioService.changePageStatus(page, PageStatus.inRevision); + page = portfolioService.changePageStatus(page, PageStatus.inRevision, getIdentity(), secCallback.getRole()); stackPanel.popUpToController(this); loadMeta(ureq); loadModel(ureq, false); @@ -426,7 +426,7 @@ public class PageRunController extends BasicController implements TooledControll } private void doClose(UserRequest ureq) { - page = portfolioService.changePageStatus(page, PageStatus.closed); + page = portfolioService.changePageStatus(page, PageStatus.closed, getIdentity(), secCallback.getRole()); stackPanel.popUpToController(this); loadMeta(ureq); loadModel(ureq, true); @@ -440,7 +440,7 @@ public class PageRunController extends BasicController implements TooledControll } private void doReopen(UserRequest ureq) { - page = portfolioService.changePageStatus(page, PageStatus.published); + page = portfolioService.changePageStatus(page, PageStatus.published, getIdentity(), secCallback.getRole()); stackPanel.popUpToController(this); loadMeta(ureq); loadModel(ureq, true); diff --git a/src/main/java/org/olat/modules/portfolio/ui/RestorePageController.java b/src/main/java/org/olat/modules/portfolio/ui/RestorePageController.java index d0ed978cba332eb5caef7d2ed7e78dace59c70e2..a12e31ca98fd9ccd70106eb5656865699abbbfc8 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/RestorePageController.java +++ b/src/main/java/org/olat/modules/portfolio/ui/RestorePageController.java @@ -33,6 +33,7 @@ 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.util.StringHelper; +import org.olat.modules.assessment.Role; import org.olat.modules.portfolio.Binder; import org.olat.modules.portfolio.Page; import org.olat.modules.portfolio.PageStatus; @@ -158,7 +159,7 @@ public class RestorePageController extends FormBasicController { @Override protected void formOK(UserRequest ureq) { - page = portfolioService.changePageStatus(page, PageStatus.draft); + page = portfolioService.changePageStatus(page, PageStatus.draft, getIdentity(), Role.user); SectionRef selectSection = getSelectedSection(); if((page.getSection() == null && selectSection != null) || diff --git a/src/main/java/org/olat/modules/portfolio/ui/media/StandardEditMediaController.java b/src/main/java/org/olat/modules/portfolio/ui/media/StandardEditMediaController.java index df215148b59a893917a1c989312af598342e0a9a..7d0e4038050fade721454e39af01feb921a23c2e 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/media/StandardEditMediaController.java +++ b/src/main/java/org/olat/modules/portfolio/ui/media/StandardEditMediaController.java @@ -54,7 +54,6 @@ public class StandardEditMediaController extends FormBasicController { private TextBoxListElement categoriesEl; private Media mediaReference; - private final String businessPath; private Map<String,String> categories = new HashMap<>(); @Autowired @@ -63,7 +62,6 @@ public class StandardEditMediaController extends FormBasicController { public StandardEditMediaController(UserRequest ureq, WindowControl wControl, Media media) { super(ureq, wControl); setTranslator(Util.createPackageTranslator(PortfolioHomeController.class, getLocale(), getTranslator())); - businessPath = media.getBusinessPath(); mediaReference = media; List<Category> categoryList = portfolioService.getCategories(media); diff --git a/src/main/java/org/olat/modules/scorm/ScormAPIMapper.java b/src/main/java/org/olat/modules/scorm/ScormAPIMapper.java index 6454c4021d080df9116d824e8e29d84bea50a7a9..3a41494cb6fde67267eee3e222319df64a749b79 100644 --- a/src/main/java/org/olat/modules/scorm/ScormAPIMapper.java +++ b/src/main/java/org/olat/modules/scorm/ScormAPIMapper.java @@ -55,6 +55,7 @@ import org.olat.course.run.scoring.ScoreEvaluation; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.course.run.userview.UserCourseEnvironmentImpl; import org.olat.modules.ModuleConfiguration; +import org.olat.modules.assessment.Role; import org.olat.user.UserManager; /** @@ -199,14 +200,14 @@ public class ScormAPIMapper implements Mapper, ScormAPICallback, Serializable { // </OLATEE-27> boolean increment = !attemptsIncremented && finish; ScoreEvaluation sceval = new ScoreEvaluation(new Float(0.0f), Boolean.valueOf(passed)); - scormNode.updateUserScoreEvaluation(sceval, userCourseEnv, identity, increment); + scormNode.updateUserScoreEvaluation(sceval, userCourseEnv, identity, increment, Role.user); if(increment) { attemptsIncremented = true; } } else if (!config.getBooleanSafe(ScormEditController.CONFIG_ATTEMPTSDEPENDONSCORE, false)) { boolean increment = !attemptsIncremented && finish; ScoreEvaluation sceval = scormNode.getUserScoreEvaluation(userCourseEnv); - scormNode.updateUserScoreEvaluation(sceval, userCourseEnv, identity, increment); + scormNode.updateUserScoreEvaluation(sceval, userCourseEnv, identity, increment, Role.user); if(increment) { attemptsIncremented = true; } @@ -214,7 +215,7 @@ public class ScormAPIMapper implements Mapper, ScormAPICallback, Serializable { } else { boolean increment = !attemptsIncremented && finish; ScoreEvaluation sceval = new ScoreEvaluation(new Float(0.0f), Boolean.valueOf(passed)); - scormNode.updateUserScoreEvaluation(sceval, userCourseEnv, identity, false); + scormNode.updateUserScoreEvaluation(sceval, userCourseEnv, identity, false, Role.user); if(increment) { attemptsIncremented = true; } @@ -254,14 +255,14 @@ public class ScormAPIMapper implements Mapper, ScormAPICallback, Serializable { // </OLATEE-27> boolean increment = !attemptsIncremented && finish; ScoreEvaluation sceval = new ScoreEvaluation(new Float(score), Boolean.valueOf(passed)); - scormNode.updateUserScoreEvaluation(sceval, userCourseEnv, identity, increment); + scormNode.updateUserScoreEvaluation(sceval, userCourseEnv, identity, increment, Role.user); if(increment) { attemptsIncremented = true; } } else if (!config.getBooleanSafe(ScormEditController.CONFIG_ATTEMPTSDEPENDONSCORE, false)) { boolean increment = !attemptsIncremented && finish; ScoreEvaluation sceval = scormNode.getUserScoreEvaluation(userCourseEnv); - scormNode.updateUserScoreEvaluation(sceval, userCourseEnv, identity, increment); + scormNode.updateUserScoreEvaluation(sceval, userCourseEnv, identity, increment, Role.user); if(increment) { attemptsIncremented = true; } @@ -274,7 +275,7 @@ public class ScormAPIMapper implements Mapper, ScormAPICallback, Serializable { // </OLATEE-27> boolean increment = !attemptsIncremented && finish; ScoreEvaluation sceval = new ScoreEvaluation(new Float(score), Boolean.valueOf(passed)); - scormNode.updateUserScoreEvaluation(sceval, userCourseEnv, identity, false); + scormNode.updateUserScoreEvaluation(sceval, userCourseEnv, identity, false, Role.user); if(increment) { attemptsIncremented = true; } diff --git a/src/main/java/org/olat/portfolio/manager/EPFrontendManager.java b/src/main/java/org/olat/portfolio/manager/EPFrontendManager.java index 694ee888bb3489b39211e029b18b0915d2f21328..1fa0c11ea1a99dcb2dc711c724d3a47d7608f5c2 100755 --- a/src/main/java/org/olat/portfolio/manager/EPFrontendManager.java +++ b/src/main/java/org/olat/portfolio/manager/EPFrontendManager.java @@ -54,6 +54,7 @@ import org.olat.course.run.userview.UserCourseEnvironmentImpl; import org.olat.group.BusinessGroup; import org.olat.group.DeletableGroupData; import org.olat.modules.assessment.AssessmentService; +import org.olat.modules.assessment.Role; import org.olat.modules.assessment.model.AssessmentEntryStatus; import org.olat.modules.webFeed.portfolio.LiveBlogArtefactHandler; import org.olat.portfolio.PortfolioModule; @@ -1148,10 +1149,10 @@ public class EPFrontendManager implements UserDataDeletable, DeletableGroupData * @param map */ public void submitMap(PortfolioStructureMap map) { - submitMap(map, true); + submitMap(map, true, Role.user); } - private void submitMap(PortfolioStructureMap map, boolean logActivity) { + private void submitMap(PortfolioStructureMap map, boolean logActivity, Role by) { if(!(map instanceof EPStructuredMap)) return;//add an exception EPStructuredMap submittedMap = (EPStructuredMap)map; @@ -1170,7 +1171,7 @@ public class EPFrontendManager implements UserDataDeletable, DeletableGroupData ienv.setIdentity(owner); UserCourseEnvironment uce = new UserCourseEnvironmentImpl(ienv, course.getCourseEnvironment()); if(logActivity) { - am.incrementNodeAttempts(courseNode, owner, uce); + am.incrementNodeAttempts(courseNode, owner, uce, by); } else { am.incrementNodeAttemptsInBackground(courseNode, owner, uce); } @@ -1192,7 +1193,7 @@ public class EPFrontendManager implements UserDataDeletable, DeletableGroupData List<PortfolioStructureMap> mapsToClose = structureManager.getOpenStructuredMapAfterDeadline(); int count = 0; for(PortfolioStructureMap mapToClose:mapsToClose) { - submitMap(mapToClose, false); + submitMap(mapToClose, false, Role.auto); if(count % 5 == 0) { // this possibly takes longer than connection timeout, so do intermediatecommits. dbInstance.intermediateCommit(); diff --git a/src/main/java/org/olat/restapi/repository/course/CourseAssessmentWebService.java b/src/main/java/org/olat/restapi/repository/course/CourseAssessmentWebService.java index 179c2290e97df3d6e8e5cac796176015e8d9838f..7f9fc07dec0d4c66d5e7ee150cbaa8d4e49ca53b 100644 --- a/src/main/java/org/olat/restapi/repository/course/CourseAssessmentWebService.java +++ b/src/main/java/org/olat/restapi/repository/course/CourseAssessmentWebService.java @@ -80,6 +80,7 @@ import org.olat.ims.qti.navigator.Navigator; import org.olat.ims.qti.process.AssessmentFactory; import org.olat.ims.qti.process.AssessmentInstance; import org.olat.modules.ModuleConfiguration; +import org.olat.modules.assessment.Role; import org.olat.modules.iq.IQManager; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryManager; @@ -329,7 +330,7 @@ public class CourseAssessmentWebService { } else { AssessableCourseNode assessableNode = (AssessableCourseNode) node; ScoreEvaluation scoreEval = new ScoreEvaluation(resultsVO.getScore(), Boolean.TRUE, Boolean.TRUE, new Long(nodeKey));//not directly pass this key - assessableNode.updateUserScoreEvaluation(scoreEval, userCourseEnvironment, requestIdentity, true); + assessableNode.updateUserScoreEvaluation(scoreEval, userCourseEnvironment, requestIdentity, true, Role.coach); } CourseFactory.saveCourseEditorTreeModel(course.getResourceableId()); @@ -440,7 +441,7 @@ public class CourseAssessmentWebService { AssessableCourseNode acn = (AssessableCourseNode) courseNode; // assessment nodes are assessable boolean incrementUserAttempts = true; - acn.updateUserScoreEvaluation(sceval, userCourseEnv, identity, incrementUserAttempts); + acn.updateUserScoreEvaluation(sceval, userCourseEnv, identity, incrementUserAttempts, Role.coach); } else { log.error("Result set already saved"); } diff --git a/src/main/java/org/olat/upgrade/OLATUpgrade_12_0_0.java b/src/main/java/org/olat/upgrade/OLATUpgrade_12_0_0.java index ce7fa7090f3e79f89ec0446f174ffe6c7f52da46..4cb4d3151e53ab4a467e774614b4516b26bfc4af 100644 --- a/src/main/java/org/olat/upgrade/OLATUpgrade_12_0_0.java +++ b/src/main/java/org/olat/upgrade/OLATUpgrade_12_0_0.java @@ -26,14 +26,44 @@ import java.io.InputStream; import java.io.OutputStream; import java.nio.file.Paths; import java.util.Arrays; +import java.util.Calendar; +import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Properties; +import java.util.Set; +import org.olat.core.commons.modules.bc.FolderConfig; import org.olat.core.commons.persistence.DB; +import org.olat.core.id.Identity; +import org.olat.core.id.Roles; import org.olat.core.util.WebappHelper; +import org.olat.course.CorruptedCourseException; +import org.olat.course.CourseFactory; +import org.olat.course.ICourse; +import org.olat.course.assessment.AssessmentHelper; +import org.olat.course.assessment.manager.EfficiencyStatementManager; +import org.olat.course.assessment.model.UserEfficiencyStatementImpl; +import org.olat.course.nodes.CourseNode; +import org.olat.course.nodes.IQTESTCourseNode; +import org.olat.course.nodes.MSCourseNode; +import org.olat.course.nodes.ScormCourseNode; +import org.olat.course.nodes.iq.IQEditController; +import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.fileresource.types.BlogFileResource; +import org.olat.fileresource.types.ImsQTI21Resource; import org.olat.fileresource.types.PodcastFileResource; +import org.olat.ims.qti.QTIResultSet; +import org.olat.ims.qti21.AssessmentTestSession; +import org.olat.ims.qti21.QTI21Service; +import org.olat.modules.assessment.AssessmentService; +import org.olat.modules.assessment.model.AssessmentEntryImpl; +import org.olat.modules.iq.IQManager; import org.olat.modules.webFeed.manager.FeedManager; +import org.olat.repository.RepositoryEntry; +import org.olat.repository.RepositoryEntryRef; +import org.olat.repository.RepositoryManager; +import org.olat.repository.model.SearchRepositoryEntryParameters; import org.olat.resource.OLATResource; import org.olat.resource.OLATResourceManager; import org.springframework.beans.factory.annotation.Autowired; @@ -46,14 +76,27 @@ import org.springframework.beans.factory.annotation.Autowired; */ public class OLATUpgrade_12_0_0 extends OLATUpgrade { + private static final int BATCH_SIZE = 50; + private static final String VERSION = "OLAT_12.0.0"; private static final String FEED_XML_TO_DB = "FEED XML TO DB"; private static final String USER_PROPERTY_CONTEXT_RENAME = "USER PROPERTY CONTEXT RENAME"; + private static final String LAST_USER_MODIFICATION = "LAST USER MODIFICATION"; @Autowired private DB dbInstance; @Autowired - FeedManager feedManager; + private FeedManager feedManager; + @Autowired + private QTI21Service qtiService; + @Autowired + private IQManager iqManager; + @Autowired + private AssessmentService assessmentService; + @Autowired + private RepositoryManager repositoryManager; + @Autowired + private EfficiencyStatementManager efficiencyStatementManager; public OLATUpgrade_12_0_0() { super(); @@ -84,6 +127,7 @@ public class OLATUpgrade_12_0_0 extends OLATUpgrade { allOk &= upgradeBlogXmlToDb(upgradeManager, uhd); // rename a user property context name to a more suitable name allOk &= changeUserPropertyContextName(upgradeManager, uhd); + allOk &= upgradeLastModified(upgradeManager, uhd); uhd.setInstallationComplete(allOk); upgradeManager.setUpgradesHistory(uhd, VERSION); @@ -181,5 +225,176 @@ public class OLATUpgrade_12_0_0 extends OLATUpgrade { } return allOk; } + + private boolean upgradeLastModified(UpgradeManager upgradeManager, UpgradeHistoryData uhd) { + boolean allOk = true; + if (!uhd.getBooleanDataValue(LAST_USER_MODIFICATION)) { + + int counter = 0; + final Roles roles = new Roles(true, true, true, true, false, true, false); + final SearchRepositoryEntryParameters params = new SearchRepositoryEntryParameters(); + params.setRoles(roles); + params.setResourceTypes(Collections.singletonList("CourseModule")); + + List<RepositoryEntry> courses; + do { + courses = repositoryManager.genericANDQueryWithRolesRestriction(params, counter, 50, true); + for(RepositoryEntry course:courses) { + try { + allOk &= processCourseAssessmentLastModified(course); + } catch (CorruptedCourseException e) { + log.error("Corrupted course: " + course.getKey(), e); + } + } + counter += courses.size(); + log.audit("Last modifications migration processed: " + courses.size() + ", total courses processed (" + counter + ")"); + dbInstance.commitAndCloseSession(); + } while(courses.size() == BATCH_SIZE); + + + uhd.setBooleanDataValue(LAST_USER_MODIFICATION, allOk); + upgradeManager.setUpgradesHistory(uhd, VERSION); + } + return allOk; + } + + + private boolean processCourseAssessmentLastModified(RepositoryEntry entry) { + try { + ICourse course = CourseFactory.loadCourse(entry); + CourseNode rootNode = course.getRunStructure().getRootNode(); + Set<Identity> changeSet = new HashSet<>(); + processCourseNodeAssessmentLastModified(course, entry, rootNode, changeSet); + dbInstance.commitAndCloseSession(); + + //update structure nodes and efficiency statement if any + Set<Identity> identitiesWithEfficiencyStatements = findIdentitiesWithEfficiencyStatements(entry); + for(Identity assessedIdentity:changeSet) { + UserCourseEnvironment userCourseEnv = AssessmentHelper + .createInitAndUpdateUserCourseEnvironment(assessedIdentity, course); + if(identitiesWithEfficiencyStatements.contains(assessedIdentity)) { + efficiencyStatementManager.updateUserEfficiencyStatement(userCourseEnv); + } + dbInstance.commitAndCloseSession(); + } + } catch(CorruptedCourseException e) { + log.error("Corrupted course: " + entry.getKey(), e); + } catch (Exception e) { + log.error("Unexpected error", e); + } finally { + dbInstance.commitAndCloseSession(); + } + return true; + } + + private boolean processCourseNodeAssessmentLastModified(ICourse course, RepositoryEntry entry, CourseNode courseNode, Set<Identity> changeSet) { + if(courseNode instanceof IQTESTCourseNode) { + updateTest(entry, (IQTESTCourseNode)courseNode, changeSet); + } else if(courseNode instanceof MSCourseNode) { + updateMS(entry, courseNode, changeSet); + } else if(courseNode instanceof ScormCourseNode) { + updateScorm(course, entry, courseNode, changeSet); + } + dbInstance.commitAndCloseSession(); + + for(int i=courseNode.getChildCount(); i-->0; ) { + CourseNode child = (CourseNode)courseNode.getChildAt(i); + processCourseNodeAssessmentLastModified(course, entry, child, changeSet); + } + return true; + } + + private void updateTest(RepositoryEntry entry, IQTESTCourseNode courseNode, Set<Identity> changeSet) { + boolean onyx = IQEditController.CONFIG_VALUE_QTI2.equals(courseNode.getModuleConfiguration().get(IQEditController.CONFIG_KEY_TYPE_QTI)); + if (onyx) return; + + RepositoryEntry testEntry = courseNode.getReferencedRepositoryEntry(); + OLATResource ores = testEntry.getOlatResource(); + boolean qti21 = ImsQTI21Resource.TYPE_NAME.equals(ores.getResourceableTypeName()); + List<AssessmentEntryImpl> assessmentEntries = loadAssessmentEntries(entry, courseNode.getIdent()); + for(AssessmentEntryImpl assessmentEntry:assessmentEntries) { + if(assessmentEntry.getLastUserModified() != null || assessmentEntry.getLastCoachModified() != null) continue; + + if(qti21) { + Long assessmentId = assessmentEntry.getAssessmentId(); + if(assessmentId != null) { + AssessmentTestSession session = qtiService.getAssessmentTestSession(assessmentEntry.getAssessmentId()); + if(session != null && session.getFinishTime() != null) { + assessmentEntry.setLastUserModified(session.getFinishTime()); + assessmentService.updateAssessmentEntry(assessmentEntry); + changeSet.add(assessmentEntry.getIdentity()); + } + } + } else { + long olatResource = entry.getOlatResource().getResourceableId().longValue(); + QTIResultSet rset = iqManager.getLastResultSet(assessmentEntry.getIdentity(), olatResource, courseNode.getIdent()); + if(rset != null && rset.getLastModified() != null ) { + assessmentEntry.setLastUserModified(rset.getLastModified()); + assessmentService.updateAssessmentEntry(assessmentEntry); + changeSet.add(assessmentEntry.getIdentity()); + } + } + } + } + + private void updateMS(RepositoryEntry entry, CourseNode msNode, Set<Identity> changeSet) { + List<AssessmentEntryImpl> assessmentEntries = loadAssessmentEntries(entry, msNode.getIdent()); + for(AssessmentEntryImpl assessmentEntry:assessmentEntries) { + if(assessmentEntry.getLastCoachModified() != null) continue; + + assessmentEntry.setLastCoachModified(assessmentEntry.getLastModified()); + assessmentService.updateAssessmentEntry(assessmentEntry); + changeSet.add(assessmentEntry.getIdentity()); + } + } + + private void updateScorm(ICourse course, RepositoryEntry entry, CourseNode scormNode, Set<Identity> changeSet) { + Long courseId = course.getResourceableId(); + String courseIdNodeId = courseId + "-" + scormNode.getIdent(); + Calendar cal = Calendar.getInstance(); + + List<AssessmentEntryImpl> assessmentEntries = loadAssessmentEntries(entry, scormNode.getIdent()); + for(AssessmentEntryImpl assessmentEntry:assessmentEntries) { + if(assessmentEntry.getLastUserModified() != null || assessmentEntry.getLastCoachModified() != null) continue; + + String userId = assessmentEntry.getIdentity().getName(); + String path = FolderConfig.getCanonicalRoot() + "/scorm/" + userId + "/" + courseIdNodeId; + File quiz = new File(path, "thequiz.xml"); + if(quiz.exists()) { + long lastModified = quiz.lastModified(); + if(lastModified > 0) { + cal.setTimeInMillis(lastModified); + assessmentEntry.setLastUserModified(cal.getTime()); + assessmentService.updateAssessmentEntry(assessmentEntry); + changeSet.add(assessmentEntry.getIdentity()); + } + } + } + } + + private List<AssessmentEntryImpl> loadAssessmentEntries(RepositoryEntryRef courseEntry, String subIdent) { + StringBuilder sb = new StringBuilder(); + sb.append("select data from assessmententry data") + .append(" inner join fetch data.identity ident") + .append(" where data.repositoryEntry.key=:courseEntryKey and data.subIdent=:subIdent") + .append(" and data.lastUserModified is null and data.lastCoachModified is null"); + return dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), AssessmentEntryImpl.class) + .setParameter("courseEntryKey", courseEntry.getKey()) + .setParameter("subIdent", subIdent) + .getResultList(); + } + + private Set<Identity> findIdentitiesWithEfficiencyStatements(RepositoryEntryRef courseRepoEntry) { + StringBuilder sb = new StringBuilder(); + sb.append("select distinct(statement.identity) from ").append(UserEfficiencyStatementImpl.class.getName()).append(" as statement ") + .append(" where statement.lastUserModified is null and statement.lastCoachModified is null and statement.courseRepoKey=:repoKey"); + + List<Identity> identities = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), Identity.class) + .setParameter("repoKey", courseRepoEntry.getKey()) + .getResultList(); + return new HashSet<>(identities); + } } diff --git a/src/main/java/org/olat/upgrade/OLATUpgrade_8_1_0.java b/src/main/java/org/olat/upgrade/OLATUpgrade_8_1_0.java index 0584402f61706c3c384ae6ecd2efa6926b33f91c..30e7b4ff2dc318ee63ccd98dcb0d895cdb223cbe 100644 --- a/src/main/java/org/olat/upgrade/OLATUpgrade_8_1_0.java +++ b/src/main/java/org/olat/upgrade/OLATUpgrade_8_1_0.java @@ -173,7 +173,7 @@ public class OLATUpgrade_8_1_0 extends OLATUpgrade { } EfficiencyStatement s = (EfficiencyStatement)XStreamHelper.createXStreamInstance().fromXML(property.getTextValue()); - efficiencyStatementManager.fillEfficiencyStatement(s, statement); + efficiencyStatementManager.fillEfficiencyStatement(s, null, statement); statement.setLastModified(property.getLastModified()); dbInstance.saveObject(statement); diff --git a/src/main/resources/database/mysql/alter_11_5_x_to_12_0_0.sql b/src/main/resources/database/mysql/alter_11_5_x_to_12_0_0.sql index 1cbc01a36778b603419ba6715a07bbea0e0f5dbe..84b3cf4b96a3d6cc1e1f7dce914f5884d81dbb7c 100644 --- a/src/main/resources/database/mysql/alter_11_5_x_to_12_0_0.sql +++ b/src/main/resources/database/mysql/alter_11_5_x_to_12_0_0.sql @@ -255,4 +255,10 @@ alter table o_gta_task add constraint gtaskreset_to_allower_idx foreign key (fk_ alter table o_info_message add column attachmentpath varchar(1024) default null; +alter table o_as_entry add column lastcoachmodified datetime default null; +alter table o_as_entry add column lastusermodified datetime default null; + +alter table o_as_eff_statement add column lastcoachmodified datetime default null; +alter table o_as_eff_statement add column lastusermodified datetime default null; + diff --git a/src/main/resources/database/mysql/setupDatabase.sql b/src/main/resources/database/mysql/setupDatabase.sql index 4b21ab2d9dfcd27c0cbd4416209151e4320eb468..9d66eadc414e6989775b8d0569e14bf5553cdf18 100644 --- a/src/main/resources/database/mysql/setupDatabase.sql +++ b/src/main/resources/database/mysql/setupDatabase.sql @@ -1127,6 +1127,8 @@ create table if not exists o_as_eff_statement ( id bigint not null, version mediumint unsigned not null, lastmodified datetime, + lastcoachmodified datetime, + lastusermodified datetime, creationdate datetime, passed bit default null, score float(65,30), @@ -1161,6 +1163,8 @@ create table o_as_entry ( id bigint not null auto_increment, creationdate datetime not null, lastmodified datetime not null, + lastcoachmodified datetime, + lastusermodified datetime, a_attemtps bigint default null, a_score float(65,30) default null, a_passed bit default null, diff --git a/src/main/resources/database/oracle/alter_11_5_x_to_12_0_0.sql b/src/main/resources/database/oracle/alter_11_5_x_to_12_0_0.sql index 895acf581f141aed088961a2c4d67f6ebd68ac4c..0b060d8af1b7a04e2886884b1772a6990b4007a6 100644 --- a/src/main/resources/database/oracle/alter_11_5_x_to_12_0_0.sql +++ b/src/main/resources/database/oracle/alter_11_5_x_to_12_0_0.sql @@ -256,3 +256,13 @@ create index idx_gtaskreset_to_allower_idx on o_gta_task (fk_allow_reset_identit alter table alter table o_info_message add attachmentpath varchar(1024) default null; + +alter table o_as_entry add lastcoachmodified date default null; +alter table o_as_entry add lastusermodified date default null; + +alter table o_as_eff_statement add column lastcoachmodified date default null; +alter table o_as_eff_statement add column lastusermodified date default null; + + + + diff --git a/src/main/resources/database/oracle/setupDatabase.sql b/src/main/resources/database/oracle/setupDatabase.sql index 22088d9ab8d095e9f8cc9d38090ea8a70415061a..95cdca54ad97ddd38a5aec795de2fcf5b1e1e056 100644 --- a/src/main/resources/database/oracle/setupDatabase.sql +++ b/src/main/resources/database/oracle/setupDatabase.sql @@ -1154,6 +1154,8 @@ create table o_as_eff_statement ( id number(20) not null, version number(20) not null, lastmodified date, + lastcoachmodified date, + lastusermodified date, creationdate date, passed number, score float(4), @@ -1189,6 +1191,8 @@ create table o_as_entry ( id number(20) GENERATED ALWAYS AS IDENTITY, creationdate date not null, lastmodified date not null, + lastcoachmodified date, + lastusermodified date, a_attemtps number(20) default null, a_score decimal default null, a_passed number default null, diff --git a/src/main/resources/database/postgresql/alter_11_5_x_to_12_0_0.sql b/src/main/resources/database/postgresql/alter_11_5_x_to_12_0_0.sql index 7a4fd7d2fe48f7dd8e0a292abb05e803bcacc5d5..4a0d80df14799fc36f04fbc90af4b907e923731b 100644 --- a/src/main/resources/database/postgresql/alter_11_5_x_to_12_0_0.sql +++ b/src/main/resources/database/postgresql/alter_11_5_x_to_12_0_0.sql @@ -257,6 +257,11 @@ create index idx_gtaskreset_to_allower_idx on o_gta_task (fk_allow_reset_identit alter table o_info_message add column attachmentpath varchar(1024) default null; +alter table o_as_entry add column lastcoachmodified timestamp default null; +alter table o_as_entry add column lastusermodified timestamp default null; + +alter table o_as_eff_statement add column lastcoachmodified timestamp default null; +alter table o_as_eff_statement add column lastusermodified timestamp default null; diff --git a/src/main/resources/database/postgresql/setupDatabase.sql b/src/main/resources/database/postgresql/setupDatabase.sql index 723deaec2fa5b3fd220f7b6240a7e3ed23ce2ef8..34b12f8da9c67164441a8a85db8e1a015c9350d8 100644 --- a/src/main/resources/database/postgresql/setupDatabase.sql +++ b/src/main/resources/database/postgresql/setupDatabase.sql @@ -1123,6 +1123,8 @@ create table o_as_eff_statement ( id int8 not null, version int4 not null, lastmodified timestamp, + lastcoachmodified timestamp, + lastusermodified timestamp, creationdate timestamp, passed boolean, score float4, @@ -1159,6 +1161,8 @@ create table o_as_entry ( id bigserial, creationdate timestamp not null, lastmodified timestamp not null, + lastcoachmodified timestamp, + lastusermodified timestamp, a_attemtps int8 default null, a_score decimal default null, a_passed bool default null, diff --git a/src/test/java/org/olat/course/assessment/AssessmentManagerTest.java b/src/test/java/org/olat/course/assessment/AssessmentManagerTest.java index 851ca4ae359d0800e3be9ef14bb26872a61e904d..bb40e0ed1874f68f85b79e33161c22bf168a1b3e 100644 --- a/src/test/java/org/olat/course/assessment/AssessmentManagerTest.java +++ b/src/test/java/org/olat/course/assessment/AssessmentManagerTest.java @@ -59,6 +59,7 @@ import org.olat.course.nodes.CourseNode; import org.olat.course.run.scoring.ScoreEvaluation; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.course.run.userview.UserCourseEnvironmentImpl; +import org.olat.modules.assessment.Role; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryManager; import org.olat.test.JunitTestHelper; @@ -162,7 +163,7 @@ public class AssessmentManagerTest extends OlatTestCase { UserCourseEnvironment userCourseEnv = new UserCourseEnvironmentImpl(ienv, course.getCourseEnvironment()); boolean incrementAttempts = true; //assessableCourseNode.updateUserScoreEvaluation(scoreEvaluation, userCourseEnv, tutor, incrementAttempts); //alternative - assessmentManager.saveScoreEvaluation(assessableCourseNode, tutor, student, scoreEvaluation, userCourseEnv, incrementAttempts); + assessmentManager.saveScoreEvaluation(assessableCourseNode, tutor, student, scoreEvaluation, userCourseEnv, incrementAttempts, Role.coach); DBFactory.getInstance().closeSession(); //the attempts mut have been incremented //assertEquals(attempts, assessableCourseNode.getUserAttempts(userCourseEnv)); //alternative @@ -175,7 +176,7 @@ public class AssessmentManagerTest extends OlatTestCase { //assessableCourseNode.updateUserUserComment(userComment, userCourseEnv, tutor); //alternative attempts++; - assessmentManager.saveNodeAttempts(assessableCourseNode, tutor, student, attempts); + assessmentManager.saveNodeAttempts(assessableCourseNode, tutor, student, attempts, Role.coach); assertEquals(attempts, assessmentManager.getNodeAttempts(assessableCourseNode, student)); //assessableCourseNode.updateUserAttempts(attempts, userCourseEnv, tutor); //alternative diff --git a/src/test/java/org/olat/course/assessment/manager/AssessmentToolManagerTest.java b/src/test/java/org/olat/course/assessment/manager/AssessmentToolManagerTest.java index c205043a6173e298a1f8f0b15460818d6a6b146a..5226817d9741bcb53c8e6c80026f0e625b0352a5 100644 --- a/src/test/java/org/olat/course/assessment/manager/AssessmentToolManagerTest.java +++ b/src/test/java/org/olat/course/assessment/manager/AssessmentToolManagerTest.java @@ -96,10 +96,10 @@ public class AssessmentToolManagerTest extends OlatTestCase { dbInstance.commitAndCloseSession(); // some datas - assessmentEntryDao.createAssessmentEntry(assessedIdentity1, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE); - assessmentEntryDao.createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 5.0f, Boolean.TRUE); - assessmentEntryDao.createAssessmentEntry(assessedIdentity3, null, entry, subIdent, refEntry, 8.0f, Boolean.TRUE); - assessmentEntryDao.createAssessmentEntry(assessedIdentity4, null, entry, subIdent, refEntry, 9.0f, Boolean.TRUE); + assessmentEntryDao.createAssessmentEntry(assessedIdentity1, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE, null, null); + assessmentEntryDao.createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 5.0f, Boolean.TRUE, null, null); + assessmentEntryDao.createAssessmentEntry(assessedIdentity3, null, entry, subIdent, refEntry, 8.0f, Boolean.TRUE, null, null); + assessmentEntryDao.createAssessmentEntry(assessedIdentity4, null, entry, subIdent, refEntry, 9.0f, Boolean.TRUE, null, null); assessmentEntryDao.createAssessmentEntry(null, UUID.randomUUID().toString(), entry, subIdent, refEntry); dbInstance.commitAndCloseSession(); diff --git a/src/test/java/org/olat/course/nodes/gta/manager/GTAManagerTest.java b/src/test/java/org/olat/course/nodes/gta/manager/GTAManagerTest.java index 0b8aa3883814b890a3a71f1f1e284a9e1251b94f..899b5a35b578395071a8cf75a4f0858a8f1fad34 100644 --- a/src/test/java/org/olat/course/nodes/gta/manager/GTAManagerTest.java +++ b/src/test/java/org/olat/course/nodes/gta/manager/GTAManagerTest.java @@ -20,15 +20,24 @@ package org.olat.course.nodes.gta.manager; import java.io.File; +import java.net.URISyntaxException; +import java.net.URL; import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.UUID; import org.junit.Assert; import org.junit.Test; import org.olat.basesecurity.GroupRoles; import org.olat.core.commons.persistence.DB; import org.olat.core.id.Identity; +import org.olat.core.logging.OLog; +import org.olat.core.logging.Tracing; +import org.olat.core.util.nodes.INode; +import org.olat.course.CourseFactory; +import org.olat.course.ICourse; +import org.olat.course.nodes.CourseNode; import org.olat.course.nodes.GTACourseNode; import org.olat.course.nodes.gta.AssignmentResponse; import org.olat.course.nodes.gta.AssignmentResponse.Status; @@ -56,6 +65,8 @@ import org.springframework.beans.factory.annotation.Autowired; */ public class GTAManagerTest extends OlatTestCase { + private static final OLog log = Tracing.createLoggerFor(GTAManagerTest.class); + @Autowired private DB dbInstance; @Autowired @@ -69,8 +80,8 @@ public class GTAManagerTest extends OlatTestCase { @Test public void createIfNotExists() { - RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false); - GTACourseNode node = new GTACourseNode(); + RepositoryEntry re = deployGTACourse(); + GTACourseNode node = getGTACourseNode(re); Assert.assertNotNull(node.getIdent()); TaskList tasks = gtaManager.createIfNotExists(re, node); @@ -100,8 +111,8 @@ public class GTAManagerTest extends OlatTestCase { public void selectTask_identity() { //prepare Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-1"); - RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false); - GTACourseNode node = new GTACourseNode(); + RepositoryEntry re = deployGTACourse(); + GTACourseNode node = getGTACourseNode(re); node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.individual.name()); TaskList tasks = gtaManager.createIfNotExists(re, node); File taskFile = new File("solo.txt"); @@ -132,8 +143,8 @@ public class GTAManagerTest extends OlatTestCase { Identity coach = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-2"); BusinessGroup businessGroup = businessGroupDao.createAndPersist(coach, "gdao", "gdao-desc", -1, -1, false, false, false, false, false); dbInstance.commit(); - RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false); - GTACourseNode node = new GTACourseNode(); + RepositoryEntry re = deployGTACourse(); + GTACourseNode node = getGTACourseNode(re); node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.group.name()); TaskList tasks = gtaManager.createIfNotExists(re, node); File taskFile = new File("bg.txt"); @@ -165,8 +176,8 @@ public class GTAManagerTest extends OlatTestCase { BusinessGroup businessGroup = businessGroupDao.createAndPersist(coach, "gdao", "gdao-desc", -1, -1, false, false, false, false, false); businessGroupRelationDao.addRole(participant, businessGroup, GroupRole.participant.name()); dbInstance.commit(); - RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false); - GTACourseNode node = new GTACourseNode(); + RepositoryEntry re = deployGTACourse(); + GTACourseNode node = getGTACourseNode(re); node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.group.name()); TaskList tasks = gtaManager.createIfNotExists(re, node); File taskFile = new File("bg.txt"); @@ -187,8 +198,8 @@ public class GTAManagerTest extends OlatTestCase { public void isTaskAssigned() { //create an individual task Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-6"); - RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false); - GTACourseNode node = new GTACourseNode(); + RepositoryEntry re = deployGTACourse(); + GTACourseNode node = getGTACourseNode(re); node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.individual.name()); TaskList tasks = gtaManager.createIfNotExists(re, node); dbInstance.commit(); @@ -211,8 +222,8 @@ public class GTAManagerTest extends OlatTestCase { public void isTaskInProcess() { //prepare Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-11"); - RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false); - GTACourseNode node = new GTACourseNode(); + RepositoryEntry re = deployGTACourse(); + GTACourseNode node = getGTACourseNode(re); node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.individual.name()); TaskList tasks = gtaManager.createIfNotExists(re, node); File taskFile = new File("solo.txt"); @@ -238,8 +249,8 @@ public class GTAManagerTest extends OlatTestCase { public void isTasksInProcess_yes() { //prepare Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-12"); - RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false); - GTACourseNode node = new GTACourseNode(); + RepositoryEntry re = deployGTACourse(); + GTACourseNode node = getGTACourseNode(re); node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.individual.name()); TaskList tasks = gtaManager.createIfNotExists(re, node); File taskFile = new File("solo.txt"); @@ -260,8 +271,8 @@ public class GTAManagerTest extends OlatTestCase { @Test public void isTasksInProcess_no() { //prepare - RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false); - GTACourseNode node = new GTACourseNode(); + RepositoryEntry re = deployGTACourse(); + GTACourseNode node = getGTACourseNode(re); node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.individual.name()); TaskList tasks = gtaManager.createIfNotExists(re, node); Assert.assertNotNull(tasks); @@ -277,8 +288,8 @@ public class GTAManagerTest extends OlatTestCase { //create an individual task Identity id1 = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-7"); Identity id2 = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-8"); - RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false); - GTACourseNode node = new GTACourseNode(); + RepositoryEntry re = deployGTACourse(); + GTACourseNode node = getGTACourseNode(re); node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.individual.name()); TaskList taskList = gtaManager.createIfNotExists(re, node); dbInstance.commit(); @@ -301,8 +312,8 @@ public class GTAManagerTest extends OlatTestCase { //create an individual task Identity id1 = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-7"); Identity id2 = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-8"); - RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false); - GTACourseNode node = new GTACourseNode(); + RepositoryEntry re = deployGTACourse(); + GTACourseNode node = getGTACourseNode(re); node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.individual.name()); TaskList taskList = gtaManager.createIfNotExists(re, node); dbInstance.commit(); @@ -334,8 +345,8 @@ public class GTAManagerTest extends OlatTestCase { //create an individual task Identity id1 = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-7"); Identity id2 = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-8"); - RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false); - GTACourseNode node = new GTACourseNode(); + RepositoryEntry re = deployGTACourse(); + GTACourseNode node = getGTACourseNode(re); node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.individual.name()); TaskList taskList = gtaManager.createIfNotExists(re, node); dbInstance.commit(); @@ -401,8 +412,8 @@ public class GTAManagerTest extends OlatTestCase { BusinessGroup businessGroup = businessGroupDao.createAndPersist(coach, "gdao", "gdao-desc", -1, -1, false, false, false, false, false); businessGroupRelationDao.addRole(participant, businessGroup, GroupRole.participant.name()); dbInstance.commit(); - RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false); - GTACourseNode node = new GTACourseNode(); + RepositoryEntry re = deployGTACourse(); + GTACourseNode node = getGTACourseNode(re); node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.group.name()); TaskList tasks = gtaManager.createIfNotExists(re, node); File taskFile = new File("bg.txt"); @@ -442,10 +453,10 @@ public class GTAManagerTest extends OlatTestCase { BusinessGroup businessGroup = businessGroupDao.createAndPersist(coach, "gdao", "gdao-desc", -1, -1, false, false, false, false, false); businessGroupRelationDao.addRole(participant, businessGroup, GroupRole.participant.name()); dbInstance.commit(); - RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false); + RepositoryEntry re = deployGTACourse(); //node 1 - GTACourseNode node1 = new GTACourseNode(); + GTACourseNode node1 = getGTACourseNode(re); node1.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.group.name()); TaskList tasks1 = gtaManager.createIfNotExists(re, node1); File taskFile = new File("bg.txt"); @@ -499,11 +510,11 @@ public class GTAManagerTest extends OlatTestCase { Identity coach = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-9"); Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-10"); dbInstance.commit(); - RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false); + RepositoryEntry re = deployGTACourse(); repositoryEntryRelationDao.addRole(coach, re, GroupRoles.coach.name()); repositoryEntryRelationDao.addRole(participant, re, GroupRoles.participant.name()); - GTACourseNode node = new GTACourseNode(); + GTACourseNode node = getGTACourseNode(re); node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.individual.name()); TaskList tasks = gtaManager.createIfNotExists(re, node); File taskFile = new File("bg.txt"); @@ -542,25 +553,25 @@ public class GTAManagerTest extends OlatTestCase { Identity participant1 = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-21"); Identity participant2 = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-22"); - RepositoryEntry re1 = JunitTestHelper.createAndPersistRepositoryEntry("", false); + RepositoryEntry re1 = deployGTACourse(); repositoryEntryRelationDao.addRole(coach, re1, GroupRoles.coach.name()); repositoryEntryRelationDao.addRole(participant1, re1, GroupRoles.participant.name()); repositoryEntryRelationDao.addRole(participant2, re1, GroupRoles.participant.name()); //course 1 - GTACourseNode node1 = new GTACourseNode(); + GTACourseNode node1 = getGTACourseNode(re1); node1.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.individual.name()); TaskList tasks1 = gtaManager.createIfNotExists(re1, node1); File taskFile = new File("bg.txt"); Assert.assertNotNull(tasks1); dbInstance.commit(); - RepositoryEntry re2 = JunitTestHelper.createAndPersistRepositoryEntry("", false); + RepositoryEntry re2 = deployGTACourse(); repositoryEntryRelationDao.addRole(coach, re2, GroupRoles.coach.name()); repositoryEntryRelationDao.addRole(participant1, re2, GroupRoles.participant.name()); //participant 2 course 2 - GTACourseNode node2 = new GTACourseNode(); + GTACourseNode node2 = getGTACourseNode(re2); node2.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.individual.name()); TaskList tasks2 = gtaManager.createIfNotExists(re2, node2); Assert.assertNotNull(tasks2); @@ -615,8 +626,8 @@ public class GTAManagerTest extends OlatTestCase { public void createTaskRevisionDate() { //prepare Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-20"); - RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false); - GTACourseNode node = new GTACourseNode(); + RepositoryEntry re = deployGTACourse(); + GTACourseNode node = getGTACourseNode(re); node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.individual.name()); TaskList tasks = gtaManager.createIfNotExists(re, node); dbInstance.commit(); @@ -640,8 +651,8 @@ public class GTAManagerTest extends OlatTestCase { public void getTaskRevisions() { //prepare Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-21"); - RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false); - GTACourseNode node = new GTACourseNode(); + RepositoryEntry re = deployGTACourse(); + GTACourseNode node = getGTACourseNode(re); node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.individual.name()); TaskList tasks = gtaManager.createIfNotExists(re, node); dbInstance.commit(); @@ -723,4 +734,31 @@ public class GTAManagerTest extends OlatTestCase { String nextSlot = gtaManager.nextSlotRoundRobin(slots, usedSlots); Assert.assertEquals("C", nextSlot); } + + private RepositoryEntry deployGTACourse() { + try { + Identity initialAuthor = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-author"); + String displayname = "GTA-" + UUID.randomUUID(); + + URL courseUrl = JunitTestHelper.class.getResource("file_resources/GTA_course.zip"); + File courseFile = new File(courseUrl.toURI()); + return JunitTestHelper.deployCourse(initialAuthor, displayname, courseFile); + } catch (URISyntaxException e) { + log.error("", e); + return null; + } + } + + private GTACourseNode getGTACourseNode(RepositoryEntry courseEntry) { + ICourse course = CourseFactory.loadCourse(courseEntry); + CourseNode rootNode = course.getRunStructure().getRootNode(); + for(int i=rootNode.getChildCount(); i-->0; ) { + INode child = rootNode.getChildAt(i); + if(child instanceof GTACourseNode) { + return ((GTACourseNode)child); + } + } + + return null; + } } diff --git a/src/test/java/org/olat/course/nodes/gta/rule/GTAReminderRuleTest.java b/src/test/java/org/olat/course/nodes/gta/rule/GTAReminderRuleTest.java index aa88c554cad581ca7f4c88ee86224a72fda9119a..6d78418506b6aefb8390b39f6119d2bcf8ebbe91 100644 --- a/src/test/java/org/olat/course/nodes/gta/rule/GTAReminderRuleTest.java +++ b/src/test/java/org/olat/course/nodes/gta/rule/GTAReminderRuleTest.java @@ -20,6 +20,8 @@ package org.olat.course.nodes.gta.rule; import java.io.File; +import java.net.URISyntaxException; +import java.net.URL; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; @@ -32,9 +34,14 @@ import org.olat.basesecurity.GroupRoles; import org.olat.basesecurity.model.GroupMembershipImpl; import org.olat.core.commons.persistence.DB; import org.olat.core.id.Identity; +import org.olat.core.logging.OLog; +import org.olat.core.logging.Tracing; +import org.olat.core.util.nodes.INode; +import org.olat.course.CourseFactory; import org.olat.course.ICourse; import org.olat.course.assessment.manager.UserCourseInformationsManager; import org.olat.course.assessment.model.UserCourseInfosImpl; +import org.olat.course.nodes.CourseNode; import org.olat.course.nodes.GTACourseNode; import org.olat.course.nodes.gta.AssignmentResponse; import org.olat.course.nodes.gta.GTARelativeToDates; @@ -66,6 +73,8 @@ import org.springframework.beans.factory.annotation.Autowired; */ public class GTAReminderRuleTest extends OlatTestCase { + private static final OLog log = Tracing.createLoggerFor(GTAReminderRuleTest.class); + @Autowired private DB dbInstance; @Autowired @@ -92,12 +101,12 @@ public class GTAReminderRuleTest extends OlatTestCase { //prepare a course with a volatile task Identity participant1 = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-1"); Identity participant2 = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-2"); - RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false); + RepositoryEntry re = deployGTACourse(); repositoryEntryRelationDao.addRole(participant1, re, GroupRoles.participant.name()); repositoryEntryRelationDao.addRole(participant2, re, GroupRoles.participant.name()); dbInstance.commit(); - GTACourseNode node = new GTACourseNode(); + GTACourseNode node = getGTACourseNode(re); node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.individual.name()); Calendar cal = Calendar.getInstance(); @@ -404,12 +413,12 @@ public class GTAReminderRuleTest extends OlatTestCase { //prepare a course with a volatile task Identity participant1 = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-1"); Identity participant2 = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-user-2"); - RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry("", false); + RepositoryEntry re = deployGTACourse(); repositoryEntryRelationDao.addRole(participant1, re, GroupRoles.participant.name()); repositoryEntryRelationDao.addRole(participant2, re, GroupRoles.participant.name()); dbInstance.commit(); - GTACourseNode node = new GTACourseNode(); + GTACourseNode node = getGTACourseNode(re); node.getModuleConfiguration().setStringValue(GTACourseNode.GTASK_TYPE, GTAType.individual.name()); Calendar cal = Calendar.getInstance(); @@ -599,4 +608,31 @@ public class GTAReminderRuleTest extends OlatTestCase { rule.setRightUnit(unit.name()); return rule; } + + private RepositoryEntry deployGTACourse() { + try { + Identity initialAuthor = JunitTestHelper.createAndPersistIdentityAsRndUser("gta-reminder"); + String displayname = "GTARemind-" + UUID.randomUUID(); + + URL courseUrl = JunitTestHelper.class.getResource("file_resources/GTA_course.zip"); + File courseFile = new File(courseUrl.toURI()); + return JunitTestHelper.deployCourse(initialAuthor, displayname, courseFile); + } catch (URISyntaxException e) { + log.error("", e); + return null; + } + } + + private GTACourseNode getGTACourseNode(RepositoryEntry courseEntry) { + ICourse course = CourseFactory.loadCourse(courseEntry); + CourseNode rootNode = course.getRunStructure().getRootNode(); + for(int i=rootNode.getChildCount(); i-->0; ) { + INode child = rootNode.getChildAt(i); + if(child instanceof GTACourseNode) { + return ((GTACourseNode)child); + } + } + + return null; + } } diff --git a/src/test/java/org/olat/modules/assessment/manager/AssessmentEntryDAOTest.java b/src/test/java/org/olat/modules/assessment/manager/AssessmentEntryDAOTest.java index 6957815923569a03be5dcc57d7b480b55436f3a1..fc20ce32f2f0710f82ccdebcb4e7102a6f2cedb6 100644 --- a/src/test/java/org/olat/modules/assessment/manager/AssessmentEntryDAOTest.java +++ b/src/test/java/org/olat/modules/assessment/manager/AssessmentEntryDAOTest.java @@ -174,7 +174,7 @@ public class AssessmentEntryDAOTest extends OlatTestCase { RepositoryEntry refEntry = JunitTestHelper.createAndPersistRepositoryEntry(); String subIdent = UUID.randomUUID().toString(); AssessmentEntry nodeAssessmentRef = assessmentEntryDao - .createAssessmentEntry(assessedIdentity, null, entry, subIdent, refEntry, 2.0f, Boolean.TRUE); + .createAssessmentEntry(assessedIdentity, null, entry, subIdent, refEntry, 2.0f, Boolean.TRUE, null, null); dbInstance.commitAndCloseSession(); AssessmentEntry resetedAssessmentRef = assessmentEntryDao @@ -210,11 +210,11 @@ public class AssessmentEntryDAOTest extends OlatTestCase { AssessmentEntry nodeAssessmentId1 = assessmentEntryDao .createAssessmentEntry(assessedIdentity1, null, entry, subIdent, refEntry); AssessmentEntry nodeAssessmentId2 = assessmentEntryDao - .createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE); + .createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE, null, null); AssessmentEntry nodeAssessmentId3 = assessmentEntryDao - .createAssessmentEntry(assessedIdentity2, null, entry, null, entry, 3.0f, Boolean.FALSE); + .createAssessmentEntry(assessedIdentity2, null, entry, null, entry, 3.0f, Boolean.FALSE, null, null); AssessmentEntry nodeAssessmentId4 = assessmentEntryDao - .createAssessmentEntry(assessedIdentity2, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE); + .createAssessmentEntry(assessedIdentity2, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE, null, null); dbInstance.commitAndCloseSession(); // load with our subIdent above @@ -239,9 +239,9 @@ public class AssessmentEntryDAOTest extends OlatTestCase { String subIdent = UUID.randomUUID().toString(); assessmentEntryDao.createAssessmentEntry(assessedIdentity1, null, entry, subIdent, refEntry); - assessmentEntryDao.createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE); - assessmentEntryDao.createAssessmentEntry(assessedIdentity3, null, entry, null, entry, 3.0f, Boolean.FALSE); - assessmentEntryDao.createAssessmentEntry(assessedIdentity4, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE); + assessmentEntryDao.createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE, null, null); + assessmentEntryDao.createAssessmentEntry(assessedIdentity3, null, entry, null, entry, 3.0f, Boolean.FALSE, null, null); + assessmentEntryDao.createAssessmentEntry(assessedIdentity4, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE, null, null); dbInstance.commitAndCloseSession(); // id 1,2,3 are in the entry, but 4 is in an other entry and must not appears in the list @@ -265,11 +265,11 @@ public class AssessmentEntryDAOTest extends OlatTestCase { AssessmentEntry nodeAssessmentId1 = assessmentEntryDao .createAssessmentEntry(assessedIdentity1, null, entry, subIdent, refEntry); AssessmentEntry nodeAssessmentId2 = assessmentEntryDao - .createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE); + .createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE, null, null); AssessmentEntry nodeAssessmentId3 = assessmentEntryDao - .createAssessmentEntry(assessedIdentity2, null, entry, null, entry, 3.0f, Boolean.FALSE); + .createAssessmentEntry(assessedIdentity2, null, entry, null, entry, 3.0f, Boolean.FALSE, null, null); AssessmentEntry nodeAssessmentId4 = assessmentEntryDao - .createAssessmentEntry(assessedIdentity1, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE); + .createAssessmentEntry(assessedIdentity1, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE, null, null); dbInstance.commitAndCloseSession(); // load for identity 1 @@ -321,11 +321,11 @@ public class AssessmentEntryDAOTest extends OlatTestCase { AssessmentEntry nodeAssessmentId1 = assessmentEntryDao .createAssessmentEntry(assessedIdentity1, null, entry, subIdent, refEntry); AssessmentEntry nodeAssessmentId2 = assessmentEntryDao - .createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE); + .createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE, null, null); AssessmentEntry nodeAssessmentId3 = assessmentEntryDao - .createAssessmentEntry(assessedIdentity2, null, entry, null, entry, 3.0f, Boolean.FALSE); + .createAssessmentEntry(assessedIdentity2, null, entry, null, entry, 3.0f, Boolean.FALSE, null, null); AssessmentEntry nodeAssessmentId4 = assessmentEntryDao - .createAssessmentEntry(assessedIdentity1, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE); + .createAssessmentEntry(assessedIdentity1, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE, null, null); dbInstance.commitAndCloseSession(); //load the assessment entries of entry @@ -350,11 +350,11 @@ public class AssessmentEntryDAOTest extends OlatTestCase { AssessmentEntry nodeAssessment1 = assessmentEntryDao .createAssessmentEntry(assessedIdentity1, null, entry, subIdent, refEntry); AssessmentEntry nodeAssessment2 = assessmentEntryDao - .createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE); + .createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE, null, null); AssessmentEntry nodeAssessment3 = assessmentEntryDao - .createAssessmentEntry(assessedIdentity2, null, entry, null, entry, 3.0f, Boolean.FALSE); + .createAssessmentEntry(assessedIdentity2, null, entry, null, entry, 3.0f, Boolean.FALSE, null, null); AssessmentEntry nodeAssessment4 = assessmentEntryDao - .createAssessmentEntry(assessedIdentity1, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE); + .createAssessmentEntry(assessedIdentity1, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE, null, null); dbInstance.commitAndCloseSession(); // delete by reference @@ -389,11 +389,11 @@ public class AssessmentEntryDAOTest extends OlatTestCase { AssessmentEntry nodeAssessment1 = assessmentEntryDao .createAssessmentEntry(assessedIdentity1, null, entry, subIdent, refEntry); AssessmentEntry nodeAssessment2 = assessmentEntryDao - .createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE); + .createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 3.0f, Boolean.FALSE, null, null); AssessmentEntry nodeAssessment3 = assessmentEntryDao - .createAssessmentEntry(assessedIdentity2, null, entry, null, entry, 3.0f, Boolean.FALSE); + .createAssessmentEntry(assessedIdentity2, null, entry, null, entry, 3.0f, Boolean.FALSE, null, null); AssessmentEntry nodeAssessment4 = assessmentEntryDao - .createAssessmentEntry(assessedIdentity1, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE); + .createAssessmentEntry(assessedIdentity1, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE, null, null); dbInstance.commitAndCloseSession(); // delete by reference @@ -433,17 +433,17 @@ public class AssessmentEntryDAOTest extends OlatTestCase { AssessmentEntry nodeAssessmentId1 = assessmentEntryDao .createAssessmentEntry(assessedIdentity1, null, entry, subIdent, refEntry); AssessmentEntry nodeAssessmentId2 = assessmentEntryDao - .createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 0.0f, Boolean.FALSE); + .createAssessmentEntry(assessedIdentity2, null, entry, subIdent, refEntry, 0.0f, Boolean.FALSE, null, null); AssessmentEntry nodeAssessmentId3 = assessmentEntryDao - .createAssessmentEntry(assessedIdentity2, null, entry, null, entry, 12.0f, Boolean.FALSE); + .createAssessmentEntry(assessedIdentity2, null, entry, null, entry, 12.0f, Boolean.FALSE, null, null); AssessmentEntry nodeAssessmentId4 = assessmentEntryDao - .createAssessmentEntry(assessedIdentity2, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE); + .createAssessmentEntry(assessedIdentity2, null, refEntry, subIdent, refEntry, 3.0f, Boolean.FALSE, null, null); AssessmentEntry nodeAssessmentId5 = assessmentEntryDao - .createAssessmentEntry(assessedIdentity3, null, entry, subIdent, refEntry, 6.0f, Boolean.TRUE); + .createAssessmentEntry(assessedIdentity3, null, entry, subIdent, refEntry, 6.0f, Boolean.TRUE, null, null); AssessmentEntry nodeAssessmentId6 = assessmentEntryDao - .createAssessmentEntry(assessedIdentity4, null, entry, subIdent, refEntry, 1.0f, Boolean.FALSE); + .createAssessmentEntry(assessedIdentity4, null, entry, subIdent, refEntry, 1.0f, Boolean.FALSE, null, null); AssessmentEntry nodeAssessmentId7 = assessmentEntryDao - .createAssessmentEntry(assessedIdentity5, null, entry, subIdent, refEntry, 10.0f, Boolean.TRUE); + .createAssessmentEntry(assessedIdentity5, null, entry, subIdent, refEntry, 10.0f, Boolean.TRUE, null, null); dbInstance.commitAndCloseSession(); // load with our subIdent above List<AssessmentEntry> assessmentEntries = assessmentEntryDao diff --git a/src/test/java/org/olat/modules/reminder/manager/ReminderRuleEngineTest.java b/src/test/java/org/olat/modules/reminder/manager/ReminderRuleEngineTest.java index 55a6408ca7044c2b59ff9e31dfb976f1f5fbf00f..97936acfb3d47e2c3a5224d2250710636f6b3698 100644 --- a/src/test/java/org/olat/modules/reminder/manager/ReminderRuleEngineTest.java +++ b/src/test/java/org/olat/modules/reminder/manager/ReminderRuleEngineTest.java @@ -50,6 +50,7 @@ import org.olat.course.run.userview.UserCourseEnvironmentImpl; import org.olat.group.BusinessGroup; import org.olat.group.manager.BusinessGroupDAO; import org.olat.group.manager.BusinessGroupRelationDAO; +import org.olat.modules.assessment.Role; import org.olat.modules.reminder.ReminderRule; import org.olat.modules.reminder.model.ReminderRuleImpl; import org.olat.modules.reminder.rule.CourseEnrollmentDateRuleSPI; @@ -1059,7 +1060,7 @@ public class ReminderRuleEngineTest extends OlatTestCase { ienv.setIdentity(student); UserCourseEnvironment userCourseEnv = new UserCourseEnvironmentImpl(ienv, course.getCourseEnvironment()); - course.getCourseEnvironment().getAssessmentManager().saveScoreEvaluation(testNode, tutor, student, scoreEval, userCourseEnv, true); + course.getCourseEnvironment().getAssessmentManager().saveScoreEvaluation(testNode, tutor, student, scoreEval, userCourseEnv, true, Role.coach); dbInstance.commit(); return testNode.getIdent(); diff --git a/src/test/java/org/olat/test/JunitTestHelper.java b/src/test/java/org/olat/test/JunitTestHelper.java index 54119607a6fd01f0f324fa29fd6af2fda8e7966f..ee9b93f298ba7069a243d29f9239c45aefad4322 100644 --- a/src/test/java/org/olat/test/JunitTestHelper.java +++ b/src/test/java/org/olat/test/JunitTestHelper.java @@ -245,4 +245,26 @@ public class JunitTestHelper { } return re; } + + /** + * Deploy a course with only a single page. + * @param initialAuthor + * @return + */ + public static RepositoryEntry deployCourse(Identity initialAuthor, String displayname, File courseFile) { + String description = "A course"; + + RepositoryEntry re = null; + try { + RepositoryHandler courseHandler = RepositoryHandlerFactory.getInstance() + .getRepositoryHandler(CourseModule.getCourseTypeName()); + re = courseHandler.importResource(initialAuthor, null, displayname, description, true, Locale.ENGLISH, courseFile, null); + + ICourse course = CourseFactory.loadCourse(re); + CourseFactory.publishCourse(course, RepositoryEntry.ACC_USERS, false, initialAuthor, Locale.ENGLISH); + } catch (Exception e) { + log.error("", e); + } + return re; + } } diff --git a/src/test/java/org/olat/test/file_resources/GTA_course.zip b/src/test/java/org/olat/test/file_resources/GTA_course.zip new file mode 100644 index 0000000000000000000000000000000000000000..1e1dadbfb9a55800ba8715461d2d38a86a2f6a92 Binary files /dev/null and b/src/test/java/org/olat/test/file_resources/GTA_course.zip differ