From c03e2cb1f84b72424cb029edbf7a65b8d133db04 Mon Sep 17 00:00:00 2001 From: srosse <none@none> Date: Mon, 19 Jun 2017 14:22:03 +0200 Subject: [PATCH] OO-2636: add absence informations in the list of course of a specific user --- .../model/IdentityRepositoryEntryKey.java | 69 +++++++++++++++++++ ...fficiencyStatementEntryTableDataModel.java | 60 +++++++++++++--- .../coach/ui/StudentCoursesController.java | 27 +++++++- .../coach/ui/_i18n/LocalStrings_de.properties | 4 ++ .../coach/ui/_i18n/LocalStrings_en.properties | 4 ++ 5 files changed, 152 insertions(+), 12 deletions(-) create mode 100644 src/main/java/org/olat/modules/coach/model/IdentityRepositoryEntryKey.java diff --git a/src/main/java/org/olat/modules/coach/model/IdentityRepositoryEntryKey.java b/src/main/java/org/olat/modules/coach/model/IdentityRepositoryEntryKey.java new file mode 100644 index 00000000000..2504fcdd934 --- /dev/null +++ b/src/main/java/org/olat/modules/coach/model/IdentityRepositoryEntryKey.java @@ -0,0 +1,69 @@ +/** + * <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.coach.model; + +/** + * + * Initial date: 19 juin 2017<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class IdentityRepositoryEntryKey { + + private final Long identityKey; + private final Long repositoryEntryKey; + + public IdentityRepositoryEntryKey(Long identityKey, Long repositoryEntryKey) { + this.identityKey = identityKey; + this.repositoryEntryKey = repositoryEntryKey; + } + + public IdentityRepositoryEntryKey(EfficiencyStatementEntry entry) { + identityKey = entry.getIdentityKey(); + repositoryEntryKey = entry.getCourse().getKey(); + } + + public Long getIdentityKey() { + return identityKey; + } + + public Long getRepositoryEntryKey() { + return repositoryEntryKey; + } + + @Override + public int hashCode() { + return (identityKey == null ? 98268 : identityKey.hashCode()) + + (repositoryEntryKey == null ? -2634785 : repositoryEntryKey.hashCode()); + } + + @Override + public boolean equals(Object obj) { + if(this == obj) { + return true; + } + if(obj instanceof IdentityRepositoryEntryKey) { + IdentityRepositoryEntryKey key = (IdentityRepositoryEntryKey)obj; + return identityKey != null && identityKey.equals(key.getIdentityKey()) + && repositoryEntryKey != null && repositoryEntryKey.equals(key.getRepositoryEntryKey()); + } + return false; + } +} \ No newline at end of file diff --git a/src/main/java/org/olat/modules/coach/ui/EfficiencyStatementEntryTableDataModel.java b/src/main/java/org/olat/modules/coach/ui/EfficiencyStatementEntryTableDataModel.java index 0f3575c069a..d1ca2387fbd 100644 --- a/src/main/java/org/olat/modules/coach/ui/EfficiencyStatementEntryTableDataModel.java +++ b/src/main/java/org/olat/modules/coach/ui/EfficiencyStatementEntryTableDataModel.java @@ -31,7 +31,9 @@ import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFl import org.olat.course.assessment.UserEfficiencyStatement; import org.olat.course.certificate.CertificateLight; import org.olat.modules.coach.model.EfficiencyStatementEntry; +import org.olat.modules.coach.model.IdentityRepositoryEntryKey; import org.olat.modules.coach.model.IdentityResourceKey; +import org.olat.modules.lecture.model.LectureBlockStatistics; import org.olat.repository.RepositoryEntry; /** @@ -46,6 +48,7 @@ import org.olat.repository.RepositoryEntry; public class EfficiencyStatementEntryTableDataModel extends DefaultFlexiTableDataModel<EfficiencyStatementEntry> implements SortableFlexiTableDataModel<EfficiencyStatementEntry> { private ConcurrentMap<IdentityResourceKey, CertificateLight> certificateMap; + private ConcurrentMap<IdentityRepositoryEntryKey, LectureBlockStatistics> lecturesStatisticsMap; public EfficiencyStatementEntryTableDataModel(FlexiTableColumnModel columnModel) { super(columnModel); @@ -91,19 +94,11 @@ public class EfficiencyStatementEntryTableDataModel extends DefaultFlexiTableDat return s == null ? null : s.getPassed(); } case certificate: { - CertificateLight certificate = null; - if(certificateMap != null) { - IdentityResourceKey key = new IdentityResourceKey(entry.getIdentityKey(), entry.getCourse().getOlatResource().getKey()); - certificate = certificateMap.get(key); - } + CertificateLight certificate = getCertificate(entry); return certificate; } case recertification: { - CertificateLight certificate = null; - if(certificateMap != null) { - IdentityResourceKey key = new IdentityResourceKey(entry.getIdentityKey(), entry.getCourse().getOlatResource().getKey()); - certificate = certificateMap.get(key); - } + CertificateLight certificate = getCertificate(entry); return certificate == null ? null : certificate.getNextRecertificationDate(); } case progress: { @@ -124,16 +119,55 @@ public class EfficiencyStatementEntryTableDataModel extends DefaultFlexiTableDat UserEfficiencyStatement s = entry.getUserEfficencyStatement(); return s == null ? null : s.getLastModified(); } + case plannedLectures: { + LectureBlockStatistics statistics = getLectureBlockStatistics(entry); + return statistics == null ? null : statistics.getTotalPlannedLectures(); + } + case attendedLectures: { + LectureBlockStatistics statistics = getLectureBlockStatistics(entry); + return statistics == null ? null : statistics.getTotalAttendedLectures(); + } + case absentLectures: { + LectureBlockStatistics statistics = getLectureBlockStatistics(entry); + return statistics == null ? null : statistics.getTotalAbsentLectures(); + } + case authorizedAbsenceLectures: { + LectureBlockStatistics statistics = getLectureBlockStatistics(entry); + return statistics == null ? null : statistics.getTotalAuthorizedAbsentLectures(); + } } } int propPos = col - UserListController.USER_PROPS_OFFSET; return entry.getIdentityProp(propPos); } + + private CertificateLight getCertificate(EfficiencyStatementEntry entry) { + if(certificateMap != null) { + IdentityResourceKey key = new IdentityResourceKey(entry.getIdentityKey(), entry.getCourse().getOlatResource().getKey()); + return certificateMap.get(key); + } + return null; + } + + private LectureBlockStatistics getLectureBlockStatistics(EfficiencyStatementEntry entry) { + if(lecturesStatisticsMap != null) { + IdentityRepositoryEntryKey key = new IdentityRepositoryEntryKey(entry); + return lecturesStatisticsMap.get(key); + } + return null; + } public void setObjects(List<EfficiencyStatementEntry> objects, ConcurrentMap<IdentityResourceKey, CertificateLight> certificates) { + setObjects(objects, certificates, null); + } + + public void setObjects(List<EfficiencyStatementEntry> objects, + ConcurrentMap<IdentityResourceKey, CertificateLight> certificates, + ConcurrentMap<IdentityRepositoryEntryKey, LectureBlockStatistics> lecturesStatisticsMap) { setObjects(objects); this.certificateMap = certificates; + this.lecturesStatisticsMap = lecturesStatisticsMap; } @Override @@ -149,7 +183,11 @@ public class EfficiencyStatementEntryTableDataModel extends DefaultFlexiTableDat certificate("table.header.certificate"), recertification("table.header.recertification"), progress("table.header.progress"), - lastModification("table.header.lastScoreDate"); + lastModification("table.header.lastScoreDate"), + plannedLectures("table.header.planned.lectures"), + attendedLectures("table.header.attended.lectures"), + absentLectures("table.header.absent.lectures"), + authorizedAbsenceLectures("table.header.authorized.absence"); private final String i18nKey; diff --git a/src/main/java/org/olat/modules/coach/ui/StudentCoursesController.java b/src/main/java/org/olat/modules/coach/ui/StudentCoursesController.java index 4b177fdb8a1..1803bf62ab2 100644 --- a/src/main/java/org/olat/modules/coach/ui/StudentCoursesController.java +++ b/src/main/java/org/olat/modules/coach/ui/StudentCoursesController.java @@ -70,10 +70,14 @@ import org.olat.modules.assessment.ui.ScoreCellRenderer; import org.olat.modules.co.ContactFormController; import org.olat.modules.coach.CoachingService; import org.olat.modules.coach.model.EfficiencyStatementEntry; +import org.olat.modules.coach.model.IdentityRepositoryEntryKey; import org.olat.modules.coach.model.IdentityResourceKey; import org.olat.modules.coach.model.StudentStatEntry; import org.olat.modules.coach.ui.EfficiencyStatementEntryTableDataModel.Columns; import org.olat.modules.coach.ui.UserDetailsController.Segment; +import org.olat.modules.lecture.LectureModule; +import org.olat.modules.lecture.LectureService; +import org.olat.modules.lecture.model.LectureBlockStatistics; import org.olat.repository.RepositoryEntry; import org.olat.user.UserManager; import org.olat.user.propertyhandlers.UserPropertyHandler; @@ -116,6 +120,10 @@ public class StudentCoursesController extends FormBasicController implements Act @Autowired private UserManager userManager; @Autowired + private LectureModule lectureModule; + @Autowired + private LectureService lectureService; + @Autowired private CoachingService coachingService; @Autowired private BaseSecurityModule securityModule; @@ -200,6 +208,14 @@ public class StudentCoursesController extends FormBasicController implements Act columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Columns.certificate, new DownloadCertificateCellRenderer())); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Columns.recertification, new DateFlexiCellRenderer(getLocale()))); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Columns.progress, new ProgressRenderer(true, getTranslator()))); + if(lectureModule.isEnabled()) { + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Columns.plannedLectures)); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Columns.attendedLectures)); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Columns.absentLectures)); + if(lectureModule.isAuthorizedAbsenceEnabled()) { + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Columns.authorizedAbsenceLectures)); + } + } columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Columns.lastModification)); model = new EfficiencyStatementEntryTableDataModel(columnsModel); @@ -247,7 +263,16 @@ public class StudentCoursesController extends FormBasicController implements Act certificateMap.put(key, certificate); } - model.setObjects(statements, certificateMap); + ConcurrentMap<IdentityRepositoryEntryKey, LectureBlockStatistics> lecturesMap = new ConcurrentHashMap<>(); + if(lectureModule.isEnabled()) { + List<LectureBlockStatistics> lectureStats = lectureService.getParticipantLecturesStatistics(student); + for(LectureBlockStatistics lectureStat:lectureStats) { + IdentityRepositoryEntryKey key = new IdentityRepositoryEntryKey(student.getKey(), lectureStat.getRepoKey()); + lecturesMap.put(key, lectureStat); + } + } + + model.setObjects(statements, certificateMap, lecturesMap); tableEl.reset(); tableEl.reloadData(); return statements; diff --git a/src/main/java/org/olat/modules/coach/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/coach/ui/_i18n/LocalStrings_de.properties index 7bbe6356bec..87310e56f26 100644 --- a/src/main/java/org/olat/modules/coach/ui/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/modules/coach/ui/_i18n/LocalStrings_de.properties @@ -60,4 +60,8 @@ table.header.progress=Fortschritt table.header.recertification=Rezertifizierung table.header.score=$org.olat.course.assessment\:table.header.score table.header.show=$org.olat.course.assessment\:table.header.show +table.header.planned.lectures=$org.olat.modules.lecture.ui\:table.header.planned.lectures +table.header.attended.lectures=$org.olat.modules.lecture.ui\:table.header.attended.lectures +table.header.absent.lectures=$org.olat.modules.lecture.ui\:table.header.absent.lectures +table.header.authorized.absence=$org.olat.modules.lecture.ui\:table.header.authorized.absence tooltip.of={0} von {1} \ No newline at end of file diff --git a/src/main/java/org/olat/modules/coach/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/modules/coach/ui/_i18n/LocalStrings_en.properties index 992686f67f5..4d6a0bd8bca 100644 --- a/src/main/java/org/olat/modules/coach/ui/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/modules/coach/ui/_i18n/LocalStrings_en.properties @@ -60,4 +60,8 @@ table.header.progress=Progress table.header.recertification=Recertification table.header.score=$org.olat.course.assessment\:table.header.score table.header.show=$org.olat.course.assessment\:table.header.show +table.header.planned.lectures=$org.olat.modules.lecture.ui\:table.header.planned.lectures +table.header.attended.lectures=$org.olat.modules.lecture.ui\:table.header.attended.lectures +table.header.absent.lectures=$org.olat.modules.lecture.ui\:table.header.absent.lectures +table.header.authorized.absence=$org.olat.modules.lecture.ui\:table.header.authorized.absence tooltip.of={0} of {1} -- GitLab