From 65b761ff6b96c4b610c2a94cdde61512fd0f6552 Mon Sep 17 00:00:00 2001 From: srosse <stephane.rosse@frentix.com> Date: Mon, 19 Aug 2019 16:42:47 +0200 Subject: [PATCH] OO-4150: add some specific participant/teacher... path to notice --- .../olat/modules/lecture/LectureModule.java | 7 +- .../lecture/manager/LectureBlockDAO.java | 25 +++- .../model/LecturesBlockSearchParameters.java | 13 +- .../lecture/ui/LecturesSecurityCallback.java | 2 + .../ui/LecturesSecurityCallbackFactory.java | 28 +++- .../ui/_i18n/LocalStrings_de.properties | 31 ++-- .../ui/_i18n/LocalStrings_en.properties | 26 ++-- ...resPermissionsSettingsAdminController.java | 2 +- .../coach/AbsenceNoticesListController.java | 6 +- .../lecture/ui/coach/AbsencesController.java | 2 +- .../ui/coach/DailyAbsencesController.java | 4 + .../ui/coach/DispensationsController.java | 8 +- .../EditDatesLecturesEntriesController.java | 19 ++- .../ui/coach/EditNoticeController.java | 7 +- .../ui/coach/EditReasonController.java | 22 ++- .../IdentitiesLecturesRollCallController.java | 2 +- .../ui/coach/LecturesCoachingController.java | 16 ++- .../DailyOverviewProfilController.java | 5 + .../ui/profile/IdentityProfileController.java | 135 +++++++++++++++++- .../wizard/AbsenceNotice1UserSearchStep.java | 5 +- .../wizard/AbsenceNotice2ConfirmUserStep.java | 5 +- .../AbsenceNotice3LecturesEntriesStep.java | 14 +- .../ui/wizard/AbsenceNotice4ReasonStep.java | 8 +- .../DatesLecturesEntriesStepController.java | 10 +- .../ui/wizard/ReasonStepController.java | 6 +- .../lecture/manager/LectureBlockDAOTest.java | 2 + 26 files changed, 330 insertions(+), 80 deletions(-) diff --git a/src/main/java/org/olat/modules/lecture/LectureModule.java b/src/main/java/org/olat/modules/lecture/LectureModule.java index 4fff4e47b74..2be255f7a2d 100644 --- a/src/main/java/org/olat/modules/lecture/LectureModule.java +++ b/src/main/java/org/olat/modules/lecture/LectureModule.java @@ -1,4 +1,5 @@ /** + * <a href="http://www.openolat.org"> * OpenOLAT - Online Learning and Training</a><br> * <p> @@ -63,7 +64,7 @@ public class LectureModule extends AbstractSpringModule implements ConfigOnOff { private static final String MASTERCOACH_CAN_SEE_APPEAL = "mastercoach.can.see.appeal"; private static final String MASTERCOACH_CAN_AUTHORIZED_APPEAL = "mastercoach.can.authorized.appeal"; - private static final String PARTICIPANT_CAN_NOTICE = "mastercoach.can.notice"; + private static final String PARTICIPANT_CAN_NOTICE = "participant.can.notice"; private static final String DAILY_ROLL_CALL = "daily.rollcall"; @@ -233,7 +234,7 @@ public class LectureModule extends AbstractSpringModule implements ConfigOnOff { teacherCanAuthorizedAbsence = "true".equals(teacherCanAuthorizedAbsenceObj); } - String teacherCanSeeAppealObj = getStringPropertyValue(TEACHER_CAN_AUTHORIZED_ABSENCE, true); + String teacherCanSeeAppealObj = getStringPropertyValue(TEACHER_CAN_SEE_APPEAL, true); if(StringHelper.containsNonWhitespace(teacherCanSeeAppealObj)) { teacherCanSeeAppeal = "true".equals(teacherCanSeeAppealObj); } @@ -268,7 +269,7 @@ public class LectureModule extends AbstractSpringModule implements ConfigOnOff { masterCoachCanAuthorizedAppeal = "true".equals(masterCoachCanAuthorizedAppealObj); } - String participantCanNoticeObj = getStringPropertyValue(MASTERCOACH_CAN_AUTHORIZED_APPEAL, true); + String participantCanNoticeObj = getStringPropertyValue(PARTICIPANT_CAN_NOTICE, true); if(StringHelper.containsNonWhitespace(participantCanNoticeObj)) { participantCanNotice = "true".equals(participantCanNoticeObj); } diff --git a/src/main/java/org/olat/modules/lecture/manager/LectureBlockDAO.java b/src/main/java/org/olat/modules/lecture/manager/LectureBlockDAO.java index 55e128dfa8b..adbdae48485 100644 --- a/src/main/java/org/olat/modules/lecture/manager/LectureBlockDAO.java +++ b/src/main/java/org/olat/modules/lecture/manager/LectureBlockDAO.java @@ -554,11 +554,24 @@ public class LectureBlockDAO { if(searchParams.getManager() != null) { sb.and() .append(" exists (select membership.key from repoentrytogroup as rel, bgroupmember as membership") - .append(" where rel.entry.key=entry.key and rel.group.key=membership.group.key and membership.identity.key=:managerKey") - .append(" and membership.role in ('").append(OrganisationRoles.administrator.name()).append("','").append(OrganisationRoles.learnresourcemanager.name()).append("','").append(OrganisationRoles.lecturemanager.name()).append("','").append(GroupRoles.owner.name()).append("')") + .append(" where rel.entry.key=entry.key and rel.group.key=membership.group.key and membership.identity.key=:managerKey") + .append(" and membership.role ").in(OrganisationRoles.administrator, OrganisationRoles.learnresourcemanager, OrganisationRoles.lecturemanager, GroupRoles.owner.name()) + .append(" )"); + } + if(searchParams.getMasterCoach() != null) { + sb.and() + .append(" exists (select mcMembership.key from lectureblocktogroup as blockToCoachGroup, bgroupmember as mcMembership") + .append(" where block.key=blockToCoachGroup.lectureBlock.key and blockToCoachGroup.group.key=mcMembership.group.key and mcMembership.identity.key=:masterCoachKey") + .append(" and mcMembership.role ").in(CurriculumRoles.mastercoach) + .append(" )"); + } + if(searchParams.getParticipant() != null) { + sb.and() + .append(" exists (select participantship.key from lectureblocktogroup as blockToParticipantGroup, bgroupmember as participantship") + .append(" where block.key=blockToParticipantGroup.lectureBlock.key and blockToParticipantGroup.group.key=participantship.group.key and participantship.identity.key=:participantKey") + .append(" and participantship.role ").in(GroupRoles.participant) .append(" )"); } - if(searchParams.getTeacher() != null) { sb.and() .append(" exists (select teachership.key from bgroupmember teachership where") @@ -607,9 +620,15 @@ public class LectureBlockDAO { if(searchParams.getManager() != null) { query.setParameter("managerKey", searchParams.getManager().getKey()); } + if(searchParams.getMasterCoach() != null) { + query.setParameter("masterCoachKey", searchParams.getMasterCoach().getKey()); + } if(searchParams.getTeacher() != null) { query.setParameter("teacherKey", searchParams.getTeacher().getKey()); } + if(searchParams.getParticipant() != null) { + query.setParameter("participantKey", searchParams.getParticipant().getKey()); + } } public LectureBlock addGroupToLectureBlock(LectureBlock block, Group group) { diff --git a/src/main/java/org/olat/modules/lecture/model/LecturesBlockSearchParameters.java b/src/main/java/org/olat/modules/lecture/model/LecturesBlockSearchParameters.java index c3c581e9598..28bc6cea45c 100644 --- a/src/main/java/org/olat/modules/lecture/model/LecturesBlockSearchParameters.java +++ b/src/main/java/org/olat/modules/lecture/model/LecturesBlockSearchParameters.java @@ -44,6 +44,7 @@ public class LecturesBlockSearchParameters { private IdentityRef teacher; private IdentityRef manager; private IdentityRef participant; + private IdentityRef masterCoach; private RepositoryEntry entry; private List<LectureRollCallStatus> rollCallStatus; private List<LectureBlockStatus> lectureBlockStatus; @@ -124,6 +125,14 @@ public class LecturesBlockSearchParameters { this.manager = manager; } + public IdentityRef getMasterCoach() { + return masterCoach; + } + + public void setMasterCoach(IdentityRef masterCoach) { + this.masterCoach = masterCoach; + } + public IdentityRef getTeacher() { return teacher; } @@ -142,8 +151,8 @@ public class LecturesBlockSearchParameters { public void setViewAs(IdentityRef identity, LectureRoles role) { switch(role) { - case lecturemanager: - case mastercoach: setManager(identity); break; + case lecturemanager: setManager(identity); break; + case mastercoach: setMasterCoach(identity); break; case teacher: setTeacher(identity); break; case participant: default: setParticipant(identity); diff --git a/src/main/java/org/olat/modules/lecture/ui/LecturesSecurityCallback.java b/src/main/java/org/olat/modules/lecture/ui/LecturesSecurityCallback.java index f8777688c4a..12a810ea7a0 100644 --- a/src/main/java/org/olat/modules/lecture/ui/LecturesSecurityCallback.java +++ b/src/main/java/org/olat/modules/lecture/ui/LecturesSecurityCallback.java @@ -33,6 +33,8 @@ public interface LecturesSecurityCallback { public boolean canChangeRates(); + public boolean canSeeAppeals(); + public boolean canApproveAppeal(); public boolean canEditConfiguration(); diff --git a/src/main/java/org/olat/modules/lecture/ui/LecturesSecurityCallbackFactory.java b/src/main/java/org/olat/modules/lecture/ui/LecturesSecurityCallbackFactory.java index a1c6a810daa..1741b3ba26d 100644 --- a/src/main/java/org/olat/modules/lecture/ui/LecturesSecurityCallbackFactory.java +++ b/src/main/java/org/olat/modules/lecture/ui/LecturesSecurityCallbackFactory.java @@ -75,13 +75,37 @@ public class LecturesSecurityCallbackFactory { return adminRole; } + @Override + public boolean canSeeAppeals() { + if(!lectureModule.isAbsenceAppealEnabled()) { + return false; + } + + if(viewAs == LectureRoles.teacher) { + return teacherRole && lectureModule.isTeacherCanSeeAppeal(); + } + if(viewAs == LectureRoles.mastercoach) { + return masterCoachRole && lectureModule.isMasterCoachCanSeeAppeal(); + } + if(viewAs == LectureRoles.lecturemanager) { + return adminRole && lectureModule.isAbsenceAppealEnabled(); + } + return false; + } + @Override public boolean canApproveAppeal() { if(adminRole) { return true; } - return (masterCoachRole && lectureModule.isMasterCoachCanAuthorizedAppeal()) - || (teacherRole && lectureModule.isTeacherCanAuthorizedAppeal()); + + if(viewAs == LectureRoles.teacher) { + return teacherRole && lectureModule.isTeacherCanAuthorizedAppeal(); + } + if(viewAs == LectureRoles.mastercoach) { + return masterCoachRole && lectureModule.isMasterCoachCanAuthorizedAppeal(); + } + return false; } @Override 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 16d4144ede6..0cf06b99f58 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 @@ -1,5 +1,4 @@ -#Wed Aug 07 15:31:55 CEST 2019 - +#Mon Aug 19 16:40:37 CEST 2019 absence.category=Absenzenbegr\u00FCndung absence.category.copied=Absenzenbegr\u00FCndung wurde erfolgreich kopiert. absence.category.copy={0} (Kopie) @@ -56,7 +55,6 @@ attendance.list.title=Absenzenliste\: {0} attendance.list.to.sign=Pr\u00E4senzliste attendance.list.to.sign.title=Pr\u00E4senzliste\: {0} authorized.absence=Entschuldigt -not.authorized.absence=Unentschuldigt authorized.absence.reason=Begr\u00FCndung autoclosed=Autoerledigt bulk=Benutzername, $org.olat.user.propertyhandlers\:table.name.email oder $org.olat.user.propertyhandlers\:table.name.institutionalUserIdentifier @@ -64,10 +62,9 @@ bulk.example=test01<br>author02<br>test@openolat.org bulk.hint=Im Suchfeld k\u00F6nenn Sie eine Liste von Benutzernamen oder E-Mailadressen der Benutzer eintragen. cancel.lecture.blocks=Lektionen absagen cancelled=Abgesagt -contact.teachers.list.name=Dozenten close.lecture.blocks=Lektionen abschliessen -close.lecture.blocks.day=Absenzenerfassung f\u00FCr {0} abschliessen close.lecture.blocks.confirmation={0} Lektionen am {1} werden abgeschlossen. +close.lecture.blocks.day=Absenzenerfassung f\u00FCr {0} abschliessen closed=Erledigt coach.absence=Absenzen coach.appeals=Rekurse @@ -99,6 +96,7 @@ confirm.delete.assessment.mode.title=Pr\u00FCfungsmodus l\u00F6schen confirm.delete.lectures=Wollen Sie wirklich diesen Lektionenblock "{0}" l\u00F6schen? confirm.delete.reason=Wollen Sie wirklich diese Begr\u00FCndung "{0}" l\u00F6schen? contact.teachers=Dozenten kontaktieren +contact.teachers.list.name=Dozenten copy=Kopieren current.lecture=Aktueller Lektionenblock date.end=$org.olat.repository\:cif.date.end @@ -133,12 +131,12 @@ empty.table.participant.list=Es wurde noch keine Anwesenheitskontrolle f\u00FCr entry.rate=Kursschwellwert error.atleastone.lecture=Bitte w\u00E4hlen Sie mindestens ein Lektionenblock. error.collision=Es gibt bereits eine Absenz an diesem Datum. -error.unauthorized.absence.msg=Es wurde <strong>eine</strong> unentschulidgte Absenz gefunden. -error.unauthorized.absences.msg=Es wurden <strong>{0}</strong> unentschulidgte Absenzen gefunden. error.integer.between=Die Eingabe muss eine Zahl zwischen {0} und {1} sein. error.integer.positive=Die Eingabe muss eine positive Zahl sein. error.reason.mandatory=Begr\u00FCndung ist erforderlich error.search.form.notempty=F\u00FCllen Sie bitte mindestens ein Feld mit zwei Charakter aus. +error.unauthorized.absence.msg=Es wurde <strong>eine</strong> unentschulidgte Absenz gefunden. +error.unauthorized.absences.msg=Es wurden <strong>{0}</strong> unentschulidgte Absenzen gefunden. evening=Abend export.footer.lectures.hint=x \= Lektion abwesend export.header.entry=Kurs\: {0} @@ -248,6 +246,8 @@ log.change.admission.date=Erstzulassungsdatum angepasst\: {0} log.change.rate=Schwellwert angepasst\: {0} log.remove.admission.date=Erstzulassungsdatum entfernt log.remove.rate=Schwellwert entfernt +mail.body=Nachricht +mail.subject=Betreff managed.flags.lecture.block.all=Vollst\u00E4ndige externe Verwaltung managed.flags.lecture.block.compulsory=Zwingend managed.flags.lecture.block.dates=Datum @@ -261,8 +261,6 @@ managed.flags.lecture.block.preparation=Vorbereitung/Nachbereitung managed.flags.lecture.block.settings=Konfiguration managed.flags.lecture.block.teachers=Dozenten managed.flags.lecture.block.title=Title -mail.subject=Betreff -mail.body=Nachricht menu.my.lectures=Absenzen menu.my.lectures.alt=Lektionen und Absenzen morning=Vormittag @@ -274,6 +272,7 @@ multi.rollcall.title.for=f\u00FCr {0} ({1} Lektionenbl\u00F6cke) new.appeal.title=Neue Rekursmeldung next.participant=Weiter zum n\u00E4chsten Teilnehmer no.teachers=Noch kein Dozent vorhanden +not.authorized.absence=Unentschuldigt notice.dates.lectures.title=Kontext notice.end.date=Enddatum notice.reason.title=Grund f\u00FCr Abwesenheit @@ -345,21 +344,22 @@ repo.participants=Teilnehmer repo.settings=Konfiguration results=Resultate rollcall=Anwesenheitskontrolle +rollcall.absence=Absenz +rollcall.absence.notice=Abmeldung rollcall.coach.hint=Hinweis\: Absenzen werden pro Lektion erfasst. Wird mehr als die H\u00E4lfte einer Lektion vers\u00E4umt, wird diese als Absenz eingetragen. rollcall.comment=Bemerkung +rollcall.dispensation=Dispens rollcall.status=Status Lektionenblock rollcall.tooltip.absence=Abwesenheit rollcall.tooltip.authorized.absence=Entschuldigte Abwesenheit rollcall.tooltip.free=Freiwillig rollcall.tooltip.ok=Anwesend rollcall.tooltip.unauthorized.absence=Unentschuldigte Abwesenheit -rollcall.absence.notice=Abmeldung -rollcall.dispensation=Dispens -rollcall.absence=Absenz save.next=Speichern und weiter save.temporary=Zwischenspeichern search.curriculums=Suche nach Curriculum search.date=Datum +search.entries=Suche nach Kurs search.form.category=Grund search.form.end=Bis search.form.login=Benutzername @@ -373,7 +373,6 @@ search.form.string=Suche search.form.string.hint=In der Suche k\u00F6nnen Sie nach Titeln eines Lektionenblockes oder nach der Externen Referenz suchen. Bei der Suche mit der Externen Referenz werden nur exakte Treffer angezeigt. search.form.till=bis search.form.type=Art -search.entries=Suche nach Kurs search.participants=Suche nach Teilnehmern search.teachers=Suche nach Dozenten send=Schicken @@ -468,14 +467,14 @@ tool.teacher=Als Dozent tools=Aktion tools.import.table=Lektionbl\u00F6cke aus Excel importieren total=Total +unauthorized.filter=Unentschuldigt +unauthorized.filter.label=Anzeige unoverride.lecture=\u00DCbergehen anhalten upto=bis {0} user.overview.appeals=Rekurse user.overview.dispensation=Dispensen user.overview.lectures=Lektionen und Absenzen user.profil=Benutzerprofil -unauthorized.filter=Unentschuldigt -unauthorized.filter.label=Anzeige warning.choose.at.least.one.appeal=Sie m\u00FCssen mindestens einen Rekurs w\u00E4hlen. warning.edit.lecture=Absenzenerfassung ist deaktiviert. warning.repositoryentry.deleted=$org.olat.repository\:repositoryentry.deleted @@ -483,4 +482,4 @@ warning.teachers.at.least.one.contact=Es gibt kein Dozent zu kontaktieren whole.day=ganzer Tag wizard.entries.label.block=<strong>{0}</strong> <small>{1}</small> ({2} Lektionenblock) wizard.entries.label.blocks=<strong>{0}</strong> <small>{1}</small> ({2} Lektionenbl\u00F6cke) -wizard.lectureblock.label=<strong>{0}</strong> <small>{1}</small><br>{2} {3} - {4} {5} Lektionen: "{6}" mit {7} +wizard.lectureblock.label=<strong>{0}</strong> <small>{1}</small><br>{2} {3} - {4} {5} Lektionen\: "{6}" mit {7} 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 f28df5c1e82..f6c53cf59c1 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 @@ -1,4 +1,4 @@ -#Wed Aug 07 15:32:15 CEST 2019 +#Mon Aug 19 16:40:11 CEST 2019 absence.category=Reason of absence absence.category.copied=Reason of absence was successfully copied. absence.category.copy={0} (copie) @@ -56,7 +56,6 @@ attendance.list.to.sign=Attendance list attendance.list.to.sign.title=Attendance list\: {0} authorized.absence=Authorized authorized.absence.reason=Reason -not.authorized.absence=Not authorized autoclosed=Auto-closed bulk=User names, $org.olat.user.propertyhandlers\:table.name.email oder $org.olat.user.propertyhandlers\:table.name.institutionalUserIdentifier bulk.example=test01<br>author02<br>test@openolat.org @@ -64,8 +63,8 @@ bulk.hint=You can give a list of user names or email addresses separated by a re cancel.lecture.blocks=Cancel lectures cancelled=Cancelled close.lecture.blocks=Close lectures -close.lecture.blocks.day=Close lectures for {0} close.lecture.blocks.confirmation={0} lectures at {1} will be closed. +close.lecture.blocks.day=Close lectures for {0} closed=Closed coach.absence=Absences coach.appeals=Appeals @@ -129,8 +128,8 @@ empty.table.lectures.blocks=There are no lectures to display. empty.table.lectures.blocks.admin=No lecture blocks have been created for this course so far. empty.table.participant.list=No roll calls have been made for this course so far. entry.rate=Course's rate -error.collision=There is already an absence at these dates. error.atleastone.lecture=Please choose at least one lecture block. +error.collision=There is already an absence at these dates. error.integer.between=The input must be a number between {0} and {1} error.integer.positive=The number must be positive. error.reason.mandatory=Reason is mandatory @@ -244,6 +243,8 @@ log.change.admission.date=Update admission date {0} log.change.rate=Update attendance rate {0} log.remove.admission.date=Remove admission date log.remove.rate=Remove attendance rate +mail.body=Message +mail.subject=Subject managed.flags.lecture.block.all=Fully externally managed managed.flags.lecture.block.compulsory=Compulsory managed.flags.lecture.block.dates=Dates @@ -257,8 +258,6 @@ managed.flags.lecture.block.preparation=Preparation managed.flags.lecture.block.settings=Configuration managed.flags.lecture.block.teachers=Teacher managed.flags.lecture.block.title=Title -mail.subject=Subject -mail.body=Message menu.my.lectures=Absences menu.my.lectures.alt=Lectures and absences morning=Morning @@ -267,6 +266,7 @@ multi.rollcall.title.for=for {0} ({1} lecture blocks) new.appeal.title=New appeal next.participant=To the next participant no.teachers=No coaches yet +not.authorized.absence=Not authorized notice.dates.lectures.title=Context notice.end.date=End date notice.reason.title=Reason of absence @@ -338,21 +338,22 @@ repo.participants=Participants repo.settings=Configuration results=Results rollcall=Roll call +rollcall.absence=Absence +rollcall.absence.notice=Notice of absence rollcall.coach.hint=Note\: absences are recorded per lesson. If more than the half a lesson is missed, the lesson is entered as an absence. rollcall.comment=Comment +rollcall.dispensation=Dispensation rollcall.status=Roll call status rollcall.tooltip.absence=Absent rollcall.tooltip.authorized.absence=Authorized absence rollcall.tooltip.free=Free rollcall.tooltip.ok=Present rollcall.tooltip.unauthorized.absence=Not authorized absence -rollcall.absence.notice=Notice of absence -rollcall.dispensation=Dispensation -rollcall.absence=Absence save.next=Save and next save.temporary=Quick save search.curriculums=Search by curriculums search.date=Date +search.entries=Search by courses search.form.category=Reason search.form.end=Until search.form.login=Username @@ -366,7 +367,6 @@ search.form.string=Search search.form.string.hint=You can search title of lecture blocks and title or external reference of courses. External reference is an exact match. search.form.till=till search.form.type=Type -search.entries=Search by courses search.participants=Search by participants search.teachers=Search by teachers send=Send @@ -461,14 +461,14 @@ tool.teacher=As teacher tools=Action tools.import.table=Import lecture blocks from Excel total=Total +unauthorized.filter=Unauthorized +unauthorized.filter.label=Display unoverride.lecture=Stop override upto=till {0} user.overview.appeals=Appeals user.overview.dispensation=Dispensation user.overview.lectures=Lectures and absences user.profil=User profil -unauthorized.filter=Unauthorized -unauthorized.filter.label=Display warning.choose.at.least.one.appeal=You need to choose at least one appeal warning.edit.lecture=Roll call ist deactivated. warning.repositoryentry.deleted=$org.olat.repository\:repositoryentry.deleted @@ -476,4 +476,4 @@ warning.teachers.at.least.one.contact=There isn't any teacher to contact whole.day=Whole day wizard.entries.label.block=<strong>{0}</strong> <small>{1}</small> ({2} lectures block) wizard.entries.label.blocks=<strong>{0}</strong> <small>{1}</small> ({2} lectures blocks) -wizard.lectureblock.label=<strong>{0}</strong> <small>{1}</small><br>{2} {3} - {4} {5} lessons: "{6}" with {7} +wizard.lectureblock.label=<strong>{0}</strong> <small>{1}</small><br>{2} {3} - {4} {5} lessons\: "{6}" with {7} diff --git a/src/main/java/org/olat/modules/lecture/ui/admin/LecturesPermissionsSettingsAdminController.java b/src/main/java/org/olat/modules/lecture/ui/admin/LecturesPermissionsSettingsAdminController.java index 0f92365a93f..6194bc7688b 100644 --- a/src/main/java/org/olat/modules/lecture/ui/admin/LecturesPermissionsSettingsAdminController.java +++ b/src/main/java/org/olat/modules/lecture/ui/admin/LecturesPermissionsSettingsAdminController.java @@ -137,6 +137,6 @@ public class LecturesPermissionsSettingsAdminController extends FormBasicControl lectureModule.setMasterCoachCanSeeAppeal(appealEnabled && masterCoachCanSeeAppealEl.isAtLeastSelected(1)); lectureModule.setMasterCoachCanAuthorizedAppeal(appealEnabled && masterCoachCanAuthorizeAppealEl.isAtLeastSelected(1)); - lectureModule.setMasterCoachCanAuthorizedAppeal(appealEnabled && participantCanNoticeEl.isAtLeastSelected(1)); + lectureModule.setParticipantCanNotice(participantCanNoticeEl.isAtLeastSelected(1)); } } diff --git a/src/main/java/org/olat/modules/lecture/ui/coach/AbsenceNoticesListController.java b/src/main/java/org/olat/modules/lecture/ui/coach/AbsenceNoticesListController.java index d915ee775e1..88e32cc7150 100644 --- a/src/main/java/org/olat/modules/lecture/ui/coach/AbsenceNoticesListController.java +++ b/src/main/java/org/olat/modules/lecture/ui/coach/AbsenceNoticesListController.java @@ -218,6 +218,10 @@ public class AbsenceNoticesListController extends FormBasicController { columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(NoticeCols.type)); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(NoticeCols.tools)); } + + protected void reloadModel() { + loadModel(lastSearchParams); + } protected void loadModel(AbsenceNoticeSearchParameters searchParams) { lastSearchParams = searchParams; @@ -485,7 +489,7 @@ public class AbsenceNoticesListController extends FormBasicController { private void doEdit(UserRequest ureq, AbsenceNoticeRow row) { AbsenceNotice notice = lectureService.getAbsenceNotice(row.getAbsenceNotice()); - editNoticeCtrl = new EditNoticeController(ureq, getWindowControl(), notice); + editNoticeCtrl = new EditNoticeController(ureq, getWindowControl(), notice, secCallback); listenTo(editNoticeCtrl); String title = translate(AbsenceNoticeHelper.getEditKey(row.getAbsenceNotice())); diff --git a/src/main/java/org/olat/modules/lecture/ui/coach/AbsencesController.java b/src/main/java/org/olat/modules/lecture/ui/coach/AbsencesController.java index fbab02b9a40..a8529e73f81 100644 --- a/src/main/java/org/olat/modules/lecture/ui/coach/AbsencesController.java +++ b/src/main/java/org/olat/modules/lecture/ui/coach/AbsencesController.java @@ -175,7 +175,7 @@ public class AbsencesController extends BasicController { private void doAddNotice(UserRequest ureq) { final EditAbsenceNoticeWrapper noticeWrapper = new EditAbsenceNoticeWrapper(AbsenceNoticeType.absence); - AbsenceNotice1UserSearchStep step = new AbsenceNotice1UserSearchStep(ureq, noticeWrapper); + AbsenceNotice1UserSearchStep step = new AbsenceNotice1UserSearchStep(ureq, noticeWrapper, secCallback); StepRunnerCallback stop = (uureq, swControl, runContext) -> { if(noticeWrapper.getAbsenceNotice() == null) { Identity absentIdentity = noticeWrapper.getIdentity(); diff --git a/src/main/java/org/olat/modules/lecture/ui/coach/DailyAbsencesController.java b/src/main/java/org/olat/modules/lecture/ui/coach/DailyAbsencesController.java index 20788080ad0..4c8a4c8d790 100644 --- a/src/main/java/org/olat/modules/lecture/ui/coach/DailyAbsencesController.java +++ b/src/main/java/org/olat/modules/lecture/ui/coach/DailyAbsencesController.java @@ -83,6 +83,10 @@ public class DailyAbsencesController extends BasicController { noticesListCtlr.setCurrentDate(date); noticesListCtlr.loadModel(searchParams); } + + public void reloadModel() { + noticesListCtlr.reloadModel(); + } @Override protected void doDispose() { diff --git a/src/main/java/org/olat/modules/lecture/ui/coach/DispensationsController.java b/src/main/java/org/olat/modules/lecture/ui/coach/DispensationsController.java index db144bf5d76..60ea054d4f8 100644 --- a/src/main/java/org/olat/modules/lecture/ui/coach/DispensationsController.java +++ b/src/main/java/org/olat/modules/lecture/ui/coach/DispensationsController.java @@ -70,6 +70,7 @@ public class DispensationsController extends BasicController { private final VelocityContainer mainVC; private final boolean withAddAbsence; + private final LecturesSecurityCallback secCallback; private final AbsenceNoticeSearchParameters searchParams = new AbsenceNoticeSearchParameters(); private StepsMainRunController addNoticeCtrl; @@ -85,6 +86,7 @@ public class DispensationsController extends BasicController { LecturesSecurityCallback secCallback, boolean withSearch, boolean withAddAbsence) { super(ureq, wControl, Util.createPackageTranslator(LectureRepositoryAdminController.class, ureq.getLocale())); + this.secCallback = secCallback; this.withAddAbsence = withAddAbsence; searchParams.addTypes(AbsenceNoticeType.notified, AbsenceNoticeType.dispensation); @@ -153,6 +155,10 @@ public class DispensationsController extends BasicController { } } + public void reloadModel() { + noticesListCtlr.reloadModel(); + } + private void doSearch(SearchAbsenceNoticeEvent event) { searchParams.setStartDate(event.getStartDate()); searchParams.setEndDate(event.getEndDate()); @@ -167,7 +173,7 @@ public class DispensationsController extends BasicController { if(!withAddAbsence) return; final EditAbsenceNoticeWrapper noticeWrapper = new EditAbsenceNoticeWrapper(type); - AbsenceNotice1UserSearchStep step = new AbsenceNotice1UserSearchStep(ureq, noticeWrapper); + AbsenceNotice1UserSearchStep step = new AbsenceNotice1UserSearchStep(ureq, noticeWrapper, secCallback); StepRunnerCallback stop = (uureq, swControl, runContext) -> { if(noticeWrapper.getAbsenceNotice() == null) { Identity absentIdentity = noticeWrapper.getIdentity(); diff --git a/src/main/java/org/olat/modules/lecture/ui/coach/EditDatesLecturesEntriesController.java b/src/main/java/org/olat/modules/lecture/ui/coach/EditDatesLecturesEntriesController.java index 91d3b939989..0d8dd434d1a 100644 --- a/src/main/java/org/olat/modules/lecture/ui/coach/EditDatesLecturesEntriesController.java +++ b/src/main/java/org/olat/modules/lecture/ui/coach/EditDatesLecturesEntriesController.java @@ -53,6 +53,7 @@ import org.olat.modules.lecture.model.EditAbsenceNoticeWrapper; import org.olat.modules.lecture.model.LectureBlockWithTeachers; import org.olat.modules.lecture.model.LecturesBlockSearchParameters; import org.olat.modules.lecture.ui.LectureRepositoryAdminController; +import org.olat.modules.lecture.ui.LecturesSecurityCallback; import org.olat.repository.RepositoryEntry; import org.olat.user.UserManager; import org.springframework.beans.factory.annotation.Autowired; @@ -79,6 +80,7 @@ public class EditDatesLecturesEntriesController extends FormBasicController { private final boolean wizard; private final Formatter formatter; private final Identity noticedIdentity; + private final LecturesSecurityCallback secCallback; private final EditAbsenceNoticeWrapper noticeWrapper; private List<RepositoryEntry> loadedRepositoryEntries; private List<LectureBlockWithTeachers> loadedLectureBlocks; @@ -89,10 +91,11 @@ public class EditDatesLecturesEntriesController extends FormBasicController { private LectureService lectureService; public EditDatesLecturesEntriesController(UserRequest ureq, WindowControl wControl, Form rootForm, - EditAbsenceNoticeWrapper noticeWrapper, boolean wizard) { + EditAbsenceNoticeWrapper noticeWrapper, LecturesSecurityCallback secCallback, boolean wizard) { super(ureq, wControl, LAYOUT_DEFAULT, null, rootForm); setTranslator(Util.createPackageTranslator(LectureRepositoryAdminController.class, ureq.getLocale())); this.wizard = wizard; + this.secCallback = secCallback; this.noticeWrapper = noticeWrapper; this.noticedIdentity = noticeWrapper.getIdentity(); formatter = Formatter.getInstance(getLocale()); @@ -168,6 +171,7 @@ public class EditDatesLecturesEntriesController extends FormBasicController { durationEl.setMandatory(true); datesEl = uifactory.addDateChooser("noticed.start", null, startDate, formLayout); + datesEl.addActionListener(FormEvent.ONCHANGE); datesEl.setDomReplacementWrapperRequired(false); datesEl.setSecondDate(endDate); datesEl.setSeparator("noticed.till"); @@ -266,7 +270,11 @@ public class EditDatesLecturesEntriesController extends FormBasicController { private Map<RepositoryEntry,Long> getRepositoryEntries() { LecturesBlockSearchParameters searchParams = new LecturesBlockSearchParameters(); - searchParams.setTeacher(getIdentity()); + searchParams.setViewAs(getIdentity(), secCallback.viewAs()); + if(noticedIdentity != null) { + searchParams.setParticipant(noticedIdentity); + } + searchParams.setStartDate(datesEl.getDate()); if(durationEl.isSelected(0)) { searchParams.setEndDate(CalendarUtils.endOfDay(searchParams.getStartDate())); @@ -311,7 +319,10 @@ public class EditDatesLecturesEntriesController extends FormBasicController { if(noticeWrapper.getPredefinedLectureBlocks() != null && !noticeWrapper.getPredefinedLectureBlocks().isEmpty()) { searchParams.setLectureBlocks(noticeWrapper.getPredefinedLectureBlocks()); } else { - searchParams.setTeacher(getIdentity()); + searchParams.setViewAs(getIdentity(), secCallback.viewAs()); + if(noticedIdentity != null) { + searchParams.setParticipant(noticedIdentity); + } searchParams.setStartDate(datesEl.getDate()); if(durationEl.isSelected(0)) { searchParams.setEndDate(CalendarUtils.endOfDay(searchParams.getStartDate())); @@ -427,7 +438,7 @@ public class EditDatesLecturesEntriesController extends FormBasicController { protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { if(durationEl == source) { updateDuration(); - } else if(targetsEl == source) { + } else if(targetsEl == source || datesEl == source) { updateTargets(); } super.formInnerEvent(ureq, source, event); diff --git a/src/main/java/org/olat/modules/lecture/ui/coach/EditNoticeController.java b/src/main/java/org/olat/modules/lecture/ui/coach/EditNoticeController.java index f829a0fdd8e..5cb96ad75a9 100644 --- a/src/main/java/org/olat/modules/lecture/ui/coach/EditNoticeController.java +++ b/src/main/java/org/olat/modules/lecture/ui/coach/EditNoticeController.java @@ -35,6 +35,7 @@ import org.olat.modules.lecture.AbsenceNoticeToRepositoryEntry; import org.olat.modules.lecture.LectureBlock; import org.olat.modules.lecture.LectureService; import org.olat.modules.lecture.model.EditAbsenceNoticeWrapper; +import org.olat.modules.lecture.ui.LecturesSecurityCallback; import org.olat.repository.RepositoryEntry; import org.springframework.beans.factory.annotation.Autowired; @@ -55,7 +56,7 @@ public class EditNoticeController extends FormBasicController { @Autowired private LectureService lectureService; - public EditNoticeController(UserRequest ureq, WindowControl wControl, AbsenceNotice notice) { + public EditNoticeController(UserRequest ureq, WindowControl wControl, AbsenceNotice notice, LecturesSecurityCallback secCallback) { super(ureq, wControl, "edit_notice"); absenceNotice = notice; @@ -73,10 +74,10 @@ public class EditNoticeController extends FormBasicController { noticeWrapper.setEntries(entries); } - datesAndLecturesCtrl = new EditDatesLecturesEntriesController(ureq, wControl, mainForm, noticeWrapper, false); + datesAndLecturesCtrl = new EditDatesLecturesEntriesController(ureq, wControl, mainForm, noticeWrapper, secCallback, false); listenTo(datesAndLecturesCtrl); - editReasonCtrl = new EditReasonController(ureq, wControl, mainForm, noticeWrapper, false); + editReasonCtrl = new EditReasonController(ureq, wControl, mainForm, noticeWrapper, secCallback, false); listenTo(editReasonCtrl); initForm(ureq); diff --git a/src/main/java/org/olat/modules/lecture/ui/coach/EditReasonController.java b/src/main/java/org/olat/modules/lecture/ui/coach/EditReasonController.java index 159e1091133..f7c094b0dcf 100644 --- a/src/main/java/org/olat/modules/lecture/ui/coach/EditReasonController.java +++ b/src/main/java/org/olat/modules/lecture/ui/coach/EditReasonController.java @@ -41,6 +41,8 @@ import org.olat.modules.lecture.AbsenceNoticeType; import org.olat.modules.lecture.LectureService; import org.olat.modules.lecture.model.EditAbsenceNoticeWrapper; import org.olat.modules.lecture.ui.LectureRepositoryAdminController; +import org.olat.modules.lecture.ui.LectureRoles; +import org.olat.modules.lecture.ui.LecturesSecurityCallback; import org.olat.user.UserManager; import org.springframework.beans.factory.annotation.Autowired; @@ -65,6 +67,7 @@ public class EditReasonController extends FormBasicController { private final boolean wizard; private final Identity noticedIdentity; private final EditAbsenceNoticeWrapper noticeWrapper; + private final LecturesSecurityCallback secCallback; private List<AbsenceCategory> absenceCategories; @Autowired @@ -73,10 +76,11 @@ public class EditReasonController extends FormBasicController { private LectureService lectureService; public EditReasonController(UserRequest ureq, WindowControl wControl, Form rootForm, - EditAbsenceNoticeWrapper noticeWrapper, boolean wizard) { + EditAbsenceNoticeWrapper noticeWrapper, LecturesSecurityCallback secCallback, boolean wizard) { super(ureq, wControl, LAYOUT_DEFAULT, null, rootForm); setTranslator(Util.createPackageTranslator(LectureRepositoryAdminController.class, ureq.getLocale())); this.wizard = wizard; + this.secCallback = secCallback; this.noticeWrapper = noticeWrapper; this.noticedIdentity = noticeWrapper.getIdentity(); absenceCategories = lectureService.getAllAbsencesCategories(); @@ -97,12 +101,14 @@ public class EditReasonController extends FormBasicController { translate("noticed.type.absence"), translate("noticed.type.notified"), translate("noticed.type.dispensation") }; typeEl = uifactory.addRadiosHorizontal("noticed.type", "noticed.type", formLayout, typeKeys, typeValues); + typeEl.setVisible(secCallback.viewAs() != LectureRoles.participant); typeEl.addActionListener(FormEvent.ONCHANGE); if(noticeWrapper.getAbsenceNoticeType() != null) { typeEl.select(noticeWrapper.getAbsenceNoticeType().name(), true); } String[] authorizedValues = new String[] { translate("noticed.autorized.yes") }; authorizedEl = uifactory.addCheckboxesHorizontal("noticed.autorized", null, formLayout, authorizedKeys, authorizedValues); + authorizedEl.setVisible(secCallback.viewAs() != LectureRoles.participant); if(noticeWrapper.getAuthorized() != null && noticeWrapper.getAuthorized().booleanValue()) { authorizedEl.select(authorizedKeys[0], true); } @@ -160,7 +166,7 @@ public class EditReasonController extends FormBasicController { } typeEl.clearError(); - if(!typeEl.isOneSelected()) { + if(typeEl.isVisible() && !typeEl.isOneSelected()) { typeEl.setErrorKey("form.legende.mandatory", null); allOk &= false; } @@ -185,7 +191,15 @@ public class EditReasonController extends FormBasicController { protected void formOK(UserRequest ureq) { noticeWrapper.setAbsenceReason(reasonEl.getValue()); noticeWrapper.setAbsenceCategory(getAbsenceCategory()); - noticeWrapper.setAuthorized(authorizedEl.isAtLeastSelected(1)); - noticeWrapper.setAbsenceNoticeType(AbsenceNoticeType.valueOf(typeEl.getSelectedKey())); + if(authorizedEl.isVisible()) { + noticeWrapper.setAuthorized(authorizedEl.isAtLeastSelected(1)); + } else { + noticeWrapper.setAuthorized(null); + } + if(typeEl.isVisible()) { + noticeWrapper.setAbsenceNoticeType(AbsenceNoticeType.valueOf(typeEl.getSelectedKey())); + } else if(noticeWrapper.getAbsenceNoticeType() != null) { + noticeWrapper.setAbsenceNoticeType(noticeWrapper.getAbsenceNoticeType()); + } } } diff --git a/src/main/java/org/olat/modules/lecture/ui/coach/IdentitiesLecturesRollCallController.java b/src/main/java/org/olat/modules/lecture/ui/coach/IdentitiesLecturesRollCallController.java index 5d02aecf85b..f225bdc88d1 100644 --- a/src/main/java/org/olat/modules/lecture/ui/coach/IdentitiesLecturesRollCallController.java +++ b/src/main/java/org/olat/modules/lecture/ui/coach/IdentitiesLecturesRollCallController.java @@ -443,7 +443,7 @@ public class IdentitiesLecturesRollCallController extends FormBasicController { noticeWrapper.setPredefinedLectureBlocks(lectureBlocksForIdentity); noticeWrapper.setCurrentDate(currentDate); - AbsenceNotice3LecturesEntriesStep step = new AbsenceNotice3LecturesEntriesStep(ureq, noticeWrapper, true); + AbsenceNotice3LecturesEntriesStep step = new AbsenceNotice3LecturesEntriesStep(ureq, noticeWrapper, secCallback, true); StepRunnerCallback stop = (uureq, swControl, runContext) -> { if(noticeWrapper.getAbsenceNotice() == null) { Identity absentIdentity = noticeWrapper.getIdentity(); diff --git a/src/main/java/org/olat/modules/lecture/ui/coach/LecturesCoachingController.java b/src/main/java/org/olat/modules/lecture/ui/coach/LecturesCoachingController.java index 6391d384dd1..ba544d2ccec 100644 --- a/src/main/java/org/olat/modules/lecture/ui/coach/LecturesCoachingController.java +++ b/src/main/java/org/olat/modules/lecture/ui/coach/LecturesCoachingController.java @@ -58,11 +58,11 @@ import org.olat.repository.RepositoryEntry; public class LecturesCoachingController extends BasicController implements Activateable2 { private Link reportLink; + private Link appealsLink; private final Link cockpitLink; private final Link lecturesLink; private final Link absenceLink; private final Link dispensationLink; - private final Link appealsLink; private final Link lecturesSearchLink; private final VelocityContainer mainVC; private final TooledStackedPanel stackPanel; @@ -95,8 +95,11 @@ public class LecturesCoachingController extends BasicController implements Activ segmentView.addSegment(absenceLink, false); dispensationLink = LinkFactory.createLink("coach.dispensation", mainVC, this); segmentView.addSegment(dispensationLink, false); - appealsLink = LinkFactory.createLink("coach.appeals", mainVC, this); - segmentView.addSegment(appealsLink, false); + + if(secCallback.canSeeAppeals()) { + appealsLink = LinkFactory.createLink("coach.appeals", mainVC, this); + segmentView.addSegment(appealsLink, false); + } lecturesSearchLink = LinkFactory.createLink("coach.lectures.search", mainVC, this); segmentView.addSegment(lecturesSearchLink, false); @@ -132,14 +135,15 @@ public class LecturesCoachingController extends BasicController implements Activ doOpenLectures(ureq); segmentView.select(lecturesLink); } else if("Absences".equalsIgnoreCase(type)) { - doAbsences(ureq); segmentView.select(absenceLink); } else if("Dispenses".equalsIgnoreCase(type)) { doDispenses(ureq); segmentView.select(dispensationLink); } else if("Appeals".equalsIgnoreCase(type)) { - doAppeals(ureq); - segmentView.select(appealsLink); + if(secCallback.canSeeAppeals()) { + doAppeals(ureq); + segmentView.select(appealsLink); + } } else if("Search".equalsIgnoreCase(type)) { List<ContextEntry> subEntries = entries.subList(1, entries.size()); doOpenLecturesSearch(ureq).activate(ureq, subEntries, entries.get(0).getTransientState()); diff --git a/src/main/java/org/olat/modules/lecture/ui/profile/DailyOverviewProfilController.java b/src/main/java/org/olat/modules/lecture/ui/profile/DailyOverviewProfilController.java index fe94c31f2d0..271cae08a26 100644 --- a/src/main/java/org/olat/modules/lecture/ui/profile/DailyOverviewProfilController.java +++ b/src/main/java/org/olat/modules/lecture/ui/profile/DailyOverviewProfilController.java @@ -90,6 +90,11 @@ public class DailyOverviewProfilController extends BasicController { lectureBlocksCtrl.setCurrentDate(currentDate); absencesListCtrl.setCurrentDate(currentDate); } + + + public void reloadModel() { + absencesListCtrl.reloadModel(); + } @Override protected void event(UserRequest ureq, Component source, Event event) { diff --git a/src/main/java/org/olat/modules/lecture/ui/profile/IdentityProfileController.java b/src/main/java/org/olat/modules/lecture/ui/profile/IdentityProfileController.java index 411de14fb46..ce90739574a 100644 --- a/src/main/java/org/olat/modules/lecture/ui/profile/IdentityProfileController.java +++ b/src/main/java/org/olat/modules/lecture/ui/profile/IdentityProfileController.java @@ -19,6 +19,8 @@ */ package org.olat.modules.lecture.ui.profile; +import java.util.ArrayList; +import java.util.Date; import java.util.List; import org.olat.admin.user.UserShortDescription; @@ -29,20 +31,38 @@ import org.olat.core.gui.components.link.LinkFactory; import org.olat.core.gui.components.stack.BreadcrumbedStackedPanel; import org.olat.core.gui.components.tabbedpane.TabbedPane; import org.olat.core.gui.components.velocity.VelocityContainer; +import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.BasicController; import org.olat.core.gui.control.generic.dtabs.Activateable2; +import org.olat.core.gui.control.generic.wizard.StepRunnerCallback; +import org.olat.core.gui.control.generic.wizard.StepsMainRunController; import org.olat.core.id.Identity; +import org.olat.core.id.Roles; import org.olat.core.id.context.ContextEntry; import org.olat.core.id.context.StateEntry; +import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; import org.olat.core.util.Util; +import org.olat.core.util.mail.ContactList; +import org.olat.core.util.mail.MailBundle; +import org.olat.core.util.mail.MailContext; +import org.olat.core.util.mail.MailContextImpl; +import org.olat.core.util.mail.MailHelper; +import org.olat.core.util.mail.MailLoggingAction; +import org.olat.core.util.mail.MailManager; +import org.olat.core.util.mail.MailerResult; +import org.olat.modules.lecture.AbsenceNoticeType; +import org.olat.modules.lecture.LectureService; +import org.olat.modules.lecture.model.EditAbsenceNoticeWrapper; import org.olat.modules.lecture.ui.AppealListRepositoryController; import org.olat.modules.lecture.ui.LectureRepositoryAdminController; import org.olat.modules.lecture.ui.LecturesSecurityCallback; import org.olat.modules.lecture.ui.ParticipantLecturesOverviewController; import org.olat.modules.lecture.ui.coach.DispensationsController; +import org.olat.modules.lecture.ui.wizard.AbsenceNotice3LecturesEntriesStep; import org.olat.user.DisplayPortraitController; +import org.springframework.beans.factory.annotation.Autowired; /** * @@ -52,22 +72,33 @@ import org.olat.user.DisplayPortraitController; */ public class IdentityProfileController extends BasicController implements Activateable2 { + private Link backLink; private Link addAbsence; - private Link addNoticeOfAbsence; private Link addDispensation; - private Link backLink; + private Link addNoticeOfAbsence; private TabbedPane tabPane; private final VelocityContainer mainVC; + private final Identity profiledIdentity; + private final LecturesSecurityCallback secCallback; + + private StepsMainRunController addNoticeCtrl; private DispensationsController dispensationsCtrl; private AppealListRepositoryController appealsCtrl; private DailyOverviewProfilController dailyOverviewCtrl; private ParticipantLecturesOverviewController lecturesCtrl; + @Autowired + private MailManager mailService; + @Autowired + private LectureService lectureService; + public IdentityProfileController(UserRequest ureq, WindowControl wControl, Identity profiledIdentity, LecturesSecurityCallback secCallback, boolean withBack) { super(ureq, wControl, Util.createPackageTranslator(LectureRepositoryAdminController.class, ureq.getLocale())); + this.profiledIdentity = profiledIdentity; + this.secCallback = secCallback; mainVC = createVelocityContainer("profile"); if(withBack) { @@ -148,6 +179,106 @@ public class IdentityProfileController extends BasicController implements Activa protected void event(UserRequest ureq, Component source, Event event) { if(source == backLink) { fireEvent(ureq, Event.BACK_EVENT); + } else if(addAbsence == source) { + doAddNotice(ureq, AbsenceNoticeType.absence); + } else if(addNoticeOfAbsence == source) { + doAddNotice(ureq, AbsenceNoticeType.notified); + } else if(addDispensation == source) { + doAddNotice(ureq, AbsenceNoticeType.dispensation); + } + } + + @Override + protected void event(UserRequest ureq, Controller source, Event event) { + if(addNoticeCtrl == source) { + if(event == Event.CANCELLED_EVENT || event == Event.DONE_EVENT || event == Event.CHANGED_EVENT) { + getWindowControl().pop(); + if(event == Event.DONE_EVENT || event == Event.CHANGED_EVENT) { + updateModels(); + } + cleanUp(); + } + } + super.event(ureq, source, event); + } + + private void cleanUp() { + removeAsListenerAndDispose(addNoticeCtrl); + addNoticeCtrl = null; + } + + private void updateModels() { + if(dispensationsCtrl != null) { + dispensationsCtrl.reloadModel(); + } + if(dailyOverviewCtrl != null) { + dailyOverviewCtrl.reloadModel(); + } + } + + private void doAddNotice(UserRequest ureq, AbsenceNoticeType type) { + final EditAbsenceNoticeWrapper noticeWrapper = new EditAbsenceNoticeWrapper(type); + noticeWrapper.setIdentity(profiledIdentity); + noticeWrapper.setCurrentDate(new Date()); + + AbsenceNotice3LecturesEntriesStep step = new AbsenceNotice3LecturesEntriesStep(ureq, noticeWrapper, secCallback, true); + StepRunnerCallback stop = (uureq, swControl, runContext) -> { + if(noticeWrapper.getAbsenceNotice() == null) { + Identity absentIdentity = noticeWrapper.getIdentity(); + lectureService.createAbsenceNotice(absentIdentity, noticeWrapper.getAbsenceNoticeType(), noticeWrapper.getAbsenceNoticeTarget(), + noticeWrapper.getStartDate(), noticeWrapper.getEndDate(), + noticeWrapper.getAbsenceCategory(), noticeWrapper.getAbsenceReason(), noticeWrapper.getAuthorized(), + noticeWrapper.getEntries(), noticeWrapper.getLectureBlocks()); + } + + if(noticeWrapper.getIdentitiesToContact() != null && !noticeWrapper.getIdentitiesToContact().isEmpty()) { + inform(ureq, noticeWrapper); + } + return StepsMainRunController.DONE_MODIFIED; + }; + + String title = translate("add.dispensation.title"); + if(type == AbsenceNoticeType.notified) { + title = translate("add.notice.absence.title"); + } else if(type == AbsenceNoticeType.absence) { + title = translate("add.absence.title"); + } + + removeAsListenerAndDispose(addNoticeCtrl); + addNoticeCtrl = new StepsMainRunController(ureq, getWindowControl(), step, stop, null, title, ""); + listenTo(addNoticeCtrl); + getWindowControl().pushAsModalDialog(addNoticeCtrl.getInitialComponent()); + } + + + private void inform(UserRequest ureq, EditAbsenceNoticeWrapper noticeWrapper) { + boolean success = false; + try { + List<ContactList> contactList = new ArrayList<>(); + ContactList memberList = new ContactList(translate("contact.teachers.list.name")); + memberList.addAllIdentites(noticeWrapper.getIdentitiesToContact()); + MailContext context = new MailContextImpl(getWindowControl().getBusinessControl().getAsString()); + MailBundle bundle = new MailBundle(); + bundle.setContext(context); + bundle.setFromId(getIdentity()); + bundle.setContactLists(contactList); + bundle.setContent(noticeWrapper.getContactSubject(), noticeWrapper.getContactSubject()); + MailerResult result = mailService.sendMessage(bundle); + success = result.isSuccessful(); + if (success) { + showInfo("msg.send.ok"); + // do logging + ThreadLocalUserActivityLogger.log(MailLoggingAction.MAIL_SENT, getClass()); + fireEvent(ureq, Event.DONE_EVENT); + } else { + Roles roles = ureq.getUserSession().getRoles(); + boolean admin = roles.isAdministrator() || roles.isSystemAdmin(); + MailHelper.printErrorsAndWarnings(result, getWindowControl(), admin, getLocale()); + fireEvent(ureq, Event.FAILED_EVENT); + } + } catch (Exception e) { + logError("", e); + showWarning("error.msg.send.nok"); } } } diff --git a/src/main/java/org/olat/modules/lecture/ui/wizard/AbsenceNotice1UserSearchStep.java b/src/main/java/org/olat/modules/lecture/ui/wizard/AbsenceNotice1UserSearchStep.java index 14daa2442c5..fcdcc184452 100644 --- a/src/main/java/org/olat/modules/lecture/ui/wizard/AbsenceNotice1UserSearchStep.java +++ b/src/main/java/org/olat/modules/lecture/ui/wizard/AbsenceNotice1UserSearchStep.java @@ -27,6 +27,7 @@ import org.olat.core.gui.control.generic.wizard.PrevNextFinishConfig; import org.olat.core.gui.control.generic.wizard.StepFormController; import org.olat.core.gui.control.generic.wizard.StepsRunContext; import org.olat.modules.lecture.model.EditAbsenceNoticeWrapper; +import org.olat.modules.lecture.ui.LecturesSecurityCallback; /** * @@ -38,10 +39,10 @@ public class AbsenceNotice1UserSearchStep extends BasicStep { private final EditAbsenceNoticeWrapper noticeWrapper; - public AbsenceNotice1UserSearchStep(UserRequest ureq, EditAbsenceNoticeWrapper noticeWrapper) { + public AbsenceNotice1UserSearchStep(UserRequest ureq, EditAbsenceNoticeWrapper noticeWrapper, LecturesSecurityCallback secCallback) { super(ureq); this.noticeWrapper = noticeWrapper; - setNextStep(new AbsenceNotice2ConfirmUserStep(ureq)); + setNextStep(new AbsenceNotice2ConfirmUserStep(ureq, secCallback)); setI18nTitleAndDescr("user.search.title", "user.search.title"); } diff --git a/src/main/java/org/olat/modules/lecture/ui/wizard/AbsenceNotice2ConfirmUserStep.java b/src/main/java/org/olat/modules/lecture/ui/wizard/AbsenceNotice2ConfirmUserStep.java index 187db70aadd..a7314d3594b 100644 --- a/src/main/java/org/olat/modules/lecture/ui/wizard/AbsenceNotice2ConfirmUserStep.java +++ b/src/main/java/org/olat/modules/lecture/ui/wizard/AbsenceNotice2ConfirmUserStep.java @@ -26,6 +26,7 @@ import org.olat.core.gui.control.generic.wizard.BasicStep; import org.olat.core.gui.control.generic.wizard.PrevNextFinishConfig; import org.olat.core.gui.control.generic.wizard.StepFormController; import org.olat.core.gui.control.generic.wizard.StepsRunContext; +import org.olat.modules.lecture.ui.LecturesSecurityCallback; /** * @@ -35,9 +36,9 @@ import org.olat.core.gui.control.generic.wizard.StepsRunContext; */ public class AbsenceNotice2ConfirmUserStep extends BasicStep { - public AbsenceNotice2ConfirmUserStep(UserRequest ureq) { + public AbsenceNotice2ConfirmUserStep(UserRequest ureq, LecturesSecurityCallback secCallback) { super(ureq); - setNextStep(new AbsenceNotice3LecturesEntriesStep(ureq)); + setNextStep(new AbsenceNotice3LecturesEntriesStep(ureq, secCallback)); setI18nTitleAndDescr("user.confirm.title", "user.confirm.title"); } diff --git a/src/main/java/org/olat/modules/lecture/ui/wizard/AbsenceNotice3LecturesEntriesStep.java b/src/main/java/org/olat/modules/lecture/ui/wizard/AbsenceNotice3LecturesEntriesStep.java index 7f98d87a006..a643267199e 100644 --- a/src/main/java/org/olat/modules/lecture/ui/wizard/AbsenceNotice3LecturesEntriesStep.java +++ b/src/main/java/org/olat/modules/lecture/ui/wizard/AbsenceNotice3LecturesEntriesStep.java @@ -27,6 +27,7 @@ import org.olat.core.gui.control.generic.wizard.PrevNextFinishConfig; import org.olat.core.gui.control.generic.wizard.StepFormController; import org.olat.core.gui.control.generic.wizard.StepsRunContext; import org.olat.modules.lecture.model.EditAbsenceNoticeWrapper; +import org.olat.modules.lecture.ui.LecturesSecurityCallback; /** * @@ -37,16 +38,19 @@ import org.olat.modules.lecture.model.EditAbsenceNoticeWrapper; public class AbsenceNotice3LecturesEntriesStep extends BasicStep { private final boolean startPoint; + private final LecturesSecurityCallback secCallback; private final EditAbsenceNoticeWrapper noticeWrapper; - public AbsenceNotice3LecturesEntriesStep(UserRequest ureq) { - this(ureq, null, false); + public AbsenceNotice3LecturesEntriesStep(UserRequest ureq, LecturesSecurityCallback secCallback) { + this(ureq, null, secCallback, false); } - public AbsenceNotice3LecturesEntriesStep(UserRequest ureq, EditAbsenceNoticeWrapper noticeWrapper, boolean startPoint) { + public AbsenceNotice3LecturesEntriesStep(UserRequest ureq, EditAbsenceNoticeWrapper noticeWrapper, + LecturesSecurityCallback secCallback, boolean startPoint) { super(ureq); this.startPoint = startPoint; - setNextStep(new AbsenceNotice4ReasonStep(ureq)); + this.secCallback = secCallback; + setNextStep(new AbsenceNotice4ReasonStep(ureq, secCallback)); if(startPoint) { this.noticeWrapper = noticeWrapper; } else { @@ -65,6 +69,6 @@ public class AbsenceNotice3LecturesEntriesStep extends BasicStep { if(noticeWrapper != null) { runContext.put("absence", noticeWrapper); } - return new DatesLecturesEntriesStepController(ureq, wControl, form, runContext); + return new DatesLecturesEntriesStepController(ureq, wControl, form, runContext, secCallback); } } diff --git a/src/main/java/org/olat/modules/lecture/ui/wizard/AbsenceNotice4ReasonStep.java b/src/main/java/org/olat/modules/lecture/ui/wizard/AbsenceNotice4ReasonStep.java index 705f81a65b8..12bd855f418 100644 --- a/src/main/java/org/olat/modules/lecture/ui/wizard/AbsenceNotice4ReasonStep.java +++ b/src/main/java/org/olat/modules/lecture/ui/wizard/AbsenceNotice4ReasonStep.java @@ -26,6 +26,7 @@ import org.olat.core.gui.control.generic.wizard.BasicStep; import org.olat.core.gui.control.generic.wizard.PrevNextFinishConfig; import org.olat.core.gui.control.generic.wizard.StepFormController; import org.olat.core.gui.control.generic.wizard.StepsRunContext; +import org.olat.modules.lecture.ui.LecturesSecurityCallback; /** * @@ -35,8 +36,11 @@ import org.olat.core.gui.control.generic.wizard.StepsRunContext; */ public class AbsenceNotice4ReasonStep extends BasicStep { - public AbsenceNotice4ReasonStep(UserRequest ureq) { + private final LecturesSecurityCallback secCallback; + + public AbsenceNotice4ReasonStep(UserRequest ureq, LecturesSecurityCallback secCallback) { super(ureq); + this.secCallback = secCallback; setNextStep(new AbsenceNotice5ContactStep(ureq)); setI18nTitleAndDescr("wizard.reason.title", "wizard.reason.title"); } @@ -48,6 +52,6 @@ public class AbsenceNotice4ReasonStep extends BasicStep { @Override public StepFormController getStepController(UserRequest ureq, WindowControl wControl, StepsRunContext runContext, Form form) { - return new ReasonStepController(ureq, wControl, form, runContext); + return new ReasonStepController(ureq, wControl, form, runContext, secCallback); } } diff --git a/src/main/java/org/olat/modules/lecture/ui/wizard/DatesLecturesEntriesStepController.java b/src/main/java/org/olat/modules/lecture/ui/wizard/DatesLecturesEntriesStepController.java index b38f295d0c0..4f52943d0be 100644 --- a/src/main/java/org/olat/modules/lecture/ui/wizard/DatesLecturesEntriesStepController.java +++ b/src/main/java/org/olat/modules/lecture/ui/wizard/DatesLecturesEntriesStepController.java @@ -28,6 +28,7 @@ import org.olat.core.gui.control.generic.wizard.StepFormBasicController; import org.olat.core.gui.control.generic.wizard.StepsEvent; import org.olat.core.gui.control.generic.wizard.StepsRunContext; import org.olat.modules.lecture.model.EditAbsenceNoticeWrapper; +import org.olat.modules.lecture.ui.LecturesSecurityCallback; import org.olat.modules.lecture.ui.coach.EditDatesLecturesEntriesController; /** @@ -37,14 +38,15 @@ import org.olat.modules.lecture.ui.coach.EditDatesLecturesEntriesController; * */ public class DatesLecturesEntriesStepController extends StepFormBasicController { - + private final EditDatesLecturesEntriesController editCtrl; - public DatesLecturesEntriesStepController(UserRequest ureq, WindowControl wControl, Form rootForm, StepsRunContext runContext) { + public DatesLecturesEntriesStepController(UserRequest ureq, WindowControl wControl, Form rootForm, StepsRunContext runContext, + LecturesSecurityCallback secCallback) { super(ureq, wControl, rootForm, runContext, LAYOUT_VERTICAL, null); - + EditAbsenceNoticeWrapper noticeWrapper = (EditAbsenceNoticeWrapper)getFromRunContext("absence"); - editCtrl = new EditDatesLecturesEntriesController(ureq, wControl, rootForm, noticeWrapper, true); + editCtrl = new EditDatesLecturesEntriesController(ureq, wControl, rootForm, noticeWrapper, secCallback, true); listenTo(editCtrl); initForm(ureq); } diff --git a/src/main/java/org/olat/modules/lecture/ui/wizard/ReasonStepController.java b/src/main/java/org/olat/modules/lecture/ui/wizard/ReasonStepController.java index b6ec2566ea4..68aa2b44c7b 100644 --- a/src/main/java/org/olat/modules/lecture/ui/wizard/ReasonStepController.java +++ b/src/main/java/org/olat/modules/lecture/ui/wizard/ReasonStepController.java @@ -28,6 +28,7 @@ import org.olat.core.gui.control.generic.wizard.StepFormBasicController; import org.olat.core.gui.control.generic.wizard.StepsEvent; import org.olat.core.gui.control.generic.wizard.StepsRunContext; import org.olat.modules.lecture.model.EditAbsenceNoticeWrapper; +import org.olat.modules.lecture.ui.LecturesSecurityCallback; import org.olat.modules.lecture.ui.coach.EditReasonController; /** @@ -40,10 +41,11 @@ public class ReasonStepController extends StepFormBasicController { private final EditReasonController editReasonCtrl; - public ReasonStepController(UserRequest ureq, WindowControl wControl, Form rootForm, StepsRunContext runContext) { + public ReasonStepController(UserRequest ureq, WindowControl wControl, Form rootForm, StepsRunContext runContext, + LecturesSecurityCallback secCallback) { super(ureq, wControl, rootForm, runContext, LAYOUT_VERTICAL, null); EditAbsenceNoticeWrapper noticeWrapper = (EditAbsenceNoticeWrapper)getFromRunContext("absence"); - editReasonCtrl = new EditReasonController(ureq, wControl, rootForm, noticeWrapper, true); + editReasonCtrl = new EditReasonController(ureq, wControl, rootForm, noticeWrapper, secCallback, true); listenTo(editReasonCtrl); initForm(ureq); } diff --git a/src/test/java/org/olat/modules/lecture/manager/LectureBlockDAOTest.java b/src/test/java/org/olat/modules/lecture/manager/LectureBlockDAOTest.java index bdbfd2d26a2..d1a28d8cb38 100644 --- a/src/test/java/org/olat/modules/lecture/manager/LectureBlockDAOTest.java +++ b/src/test/java/org/olat/modules/lecture/manager/LectureBlockDAOTest.java @@ -197,6 +197,8 @@ public class LectureBlockDAOTest extends OlatTestCase { searchParams.setSearchString("Hello"); searchParams.setStartDate(new Date()); searchParams.setTeacher(id); + searchParams.setMasterCoach(id); + searchParams.setManager(id); List<LectureBlock> blocks = lectureBlockDao.searchLectureBlocks(searchParams); Assert.assertNotNull(blocks); -- GitLab