diff --git a/src/main/java/org/olat/modules/quality/analysis/AnalysisSearchParameter.java b/src/main/java/org/olat/modules/quality/analysis/AnalysisSearchParameter.java index 669803872d00fa265ba0b1c43c5b660900007327..5fa597491c290badcd86ee2584c8c2d7958fa67b 100644 --- a/src/main/java/org/olat/modules/quality/analysis/AnalysisSearchParameter.java +++ b/src/main/java/org/olat/modules/quality/analysis/AnalysisSearchParameter.java @@ -53,6 +53,7 @@ public class AnalysisSearchParameter { private Collection<? extends CurriculumRef> contextCurriculumRefs; private List<? extends CurriculumElementRef> contextCurriculumElementRefs; private List<? extends TaxonomyLevelRef> contextTaxonomyLevelRefs; + private Collection<Integer> seriesIndexes; private boolean withUserInfosOnly; public RepositoryEntryRef getFormEntryRef() { @@ -164,6 +165,14 @@ public class AnalysisSearchParameter { return withUserInfosOnly; } + public Collection<Integer> getSeriesIndexes() { + return seriesIndexes; + } + + public void setSeriesIndexes(Collection<Integer> seriesIndexes) { + this.seriesIndexes = seriesIndexes; + } + public void setWithUserInfosOnly(boolean withUserInfosOnly) { this.withUserInfosOnly = withUserInfosOnly; } @@ -204,6 +213,9 @@ public class AnalysisSearchParameter { clone.contextTaxonomyLevelRefs = this.contextTaxonomyLevelRefs != null ? new ArrayList<>(this.contextTaxonomyLevelRefs) : null; + clone.seriesIndexes = this.seriesIndexes != null + ? new ArrayList<>(this.seriesIndexes) + : null; clone.withUserInfosOnly = this.withUserInfosOnly; return clone; } diff --git a/src/main/java/org/olat/modules/quality/analysis/AvailableAttributes.java b/src/main/java/org/olat/modules/quality/analysis/AvailableAttributes.java index 9e49ae22c7f794d11ef8f84d5b18fa8d03854081..f898e4b4650b9a077a477149dea5eddb6ecbf572 100644 --- a/src/main/java/org/olat/modules/quality/analysis/AvailableAttributes.java +++ b/src/main/java/org/olat/modules/quality/analysis/AvailableAttributes.java @@ -37,11 +37,12 @@ public class AvailableAttributes { private final boolean contextCurriculum; private final boolean contextCurriculumElement; private final boolean contextTaxonomyLevel; + private final boolean seriesIndex; public AvailableAttributes(boolean topicIdentity, boolean topicRepository, boolean topicOrganisation, boolean topicCurriculum, boolean topicCurriculumElement, Boolean contextLocation, boolean contextOrganisation, boolean contextCurriculum, boolean contextCurriculumElement, - boolean contextTaxonomyLevel) { + boolean contextTaxonomyLevel, boolean seriesIndex) { this.topicIdentity = topicIdentity; this.topicRepository = topicRepository; this.topicOrganisation = topicOrganisation; @@ -52,6 +53,7 @@ public class AvailableAttributes { this.contextCurriculum = contextCurriculum; this.contextCurriculumElement = contextCurriculumElement; this.contextTaxonomyLevel = contextTaxonomyLevel; + this.seriesIndex = seriesIndex; } public boolean isTopicIdentity() { @@ -94,4 +96,8 @@ public class AvailableAttributes { return contextTaxonomyLevel; } + public boolean isSeriesIndex() { + return seriesIndex; + } + } diff --git a/src/main/java/org/olat/modules/quality/analysis/QualityAnalysisService.java b/src/main/java/org/olat/modules/quality/analysis/QualityAnalysisService.java index 7eecdd3eee00efe7c4ce00f673bdc20856bd2d2c..5fb4ee93628ccdd410a7b98894faa8765f1c84d7 100644 --- a/src/main/java/org/olat/modules/quality/analysis/QualityAnalysisService.java +++ b/src/main/java/org/olat/modules/quality/analysis/QualityAnalysisService.java @@ -76,6 +76,8 @@ public interface QualityAnalysisService { public List<CurriculumElement> loadContextCurriculumElements(AnalysisSearchParameter searchParams, boolean withParents); public List<TaxonomyLevel> loadContextTaxonomyLevels(AnalysisSearchParameter searchParams, boolean withParents); + + public Integer loadMaxSeriesIndex(AnalysisSearchParameter searchParams); public SessionFilter createSessionFilter(AnalysisSearchParameter searchParams); diff --git a/src/main/java/org/olat/modules/quality/analysis/manager/AnalysisFilterDAO.java b/src/main/java/org/olat/modules/quality/analysis/manager/AnalysisFilterDAO.java index bf8fd2da14d761cc867a12ddb587737c2c9f70bb..316ed3760b8b8be97035da37574ad651d2b941d1 100644 --- a/src/main/java/org/olat/modules/quality/analysis/manager/AnalysisFilterDAO.java +++ b/src/main/java/org/olat/modules/quality/analysis/manager/AnalysisFilterDAO.java @@ -73,6 +73,7 @@ public class AnalysisFilterDAO { sb.append(" , count(contextToCurriculum.curriculum.key) > 0"); sb.append(" , count(contextToCurriculumElement.curriculumElement.key) > 0"); sb.append(" , count(contextToTaxonomyLevel.taxonomyLevel.key) > 0"); + sb.append(" , CASE WHEN max(survey.seriesIndex) is not null THEN max(survey.seriesIndex) ELSE 0 END >= 2"); sb.append(" )"); appendFrom(sb, searchParams); appendWhere(sb, searchParams); @@ -255,6 +256,18 @@ public class AnalysisFilterDAO { return query.getResultList(); } + public Integer loadMaxSeriesIndex(AnalysisSearchParameter searchParams) { + QueryBuilder sb = new QueryBuilder(); + sb.append("select max(survey.seriesIndex)"); + appendFrom(sb, searchParams); + appendWhere(sb, searchParams); + + TypedQuery<Integer> query = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), Integer.class); + appendParameters(query, searchParams); + return query.getResultList().get(0); + } + List<Long> loadSessionKeys(AnalysisSearchParameter searchParams) { QueryBuilder sb = new QueryBuilder(); appendSelectSessionKeys(sb, searchParams); @@ -459,6 +472,9 @@ public class AnalysisFilterDAO { } } } + if (searchParams.getSeriesIndexes() != null && !searchParams.getSeriesIndexes().isEmpty()) { + sb.and().append("survey.seriesIndex in :seriesIndexes"); + } if (searchParams.isWithUserInfosOnly()) { sb.and(); sb.append("("); @@ -534,6 +550,9 @@ public class AnalysisFilterDAO { query.setParameter(parameter, value); } } + if (searchParams.getSeriesIndexes() != null && !searchParams.getSeriesIndexes().isEmpty()) { + query.setParameter("seriesIndexes", searchParams.getSeriesIndexes()); + } } } diff --git a/src/main/java/org/olat/modules/quality/analysis/manager/QualityAnalysisServiceImpl.java b/src/main/java/org/olat/modules/quality/analysis/manager/QualityAnalysisServiceImpl.java index cd3afb8e55cde721740faecc9ead3a9e513372e2..6b8304e9eb20a05a2636fe08b84bf199500891e0 100644 --- a/src/main/java/org/olat/modules/quality/analysis/manager/QualityAnalysisServiceImpl.java +++ b/src/main/java/org/olat/modules/quality/analysis/manager/QualityAnalysisServiceImpl.java @@ -229,6 +229,11 @@ public class QualityAnalysisServiceImpl implements QualityAnalysisService { return levels; } + @Override + public Integer loadMaxSeriesIndex(AnalysisSearchParameter searchParams) { + return filterDao.loadMaxSeriesIndex(searchParams); + } + private boolean isUnusedChild(String pathToCheck, List<String> pathes) { for (String path : pathes) { if (path.contains(pathToCheck)) { diff --git a/src/main/java/org/olat/modules/quality/analysis/ui/FilterController.java b/src/main/java/org/olat/modules/quality/analysis/ui/FilterController.java index f439de5a10db72e6a328e945af3e7e5ece876a33..c3d2c7fde6a78a0ff609613e0b83092f5f5e656c 100644 --- a/src/main/java/org/olat/modules/quality/analysis/ui/FilterController.java +++ b/src/main/java/org/olat/modules/quality/analysis/ui/FilterController.java @@ -73,12 +73,13 @@ import org.springframework.beans.factory.annotation.Autowired; /** * * Initial date: 04.09.2018<br> + * * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com * */ public class FilterController extends FormBasicController { - private static final String[] WITH_USER_INFOS_KEYS = new String[] {"filter.with.user.informations"}; + private static final String[] WITH_USER_INFOS_KEYS = new String[] { "filter.with.user.informations" }; private DateChooser dateRangeFromEl; private DateChooser dateRangeToEl; @@ -92,12 +93,13 @@ public class FilterController extends FormBasicController { private MultipleSelectionElement contextCurriculumElementEl; private MultipleSelectionElement contextTaxonomyLevelEl; private MultipleSelectionElement contextLocationEl; + private MultipleSelectionElement seriesIndexEl; private MultipleSelectionElement withUserInformationsEl; - + private final AnalysisSearchParameter searchParams; private final AvailableAttributes availableAttributes; private final boolean sessionInformationsAvailable; - + @Autowired private QualityAnalysisService analysisService; @Autowired @@ -126,24 +128,24 @@ public class FilterController extends FormBasicController { @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { formLayout.setElementCssClass("o_qual_ana_filter"); - + FormLayoutContainer dateRange = FormLayoutContainer.createHorizontalFormLayout("dateRange", getTranslator()); flc.add("dateRange", dateRange); dateRange.setElementCssClass("o_date_range"); dateRangeFromEl = uifactory.addDateChooser("filter.date.range.from", null, dateRange); dateRangeFromEl.setElementCssClass("o_date_range_from"); dateRangeFromEl.addActionListener(FormEvent.ONCHANGE); - + dateRangeToEl = uifactory.addDateChooser("filter.date.range.to", null, dateRange); dateRangeToEl.setElementCssClass("o_date_range_to"); dateRangeToEl.addActionListener(FormEvent.ONCHANGE); topicIdentityEl = uifactory.addCheckboxesDropdown("filter.topic.identities", formLayout); topicIdentityEl.addActionListener(FormEvent.ONCLICK); - + topicOrganisationEl = uifactory.addCheckboxesDropdown("filter.topic.organisations", formLayout); topicOrganisationEl.addActionListener(FormEvent.ONCLICK); - + topicCurriculumEl = uifactory.addCheckboxesDropdown("filter.topic.curriculums", formLayout); topicCurriculumEl.addActionListener(FormEvent.ONCLICK); @@ -152,10 +154,10 @@ public class FilterController extends FormBasicController { topicRepositoryEl = uifactory.addCheckboxesDropdown("filter.topic.repositories", formLayout); topicRepositoryEl.addActionListener(FormEvent.ONCLICK); - + contextOrganisationEl = uifactory.addCheckboxesDropdown("filter.context.organisations", formLayout); contextOrganisationEl.addActionListener(FormEvent.ONCLICK); - + contextCurriculumEl = uifactory.addCheckboxesDropdown("filter.context.curriculums", formLayout); contextCurriculumEl.addActionListener(FormEvent.ONCLICK); @@ -167,15 +169,18 @@ public class FilterController extends FormBasicController { contextLocationEl = uifactory.addCheckboxesDropdown("filter.context.location", formLayout); contextLocationEl.addActionListener(FormEvent.ONCLICK); - + + seriesIndexEl = uifactory.addCheckboxesDropdown("filter.series.index", formLayout); + seriesIndexEl.addActionListener(FormEvent.ONCLICK); + withUserInformationsEl = uifactory.addCheckboxesVertical("filter.with.user.informations.label", formLayout, WITH_USER_INFOS_KEYS, translateAll(getTranslator(), WITH_USER_INFOS_KEYS), 1); withUserInformationsEl.addActionListener(FormEvent.ONCLICK); withUserInformationsEl.setVisible(sessionInformationsAvailable); - + setSelectionValues(); } - + private void setSelectionValues() { setTopicIdentityValues(); setTopicOrganisationValues(); @@ -187,41 +192,42 @@ public class FilterController extends FormBasicController { setContextCurriculumElementValues(); setContextTaxonomyLevelValues(); setContextLocationValues(); + setSeriesIndexValues(); } - + private void setTopicIdentityValues() { if (!availableAttributes.isTopicIdentity()) { topicIdentityEl.setVisible(false); } - + Collection<String> selectedKeys = topicIdentityEl.getSelectedKeys(); - + AnalysisSearchParameter searchParamsClone = searchParams.clone(); searchParamsClone.setTopicIdentityRefs(null); List<IdentityShort> identities = analysisService.loadTopicIdentity(searchParamsClone); - + KeysValues keysValues = QualityUIFactory.getIdentityKeysValues(identities); topicIdentityEl.setKeysAndValues(keysValues.getKeys(), keysValues.getValues()); - for (String key: selectedKeys) { + for (String key : selectedKeys) { topicIdentityEl.select(key, true); } } - + private void setTopicOrganisationValues() { if (!availableAttributes.isTopicOrganisation() || !organisationModule.isEnabled()) { topicOrganisationEl.setVisible(false); return; } - + Collection<String> selectedKeys = topicOrganisationEl.getSelectedKeys(); - + AnalysisSearchParameter searchParamsClone = searchParams.clone(); searchParamsClone.setTopicOrganisationRefs(null); List<Organisation> organisations = analysisService.loadTopicOrganisations(searchParamsClone, true); - + KeysValues keysValues = QualityUIFactory.getOrganisationFlatKeysValues(organisations, null); topicOrganisationEl.setKeysAndValues(keysValues.getKeys(), keysValues.getValues()); - for (String key: selectedKeys) { + for (String key : selectedKeys) { topicOrganisationEl.select(key, true); } } @@ -231,15 +237,15 @@ public class FilterController extends FormBasicController { topicCurriculumEl.setVisible(false); return; } - + Collection<String> selectedKeys = topicCurriculumEl.getSelectedKeys(); - + AnalysisSearchParameter searchParamsClone = searchParams.clone(); searchParamsClone.setTopicCurriculumRefs(null); List<Curriculum> curriculums = analysisService.loadTopicCurriculums(searchParamsClone); KeysValues keysValues = QualityUIFactory.getCurriculumKeysValues(curriculums, null); topicCurriculumEl.setKeysAndValues(keysValues.getKeys(), keysValues.getValues()); - for (String key: selectedKeys) { + for (String key : selectedKeys) { topicCurriculumEl.select(key, true); } } @@ -249,46 +255,48 @@ public class FilterController extends FormBasicController { contextCurriculumElementEl.setVisible(false); return; } - + Collection<String> selectedKeys = topicCurriculumEl.getSelectedKeys(); AnalysisSearchParameter curriculumElementSearchParams = searchParams.clone(); curriculumElementSearchParams.setTopicCurriculumElementRefs(null); - List<CurriculumElement> curriculumElements = analysisService.loadTopicCurriculumElements(curriculumElementSearchParams); - + List<CurriculumElement> curriculumElements = analysisService + .loadTopicCurriculumElements(curriculumElementSearchParams); + KeysValues keysValues = QualityUIFactory.getCurriculumElementFlatKeysValues(curriculumElements, null); topicCurriculumElementEl.setKeysAndValues(keysValues.getKeys(), keysValues.getValues()); - for (String key: selectedKeys) { + for (String key : selectedKeys) { topicCurriculumElementEl.select(key, true); } } - + private void setTopicRepositoryValues() { if (!availableAttributes.isTopicRepository()) { topicRepositoryEl.setVisible(false); } - + Collection<String> selectedKeys = topicRepositoryEl.getSelectedKeys(); - + AnalysisSearchParameter searchParamsClone = searchParams.clone(); searchParamsClone.setTopicRepositoryRefs(null); List<RepositoryEntry> entries = analysisService.loadTopicRepositoryEntries(searchParamsClone); - + KeysValues keysValues = QualityUIFactory.getRepositoryEntriesFlatKeysValues(entries); topicRepositoryEl.setKeysAndValues(keysValues.getKeys(), keysValues.getValues()); - for (String key: selectedKeys) { + for (String key : selectedKeys) { topicRepositoryEl.select(key, true); } } private void setContextOrganisationValues() { - if (!availableAttributes.isContextOrganisation() || !organisationModule.isEnabled() || !curriculumModule.isEnabled()) { + if (!availableAttributes.isContextOrganisation() || !organisationModule.isEnabled() + || !curriculumModule.isEnabled()) { contextOrganisationEl.setVisible(false); return; } - + Collection<String> selectedKeys = contextOrganisationEl.getSelectedKeys(); - + AnalysisSearchParameter searchParamsClone = searchParams.clone(); searchParamsClone.setContextOrganisationRefs(null); searchParamsClone.setContextCurriculumRefs(null); @@ -296,10 +304,10 @@ public class FilterController extends FormBasicController { List<Organisation> organisations = analysisService.loadContextOrganisations(searchParamsClone, true); OrganisationTreeModel organisationModel = new OrganisationTreeModel(); organisationModel.loadTreeModel(organisations); - + KeysValues keysValues = QualityUIFactory.getOrganisationKeysValues(organisationModel, null); contextOrganisationEl.setKeysAndValues(keysValues.getKeys(), keysValues.getValues()); - for (String key: selectedKeys) { + for (String key : selectedKeys) { contextOrganisationEl.select(key, true); } } @@ -309,16 +317,16 @@ public class FilterController extends FormBasicController { contextCurriculumEl.setVisible(false); return; } - + Collection<String> selectedKeys = contextCurriculumEl.getSelectedKeys(); - + AnalysisSearchParameter curriculumSearchParams = searchParams.clone(); curriculumSearchParams.setContextCurriculumRefs(null); curriculumSearchParams.setContextCurriculumElementRefs(null); List<Curriculum> curriculums = analysisService.loadContextCurriculums(curriculumSearchParams); KeysValues keysValues = QualityUIFactory.getCurriculumKeysValues(curriculums, null); contextCurriculumEl.setKeysAndValues(keysValues.getKeys(), keysValues.getValues()); - for (String key: selectedKeys) { + for (String key : selectedKeys) { contextCurriculumEl.select(key, true); } } @@ -328,7 +336,7 @@ public class FilterController extends FormBasicController { contextCurriculumElementEl.setVisible(false); return; } - + Collection<String> selectedKeys = contextCurriculumEl.getSelectedKeys(); AnalysisSearchParameter curriculumElementSearchParams = searchParams.clone(); @@ -336,36 +344,37 @@ public class FilterController extends FormBasicController { ? contextCurriculumEl.getSelectedKeys() : contextCurriculumEl.getKeys(); List<? extends CurriculumRef> curriculumRefs = curriculumKeys.stream() - .map(key -> QualityUIFactory.getCurriculumRef(key)) - .collect(toList()); + .map(key -> QualityUIFactory.getCurriculumRef(key)).collect(toList()); curriculumElementSearchParams.setContextCurriculumRefs(curriculumRefs); curriculumElementSearchParams.setContextCurriculumElementRefs(null); - List<CurriculumElement> curriculumElements = analysisService.loadContextCurriculumElements(curriculumElementSearchParams, true); - + List<CurriculumElement> curriculumElements = analysisService + .loadContextCurriculumElements(curriculumElementSearchParams, true); + CurriculumTreeModel curriculumTreeModel = new CurriculumTreeModel(); curriculumTreeModel.loadTreeModel(curriculumElements); KeysValues keysValues = QualityUIFactory.getCurriculumElementKeysValues(curriculumTreeModel, null); contextCurriculumElementEl.setKeysAndValues(keysValues.getKeys(), keysValues.getValues()); - for (String key: selectedKeys) { + for (String key : selectedKeys) { contextCurriculumElementEl.select(key, true); } } - + private void setContextTaxonomyLevelValues() { if (!availableAttributes.isContextTaxonomyLevel()) { contextTaxonomyLevelEl.setVisible(false); return; } - + Collection<String> selectedKeys = contextOrganisationEl.getSelectedKeys(); - + AnalysisSearchParameter searchParamsClone = searchParams.clone(); searchParamsClone.setContextTaxonomyLevelRefs(null); List<TaxonomyLevel> levels = analysisService.loadContextTaxonomyLevels(searchParamsClone, true); - + KeyValues keyValues = new KeyValues(); - // Create the key / value pairs and sort them according to the hierarchical structure. - for (TaxonomyLevel level:levels) { + // Create the key / value pairs and sort them according to the hierarchical + // structure. + for (TaxonomyLevel level : levels) { String key = Long.toString(level.getKey()); ArrayList<String> names = new ArrayList<>(); QualityUIFactory.addParentTaxonomyLevelNames(names, level); @@ -374,42 +383,65 @@ public class FilterController extends FormBasicController { keyValues.add(entry(key, value)); } keyValues.sort(VALUE_ASC); - + // Replace with the intended value (but keep the sort order). - for (TaxonomyLevel level:levels) { + for (TaxonomyLevel level : levels) { String key = Long.toString(level.getKey()); String intendedLevel = QualityUIFactory.getIntendedTaxonomyLevel(level); keyValues.replaceOrPut(entry(key, intendedLevel)); } - + contextTaxonomyLevelEl.setKeysAndValues(keyValues.keys(), keyValues.values()); - for (String key: selectedKeys) { + for (String key : selectedKeys) { contextTaxonomyLevelEl.select(key, true); } } - + private void setContextLocationValues() { if (!availableAttributes.isContextLocation()) { contextLocationEl.setVisible(false); return; } - + Collection<String> selectedKeys = contextLocationEl.getSelectedKeys(); - + AnalysisSearchParameter locationSearchParams = searchParams.clone(); locationSearchParams.setContextLocations(null); List<String> locations = analysisService.loadContextLocations(locationSearchParams); locations.sort(String::compareToIgnoreCase); String[] locs = locations.stream().toArray(String[]::new); contextLocationEl.setKeysAndValues(locs, locs); - for (String key: selectedKeys) { + for (String key : selectedKeys) { contextLocationEl.select(key, true); } } - + + private void setSeriesIndexValues() { + if (!availableAttributes.isSeriesIndex()) { + seriesIndexEl.setVisible(false); + return; + } + + Collection<String> selectedKeys = seriesIndexEl.getSelectedKeys(); + + AnalysisSearchParameter clonedSearchParams = searchParams.clone(); + clonedSearchParams.setSeriesIndexes(null); + int maxSerieIndex = analysisService.loadMaxSeriesIndex(clonedSearchParams); + KeyValues keyValues = new KeyValues(); + for (int i = 1; i <= maxSerieIndex; i++) { + String key = String.valueOf(i); + String value = translate("filter.series.index.value", new String[] { key }); + keyValues.add(entry(key, value)); + } + seriesIndexEl.setKeysAndValues(keyValues.keys(), keyValues.values()); + for (String key : selectedKeys) { + seriesIndexEl.select(key, true); + } + } + @Override protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { - if (source == dateRangeFromEl) { + if (source == dateRangeFromEl) { doFiltered(ureq); } else if (source == dateRangeToEl) { doFiltered(ureq); @@ -433,6 +465,8 @@ public class FilterController extends FormBasicController { doFiltered(ureq); } else if (source == contextLocationEl) { doFiltered(ureq); + } else if (source == seriesIndexEl) { + doFiltered(ureq); } else if (source == withUserInformationsEl) { doFiltered(ureq); } @@ -458,6 +492,7 @@ public class FilterController extends FormBasicController { getSearchParamContextCurriculumElements(); getSearchParamContextTaxonomyLevels(); getSearchParamContextLocations(); + getSearchParamSeriesIndex(); getSearchParamWithUserInfosOnly(); } @@ -468,35 +503,36 @@ public class FilterController extends FormBasicController { private void getSearchParamDateRangeTo() { Date dateRangeTo = dateRangeToEl.getDate(); - - //Include the whole day - Calendar endOfDay = new GregorianCalendar(); - endOfDay.setTime(dateRangeTo); - endOfDay.set(Calendar.HOUR_OF_DAY, 0); - endOfDay.set(Calendar.MINUTE, 0); - endOfDay.set(Calendar.SECOND, 0); - endOfDay.set(Calendar.MILLISECOND, 0); - endOfDay.add(Calendar.DAY_OF_MONTH, 1); - - searchParams.setDateRangeTo(endOfDay.getTime()); + + if (dateRangeTo != null) { + // Include the whole day + Calendar endOfDay = new GregorianCalendar(); + endOfDay.setTime(dateRangeTo); + endOfDay.set(Calendar.HOUR_OF_DAY, 0); + endOfDay.set(Calendar.MINUTE, 0); + endOfDay.set(Calendar.SECOND, 0); + endOfDay.set(Calendar.MILLISECOND, 0); + endOfDay.add(Calendar.DAY_OF_MONTH, 1); + searchParams.setDateRangeTo(endOfDay.getTime()); + } else { + searchParams.setDateRangeTo(null); + } } private void getSearchParamTopicIdentitys() { if (topicIdentityEl.isVisible() && topicIdentityEl.isAtLeastSelected(1)) { List<IdentityRef> identityRefs = topicIdentityEl.getSelectedKeys().stream() - .map(key -> QualityUIFactory.getIdentityRef(key)) - .collect(toList()); + .map(key -> QualityUIFactory.getIdentityRef(key)).collect(toList()); searchParams.setTopicIdentityRefs(identityRefs); } else { searchParams.setTopicIdentityRefs(null); } } - + private void getSearchParamTopicOrganisations() { if (topicOrganisationEl.isVisible() && topicOrganisationEl.isAtLeastSelected(1)) { List<OrganisationRef> organisationRefs = topicOrganisationEl.getSelectedKeys().stream() - .map(key -> QualityUIFactory.getOrganisationRef(key)) - .collect(toList()); + .map(key -> QualityUIFactory.getOrganisationRef(key)).collect(toList()); searchParams.setTopicOrganisationRefs(organisationRefs); } else { searchParams.setTopicOrganisationRefs(null); @@ -506,30 +542,27 @@ public class FilterController extends FormBasicController { private void getSearchParamTopicCurriculums() { if (topicCurriculumEl.isVisible() && topicCurriculumEl.isAtLeastSelected(1)) { Collection<CurriculumRef> curriculumRefs = topicCurriculumEl.getSelectedKeys().stream() - .map(key -> QualityUIFactory.getCurriculumRef(key)) - .collect(toList()); + .map(key -> QualityUIFactory.getCurriculumRef(key)).collect(toList()); searchParams.setTopicCurriculumRefs(curriculumRefs); } else { searchParams.setTopicCurriculumRefs(null); } } - + private void getSearchParamTopicCurriculumElements() { if (topicCurriculumElementEl.isVisible() && topicCurriculumElementEl.isAtLeastSelected(1)) { List<CurriculumElementRef> curriculumElementRefs = topicCurriculumElementEl.getSelectedKeys().stream() - .map(key -> QualityUIFactory.getCurriculumElementRef(key)) - .collect(toList()); + .map(key -> QualityUIFactory.getCurriculumElementRef(key)).collect(toList()); searchParams.setTopicCurriculumElementRefs(curriculumElementRefs); } else { searchParams.setTopicCurriculumElementRefs(null); } } - + private void getSearchParamTopicRepositorys() { if (topicRepositoryEl.isVisible() && topicRepositoryEl.isAtLeastSelected(1)) { List<RepositoryEntryRef> entryRefs = topicRepositoryEl.getSelectedKeys().stream() - .map(key -> QualityUIFactory.getRepositoryEntryRef(key)) - .collect(toList()); + .map(key -> QualityUIFactory.getRepositoryEntryRef(key)).collect(toList()); searchParams.setTopicRepositoryRefs(entryRefs); } else { searchParams.setTopicRepositoryRefs(null); @@ -539,8 +572,7 @@ public class FilterController extends FormBasicController { private void getSearchParamContextOrganisations() { if (contextOrganisationEl.isVisible() && contextOrganisationEl.isAtLeastSelected(1)) { List<OrganisationRef> organisationRefs = contextOrganisationEl.getSelectedKeys().stream() - .map(key -> QualityUIFactory.getOrganisationRef(key)) - .collect(toList()); + .map(key -> QualityUIFactory.getOrganisationRef(key)).collect(toList()); searchParams.setContextOrganisationRefs(organisationRefs); } else { searchParams.setContextOrganisationRefs(null); @@ -550,8 +582,7 @@ public class FilterController extends FormBasicController { private void getSearchParamContextCurriculums() { if (contextCurriculumEl.isVisible() && contextCurriculumEl.isAtLeastSelected(1)) { Collection<CurriculumRef> curriculumRefs = contextCurriculumEl.getSelectedKeys().stream() - .map(key -> QualityUIFactory.getCurriculumRef(key)) - .collect(toList()); + .map(key -> QualityUIFactory.getCurriculumRef(key)).collect(toList()); searchParams.setContextCurriculumRefs(curriculumRefs); } else { searchParams.setContextCurriculumRefs(null); @@ -561,20 +592,17 @@ public class FilterController extends FormBasicController { private void getSearchParamContextCurriculumElements() { if (contextCurriculumElementEl.isVisible() && contextCurriculumElementEl.isAtLeastSelected(1)) { List<CurriculumElementRef> curriculumElementRefs = contextCurriculumElementEl.getSelectedKeys().stream() - .map(key -> QualityUIFactory.getCurriculumElementRef(key)) - .collect(toList()); + .map(key -> QualityUIFactory.getCurriculumElementRef(key)).collect(toList()); searchParams.setContextCurriculumElementRefs(curriculumElementRefs); } else { searchParams.setContextCurriculumElementRefs(null); } } - + private void getSearchParamContextTaxonomyLevels() { if (contextTaxonomyLevelEl.isVisible() && contextTaxonomyLevelEl.isAtLeastSelected(1)) { List<TaxonomyLevelRef> curriculumElementRefs = contextTaxonomyLevelEl.getSelectedKeys().stream() - .map(Long::parseLong) - .map(TaxonomyLevelRefImpl::new) - .collect(toList()); + .map(Long::parseLong).map(TaxonomyLevelRefImpl::new).collect(toList()); searchParams.setContextTaxonomyLevelRefs(curriculumElementRefs); } else { searchParams.setContextTaxonomyLevelRefs(null); @@ -589,7 +617,17 @@ public class FilterController extends FormBasicController { searchParams.setContextLocations(null); } } - + + private void getSearchParamSeriesIndex() { + if (seriesIndexEl.isVisible() && seriesIndexEl.isAtLeastSelected(1)) { + Collection<Integer> seriesIndexes = seriesIndexEl.getSelectedKeys().stream().map(Integer::valueOf) + .collect(toList()); + searchParams.setSeriesIndexes(seriesIndexes); + } else { + searchParams.setSeriesIndexes(null); + } + } + private void getSearchParamWithUserInfosOnly() { boolean withUserInfosOnly = withUserInformationsEl.isVisible() && withUserInformationsEl.isAtLeastSelected(1); searchParams.setWithUserInfosOnly(withUserInfosOnly); diff --git a/src/main/java/org/olat/modules/quality/analysis/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/quality/analysis/ui/_i18n/LocalStrings_de.properties index 1ac8f630b3a57e88127af54b2fc72bc0601794a2..393eab5fe1e2a621a4a89a3a519960746d178b3d 100644 --- a/src/main/java/org/olat/modules/quality/analysis/ui/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/modules/quality/analysis/ui/_i18n/LocalStrings_de.properties @@ -17,6 +17,8 @@ filter.date.range.from=Datenerhebungen von filter.date.range.to=Datenerhebungen to filter.hide=Filter filter.panel.header=Filter +filter.series.index=Serie +filter.series.index.value=Datenerhebung {0} filter.show=Filter filter.topic.curriculum.elements=Beurteilungsgegenstand Curriculumelement filter.topic.curriculums=Beurteilungsgegenstand Curriculum diff --git a/src/main/java/org/olat/modules/quality/analysis/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/modules/quality/analysis/ui/_i18n/LocalStrings_en.properties index 1dbe830fd23cbf6c060161b0b5ce289fa39d62f1..e97216c17af1cebe2747ee489585ebfe5d6c7f92 100644 --- a/src/main/java/org/olat/modules/quality/analysis/ui/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/modules/quality/analysis/ui/_i18n/LocalStrings_en.properties @@ -17,6 +17,8 @@ filter.date.range.from=Data collections from filter.date.range.to=Data collections to filter.hide=Filters filter.panel.header=Filters +filter.series.index=Series +filter.series.index.value=Data collection {0} filter.show=Filters filter.topic.curriculum.elements=Topic curriculum element filter.topic.curriculums=Topic curriculum diff --git a/src/test/java/org/olat/modules/quality/analysis/manager/AnalysisFilterDAOTest.java b/src/test/java/org/olat/modules/quality/analysis/manager/AnalysisFilterDAOTest.java index 1d2905e9f82b71fe40fae81167473f1365b28cc1..2ebb588ceb4ab32ec803ad6996204c12f5e23c14 100644 --- a/src/test/java/org/olat/modules/quality/analysis/manager/AnalysisFilterDAOTest.java +++ b/src/test/java/org/olat/modules/quality/analysis/manager/AnalysisFilterDAOTest.java @@ -208,6 +208,7 @@ public class AnalysisFilterDAOTest extends OlatTestCase { assertThat(attributes.isContextCurriculum()).isFalse(); assertThat(attributes.isContextCurriculumElement()).isFalse(); assertThat(attributes.isContextTaxonomyLevel()).isFalse(); + assertThat(attributes.isSeriesIndex()).isFalse(); } @Test @@ -369,6 +370,21 @@ public class AnalysisFilterDAOTest extends OlatTestCase { assertThat(attributes.isContextTaxonomyLevel()).isTrue(); } + + @Test + public void shouldGetAvailableAttributeForSeriesIndex() { + RepositoryEntry formEntry = JunitTestHelper.createAndPersistRepositoryEntry(); + Organisation dcOrganisation = qualityTestHelper.createOrganisation(); + QualityDataCollection dc1 = qualityService.createDataCollection(asList(dcOrganisation), formEntry); + QualityDataCollection dc2 = qualityService.createDataCollection(asList(dcOrganisation), dc1, null, null); + finish(asList(dc1, dc2)); + dbInstance.commitAndCloseSession(); + + AnalysisSearchParameter searchParams = new AnalysisSearchParameter(); + AvailableAttributes attributes = sut.getAvailableAttributes(searchParams); + + assertThat(attributes.isSeriesIndex()).isTrue(); + } private QualityDataCollection createFinishedDataCollection() { RepositoryEntry formEntry = JunitTestHelper.createAndPersistRepositoryEntry(); @@ -715,6 +731,25 @@ public class AnalysisFilterDAOTest extends OlatTestCase { .doesNotContainNull(); } + @Test + public void shouldLoadMaxSerieIndex() { + RepositoryEntry formEntry = JunitTestHelper.createAndPersistRepositoryEntry(); + Organisation dcOrganisation = organisationService.createOrganisation("", "", null, null, null); + QualityDataCollection dc1 = qualityService.createDataCollection(asList(dcOrganisation), formEntry); + QualityDataCollection dc2 = qualityService.createDataCollection(asList(dcOrganisation), dc1, null, null); + QualityDataCollection dc3 = qualityService.createDataCollection(asList(dcOrganisation), dc2, null, null); + QualityDataCollection dc4 = qualityService.createDataCollection(asList(dcOrganisation), formEntry); + QualityDataCollection dc5 = qualityService.createDataCollection(asList(dcOrganisation), dc4, null, null); + QualityDataCollection dc6 = qualityService.createDataCollection(asList(dcOrganisation), formEntry); + finish(asList(dc1, dc2, dc3, dc4, dc5, dc6)); + dbInstance.commitAndCloseSession(); + + AnalysisSearchParameter searchParams = new AnalysisSearchParameter(); + Integer maxLevels = sut.loadMaxSeriesIndex(searchParams); + + assertThat(maxLevels).isEqualTo(3); + } + @Test public void shouldLoadGroupedStatistics() { RepositoryEntry formEntry = JunitTestHelper.createAndPersistRepositoryEntry(); @@ -819,7 +854,6 @@ public class AnalysisFilterDAOTest extends OlatTestCase { } } } - @Test public void shouldLoadGroupedStatisticForEveryGroupBy() { @@ -1348,7 +1382,27 @@ public class AnalysisFilterDAOTest extends OlatTestCase { long expectedUnfiltered = asList(executor1, executor2, executorOther).size(); assertThat(countUnfiltered).isEqualTo(expectedUnfiltered); } - + + @Test + public void shouldFilterBySerieNumber() { + RepositoryEntry formEntry = JunitTestHelper.createAndPersistRepositoryEntry(); + Organisation dcOrganisation = organisationService.createOrganisation("", "", null, null, null); + QualityDataCollection dc1 = qualityService.createDataCollection(asList(dcOrganisation), formEntry); + QualityDataCollection dc2 = qualityService.createDataCollection(asList(dcOrganisation), dc1, null, null); + QualityDataCollection dc3 = qualityService.createDataCollection(asList(dcOrganisation), dc2, null, null); + QualityDataCollection dc4 = qualityService.createDataCollection(asList(dcOrganisation), formEntry); + QualityDataCollection dc5 = qualityService.createDataCollection(asList(dcOrganisation), dc4, null, null); + QualityDataCollection dc6 = qualityService.createDataCollection(asList(dcOrganisation), formEntry); + finish(asList(dc1, dc2, dc3, dc4, dc5, dc6)); + dbInstance.commitAndCloseSession(); + + AnalysisSearchParameter searchParams = new AnalysisSearchParameter(); + searchParams.setSeriesIndexes(asList(1, 3)); + Long count = sut.loadAnalyticFigures(searchParams).getDataCollectionCount(); + + long expected = asList(dc1, dc3, dc4, dc6).size(); + assertThat(count).isEqualTo(expected); + } private void finish(Collection<QualityDataCollection> dataCollections) { for (QualityDataCollection dataCollection: dataCollections) {