diff --git a/src/main/java/org/olat/admin/restapi/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/admin/restapi/_i18n/LocalStrings_de.properties
index 23db5bb427956a432722de3ba8d86239c352c836..0e1eb1dee19723bd7cac57567fcd4a4e62bc6150 100644
--- a/src/main/java/org/olat/admin/restapi/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/admin/restapi/_i18n/LocalStrings_de.properties
@@ -30,6 +30,7 @@ managed.flags.course.layout=Einstellung f\u00fcr Layout
 managed.flags.course.lecture=Lektionen
 managed.flags.course.lecturemanagement=Lektionen verwalten
 managed.flags.course.lectureconfig=Lektionen und Absenzen in Kurs konfigurieren
+managed.flags.course.organisations=Organisationen
 managed.flags.course.resourcefolder=Einstellung f\u00fcr Ressourcenordner
 managed.flags.course.efficencystatement=Einstellung f\u00fcr Leistungsnachweis
 managed.flags.course.calendar=Einstellung f\u00fcr Kalender
diff --git a/src/main/java/org/olat/admin/restapi/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/admin/restapi/_i18n/LocalStrings_en.properties
index 1bdc56e1d9f56a46d4f449ffbee755bbfad0c365..8257e3dcac4f7793821d11bff7232a273f5df952 100644
--- a/src/main/java/org/olat/admin/restapi/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/admin/restapi/_i18n/LocalStrings_en.properties
@@ -27,6 +27,7 @@ managed.flags.course.lecture=Lectures
 managed.flags.course.lecturemanagement=Lectures management
 managed.flags.course.lectureconfig=Configuration of lectures and absences in the course
 managed.flags.course.membersmanagement=Members management
+managed.flags.course.organisations=Organisations
 managed.flags.course.resourcefolder=Resource folder configuration
 managed.flags.course.settings=Settings
 managed.flags.course.title=Course title
