diff --git a/src/main/java/org/olat/course/learningpath/LearningPathConfigs.java b/src/main/java/org/olat/course/learningpath/LearningPathConfigs.java index f3e6070d3281b7a0f04223cffdc04564222cf86b..7b549dff853789fd3f7c1567bc18da3cec0ca07c 100644 --- a/src/main/java/org/olat/course/learningpath/LearningPathConfigs.java +++ b/src/main/java/org/olat/course/learningpath/LearningPathConfigs.java @@ -19,6 +19,8 @@ */ package org.olat.course.learningpath; +import java.util.Date; + import org.olat.modules.assessment.model.AssessmentEntryStatus; import org.olat.modules.assessment.model.AssessmentObligation; @@ -36,6 +38,8 @@ public interface LearningPathConfigs { public AssessmentObligation getObligation(); + public Date getStartDate(); + public FullyAssessedResult isFullyAssessedOnNodeVisited(); public FullyAssessedResult isFullyAssessedOnConfirmation(boolean confirmed); diff --git a/src/main/java/org/olat/course/learningpath/evaluation/ConfigStartDateEvaluator.java b/src/main/java/org/olat/course/learningpath/evaluation/ConfigStartDateEvaluator.java new file mode 100644 index 0000000000000000000000000000000000000000..e7ba98cb3ab348fbd4aa3ce3e715665bc1e38c09 --- /dev/null +++ b/src/main/java/org/olat/course/learningpath/evaluation/ConfigStartDateEvaluator.java @@ -0,0 +1,48 @@ +/** + * <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.evaluation; + +import java.util.Date; + +import org.olat.core.CoreSpringFactory; +import org.olat.course.learningpath.LearningPathService; +import org.olat.course.nodes.CourseNode; +import org.olat.course.run.scoring.StartDateEvaluator; +import org.olat.course.run.scoring.StatusEvaluator.Blocker; + +/** + * + * Initial date: 4 Nov 2019<br> + * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com + * + */ +public class ConfigStartDateEvaluator implements StartDateEvaluator { + + @Override + public void evaluate(CourseNode courseNode, Blocker blocker) { + LearningPathService learningPathService = CoreSpringFactory.getImpl(LearningPathService.class); + Date startDate = learningPathService.getConfigs(courseNode).getStartDate(); + Date now = new Date(); + if (startDate != null && startDate.after(now)) { + blocker.block(); + } + } + +} diff --git a/src/main/java/org/olat/course/learningpath/evaluation/LearningPathEvaluatorBuilder.java b/src/main/java/org/olat/course/learningpath/evaluation/LearningPathEvaluatorBuilder.java index cc7cc706931ae603c1ffb01dbdb6800b40973843..e35c95a76ad40457a5ec69b41de59aa2bb49562f 100644 --- a/src/main/java/org/olat/course/learningpath/evaluation/LearningPathEvaluatorBuilder.java +++ b/src/main/java/org/olat/course/learningpath/evaluation/LearningPathEvaluatorBuilder.java @@ -21,6 +21,7 @@ package org.olat.course.learningpath.evaluation; import org.olat.course.run.scoring.AccountingEvaluators; import org.olat.course.run.scoring.AccountingEvaluatorsBuilder; +import org.olat.course.run.scoring.StartDateEvaluator; import org.olat.course.run.scoring.StatusEvaluator; /** @@ -31,9 +32,11 @@ import org.olat.course.run.scoring.StatusEvaluator; */ public class LearningPathEvaluatorBuilder { + private static final StartDateEvaluator CONFIG_START_DATE_EVALUATOR = new ConfigStartDateEvaluator(); private static final StatusEvaluator LINEAR_STATUS_EVALUATOR = new DefaultLinearStatusEvaluator(); private static final AccountingEvaluators DEFAULT = AccountingEvaluatorsBuilder .builder() + .withStartDateEvaluator(CONFIG_START_DATE_EVALUATOR) .withObligationEvaluator(new ConfigObligationEvaluator()) .withDurationEvaluator(new ConfigDurationEvaluator()) .withStatusEvaluator(LINEAR_STATUS_EVALUATOR) diff --git a/src/main/java/org/olat/course/learningpath/model/ModuleLearningPathConfigs.java b/src/main/java/org/olat/course/learningpath/model/ModuleLearningPathConfigs.java index 017aaae0aa60d56eb1ecf721e3fe016f667c8072..59d6fbbf59c3cc5138580b256c59936a1ac731eb 100644 --- a/src/main/java/org/olat/course/learningpath/model/ModuleLearningPathConfigs.java +++ b/src/main/java/org/olat/course/learningpath/model/ModuleLearningPathConfigs.java @@ -24,6 +24,7 @@ import static org.olat.course.learningpath.ui.LearningPathNodeConfigController.C import static org.olat.course.learningpath.ui.LearningPathNodeConfigController.CONFIG_KEY_DURATION; import static org.olat.course.learningpath.ui.LearningPathNodeConfigController.CONFIG_KEY_OBLIGATION; import static org.olat.course.learningpath.ui.LearningPathNodeConfigController.CONFIG_KEY_SCORE_CUT_VALUE; +import static org.olat.course.learningpath.ui.LearningPathNodeConfigController.CONFIG_KEY_START; import static org.olat.course.learningpath.ui.LearningPathNodeConfigController.CONFIG_KEY_TRIGGER; import static org.olat.course.learningpath.ui.LearningPathNodeConfigController.CONFIG_VALUE_TRIGGER_CONFIRMED; import static org.olat.course.learningpath.ui.LearningPathNodeConfigController.CONFIG_VALUE_TRIGGER_NODE_VISITED; @@ -31,6 +32,8 @@ import static org.olat.course.learningpath.ui.LearningPathNodeConfigController.C import static org.olat.course.learningpath.ui.LearningPathNodeConfigController.CONFIG_VALUE_TRIGGER_SCORE; import static org.olat.course.learningpath.ui.LearningPathNodeConfigController.CONFIG_VALUE_TRIGGER_STATUS_DONE; +import java.util.Date; + import org.olat.core.util.StringHelper; import org.olat.course.learningpath.LearningPathConfigs; import org.olat.modules.ModuleConfiguration; @@ -81,6 +84,11 @@ public class ModuleLearningPathConfigs implements LearningPathConfigs { return AssessmentObligation.valueOf(value); } + @Override + public Date getStartDate() { + return moduleConfiguration.getDateValue(CONFIG_KEY_START); + } + @Override public FullyAssessedResult isFullyAssessedOnNodeVisited() { String doneTriggerName = getDoneTriggerName(); diff --git a/src/main/java/org/olat/course/learningpath/model/UnsupportedLearningPathConfigs.java b/src/main/java/org/olat/course/learningpath/model/UnsupportedLearningPathConfigs.java index 7ecaf00985bbee72e785cd5f53d63680e045577a..c56b07bf11818deec91a8b9c42e54a8284325c15 100644 --- a/src/main/java/org/olat/course/learningpath/model/UnsupportedLearningPathConfigs.java +++ b/src/main/java/org/olat/course/learningpath/model/UnsupportedLearningPathConfigs.java @@ -19,6 +19,8 @@ */ package org.olat.course.learningpath.model; +import java.util.Date; + import org.olat.course.learningpath.LearningPathConfigs; import org.olat.modules.assessment.model.AssessmentEntryStatus; import org.olat.modules.assessment.model.AssessmentObligation; @@ -45,6 +47,11 @@ public class UnsupportedLearningPathConfigs implements LearningPathConfigs { public AssessmentObligation getObligation() { return AssessmentObligation.optional; } + + @Override + public Date getStartDate() { + return null; + } @Override public FullyAssessedResult isFullyAssessedOnNodeVisited() { diff --git a/src/main/java/org/olat/course/learningpath/ui/LearningPathNodeConfigController.java b/src/main/java/org/olat/course/learningpath/ui/LearningPathNodeConfigController.java index 76cd113b893553f9a9b065036134a19a3be75859..c37bd590f9c1847f731742240eb40a5f96b9f4f2 100644 --- a/src/main/java/org/olat/course/learningpath/ui/LearningPathNodeConfigController.java +++ b/src/main/java/org/olat/course/learningpath/ui/LearningPathNodeConfigController.java @@ -22,10 +22,12 @@ package org.olat.course.learningpath.ui; import static org.olat.core.gui.components.util.KeyValues.entry; import java.util.Arrays; +import java.util.Date; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; +import org.olat.core.gui.components.form.flexible.elements.DateChooser; import org.olat.core.gui.components.form.flexible.elements.SingleSelection; import org.olat.core.gui.components.form.flexible.elements.TextElement; import org.olat.core.gui.components.form.flexible.impl.FormBasicController; @@ -53,6 +55,7 @@ public class LearningPathNodeConfigController extends FormBasicController { public static final String CONFIG_KEY_DURATION = "duration"; public static final String CONFIG_KEY_OBLIGATION = "obligation"; public static final String CONFIG_DEFAULT_OBLIGATION = AssessmentObligation.mandatory.name(); + public static final String CONFIG_KEY_START = "start.date"; public static final String CONFIG_KEY_TRIGGER = "fully.assessed.trigger"; public static final String CONFIG_VALUE_TRIGGER_NONE = "none"; public static final String CONFIG_VALUE_TRIGGER_NODE_VISITED = "nodeVisited"; @@ -65,6 +68,7 @@ public class LearningPathNodeConfigController extends FormBasicController { private TextElement durationEl; private SingleSelection obligationEl; + private DateChooser startDateEl; private SingleSelection triggerEl; private TextElement scoreCutEl; @@ -97,6 +101,10 @@ public class LearningPathNodeConfigController extends FormBasicController { } obligationEl.setVisible(ctrlConfig.isObligationVisible()); + Date startDate = moduleConfigs.getDateValue(CONFIG_KEY_START); + startDateEl = uifactory.addDateChooser("config.start.date", startDate, formLayout); + startDateEl.setDateChooserTimeEnabled(true); + KeyValues triggerKV = getTriggerKV(); triggerEl = uifactory.addRadiosVertical("config.trigger", formLayout, triggerKV.keys(), triggerKV.values()); @@ -207,6 +215,9 @@ public class LearningPathNodeConfigController extends FormBasicController { : CONFIG_DEFAULT_OBLIGATION; moduleConfigs.setStringValue(CONFIG_KEY_OBLIGATION, obligation); + Date startDate = startDateEl.getDate(); + moduleConfigs.setDateValue(CONFIG_KEY_START, startDate); + String trigger = triggerEl.isOneSelected() ? triggerEl.getSelectedKey() : CONFIG_DEFAULT_TRIGGER; 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 597d5950526e44f345831dbd69ea06cd2ad87c7a..bad2ec3f66ec716188a9aeb978addd6da37bef79 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 @@ -4,6 +4,7 @@ congig.obligation=Pflicht config.obligation.mandatory=Obligatorisch config.obligation.optional=Freiwillig config.score.cut=Punkteminimum +config.start.date=Bearbeitbar ab config.trigger=Abschluss config.trigger.confirmed=Best\u00E4tigt config.trigger.none=Ohne Abschluss 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 87d36bd55d6d9520fea5d32389c591be8ae04acb..ed3af6c72aaec556e4a9f15c9ea74a10352b993e 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 @@ -5,6 +5,7 @@ config.obligation=Obligation config.obligation.mandatory=Mandatory config.obligation.optional=Optional config.score.cut=Minimal score +config.start.date=Editable from config.trigger=Completion config.trigger.confirmed=Confirmed config.trigger.none=No completion diff --git a/src/main/java/org/olat/course/nodes/st/assessment/STLearningPathConfigs.java b/src/main/java/org/olat/course/nodes/st/assessment/STLearningPathConfigs.java index cbe54595064dc67fd71e6ba6a482c4cbca766566..f1af76e13baa00b342b0d016d5cf29d08f43d9d5 100644 --- a/src/main/java/org/olat/course/nodes/st/assessment/STLearningPathConfigs.java +++ b/src/main/java/org/olat/course/nodes/st/assessment/STLearningPathConfigs.java @@ -19,6 +19,8 @@ */ package org.olat.course.nodes.st.assessment; +import java.util.Date; + import org.olat.course.learningpath.LearningPathConfigs; import org.olat.modules.assessment.model.AssessmentEntryStatus; import org.olat.modules.assessment.model.AssessmentObligation; @@ -46,6 +48,11 @@ public class STLearningPathConfigs implements LearningPathConfigs { return null; } + @Override + public Date getStartDate() { + return null; + } + @Override public FullyAssessedResult isFullyAssessedOnNodeVisited() { return LearningPathConfigs.notFullyAssessed(); diff --git a/src/main/java/org/olat/course/run/scoring/AccountingEvaluators.java b/src/main/java/org/olat/course/run/scoring/AccountingEvaluators.java index ff2de92bdb49c9d8f59bbe48bab0c04de67fef7d..11b0e37639703744f66b1be7304ade6a64fd976a 100644 --- a/src/main/java/org/olat/course/run/scoring/AccountingEvaluators.java +++ b/src/main/java/org/olat/course/run/scoring/AccountingEvaluators.java @@ -27,6 +27,8 @@ package org.olat.course.run.scoring; */ public interface AccountingEvaluators { + public StartDateEvaluator getStartDateEvaluator(); + public ObligationEvaluator getObligationEvaluator(); public DurationEvaluator getDurationEvaluator(); diff --git a/src/main/java/org/olat/course/run/scoring/AccountingEvaluatorsBuilder.java b/src/main/java/org/olat/course/run/scoring/AccountingEvaluatorsBuilder.java index 93076e0edc24b48ec87758cf5bf99c6a63bb593a..af01331f789a590f1477e6229a4287c42124254a 100644 --- a/src/main/java/org/olat/course/run/scoring/AccountingEvaluatorsBuilder.java +++ b/src/main/java/org/olat/course/run/scoring/AccountingEvaluatorsBuilder.java @@ -28,6 +28,7 @@ package org.olat.course.run.scoring; public class AccountingEvaluatorsBuilder { private static AccountingEvaluators CONVENTIONAL = builder() + .withStartDateEvaluator(AccountingEvaluatorsFactory.createNoBlockingStartDateEvaluator()) .withObligationEvaluator(AccountingEvaluatorsFactory.createNullObligationEvaluator()) .withDurationEvaluator(AccountingEvaluatorsFactory.createNullDurationEvaluator()) .withScoreEvaluator(AccountingEvaluatorsFactory.createUnchangingScoreEvaluator()) @@ -38,6 +39,7 @@ public class AccountingEvaluatorsBuilder { .withLastModificationsEvaluator(AccountingEvaluatorsFactory.createUnchangingLastModificationsEvaluator()) .build(); + private StartDateEvaluator startDateEvaluator; private ObligationEvaluator obligationEvaluator; private DurationEvaluator durationEvaluator; private ScoreEvaluator scoreEvaluator; @@ -51,6 +53,11 @@ public class AccountingEvaluatorsBuilder { // } + public AccountingEvaluatorsBuilder withStartDateEvaluator(StartDateEvaluator startDateEvaluator) { + this.startDateEvaluator = startDateEvaluator; + return this; + } + public AccountingEvaluatorsBuilder withObligationEvaluator(ObligationEvaluator obligationEvaluator) { this.obligationEvaluator = obligationEvaluator; return this; @@ -93,6 +100,9 @@ public class AccountingEvaluatorsBuilder { public AccountingEvaluators build() { AccountingEvaluatorsImpl impl = new AccountingEvaluatorsImpl(); + impl.startDateEvaluator = this.startDateEvaluator != null + ? this.startDateEvaluator + : AccountingEvaluatorsFactory.createNoBlockingStartDateEvaluator(); impl.obligationEvaluator = this.obligationEvaluator != null ? this.obligationEvaluator : AccountingEvaluatorsFactory.createNullObligationEvaluator(); @@ -130,6 +140,7 @@ public class AccountingEvaluatorsBuilder { private static class AccountingEvaluatorsImpl implements AccountingEvaluators { + private StartDateEvaluator startDateEvaluator; private ObligationEvaluator obligationEvaluator; private DurationEvaluator durationEvaluator; private ScoreEvaluator scoreEvaluator; @@ -139,6 +150,11 @@ public class AccountingEvaluatorsBuilder { private FullyAssessedEvaluator fullyAssessedEvaluator; private LastModificationsEvaluator lastModificationsEvaluator; + @Override + public StartDateEvaluator getStartDateEvaluator() { + return startDateEvaluator; + } + @Override public ObligationEvaluator getObligationEvaluator() { return obligationEvaluator; diff --git a/src/main/java/org/olat/course/run/scoring/AccountingEvaluatorsFactory.java b/src/main/java/org/olat/course/run/scoring/AccountingEvaluatorsFactory.java index 34da3224c898bc648d28c4c544d3a9694c19f3c7..c055c651b67bac00dc89b074501a50ce0d9450eb 100644 --- a/src/main/java/org/olat/course/run/scoring/AccountingEvaluatorsFactory.java +++ b/src/main/java/org/olat/course/run/scoring/AccountingEvaluatorsFactory.java @@ -23,6 +23,7 @@ import java.util.List; import org.olat.course.condition.interpreter.ConditionInterpreter; import org.olat.course.nodes.CourseNode; +import org.olat.course.run.scoring.StatusEvaluator.Blocker; import org.olat.modules.assessment.model.AssessmentEntryStatus; import org.olat.modules.assessment.model.AssessmentObligation; import org.olat.repository.RepositoryEntry; @@ -35,6 +36,7 @@ import org.olat.repository.RepositoryEntry; */ class AccountingEvaluatorsFactory { + private static final StartDateEvaluator NO_BLOCKING_START_DATE_EVALUATOR = new NoBlockingStartDateEvaluator(); private static final ObligationEvaluator NULL_OBLIGATION_EVALUATOR = new NullObligationEvaluator(); private static final DurationEvaluator NULL_DURATION_EVALUATOR = new NullDurationEvaluator(); private static final ScoreEvaluator UNCHANGING_SCORE_EVALUATOR = new UnchangingScoreEvaluator(); @@ -44,6 +46,10 @@ class AccountingEvaluatorsFactory { private static final FullyAssessedEvaluator UNCHANGING_FULLY_ASSESSED_EVALUATOR = new UnchangingFullyAssessedEvaluator(); private static final LastModificationsEvaluator UNCHANGING_LAST_MODIFICATIONS_EVALUATOR = new UnchangingLastModificationEvaluator(); + static StartDateEvaluator createNoBlockingStartDateEvaluator() { + return NO_BLOCKING_START_DATE_EVALUATOR; + } + static ObligationEvaluator createNullObligationEvaluator() { return NULL_OBLIGATION_EVALUATOR; } @@ -80,6 +86,15 @@ class AccountingEvaluatorsFactory { // } + private static class NoBlockingStartDateEvaluator implements StartDateEvaluator { + + @Override + public void evaluate(CourseNode courseNode, Blocker blocker) { + // nothing to do + } + + } + private static class NullObligationEvaluator implements ObligationEvaluator { @Override diff --git a/src/main/java/org/olat/course/run/scoring/AssessmentAccounting.java b/src/main/java/org/olat/course/run/scoring/AssessmentAccounting.java index a739fb83e99a23c24584054ff170281353c9d359..ea1da76fbc2835cd5b1658975b44e62cd62b8217 100644 --- a/src/main/java/org/olat/course/run/scoring/AssessmentAccounting.java +++ b/src/main/java/org/olat/course/run/scoring/AssessmentAccounting.java @@ -154,6 +154,9 @@ public class AssessmentAccounting implements ScoreAccounting { AccountingEvaluators evaluators = courseAssessmentService.getEvaluators(courseNode, courseConfig); + StartDateEvaluator startDateEvaluator = evaluators.getStartDateEvaluator(); + startDateEvaluator.evaluate(courseNode, blocker); + ObligationEvaluator obligationEvaluator = evaluators.getObligationEvaluator(); AssessmentObligation obligation = obligationEvaluator.getObligation(result, courseNode); result.setObligation(obligation); diff --git a/src/main/java/org/olat/course/run/scoring/StartDateEvaluator.java b/src/main/java/org/olat/course/run/scoring/StartDateEvaluator.java new file mode 100644 index 0000000000000000000000000000000000000000..29c61f0fc176f6e966bdce2233550ad5df8c34f1 --- /dev/null +++ b/src/main/java/org/olat/course/run/scoring/StartDateEvaluator.java @@ -0,0 +1,41 @@ +/** + * <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.run.scoring; + +import org.olat.course.nodes.CourseNode; +import org.olat.course.run.scoring.StatusEvaluator.Blocker; + +/** + * + * Initial date: 4 Nov 2019<br> + * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com + * + */ +public interface StartDateEvaluator { + + /** + * My block the start of the evaluation. + * + * @param courseNode + * @param blocker + */ + public void evaluate(CourseNode courseNode, Blocker blocker); + +}