diff --git a/src/main/java/org/olat/modules/lecture/AbsenceNoticeSearchParameters.java b/src/main/java/org/olat/modules/lecture/AbsenceNoticeSearchParameters.java
index 2bebf1e58d812eca178101b61c82f4d9e38dedc5..ea5d603f73db595c8d8217a67013acca817f6ef9 100644
--- a/src/main/java/org/olat/modules/lecture/AbsenceNoticeSearchParameters.java
+++ b/src/main/java/org/olat/modules/lecture/AbsenceNoticeSearchParameters.java
@@ -70,6 +70,7 @@ public class AbsenceNoticeSearchParameters {
 		if(types == null || types.isEmpty()) {
 			typesList.clear();
 		} else {
+			typesList.clear();
 			typesList.addAll(types);
 		}
 	}
diff --git a/src/main/java/org/olat/modules/lecture/manager/AbsenceNoticeDAO.java b/src/main/java/org/olat/modules/lecture/manager/AbsenceNoticeDAO.java
index 516718c238a68a0e20407f41a3dcc21be2b1636a..e98615051a5b892fd40165e999027df4e4747274 100644
--- a/src/main/java/org/olat/modules/lecture/manager/AbsenceNoticeDAO.java
+++ b/src/main/java/org/olat/modules/lecture/manager/AbsenceNoticeDAO.java
@@ -225,9 +225,11 @@ public class AbsenceNoticeDAO {
 			  .append("(notice.startDate>=:startDate and notice.startDate<=:endDate)")
 			  .append(" or ")
 			  .append("(notice.endDate>=:startDate and notice.endDate<=:endDate)")
-			  .append(" or ")
-			  .append("(notice.startDate is null and notice.endDate is null)")
 			  .append(")");
+		} else if(searchParams.getStartDate() != null) {
+			sb.and().append(" notice.startDate>=:startDate");
+		} else if(searchParams.getEndDate() != null) {
+			sb.and().append(" notice.endDate<=:endDate");
 		}
 		
 		if(searchParams.getParticipant() != null) {
diff --git a/src/main/java/org/olat/modules/lecture/manager/AbsenceNoticeToLectureBlockDAO.java b/src/main/java/org/olat/modules/lecture/manager/AbsenceNoticeToLectureBlockDAO.java
index 0044ee5ba8a5ac87696af96bc766ae11c047c55e..ef8a58fa2736a233878c36976ddb2c52a551d3f1 100644
--- a/src/main/java/org/olat/modules/lecture/manager/AbsenceNoticeToLectureBlockDAO.java
+++ b/src/main/java/org/olat/modules/lecture/manager/AbsenceNoticeToLectureBlockDAO.java
@@ -53,16 +53,18 @@ public class AbsenceNoticeToLectureBlockDAO {
 		return rel;
 	}
 	
-	public List<LectureBlockRollCall> getRollCallsByLectureBlock(AbsenceNotice notice) {
+	public List<LectureBlockRollCall> searchRollCallsByLectureBlock(AbsenceNotice notice) {
 		QueryBuilder sb = new QueryBuilder();
 		sb.append("select rollCall from absencenoticetolectureblock noticeToBlock")
 		  .append(" inner join noticeToBlock.lectureBlock as block")
 		  .append(" inner join lectureblockrollcall as rollCall on (rollCall.lectureBlock.key=block.key)")
-		  .append(" where noticeToBlock.absenceNotice.key=:noticeKey");
+		  .append(" left join fetch rollCall.absenceNotice as currentNotice")
+		  .append(" where rollCall.identity.key=:identityKey and noticeToBlock.absenceNotice.key=:noticeKey");
 		
 		return dbInstance.getCurrentEntityManager()
 				.createQuery(sb.toString(), LectureBlockRollCall.class)
 				.setParameter("noticeKey", notice.getKey())
+				.setParameter("identityKey", notice.getIdentity().getKey())
 				.getResultList();
 	}
 	
diff --git a/src/main/java/org/olat/modules/lecture/manager/AbsenceNoticeToRepositoryEntryDAO.java b/src/main/java/org/olat/modules/lecture/manager/AbsenceNoticeToRepositoryEntryDAO.java
index 931ab2b22b8b4f9d8ba4eb001a174dd1b1746785..588fce843cfb7f5c1627ba8b64f4dbeb255c2618 100644
--- a/src/main/java/org/olat/modules/lecture/manager/AbsenceNoticeToRepositoryEntryDAO.java
+++ b/src/main/java/org/olat/modules/lecture/manager/AbsenceNoticeToRepositoryEntryDAO.java
@@ -24,6 +24,7 @@ import java.util.List;
 
 import javax.persistence.TemporalType;
 
+import org.olat.basesecurity.IdentityRef;
 import org.olat.core.commons.persistence.DB;
 import org.olat.core.commons.persistence.QueryBuilder;
 import org.olat.modules.lecture.AbsenceNotice;
@@ -82,20 +83,29 @@ public class AbsenceNoticeToRepositoryEntryDAO {
 	 * @param notice
 	 * @return
 	 */
-	public List<LectureBlockRollCall> getRollCallsByRepositoryEntry(AbsenceNotice notice) {
+	public List<LectureBlockRollCall> searchRollCallsByRepositoryEntry(AbsenceNotice notice) {
 		QueryBuilder sb = new QueryBuilder();
 		sb.append("select rollCall from absencenoticetoentry noticeToEntry")
 		  .append(" inner join noticeToEntry.entry as entry")
 		  .append(" inner join noticeToEntry.absenceNotice as notice")
 		  .append(" inner join lectureblock as block on (block.entry.key=entry.key)")
 		  .append(" inner join lectureblockrollcall as rollCall on (rollCall.lectureBlock.key=block.key)")
-		  .append(" inner join fetch rollCall.absenceNotice as currentNotice")
-		  .append(" where notice.key=:noticeKey and ");
-		AbsenceNoticeDAO.noticeBlockDates(sb);
+		  .append(" left join fetch rollCall.absenceNotice as currentNotice")
+		  .append(" where notice.key=:noticeKey and rollCall.identity.key=:identityKey")
+		  .append(" and (")
+		  .append("  (block.startDate>=:startDate and block.endDate<=:endDate)")
+		  .append("  or ")
+		  .append("  (block.startDate<=:startDate and block.startDate>=:endDate)")
+		  .append("  or ")
+		  .append("  (block.endDate<=:startDate and block.endDate>=:endDate)")
+		  .append(" )");
 		
 		return dbInstance.getCurrentEntityManager()
 				.createQuery(sb.toString(), LectureBlockRollCall.class)
 				.setParameter("noticeKey", notice.getKey())
+				.setParameter("identityKey", notice.getIdentity().getKey())
+				.setParameter("startDate", notice.getStartDate())
+				.setParameter("endDate", notice.getEndDate())
 				.getResultList();
 	}
 	
@@ -104,11 +114,11 @@ public class AbsenceNoticeToRepositoryEntryDAO {
 	 * @param notice
 	 * @return
 	 */
-	public List<LectureBlockRollCall> getRollCallsOfAllEntries(AbsenceNotice notice) {
+	public List<LectureBlockRollCall> searchRollCallsOfAllEntries(IdentityRef identity, Date start, Date end) {
 		QueryBuilder sb = new QueryBuilder();
-		sb.append("select rollCall from lectureblock block")
-		  .append(" inner join lectureblockrollcall as rollCall on (rollCall.lectureBlock.key=block.key)")
-		  .append(" inner join fetch rollCall.absenceNotice as currentNotice")
+		sb.append("select rollCall from lectureblockrollcall as rollCall")
+		  .append(" inner join rollCall.lectureBlock as block")
+		  .append(" left join fetch rollCall.absenceNotice as currentNotice")
 		  .append(" where rollCall.identity.key=:identityKey")
 		  .append(" and (")
 		  .append("  (block.startDate>=:startDate and block.endDate<=:endDate)")
@@ -120,9 +130,9 @@ public class AbsenceNoticeToRepositoryEntryDAO {
 		
 		return dbInstance.getCurrentEntityManager()
 				.createQuery(sb.toString(), LectureBlockRollCall.class)
-				.setParameter("identityKey", notice.getIdentity().getKey())
-				.setParameter("startDate", notice.getStartDate(), TemporalType.TIMESTAMP)
-				.setParameter("endDate", notice.getEndDate(), TemporalType.TIMESTAMP)
+				.setParameter("identityKey", identity.getKey())
+				.setParameter("startDate", start, TemporalType.TIMESTAMP)
+				.setParameter("endDate", end, TemporalType.TIMESTAMP)
 				.getResultList();
 	}
 
diff --git a/src/main/java/org/olat/modules/lecture/manager/LectureServiceImpl.java b/src/main/java/org/olat/modules/lecture/manager/LectureServiceImpl.java
index 3d58ecdce90b4015086dccc50a0334f3b2ff8cd8..21b61c73382a0ff7577002f78b9eb5e4da4e9fad 100644
--- a/src/main/java/org/olat/modules/lecture/manager/LectureServiceImpl.java
+++ b/src/main/java/org/olat/modules/lecture/manager/LectureServiceImpl.java
@@ -662,15 +662,22 @@ public class LectureServiceImpl implements LectureService, UserDataDeletable, De
 		}
 		Set<LectureBlockRollCall> currentRollCallSet = new HashSet<>(currentRollCalls);
 		
+		IdentityRef identity = notice.getIdentity();
+		Date start = notice.getStartDate();
+		Date end = notice.getEndDate();
+		
 		List<LectureBlockRollCall> rollCalls;
 		switch(notice.getNoticeTarget()) {
-			case lectureblocks: rollCalls = absenceNoticeToLectureBlockDao.getRollCallsByLectureBlock(notice); break;
-			case entries: rollCalls = absenceNoticeToRepositoryEntryDao.getRollCallsByRepositoryEntry(notice); break;
-			case allentries: rollCalls = absenceNoticeToRepositoryEntryDao.getRollCallsOfAllEntries(notice); break;
+			case lectureblocks: rollCalls = absenceNoticeToLectureBlockDao.searchRollCallsByLectureBlock(notice); break;
+			case entries: rollCalls = absenceNoticeToRepositoryEntryDao.searchRollCallsByRepositoryEntry(notice); break;
+			case allentries: rollCalls = absenceNoticeToRepositoryEntryDao.searchRollCallsOfAllEntries(identity, start, end); break;
 			default: rollCalls = Collections.emptyList();
 		}
 		
 		for(LectureBlockRollCall rollCall:rollCalls) {
+			if(!rollCall.getIdentity().equals(notice.getIdentity())) {
+				continue;// this is a paranoia check, the search methods already do this
+			}
 			if(currentRollCallSet.contains(rollCall)) {
 				currentRollCallSet.remove(rollCall);
 			} else {
diff --git a/src/main/java/org/olat/modules/lecture/model/EditAbsenceNoticeWrapper.java b/src/main/java/org/olat/modules/lecture/model/EditAbsenceNoticeWrapper.java
index c5d60a7a1f981813e446abc409bd735c420b1102..51e08888df5e0e8bf6b73ce68a7ba670e57261f1 100644
--- a/src/main/java/org/olat/modules/lecture/model/EditAbsenceNoticeWrapper.java
+++ b/src/main/java/org/olat/modules/lecture/model/EditAbsenceNoticeWrapper.java
@@ -67,6 +67,10 @@ public class EditAbsenceNoticeWrapper {
 	private List<VFSItem> attachmentsToDelete = new ArrayList<>();
 	
 	private EditAbsenceNoticeWrapper(AbsenceNotice notice) {
+		wrap(notice);
+	}
+	
+	public void wrap(AbsenceNotice notice) {
 		absenceNotice = notice;
 		identity = notice.getIdentity();
 		startDate = notice.getStartDate();
diff --git a/src/main/java/org/olat/modules/lecture/ui/AppealListRepositoryController.java b/src/main/java/org/olat/modules/lecture/ui/AppealListRepositoryController.java
index 991db9200704af9d84778c287ced0a38d0589c16..f01f9b808905715e754ce1c1faeb6137a1b8a52c 100644
--- a/src/main/java/org/olat/modules/lecture/ui/AppealListRepositoryController.java
+++ b/src/main/java/org/olat/modules/lecture/ui/AppealListRepositoryController.java
@@ -205,6 +205,10 @@ public class AppealListRepositoryController extends FormBasicController {
 		loadModel(true);
 	}
 	
+	public void reloadModel() {
+		loadModel(false);
+	}
+	
 	protected void loadModel(boolean reset) {
 		searchParams.setEntry(entry);
 		searchParams.setCalledIdentity(profiledIdentity);
diff --git a/src/main/java/org/olat/modules/lecture/ui/ParticipantLecturesOverviewController.java b/src/main/java/org/olat/modules/lecture/ui/ParticipantLecturesOverviewController.java
index 72aa51bf7f995bc8ee24351c0a249a960960b70d..a8ff169cadbdf881354882420523671784bc1c64 100644
--- a/src/main/java/org/olat/modules/lecture/ui/ParticipantLecturesOverviewController.java
+++ b/src/main/java/org/olat/modules/lecture/ui/ParticipantLecturesOverviewController.java
@@ -310,7 +310,7 @@ public class ParticipantLecturesOverviewController extends FormBasicController i
 		return new ArrayList<>(results.values());
 	}
 	
-	private void loadModel() {
+	public void loadModel() {
 		List<LectureBlockStatistics> statistics = lectureService.getParticipantLecturesStatistics(assessedIdentity);
 		if(filterByEntries != null && !filterByEntries.isEmpty()) {
 			Set<Long> acceptedEntries = filterByEntries.stream()
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 00becb55136e6c185ef4479a18688d15415d0ff2..736806738d013f76c7a3a5387d3a30b3c666432f 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
@@ -324,6 +324,7 @@ planned.lectures=Geplante Lektionen
 previous.participant=Zur\u00FCck zum letzten Teilnehmer
 private.dates=$org.olat.repository\:cif.private.dates
 profile=Profil
+prolongate.notice=Verlängern
 public.dates=$org.olat.repository\:cif.public.dates
 rate.error.title=Die Anwesenheitsquote liegt unter dem erforderlichen Limit.
 rate.warning.title=Die Anwesenheitsquote ist nah am erforderlichen Limit.
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 2ee51ee8aa577f83ea9f546be1adf8f51e71e239..87aef9093b459fb69635b185de90ef9105ed689e 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
@@ -323,6 +323,7 @@ planned.lectures=Planned lectures
 previous.participant=Back to previous participant
 private.dates=$org.olat.repository\:cif.private.dates
 profile=Profile
+prolongate.notice=Prolong
 public.dates=$org.olat.repository\:cif.public.dates
 rate.error.title=The attendance rate is under the mandatory limit.
 rate.warning.title=The attendance rate is close to the mandatory limit.
diff --git a/src/main/java/org/olat/modules/lecture/ui/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/modules/lecture/ui/_i18n/LocalStrings_fr.properties
index c3e515a28f53fd506acdd631b8de8f6dd42bb66f..d2a6f0e2141a1ef7e6838466bed772152c01a781 100644
--- a/src/main/java/org/olat/modules/lecture/ui/_i18n/LocalStrings_fr.properties
+++ b/src/main/java/org/olat/modules/lecture/ui/_i18n/LocalStrings_fr.properties
@@ -1,14 +1,22 @@
-#Wed Aug 21 10:55:15 CEST 2019
+#Wed Aug 21 18:47:34 CEST 2019
 absence.category=Raison de l'absence
 absence.category.copied=La raison de l'absence a \u00E9t\u00E9 copi\u00E9 avec succ\u00E8s.
 absence.category.copy={0} (copie)
 absence.category.description=Description
 absence.category.in.use=Cette raison d'absence est encore utilis\u00E9 par certaines notices d'absences et ne peut pas \u00EAtre effac\u00E9e.
 absence.category.title=Raison de l'absence
+absences.batch.authorize=Excuser des absences
 absences.title=Liste d'absences
 active=Actif
+add.absence=Saisir une nouvelle absence
+add.absence.category=Ajouter une justification d'absence
+add.absence.title=Saisir une absence
 add.assessment.mode=Marqu\u00E9 comme \u00E9valuation
+add.dispensation=Saisir une nouvelle dispense
+add.dispensation.title=Saisir une dispense
 add.lecture=Cr\u00E9er un nouveau cours bloc
+add.notice.absence=Saisir un nouvel avis d'absence
+add.notice.absence.title=Saisir un avis d'absence
 add.reason=Cr\u00E9er une justification
 admin.menu.title=Cours blocs
 admin.menu.title.alt=Administration des cours blocs et absences
@@ -42,6 +50,7 @@ appeals.title=Liste de recours
 appeals.update.title=Edit {0} recours
 archive.entry=Archivage
 assessment.tool=Outil d'\u00E9valuation
+attachment.upload=Certificat m\u00E9dical, justification, etc
 attendance.list=Liste d'absences
 attendance.list.title=Liste d'absence\: {0}
 attendance.list.to.sign=Liste de pr\u00E9sence
@@ -55,16 +64,25 @@ bulk.hint=Vous pouvez entrer une liste de noms d'utilisateurs ou d'adresses cour
 cancel.lecture.blocks=Annuler le cours bloc
 cancelled=Annul\u00E9
 close.lecture.blocks=Termin\u00E9 le cours bloc
+close.lecture.blocks.confirmation={0} cours seront clos le {1}.
+close.lecture.blocks.day=Clore les absences de {0}
 closed=Termin\u00E9
 coach.absence=Absences
 coach.appeals=Recours
 coach.cockpit=Cockpit
+coach.dispensation=Avis d'absences / dispenses
 coach.lectures=Cours
+coach.lectures.search=Recherche d'utilisateurs
+coach.report=Rapport
 cockpit.absences=Absences
 cockpit.date=pour {0}
+cockpit.day.overview=Aper\u00E7u journalier
 cockpit.lectures=Cours
 cockpit.lectures.day.list=Vous n'avez pas de cours ce jour-l\u00E0.
 cockpit.pending.day={0} {1} ({2} cours)
+cockpit.pending.day.plural={0} {1} ({2} cours)
+cockpit.pending.days=Un certain nombre de cours n'ont pas \u00E9t\u00E9 clos. Enregistrez s'il vous pla\u00EEt les absences pour la journ\u00E9e suivante\:
+cockpit.pending.days.plural=Un certain nombre de cours n'ont pas \u00E9t\u00E9 clos. Enregistrez s'il vous pla\u00EEt les absences pour les jours suivants\:
 config.calculate.attendance.rate=Calculer le taux de pr\u00E9sence
 config.override=Permettre de modifier la configuration standard
 config.override.no=Non
@@ -73,10 +91,13 @@ config.rollcall.enabled=Activer le contr\u00F4le du taux de pr\u00E9sence
 config.sync.course.calendar=Synchroniser le calendrier du cours
 config.sync.participant.calendar=Synchroniser le calendrier des participants
 config.sync.teacher.calendar=Synchroniser le calendrier des charg\u00E9s de cours
+confirm.delete.absence.category=Voulez-vous vraiment effacer la justification d'absence "{0}"?
 confirm.delete.assessment.mode.text=Voulez-vous vraiment effacer l'examen de ce cours bloc "{0}"?
 confirm.delete.assessment.mode.title=Effacer l'examen
 confirm.delete.lectures=Voulez-vous vraiment effacer ce cours block "{0}"?
 confirm.delete.reason=Voulez-vous vraiment effacer cette justification "{0}"?
+contact.teachers=Contacter les charg\u00E9s de cours
+contact.teachers.list.name=Charg\u00E9s de cours
 copy=Copier
 current.lecture=Cours bloc actuel
 date.end=$org.olat.repository\:cif.date.end
@@ -90,11 +111,18 @@ delete.lectures.title=Effacer un cours bloc
 delete.title=Effacer une justification
 detailled.list=Liste d\u00E9taill\u00E9e
 details=D\u00E9tails
+dispensations.title=Avis d'absences / dispenses
 done=Termin\u00E9
+edit.absence.category=Editer la justification d'absence
 edit.assessment.mode=Editer la configuration d'\u00E9valuation
 edit.participant.rate=Editer la valeur seuil personalis\u00E9e
 edit.reason=Editer la justification
+edit.type.absence=Editer l'absence
+edit.type.dispensation=Editer la dispense
+edit.type.notice.absence=Editer l'avis d'absence
 effective.lectures=Le\u00E7ons effectives
+empty.absences.list=Il n'y a pas d'absences ou de dispenses qui correspondent \u00E0 vos crit\u00E8res de recherche.
+empty.appeals.list=Il n'y a pas de recours qui correspondent \u00E0 vos crit\u00E8res de recherche.
 empty.lectures.list=La liste est vide
 empty.repository.entry.lectures=Vous n'avez pas encore de le\u00E7ons dans ce cours.
 empty.table.current.lectures.blocks=Vous n'avez aucun cours bloc actuellement.
@@ -103,10 +131,13 @@ empty.table.lectures.blocks.admin=Aucun cours bloc n'a \u00E9t\u00E9 cr\u00E9\u0
 empty.table.participant.list=Aucun contr\u00F4le de pr\u00E9sence n'a \u00E9t\u00E9 effectu\u00E9 pour ce cours jusqu'\u00E0 maintenant.
 entry.rate=Valeur seuil pour le cours
 error.atleastone.lecture=Choisissez au moins un cours bloc s'il vous pla\u00EEt.
+error.collision=Il y a d\u00E9j\u00E0 une absence pour ces dates.
 error.integer.between=La valeur doit \u00EAtre un nombre entre {0} et {1}
 error.integer.positive=La valeur doit \u00EAtre un nombre positif.
 error.reason.mandatory=La justification est requis.
 error.search.form.notempty=Veuillez remplir au minimum un champ du formulaire avec deux caract\u00E8res s'il vous pla\u00EEt. 
+error.unauthorized.absence.msg=<strong>Une</strong> absence non-excus\u00E9e a \u00E9t\u00E9 trouv\u00E9e.
+error.unauthorized.absences.msg=<strong>{0}</strong> absences non-excus\u00E9es ont \u00E9t\u00E9 trouv\u00E9es.
 evening=Soir\u00E9e
 export.footer.lectures.hint=x \= Absence
 export.header.entry=Cours\: {0}
@@ -156,6 +187,9 @@ lecture.can.override.standard.configuration=Permettre de modifier la configurati
 lecture.compulsory=Pr\u00E9sence obligatoire
 lecture.count.authorized.absence.attendant=Compter les absences excus\u00E9es comme pr\u00E9sent
 lecture.course.admin.title=Configuration des cours blocs et absences du cours
+lecture.daily.batch.absence=Saisie journali\u00E8re des absences
+lecture.daily.batch.absence.day=Oui, autoriser la saisie des absences de tous les cours blocs d'une journ\u00E9e
+lecture.daily.batch.absence.start=Non, au d\u00E9but des cours blocs seulement
 lecture.date=Date
 lecture.deleted=Cours bloc a \u00E9t\u00E9 effac\u00E9 avec succ\u00E8s.
 lecture.descr=Description
@@ -164,7 +198,13 @@ lecture.from.to=Depuis
 lecture.from.to.format={0} jusqu'\u00E0 {1}
 lecture.groups=Cours / groupes / curriculum
 lecture.location=Lieu
+lecture.mastercoach.can.authorize.absence=Les professeurs peuvent excuser les absences
+lecture.mastercoach.can.authorize.appeal=Les professeurs peuvent octroyer un recours
+lecture.mastercoach.can.record.notice=Les professeurs peuvent saisir les avis d'absences
+lecture.mastercoach.can.see.absence=Les professeurs peuvent voir les absences
+lecture.mastercoach.can.see.appeal=Les professeurs peuvent voir les recours
 lecture.owner.can.view.all.curriculum.elements=Les propri\u00E9taires peuvent voir tous les cours de l'\u00E9l\u00E9ment de curriculum
+lecture.participant.can.notice=Les participants peuvent notifier une absence
 lecture.preparation=Pr\u00E9paration/suivi
 lecture.reminder.enabled=Activ\u00E9 la fonction de rappel
 lecture.reminder.period=D\u00E9lai de rappel
@@ -178,12 +218,17 @@ lecture.status.partially.done.enabled=Activer la possibilit\u00E9 de le\u00E7ons
 lecture.taxonomy=Taxonomie
 lecture.teacher=Charg\u00E9s de cours
 lecture.teacher.can.authorize.absence=Les charg\u00E9s de cours peuvent excuser les absences
+lecture.teacher.can.authorize.appeal=Les charg\u00E9s de cours peuvent octroyer un recours
+lecture.teacher.can.see.appeal=Les charg\u00E9s de cours peuvent voir les recours
 lecture.teacher.reminder.body=<p>Ch\u00E8re charg\u00E9e de cours<br>Cher charg\u00E9 de cours</p><p>Nous aimerions vous rappeler que vous devez encore noter les absences pour un cours bloc. Avec le lien ci-dessous vous m\u00E8nera directement au cours bloc en question\:<br><a href\='{3}'>{3}</a></p><p>Merci beaucoup\!</p><p>Votre administrateur de cours</p>
 lecture.teacher.reminder.subject=Rappel cours bloc "{0}"
 lecture.time=Temps
 lecture.time.from=de
 lecture.time.until=jusqu'\u00E0
 lecture.title=Titre
+lectures.admin.absences.categories=Justifications d'absences
+lectures.admin.permissions=Autorisations
+lectures.admin.permissions.title=Autorisations pour charg\u00E9s de cours et professeurs
 lectures.admin.reasons=Justifications absences
 lectures.admin.report=Rapport cours blocs
 lectures.admin.settings=Configuration de l'administration des cours blocs et des absences
@@ -202,6 +247,8 @@ log.change.admission.date=Date d'inscription modifi\u00E9e\: {0}
 log.change.rate=Valeur seuil modifi\u00E9e\: {0}
 log.remove.admission.date=Date d'inscription enlev\u00E9e
 log.remove.rate=Valeur seuil enlev\u00E9e
+mail.body=Message
+mail.subject=Sujet
 managed.flags.lecture.block.all=Gestion externe compl\u00E8te
 managed.flags.lecture.block.compulsory=Obligatoire
 managed.flags.lecture.block.dates=Date
@@ -218,26 +265,50 @@ managed.flags.lecture.block.title=Titre
 menu.my.lectures=Absences
 menu.my.lectures.alt=Cours blocs et absences
 morning=Matin\u00E9e
+multi.rollcall.callee.cmc.title=Saisie multiple des absences de cours <small>pour {0} ({1} cours blocs)</small>
+multi.rollcall.callee.title=Aper\u00E7u journalier
 multi.rollcall.callee.title.for=pour {0}
+multi.rollcall.title=Saisie multiple de cours
+multi.rollcall.title.for=pour {0} ({1} cours blocks)
 new.appeal.title=Nouvelle notification de recours
 next.participant=Participant suivant
 no.teachers=Pas encore de charg\u00E9 de cours disponible
+not.authorized.absence=Injustifi\u00E9
+notice.dates.lectures.title=Contexte
+notice.end.date=Date de fin
 notice.reason.title=Raison de l'absence
+notice.search=Recherche
+notice.start.date=Date de d\u00E9but
+noticed.absence.authorized=Excus\u00E9
 noticed.absence.unauthorized=Absent
+noticed.autorized.yes=Excus\u00E9
+noticed.category=Justification
+noticed.dispensation=Dispense
 noticed.duration=Dur\u00E9e
+noticed.duration.days=Choix de la date
+noticed.duration.exact=Exact (avec l'heure)
 noticed.duration.today=Aujourd'hui
 noticed.entries=Cours
 noticed.identity=Personne absente
 noticed.lectures=Cours-blocs
+noticed.notice.absence=Avis d'absence
 noticed.reason=Commentaire
 noticed.target.all=Tous les cours
 noticed.target.courses=Cours choisis
 noticed.target.lectureblocks=Cours-blocs choisis
+noticed.targets=Absent pour
 noticed.teachers=Charg\u00E9s de cours
 noticed.till=jusqu'\u00E0
 noticed.type=Type
+noticed.type.absence=Sans avis pr\u00E9alable
+noticed.type.dispensation=Dispens\u00E9
+noticed.type.notified=Avis d'absence
+num.alert.absence.explain={0} absence(s) injustifi\u00E9e(s)
+num.warnings.dispensation.explain={0} dispense(s) injustifi\u00E9e(s)
+num.warnings.notice.absence.explain={0} avis d'absence(s) injustifi\u00E9e(s)
 open=Ouvert
 open.course=Cours ouvert
+open.specific.course=Ouvrir "{0}"
 override.lecture=Passer outre la gestion ext\u00E9rieure du cours
 partiallydone=En partie termin\u00E9
 participant.rate=Valeur seuil
@@ -253,6 +324,7 @@ planned.lectures=Cours blocs pr\u00E9vus
 previous.participant=Participant pr\u00E9c\u00E9dent
 private.dates=$org.olat.repository\:cif.private.dates
 profile=Profil
+prolongate.notice=Prolonger
 public.dates=$org.olat.repository\:cif.public.dates
 rate.error.title=Le taux de pr\u00E9sence se situe sous la limite obligatoire.
 rate.warning.title=Le taux de pr\u00E9sence est proche de la limite obligatoire.
@@ -275,8 +347,10 @@ repo.settings=Configuration
 results=R\u00E9sultats
 rollcall=Contr\u00F4le de pr\u00E9sence
 rollcall.absence=Absence
+rollcall.absence.notice=Avis d'absence
 rollcall.coach.hint=Note\: les absences sont enregistr\u00E9es pour chaque le\u00E7on. Si plus de la moiti\u00E9 d'une le\u00E7on est manqu\u00E9e, elle sera consid\u00E9r\u00E9e comme une absence.
 rollcall.comment=Remarque
+rollcall.dispensation=Dispense
 rollcall.status=Status du cours bloc
 rollcall.tooltip.absence=Absence
 rollcall.tooltip.authorized.absence=Absence excus\u00E9e
@@ -306,6 +380,7 @@ search.teachers=Recherche par charg\u00E9s de cours
 send=Envoyer
 several.entries=Plusieurs
 site.title=Gestion des cours blocs
+site.title.alt=Gestion des cours blocs
 start.desktop=Bureau
 start.label=Noter les absences
 start.mobile=Mobile
@@ -314,6 +389,8 @@ sync.course.calendar.enabled=Synchroniser le calendrier du cours
 sync.participants.calendar.enabled=Synchroniser le calendrier des participants
 sync.teachers.calendar.enabled=Synchroniser le calendrier des charg\u00E9s de cours
 table.header.absence=Pr\u00E9sences
+table.header.absences.alert=Nombre d'absences injustifi\u00E9es
+table.header.absences.warning=Nombre de dispenses et avis d'absences injustifi\u00E9es
 table.header.absent.lectures=Absences
 table.header.actions=<i class\='o_icon o_icon_actions o_icon-lg'> </i>
 table.header.appeal.status=Recours
@@ -361,6 +438,7 @@ table.header.log.effective.lectures=Le\u00E7ons effectives
 table.header.log.planned.lectures=Le\u00E7ons pr\u00E9vues
 table.header.log.user=Utilisateur
 table.header.notice.type=Type
+table.header.num.absences=Nombre de participants absents
 table.header.num.lecture.block=Cours
 table.header.num.participants=Nombre de participants
 table.header.num.presences=Nombre de participants pr\u00E9sents
@@ -391,9 +469,13 @@ tool.teacher=Comme charg\u00E9 de cours
 tools=Action
 tools.import.table=Importer des cours blocs depuis Excel
 total=Total
+unauthorized.filter=Injustifi\u00E9
+unauthorized.filter.label=Afficher
 unoverride.lecture=Retour en gestion ext\u00E9rieur
 upto=jusqu'\u00E0 {0}
 user.overview.appeals=Recours
+user.overview.dispensation=Dispenses
+user.overview.lectures=Cours et absences
 user.profil=Profil de l'utilisateur
 warning.choose.at.least.one.appeal=S'il-vous-pla\u00EEt, s\u00E9lectionnez au moins un recours.
 warning.edit.lecture=Le contr\u00F4le d'absence est d\u00E9sactiv\u00E9.
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 9744dbd22f3750abc5cbefd1717bdb09aa3d754f..aa7d782f283dac64c3d508f9376818b865f92536 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
@@ -60,6 +60,7 @@ public class AbsencesController extends BasicController {
 	private Link addAbsenceButton;
 	private VelocityContainer mainVC;
 
+	private final Roles roles;
 	private final LecturesSecurityCallback secCallback;
 	private final AbsenceNoticeSearchParameters searchParams = new AbsenceNoticeSearchParameters();
 	
@@ -74,6 +75,7 @@ public class AbsencesController extends BasicController {
 		super(ureq, wControl, Util.createPackageTranslator(LectureRepositoryAdminController.class, ureq.getLocale()));
 		
 		this.secCallback = secCallback;
+		this.roles = ureq.getUserSession().getRoles();
 		searchParams.addTypes(AbsenceNoticeType.absence);
 		searchParams.setViewAs(getIdentity(), ureq.getUserSession().getRoles(), secCallback.viewAs());
 		searchParams.setLinkedToRollCall(true);
@@ -95,14 +97,13 @@ public class AbsencesController extends BasicController {
 		
 		putInitialPanel(mainVC);
 		noticesListCtlr.loadModel(searchParams);
-		loadUnauthorizedAbsences(ureq);
+		loadUnauthorizedAbsences();
 	}
 	
-	private void loadUnauthorizedAbsences(UserRequest ureq) {
+	private void loadUnauthorizedAbsences() {
 		AbsenceNoticeSearchParameters unauthorizedSearchParams = new AbsenceNoticeSearchParameters();
 		unauthorizedSearchParams.addTypes(AbsenceNoticeType.absence);
 		unauthorizedSearchParams.setLinkedToRollCall(true);
-		Roles roles = ureq.getUserSession().getRoles();
 		unauthorizedSearchParams.setViewAs(getIdentity(), roles, secCallback.viewAs());
 
 		List<AbsenceNoticeInfos> unauthorizedAbsences = lectureService.searchAbsenceNotices(unauthorizedSearchParams);
@@ -152,6 +153,11 @@ public class AbsencesController extends BasicController {
 		}
 	}
 	
+	protected void reloadModels() {
+		noticesListCtlr.reloadModel();
+		loadUnauthorizedAbsences();
+	}
+	
 	private void doSearch(SearchAbsenceNoticeEvent event) {
 		searchParams.setStartDate(event.getStartDate());
 		searchParams.setEndDate(event.getEndDate());
diff --git a/src/main/java/org/olat/modules/lecture/ui/coach/AppealsController.java b/src/main/java/org/olat/modules/lecture/ui/coach/AppealsController.java
index 720394980d725bbecb3cdbde5598916c6e157f06..787ebc3c3254f3fde28c6657be07982f3a497cd5 100644
--- a/src/main/java/org/olat/modules/lecture/ui/coach/AppealsController.java
+++ b/src/main/java/org/olat/modules/lecture/ui/coach/AppealsController.java
@@ -96,6 +96,10 @@ public class AppealsController extends BasicController {
 		}
 	}
 	
+	protected void reloadModels() {
+		loadPendentAppeals();
+	}
+	
 	private void loadPendentAppeals() {
 		LectureBlockRollCallSearchParameters searchParams = new LectureBlockRollCallSearchParameters();
 		searchParams.setAppealStatus(Collections.singletonList(LectureBlockAppealStatus.pending));
diff --git a/src/main/java/org/olat/modules/lecture/ui/coach/DailyLectureBlockOverviewController.java b/src/main/java/org/olat/modules/lecture/ui/coach/DailyLectureBlockOverviewController.java
index 0f7361b6e5094c89d528ce1cbd712e69ec7f19ae..bf99deff1e38ddfb49137324eaa93d9bcd9d02bc 100644
--- a/src/main/java/org/olat/modules/lecture/ui/coach/DailyLectureBlockOverviewController.java
+++ b/src/main/java/org/olat/modules/lecture/ui/coach/DailyLectureBlockOverviewController.java
@@ -214,7 +214,7 @@ public class DailyLectureBlockOverviewController extends FormBasicController {
 		closeButton.setVisible(canClose);
 	}
 	
-	private void loadModel() {
+	protected void loadModel() {
 		LecturesBlockSearchParameters searchParams = new LecturesBlockSearchParameters();
 		searchParams.setStartDate(CalendarUtils.startOfDay(currentDate));
 		searchParams.setEndDate(CalendarUtils.endOfDay(currentDate));
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 0d8dd434d1ac5802fc3b0a07c53b13592fb10db4..e0eba14b8a5288611421ad4837ef534bf9871e75 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
@@ -32,11 +32,13 @@ import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.form.flexible.FormItem;
 import org.olat.core.gui.components.form.flexible.FormItemContainer;
 import org.olat.core.gui.components.form.flexible.elements.DateChooser;
+import org.olat.core.gui.components.form.flexible.elements.FormLink;
 import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement;
 import org.olat.core.gui.components.form.flexible.elements.SingleSelection;
 import org.olat.core.gui.components.form.flexible.impl.Form;
 import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
 import org.olat.core.gui.components.form.flexible.impl.FormEvent;
+import org.olat.core.gui.components.link.Link;
 import org.olat.core.gui.components.util.KeyValues;
 import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.WindowControl;
@@ -74,6 +76,7 @@ public class EditDatesLecturesEntriesController extends FormBasicController {
 	private DateChooser datesEl;
 	private SingleSelection targetsEl;
 	private SingleSelection durationEl;
+	private FormLink prolongateButton;
 	private MultipleSelectionElement entriesEl;
 	private MultipleSelectionElement lectureBlocksEl;
 
@@ -177,6 +180,11 @@ public class EditDatesLecturesEntriesController extends FormBasicController {
 		datesEl.setSeparator("noticed.till");
 		datesEl.setMandatory(true);
 
+		if(noticeWrapper.getAbsenceNotice() == null) {
+			prolongateButton = uifactory.addFormLink("prolongate.notice", formLayout, Link.BUTTON);
+			prolongateButton.setVisible(false);
+		}
+
 		// targets: all, courses, lectureblocks
 		String[] targetValues = new String[] {
 			translate("noticed.target.all"), translate("noticed.target.courses"), translate("noticed.target.lectureblocks")
@@ -408,6 +416,9 @@ public class EditDatesLecturesEntriesController extends FormBasicController {
 		allOk &= validate(entriesEl);
 		
 		datesEl.clearError();
+		if(prolongateButton != null) {
+			prolongateButton.setVisible(false);
+		}
 		if(datesEl.getDate() == null || datesEl.getSecondDate() == null) {
 			datesEl.setErrorKey("form.legende.mandatory", null);
 			allOk &= false;
@@ -418,6 +429,10 @@ public class EditDatesLecturesEntriesController extends FormBasicController {
 			if(!notices.isEmpty()) {
 				datesEl.setErrorKey("error.collision", null);
 				allOk &= false;
+				if(prolongateButton != null) {
+					prolongateButton.setVisible(true);
+					prolongateButton.setUserObject(notices);
+				}
 			}
 		}
 
@@ -440,6 +455,8 @@ public class EditDatesLecturesEntriesController extends FormBasicController {
 			updateDuration();
 		} else if(targetsEl == source || datesEl == source) {
 			updateTargets();
+		} else if(prolongateButton == source) {
+			doProlongate();
 		}
 		super.formInnerEvent(ureq, source, event);
 	}
@@ -468,6 +485,44 @@ public class EditDatesLecturesEntriesController extends FormBasicController {
 		}
 	}
 	
+	private void doProlongate() {
+		Dates dates = getDates();
+		List<AbsenceNotice> notices = lectureService.detectCollision(noticedIdentity,
+				noticeWrapper.getAbsenceNotice(), dates.getStartDate(), dates.getEndDate());
+		if(!notices.isEmpty()) {
+			AbsenceNotice notice = notices.get(0);
+			noticeWrapper.wrap(notice);
+			if(notice.getStartDate().before(dates.getStartDate())) {
+				datesEl.setDate(notice.getStartDate());
+			} else {
+				noticeWrapper.setStartDate(dates.getStartDate());
+			}
+			if(notice.getEndDate().after(dates.getEndDate())) {
+				datesEl.setSecondDate(notice.getEndDate());
+			} else {
+				noticeWrapper.setEndDate(dates.getEndDate());
+			}
+			updateTargets();
+			
+			Date startDate = noticeWrapper.getStartDate();
+			Date endDate = noticeWrapper.getEndDate();
+			boolean sameDay = CalendarUtils.isSameDay(startDate, endDate);
+			boolean startDay = AbsenceNoticeHelper.isStartOfWholeDay(startDate);
+			boolean endDay = AbsenceNoticeHelper.isEndOfWholeDay(endDate);
+
+			String selectedDurationKey;
+			if(sameDay && startDay && endDay) {
+				selectedDurationKey = "today";
+			} else if(startDay && endDay) {
+				selectedDurationKey = "days";
+			} else {
+				selectedDurationKey = "exact";
+			}
+			durationEl.select(selectedDurationKey, true);
+			updateDuration();
+		}
+	}
+	
 	public Dates getDates() {
 		Date start = null;
 		Date end = null;
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 b1c3c330a60f5b4abc2cce9e5ae230605f642231..96f5e01c15aa863d7f11164e73dad2c21d6de4f0 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
@@ -203,6 +203,8 @@ public class LecturesCoachingController extends BasicController implements Activ
 			WindowControl swControl = addToHistory(ureq, OresHelper.createOLATResourceableType("Cockpit"), null);
 			cockpitController = new LecturesCockpitController(ureq, swControl, secCallback);
 			listenTo(cockpitController);
+		} else {
+			cockpitController.reloadModels();
 		}
 		addToHistory(ureq, cockpitController);
 		mainVC.put("segmentCmp", cockpitController.getInitialComponent()); 
@@ -230,6 +232,8 @@ public class LecturesCoachingController extends BasicController implements Activ
 			WindowControl swControl = addToHistory(ureq, OresHelper.createOLATResourceableType("Absences"), null);
 			absencesController = new AbsencesController(ureq, swControl, getCurrentDate(), secCallback);
 			listenTo(absencesController);
+		} else {
+			absencesController.reloadModels();
 		}
 		addToHistory(ureq, absencesController);
 		mainVC.put("segmentCmp", absencesController.getInitialComponent());  
@@ -240,6 +244,8 @@ public class LecturesCoachingController extends BasicController implements Activ
 			WindowControl swControl = addToHistory(ureq, OresHelper.createOLATResourceableType("Dispenses"), null);
 			dispensationsController = new DispensationsController(ureq, swControl, getCurrentDate(), secCallback, true, true);
 			listenTo(dispensationsController);
+		} else {
+			dispensationsController.reloadModel();
 		}
 		addToHistory(ureq, dispensationsController);
 		mainVC.put("segmentCmp", dispensationsController.getInitialComponent());   
@@ -250,6 +256,8 @@ public class LecturesCoachingController extends BasicController implements Activ
 			WindowControl swControl = addToHistory(ureq, OresHelper.createOLATResourceableType("Appeals"), null);
 			appealsController = new AppealsController(ureq, swControl, secCallback);
 			listenTo(appealsController);
+		} else {
+			appealsController.reloadModels();
 		}
 		addToHistory(ureq, appealsController);
 		mainVC.put("segmentCmp", appealsController.getInitialComponent());   
diff --git a/src/main/java/org/olat/modules/lecture/ui/coach/LecturesCockpitController.java b/src/main/java/org/olat/modules/lecture/ui/coach/LecturesCockpitController.java
index 01b55cee75b5d0c182e6fedb54f63b99d52bbe2b..83f846b520867ef0699321c47108b1b1846c93cf 100644
--- a/src/main/java/org/olat/modules/lecture/ui/coach/LecturesCockpitController.java
+++ b/src/main/java/org/olat/modules/lecture/ui/coach/LecturesCockpitController.java
@@ -188,6 +188,14 @@ public class LecturesCockpitController extends BasicController implements Activa
 		cleanUp();
 	}
 	
+	protected void reloadModels() {
+		if(lectureBlocksCtrl != null) {
+			lectureBlocksCtrl.loadModel();
+		}
+		absencesListCtrl.reloadModel();
+		loadPendingLectureBlocks();
+	}
+	
 	private void doRollCall(UserRequest ureq, List<LectureBlock> lectureBlocks) {
 		if(lectureBlocks.isEmpty()) {
 			// msg
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 70c231a1519d23000a76c8fe0247896eabac3397..015194697b6902798764cd5eebeade96c283d95e 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
@@ -29,6 +29,7 @@ import org.olat.core.gui.components.link.Link;
 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.tabbedpane.TabbedPaneChangedEvent;
 import org.olat.core.gui.components.velocity.VelocityContainer;
 import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.Event;
@@ -66,6 +67,11 @@ public class IdentityProfileController extends BasicController implements Activa
 	private Link addDispensation;
 	private Link addNoticeOfAbsence;
 	
+	private final int dailyTab;
+	private final int lecturesTab;
+	private final int appealsTab;
+	private final int dispensationsTab;
+	
 	private TabbedPane tabPane;
 	private final VelocityContainer mainVC;
 	
@@ -118,10 +124,10 @@ public class IdentityProfileController extends BasicController implements Activa
 		// day overview
 		dailyOverviewCtrl = new DailyOverviewProfilController(ureq, getWindowControl(), profiledIdentity, secCallback);
 		listenTo(dailyOverviewCtrl);
-		tabPane.addTab(translate("cockpit.day.overview"), dailyOverviewCtrl);
+		dailyTab = tabPane.addTab(translate("cockpit.day.overview"), dailyOverviewCtrl);
 		
 		// list of lectures
-		tabPane.addTab(translate("user.overview.lectures"), uureq -> {
+		lecturesTab = tabPane.addTab(translate("user.overview.lectures"), uureq -> {
 			lecturesCtrl = new ParticipantLecturesOverviewController(uureq, getWindowControl(), profiledIdentity, null,
 					true, true, true, true, true, false);
 			listenTo(lecturesCtrl);
@@ -133,14 +139,14 @@ public class IdentityProfileController extends BasicController implements Activa
 		});
 
 		// dispensation
-		tabPane.addTab(translate("user.overview.dispensation"), uureq -> {
+		dispensationsTab = tabPane.addTab(translate("user.overview.dispensation"), uureq -> {
 			dispensationsCtrl = new DispensationsController(uureq, getWindowControl(), null, secCallback, false, false);
 			listenTo(dispensationsCtrl);
 			return dispensationsCtrl.getInitialComponent();
 		});
 
 		// appeals
-		tabPane.addTab(translate("user.overview.appeals"), uureq -> {
+		appealsTab = tabPane.addTab(translate("user.overview.appeals"), uureq -> {
 			appealsCtrl = new AppealListRepositoryController(uureq, getWindowControl(), profiledIdentity, secCallback);
 			listenTo(appealsCtrl);
 			return appealsCtrl.getInitialComponent();
@@ -169,6 +175,10 @@ public class IdentityProfileController extends BasicController implements Activa
 			doAddNotice(ureq, AbsenceNoticeType.notified);
 		} else if(addDispensation == source) {
 			doAddNotice(ureq, AbsenceNoticeType.dispensation);
+		} else if(source == tabPane) {
+			if(event instanceof TabbedPaneChangedEvent) {
+				reload();
+			}
 		}
 	}
 	
@@ -191,6 +201,19 @@ public class IdentityProfileController extends BasicController implements Activa
 		addNoticeCtrl = null;
 	}
 	
+	private void reload() {
+		int selectedPane = tabPane.getSelectedPane();
+		if(dispensationsCtrl != null && dispensationsTab == selectedPane) {
+			dispensationsCtrl.reloadModel();
+		} else if(dailyOverviewCtrl != null && dailyTab == selectedPane) {
+			dailyOverviewCtrl.reloadModel();
+		} else if(lecturesCtrl != null && lecturesTab == selectedPane) {
+			lecturesCtrl.loadModel();
+		} else if(appealsCtrl != null && appealsTab == selectedPane) {
+			appealsCtrl.reloadModel();
+		}
+	}
+	
 	private void updateModels() {
 		if(dispensationsCtrl != null) {
 			dispensationsCtrl.reloadModel();
diff --git a/src/test/java/org/olat/modules/lecture/manager/AbsenceNoticeToLectureBlockDAOTest.java b/src/test/java/org/olat/modules/lecture/manager/AbsenceNoticeToLectureBlockDAOTest.java
index 2f7e3574ebe10d26663e59489d0ba7906edf1bd6..ca518b79c841011b4b1fbf36b88e0eefc0ab4cb4 100644
--- a/src/test/java/org/olat/modules/lecture/manager/AbsenceNoticeToLectureBlockDAOTest.java
+++ b/src/test/java/org/olat/modules/lecture/manager/AbsenceNoticeToLectureBlockDAOTest.java
@@ -19,7 +19,10 @@
  */
 package org.olat.modules.lecture.manager;
 
+import java.util.Calendar;
+import java.util.Collections;
 import java.util.Date;
+import java.util.List;
 
 import org.junit.Assert;
 import org.junit.Test;
@@ -31,7 +34,11 @@ import org.olat.modules.lecture.AbsenceNoticeTarget;
 import org.olat.modules.lecture.AbsenceNoticeToLectureBlock;
 import org.olat.modules.lecture.AbsenceNoticeType;
 import org.olat.modules.lecture.LectureBlock;
+import org.olat.modules.lecture.LectureBlockRollCall;
+import org.olat.modules.lecture.LectureService;
+import org.olat.modules.vitero.model.GroupRole;
 import org.olat.repository.RepositoryEntry;
+import org.olat.repository.manager.RepositoryEntryRelationDAO;
 import org.olat.test.JunitTestHelper;
 import org.olat.test.OlatTestCase;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -47,10 +54,14 @@ public class AbsenceNoticeToLectureBlockDAOTest extends OlatTestCase {
 	@Autowired
 	private DB dbInstance;
 	@Autowired
+	private LectureService lectureService;
+	@Autowired
 	private LectureBlockDAO lectureBlockDao;
 	@Autowired
 	private AbsenceNoticeDAO absenceNoticeDao;
 	@Autowired
+	private RepositoryEntryRelationDAO repositoryEntryRelationDAO;
+	@Autowired
 	private AbsenceNoticeToLectureBlockDAO absenceNoticeToLectureBlockDao;
 	
 	@Test
@@ -88,4 +99,108 @@ public class AbsenceNoticeToLectureBlockDAOTest extends OlatTestCase {
 	}
 	
 
+	@Test
+	public void searchRollCallsByLectureBlock() {
+		// make a course, with a participant, with a lecture block, an absence
+		RepositoryEntry entry = JunitTestHelper.createAndPersistRepositoryEntry();
+		LectureBlock lectureBlock = createMinimalLectureBlock(entry, new Date(), new Date());
+		Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("absent-1");
+		repositoryEntryRelationDAO.addRole(participant, entry, GroupRole.participant.name());
+		AbsenceNotice notice = lectureService.createAbsenceNotice(participant, AbsenceNoticeType.absence, AbsenceNoticeTarget.entries,
+				CalendarUtils.startOfDay(new Date()), CalendarUtils.endOfDay(new Date()),
+				null, null, Boolean.TRUE, null, Collections.singletonList(lectureBlock), null);
+		dbInstance.commit();
+		
+		LectureBlockRollCall rollCall = lectureService.getOrCreateRollCall(participant, lectureBlock, null, null, null);
+		Assert.assertNotNull(rollCall);
+		
+		dbInstance.commitAndCloseSession();
+		
+		List<LectureBlockRollCall> rollCallList = absenceNoticeToLectureBlockDao.searchRollCallsByLectureBlock(notice);
+		Assert.assertNotNull(rollCallList);
+		Assert.assertEquals(1, rollCallList.size());
+		Assert.assertTrue(rollCallList.contains(rollCall));
+	}
+	
+	/**
+	 * The test make sure that the search method returns the roll call
+	 * of the right user, at the right dates, with the right course. It
+	 * adds noise in the form of a second course, second lecture block
+	 * with different dates and a second participant (with a lecture at
+	 * the moment of the search).
+	 * 
+	 */
+	@Test
+	public void searchRollCallsByLectureBlock_severalParticipants() {
+		// make a course, with a participant, with a lecture block, an absence
+		RepositoryEntry entry = JunitTestHelper.createAndPersistRepositoryEntry();
+		Calendar cal = Calendar.getInstance();
+		cal.set(Calendar.HOUR_OF_DAY, 12);
+		Date startLecture = cal.getTime();
+		cal.set(Calendar.HOUR_OF_DAY, 14);
+		Date endLecture = cal.getTime();
+		
+		LectureBlock lectureBlock = createMinimalLectureBlock(entry, startLecture, endLecture);
+		
+		cal.add(Calendar.DATE, -7);
+		cal.set(Calendar.HOUR_OF_DAY, 12);
+		Date oldStartLecture = cal.getTime();
+		cal.set(Calendar.HOUR_OF_DAY, 14);
+		Date oldEndLecture = cal.getTime();
+		LectureBlock oldLectureBlock = createMinimalLectureBlock(entry, oldStartLecture, oldEndLecture);
+		
+		// second repository entry for some noise
+		RepositoryEntry entry2 = JunitTestHelper.createAndPersistRepositoryEntry();
+		LectureBlock lectureBlockEntry2 = createMinimalLectureBlock(entry2, startLecture, endLecture);
+		
+		// memberships
+		Identity participant1 = JunitTestHelper.createAndPersistIdentityAsRndUser("absent-1");
+		Identity participant2 = JunitTestHelper.createAndPersistIdentityAsRndUser("absent-2");
+		repositoryEntryRelationDAO.addRole(participant1, entry, GroupRole.participant.name());
+		repositoryEntryRelationDAO.addRole(participant2, entry, GroupRole.participant.name());
+		repositoryEntryRelationDAO.addRole(participant1, entry2, GroupRole.participant.name());
+		repositoryEntryRelationDAO.addRole(participant2, entry2, GroupRole.participant.name());
+		
+		AbsenceNotice notice1 = lectureService.createAbsenceNotice(participant1, AbsenceNoticeType.absence, AbsenceNoticeTarget.entries,
+				CalendarUtils.startOfDay(new Date()), CalendarUtils.endOfDay(new Date()),
+				null, null, Boolean.TRUE, null, Collections.singletonList(lectureBlock), null);
+		AbsenceNotice notice2 = lectureService.createAbsenceNotice(participant2, AbsenceNoticeType.absence, AbsenceNoticeTarget.entries,
+				CalendarUtils.startOfDay(new Date()), CalendarUtils.endOfDay(new Date()),
+				null, null, Boolean.TRUE, null, Collections.singletonList(lectureBlock), null);
+		dbInstance.commit();
+		Assert.assertNotNull(notice1);
+		Assert.assertNotNull(notice2);
+		
+		// roll call first entry
+		LectureBlockRollCall rollCall1 = lectureService.getOrCreateRollCall(participant1, lectureBlock, null, null, null);
+		Assert.assertNotNull(rollCall1);
+		LectureBlockRollCall rollCall2 = lectureService.getOrCreateRollCall(participant2, lectureBlock, null, null, null);
+		Assert.assertNotNull(rollCall2);
+		LectureBlockRollCall oldRollCall1 = lectureService.getOrCreateRollCall(participant1, oldLectureBlock, null, null, null);
+		Assert.assertNotNull(oldRollCall1);
+		// roll call second entry
+		LectureBlockRollCall rollCall1Entry2 = lectureService.getOrCreateRollCall(participant1, lectureBlockEntry2 , null, null, null);
+		Assert.assertNotNull(rollCall1Entry2);
+		LectureBlockRollCall rollCall2Entry2  = lectureService.getOrCreateRollCall(participant2, lectureBlockEntry2, null, null, null);
+		Assert.assertNotNull(rollCall2Entry2);
+		
+		dbInstance.commitAndCloseSession();
+		
+		List<LectureBlockRollCall> rollCallList = absenceNoticeToLectureBlockDao.searchRollCallsByLectureBlock(notice1);
+		Assert.assertNotNull(rollCallList);
+		Assert.assertEquals(1, rollCallList.size());
+		Assert.assertTrue(rollCallList.contains(rollCall1));
+		Assert.assertFalse(rollCallList.contains(rollCall2));
+		Assert.assertFalse(rollCallList.contains(oldRollCall1));
+	}
+	
+	private LectureBlock createMinimalLectureBlock(RepositoryEntry entry, Date start, Date end) {
+		LectureBlock lectureBlock = lectureBlockDao.createLectureBlock(entry);
+		lectureBlock.setStartDate(start);
+		lectureBlock.setEndDate(end);
+		lectureBlock.setTitle("Absence");
+		lectureBlock.setPlannedLecturesNumber(4);
+		lectureBlock.setEffectiveLecturesNumber(4);
+		return lectureBlockDao.update(lectureBlock);
+	}
 }
diff --git a/src/test/java/org/olat/modules/lecture/manager/AbsenceNoticeToRepositoryEntryDAOTest.java b/src/test/java/org/olat/modules/lecture/manager/AbsenceNoticeToRepositoryEntryDAOTest.java
index 5928d2c8ae4c5296479b6b631cd4b94b60e9a912..2d03775fb79f71fd0f5aa87aad1befbc6bb59923 100644
--- a/src/test/java/org/olat/modules/lecture/manager/AbsenceNoticeToRepositoryEntryDAOTest.java
+++ b/src/test/java/org/olat/modules/lecture/manager/AbsenceNoticeToRepositoryEntryDAOTest.java
@@ -86,7 +86,7 @@ public class AbsenceNoticeToRepositoryEntryDAOTest extends OlatTestCase {
 	}
 	
 	@Test
-	public void getRollCalls() {
+	public void searchRollCallsByRepositoryEntry() {
 		// make a course, with a participant, with a lecture block, an absence
 		RepositoryEntry entry = JunitTestHelper.createAndPersistRepositoryEntry();
 		LectureBlock lectureBlock = createMinimalLectureBlock(entry, new Date(), new Date());
@@ -102,14 +102,87 @@ public class AbsenceNoticeToRepositoryEntryDAOTest extends OlatTestCase {
 		
 		dbInstance.commitAndCloseSession();
 		
-		List<LectureBlockRollCall> rollCallList = absenceNoticeToRepositoryEntryDao.getRollCallsByRepositoryEntry(notice);
+		List<LectureBlockRollCall> rollCallList = absenceNoticeToRepositoryEntryDao.searchRollCallsByRepositoryEntry(notice);
 		Assert.assertNotNull(rollCallList);
 		Assert.assertEquals(1, rollCallList.size());
 		Assert.assertTrue(rollCallList.contains(rollCall));
 	}
 	
+	/**
+	 * The test make sure that the search method returns the roll call
+	 * of the right user, at the right dates, with the right course. It
+	 * adds noise in the form of a second course, second lecture block
+	 * with different dates and a second participant (with a lecture at
+	 * the moment of the search).
+	 * 
+	 */
 	@Test
-	public void getRollCallsOfAllEntries() {
+	public void searchRollCallsByRepositoryEntry_severalParticipants() {
+		// make a course, with a participant, with a lecture block, an absence
+		RepositoryEntry entry = JunitTestHelper.createAndPersistRepositoryEntry();
+		Calendar cal = Calendar.getInstance();
+		cal.set(Calendar.HOUR_OF_DAY, 12);
+		Date startLecture = cal.getTime();
+		cal.set(Calendar.HOUR_OF_DAY, 14);
+		Date endLecture = cal.getTime();
+		
+		LectureBlock lectureBlock = createMinimalLectureBlock(entry, startLecture, endLecture);
+		
+		cal.add(Calendar.DATE, -7);
+		cal.set(Calendar.HOUR_OF_DAY, 12);
+		Date oldStartLecture = cal.getTime();
+		cal.set(Calendar.HOUR_OF_DAY, 14);
+		Date oldEndLecture = cal.getTime();
+		LectureBlock oldLectureBlock = createMinimalLectureBlock(entry, oldStartLecture, oldEndLecture);
+		
+		// second repository entry for some noise
+		RepositoryEntry entry2 = JunitTestHelper.createAndPersistRepositoryEntry();
+		LectureBlock lectureBlockEntry2 = createMinimalLectureBlock(entry2, startLecture, endLecture);
+		
+		// memberships
+		Identity participant1 = JunitTestHelper.createAndPersistIdentityAsRndUser("absent-1");
+		Identity participant2 = JunitTestHelper.createAndPersistIdentityAsRndUser("absent-2");
+		repositoryEntryRelationDAO.addRole(participant1, entry, GroupRole.participant.name());
+		repositoryEntryRelationDAO.addRole(participant2, entry, GroupRole.participant.name());
+		repositoryEntryRelationDAO.addRole(participant1, entry2, GroupRole.participant.name());
+		repositoryEntryRelationDAO.addRole(participant2, entry2, GroupRole.participant.name());
+		
+		
+		AbsenceNotice notice1 = lectureService.createAbsenceNotice(participant1, AbsenceNoticeType.absence, AbsenceNoticeTarget.entries,
+				CalendarUtils.startOfDay(new Date()), CalendarUtils.endOfDay(new Date()),
+				null, null, Boolean.TRUE, Collections.singletonList(entry), null, null);
+		AbsenceNotice notice2 = lectureService.createAbsenceNotice(participant2, AbsenceNoticeType.absence, AbsenceNoticeTarget.entries,
+				CalendarUtils.startOfDay(new Date()), CalendarUtils.endOfDay(new Date()),
+				null, null, Boolean.TRUE, Collections.singletonList(entry), null, null);
+		dbInstance.commit();
+		Assert.assertNotNull(notice1);
+		Assert.assertNotNull(notice2);
+		
+		// roll call first entry
+		LectureBlockRollCall rollCall1 = lectureService.getOrCreateRollCall(participant1, lectureBlock, null, null, null);
+		Assert.assertNotNull(rollCall1);
+		LectureBlockRollCall rollCall2 = lectureService.getOrCreateRollCall(participant2, lectureBlock, null, null, null);
+		Assert.assertNotNull(rollCall2);
+		LectureBlockRollCall oldRollCall1 = lectureService.getOrCreateRollCall(participant1, oldLectureBlock, null, null, null);
+		Assert.assertNotNull(oldRollCall1);
+		// roll call second entry
+		LectureBlockRollCall rollCall1Entry2 = lectureService.getOrCreateRollCall(participant1, lectureBlockEntry2 , null, null, null);
+		Assert.assertNotNull(rollCall1Entry2);
+		LectureBlockRollCall rollCall2Entry2  = lectureService.getOrCreateRollCall(participant2, lectureBlockEntry2, null, null, null);
+		Assert.assertNotNull(rollCall2Entry2);
+		
+		dbInstance.commitAndCloseSession();
+		
+		List<LectureBlockRollCall> rollCallList = absenceNoticeToRepositoryEntryDao.searchRollCallsByRepositoryEntry(notice1);
+		Assert.assertNotNull(rollCallList);
+		Assert.assertEquals(1, rollCallList.size());
+		Assert.assertTrue(rollCallList.contains(rollCall1));
+		Assert.assertFalse(rollCallList.contains(rollCall2));
+		Assert.assertFalse(rollCallList.contains(oldRollCall1));
+	}
+	
+	@Test
+	public void searchRollCallsOfAllEntries() {
 		// make a course, with a participant, with a lecture block, an absence
 		RepositoryEntry entry = JunitTestHelper.createAndPersistRepositoryEntry();
 		Calendar cal = Calendar.getInstance();
@@ -123,7 +196,7 @@ public class AbsenceNoticeToRepositoryEntryDAOTest extends OlatTestCase {
 		repositoryEntryRelationDAO.addRole(participant, entry, GroupRole.participant.name());
 		AbsenceNotice notice = lectureService.createAbsenceNotice(participant, AbsenceNoticeType.absence, AbsenceNoticeTarget.allentries,
 				CalendarUtils.startOfDay(new Date()), CalendarUtils.endOfDay(new Date()),
-				null, null, Boolean.TRUE, Collections.singletonList(entry), null, null);
+				null, null, Boolean.TRUE, null, null, null);
 		dbInstance.commit();
 		
 		LectureBlockRollCall rollCall = lectureService.getOrCreateRollCall(participant, lectureBlock, null, null, null);
@@ -131,12 +204,72 @@ public class AbsenceNoticeToRepositoryEntryDAOTest extends OlatTestCase {
 		
 		dbInstance.commitAndCloseSession();
 		
-		List<LectureBlockRollCall> rollCallList = absenceNoticeToRepositoryEntryDao.getRollCallsOfAllEntries(notice);
+		List<LectureBlockRollCall> rollCallList = absenceNoticeToRepositoryEntryDao
+				.searchRollCallsOfAllEntries(notice.getIdentity(), notice.getStartDate(), notice.getEndDate());
 		Assert.assertNotNull(rollCallList);
 		Assert.assertEquals(1, rollCallList.size());
 		Assert.assertTrue(rollCallList.contains(rollCall));
 	}
 	
+	/**
+	 * The test make sure that the search method returns the roll call
+	 * of the right user, at the right dates, with the right course. It
+	 * adds noise in the form of a second course, second lecture block
+	 * with different dates and a second participant (with a lecture at
+	 * the moment of the search).
+	 * 
+	 */
+	@Test
+	public void searchRollCallsOfAllEntries_severalParticipants() {
+		// make a course, with a participant, with a lecture block, an absence
+		RepositoryEntry entry = JunitTestHelper.createAndPersistRepositoryEntry();
+		Calendar cal = Calendar.getInstance();
+		cal.set(Calendar.HOUR_OF_DAY, 12);
+		Date startLecture = cal.getTime();
+		cal.set(Calendar.HOUR_OF_DAY, 14);
+		Date endLecture = cal.getTime();
+		
+		LectureBlock lectureBlock = createMinimalLectureBlock(entry, startLecture, endLecture);
+		
+		cal.add(Calendar.DATE, -7);
+		cal.set(Calendar.HOUR_OF_DAY, 12);
+		Date oldStartLecture = cal.getTime();
+		cal.set(Calendar.HOUR_OF_DAY, 14);
+		Date oldEndLecture = cal.getTime();
+		LectureBlock oldLectureBlock = createMinimalLectureBlock(entry, oldStartLecture, oldEndLecture);
+		
+		Identity participant1 = JunitTestHelper.createAndPersistIdentityAsRndUser("absent-1");
+		Identity participant2 = JunitTestHelper.createAndPersistIdentityAsRndUser("absent-2");
+		repositoryEntryRelationDAO.addRole(participant1, entry, GroupRole.participant.name());
+		repositoryEntryRelationDAO.addRole(participant2, entry, GroupRole.participant.name());
+		AbsenceNotice notice1 = lectureService.createAbsenceNotice(participant1, AbsenceNoticeType.absence, AbsenceNoticeTarget.allentries,
+				CalendarUtils.startOfDay(new Date()), CalendarUtils.endOfDay(new Date()),
+				null, null, Boolean.TRUE, null, null, null);
+		AbsenceNotice notice2 = lectureService.createAbsenceNotice(participant2, AbsenceNoticeType.absence, AbsenceNoticeTarget.allentries,
+				CalendarUtils.startOfDay(new Date()), CalendarUtils.endOfDay(new Date()),
+				null, null, Boolean.TRUE, null, null, null);
+		dbInstance.commit();
+		Assert.assertNotNull(notice1);
+		Assert.assertNotNull(notice2);
+		
+		LectureBlockRollCall rollCall1 = lectureService.getOrCreateRollCall(participant1, lectureBlock, null, null, null);
+		Assert.assertNotNull(rollCall1);
+		LectureBlockRollCall rollCall2 = lectureService.getOrCreateRollCall(participant2, lectureBlock, null, null, null);
+		Assert.assertNotNull(rollCall2);
+		LectureBlockRollCall oldRollCall1 = lectureService.getOrCreateRollCall(participant1, oldLectureBlock, null, null, null);
+		Assert.assertNotNull(oldRollCall1);
+		
+		dbInstance.commitAndCloseSession();
+		
+		List<LectureBlockRollCall> rollCallList = absenceNoticeToRepositoryEntryDao
+				.searchRollCallsOfAllEntries(notice1.getIdentity(), notice1.getStartDate(), notice1.getEndDate());
+		Assert.assertNotNull(rollCallList);
+		Assert.assertEquals(1, rollCallList.size());
+		Assert.assertTrue(rollCallList.contains(rollCall1));
+		Assert.assertFalse(rollCallList.contains(rollCall2));
+		Assert.assertFalse(rollCallList.contains(oldRollCall1));
+	}
+	
 	private LectureBlock createMinimalLectureBlock(RepositoryEntry entry, Date start, Date end) {
 		LectureBlock lectureBlock = lectureBlockDao.createLectureBlock(entry);
 		lectureBlock.setStartDate(start);