From 62835b26f058192cd6d939f1448ba55bc039214a Mon Sep 17 00:00:00 2001 From: srosse <none@none> Date: Mon, 20 Feb 2017 13:51:49 +0100 Subject: [PATCH] OO-2560: show the result of the last test session for self-test course elements --- .../olat/course/nodes/IQSELFCourseNode.java | 29 +++++++++++++++---- .../nodes/SelfAssessableCourseNode.java | 13 +++++++++ .../iq/QTI21AssessmentRunController.java | 25 +++++++++++----- .../nodes/iq/_content/assessment_run.html | 8 ++--- .../java/org/olat/ims/qti21/QTI21Service.java | 11 +++++++ .../manager/AssessmentTestSessionDAO.java | 29 +++++++++++++++++++ .../ims/qti21/manager/QTI21ServiceImpl.java | 6 ++++ .../ui/AssessmentTestDisplayController.java | 14 ++++----- 8 files changed, 111 insertions(+), 24 deletions(-) diff --git a/src/main/java/org/olat/course/nodes/IQSELFCourseNode.java b/src/main/java/org/olat/course/nodes/IQSELFCourseNode.java index 0b8c19d7f7b..a8d2eec19d8 100644 --- a/src/main/java/org/olat/course/nodes/IQSELFCourseNode.java +++ b/src/main/java/org/olat/course/nodes/IQSELFCourseNode.java @@ -63,6 +63,8 @@ import org.olat.ims.qti.export.QTIExportFormatterCSVType2; import org.olat.ims.qti.export.QTIExportManager; import org.olat.ims.qti.fileresource.TestFileResource; import org.olat.ims.qti.process.AssessmentInstance; +import org.olat.ims.qti21.AssessmentTestSession; +import org.olat.ims.qti21.QTI21Service; import org.olat.ims.qti21.manager.AssessmentTestSessionDAO; import org.olat.modules.ModuleConfiguration; import org.olat.modules.iq.IQManager; @@ -315,6 +317,7 @@ public class IQSELFCourseNode extends AbstractAccessableCourseNode implements Se @Override public ScoreEvaluation getUserScoreEvaluation(final UserCourseEnvironment userCourseEnv) { // read score from properties save score, passed and attempts information + ScoreEvaluation scoreEvaluation = null; RepositoryEntry referencedRepositoryEntry = getReferencedRepositoryEntry(); if (referencedRepositoryEntry != null && OnyxModule.isOnyxTest(getReferencedRepositoryEntry().getOlatResource())) { AssessmentManager am = userCourseEnv.getCourseEnvironment().getAssessmentManager(); @@ -324,9 +327,18 @@ public class IQSELFCourseNode extends AbstractAccessableCourseNode implements Se Long assessmentID = am.getAssessmentID(this, mySelf); // <OLATCE-374> Boolean fullyAssessed = am.getNodeFullyAssessed(this, mySelf); - ScoreEvaluation se = new ScoreEvaluation(score, passed, fullyAssessed, assessmentID); + scoreEvaluation = new ScoreEvaluation(score, passed, fullyAssessed, assessmentID); // </OLATCE-374> - return se; + } else if(referencedRepositoryEntry != null && ImsQTI21Resource.TYPE_NAME.equals(referencedRepositoryEntry.getOlatResource().getResourceableTypeName())) { + RepositoryEntry courseEntry = userCourseEnv.getCourseEnvironment().getCourseGroupManager().getCourseEntry(); + Identity assessedIdentity = userCourseEnv.getIdentityEnvironment().getIdentity(); + AssessmentTestSession testSession = CoreSpringFactory.getImpl(QTI21Service.class) + .getLastAssessmentTestSessions(courseEntry, getIdent(), referencedRepositoryEntry, assessedIdentity); + if(testSession != null) { + boolean fullyAssessed = (testSession.getFinishTime() != null || testSession.getTerminationTime() != null); + Float score = testSession.getScore() == null ? null : testSession.getScore().floatValue(); + scoreEvaluation = new ScoreEvaluation(score, testSession.getPassed(), fullyAssessed, testSession.getKey()); + } } else { Identity identity = userCourseEnv.getIdentityEnvironment().getIdentity(); long olatResourceId = userCourseEnv.getCourseEnvironment().getCourseResourceableId().longValue(); @@ -334,16 +346,23 @@ public class IQSELFCourseNode extends AbstractAccessableCourseNode implements Se if (qTIResultSet != null) { Boolean passed = qTIResultSet.getIsPassed(); Boolean fullyAssessed = qTIResultSet.getFullyAssessed(); - ScoreEvaluation scoreEvaluation = new ScoreEvaluation(new Float(qTIResultSet.getScore()), passed, fullyAssessed, new Long(qTIResultSet.getAssessmentID())); - return scoreEvaluation; + scoreEvaluation = new ScoreEvaluation(new Float(qTIResultSet.getScore()), passed, fullyAssessed, new Long(qTIResultSet.getAssessmentID())); } } - return null; + return scoreEvaluation; } + @Override + public Integer getUserAttempts(UserCourseEnvironment userCourseEnvironment) { + AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); + Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity(); + return am.getNodeAttempts(this, mySelf); + } + /** * @see org.olat.course.nodes.AssessableCourseNode#incrementUserAttempts(org.olat.course.run.userview.UserCourseEnvironment) */ + @Override public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment) { AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager(); Identity mySelf = userCourseEnvironment.getIdentityEnvironment().getIdentity(); diff --git a/src/main/java/org/olat/course/nodes/SelfAssessableCourseNode.java b/src/main/java/org/olat/course/nodes/SelfAssessableCourseNode.java index cb431bedd4b..5e9a0957567 100644 --- a/src/main/java/org/olat/course/nodes/SelfAssessableCourseNode.java +++ b/src/main/java/org/olat/course/nodes/SelfAssessableCourseNode.java @@ -45,4 +45,17 @@ public interface SelfAssessableCourseNode extends CourseNode { * @return Returns the ScoreEvaluation. */ public ScoreEvaluation getUserScoreEvaluation(UserCourseEnvironment userCourseEnv); + + /** + * @param userCourseEnvironment + * @return The users attempts of this node + */ + public Integer getUserAttempts(UserCourseEnvironment userCourseEnvironment); + + /** + * Increments the users attempts for this node and this user + 1. + * @param userCourseEnvironment + */ + public void incrementUserAttempts(UserCourseEnvironment userCourseEnvironment); + } 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 42d1fc208eb..4a23c7a5db0 100644 --- a/src/main/java/org/olat/course/nodes/iq/QTI21AssessmentRunController.java +++ b/src/main/java/org/olat/course/nodes/iq/QTI21AssessmentRunController.java @@ -56,6 +56,7 @@ import org.olat.course.nodes.CourseNode; import org.olat.course.nodes.IQSELFCourseNode; import org.olat.course.nodes.IQTESTCourseNode; import org.olat.course.nodes.QTICourseNode; +import org.olat.course.nodes.SelfAssessableCourseNode; import org.olat.course.run.scoring.ScoreEvaluation; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.fileresource.FileResourceManager; @@ -187,9 +188,21 @@ public class QTI21AssessmentRunController extends BasicController implements Gen } else { mainVC.contextPut("attemptsConfig", Boolean.FALSE); } - // user data - if(courseNode instanceof IQTESTCourseNode) { + // user data + if (courseNode instanceof SelfAssessableCourseNode) { + SelfAssessableCourseNode acn = (SelfAssessableCourseNode)courseNode; + ScoreEvaluation scoreEval = acn.getUserScoreEvaluation(userCourseEnv); + Integer attempts = acn.getUserAttempts(userCourseEnv); + if (scoreEval != null) { + mainVC.contextPut("hasResults", Boolean.TRUE); + mainVC.contextPut("score", AssessmentHelper.getRoundedScore(scoreEval.getScore())); + mainVC.contextPut("hasPassedValue", (scoreEval.getPassed() == null ? Boolean.FALSE : Boolean.TRUE)); + mainVC.contextPut("passed", scoreEval.getPassed()); + mainVC.contextPut("attempts", attempts); //at least one attempt + exposeResults(ureq); + } + } else if(courseNode instanceof IQTESTCourseNode) { IQTESTCourseNode testCourseNode = (IQTESTCourseNode)courseNode; AssessmentEntry assessmentEntry = testCourseNode.getUserAssessmentEntry(userCourseEnv); if(assessmentEntry == null) { @@ -223,9 +236,7 @@ public class QTI21AssessmentRunController extends BasicController implements Gen mainVC.contextPut("log", am.getUserNodeLog(courseNode, identity)); } } - } - - exposeResults(ureq); + } } private void checkChats (UserRequest ureq) { @@ -505,10 +516,10 @@ public class QTI21AssessmentRunController extends BasicController implements Gen if(increment) { ThreadLocalUserActivityLogger.log(QTI21LoggingAction.QTI_CLOSE_IN_COURSE, getClass()); } - } else if(courseNode instanceof IQSELFCourseNode) { + } else if(courseNode instanceof SelfAssessableCourseNode) { boolean increment = incrementAttempts.getAndSet(false); if(increment) { - ((IQSELFCourseNode)courseNode).incrementUserAttempts(userCourseEnv); + ((SelfAssessableCourseNode)courseNode).incrementUserAttempts(userCourseEnv); } } } diff --git a/src/main/java/org/olat/course/nodes/iq/_content/assessment_run.html b/src/main/java/org/olat/course/nodes/iq/_content/assessment_run.html index 66b5812c886..1b0dbd4dde8 100644 --- a/src/main/java/org/olat/course/nodes/iq/_content/assessment_run.html +++ b/src/main/java/org/olat/course/nodes/iq/_content/assessment_run.html @@ -1,5 +1,5 @@ #if ($enableScoreInfo) - #if($attempts && $attempts > 0) + #if($r.isNotNull($attempts) && $attempts > 0) <div class="panel panel-default o_personal"> <div class="panel-heading"> <h4 class="panel-title">$r.translate("personal.title")</h4> @@ -19,11 +19,11 @@ <tr class="o_attempts"> <th>$r.translate("attempts.yourattempts")</th> <td>$attempts</td> - </tr> + </tr> <tr class="o_score"> <th>$r.translate("score.yourscore")</th> - <td>$score</td> - </tr> + <td>#if($r.isNotNull($score))$score#end</td> + </tr> <tr class="o_state #if ($hasPassedValue && $passed) o_passed #elseif($hasPassedValue && !$passed) o_failed #else o_unknown #end"> <th>$r.translate("passed.yourpassed")</th> <td> diff --git a/src/main/java/org/olat/ims/qti21/QTI21Service.java b/src/main/java/org/olat/ims/qti21/QTI21Service.java index ce066d90961..de122275db6 100644 --- a/src/main/java/org/olat/ims/qti21/QTI21Service.java +++ b/src/main/java/org/olat/ims/qti21/QTI21Service.java @@ -228,6 +228,17 @@ public interface QTI21Service { */ public List<AssessmentTestSession> getAssessmentTestSessions(RepositoryEntryRef courseEntry, String subIdent, IdentityRef identity); + /** + * Retrieve the last finished test session. + * + * @param courseEntry + * @param subIdent + * @param testEntry + * @param identity + * @return + */ + public AssessmentTestSession getLastAssessmentTestSessions(RepositoryEntryRef courseEntry, String subIdent, RepositoryEntry testEntry, IdentityRef identity); + /** * Retrieve the sessions for a test. * diff --git a/src/main/java/org/olat/ims/qti21/manager/AssessmentTestSessionDAO.java b/src/main/java/org/olat/ims/qti21/manager/AssessmentTestSessionDAO.java index 053582b7822..f45e969ae95 100644 --- a/src/main/java/org/olat/ims/qti21/manager/AssessmentTestSessionDAO.java +++ b/src/main/java/org/olat/ims/qti21/manager/AssessmentTestSessionDAO.java @@ -354,6 +354,35 @@ public class AssessmentTestSessionDAO { return query.getResultList(); } + public AssessmentTestSession getLastUserTestSession(RepositoryEntryRef courseEntry, String courseSubIdent, RepositoryEntry testEntry, IdentityRef identity) { + StringBuilder sb = new StringBuilder(); + sb.append("select session from qtiassessmenttestsession session") + .append(" left join fetch session.testEntry testEntry") + .append(" left join fetch testEntry.olatResource testResource") + .append(" where session.repositoryEntry.key=:repositoryEntryKey and session.identity.key=:identityKey ") + .append(" and session.testEntry.key=:testEntryKey and (session.finishTime is not null or session.terminationTime is not null) and "); + if(StringHelper.containsNonWhitespace(courseSubIdent)) { + sb.append("session.subIdent=:subIdent"); + } else { + sb.append("session.subIdent is null"); + } + sb.append(" order by session.creationDate desc"); + + TypedQuery<AssessmentTestSession> query = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), AssessmentTestSession.class) + .setParameter("repositoryEntryKey", courseEntry.getKey()) + .setParameter("testEntryKey", testEntry.getKey()) + .setParameter("identityKey", identity.getKey()); + if(StringHelper.containsNonWhitespace(courseSubIdent)) { + query.setParameter("subIdent", courseSubIdent); + } + List<AssessmentTestSession> sessions = query + .setFirstResult(0) + .setMaxResults(1) + .getResultList(); + return sessions.size() > 0 ? sessions.get(0) : null; + } + public List<AssessmentTestSession> getRunningTestSessions(RepositoryEntryRef entry, String courseSubIdent, RepositoryEntry testEntry) { StringBuilder sb = new StringBuilder(); sb.append("select session from qtiassessmenttestsession session") diff --git a/src/main/java/org/olat/ims/qti21/manager/QTI21ServiceImpl.java b/src/main/java/org/olat/ims/qti21/manager/QTI21ServiceImpl.java index 49bd29f58a0..957d5e2c123 100644 --- a/src/main/java/org/olat/ims/qti21/manager/QTI21ServiceImpl.java +++ b/src/main/java/org/olat/ims/qti21/manager/QTI21ServiceImpl.java @@ -476,6 +476,12 @@ public class QTI21ServiceImpl implements QTI21Service, UserDataDeletable, Initia public List<AssessmentTestSession> getAssessmentTestSessions(RepositoryEntryRef courseEntry, String subIdent, IdentityRef identity) { return testSessionDao.getUserTestSessions(courseEntry, subIdent, identity); } + + @Override + public AssessmentTestSession getLastAssessmentTestSessions(RepositoryEntryRef courseEntry, String subIdent, + RepositoryEntry testEntry, IdentityRef identity) { + return testSessionDao.getLastUserTestSession(courseEntry, subIdent, testEntry, identity); + } @Override public List<AssessmentTestSession> getAssessmentTestSessions(RepositoryEntryRef courseEntry, String subIdent, RepositoryEntry testEntry) { diff --git a/src/main/java/org/olat/ims/qti21/ui/AssessmentTestDisplayController.java b/src/main/java/org/olat/ims/qti21/ui/AssessmentTestDisplayController.java index fd8079b5046..af61754803f 100644 --- a/src/main/java/org/olat/ims/qti21/ui/AssessmentTestDisplayController.java +++ b/src/main/java/org/olat/ims/qti21/ui/AssessmentTestDisplayController.java @@ -1196,14 +1196,12 @@ public class AssessmentTestDisplayController extends BasicController implements } } } - - if(score != null || pass != null) { - if(submit) { - outcomesListener.submit(score, pass, candidateSession.getKey()); - } else { - outcomesListener.updateOutcomes(score, pass); - } - } + + if(submit) { + outcomesListener.submit(score, pass, candidateSession.getKey()); + } else { + outcomesListener.updateOutcomes(score, pass); + } } private AssessmentResult computeTestAssessmentResult(UserRequest ureq, final AssessmentTestSession testSession) { -- GitLab