From eb9227823123e2548a4249d0343236b13884c6d0 Mon Sep 17 00:00:00 2001
From: uhensler <urs.hensler@frentix.com>
Date: Fri, 24 May 2019 10:04:49 +0200
Subject: [PATCH] OO-4066: Add whone curriculum element hierarchy to email and
 report context

---
 .../modules/curriculum/CurriculumService.java |  2 +-
 .../manager/CurriculumElementDAO.java         |  5 +-
 .../manager/CurriculumServiceImpl.java        |  2 +-
 .../quality/manager/QualityMailing.java       |  2 +-
 ...ualityUIContextsDataCollectionBuilder.java | 54 ++++++++++++++-----
 5 files changed, 48 insertions(+), 17 deletions(-)

diff --git a/src/main/java/org/olat/modules/curriculum/CurriculumService.java b/src/main/java/org/olat/modules/curriculum/CurriculumService.java
index 6237bbd9069..7c8cb5c61a3 100644
--- a/src/main/java/org/olat/modules/curriculum/CurriculumService.java
+++ b/src/main/java/org/olat/modules/curriculum/CurriculumService.java
@@ -240,7 +240,7 @@ public interface CurriculumService {
 	
 	public CurriculumElement getCurriculumElement(CurriculumElementRef element);
 
-	public List<CurriculumElement> getCurriculumElements(Collection<CurriculumElementRef> elementRefs);
+	public List<CurriculumElement> getCurriculumElements(Collection<? extends CurriculumElementRef> elementRefs);
 	
 	public void deleteCurriculumElement(CurriculumElementRef element);
 	
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 5c172fe8d2a..fa071327a7f 100644
--- a/src/main/java/org/olat/modules/curriculum/manager/CurriculumElementDAO.java
+++ b/src/main/java/org/olat/modules/curriculum/manager/CurriculumElementDAO.java
@@ -144,19 +144,20 @@ public class CurriculumElementDAO {
 		return elements == null || elements.isEmpty() ? null : elements.get(0);
 	}
 
-	public List<CurriculumElement> loadByKeys(Collection<CurriculumElementRef> elementRefs) {
+	public List<CurriculumElement> loadByKeys(Collection<? extends CurriculumElementRef> elementRefs) {
 		if (elementRefs == null || elementRefs.isEmpty()) return new ArrayList<>(0);
 		
 		StringBuilder sb = new StringBuilder(128);
 		sb.append("select el");
 		sb.append("  from curriculumelement el");
 		sb.append("       left join fetch el.type");
+		sb.append("       left join el.parent parentEl");
 		sb.append(" where el.key in :keys");
 		
 		List<Long> keys = elementRefs.stream().map(CurriculumElementRef::getKey).collect(Collectors.toList());
 		return dbInstance.getCurrentEntityManager()
 				.createQuery(sb.toString(), CurriculumElement.class)
-				.setParameter("keys", keys )
+				.setParameter("keys", keys)
 				.getResultList();
 	}
 	
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 5159c8ea214..d40556a4aab 100644
--- a/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java
+++ b/src/main/java/org/olat/modules/curriculum/manager/CurriculumServiceImpl.java
@@ -338,7 +338,7 @@ public class CurriculumServiceImpl implements CurriculumService, OrganisationDat
 	}
 
 	@Override
-	public List<CurriculumElement> getCurriculumElements(Collection<CurriculumElementRef> elementRefs) {
+	public List<CurriculumElement> getCurriculumElements(Collection<? extends CurriculumElementRef> elementRefs) {
 		return curriculumElementDao.loadByKeys(elementRefs);
 	}
 
diff --git a/src/main/java/org/olat/modules/quality/manager/QualityMailing.java b/src/main/java/org/olat/modules/quality/manager/QualityMailing.java
index 7b024642d6a..d655c715ec4 100644
--- a/src/main/java/org/olat/modules/quality/manager/QualityMailing.java
+++ b/src/main/java/org/olat/modules/quality/manager/QualityMailing.java
@@ -323,8 +323,8 @@ class QualityMailing {
 		StringBuilder sb = new StringBuilder();
 		List<UIContext> uiContexts = QualityUIContextsBuilder.builder(dataCollection, locale)
 				.addAttribute(Attribute.ROLE)
-				.addAttribute(Attribute.COURSE)
 				.addAttribute(Attribute.CURRICULUM_ELEMENTS)
+				.addAttribute(Attribute.COURSE)
 				.addAttribute(Attribute.TAXONOMY_LEVELS)
 				.build()
 				.getUiContexts();
diff --git a/src/main/java/org/olat/modules/quality/ui/QualityUIContextsDataCollectionBuilder.java b/src/main/java/org/olat/modules/quality/ui/QualityUIContextsDataCollectionBuilder.java
index 3642cd4a0c0..6d78b177d83 100644
--- a/src/main/java/org/olat/modules/quality/ui/QualityUIContextsDataCollectionBuilder.java
+++ b/src/main/java/org/olat/modules/quality/ui/QualityUIContextsDataCollectionBuilder.java
@@ -36,6 +36,7 @@ import org.olat.core.util.StringHelper;
 import org.olat.core.util.Util;
 import org.olat.modules.curriculum.CurriculumElement;
 import org.olat.modules.curriculum.CurriculumElementType;
+import org.olat.modules.curriculum.CurriculumService;
 import org.olat.modules.quality.QualityContext;
 import org.olat.modules.quality.QualityContextRole;
 import org.olat.modules.quality.QualityContextToCurriculumElement;
@@ -64,6 +65,8 @@ public class QualityUIContextsDataCollectionBuilder extends QualityUIContextsBui
 	
 	@Autowired
 	private QualityService qualityService;
+	@Autowired
+	private CurriculumService curriculumService;
 	
 	QualityUIContextsDataCollectionBuilder(QualityDataCollection dataCollection, Locale locale) {
 		this.dataCollection = dataCollection;
@@ -105,6 +108,10 @@ public class QualityUIContextsDataCollectionBuilder extends QualityUIContextsBui
 					uiContext.add(keyValue);
 				}
 			}
+			if (attributes.contains(Attribute.CURRICULUM_ELEMENTS)) {
+				Collection<KeyValue> keyValues = getCurriculumElements(contexts);
+				uiContext.addAll(keyValues);
+			}
 			if (attributes.contains(Attribute.COURSE)) {
 				String value = getAudienceCourses(contexts);
 				if (StringHelper.containsNonWhitespace(value)) {
@@ -113,10 +120,6 @@ public class QualityUIContextsDataCollectionBuilder extends QualityUIContextsBui
 					uiContext.add(keyValue);
 				}
 			}
-			if (attributes.contains(Attribute.CURRICULUM_ELEMENTS)) {
-				Collection<KeyValue> keyValues = getCurriculumElements(contexts);
-				uiContext.addAll(keyValues);
-			}
 			if (attributes.contains(Attribute.TAXONOMY_LEVELS)) {
 				Collection<KeyValue> keyValues = getTaxonomyLevels(contexts);
 				uiContext.addAll(keyValues);
@@ -159,25 +162,52 @@ public class QualityUIContextsDataCollectionBuilder extends QualityUIContextsBui
 				.collect(Collectors.joining(DELIMITER));
 	}
 	
-	private Collection<KeyValue> getCurriculumElements(List<QualityContext> contexts) {
-		// Group curriculum elements by the name of the type and join the display names
-		Map<String, String> typesNamesToCurriculumElements = contexts.stream()
+	private List<KeyValue> getCurriculumElements(List<QualityContext> contexts) {
+		// Get a list of all curriculum elements and its parents.
+		List<CurriculumElement> elements = contexts.stream()
 				.map(QualityContext::getContextToCurriculumElement)
 				.flatMap(Set::stream)
 				.map(QualityContextToCurriculumElement::getCurriculumElement)
 				.distinct()
 				.filter(Objects::nonNull)
-				.collect(Collectors.groupingBy(element -> getTypeName(element),
-					Collectors.mapping(CurriculumElement::getDisplayName, Collectors.joining(DELIMITER))));
+				.collect(Collectors.toList());
 		
-		List<KeyValue> keyValues = new ArrayList<>(typesNamesToCurriculumElements.size());
-		for (Map.Entry<String, String> entry : typesNamesToCurriculumElements.entrySet()) {
-			KeyValue keyValue = new KeyValue(entry.getKey(), entry.getValue());
+		// reload to fetch the parents
+		elements = curriculumService.getCurriculumElements(elements);
+		List<CurriculumElement> elementsHierarchical = new ArrayList<>();
+		for (CurriculumElement element: elements) {
+			addParents(elementsHierarchical, element);
+		}
+		// reverse, so that the top most element is the first element
+		List<CurriculumElement> invertedList = new ArrayList<>();
+		for (int i = elementsHierarchical.size() - 1; i >= 0; i--) {
+			invertedList.add(elementsHierarchical.get(i));
+		}
+		elementsHierarchical = invertedList;
+		
+		List<KeyValue> keyValues = new ArrayList<>(elementsHierarchical.size());
+		for (CurriculumElement element : elementsHierarchical) {
+			KeyValue keyValue = new KeyValue(getTypeName(element), getName(element));
 			keyValues.add(keyValue);
 		}
 		return keyValues;
 	}
+
+	private void addParents(List<CurriculumElement> elementsHierarchical, CurriculumElement element) {
+		elementsHierarchical.add(element);
+		if (element.getParent() != null) {
+			addParents(elementsHierarchical, element.getParent());
+		}
+	}
 	
+	private String getName(CurriculumElement element) {
+		StringBuilder sb = new StringBuilder(element.getDisplayName());
+		if (StringHelper.containsNonWhitespace(element.getIdentifier())) {
+			sb.append(" (").append(element.getIdentifier()).append(")");
+		}
+		return sb.toString();
+	}
+
 	private String getTypeName(CurriculumElement element) {
 		CurriculumElementType curriculumElementType = element.getType();
 		return curriculumElementType != null
-- 
GitLab