diff --git a/src/main/java/org/olat/modules/curriculum/CurriculumService.java b/src/main/java/org/olat/modules/curriculum/CurriculumService.java
index d68466e0dbc58f8db09bbff5cf13b3e9ab1bdc4e..bc671d6be5e78b3ed6e67209a050e7078a710f67 100644
--- a/src/main/java/org/olat/modules/curriculum/CurriculumService.java
+++ b/src/main/java/org/olat/modules/curriculum/CurriculumService.java
@@ -190,6 +190,8 @@ public interface CurriculumService {
 	
 	public CurriculumElement getCurriculumElement(CurriculumElementRef element);
 	
+	public void deleteCurriculumElement(CurriculumElementRef element);
+	
 	/**
 	 * Return all the elements of a curriculum, but flat.
 	 * 
diff --git a/src/main/java/org/olat/modules/curriculum/manager/CurriculumDAO.java b/src/main/java/org/olat/modules/curriculum/manager/CurriculumDAO.java
index 1ec02a3dfde3d4956710a495a877e1c7072baab6..0eee8855447465af03728373367a2aca27b45208 100644
--- a/src/main/java/org/olat/modules/curriculum/manager/CurriculumDAO.java
+++ b/src/main/java/org/olat/modules/curriculum/manager/CurriculumDAO.java
@@ -32,6 +32,7 @@ import org.olat.basesecurity.OrganisationRoles;
 import org.olat.basesecurity.manager.GroupDAO;
 import org.olat.core.commons.persistence.DB;
 import org.olat.core.commons.persistence.PersistenceHelper;
+import org.olat.core.commons.persistence.QueryBuilder;
 import org.olat.core.id.Identity;
 import org.olat.core.id.Organisation;
 import org.olat.core.id.OrganisationRef;
@@ -87,14 +88,14 @@ public class CurriculumDAO {
 	}
 	
 	public List<Curriculum> getMyCurriculums(IdentityRef identity) {
-		StringBuilder sb = new StringBuilder(256);
+		QueryBuilder sb = new QueryBuilder(256);
 		sb.append("select cur from curriculum cur")
 		  .append(" left join fetch cur.organisation organis")
 		  .append(" inner join fetch cur.group baseGroup")
 		  .append(" where exists (select curElement from curriculumelement curElement")
 		  .append("  inner join curElement.group as bGroup")
 		  .append("  inner join bGroup.members membership")
-		  .append("  where curElement.curriculum.key=cur.key and membership.identity.key=:memberKey and membership.role in ('").append(CurriculumRoles.participant).append("')")
+		  .append("  where curElement.curriculum.key=cur.key and membership.identity.key=:memberKey and membership.role ").in(CurriculumRoles.participant, CurriculumRoles.coach)
 		  .append(" )");
 	
 		return dbInstance.getCurrentEntityManager()
diff --git a/src/main/java/org/olat/modules/curriculum/manager/CurriculumElementDAO.java b/src/main/java/org/olat/modules/curriculum/manager/CurriculumElementDAO.java
index fd045b92ccfa24550b1919f7c95f64908ddb25b9..63c7e15f739df2ff56203db0a44bf312178c9f60 100644
--- a/src/main/java/org/olat/modules/curriculum/manager/CurriculumElementDAO.java
+++ b/src/main/java/org/olat/modules/curriculum/manager/CurriculumElementDAO.java
@@ -31,6 +31,7 @@ import java.util.stream.Collectors;
 
 import javax.persistence.TypedQuery;
 
+import org.olat.basesecurity.Group;
 import org.olat.basesecurity.GroupMembership;
 import org.olat.basesecurity.manager.GroupDAO;
 import org.olat.core.commons.persistence.DB;
@@ -88,6 +89,19 @@ public class CurriculumElementDAO {
 		return element;
 	}
 	
+	/**
+	 * The element must be loaded. The method doesn't do a relead.
+	 * 
+	 * @param element
+	 */
+	public void deleteCurriculumElement(CurriculumElement element) {
+		dbInstance.getCurrentEntityManager().remove(element);
+		
+		Group group = element.getGroup();
+		groupDao.removeMemberships(group);
+		groupDao.removeGroup(group);
+	}
+	
 	public CurriculumElement loadByKey(Long key) {
 		StringBuilder sb = new StringBuilder(128);
 		sb.append("select el from curriculumelement el")
@@ -150,6 +164,20 @@ public class CurriculumElementDAO {
 		return elementImpl;
 	}
 	
+	public boolean hasRelations(CurriculumElementRef curriculumElementRef) {
+		StringBuilder sb = new StringBuilder(128);
+		sb.append("select context.key from qualitycontext as context")
+		  .append(" where context.audienceCurriculumElement.key=:curriculumElementKey");
+		
+		List<Long> keys = dbInstance.getCurrentEntityManager()
+				.createQuery(sb.toString(), Long.class)
+				.setParameter("curriculumElementKey", curriculumElementRef.getKey())
+				.setFirstResult(0)
+				.setMaxResults(1)
+				.getResultList();
+		return keys != null && keys.size() > 0 && keys.get(0) != null;
+	}
+	
 	public List<CurriculumElement> loadElements(CurriculumRef curriculum) {
 		StringBuilder sb = new StringBuilder(256);
 		sb.append("select el from curriculumelement el")
diff --git a/src/main/java/org/olat/modules/curriculum/manager/CurriculumElementToTaxonomyLevelDAO.java b/src/main/java/org/olat/modules/curriculum/manager/CurriculumElementToTaxonomyLevelDAO.java
index e277771e07dee3f85c482df75b490a437e5554ac..88e23d4bb204ad4913150811c19741d2b8cdf575 100644
--- a/src/main/java/org/olat/modules/curriculum/manager/CurriculumElementToTaxonomyLevelDAO.java
+++ b/src/main/java/org/olat/modules/curriculum/manager/CurriculumElementToTaxonomyLevelDAO.java
@@ -76,6 +76,27 @@ public class CurriculumElementToTaxonomyLevelDAO {
 				.getResultList();
 	}
 	
+	public List<CurriculumElementToTaxonomyLevel> getRelations(CurriculumElementRef curriculumElement) {
+		StringBuilder sb = new StringBuilder(256);
+		sb.append("select rel from curriculumelementtotaxonomylevel rel")
+		  .append(" where rel.curriculumElement.key=:elementKey");
+		return dbInstance.getCurrentEntityManager()
+				.createQuery(sb.toString(), CurriculumElementToTaxonomyLevel.class)
+				.setParameter("elementKey", curriculumElement.getKey())
+				.getResultList();
+	}
+	
+	public void removeRelation(CurriculumElementToTaxonomyLevel rel) {
+		dbInstance.getCurrentEntityManager().remove(rel);
+	}
+	
+	public void deleteRelation(CurriculumElementRef curriculumElement) {
+		List<CurriculumElementToTaxonomyLevel> relationsToDelete = getRelations(curriculumElement);
+		for(CurriculumElementToTaxonomyLevel relationToDelete:relationsToDelete) {
+			dbInstance.getCurrentEntityManager().remove(relationToDelete);
+		}
+	}
+	
 	public void deleteRelation(CurriculumElementRef curriculumElement, TaxonomyLevelRef taxonomyLevel) {
 		StringBuilder sb = new StringBuilder(256);
 		sb.append("select rel from curriculumelementtotaxonomylevel rel")
diff --git a/src/main/java/org/olat/modules/curriculum/manager/CurriculumRepositoryEntryRelationDAO.java b/src/main/java/org/olat/modules/curriculum/manager/CurriculumRepositoryEntryRelationDAO.java
index 525a9c23fcaf807ad2003e94da419dabccdb28f6..a146552d7daa0bbb60f805c8ced2ecffddfcca8d 100644
--- a/src/main/java/org/olat/modules/curriculum/manager/CurriculumRepositoryEntryRelationDAO.java
+++ b/src/main/java/org/olat/modules/curriculum/manager/CurriculumRepositoryEntryRelationDAO.java
@@ -29,6 +29,7 @@ import java.util.stream.Collectors;
 import javax.persistence.TypedQuery;
 
 import org.olat.core.commons.persistence.DB;
+import org.olat.core.commons.persistence.QueryBuilder;
 import org.olat.core.id.Identity;
 import org.olat.modules.curriculum.CurriculumElement;
 import org.olat.modules.curriculum.CurriculumElementRef;
@@ -36,6 +37,7 @@ import org.olat.modules.curriculum.CurriculumRef;
 import org.olat.modules.curriculum.CurriculumRoles;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryEntryRef;
+import org.olat.repository.RepositoryEntryStatusEnum;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -64,15 +66,15 @@ public class CurriculumRepositoryEntryRelationDAO {
 			.getResultList();
 	}
 	
-	public List<RepositoryEntry> getRepositoryEntries(CurriculumElementRef element) {
-		StringBuilder sb = new StringBuilder(256);
+	public List<RepositoryEntry> getRepositoryEntries(CurriculumElementRef element, RepositoryEntryStatusEnum[] status) {
+		QueryBuilder sb = new QueryBuilder(256);
 		sb.append("select distinct v from repositoryentry as v")
 		  .append(" inner join fetch v.olatResource as ores")
 		  .append(" inner join fetch v.statistics as statistics")
 		  .append(" left join fetch v.lifecycle as lifecycle")
 		  .append(" inner join v.groups as rel")
 		  .append(" inner join curriculumelement as el on (el.group.key=rel.group.key)")
-		  .append(" where el.key=:elementKey");
+		  .append(" where el.key=:elementKey and v.status ").in(status);
 
 		return dbInstance.getCurrentEntityManager()
 			.createQuery(sb.toString(), RepositoryEntry.class)
diff --git a/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java b/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java
index 1175dfe8d376011881a48bb16b9ded632b044b9b..726f84533addabd1410b445d6d329e13d9a07e43 100644
--- a/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java
+++ b/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java
@@ -43,12 +43,14 @@ import org.olat.modules.curriculum.CurriculumElement;
 import org.olat.modules.curriculum.CurriculumElementManagedFlag;
 import org.olat.modules.curriculum.CurriculumElementMembership;
 import org.olat.modules.curriculum.CurriculumElementRef;
+import org.olat.modules.curriculum.CurriculumElementStatus;
 import org.olat.modules.curriculum.CurriculumElementType;
 import org.olat.modules.curriculum.CurriculumElementTypeRef;
 import org.olat.modules.curriculum.CurriculumElementTypeToType;
 import org.olat.modules.curriculum.CurriculumRef;
 import org.olat.modules.curriculum.CurriculumRoles;
 import org.olat.modules.curriculum.CurriculumService;
+import org.olat.modules.curriculum.model.CurriculumElementImpl;
 import org.olat.modules.curriculum.model.CurriculumElementInfos;
 import org.olat.modules.curriculum.model.CurriculumElementMembershipChange;
 import org.olat.modules.curriculum.model.CurriculumElementRepositoryEntryViews;
@@ -61,9 +63,11 @@ import org.olat.modules.taxonomy.TaxonomyLevelRef;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryEntryMyView;
 import org.olat.repository.RepositoryEntryRef;
+import org.olat.repository.RepositoryEntryStatusEnum;
 import org.olat.repository.manager.RepositoryEntryDAO;
 import org.olat.repository.manager.RepositoryEntryMyCourseQueries;
 import org.olat.repository.manager.RepositoryEntryRelationDAO;
+import org.olat.repository.model.RepositoryEntryToGroupRelation;
 import org.olat.repository.model.SearchMyRepositoryEntryViewParams;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -234,6 +238,36 @@ public class CurriculumServiceImpl implements CurriculumService {
 		return curriculumElementDao.loadByKey(element.getKey());
 	}
 
+	@Override
+	public void deleteCurriculumElement(CurriculumElementRef element) {
+		List<CurriculumElement> children = curriculumElementDao.getChildren(element);
+		for(CurriculumElement child:children) {
+			deleteCurriculumElement(child);
+		}
+
+		CurriculumElement reloadedElement = curriculumElementDao.loadByKey(element.getKey());
+
+		// remove relations to repository entries
+		List<RepositoryEntryToGroupRelation> relationsToRepo = repositoryEntryRelationDao.getCurriculumRelations(reloadedElement);
+		for(RepositoryEntryToGroupRelation relationToRepo:relationsToRepo) {
+			if(!relationToRepo.isDefaultGroup()) {// only paranoia
+				repositoryEntryRelationDao.removeRelation(relationToRepo);
+			}
+		}
+		// remove relations to taxonomy
+		curriculumElementToTaxonomyLevelDao.deleteRelation(reloadedElement);
+
+		if(curriculumElementDao.hasRelations(reloadedElement)) {
+			groupDao.removeMemberships(reloadedElement.getGroup());
+			//only flag as deleted
+			((CurriculumElementImpl)reloadedElement).setParent(null);
+			reloadedElement.setStatus(CurriculumElementStatus.deleted);
+			curriculumElementDao.update(reloadedElement);
+		} else {
+			curriculumElementDao.deleteCurriculumElement(reloadedElement);
+		}
+	}
+
 	@Override
 	public CurriculumElement updateCurriculumElement(CurriculumElement element) {
 		return curriculumElementDao.update(element);
@@ -373,7 +407,7 @@ public class CurriculumServiceImpl implements CurriculumService {
 
 	@Override
 	public List<RepositoryEntry> getRepositoryEntries(CurriculumElementRef element) {
-		return curriculumRepositoryEntryRelationDao.getRepositoryEntries(element);
+		return curriculumRepositoryEntryRelationDao.getRepositoryEntries(element, RepositoryEntryStatusEnum.preparationToClosed());
 	}
 
 	@Override
diff --git a/src/main/java/org/olat/modules/curriculum/ui/ConfirmCurriculumElementDeleteController.java b/src/main/java/org/olat/modules/curriculum/ui/ConfirmCurriculumElementDeleteController.java
new file mode 100644
index 0000000000000000000000000000000000000000..a1a3fccc90433fdef7e8359d798338b2066de3ba
--- /dev/null
+++ b/src/main/java/org/olat/modules/curriculum/ui/ConfirmCurriculumElementDeleteController.java
@@ -0,0 +1,95 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.modules.curriculum.ui;
+
+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.FormLink;
+import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
+import org.olat.core.gui.components.form.flexible.impl.FormEvent;
+import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer;
+import org.olat.core.gui.components.link.Link;
+import org.olat.core.gui.control.Controller;
+import org.olat.core.gui.control.Event;
+import org.olat.core.gui.control.WindowControl;
+import org.olat.modules.curriculum.CurriculumService;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * 
+ * Initial date: 26 juil. 2018<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class ConfirmCurriculumElementDeleteController extends FormBasicController {
+	
+	private FormLink deleteButton;
+	
+	private final CurriculumElementRow rowToDelete;
+	
+	@Autowired
+	private CurriculumService curriculumService;
+	
+	public ConfirmCurriculumElementDeleteController(UserRequest ureq, WindowControl wControl, CurriculumElementRow rowToDelete) {
+		super(ureq, wControl, "confirm_delete_curriculum_element");
+		this.rowToDelete = rowToDelete;
+		
+		initForm(ureq);
+	}
+
+	@Override
+	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
+		if(formLayout instanceof FormLayoutContainer) {
+			((FormLayoutContainer)formLayout).contextPut("element", rowToDelete);
+		}
+
+		uifactory.addFormCancelButton("cancel", formLayout, ureq, getWindowControl());
+		deleteButton = uifactory.addFormLink("delete", formLayout, Link.BUTTON);
+	}
+	
+	@Override
+	protected void doDispose() {
+		//
+	}
+
+	@Override
+	protected void formOK(UserRequest ureq) {
+		//
+	}
+
+	@Override
+	protected void formCancelled(UserRequest ureq) {
+		fireEvent(ureq, Event.CANCELLED_EVENT);
+	}
+
+	@Override
+	protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
+		if(deleteButton == source) {
+			doDelete();
+			fireEvent(ureq, Event.DONE_EVENT);
+		}
+		super.formInnerEvent(ureq, source, event);
+	}
+	
+	private void doDelete() {
+		curriculumService.deleteCurriculumElement(rowToDelete);
+	}
+}
diff --git a/src/main/java/org/olat/modules/curriculum/ui/CurriculumComposerController.java b/src/main/java/org/olat/modules/curriculum/ui/CurriculumComposerController.java
index a00e41455fc274f3766df15f7869dda1556ae471..d248f5d56faa7b346f4b909c0ed53f9879c3d7f8 100644
--- a/src/main/java/org/olat/modules/curriculum/ui/CurriculumComposerController.java
+++ b/src/main/java/org/olat/modules/curriculum/ui/CurriculumComposerController.java
@@ -87,6 +87,7 @@ public class CurriculumComposerController extends FormBasicController implements
 	private CloseableCalloutWindowController toolsCalloutCtrl;
 	private EditCurriculumElementController newSubElementCtrl;
 	private MoveCurriculumElementController moveElementCtrl;
+	private ConfirmCurriculumElementDeleteController confirmDeleteCtrl;
 	
 	private int counter;
 	private final Curriculum curriculum;
@@ -195,7 +196,7 @@ public class CurriculumComposerController extends FormBasicController implements
 
 	@Override
 	protected void event(UserRequest ureq, Controller source, Event event) {
-		if(newElementCtrl == source || newSubElementCtrl == source || moveElementCtrl == source) {
+		if(newElementCtrl == source || newSubElementCtrl == source || moveElementCtrl == source || confirmDeleteCtrl == source) {
 			if(event == Event.DONE_EVENT || event == Event.CHANGED_EVENT) {
 				loadModel();
 			}
@@ -208,9 +209,11 @@ public class CurriculumComposerController extends FormBasicController implements
 	}
 	
 	private void cleanUp() {
+		removeAsListenerAndDispose(confirmDeleteCtrl);
 		removeAsListenerAndDispose(moveElementCtrl);
 		removeAsListenerAndDispose(newElementCtrl);
 		removeAsListenerAndDispose(cmc);
+		confirmDeleteCtrl = null;
 		moveElementCtrl = null;
 		newElementCtrl = null;
 		cmc = null;
@@ -346,6 +349,18 @@ public class CurriculumComposerController extends FormBasicController implements
 		}
 	}
 	
+	private void doConfirmDelete(UserRequest ureq, CurriculumElementRow row) {
+		if(confirmDeleteCtrl != null) return;
+		
+		confirmDeleteCtrl = new ConfirmCurriculumElementDeleteController(ureq, getWindowControl(), row);
+		listenTo(confirmDeleteCtrl);
+		
+		cmc = new CloseableModalController(getWindowControl(), "close", confirmDeleteCtrl.getInitialComponent(), true,
+				translate("confirmation.delete.element.title", new String[] { row.getDisplayName() }));
+		listenTo(cmc);
+		cmc.activate();
+	}
+	
 	private void launch(UserRequest ureq, RepositoryEntryRef ref) {
 		String businessPath = "[RepositoryEntry:" + ref.getKey() + "]";
 		if(!NewControllerFactory.getInstance().launch(businessPath, ureq, getWindowControl())) {
@@ -453,7 +468,7 @@ public class CurriculumComposerController extends FormBasicController implements
 				doMoveCurriculumElement(ureq, row);
 			} else if(deleteLink == source) {
 				close();
-				showWarning("Not implemented");
+				doConfirmDelete(ureq, row);
 			} else if(newLink == source) {
 				close();
 				doNewSubCurriculumElement(ureq, row);
diff --git a/src/main/java/org/olat/modules/curriculum/ui/CurriculumListController.java b/src/main/java/org/olat/modules/curriculum/ui/CurriculumListController.java
index 9f9334b4fb268d00fc84ff6c9597b883bceedeb6..0183daf53459db18c97e27e9b7df806e2fdce5d7 100644
--- a/src/main/java/org/olat/modules/curriculum/ui/CurriculumListController.java
+++ b/src/main/java/org/olat/modules/curriculum/ui/CurriculumListController.java
@@ -141,5 +141,4 @@ public class CurriculumListController extends FormBasicController implements Act
 		listenTo(elementlistCtrl);
 		stackPanel.pushController(row.getDisplayName(), elementlistCtrl);
 	}
-
 }
diff --git a/src/main/java/org/olat/modules/curriculum/ui/_content/confirm_delete_curriculum_element.html b/src/main/java/org/olat/modules/curriculum/ui/_content/confirm_delete_curriculum_element.html
new file mode 100644
index 0000000000000000000000000000000000000000..2ece167be52dab0219075db8b8753fe9e31b0baf
--- /dev/null
+++ b/src/main/java/org/olat/modules/curriculum/ui/_content/confirm_delete_curriculum_element.html
@@ -0,0 +1,7 @@
+<div class="o_warning">
+	<p>$r.translate("confirmation.delete.element", ${element.getDisplayName()})</p>
+</div>
+<div class="o_button_group">
+	$r.render("cancel")
+	$r.render("delete")
+</div>
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_de.properties
index 0796de62cde9ff409489a351a403dcd712281f0d..071c19ab409bcb9ce82c08dac4f41d8d51d69dcd 100644
--- a/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/modules/curriculum/ui/_i18n/LocalStrings_de.properties
@@ -17,6 +17,8 @@ confirm.remove.resource.title=Lernresourcen entfernen
 confirm.remove.resource.text=Wollen Sie wirklich diesen Lernresourcen entfernen?
 confirmation.delete.type=Wollen Sie wirklich den Typ "{0}" l\u00F6schen?
 confirmation.delete.type.title=Typ "{0}" l\u00F6schen
+confirmation.delete.element=Wollen Sie wirklich diesen Curriculum Element "{0}" l\u00F6schen?
+confirmation.delete.element.title=Curriculum Element "{0}" l\u00F6schen
 curriculum.admin.enabled=Curriculum einschalten
 curriculum.configuration=Curriculum
 curriculum.description=Beschreibung
diff --git a/src/main/java/org/olat/modules/lecture/restapi/LectureBlockWebService.java b/src/main/java/org/olat/modules/lecture/restapi/LectureBlockWebService.java
index e133485c2f8138ad3ab9ce4393bec3569e49b9f7..1f176b4d1e2c00c8af8c845180cd787b2c4a4ea6 100644
--- a/src/main/java/org/olat/modules/lecture/restapi/LectureBlockWebService.java
+++ b/src/main/java/org/olat/modules/lecture/restapi/LectureBlockWebService.java
@@ -34,9 +34,13 @@ import javax.ws.rs.core.Response.Status;
 
 import org.olat.basesecurity.BaseSecurity;
 import org.olat.basesecurity.Group;
+import org.olat.core.commons.persistence.DB;
 import org.olat.core.id.Identity;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
+import org.olat.modules.curriculum.CurriculumElement;
+import org.olat.modules.curriculum.CurriculumElementStatus;
+import org.olat.modules.curriculum.CurriculumService;
 import org.olat.modules.lecture.LectureBlock;
 import org.olat.modules.lecture.LectureService;
 import org.olat.modules.lecture.manager.LectureBlockToTaxonomyLevelDAO;
@@ -63,6 +67,8 @@ public class LectureBlockWebService {
 	private final RepositoryEntry entry;
 	private final LectureBlock lectureBlock;
 	
+	@Autowired
+	private DB dbInstance;
 	@Autowired
 	private BaseSecurity securityManager;
 	@Autowired
@@ -72,6 +78,8 @@ public class LectureBlockWebService {
 	@Autowired
 	private RepositoryService repositoryService;
 	@Autowired
+	private CurriculumService curriculumService;
+	@Autowired
 	private LectureBlockToTaxonomyLevelDAO lectureBlockToTaxonomyLevelDao;
 	
 	public LectureBlockWebService(LectureBlock lectureBlock, RepositoryEntry entry) {
@@ -193,6 +201,7 @@ public class LectureBlockWebService {
 			currentGroups.add(defGroup);
 			reloadedBlock = lectureService.save(reloadedBlock, currentGroups);
 		}
+		dbInstance.commit();
 		lectureService.syncParticipantSummaries(reloadedBlock);
 		return Response.ok().build();
 	}
@@ -215,6 +224,64 @@ public class LectureBlockWebService {
 		return Response.ok().build();
 	}
 	
+	/**
+	 * Add the group of all curriculum elements to the lecture block participants list.
+	 * @response.representation.200.doc Successfully added
+	 * @return 200 if all ok
+	 */
+	@PUT
+	@Path("participants/curriculum")
+	public Response addCurriculumElementParticipantGroup() {
+		LectureBlock reloadedBlock = lectureService.getLectureBlock(lectureBlock);
+		List<CurriculumElement> elements = curriculumService.getCurriculumElements(entry);
+		List<Group> currentGroups = lectureService.getLectureBlockToGroups(reloadedBlock);
+		
+		boolean changed = false;
+		for(CurriculumElement element:elements) {
+			Group elementGroup = element.getGroup();
+			if(element.getStatus() != CurriculumElementStatus.deleted && !currentGroups.contains(elementGroup)) {
+				currentGroups.add(elementGroup);
+				changed = true;
+			}
+		}
+		if(changed) {
+			reloadedBlock = lectureService.save(reloadedBlock, currentGroups);
+		}
+		dbInstance.commit();
+		lectureService.syncParticipantSummaries(reloadedBlock);
+		Status status = changed ? Status.OK : Status.NOT_MODIFIED;
+		return Response.ok(status).build();
+	}
+	
+	/**
+	 * Remove the group of all curriculum elements from the lecture block participants.
+	 * @response.representation.200.doc Successfully removed
+	 * @return 200 if all ok
+	 */
+	@DELETE
+	@Path("participants/curriculum")
+	public Response deleteCurriculumElementParticipantGroup() {
+		LectureBlock reloadedBlock = lectureService.getLectureBlock(lectureBlock);
+		List<CurriculumElement> elements = curriculumService.getCurriculumElements(entry);
+		List<Group> currentGroups = lectureService.getLectureBlockToGroups(reloadedBlock);
+		
+		boolean changed = false;
+		for(CurriculumElement element:elements) {
+			Group elementGroup = element.getGroup();
+			if(currentGroups.contains(elementGroup)) {
+				currentGroups.remove(elementGroup);
+				changed = true;
+			}
+		}
+		
+		if(changed) {
+			lectureService.save(reloadedBlock, currentGroups);
+		}
+		
+		Status status = changed ? Status.OK : Status.NOT_MODIFIED;
+		return Response.ok(status).build();
+	}
+	
 	@GET
 	@Path("taxonomy/levels")
 	@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
diff --git a/src/main/java/org/olat/modules/lecture/ui/EditLectureBlockController.java b/src/main/java/org/olat/modules/lecture/ui/EditLectureBlockController.java
index 0aa76fb495266476cd40967d0429b375d0262414..965b6255f8adfdf7351df9e645f213e3dd24e782 100644
--- a/src/main/java/org/olat/modules/lecture/ui/EditLectureBlockController.java
+++ b/src/main/java/org/olat/modules/lecture/ui/EditLectureBlockController.java
@@ -57,6 +57,8 @@ import org.olat.group.BusinessGroup;
 import org.olat.group.BusinessGroupOrder;
 import org.olat.group.BusinessGroupService;
 import org.olat.group.model.SearchBusinessGroupParams;
+import org.olat.modules.curriculum.CurriculumElement;
+import org.olat.modules.curriculum.CurriculumService;
 import org.olat.modules.lecture.LectureBlock;
 import org.olat.modules.lecture.LectureBlockAuditLog;
 import org.olat.modules.lecture.LectureBlockManagedFlag;
@@ -114,6 +116,8 @@ public class EditLectureBlockController extends FormBasicController {
 	@Autowired
 	private RepositoryService repositoryService;
 	@Autowired
+	private CurriculumService curriculumService;
+	@Autowired
 	private BusinessGroupService businessGroupService;
 
 	public EditLectureBlockController(UserRequest ureq, WindowControl wControl, RepositoryEntry entry) {
@@ -217,6 +221,10 @@ public class EditLectureBlockController extends FormBasicController {
 		for(BusinessGroup businessGroup:businessGroups) {
 			groupBox.add(new GroupBox(businessGroup));
 		}
+		List<CurriculumElement> elements = curriculumService.getCurriculumElements(entry);
+		for(CurriculumElement element:elements) {
+			groupBox.add(new GroupBox(element));
+		}
 		String[] groupKeys = new String[groupBox.size()];
 		String[] groupValues = new String[groupBox.size()];
 		for(int i=groupBox.size(); i-->0; ) {
@@ -345,7 +353,7 @@ public class EditLectureBlockController extends FormBasicController {
 
 	@Override
 	protected boolean validateFormLogic(UserRequest ureq) {
-		boolean allOk = true;
+		boolean allOk = super.validateFormLogic(ureq);
 		
 		titleEl.clearError();
 		if(!StringHelper.containsNonWhitespace(titleEl.getValue())) {
@@ -381,7 +389,7 @@ public class EditLectureBlockController extends FormBasicController {
 		allOk &= validateInt(startMinuteEl, 60);
 		allOk &= validateInt(endHourEl, 24);
 		allOk &= validateInt(endMinuteEl, 60);
-		return allOk & super.validateFormLogic(ureq);
+		return allOk;
 	}
 	
 	private boolean validateInt(TextElement element, int max) {
@@ -560,6 +568,7 @@ public class EditLectureBlockController extends FormBasicController {
 		
 		private BusinessGroup businessGroup;
 		private RepositoryEntry repoEntry;
+		private CurriculumElement curriculumElement;
 		private final Group baseGroup;
 		
 		public GroupBox(RepositoryEntry entry, Group baseGroup) {
@@ -572,6 +581,11 @@ public class EditLectureBlockController extends FormBasicController {
 			baseGroup = businessGroup.getBaseGroup();
 		}
 		
+		public GroupBox(CurriculumElement curriculumElement) {
+			this.curriculumElement = curriculumElement;
+			baseGroup = curriculumElement.getGroup();
+		}
+		
 		public String getName() {
 			if(repoEntry != null) {
 				return repoEntry.getDisplayname();
@@ -579,6 +593,9 @@ public class EditLectureBlockController extends FormBasicController {
 			if(businessGroup != null) {
 				return businessGroup.getName();
 			}
+			if(curriculumElement != null) {
+				return curriculumElement.getDisplayName();
+			}
 			return null;
 		}
 		
diff --git a/src/main/java/org/olat/modules/lecture/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/lecture/ui/_i18n/LocalStrings_de.properties
index d47773937dcdfc16c70c038d3c05112dc8233020..39fe2fcac4f6b531230b1bcc5ebf14a9b61ca668 100644
--- a/src/main/java/org/olat/modules/lecture/ui/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/modules/lecture/ui/_i18n/LocalStrings_de.properties
@@ -128,7 +128,7 @@ lecture.descr=Beschreibung
 lecture.end=Ende
 lecture.from.to=Zeit von\:
 lecture.from.to.format={0} bis {1}
-lecture.groups=Kurs / Gruppe
+lecture.groups=Kurs / Gruppe / Curriculum
 lecture.location=Ort
 lecture.preparation=Vorbereitung/Nachbereitung
 lecture.reminder.enabled=Erinnerungsfunktion einschalten
diff --git a/src/main/java/org/olat/modules/lecture/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/modules/lecture/ui/_i18n/LocalStrings_en.properties
index 3f3312beb46ae54e28474b65adbe60d482394ba2..c9d9738fff6c2a9e635b250d60ece118dc6a2137 100644
--- a/src/main/java/org/olat/modules/lecture/ui/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/modules/lecture/ui/_i18n/LocalStrings_en.properties
@@ -128,7 +128,7 @@ lecture.descr=Description
 lecture.end=End
 lecture.from.to=Time from\:
 lecture.from.to.format={0} until {1}
-lecture.groups=Course / groups
+lecture.groups=Course / groups / curriculum
 lecture.location=Location
 lecture.preparation=Preparation
 lecture.reminder.enabled=Reminder enabled
diff --git a/src/main/java/org/olat/modules/lecture/ui/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/modules/lecture/ui/_i18n/LocalStrings_fr.properties
index 33707d271d85337ec91f10459d555209af656bf6..cf178e9ae29c7b522a200e453384792f3b84bbd9 100644
--- a/src/main/java/org/olat/modules/lecture/ui/_i18n/LocalStrings_fr.properties
+++ b/src/main/java/org/olat/modules/lecture/ui/_i18n/LocalStrings_fr.properties
@@ -117,7 +117,7 @@ lecture.descr=Description
 lecture.end=Fin
 lecture.from.to=Depuis
 lecture.from.to.format={0} jusqu'\u00E0 {1}
-lecture.groups=Cours / groupes
+lecture.groups=Cours / groupes / curriculum
 lecture.location=Lieu
 lecture.preparation=Pr\u00E9paration/suivi
 lecture.reminder.enabled=Activ\u00E9 la fonction de rappel
diff --git a/src/main/java/org/olat/modules/lecture/ui/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/modules/lecture/ui/_i18n/LocalStrings_pt_BR.properties
index 5ccf764d7b1431551c0aad59b6115e74520b658b..ca1467a93c51917bb07dd1cffa0fd495aa6c950a 100644
--- a/src/main/java/org/olat/modules/lecture/ui/_i18n/LocalStrings_pt_BR.properties
+++ b/src/main/java/org/olat/modules/lecture/ui/_i18n/LocalStrings_pt_BR.properties
@@ -117,7 +117,6 @@ lecture.descr=Descri\u00E7\u00E3o
 lecture.end=Fim
 lecture.from.to=Tempo de\:
 lecture.from.to.format={0} at\u00E9 {1}
-lecture.groups=Curso / grupos
 lecture.location=Localiza\u00E7\u00E3o
 lecture.preparation=Prepara\u00E7\u00E3o
 lecture.reminder.enabled=Lembrete ativo
diff --git a/src/main/java/org/olat/repository/manager/RepositoryEntryRelationDAO.java b/src/main/java/org/olat/repository/manager/RepositoryEntryRelationDAO.java
index 83943b0872abfd09d8f9a57fe71fc8ebe1d6cafa..f635287416b6791de32917c7dad84b855653b884 100644
--- a/src/main/java/org/olat/repository/manager/RepositoryEntryRelationDAO.java
+++ b/src/main/java/org/olat/repository/manager/RepositoryEntryRelationDAO.java
@@ -43,6 +43,7 @@ import org.olat.core.commons.persistence.PersistenceHelper;
 import org.olat.core.id.Identity;
 import org.olat.core.id.Organisation;
 import org.olat.core.id.OrganisationRef;
+import org.olat.modules.curriculum.CurriculumElementRef;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryEntryRef;
 import org.olat.repository.RepositoryEntryRelationType;
@@ -612,7 +613,7 @@ public class RepositoryEntryRelationDAO {
 	 * @return The number of relations
 	 */
 	public int countRelations(Group group) {
-		StringBuilder sb = new StringBuilder();
+		StringBuilder sb = new StringBuilder(128);
 		sb.append("select count(rel) from repoentrytogroup as rel")
 		  .append(" where rel.group.key=:groupKey");
 
@@ -626,7 +627,7 @@ public class RepositoryEntryRelationDAO {
 	public List<RepositoryEntryToGroupRelation> getBusinessGroupAndCurriculumRelations(RepositoryEntryRef re) {
 		if(re == null) return Collections.emptyList();
 		
-		StringBuilder sb = new StringBuilder();
+		StringBuilder sb = new StringBuilder(512);
 		sb.append("select rel from repoentrytogroup as rel")
 		  .append(" inner join fetch rel.entry as entry")
 		  .append(" inner join fetch rel.group as baseGroup")
@@ -640,6 +641,22 @@ public class RepositoryEntryRelationDAO {
 			.getResultList();
 	}
 	
+	public List<RepositoryEntryToGroupRelation> getCurriculumRelations(CurriculumElementRef curriculumElement) {
+		if(curriculumElement == null || curriculumElement.getKey() == null) return Collections.emptyList();
+		
+		StringBuilder sb = new StringBuilder(512);
+		sb.append("select rel from repoentrytogroup as rel")
+		  .append(" inner join fetch rel.entry as entry")
+		  .append(" inner join fetch rel.group as baseGroup")
+		  .append(" inner join curriculumelement curEl on (curEl.group.key=baseGroup.key)")
+		  .append(" where curEl.key=:elementKey");
+
+		return dbInstance.getCurrentEntityManager()
+			.createQuery(sb.toString(), RepositoryEntryToGroupRelation.class)
+			.setParameter("elementKey", curriculumElement.getKey())
+			.getResultList();
+	}
+	
 	public boolean hasRelation(Group group, RepositoryEntryRef re) {
 		if(re == null || group == null) return false;
 		
diff --git a/src/test/java/org/olat/modules/curriculum/manager/CurriculumRepositoryEntryRelationDAOTest.java b/src/test/java/org/olat/modules/curriculum/manager/CurriculumRepositoryEntryRelationDAOTest.java
index 084c2a5471e16f54d78673d05961ef2c2c6469b9..6c9200b209ae1d6cfdf54d8135b162336b855c27 100644
--- a/src/test/java/org/olat/modules/curriculum/manager/CurriculumRepositoryEntryRelationDAOTest.java
+++ b/src/test/java/org/olat/modules/curriculum/manager/CurriculumRepositoryEntryRelationDAOTest.java
@@ -31,6 +31,7 @@ import org.olat.modules.curriculum.CurriculumElement;
 import org.olat.modules.curriculum.CurriculumRoles;
 import org.olat.modules.curriculum.CurriculumService;
 import org.olat.repository.RepositoryEntry;
+import org.olat.repository.RepositoryEntryStatusEnum;
 import org.olat.test.JunitTestHelper;
 import org.olat.test.OlatTestCase;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -60,7 +61,7 @@ public class CurriculumRepositoryEntryRelationDAOTest extends OlatTestCase {
 		curriculumService.addRepositoryEntry(element, entry, false);
 		dbInstance.commitAndCloseSession();
 		
-		List<RepositoryEntry> entries = curriculumRepositoryEntryRelationDao.getRepositoryEntries(element);
+		List<RepositoryEntry> entries = curriculumRepositoryEntryRelationDao.getRepositoryEntries(element, RepositoryEntryStatusEnum.preparationToClosed());
 		Assert.assertNotNull(entries);
 		Assert.assertEquals(1, entries.size());
 		Assert.assertEquals(entry, entries.get(0));
diff --git a/src/test/java/org/olat/restapi/LecturesBlocksTest.java b/src/test/java/org/olat/restapi/LecturesBlocksTest.java
index 7bbaa24ef2afb50f0ac0cc1175e40414d89466c6..4ff3f6d94020b3c866195fba5a45cb52bce6d647 100644
--- a/src/test/java/org/olat/restapi/LecturesBlocksTest.java
+++ b/src/test/java/org/olat/restapi/LecturesBlocksTest.java
@@ -43,12 +43,17 @@ import org.assertj.core.api.Assertions;
 import org.junit.Assert;
 import org.junit.Test;
 import org.olat.basesecurity.Group;
+import org.olat.basesecurity.OrganisationService;
 import org.olat.core.commons.persistence.DB;
 import org.olat.core.id.Identity;
+import org.olat.core.id.Organisation;
 import org.olat.core.logging.OLog;
 import org.olat.core.logging.Tracing;
 import org.olat.course.CourseFactory;
 import org.olat.course.ICourse;
+import org.olat.modules.curriculum.Curriculum;
+import org.olat.modules.curriculum.CurriculumElement;
+import org.olat.modules.curriculum.CurriculumService;
 import org.olat.modules.lecture.LectureBlock;
 import org.olat.modules.lecture.LectureBlockStatus;
 import org.olat.modules.lecture.LectureBlockToTaxonomyLevel;
@@ -95,6 +100,10 @@ public class LecturesBlocksTest extends OlatJerseyTestCase {
 	@Autowired
 	private RepositoryService repositoryService;
 	@Autowired
+	private CurriculumService curriculumService;
+	@Autowired
+	private OrganisationService organisationService;
+	@Autowired
 	private LectureBlockToTaxonomyLevelDAO lectureBlockToTaxonomyLevelDao;
 	
 	/**
@@ -460,6 +469,78 @@ public class LecturesBlocksTest extends OlatJerseyTestCase {
 		Assert.assertEquals(0, groups.size());
 	}
 
+	@Test
+	public void addRepositoryEntryCurriculumElementToLectureBlock()
+	throws IOException, URISyntaxException {
+		// prepare a course with a curriculum element and a lecture block
+		Identity author = JunitTestHelper.createAndPersistIdentityAsAuthor("lect-1");
+		RepositoryEntry entry = JunitTestHelper.deployBasicCourse(author);
+		LectureBlock block = createLectureBlock(entry);
+		dbInstance.commit();
+		Organisation defOrganisation = organisationService.getDefaultOrganisation();
+		Curriculum curriculum = curriculumService.createCurriculum("add-group", "Add group REST", "", defOrganisation);
+		CurriculumElement curriculumElement = curriculumService.createCurriculumElement("add-group", "Add element group", null, null, null, null, curriculum);
+		curriculumService.addRepositoryEntry(curriculumElement, entry, true);
+		dbInstance.commit();
+
+		RestConnection conn = new RestConnection();
+		Assert.assertTrue(conn.login("administrator", "openolat"));
+
+		URI uri = UriBuilder.fromUri(getContextURI()).path("repo").path("entries")
+				.path(entry.getKey().toString())
+				.path("lectureblocks").path(block.getKey().toString())
+				.path("participants").path("curriculum").build();
+		HttpPut method = conn.createPut(uri, MediaType.APPLICATION_JSON, true);
+		HttpResponse response = conn.execute(method);
+		
+		// check the response
+		Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+		EntityUtils.consume(response.getEntity());
+		
+		//check the database
+		List<Group> groups = lectureService.getLectureBlockToGroups(block);
+		Assert.assertNotNull(groups);
+		Assert.assertEquals(1, groups.size());
+		Assert.assertTrue(groups.contains(curriculumElement.getGroup()));
+	}
+	
+	@Test
+	public void removeRepositoryEntryCurriculumElementToLectureBlock()
+	throws IOException, URISyntaxException {
+		// prepare a course with a curriculum element and a lecture block
+		// the lecture block use already the curriculum element as source of participants
+		Identity author = JunitTestHelper.createAndPersistIdentityAsAuthor("lect-1");
+		RepositoryEntry entry = JunitTestHelper.deployBasicCourse(author);
+		LectureBlock block = createLectureBlock(entry);
+		dbInstance.commit();
+		Organisation defOrganisation = organisationService.getDefaultOrganisation();
+		Curriculum curriculum = curriculumService.createCurriculum("rm-group", "Remove group REST", "", defOrganisation);
+		CurriculumElement curriculumElement = curriculumService.createCurriculumElement("rm-group", "Remove element group", null, null, null, null, curriculum);
+		curriculumService.addRepositoryEntry(curriculumElement, entry, true);
+		dbInstance.commit();
+		lectureService.save(block, Collections.singletonList(curriculumElement.getGroup()));
+		dbInstance.commit();
+		
+		RestConnection conn = new RestConnection();
+		Assert.assertTrue(conn.login("administrator", "openolat"));
+
+		URI uri = UriBuilder.fromUri(getContextURI()).path("repo").path("entries")
+				.path(entry.getKey().toString())
+				.path("lectureblocks").path(block.getKey().toString())
+				.path("participants").path("curriculum").build();
+		HttpDelete method = conn.createDelete(uri, MediaType.APPLICATION_JSON);
+		HttpResponse response = conn.execute(method);
+		
+		// check the response
+		Assert.assertEquals(200, response.getStatusLine().getStatusCode());
+		EntityUtils.consume(response.getEntity());
+		
+		//check the database
+		List<Group> groups = lectureService.getLectureBlockToGroups(block);
+		Assert.assertNotNull(groups);
+		Assert.assertTrue(groups.isEmpty());
+	}
+
 	@Test
 	public void addTeacherToLectureBlock()
 	throws IOException, URISyntaxException {