diff --git a/src/main/java/org/olat/course/assessment/AssessmentAction.java b/src/main/java/org/olat/course/assessment/AssessmentAction.java
index 4305bc40c2ea261b6f51b625e88b8374e3d1b698..0cf51148cef362f7d3b3df3502d186436e35c7b4 100644
--- a/src/main/java/org/olat/course/assessment/AssessmentAction.java
+++ b/src/main/java/org/olat/course/assessment/AssessmentAction.java
@@ -27,7 +27,7 @@ package org.olat.course.assessment;
  */
 public enum AssessmentAction {
 
-	nodeClicked,
+	nodeVisited,
 	confirmed
 	
 }
diff --git a/src/main/java/org/olat/course/assessment/AssessmentManager.java b/src/main/java/org/olat/course/assessment/AssessmentManager.java
index 152fc0f08f7bc936775bfba940511fda26b36cb1..1e5701a2d75a1ecf0ab56f7c7d278309d11c7dea 100644
--- a/src/main/java/org/olat/course/assessment/AssessmentManager.java
+++ b/src/main/java/org/olat/course/assessment/AssessmentManager.java
@@ -98,6 +98,8 @@ public interface AssessmentManager {
 	public void updateCurrentCompletion(CourseNode courseNode, Identity assessedIdentity, UserCourseEnvironment userCourseEnvironment,
 			Double currentCompletion, AssessmentRunStatus status, Role by);
 
+	public void updateAssessmentStatus(CourseNode courseNode, Identity assessedIdentity, AssessmentEntryStatus status, Role by);
+	
 	/**
 	 * Save an assessment comment for this node for a user. If there is already a comment property available, 
 	 * it will be overwritten with the new value
@@ -275,7 +277,7 @@ public interface AssessmentManager {
 	 */
 	public Boolean getNodeFullyAssessed(CourseNode courseNode, Identity identity);
 	
-
+	
 	public AssessmentEntry getAssessmentEntry(CourseNode courseNode, Identity assessedIdentity);
 	
 	public AssessmentEntry createAssessmentEntry(CourseNode courseNode, Identity assessedIdentity, ScoreEvaluation scoreEvaluation);
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 704e29e30aa6cfb338c3e8ba65656756ef3ce99a..4aeebb7908cd87fc28f3be354ca1f86d2a2fecc7 100644
--- a/src/main/java/org/olat/course/assessment/manager/CourseAssessmentManagerImpl.java
+++ b/src/main/java/org/olat/course/assessment/manager/CourseAssessmentManagerImpl.java
@@ -417,6 +417,20 @@ public class CourseAssessmentManagerImpl implements AssessmentManager {
 		DBFactory.getInstance().commit();
 	}
 
+	@Override
+	public void updateAssessmentStatus(CourseNode courseNode, Identity assessedIdentity, AssessmentEntryStatus status,
+			Role by) {
+		AssessmentEntry nodeAssessment = getOrCreate(assessedIdentity, courseNode);
+		if(by == Role.coach) {
+			nodeAssessment.setLastCoachModified(new Date());
+		} else if(by == Role.user) {
+			nodeAssessment.setLastUserModified(new Date());
+		}
+		nodeAssessment.setAssessmentStatus(status);
+		assessmentService.updateAssessmentEntry(nodeAssessment);
+		DBFactory.getInstance().commit();
+	}
+
 	@Override
 	public void saveScoreEvaluation(CourseNode courseNode, Identity identity, Identity assessedIdentity,
 			ScoreEvaluation scoreEvaluation, UserCourseEnvironment userCourseEnv,
diff --git a/src/main/java/org/olat/course/learningpath/LearningPathConfigs.java b/src/main/java/org/olat/course/learningpath/LearningPathConfigs.java
new file mode 100644
index 0000000000000000000000000000000000000000..e065ba78abb4e05aa58e21a12e418fa29fb559a7
--- /dev/null
+++ b/src/main/java/org/olat/course/learningpath/LearningPathConfigs.java
@@ -0,0 +1,32 @@
+/**
+ * <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.learningpath;
+
+/**
+ * 
+ * Initial date: 30 Aug 2019<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+public interface LearningPathConfigs {
+
+	boolean isDoneOnNodeVisited();
+
+}
diff --git a/src/main/java/org/olat/course/learningpath/LearningPathNodeAccessProvider.java b/src/main/java/org/olat/course/learningpath/LearningPathNodeAccessProvider.java
index 2c830c4c3810d6e846932149a196d65869578cb5..a06400cadb4ac10bc8cc82bc0092a184fc6b0f7d 100644
--- a/src/main/java/org/olat/course/learningpath/LearningPathNodeAccessProvider.java
+++ b/src/main/java/org/olat/course/learningpath/LearningPathNodeAccessProvider.java
@@ -31,12 +31,18 @@ import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.generic.tabbable.TabbableController;
 import org.olat.core.gui.translator.Translator;
+import org.olat.core.id.Identity;
 import org.olat.core.util.Util;
+import org.olat.course.assessment.AssessmentManager;
 import org.olat.course.learningpath.manager.UnsupportedLearningPathNodeHandler;
-import org.olat.course.learningpath.ui.LeaningPathNodeConfigController;
+import org.olat.course.learningpath.ui.LearningPathNodeConfigController;
 import org.olat.course.learningpath.ui.TabbableLeaningPathNodeConfigController;
 import org.olat.course.nodeaccess.NodeAccessProvider;
 import org.olat.course.nodes.CourseNode;
+import org.olat.course.run.navigation.NodeVisitedListener;
+import org.olat.course.run.userview.UserCourseEnvironment;
+import org.olat.modules.assessment.Role;
+import org.olat.modules.assessment.model.AssessmentEntryStatus;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -47,7 +53,7 @@ import org.springframework.stereotype.Service;
  *
  */
 @Service
-public class LearningPathNodeAccessProvider implements NodeAccessProvider {
+public class LearningPathNodeAccessProvider implements NodeAccessProvider, NodeVisitedListener {
 
 	private static final String UNSUPPORTED_LEARNING_PATH_TYPE = UnsupportedLearningPathNodeHandler.NODE_TYPE;
 	
@@ -67,7 +73,7 @@ public class LearningPathNodeAccessProvider implements NodeAccessProvider {
 		}
 	}
 	
-	private  LearningPathNodeHandler getLearningPathNodeHandler(String courseNodeType) {
+	private LearningPathNodeHandler getLearningPathNodeHandler(String courseNodeType) {
 		LearningPathNodeHandler handler = learningPathNodeHandlers.get(courseNodeType);
 		if (handler == null) {
 			handler = nonLearningPathNodeHandler;
@@ -75,10 +81,14 @@ public class LearningPathNodeAccessProvider implements NodeAccessProvider {
 		return handler;
 	}
 
-	private  LearningPathNodeHandler getLearningPathNodeHandler(CourseNode courseNode) {
+	private LearningPathNodeHandler getLearningPathNodeHandler(CourseNode courseNode) {
 		return getLearningPathNodeHandler(courseNode.getType());
 	}
 	
+	private LearningPathConfigs getConfigs(CourseNode courseNode) {
+		return getLearningPathNodeHandler(courseNode).getConfigs(courseNode);
+	}
+	
 	@Override
 	public String getType() {
 		return "learningpath";
@@ -86,7 +96,7 @@ public class LearningPathNodeAccessProvider implements NodeAccessProvider {
 
 	@Override
 	public String getDisplayName(Locale locale) {
-		Translator translator = Util.createPackageTranslator(LeaningPathNodeConfigController.class, locale);
+		Translator translator = Util.createPackageTranslator(LearningPathNodeConfigController.class, locale);
 		return translator.translate("access.provider.name");
 	}
 
@@ -97,8 +107,19 @@ public class LearningPathNodeAccessProvider implements NodeAccessProvider {
 	
 	@Override
 	public TabbableController createEditController(UserRequest ureq, WindowControl wControl, CourseNode courseNode) {
-		Controller configCtrl = getLearningPathNodeHandler(courseNode).createEditController(ureq, wControl, courseNode);
+		Controller configCtrl = getLearningPathNodeHandler(courseNode).createConfigEditController(ureq, wControl, courseNode);
 		return new TabbableLeaningPathNodeConfigController(ureq, wControl, configCtrl);
 	}
 
+	@Override
+	public void onNodeVisited(CourseNode courseNode, UserCourseEnvironment userCourseEnvironment) {
+		boolean doneOnNodeStarted = getConfigs(courseNode).isDoneOnNodeVisited();
+		boolean participant = userCourseEnvironment.isParticipant();
+		if (doneOnNodeStarted && participant) {
+			AssessmentManager am = userCourseEnvironment.getCourseEnvironment().getAssessmentManager();
+			Identity identity = userCourseEnvironment.getIdentityEnvironment().getIdentity();
+			am.updateAssessmentStatus(courseNode, identity, AssessmentEntryStatus.done, Role.user);
+		}
+	}
+
 }
diff --git a/src/main/java/org/olat/course/learningpath/LearningPathNodeHandler.java b/src/main/java/org/olat/course/learningpath/LearningPathNodeHandler.java
index b9af39fffa37830d63254583027a9de8dc382ba3..11d3a5de32d9a59486a8240f72b5dba0364761d2 100644
--- a/src/main/java/org/olat/course/learningpath/LearningPathNodeHandler.java
+++ b/src/main/java/org/olat/course/learningpath/LearningPathNodeHandler.java
@@ -36,6 +36,8 @@ public interface LearningPathNodeHandler {
 	
 	public boolean isSupported();
 	
-	public Controller createEditController(UserRequest ureq, WindowControl wControl, CourseNode courseNode);
+	public LearningPathConfigs getConfigs(CourseNode courseNode);
+	
+	public Controller createConfigEditController(UserRequest ureq, WindowControl wControl, CourseNode courseNode);
 
 }
diff --git a/src/main/java/org/olat/course/learningpath/manager/UnsupportedLearningPathNodeHandler.java b/src/main/java/org/olat/course/learningpath/manager/UnsupportedLearningPathNodeHandler.java
index 1a19f66eff356e8e1c8e9654e73f7bc26ad37f32..5446810c11ccb9100bc34f2300aead4e7db61a07 100644
--- a/src/main/java/org/olat/course/learningpath/manager/UnsupportedLearningPathNodeHandler.java
+++ b/src/main/java/org/olat/course/learningpath/manager/UnsupportedLearningPathNodeHandler.java
@@ -22,7 +22,9 @@ package org.olat.course.learningpath.manager;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.WindowControl;
+import org.olat.course.learningpath.LearningPathConfigs;
 import org.olat.course.learningpath.LearningPathNodeHandler;
+import org.olat.course.learningpath.model.UnsupportedLearningPathConfigs;
 import org.olat.course.nodes.CourseNode;
 import org.springframework.stereotype.Service;
 
@@ -37,6 +39,8 @@ public class UnsupportedLearningPathNodeHandler implements LearningPathNodeHandl
 
 	public static final String NODE_TYPE = "unsupported.learning.path.nodes";
 
+	private static final UnsupportedLearningPathConfigs UNSUPPORTED_LEARNING_PATH_CONFIGS = new UnsupportedLearningPathConfigs();
+
 	@Override
 	public String acceptCourseNodeType() {
 		return NODE_TYPE;
@@ -48,7 +52,12 @@ public class UnsupportedLearningPathNodeHandler implements LearningPathNodeHandl
 	}
 
 	@Override
-	public Controller createEditController(UserRequest ureq, WindowControl wControl, CourseNode courseNode) {
+	public LearningPathConfigs getConfigs(CourseNode courseNode) {
+		return UNSUPPORTED_LEARNING_PATH_CONFIGS;
+	}
+
+	@Override
+	public Controller createConfigEditController(UserRequest ureq, WindowControl wControl, CourseNode courseNode) {
 		return null;
 	}
 
diff --git a/src/main/java/org/olat/course/learningpath/model/ModuleLearningPathConfigs.java b/src/main/java/org/olat/course/learningpath/model/ModuleLearningPathConfigs.java
new file mode 100644
index 0000000000000000000000000000000000000000..ac3e8863c1f3de93d9324470aa57dc9967919b1d
--- /dev/null
+++ b/src/main/java/org/olat/course/learningpath/model/ModuleLearningPathConfigs.java
@@ -0,0 +1,53 @@
+/**
+ * <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.learningpath.model;
+
+import static org.olat.course.learningpath.ui.LearningPathNodeConfigController.CONFIG_DEFAULT_DONE_TRIGGER;
+import static org.olat.course.learningpath.ui.LearningPathNodeConfigController.CONFIG_KEY_DONE_TRIGGER;
+
+import org.olat.course.assessment.AssessmentAction;
+import org.olat.course.learningpath.LearningPathConfigs;
+import org.olat.modules.ModuleConfiguration;
+
+/**
+ * 
+ * Initial date: 30 Aug 2019<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+public class ModuleLearningPathConfigs implements LearningPathConfigs {
+	
+	private final ModuleConfiguration moduleConfiguration;
+
+	public ModuleLearningPathConfigs(ModuleConfiguration moduleConfiguration) {
+		this.moduleConfiguration = moduleConfiguration;
+	}
+
+	@Override
+	public boolean isDoneOnNodeVisited() {
+		String doneTriggerName = getDoneTriggerName();
+		return AssessmentAction.nodeVisited.name().equals(doneTriggerName);
+	}
+
+	private String getDoneTriggerName() {
+		return moduleConfiguration.getStringValue(CONFIG_KEY_DONE_TRIGGER, CONFIG_DEFAULT_DONE_TRIGGER);
+	}
+
+}
diff --git a/src/main/java/org/olat/course/learningpath/model/UnsupportedLearningPathConfigs.java b/src/main/java/org/olat/course/learningpath/model/UnsupportedLearningPathConfigs.java
new file mode 100644
index 0000000000000000000000000000000000000000..18ea79773eaac3a5ecfe8e49962044624b834751
--- /dev/null
+++ b/src/main/java/org/olat/course/learningpath/model/UnsupportedLearningPathConfigs.java
@@ -0,0 +1,37 @@
+/**
+ * <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.learningpath.model;
+
+import org.olat.course.learningpath.LearningPathConfigs;
+
+/**
+ * 
+ * Initial date: 30 Aug 2019<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+public class UnsupportedLearningPathConfigs implements LearningPathConfigs {
+
+	@Override
+	public boolean isDoneOnNodeVisited() {
+		return false;
+	}
+
+}
diff --git a/src/main/java/org/olat/course/learningpath/ui/LeaningPathNodeConfigController.java b/src/main/java/org/olat/course/learningpath/ui/LearningPathNodeConfigController.java
similarity index 94%
rename from src/main/java/org/olat/course/learningpath/ui/LeaningPathNodeConfigController.java
rename to src/main/java/org/olat/course/learningpath/ui/LearningPathNodeConfigController.java
index a31ea79948e6296c71e8bb58b7f64628e514e168..0ec8510ead03e028ed1562d9722d4b094776370e 100644
--- a/src/main/java/org/olat/course/learningpath/ui/LeaningPathNodeConfigController.java
+++ b/src/main/java/org/olat/course/learningpath/ui/LearningPathNodeConfigController.java
@@ -45,7 +45,7 @@ import org.olat.modules.ModuleConfiguration;
  * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
  *
  */
-public class LeaningPathNodeConfigController extends FormBasicController {
+public class LearningPathNodeConfigController extends FormBasicController {
 	
 	public static final String CONFIG_KEY_ESTIMATED_DURATION = "learning.path.estimated.duration";
 	public static final String CONFIG_KEY_OBLIGATION = "learning.path.obligation";
@@ -63,7 +63,7 @@ public class LeaningPathNodeConfigController extends FormBasicController {
 	private final ModuleConfiguration configs;
 	private final LearningPathControllerConfig ctrlConfig;
 
-	public LeaningPathNodeConfigController(UserRequest ureq, WindowControl wControl,
+	public LearningPathNodeConfigController(UserRequest ureq, WindowControl wControl,
 			ModuleConfiguration configs, LearningPathControllerConfig ctrlConfig) {
 		super(ureq, wControl);
 		this.configs = configs;
@@ -99,8 +99,9 @@ public class LeaningPathNodeConfigController extends FormBasicController {
 	
 	private KeyValues getDoneTriggerKV() {
 		KeyValues doneTriggerKV = new KeyValues();
-		if (ctrlConfig.getAssessmentActions().contains(AssessmentAction.nodeClicked)) {
-			doneTriggerKV.add(entry(AssessmentAction.nodeClicked.name(), translate("config.done.trigger.started")));
+		doneTriggerKV.add(entry(CONFIG_VALUE_DONE_TRIGGER_NONE, translate("config.done.trigger.none")));
+		if (ctrlConfig.getAssessmentActions().contains(AssessmentAction.nodeVisited)) {
+			doneTriggerKV.add(entry(AssessmentAction.nodeVisited.name(), translate("config.done.trigger.visited")));
 		}
 		if (ctrlConfig.getAssessmentActions().contains(AssessmentAction.confirmed)) {
 			doneTriggerKV.add(entry(AssessmentAction.confirmed.name(), translate("config.done.trigger.confirmed")));
@@ -144,10 +145,6 @@ public class LeaningPathNodeConfigController extends FormBasicController {
 
 	@Override
 	protected void formOK(UserRequest ureq) {
-		fireEvent(ureq, Event.DONE_EVENT);
-	}
-	
-	protected ModuleConfiguration getUpdatedConfig() {
 		String estimatedTime = estimatedDurationEl.getValue();
 		configs.setStringValue(CONFIG_KEY_ESTIMATED_DURATION, estimatedTime);
 		
@@ -161,7 +158,7 @@ public class LeaningPathNodeConfigController extends FormBasicController {
 				: CONFIG_DEFAULT_DONE_TRIGGER;
 		configs.setStringValue(CONFIG_KEY_DONE_TRIGGER, doneTrigger);
 		
-		return configs;
+		fireEvent(ureq, Event.DONE_EVENT);
 	}
 
 	@Override
diff --git a/src/main/java/org/olat/course/learningpath/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/learningpath/ui/_i18n/LocalStrings_de.properties
index e82e801641758af6343a6d648330f78d37c4fa11..a69096293473d7936529448126383e7675e6c1f3 100644
--- a/src/main/java/org/olat/course/learningpath/ui/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/course/learningpath/ui/_i18n/LocalStrings_de.properties
@@ -2,7 +2,8 @@ access.provider.name=Lernpfad
 error.positiv.int=Geben Sie eine positive Zahl ein.
 config.done.trigger=Lernfortschritt
 config.done.trigger.confirmed=Best\u00E4tigt
-config.done.trigger.started=Ge\u00F6ffnet
+config.done.trigger.none=W\u00E4hlen Sie einen Eintrag aus
+config.done.trigger.visited=Ge\u00F6ffnet
 config.estimated.duration=Zeitvorgabe (Minuten)
 congig.obligation=Pflicht
 config.obligation.mandatory=Obligatorisch
diff --git a/src/main/java/org/olat/course/learningpath/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/learningpath/ui/_i18n/LocalStrings_en.properties
index 389a8ac410283c1fac23b984c9ccf2b185cd7c11..9d2ccfe9eac8d228a717c45570fbd323e95c041f 100644
--- a/src/main/java/org/olat/course/learningpath/ui/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/course/learningpath/ui/_i18n/LocalStrings_en.properties
@@ -2,7 +2,8 @@ access.provider.name=Learning path
 error.positiv.int=Enter a positive number.
 config.done.trigger=Done trigger
 config.done.trigger.confirmed=Confirmed
-config.done.trigger.started=Opened
+config.done.trigger.none=Select an entry
+config.done.trigger.visited=Opened
 config.estimated.duration=Estimated duration (minutes)
 config.obligation=Obligation
 config.obligation.mandatory=Mandatory
diff --git a/src/main/java/org/olat/course/nodeaccess/NodeAccessType.java b/src/main/java/org/olat/course/nodeaccess/NodeAccessType.java
index a73f2b25fa8f5cfc31072082fd21bff7425ca8cb..c4c6d844bcdd1521393e55818dcfdd3649ede7de 100644
--- a/src/main/java/org/olat/course/nodeaccess/NodeAccessType.java
+++ b/src/main/java/org/olat/course/nodeaccess/NodeAccessType.java
@@ -21,6 +21,7 @@ package org.olat.course.nodeaccess;
 
 import org.olat.course.ICourse;
 import org.olat.course.nodeaccess.model.NodeAccessTypeImpl;
+import org.olat.course.run.userview.UserCourseEnvironment;
 
 /**
  * 
@@ -39,5 +40,9 @@ public interface NodeAccessType {
 	public static NodeAccessType of(ICourse course) {
 		return course.getCourseConfig().getNodeAccessType();
 	}
+	
+	public static NodeAccessType of(UserCourseEnvironment userCourseEnvironment) {
+		return userCourseEnvironment.getCourseEnvironment().getCourseConfig().getNodeAccessType();
+	}
 
 }
diff --git a/src/main/java/org/olat/course/nodes/sp/SPLearningPathNodeHandler.java b/src/main/java/org/olat/course/nodes/sp/SPLearningPathNodeHandler.java
index 0d4674e68756dfdf6082ef2fe593c050ec667b2a..91d5725d524966fd6c89ade2b2204431245e9576 100644
--- a/src/main/java/org/olat/course/nodes/sp/SPLearningPathNodeHandler.java
+++ b/src/main/java/org/olat/course/nodes/sp/SPLearningPathNodeHandler.java
@@ -23,9 +23,11 @@ import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.course.assessment.AssessmentAction;
+import org.olat.course.learningpath.LearningPathConfigs;
 import org.olat.course.learningpath.LearningPathNodeHandler;
-import org.olat.course.learningpath.ui.LeaningPathNodeConfigController;
-import org.olat.course.learningpath.ui.LeaningPathNodeConfigController.LearningPathControllerConfig;
+import org.olat.course.learningpath.model.ModuleLearningPathConfigs;
+import org.olat.course.learningpath.ui.LearningPathNodeConfigController;
+import org.olat.course.learningpath.ui.LearningPathNodeConfigController.LearningPathControllerConfig;
 import org.olat.course.nodes.CourseNode;
 import org.olat.course.nodes.SPCourseNode;
 import org.springframework.stereotype.Service;
@@ -50,11 +52,16 @@ public class SPLearningPathNodeHandler implements LearningPathNodeHandler {
 	}
 
 	@Override
-	public Controller createEditController(UserRequest ureq, WindowControl wControl, CourseNode courseNode) {
-		LearningPathControllerConfig ctrlConfig = LeaningPathNodeConfigController.builder()
-				.addAssessmentAction(AssessmentAction.nodeClicked)
+	public LearningPathConfigs getConfigs(CourseNode courseNode) {
+		return new ModuleLearningPathConfigs(courseNode.getModuleConfiguration());
+	}
+
+	@Override
+	public Controller createConfigEditController(UserRequest ureq, WindowControl wControl, CourseNode courseNode) {
+		LearningPathControllerConfig ctrlConfig = LearningPathNodeConfigController.builder()
+				.addAssessmentAction(AssessmentAction.nodeVisited)
 				.build();
-		return new LeaningPathNodeConfigController(ureq, wControl, courseNode.getModuleConfiguration(), ctrlConfig);
+		return new LearningPathNodeConfigController(ureq, wControl, courseNode.getModuleConfiguration(), ctrlConfig);
 	}
 
 }
diff --git a/src/main/java/org/olat/course/nodes/st/STLearningPathNodeHandler.java b/src/main/java/org/olat/course/nodes/st/STLearningPathNodeHandler.java
index afd7745fcfb2c2524998f4ae95c998116522195b..be6935535e8285945e1c30a8eee3643c52936ce8 100644
--- a/src/main/java/org/olat/course/nodes/st/STLearningPathNodeHandler.java
+++ b/src/main/java/org/olat/course/nodes/st/STLearningPathNodeHandler.java
@@ -25,7 +25,9 @@ import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.generic.messages.MessageUIFactory;
 import org.olat.core.gui.translator.Translator;
 import org.olat.core.util.Util;
+import org.olat.course.learningpath.LearningPathConfigs;
 import org.olat.course.learningpath.LearningPathNodeHandler;
+import org.olat.course.learningpath.model.ModuleLearningPathConfigs;
 import org.olat.course.learningpath.ui.TabbableLeaningPathNodeConfigController;
 import org.olat.course.nodes.CourseNode;
 import org.olat.course.nodes.STCourseNode;
@@ -51,7 +53,12 @@ public class STLearningPathNodeHandler implements LearningPathNodeHandler {
 	}
 
 	@Override
-	public Controller createEditController(UserRequest ureq, WindowControl wControl, CourseNode courseNode) {
+	public LearningPathConfigs getConfigs(CourseNode courseNode) {
+		return new ModuleLearningPathConfigs(courseNode.getModuleConfiguration());
+	}
+
+	@Override
+	public Controller createConfigEditController(UserRequest ureq, WindowControl wControl, CourseNode courseNode) {
 		Translator translator = Util.createPackageTranslator(TabbableLeaningPathNodeConfigController.class, ureq.getLocale());
 		return MessageUIFactory.createInfoMessage(ureq, wControl, null, translator.translate("no.configurations"));
 	}
diff --git a/src/main/java/org/olat/course/nodes/video/VideoLearningPathNodeHandler.java b/src/main/java/org/olat/course/nodes/video/VideoLearningPathNodeHandler.java
index 0ba8cefb528510ff902a7c169c075f28a2eec8e1..a358dcdbdeac54f134336c2419e979053e0fb6f3 100644
--- a/src/main/java/org/olat/course/nodes/video/VideoLearningPathNodeHandler.java
+++ b/src/main/java/org/olat/course/nodes/video/VideoLearningPathNodeHandler.java
@@ -23,9 +23,11 @@ import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.course.assessment.AssessmentAction;
+import org.olat.course.learningpath.LearningPathConfigs;
 import org.olat.course.learningpath.LearningPathNodeHandler;
-import org.olat.course.learningpath.ui.LeaningPathNodeConfigController;
-import org.olat.course.learningpath.ui.LeaningPathNodeConfigController.LearningPathControllerConfig;
+import org.olat.course.learningpath.model.ModuleLearningPathConfigs;
+import org.olat.course.learningpath.ui.LearningPathNodeConfigController;
+import org.olat.course.learningpath.ui.LearningPathNodeConfigController.LearningPathControllerConfig;
 import org.olat.course.nodes.CourseNode;
 import org.olat.course.nodes.VideoCourseNode;
 import org.springframework.stereotype.Service;
@@ -50,11 +52,16 @@ public class VideoLearningPathNodeHandler implements LearningPathNodeHandler {
 	}
 
 	@Override
-	public Controller createEditController(UserRequest ureq, WindowControl wControl, CourseNode courseNode) {
-		LearningPathControllerConfig ctrlConfig = LeaningPathNodeConfigController.builder()
-				.addAssessmentAction(AssessmentAction.nodeClicked)
+	public LearningPathConfigs getConfigs(CourseNode courseNode) {
+		return new ModuleLearningPathConfigs(courseNode.getModuleConfiguration());
+	}
+
+	@Override
+	public Controller createConfigEditController(UserRequest ureq, WindowControl wControl, CourseNode courseNode) {
+		LearningPathControllerConfig ctrlConfig = LearningPathNodeConfigController.builder()
+				.addAssessmentAction(AssessmentAction.nodeVisited)
 				.build();
-		return new LeaningPathNodeConfigController(ureq, wControl, courseNode.getModuleConfiguration(), ctrlConfig);
+		return new LearningPathNodeConfigController(ureq, wControl, courseNode.getModuleConfiguration(), ctrlConfig);
 	}
 
 }
diff --git a/src/main/java/org/olat/course/run/RunMainController.java b/src/main/java/org/olat/course/run/RunMainController.java
index f106a56dcd02f494568493b2d88cc1adbdaf89c1..0fb6d5760274b63d10f49c8d8e84fb9c0b05efe6 100644
--- a/src/main/java/org/olat/course/run/RunMainController.java
+++ b/src/main/java/org/olat/course/run/RunMainController.java
@@ -798,6 +798,7 @@ public class RunMainController extends MainLayoutBasicController implements Gene
 	/**
 	 * @see org.olat.core.gui.control.DefaultController#doDispose(boolean)
 	 */
+	@Override
 	protected void doDispose() {
 		// remove as listener from this course events:
 		// - group modification events
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 bfa924cc626a18fb514ba91e415da76a46bedc3f..1c44d050103c02b1bddce4e348db1c5a6f080201 100644
--- a/src/main/java/org/olat/course/run/preview/PreviewAssessmentManager.java
+++ b/src/main/java/org/olat/course/run/preview/PreviewAssessmentManager.java
@@ -122,24 +122,15 @@ final class PreviewAssessmentManager implements AssessmentManager {
 		//
 	}
 
-	/**
-	 * @see org.olat.course.assessment.AssessmentManager#saveNodeCoachComment(org.olat.course.nodes.CourseNode, org.olat.core.id.Identity, java.lang.String)
-	 */
 	@Override
 	public void saveNodeCoachComment(CourseNode courseNode, Identity assessedIdentity, String comment) {
 		throw new AssertException("Not implemented for preview.");
 	}
 
-	/**
-	 * @see org.olat.course.assessment.AssessmentManager#saveNodePassed(org.olat.course.nodes.CourseNode, org.olat.core.id.Identity, org.olat.core.id.Identity, java.lang.Boolean)
-	 */
 	private void saveNodePassed(CourseNode courseNode, Boolean passed) {
 		nodePassed.put(courseNode.getIdent(), passed);
 	}
 
-	/**
-	 * @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, Role by) {
 		Integer attempts = nodeAttempts.get(courseNode.getIdent());
@@ -149,10 +140,6 @@ final class PreviewAssessmentManager implements AssessmentManager {
 		nodeAttempts.put(courseNode.getIdent(), Integer.valueOf(iAttempts));
 	}
 	
-	/**
-	 * @see org.olat.course.assessment.AssessmentManager#incrementNodeAttemptsInBackground(org.olat.course.nodes.CourseNode,
-	 *      org.olat.core.id.Identity, org.olat.course.run.userview.UserCourseEnvironment)
-	 */
 	@Override
 	public void incrementNodeAttemptsInBackground(CourseNode courseNode, Identity identity, UserCourseEnvironment userCourseEnvironment) {
 		incrementNodeAttempts(courseNode, identity, userCourseEnvironment, Role.auto);
@@ -164,6 +151,12 @@ final class PreviewAssessmentManager implements AssessmentManager {
 		//
 	}
 
+	@Override
+	public void updateAssessmentStatus(CourseNode courseNode, Identity assessedIdentity, AssessmentEntryStatus status,
+			Role by) {
+		//
+	}
+
 	@Override
 	public void updateLastModifications(CourseNode courseNode, Identity assessedIdentity, UserCourseEnvironment userCourseEnvironment, Role by) {
 		//
@@ -174,17 +167,11 @@ final class PreviewAssessmentManager implements AssessmentManager {
 		//
 	}
 
-	/**
-	 * @see org.olat.course.assessment.AssessmentManager#getNodeScore(org.olat.course.nodes.CourseNode, org.olat.core.id.Identity)
-	 */
 	@Override
 	public Float getNodeScore(CourseNode courseNode, Identity identity) {
 		return nodeScores.get(courseNode.getIdent());
 	}
 
-	/**
-	 * @see org.olat.course.assessment.AssessmentManager#getNodeComment(org.olat.course.nodes.CourseNode, org.olat.core.id.Identity)
-	 */
 	@Override
 	public String getNodeComment(CourseNode courseNode, Identity identity) {
 		return "This is a preview"; //default comment for preview
@@ -195,17 +182,11 @@ final class PreviewAssessmentManager implements AssessmentManager {
 		return Collections.emptyList();
 	}
 
-	/**
-	 * @see org.olat.course.assessment.AssessmentManager#getNodeCoachComment(org.olat.course.nodes.CourseNode, org.olat.core.id.Identity)
-	 */
 	@Override
 	public String getNodeCoachComment(CourseNode courseNode, Identity identity) {
 		return "This is a preview"; //default comment for preview
 	}
 
-	/**
-	 * @see org.olat.course.assessment.AssessmentManager#getNodePassed(org.olat.course.nodes.CourseNode, org.olat.core.id.Identity)
-	 */
 	@Override
 	public Boolean getNodePassed(CourseNode courseNode, Identity identity) {
 		return nodePassed.get(courseNode.getIdent());
@@ -216,9 +197,6 @@ final class PreviewAssessmentManager implements AssessmentManager {
 		return nodePassed.get(courseNode.getIdent());
 	}
 
-	/**
-	 * @see org.olat.course.assessment.AssessmentManager#getNodeAttempts(org.olat.course.nodes.CourseNode, org.olat.core.id.Identity)
-	 */
 	@Override
 	public Integer getNodeAttempts(CourseNode courseNode, Identity identity) {
 		Integer attempts = nodeAttempts.get(courseNode.getIdent());
@@ -235,36 +213,20 @@ final class PreviewAssessmentManager implements AssessmentManager {
 		return null;
 	}
 
-	/**
-	 * @see org.olat.course.assessment.AssessmentManager#registerForAssessmentChangeEvents(org.olat.core.util.event.GenericEventListener, org.olat.core.id.Identity)
-	 */
 	@Override
 	public void registerForAssessmentChangeEvents(GenericEventListener gel, Identity identity) {
 		throw new AssertException("Not implemented for preview.");
 	}
 
-	/**
-	 * @see org.olat.course.assessment.AssessmentManager#deregisterFromAssessmentChangeEvents(org.olat.core.util.event.GenericEventListener)
-	 */
 	@Override
 	public void deregisterFromAssessmentChangeEvents(GenericEventListener gel) {
 		throw new AssertException("Not implemented for preview.");
 	}
 
-	/**
-	 * 
-	 * @see org.olat.course.assessment.AssessmentManager#saveAssessmentID(org.olat.course.nodes.CourseNode, org.olat.core.id.Identity, java.lang.String)
-	 */
 	private void saveAssessmentID(CourseNode courseNode, Long assessmentID) {
 		nodeAssessmentID.put(courseNode.getIdent(), assessmentID);
 	}
 	
-	/**
-	 * 
-	 * @param courseNode
-	 * @param identity
-	 * @return
-	 */
 	@Override
 	public Long getAssessmentID(CourseNode courseNode, Identity identity) {
 		return nodeAssessmentID.get(courseNode.getIdent());
@@ -288,7 +250,7 @@ final class PreviewAssessmentManager implements AssessmentManager {
 	}
 
 	@Override
-	public OLATResourceable createOLATResourceableForLocking(Identity assessedIdentity) {				
+	public OLATResourceable createOLATResourceableForLocking(Identity assessedIdentity) {
 		throw new AssertException("Not implemented for preview.");
 	}
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/assessment/AssessmentEntry.java b/src/main/java/org/olat/modules/assessment/AssessmentEntry.java
index a2ef10fa18bcc10cef38081820b195f6429b0aaa..7d7a7569b4f453f7e191afd932c24e6ddae16e20 100644
--- a/src/main/java/org/olat/modules/assessment/AssessmentEntry.java
+++ b/src/main/java/org/olat/modules/assessment/AssessmentEntry.java
@@ -68,6 +68,8 @@ public interface AssessmentEntry extends AssessmentEntryLight {
 	public AssessmentEntryStatus getAssessmentStatus();
 	
 	public void setAssessmentStatus(AssessmentEntryStatus assessmentStatus);
+	
+	public Date getAssessmentDone();
 
 	/**
 	 * Used by Onyx
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 d808e38b8dade221b5a854debc9ea0860bd678a1..8a5403ebe96714c23557aaf5b9e705bc5eb66497 100644
--- a/src/main/java/org/olat/modules/assessment/model/AssessmentEntryImpl.java
+++ b/src/main/java/org/olat/modules/assessment/model/AssessmentEntryImpl.java
@@ -89,6 +89,8 @@ public class AssessmentEntryImpl implements Persistable, ModifiedInfo, CreateInf
 	private Boolean passed;
 	@Column(name="a_status", nullable=true, insertable=true, updatable=true)
 	private String status;
+	@Column(name="a_date_done", nullable=true, insertable=true, updatable=true)
+	private Date assessmentDone;
 	@Column(name="a_details", nullable=true, insertable=true, updatable=true)
 	private String details;
 	@Column(name="a_user_visibility", nullable=true, insertable=true, updatable=true)
@@ -240,6 +242,13 @@ public class AssessmentEntryImpl implements Persistable, ModifiedInfo, CreateInf
 
 	@Override
 	public void setAssessmentStatus(AssessmentEntryStatus assessmentStatus) {
+		AssessmentEntryStatus previousStatus = getAssessmentStatus();
+		if (AssessmentEntryStatus.done.equals(assessmentStatus) && !AssessmentEntryStatus.done.equals(previousStatus)) {
+			assessmentDone = new Date();
+		} else {
+			assessmentDone = null;
+		}
+		
 		if(assessmentStatus == null) {
 			this.status = null;
 		} else {
@@ -247,6 +256,11 @@ public class AssessmentEntryImpl implements Persistable, ModifiedInfo, CreateInf
 		}
 	}
 
+	@Override
+	public Date getAssessmentDone() {
+		return assessmentDone;
+	}
+
 	@Override
 	public Boolean getUserVisibility() {
 		return userVisibility;
diff --git a/src/main/resources/database/mysql/alter_14_1_x_to_14_2_0.sql b/src/main/resources/database/mysql/alter_14_1_x_to_14_2_0.sql
index 57509da67cfd58b932fee14ef1b6892b74975887..3171b6b3f8584666296fae0a420835f57cf7991f 100644
--- a/src/main/resources/database/mysql/alter_14_1_x_to_14_2_0.sql
+++ b/src/main/resources/database/mysql/alter_14_1_x_to_14_2_0.sql
@@ -1,4 +1,5 @@
 -- Assessment
-alter table o_as_entry add a_first_visit datetime null;
-alter table o_as_entry add a_last_visit datetime null;
-alter table o_as_entry add a_num_visits int8 null;
+alter table o_as_entry add a_first_visit datetime;
+alter table o_as_entry add a_last_visit datetime;
+alter table o_as_entry add a_num_visits int8;
+alter table o_as_entry add a_date_done datetime;
diff --git a/src/main/resources/database/oracle/alter_14_1_x_to_14_2_0.sql b/src/main/resources/database/oracle/alter_14_1_x_to_14_2_0.sql
index b2c56945bb691947410a2b2a3e70fd8008b81b7f..cf8eba16f1773a737d56959ee530945a28bcb49a 100644
--- a/src/main/resources/database/oracle/alter_14_1_x_to_14_2_0.sql
+++ b/src/main/resources/database/oracle/alter_14_1_x_to_14_2_0.sql
@@ -2,3 +2,4 @@
 alter table o_as_entry add a_first_visit date;
 alter table o_as_entry add a_last_visit date;
 alter table o_as_entry add a_num_visits number(20);
+alter table o_as_entry add a_date_done date;
diff --git a/src/main/resources/database/postgresql/alter_14_1_x_to_14_2_0.sql b/src/main/resources/database/postgresql/alter_14_1_x_to_14_2_0.sql
index fecbd02bb28dca2f04a95f85258c85186ea6f631..806c9d9c5c0d73cebc33d988378f4ac8899956b5 100644
--- a/src/main/resources/database/postgresql/alter_14_1_x_to_14_2_0.sql
+++ b/src/main/resources/database/postgresql/alter_14_1_x_to_14_2_0.sql
@@ -1,4 +1,5 @@
 -- Assessment
-alter table o_as_entry add a_first_visit timestamp null;
-alter table o_as_entry add a_last_visit timestamp null;
-alter table o_as_entry add a_num_visits int8 null;
+alter table o_as_entry add a_first_visit timestamp;
+alter table o_as_entry add a_last_visit timestamp;
+alter table o_as_entry add a_num_visits int8;
+alter table o_as_entry add a_date_done timestamp;
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 b982a7e029ada97b05acdd8d294b18a551511de9..c249aa8d6b3c540741db7d63133e3a992ad0e00f 100644
--- a/src/test/java/org/olat/modules/assessment/manager/AssessmentEntryDAOTest.java
+++ b/src/test/java/org/olat/modules/assessment/manager/AssessmentEntryDAOTest.java
@@ -33,6 +33,7 @@ import org.olat.group.BusinessGroup;
 import org.olat.group.manager.BusinessGroupDAO;
 import org.olat.group.manager.BusinessGroupRelationDAO;
 import org.olat.modules.assessment.AssessmentEntry;
+import org.olat.modules.assessment.model.AssessmentEntryStatus;
 import org.olat.repository.RepositoryEntry;
 import org.olat.test.JunitTestHelper;
 import org.olat.test.OlatTestCase;
@@ -230,6 +231,43 @@ public class AssessmentEntryDAOTest extends OlatTestCase {
 		Assert.assertEquals(nodeAssessment.getNumberOfVisits().intValue(), 2);
 	}
 	
+	@Test
+	public void setAssessmentDone() {
+		Identity assessedIdentity = JunitTestHelper.createAndPersistIdentityAsRndUser("as-node-6");
+		RepositoryEntry entry = JunitTestHelper.createAndPersistRepositoryEntry();
+		RepositoryEntry refEntry = JunitTestHelper.createAndPersistRepositoryEntry();
+		String subIdent = UUID.randomUUID().toString();
+		AssessmentEntry nodeAssessment = assessmentEntryDao
+				.createAssessmentEntry(assessedIdentity, null, entry, subIdent, refEntry, 2.0f, Boolean.TRUE, null, null);
+		dbInstance.commitAndCloseSession();
+		
+		Assert.assertNull(nodeAssessment.getAssessmentDone());
+		
+		nodeAssessment.setAssessmentStatus(AssessmentEntryStatus.done);
+		nodeAssessment = assessmentEntryDao.updateAssessmentEntry(nodeAssessment);
+		dbInstance.commitAndCloseSession();
+		
+		Assert.assertNotNull(nodeAssessment.getAssessmentDone());
+		
+		nodeAssessment.setAssessmentStatus(null);
+		nodeAssessment = assessmentEntryDao.updateAssessmentEntry(nodeAssessment);
+		dbInstance.commitAndCloseSession();
+		
+		Assert.assertNull(nodeAssessment.getAssessmentDone());
+		
+		nodeAssessment.setAssessmentStatus(AssessmentEntryStatus.inProgress);
+		nodeAssessment = assessmentEntryDao.updateAssessmentEntry(nodeAssessment);
+		dbInstance.commitAndCloseSession();
+		
+		Assert.assertNull(nodeAssessment.getAssessmentDone());
+		
+		nodeAssessment.setAssessmentStatus(AssessmentEntryStatus.done);
+		nodeAssessment = assessmentEntryDao.updateAssessmentEntry(nodeAssessment);
+		dbInstance.commitAndCloseSession();
+		
+		Assert.assertNotNull(nodeAssessment.getAssessmentDone());
+	}
+	
 	@Test
 	public void loadAssessmentEntries_subIdent() {
 		Identity assessedIdentity1 = JunitTestHelper.createAndPersistIdentityAsRndUser("as-node-7");