From b36ff68fb775288eae484778d65288757cadb7ca Mon Sep 17 00:00:00 2001
From: srosse <none@none>
Date: Thu, 12 Mar 2015 09:42:04 +0100
Subject: [PATCH] OO-1349: add isAssessmentMode function to the expert rules

---
 .../assessment/AssessmentModeManager.java     |  8 +++
 .../manager/AssessmentModeManagerImpl.java    | 23 +++++-
 .../interpreter/ConditionInterpreter.java     |  3 +-
 .../interpreter/IsAssessmentModeFunction.java | 71 +++++++++++++++++++
 .../OnlyGroupConditionInterpreter.java        |  1 +
 .../course/editor/_chelp/ced-expert-eg.html   |  3 +
 .../editor/_i18n/LocalStrings_de.properties   |  1 +
 .../editor/_i18n/LocalStrings_en.properties   |  1 +
 .../manager/AssessmentModeManagerTest.java    | 34 +++++++++
 9 files changed, 143 insertions(+), 2 deletions(-)
 create mode 100644 src/main/java/org/olat/course/condition/interpreter/IsAssessmentModeFunction.java

diff --git a/src/main/java/org/olat/course/assessment/AssessmentModeManager.java b/src/main/java/org/olat/course/assessment/AssessmentModeManager.java
index 00df18a5097..0924eda773a 100644
--- a/src/main/java/org/olat/course/assessment/AssessmentModeManager.java
+++ b/src/main/java/org/olat/course/assessment/AssessmentModeManager.java
@@ -97,6 +97,14 @@ public interface AssessmentModeManager {
 	 */
 	public List<AssessmentMode> getAssessmentModes(Date now);
 	
+	/**
+	 * Return true if the course is in assessment mode at the specified time.
+	 * @param entry
+	 * @param now
+	 * @return
+	 */
+	public boolean isInAssessmentMode(RepositoryEntryRef entry, Date date);
+	
 	public Set<Long> getAssessedIdentityKeys(AssessmentMode assessmentMode);
 	
 	/**
diff --git a/src/main/java/org/olat/course/assessment/manager/AssessmentModeManagerImpl.java b/src/main/java/org/olat/course/assessment/manager/AssessmentModeManagerImpl.java
index 848bf763c45..e6b798264b4 100644
--- a/src/main/java/org/olat/course/assessment/manager/AssessmentModeManagerImpl.java
+++ b/src/main/java/org/olat/course/assessment/manager/AssessmentModeManagerImpl.java
@@ -360,7 +360,7 @@ public class AssessmentModeManagerImpl implements AssessmentModeManager {
 		
 		StringBuilder sb = new StringBuilder();
 		sb.append("select mode from courseassessmentmode mode where ")
-		  .append(" (mode.beginWithLeadTime<=:now and mode.endWithFollowupTime>=:now and mode.manualBeginEnd=false	)")
+		  .append(" (mode.beginWithLeadTime<=:now and mode.endWithFollowupTime>=:now and mode.manualBeginEnd=false)")
 		  .append(" or mode.statusString in ('").append(Status.leadtime.name()).append("','")
 		  .append(Status.assessment.name()).append("','").append(Status.followup.name()).append("')");
 
@@ -370,6 +370,27 @@ public class AssessmentModeManagerImpl implements AssessmentModeManager {
 				.getResultList();
 	}
 
+	@Override
+	public boolean isInAssessmentMode(RepositoryEntryRef entry, Date date) {
+		Calendar cal = Calendar.getInstance();
+		cal.set(Calendar.MILLISECOND, 0);
+		cal.set(Calendar.SECOND, 0);
+		
+		StringBuilder sb = new StringBuilder();
+		sb.append("select count(mode) from courseassessmentmode mode where ")
+		  .append(" mode.repositoryEntry.key=:repoKey and (")
+		  .append(" (mode.beginWithLeadTime<=:now and mode.endWithFollowupTime>=:now and mode.manualBeginEnd=false)")
+		  .append(" or mode.statusString in ('").append(Status.leadtime.name()).append("','")
+		  .append(Status.assessment.name()).append("','").append(Status.followup.name()).append("'))");
+
+		List<Number> count = dbInstance.getCurrentEntityManager()
+				.createQuery(sb.toString(), Number.class)
+				.setParameter("now", date)
+				.setParameter("repoKey", entry.getKey())
+				.getResultList();
+		return count != null && count.size() > 0 && count.get(0).intValue() > 0;
+	}
+
 	@Override
 	public AssessmentModeToGroup createAssessmentModeToGroup(AssessmentMode mode, BusinessGroup group) {
 		AssessmentModeToGroupImpl modeToGroup = new AssessmentModeToGroupImpl();
diff --git a/src/main/java/org/olat/course/condition/interpreter/ConditionInterpreter.java b/src/main/java/org/olat/course/condition/interpreter/ConditionInterpreter.java
index 5bf81a62077..726bd90fa3a 100644
--- a/src/main/java/org/olat/course/condition/interpreter/ConditionInterpreter.java
+++ b/src/main/java/org/olat/course/condition/interpreter/ConditionInterpreter.java
@@ -133,7 +133,8 @@ public class ConditionInterpreter {
 		env.addFunction(IsCourseCoachFunction.name, new IsCourseCoachFunction(userCourseEnv));
 		env.addFunction(IsCourseParticipantFunction.name, new IsCourseParticipantFunction(userCourseEnv));
 		env.addFunction(IsCourseAdministratorFunction.name, new IsCourseAdministratorFunction(userCourseEnv));
-
+		
+		env.addFunction(IsAssessmentModeFunction.name, new IsAssessmentModeFunction(userCourseEnv));
 		env.addFunction(GetCourseBeginDateFunction.name, new GetCourseBeginDateFunction(userCourseEnv));
 		env.addFunction(GetCourseEndDateFunction.name, new GetCourseEndDateFunction(userCourseEnv));
 		env.addFunction(GetInitialCourseLaunchDateFunction.name, new GetInitialCourseLaunchDateFunction(userCourseEnv));
diff --git a/src/main/java/org/olat/course/condition/interpreter/IsAssessmentModeFunction.java b/src/main/java/org/olat/course/condition/interpreter/IsAssessmentModeFunction.java
new file mode 100644
index 00000000000..1635bb3ca84
--- /dev/null
+++ b/src/main/java/org/olat/course/condition/interpreter/IsAssessmentModeFunction.java
@@ -0,0 +1,71 @@
+/**
+ * <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.condition.interpreter;
+
+import java.util.Date;
+
+import org.olat.core.CoreSpringFactory;
+import org.olat.course.assessment.AssessmentModeManager;
+import org.olat.course.editor.CourseEditorEnv;
+import org.olat.course.run.userview.UserCourseEnvironment;
+import org.olat.repository.RepositoryEntry;
+
+/**
+ * 
+ * Initial date: 12.03.2015<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class IsAssessmentModeFunction extends AbstractFunction {
+	public static final String name = "isAssessmentMode";
+
+	/**
+	 * Constructor
+	 * @param userCourseEnv
+	 */
+	public IsAssessmentModeFunction(UserCourseEnvironment userCourseEnv) {
+		super(userCourseEnv);
+	}
+
+	/**
+	 * @see com.neemsoft.jmep.FunctionCB#call(java.lang.Object[])
+	 */
+	@Override
+	public Object call(Object[] inStack) {
+		/*
+		 * expression check only if cev != null
+		 */
+		CourseEditorEnv cev = getUserCourseEnv().getCourseEditorEnv();
+		if (cev != null) {
+			// return a valid value to continue with condition evaluation test
+			return defaultValue();
+		}
+
+		AssessmentModeManager assessmentModeMgr = CoreSpringFactory.getImpl(AssessmentModeManager.class);
+		RepositoryEntry entry = getUserCourseEnv().getCourseEnvironment().getCourseGroupManager().getCourseEntry();
+		boolean inAssessment = assessmentModeMgr.isInAssessmentMode(entry, new Date());
+		return inAssessment ? ConditionInterpreter.INT_TRUE: ConditionInterpreter.INT_FALSE;
+	}
+
+	@Override
+	protected Object defaultValue() {
+		return ConditionInterpreter.INT_TRUE;
+	}
+}
\ No newline at end of file
diff --git a/src/main/java/org/olat/course/condition/interpreter/OnlyGroupConditionInterpreter.java b/src/main/java/org/olat/course/condition/interpreter/OnlyGroupConditionInterpreter.java
index 09e63743ba7..9276afbbdc5 100644
--- a/src/main/java/org/olat/course/condition/interpreter/OnlyGroupConditionInterpreter.java
+++ b/src/main/java/org/olat/course/condition/interpreter/OnlyGroupConditionInterpreter.java
@@ -80,6 +80,7 @@ public class OnlyGroupConditionInterpreter extends ConditionInterpreter{
 		env.addFunction(IsCourseCoachFunction.name, new DummyBooleanFunction(userCourseEnv));
 		env.addFunction(IsCourseParticipantFunction.name, new DummyBooleanFunction(userCourseEnv));
 		env.addFunction(IsCourseAdministratorFunction.name, new DummyBooleanFunction(userCourseEnv));
+		env.addFunction(IsAssessmentModeFunction.name, new DummyBooleanFunction(userCourseEnv));
 
 		env.addFunction(GetAttemptsFunction.name, new DummyIntegerFunction(userCourseEnv));
 
diff --git a/src/main/java/org/olat/course/editor/_chelp/ced-expert-eg.html b/src/main/java/org/olat/course/editor/_chelp/ced-expert-eg.html
index 26c59deda29..6fe4ab4e102 100644
--- a/src/main/java/org/olat/course/editor/_chelp/ced-expert-eg.html
+++ b/src/main/java/org/olat/course/editor/_chelp/ced-expert-eg.html
@@ -73,6 +73,9 @@
 		<tr> 
 			<td><b>(getCourseBeginDate(0) &lt;= today) &amp; (getCourseEndDate(0) &gt;= today)</b> <br/>$r.translate("chelp.egR17") <br/><br/></td>
 		</tr>
+		<tr> 
+			<td><b>isAssessmentMode(0)</b> <br/>$r.translate("chelp.egR18") <br/><br/></td>
+		</tr>
 	</tbody>
 </table>
 <br/>
diff --git a/src/main/java/org/olat/course/editor/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/editor/_i18n/LocalStrings_de.properties
index da3c15d6861..c01aac1a607 100644
--- a/src/main/java/org/olat/course/editor/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/course/editor/_i18n/LocalStrings_de.properties
@@ -159,6 +159,7 @@ chelp.egR14=Gibt $\:chelp.wordTrue w\u00E4hrend zwei Stunden ab Einschreibezeitp
 chelp.egR15=Gibt $\:chelp.wordTrue, wenn der Kursteilnehmer den Kurs noch nicht besucht hat oder w\u00E4hrend zwei Stunden seit dem ersten Kursbesuch. So kann abgebildet werden, dass jeder Kursteilnehmer nur w\u00E4hrend einer bestimmten Zeitdauer den Kurs sehen kann.
 chelp.egR16=Gibt $\:chelp.wordTrue, wenn sich der Benutzer seit mehr als 10 Minuten im Kurs bewegt.
 chelp.egR17=Gibt den Wert $\:chelp.wordTrue zur\u00FCck, wenn das heutige Datum zwischen Beginn- und Enddatum des Durchf\u00FChrungszeitraums des Kurses liegt.
+chelp.egR18=Gibt $\:chelp.wordTrue sobald der Kurs innerhalb eine Pr\u00FCfung ist.
 chelp.egR2=Mit Ausnahme der Gruppe <i>&laquo;$\:chelp.deb&raquo;</i> ist der Kursbaustein f\u00FCr alle Kursteilnehmer sichtbar.
 chelp.egR3=Der Kursbaustein ist zwischen dem 22.03.2004 und 23.08.2004 f\u00FCr alle Kursteilnehmer sichtbar, w\u00E4hrend er f\u00FCr Mitglieder der Lerngruppe <i>&laquo;$\:chelp.coach&raquo;</i> jederzeit sichtbar ist.
 chelp.egR4=Der Kursbaustein ist zwischen dem 03.09.2004 und 13.10.2004 f\u00FCr alle Kursteilnehmer der Rechtegruppe <i>&laquo;$\:chelp.asses&raquo;</i> sichtbar, w\u00E4hrend er f\u00FCr die Person mit dem Benutzernamen <i>&laquo;$\:chelp.author&raquo;</i> jederzeit sichtbar ist.
diff --git a/src/main/java/org/olat/course/editor/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/editor/_i18n/LocalStrings_en.properties
index c42f3cdd79d..338e24e5a97 100644
--- a/src/main/java/org/olat/course/editor/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/course/editor/_i18n/LocalStrings_en.properties
@@ -159,6 +159,7 @@ chelp.egR14=Generates $\:chelp.wordTrue within two hours starting at the moment
 chelp.egR15=Generates $\:chelp.wordTrue if a course participant has not yet taken any courses or during the first two hours after taking a course. This way it is possible represent that each course participant can only see courses for a certain period of time.
 chelp.egR16=Generates $\:chelp.wordTrue if a user is active for more than 10 min within a course.
 chelp.egR17=Returns the value $\:chelp.wordTrue if today's date lies in between the start and end date of the execution period.
+chelp.egR18=Returns the value $\:chelp.wordTrue if the course is within an assessment.
 chelp.egR2=With the exception of the group <i>&laquo;$\:chelp.deb&raquo;</i> this course element is visible for all participants.
 chelp.egR3=This course element is visible for all participants between 22-3-2004 and 23-8-2004. For members of the learning group <i>&laquo;$\:chelp.coach&raquo;</i> it is always visible.
 chelp.egR4=This course element is visible for all participants of the right group <i>&laquo;$\:chelp.asses&raquo;</i> between 3-9-2004 and 13-10-2004. For the person with the user name <i>&laquo;$\:chelp.author&raquo;</i> it is always visible.
diff --git a/src/test/java/org/olat/course/assessment/manager/AssessmentModeManagerTest.java b/src/test/java/org/olat/course/assessment/manager/AssessmentModeManagerTest.java
index 7da62aee266..b25e62cae21 100644
--- a/src/test/java/org/olat/course/assessment/manager/AssessmentModeManagerTest.java
+++ b/src/test/java/org/olat/course/assessment/manager/AssessmentModeManagerTest.java
@@ -270,6 +270,33 @@ public class AssessmentModeManagerTest extends OlatTestCase {
 		Assert.assertTrue(currentModes.contains(mode));
 	}
 	
+	@Test
+	public void isInAssessmentMode() {
+		RepositoryEntry entry = JunitTestHelper.createAndPersistRepositoryEntry();
+		RepositoryEntry entryReference = JunitTestHelper.createAndPersistRepositoryEntry();
+		AssessmentMode mode = createMinimalAssessmentmode(entry);
+		mode = assessmentModeMgr.persist(mode);
+		dbInstance.commitAndCloseSession();
+		Assert.assertNotNull(mode);
+		
+		//check
+		Date now = new Date();
+		boolean entryNow = assessmentModeMgr.isInAssessmentMode(entry, now);
+		Assert.assertTrue(entryNow);
+		
+		//no assessment for this course
+		boolean entryReferenceNow = assessmentModeMgr.isInAssessmentMode(entryReference, now);
+		Assert.assertFalse(entryReferenceNow);
+		
+		//out of assessment scope
+		Calendar cal = Calendar.getInstance();
+		cal.setTime(now);
+		cal.add(Calendar.DATE, -1);
+		Date aDayBefore = cal.getTime();
+		boolean entryReferencePast = assessmentModeMgr.isInAssessmentMode(entryReference, aDayBefore);
+		Assert.assertFalse(entryReferencePast);
+	}
+	
 	/**
 	 * Check an assessment linked to a group with one participant
 	 * 
@@ -670,6 +697,13 @@ public class AssessmentModeManagerTest extends OlatTestCase {
 		Assert.assertFalse(notAllowed4);
 	}
 
+	/**
+	 * Create a minimal assessment mode which start one hour before now
+	 * and stop two hours after now.
+	 * 
+	 * @param entry
+	 * @return
+	 */
 	private AssessmentMode createMinimalAssessmentmode(RepositoryEntry entry) {
 		AssessmentMode mode = assessmentModeMgr.createAssessmentMode(entry);
 		mode.setName("Assessment to load");
-- 
GitLab