From baa14ee5c751ef0d361fd86a19820264c30fe9d4 Mon Sep 17 00:00:00 2001
From: uhensler <urs.hensler@frentix.com>
Date: Tue, 17 Dec 2019 16:25:47 +0100
Subject: [PATCH] OO-4422: Order containerized elements of surveys in reports
 and Excel export

---
 .../nodes/ms/MSStatisticController.java       |  3 +-
 .../modules/forms/EvaluationFormManager.java  |  9 ++++++
 .../manager/EvaluationFormManagerImpl.java    | 32 +++++++++++++++++++
 .../forms/ui/EvaluationFormExcelExport.java   |  3 +-
 .../ui/EvaluationFormReportController.java    |  8 ++++-
 .../analysis/ui/GroupByController.java        |  6 +++-
 6 files changed, 57 insertions(+), 4 deletions(-)

diff --git a/src/main/java/org/olat/course/nodes/ms/MSStatisticController.java b/src/main/java/org/olat/course/nodes/ms/MSStatisticController.java
index 1e01c8f9fba..dca6b34f405 100644
--- a/src/main/java/org/olat/course/nodes/ms/MSStatisticController.java
+++ b/src/main/java/org/olat/course/nodes/ms/MSStatisticController.java
@@ -144,7 +144,8 @@ public class MSStatisticController extends FormBasicController {
 	private List<RubricWrapper> wrapRubics(Form form) {
 		int counter = 1;
 		List<RubricWrapper> rubrics = new ArrayList<>();
-		for (AbstractElement element : form.getElements()) {
+		List<AbstractElement> elements = evaluationFormManager.getUncontainerizedElements(form);
+		for (AbstractElement element : elements) {
 			if (Rubric.TYPE.equals(element.getType())) {
 				Rubric rubric = (Rubric)element;
 				String labelCode = translate("tool.stats.table.title.rubric", new String[] { Integer.toString(counter) });
diff --git a/src/main/java/org/olat/modules/forms/EvaluationFormManager.java b/src/main/java/org/olat/modules/forms/EvaluationFormManager.java
index 32bb2666882..b29bac8fd69 100644
--- a/src/main/java/org/olat/modules/forms/EvaluationFormManager.java
+++ b/src/main/java/org/olat/modules/forms/EvaluationFormManager.java
@@ -31,6 +31,7 @@ import org.olat.core.id.Identity;
 import org.olat.core.util.vfs.VFSLeaf;
 import org.olat.modules.ceditor.DataStorage;
 import org.olat.modules.forms.model.jpa.EvaluationFormResponses;
+import org.olat.modules.forms.model.xml.AbstractElement;
 import org.olat.modules.forms.model.xml.Form;
 import org.olat.modules.forms.model.xml.Rubric;
 import org.olat.repository.RepositoryEntry;
@@ -48,6 +49,14 @@ public interface EvaluationFormManager {
 	public Form loadForm(RepositoryEntry formEntry);
 	
 	public DataStorage loadStorage(RepositoryEntry formEntry);
+	
+	/**
+	 * Removes all Containers and returns the elements in the right order.
+	 *
+	 * @param form
+	 * @return
+	 */
+	public List<AbstractElement> getUncontainerizedElements(Form form);
 
 	public EvaluationFormSurvey createSurvey(EvaluationFormSurveyIdentifier identifier, RepositoryEntry formEntry);
 	
diff --git a/src/main/java/org/olat/modules/forms/manager/EvaluationFormManagerImpl.java b/src/main/java/org/olat/modules/forms/manager/EvaluationFormManagerImpl.java
index f4bf6f7163e..9c7dbfeef06 100644
--- a/src/main/java/org/olat/modules/forms/manager/EvaluationFormManagerImpl.java
+++ b/src/main/java/org/olat/modules/forms/manager/EvaluationFormManagerImpl.java
@@ -31,6 +31,8 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 import org.olat.basesecurity.IdentityRef;
@@ -68,6 +70,8 @@ import org.olat.modules.forms.model.SlidersStepCountsImpl;
 import org.olat.modules.forms.model.StepCountsBuilder;
 import org.olat.modules.forms.model.jpa.CalculatedLong;
 import org.olat.modules.forms.model.jpa.EvaluationFormResponses;
+import org.olat.modules.forms.model.xml.AbstractElement;
+import org.olat.modules.forms.model.xml.Container;
 import org.olat.modules.forms.model.xml.Form;
 import org.olat.modules.forms.model.xml.FormXStream;
 import org.olat.modules.forms.model.xml.Rubric;
@@ -124,6 +128,34 @@ public class EvaluationFormManagerImpl implements EvaluationFormManager {
 		return new FormDataElementStorage(formFile);
 	}
 
+	@Override
+	public List<AbstractElement> getUncontainerizedElements(Form form) {
+		List<AbstractElement> rawElements = form.getElements();
+		Map<String, AbstractElement> elementIdToElement = rawElements.stream()
+				.collect(Collectors.toMap(AbstractElement::getId, Function.identity()));
+		
+		List<AbstractElement> uncontainerizedElements = new ArrayList<>(rawElements.size());
+		for (AbstractElement element : rawElements) {
+			if (element instanceof Container) {
+				Container container = (Container)element;
+				List<String> allElementIds = container.getContainerSettings().getAllElementIds();
+				for (String elementId : allElementIds) {
+					AbstractElement uncontainerizedElement = elementIdToElement.remove(elementId);
+					if (uncontainerizedElement != null) {
+						uncontainerizedElements.add(uncontainerizedElement);
+					}
+				}
+			} else {
+				AbstractElement uncontainerizedElement = elementIdToElement.remove(element.getId());
+				// If null, it was already in a container
+				if (uncontainerizedElement != null) {
+					uncontainerizedElements.add(uncontainerizedElement);
+				}
+			}
+		}
+		return uncontainerizedElements;
+	}
+
 	@Override
 	public EvaluationFormSurvey createSurvey(EvaluationFormSurveyIdentifier identifier, RepositoryEntry formEntry) {
 		return evaluationFormSurveyDao.createSurvey(identifier.getOLATResourceable(), identifier.getSubident(),
diff --git a/src/main/java/org/olat/modules/forms/ui/EvaluationFormExcelExport.java b/src/main/java/org/olat/modules/forms/ui/EvaluationFormExcelExport.java
index e1eb6004abd..74d900d8619 100644
--- a/src/main/java/org/olat/modules/forms/ui/EvaluationFormExcelExport.java
+++ b/src/main/java/org/olat/modules/forms/ui/EvaluationFormExcelExport.java
@@ -147,7 +147,8 @@ public class EvaluationFormExcelExport {
 	}
 
 	private void addContent(OpenXMLWorkbook workbook, OpenXMLWorksheet exportSheet) {
-		for (AbstractElement element: form.getElements()) {
+		List<AbstractElement> elements = evaluationFormManager.getUncontainerizedElements(form);
+		for (AbstractElement element: elements) {
 			String elementType = element.getType();
 			switch (elementType) {
 			case Title.TYPE:
diff --git a/src/main/java/org/olat/modules/forms/ui/EvaluationFormReportController.java b/src/main/java/org/olat/modules/forms/ui/EvaluationFormReportController.java
index 5b4f7f42a58..16064f9f736 100644
--- a/src/main/java/org/olat/modules/forms/ui/EvaluationFormReportController.java
+++ b/src/main/java/org/olat/modules/forms/ui/EvaluationFormReportController.java
@@ -30,6 +30,7 @@ import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.util.CodeHelper;
 import org.olat.modules.ceditor.DataStorage;
+import org.olat.modules.forms.EvaluationFormManager;
 import org.olat.modules.forms.RubricsComparison;
 import org.olat.modules.forms.SessionFilter;
 import org.olat.modules.forms.handler.DefaultReportProvider;
@@ -40,6 +41,7 @@ import org.olat.modules.forms.model.xml.AbstractElement;
 import org.olat.modules.forms.model.xml.Form;
 import org.olat.modules.forms.model.xml.Rubric;
 import org.olat.modules.forms.ui.model.EvaluationFormReportElement;
+import org.springframework.beans.factory.annotation.Autowired;
 
 /**
  * 
@@ -57,6 +59,9 @@ public class EvaluationFormReportController extends FormBasicController {
 	private final Component header;
 	private final List<ReportFragment> fragments = new ArrayList<>();
 	
+	@Autowired
+	private EvaluationFormManager evaluationFormManager;
+	
 	public EvaluationFormReportController(UserRequest ureq, WindowControl wControl, Form form, DataStorage storage, SessionFilter filter) {
 			this(ureq, wControl, form, storage, filter, null, null, null);
 	}
@@ -89,7 +94,8 @@ public class EvaluationFormReportController extends FormBasicController {
 		if (header != null) {
 			flc.put("header", header);
 		}
-		for (AbstractElement element: form.getElements()) {
+		List<AbstractElement> elements = evaluationFormManager.getUncontainerizedElements(form);
+		for (AbstractElement element: elements) {
 			EvaluationFormReportHandler reportHandler = provider.getReportHandler(element);
 			if (reportHandler != null) {
 				EvaluationFormReportElement reportElement = reportHandler.getReportElement(ureq, getWindowControl(), element, filter,
diff --git a/src/main/java/org/olat/modules/quality/analysis/ui/GroupByController.java b/src/main/java/org/olat/modules/quality/analysis/ui/GroupByController.java
index d1ac6777551..da4747aaab6 100644
--- a/src/main/java/org/olat/modules/quality/analysis/ui/GroupByController.java
+++ b/src/main/java/org/olat/modules/quality/analysis/ui/GroupByController.java
@@ -66,6 +66,7 @@ import org.olat.core.gui.control.creator.ControllerCreator;
 import org.olat.core.util.StringHelper;
 import org.olat.modules.curriculum.model.CurriculumElementRefImpl;
 import org.olat.modules.curriculum.model.CurriculumRefImpl;
+import org.olat.modules.forms.EvaluationFormManager;
 import org.olat.modules.forms.RubricsComparison.Attribute;
 import org.olat.modules.forms.model.xml.AbstractElement;
 import org.olat.modules.forms.model.xml.Form;
@@ -162,6 +163,8 @@ public abstract class GroupByController extends FormBasicController implements F
 	private QualityAnalysisService analysisService;
 	@Autowired
 	private QualityService qualityService;
+	@Autowired
+	private EvaluationFormManager evaluationFormManager;
 	
 	public GroupByController(UserRequest ureq, WindowControl wControl, TooledStackedPanel stackPanel,
 			FilterController filterCtrl, Form evaluationForm, AvailableAttributes availableAttributes,
@@ -186,7 +189,8 @@ public abstract class GroupByController extends FormBasicController implements F
 	private List<SliderWrapper> initSliders(Form evaluationForm) {
 		int counter = 1;
 		List<SliderWrapper> sliderWrappers = new ArrayList<>();
-		for (AbstractElement element : evaluationForm.getElements()) {
+		List<AbstractElement> elements = evaluationFormManager.getUncontainerizedElements(evaluationForm);
+		for (AbstractElement element : elements) {
 			if (element instanceof Rubric) {
 				Rubric rubric = (Rubric) element;
 				for (Slider slider : rubric.getSliders()) {
-- 
GitLab