diff --git a/src/main/java/org/olat/modules/coach/model/CoachingSecurity.java b/src/main/java/org/olat/modules/coach/model/CoachingSecurity.java
index 3a2d82fdf06d38c7a602173cb084c90a66599f51..bbe1a0143eaccea9ddf92529ddc647ca753c2dc7 100644
--- a/src/main/java/org/olat/modules/coach/model/CoachingSecurity.java
+++ b/src/main/java/org/olat/modules/coach/model/CoachingSecurity.java
@@ -1,3 +1,22 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
 package org.olat.modules.coach.model;
 
 /**
diff --git a/src/main/java/org/olat/modules/lecture/LectureService.java b/src/main/java/org/olat/modules/lecture/LectureService.java
index caf6315e9e0ce4d5654efe4115c603e1ab470d76..615cf9792ad5e856577a802fdf4b6dd87dd1aafc 100644
--- a/src/main/java/org/olat/modules/lecture/LectureService.java
+++ b/src/main/java/org/olat/modules/lecture/LectureService.java
@@ -26,6 +26,8 @@ import java.util.List;
 import org.olat.basesecurity.Group;
 import org.olat.basesecurity.IdentityRef;
 import org.olat.core.id.Identity;
+import org.olat.core.util.vfs.VFSContainer;
+import org.olat.core.util.vfs.VFSItem;
 import org.olat.modules.lecture.model.AbsenceNoticeInfos;
 import org.olat.modules.lecture.model.AggregatedLectureBlocksStatistics;
 import org.olat.modules.lecture.model.IdentityRateWarning;
@@ -299,6 +301,10 @@ public interface LectureService {
 	public AbsenceNotice updateAbsenceNotice(AbsenceNotice absenceNotice, Identity authorizer,
 			List<RepositoryEntry> entries, List<LectureBlock> lectureBlocks);
 	
+	public AbsenceNotice updateAbsenceNoticeAttachments(AbsenceNotice absenceNotice, List<VFSItem> newFiles, List<VFSItem> filesToDelete);
+	
+	public VFSContainer getAbsenceNoticeAttachmentsContainer(AbsenceNotice absenceNotice);
+	
 	/**
 	 * Reload the absence notice.
 	 * 
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 3d9d503531830ed9e81b241c51a5d4cc165ac8c0..b8a3d8035758301469abde9a73e5f0668d517c07 100644
--- a/src/main/java/org/olat/modules/lecture/manager/LectureServiceImpl.java
+++ b/src/main/java/org/olat/modules/lecture/manager/LectureServiceImpl.java
@@ -19,6 +19,8 @@
  */
 package org.olat.modules.lecture.manager;
 
+import java.io.File;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Collections;
@@ -60,6 +62,10 @@ import org.olat.core.util.mail.MailContextImpl;
 import org.olat.core.util.mail.MailManager;
 import org.olat.core.util.mail.MailTemplate;
 import org.olat.core.util.mail.MailerResult;
+import org.olat.core.util.vfs.LocalFolderImpl;
+import org.olat.core.util.vfs.VFSContainer;
+import org.olat.core.util.vfs.VFSItem;
+import org.olat.core.util.vfs.VFSManager;
 import org.olat.group.BusinessGroup;
 import org.olat.group.DeletableGroupData;
 import org.olat.modules.coach.model.IdentityRepositoryEntryKey;
@@ -626,6 +632,63 @@ public class LectureServiceImpl implements LectureService, UserDataDeletable, De
 		}
 	}
 	
+	@Override
+	public AbsenceNotice updateAbsenceNoticeAttachments(AbsenceNotice absenceNotice, List<VFSItem> newFiles, List<VFSItem> filesToDelete) {
+		if(!filesToDelete.isEmpty()) {
+			for(VFSItem file:filesToDelete) {
+				file.delete();
+			}
+		}
+	
+		if(!newFiles.isEmpty()) {
+			LocalFolderImpl rootContainer = getAbsenceNoticesAttachmentsPath();
+			File rootDir = rootContainer.getBasefile();
+			String noticeStorage = ((AbsenceNoticeImpl)absenceNotice).getAttachmentsDirectory();
+			if(noticeStorage == null) {	
+				File userDir = new File(rootDir, absenceNotice.getIdentity().getKey().toString());
+				File noticeDir = new File(userDir, absenceNotice.getKey().toString());
+				noticeDir.mkdirs();
+				
+				Path relativePath = rootDir.toPath().relativize(noticeDir.toPath());
+				noticeStorage = relativePath.toString();
+				((AbsenceNoticeImpl)absenceNotice).setAttachmentsDirectory(noticeStorage);
+				absenceNotice = absenceNoticeDao.updateAbsenceNotice(absenceNotice);
+				dbInstance.commit();
+			}
+			
+			VFSItem noticeItem = rootContainer.resolve(noticeStorage);
+			if(noticeItem instanceof VFSContainer) {
+				VFSContainer noticeContainer = (VFSContainer)noticeItem;
+				for(VFSItem file:newFiles) {
+					noticeContainer.copyFrom(file);
+				}
+			}
+		}
+		
+		return absenceNotice;
+	}
+
+	
+    @Override
+	public VFSContainer getAbsenceNoticeAttachmentsContainer(AbsenceNotice absenceNotice) {
+    	if(absenceNotice == null || absenceNotice.getKey() == null) return null;
+
+		LocalFolderImpl rootContainer = getAbsenceNoticesAttachmentsPath();
+		VFSItem userItem = rootContainer.resolve(absenceNotice.getIdentity().getKey().toString());
+    	if(userItem instanceof VFSContainer) {
+    		VFSContainer userContainer = (VFSContainer)userItem;
+    		VFSItem noticeItem = userContainer.resolve(absenceNotice.getKey().toString());
+    		if(noticeItem instanceof VFSContainer) {
+    			return (VFSContainer)noticeItem;
+    		}
+    	}
+		return null;
+	}
+
+	private LocalFolderImpl getAbsenceNoticesAttachmentsPath() {
+    	return VFSManager.olatRootContainer("/lectures/notices/", null);
+	}
+
 	@Override
 	public AbsenceNotice getAbsenceNotice(AbsenceNoticeRef notice) {
 		return absenceNoticeDao.loadAbsenceNotice(notice.getKey());
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 ee0326daf7cb73ec2d24df11500713079e0b945e..c5d60a7a1f981813e446abc409bd735c420b1102 100644
--- a/src/main/java/org/olat/modules/lecture/model/EditAbsenceNoticeWrapper.java
+++ b/src/main/java/org/olat/modules/lecture/model/EditAbsenceNoticeWrapper.java
@@ -24,6 +24,8 @@ import java.util.Date;
 import java.util.List;
 
 import org.olat.core.id.Identity;
+import org.olat.core.util.vfs.VFSContainer;
+import org.olat.core.util.vfs.VFSItem;
 import org.olat.modules.lecture.AbsenceCategory;
 import org.olat.modules.lecture.AbsenceNotice;
 import org.olat.modules.lecture.AbsenceNoticeTarget;
@@ -59,6 +61,10 @@ public class EditAbsenceNoticeWrapper {
 	private List<LectureBlock> lectureBlocks;
 	
 	private List<LectureBlock> predefinedLectureBlocks;
+
+	private VFSContainer tempUploadFolder;
+	private VFSContainer documentContainer;
+	private List<VFSItem> attachmentsToDelete = new ArrayList<>();
 	
 	private EditAbsenceNoticeWrapper(AbsenceNotice notice) {
 		absenceNotice = notice;
@@ -215,6 +221,26 @@ public class EditAbsenceNoticeWrapper {
 		this.identitiesToContact = identitiesToContact;
 	}
 
+	public VFSContainer getTempUploadFolder() {
+		return tempUploadFolder;
+	}
+
+	public void setTempUploadFolder(VFSContainer tempUploadFolder) {
+		this.tempUploadFolder = tempUploadFolder;
+	}
+
+	public VFSContainer getDocumentContainer() {
+		return documentContainer;
+	}
+
+	public void setDocumentContainer(VFSContainer documentContainer) {
+		this.documentContainer = documentContainer;
+	}
+	
+	public List<VFSItem> getAttachmentsToDelete() {
+		return attachmentsToDelete;
+	}
+
 	public void commitChanges(AbsenceNotice notice) {
 		notice.setStartDate(startDate);
 		notice.setEndDate(endDate);
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 0cf06b99f58954919726b328f0b0cab69bb8a562..00becb55136e6c185ef4479a18688d15415d0ff2 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,4 +1,4 @@
-#Mon Aug 19 16:40:37 CEST 2019
+#Tue Aug 20 13:54:27 CEST 2019
 absence.category=Absenzenbegr\u00FCndung
 absence.category.copied=Absenzenbegr\u00FCndung wurde erfolgreich kopiert.
 absence.category.copy={0} (Kopie)
@@ -50,6 +50,7 @@ appeals.title=Rekursliste
 appeals.update.title=Edit {0} Rekurs
 archive.entry=Archivierung
 assessment.tool=Bewertungswerkzeug
+attachment.upload=Artzzeugnis, Best\u00E4tigung etc.
 attendance.list=Absenzenliste
 attendance.list.title=Absenzenliste\: {0}
 attendance.list.to.sign=Pr\u00E4senzliste
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 508e35f073ef346abd250d2b382ac2ead3817998..2ee51ee8aa577f83ea9f546be1adf8f51e71e239 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,484 +1,485 @@
-#Mon Aug 19 18:54:56 CEST 2019
-edit.reason=Edit reason
-table.legend.free=Free lecture
-config.override.no=No
-table.header.tools=<i class\='o_icon o_icon_actions o_icon-lg'> </i>
-lecture.block.effective.reason=Reason
-authorized.absence.reason=Reason
-table.header.date=Date
-lecture.mastercoach.can.authorize.appeal=Master coaches can authorize appeals
-noticed.teachers=Teachers
-participant.rate.edit=Personal rate
-table.header.participants=Participants
-empty.table.lectures.blocks=There are no lectures to display.
-noticed.type.notified=Notice of absence
-infos.participant.attendance.rate=Personal attendance rate\: {0}%
-lecture.mastercoach.can.see.appeal=Master coaches can see appeals
-table.header.attended.lectures=Attended
-noticed.type.dispensation=Dispensation
-coach.absence=Absences
-add.reason=Add reason
-search.form.string.hint=You can search title of lecture blocks and title or external reference of courses. External reference is an exact match.
-lecture.calculate.attendance.rate.default.enabled=Calculate attendance rate (default)
-lecture.course.admin.title=Configuration of lectures and absence management in course
-appeal.approved=Approved
-add.assessment.mode=Mark as exam
+#Tue Aug 20 13:54:06 CEST 2019
+absence.category=Reason of absence
 absence.category.copied=Reason of absence was successfully copied.
-user.overview.appeals=Appeals
-profile=Profile
-add.dispensation.title=Record dispensation
+absence.category.copy={0} (copie)
+absence.category.description=Description
+absence.category.in.use=This reason of absence is still used by some notices and cannot be deleted.
+absence.category.title=Reason of the absence
+absences.batch.authorize=Authorize absence
+absences.title=List of absences
 active=Active
-pdf.table.header.signature=Signature
-absence.category=Reason of absence
+add.absence=Record new absence
+add.absence.category=Add absences reason
+add.absence.title=Record an absence
+add.assessment.mode=Mark as exam
+add.dispensation=Record new dispensation
+add.dispensation.title=Record dispensation
+add.lecture=New lecture block
+add.notice.absence=Record new notice of absence
+add.notice.absence.title=Record notice of absence
+add.reason=Add reason
+admin.menu.title=Lectures
+admin.menu.title.alt=Lectures and absence management
+afternoon=Afternoon
+aggregated.list=Aggregated list
+alert.appeal.pending=<strong>A</strong> pending appeal was found.
+alert.appeals.pending=<strong>{0}</strong> pending appeals was found.
+all=All
+all.desc=Mark all lectures as absent
+all.teachers.switch=All teachers
 all.teachers.switch.tooltip.off=Show all lecture blocks
-sync.course.calendar.enabled=Synchronize courses calendars
-no.teachers=No coaches yet
-cockpit.pending.days=There is some lectures which are not already closed. Please record the absences for the following day\:
-table.header.lecture.9=9
-lectures.with.curriculum=Absences within a curriculum
-table.header.lecture.1=1
-noticed.targets=Absence for
-partiallydone=Partially done
-table.header.absent.lectures=Absent
-table.header.lecture.2=2
-table.header.lecture.3=3
-pdf.table.header.all=All
-table.header.lecture.4=4
-rate.error.title=The attendance rate is under the mandatory limit.
-table.header.lecture.5=5
-export.header.location=Room\: {0}
-table.header.lecture.6=6
-table.header.lecture.7=7
-multi.rollcall.callee.title=Daily overview
-noticed.identity=Absent person
-table.header.lecture.8=8
-config.sync.course.calendar=Synchronize course calendar
-table.legend.authorized=Authorized absence
-edit.absence.category=Edit reason of absence
-log.remove.rate=Remove attendance rate
-contact.teachers=Contact teachers
-assessment.tool=Assessment tool
-lecture.block.dateAndTime={2} from {3} to {4}
-lecture.absence.default.authorized=Absence per default authorized
-absence.category.in.use=This reason of absence is still used by some notices and cannot be deleted.
-lecture.teacher.can.authorize.absence=Teachers can authorize absences
-import.lectures=Import lecture blocks
-date.end=$org.olat.repository\:cif.date.end
-lecture.mastercoach.can.see.absence=Master coaches can see absences
-lecture.groups=Course / groups / curriculum
-search.form.login=Username
+all.teachers.switch.tooltip.on=Show only my lecture blocks
+appeal=Appeal
+appeal.approved=Approved
+appeal.batch.update=Change status
+appeal.body=<p>Dear {1}</p>
+appeal.body.title=<h4>Appeal of the following lecture block\:</h4><p><a href\="{3}">{3}</a></p>
+appeal.closed=Closed
+appeal.contact.list=Teacher
+appeal.form.explain=The decision need to be motivated.
+appeal.from=From {0}
+appeal.pending=Pending
+appeal.rejected=Rejected
+appeal.sent=Send at {0}
+appeal.sent.tooltip=Appeal was sent at {0}
+appeal.status=Status
+appeal.subject=Appeal lecture block "{0}"
+appeal.title=Appeal for\: "{0}"
+appeal.tooltip=Appeal possible from {0} until {1}
+appeals.title=List of appeals
 appeals.update.title=Edit {0} appeal(s)
+archive.entry=Archive
+assessment.tool=Assessment tool
+attachment.upload=Doctor's certificate, justification etc.
 attendance.list=Absence list
+attendance.list.title=Absence list\: {0}
+attendance.list.to.sign=Attendance list
+attendance.list.to.sign.title=Attendance list\: {0}
+authorized.absence=Authorized
+authorized.absence.reason=Reason
+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
+bulk.hint=You can give a list of user names or email addresses separated by a return.
+cancel.lecture.blocks=Cancel lectures
+cancelled=Cancelled
+close.lecture.blocks=Close lectures
+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
+coach.cockpit=Cockpit
+coach.dispensation=Notices of absence / dispensation
 coach.lectures=Lectures
-detailled.list=Detailled list
-lecture.admin.global.title=Global configuration
-table.header.authorized.absence=Excused
-user.overview.lectures=Lectures and absences
-delete.assessment.mode=Delete exam
-lecture.block.copied=The lectures block was successfully copied.
-dates.public=$org.olat.repository\:cif.dates.public
-start.desktop=Desktop
-appeal.body=<p>Dear {1}</p>
-lecture.teacher=Teacher
-table.header.owners=Course owners
-lecture.start=Begin
-add.absence=Record new absence
-noticed.type=Type
+coach.lectures.search=User search
+coach.report=Report
+cockpit.absences=Absences
+cockpit.date=for {0}
+cockpit.day.overview=Daily overview
+cockpit.lectures=Lectures
 cockpit.lectures.day.list=You don't have any lectures this day.
-user.profil=User profil
-save.next=Save and next
-not.authorized.absence=Not authorized
-managed.flags.lecture.block.preparation=Preparation
-noticed.lectures=Lectures
-table.header.num.lecture.block=Lectures
-search.form.status.open=$\:open
-table.header.log.user=User
-tool.teacher=As teacher
-rollcall.tooltip.absence=Absent
+cockpit.pending.day={0} {1} ({2} lectures)
 cockpit.pending.day.plural={0} {1} ({2} lectures)
-lecture.show.all.teachers.mine=Only my lectures block
+cockpit.pending.days=There is some lectures which are not already closed. Please record the absences for the following day\:
+cockpit.pending.days.plural=There is some lectures which are not already closed. Please record the absences for the following days\:
+config.calculate.attendance.rate=Calculate attendance rate
+config.override=Override default configuration
+config.override.no=No
+config.override.yes=Yes
+config.rollcall.enabled=Roll call enabled
+config.sync.course.calendar=Synchronize course calendar
+config.sync.participant.calendar=Synchronize participants calendar
+config.sync.teacher.calendar=Synchronize teacher calendar
 confirm.delete.absence.category=Do you really want to delete this reason of absence "{0}"?
-lecture.can.override.standard.configuration=Allow override of configuration
-close.lecture.blocks=Close lectures
-mail.subject=Subject
-num.warnings.notice.absence.explain={0} of unauthorized notice(s) of absence
-pdf.table.header.comment=Comment
-search.form.till=till
-absences.batch.authorize=Authorize absence
-first.admission=First admission
-pdf.table.header.lectures=Lectures
-attendance.list.to.sign=Attendance list
-multi.rollcall.callee.title.for=for {0}
-rollcall.absence.notice=Notice of absence
-appeal.rejected=Rejected
-notice.search=Search
-save.temporary=Quick save
-search.form.category=Reason
-appeal.body.title=<h4>Appeal of the following lecture block\:</h4><p><a href\="{3}">{3}</a></p>
-absences.title=List of absences
-coach.lectures.search=User search
-lecture.daily.batch.absence.start=No, first at start time of lecture blocks
-lecture.teacher.reminder.body=Reminder lectures block "{0}" in course {3}
-previous.participant=Back to previous participant
-rollcall=Roll call
-managed.flags.lecture.block.plannedLectures=Planned lectures
-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.
-appeal.pending=Pending
-table.header.num.absences=Number of absent participants
-noticed.absence.unauthorized=Absent
-repo.lectures.appeals=Appeals
-cockpit.lectures=Lectures
-close.lecture.blocks.day=Close lectures for {0}
-info.no.lectures=You don't follow any lectures for the moment.
-entry.rate=Course's rate
-table.header.unauthorized.absence=Not excused
-lecture.assessment.mode.enabled=Allow assessment mode for lectures
-num.alert.absence.explain={0} of unauthorized absence(s)
-pdf.table.dates={0} from {1} to {2}
-lecture.participant.can.notice=Participants are allowed to notify an absence
-public.dates=$org.olat.repository\:cif.public.dates
-table.header.external.ref=Ext. ref.
-lecture.assessment.mode.seb=Safe Exam Browser Keys
-lecture.time.until=until
-search.date=Date
-lecture.teacher.reminder.subject=Reminder lectures block "{0}"
-reason.id=ID
-sync.participants.calendar.enabled=Synchronize participants calendars
-warning.choose.at.least.one.appeal=You need to choose at least one appeal
-lecture.time=Time
-filter.showAll=Show all
-table.header.planned.lectures=Lectures
+confirm.delete.assessment.mode.text=Do you really want to delete the exam of this lecture block "{0}"?
 confirm.delete.assessment.mode.title=Delete exam
-lecture.taxonomy=Taxonomy
-lecture.status.enabled=Lectures status
-noticed.type.absence=Without notification
-in.progress=In process
+confirm.delete.lectures=Do you really want to delete these lectures "{0}"?
+confirm.delete.reason=Do you really want to delete this reason "{0}"?
+contact.teachers=Contact teachers
+contact.teachers.list.name=Teachers
+copy=Copy
+current.lecture=Current lectures
+date.end=$org.olat.repository\:cif.date.end
+date.start=$org.olat.repository\:cif.date.start
+dates=$org.olat.repository\:cif.dates
+dates.none=$org.olat.repository\:cif.dates.none
+dates.private=$org.olat.repository\:cif.dates.private
+dates.public=$org.olat.repository\:cif.dates.public
+delete.assessment.mode=Delete exam
+delete.lectures.title=Delete lectures
+delete.title=Delete reason
+detailled.list=Detailled list
+details=Details
+dispensations.title=Notices of absence / dispensations
+done=Done
+edit.absence.category=Edit reason of absence
+edit.assessment.mode=Edit exam
+edit.participant.rate=Edit participant's rate
+edit.reason=Edit reason
+edit.type.absence=Edit absence
+edit.type.dispensation=Edit dispensation
+edit.type.notice.absence=Edit notice of absence
+effective.lectures=Effective lectures
+empty.absences.list=There isn't any absences/dispensations with the wished criteria.
+empty.appeals.list=There is no appeal which meets your criteria.
+empty.lectures.list=The table is empty
+empty.repository.entry.lectures=You haven't need to follow a lecture in the course.
+empty.table.current.lectures.blocks=There are not lectures to start at the moment.
+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.
-lecture.count.authorized.absence.attendant=Count authorized absence as attendant
-lectures.table.pending=Pending lecture blocks
-search.form.type=Type
+entry.rate=Course's rate
+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
+error.search.form.notempty=Please fill in at least one field with two characters.
 error.unauthorized.absence.msg=<strong>A</strong> unauthorized absence was found.
-notice.reason.title=Reason of absence
-several.entries=Several
-override.lecture=Override external management
-export.header.lectures=Lectures
-managed.flags.lecture.block.groups=Course / groups
-lecture.descr=Description
-bulk.example=test01<br>author02<br>test@openolat.org
-noticed.target.all=All courses
-cancelled=Cancelled
-appeal.title=Appeal for\: "{0}"
-bulk=User names, $org.olat.user.propertyhandlers\:table.name.email oder $org.olat.user.propertyhandlers\:table.name.institutionalUserIdentifier
-lectures.admin.reasons=Reasons lectures
-absence.category.title=Reason of the absence
-table.legend.attended=Attended
-lecture.autoclose.notification.subject=Lecture block "{0}" autoerledigt
-authorized.absence=Authorized
-appeal.batch.update=Change status
-lecture.admin.course.override.title=Configuration - can be overridden at course level
-coach.report=Report
-search.form.status.reopen=$\:reopen
-lecture.assessment.mode.ips=Admissible IP addresses
-table.header.absence=Absence
-lecture.block.comment=Comment
-lectures.table.current=Current lecture block
-repo.lectures=Lectures
-admin.menu.title.alt=Lectures and absence management
-managed.flags.lecture.block.settings=Configuration
-menu.my.lectures.alt=Lectures and absences
-search.curriculums=Search by curriculums
-edit.participant.rate=Edit participant's rate
-notice.dates.lectures.title=Context
-form.managedflags.intro.short=This lecture block has been created by an external tool. Therefore some settings can not be modified and used within OpenOlat.
-appeal.closed=Closed
-lecture.status.partially.done.enabled=Allow holding partial lectures
-delete.lectures.title=Delete lectures
+error.unauthorized.absences.msg=<strong>{0}</strong> unauthorised absences was found.
 evening=Evening
-lectures.repository.print.title=Lectures and absences of {1} in course {0}
-rollcall.status=Roll call status
-unauthorized.filter=Unauthorized
-table.header.preparation=Preparation
-confirm.delete.assessment.mode.text=Do you really want to delete the exam of this lecture block "{0}"?
-tool.participant=As participant
-noticed.duration=Duration
-reason.copied=Reason was successfully copied.
-table.header.progress=Grafik
-open.course=Open course
-error.atleastone.lecture=Please choose at least one lecture block.
-mail.body=Message
-lecture.appeal.absence.enabled=Appeal absence enabled
-all=All
-cancel.lecture.blocks=Cancel lectures
-rollcall.dispensation=Dispensation
-dispensations.title=Notices of absence / dispensations
-unauthorized.filter.label=Display
-table.header.infos=<i class\='o_icon o_icon-lg o_icon_info'>  </i>
-table.legend.absent=Absent
+export.footer.lectures.hint=x \= lecture absent
 export.header.entry=Course\: {0}
-table.header.id=ID
-site.title.alt=Lectures management
-search.form.string=Search
-start.mobile=Mobile
-log.add.admission.date=Add admission date {0}
-table.header.rate=Presence
-lecture.time.from=from
-managed.flags.lecture.block.compulsory=Compulsory
-reason.deleted=Reason was successfully deleted.
-search.participants=Search by participants
-empty.table.current.lectures.blocks=There are not lectures to start at the moment.
-lecture.show.all.teachers.all=Lectures block of all teachers
-attendance.list.to.sign.title=Attendance list\: {0}
-total=Total
-table.header.log.effective.lectures=Effective lectures
-lecture.auto.close.period=Auto close period in days
-rollcall.tooltip.authorized.absence=Authorized absence
-today=Today
-lecture.reminder.period=Reminder period in days
-noticed.notice.absence=Notice of absence
-search.form.status=Status
-table.header.absences.alert=Number of unauthorized absences
-table.header.log.planned.lectures=Planned lectures
-noticed.duration.days=Day choice
-unoverride.lecture=Stop override
-appeal.subject=Appeal lecture block "{0}"
-coach.cockpit=Cockpit
-table.header.import.status=Status
-noticed.till=till
+export.header.lectureblocks=Lectures block\: {0} the {1} at {2} until {3}
+export.header.lectures=Lectures
+export.header.location=Room\: {0}
+export.header.teachers=Teachers\: {0}
+filter.mandatory=Compulsory
+filter.showAll=Show all
+filter.warning=Warnings
+first.admission=First admission
+form.managedflags.intro=This lecture block has been created by an external tool. Therefore some settings and modules can not be modified and used within OpenOlat. The following elements are blocked within OpenOlat\: {0}
+form.managedflags.intro.short=This lecture block has been created by an external tool. Therefore some settings can not be modified and used within OpenOlat.
+from=from {0}
+import.lectures=Import lecture blocks
+in.progress=In process
+info.lecture.block.optional=This lecture block is optional.
+info.no.lectures=You don't follow any lectures for the moment.
+infos.participant.attendance.rate=Personal attendance rate\: {0}%
+interceptor.start=You have now a roll call for the course "{0}" {1} from {4} until {5}.
+lecture.absence.default.authorized=Absence per default authorized
+lecture.admin.course.override.title=Configuration - can be overridden at course level
+lecture.admin.enabled=Enable lectures and absence management
+lecture.admin.global.title=Global configuration
+lecture.appeal.absence.enabled=Appeal absence enabled
+lecture.appeal.absence.period=Appeal absence period in days
+lecture.assessment.mode.enabled=Allow assessment mode for lectures
+lecture.assessment.mode.followup.time=Follow-up
+lecture.assessment.mode.ips=Admissible IP addresses
+lecture.assessment.mode.leading.time=Prep time
+lecture.assessment.mode.seb=Safe Exam Browser Keys
 lecture.attendance.rate.default=Attendance quota global in %
-reason.copy={0} (Copy)
-reason=Reason
-error.search.form.notempty=Please fill in at least one field with two characters.
-pdf.table.header.participants=First name / last name
-table.header.num.participants=\#
-noticed.dispensation=Dispensation
-tools.import.table=Import lecture blocks from Excel
+lecture.authorized.absence.enabled=Authorized absences
+lecture.auto.close.period=Auto close period in days
+lecture.autoclose.notification.body=<p>Dear course administrator</p><p>We want inform you that the lecture block was closed automatically. With the following link, you can access the lecture block\:<br><a href\='{3}'>{3}</a></p>
+lecture.autoclose.notification.subject=Lecture block "{0}" autoerledigt
+lecture.block=Lectures block
+lecture.block.comment=Comment
+lecture.block.copied=The lectures block was successfully copied.
+lecture.block.copy={0} (Copy)
+lecture.block.dateAndTime={2} from {3} to {4}
+lecture.block.effective.end=Effective end
+lecture.block.effective.reason=Reason
+lecture.block.status=Status
+lecture.calculate.attendance.rate.default.enabled=Calculate attendance rate (default)
+lecture.can.override.standard.configuration=Allow override of configuration
+lecture.compulsory=Compulsory
+lecture.count.authorized.absence.attendant=Count authorized absence as attendant
+lecture.course.admin.title=Configuration of lectures and absence management in course
+lecture.daily.batch.absence=Daily recording absences
+lecture.daily.batch.absence.day=Yes, recording of the absences of all lectures blocks of the day
+lecture.daily.batch.absence.start=No, first at start time of lecture blocks
 lecture.date=Date
-search.entries=Search by courses
-table.legend.unauthorized=Not authorized absence
-table.header.appeal.status=Appeal
-wizard.entries.label.blocks=<strong>{0}</strong> <small>{1}</small> ({2} lectures blocks)
-noticed.duration.today=Today
-current.lecture=Current lectures
-edit.assessment.mode=Edit exam
-reason.in.use=This reason is still used by some lectures and cannot be deleted.
-error.reason.mandatory=Reason is mandatory
-filter.mandatory=Compulsory
-table.header.compulsory.long=Compulsory presence
+lecture.deleted=Lectures was successfully deleted.
+lecture.descr=Description
+lecture.end=End
+lecture.from.to=Time from\:
+lecture.from.to.format={0} until {1}
+lecture.groups=Course / groups / curriculum
+lecture.location=Location
 lecture.mastercoach.can.authorize.absence=Master coaches can authorize absences
-morning=Morning
-appeal.sent.tooltip=Appeal was sent at {0}
-rollcall.tooltip.ok=Present
-form.managedflags.intro=This lecture block has been created by an external tool. Therefore some settings and modules can not be modified and used within OpenOlat. The following elements are blocked within OpenOlat\: {0}
-repo.settings=Configuration
-empty.repository.entry.lectures=You haven't need to follow a lecture in the course.
-rollcall.absence=Absence
-cockpit.absences=Absences
-absence.category.copy={0} (copie)
-appeal.sent=Send at {0}
-lectures.admin.permissions=Permissions
-aggregated.list=Aggregated list
-multi.rollcall.title.for=for {0} ({1} lecture blocks)
-warning.repositoryentry.deleted=$org.olat.repository\:repositoryentry.deleted
-coach.dispensation=Notices of absence / dispensation
-appeal.status=Status
-multi.rollcall.title=Multi-lectures recording
+lecture.mastercoach.can.authorize.appeal=Master coaches can authorize appeals
+lecture.mastercoach.can.record.notice=Master coaches can record notice of absences
+lecture.mastercoach.can.see.absence=Master coaches can see absences
+lecture.mastercoach.can.see.appeal=Master coaches can see appeals
 lecture.owner.can.view.all.curriculum.elements=Course owner can see all courses in curriculum elements
-table.header.lecture.block=Lecture block
-error.integer.between=The input must be a number between {0} and {1}
+lecture.participant.can.notice=Participants are allowed to notify an absence
 lecture.preparation=Preparation
-upto=till {0}
-lecture.title=Title
+lecture.reminder.enabled=Reminder enabled
+lecture.reminder.period=Reminder period in days
+lecture.rollcall.default.enabled=Roll call enabled (default)
+lecture.show.all.teachers=Default display in course
+lecture.show.all.teachers.all=Lectures block of all teachers
+lecture.show.all.teachers.mine=Only my lectures block
+lecture.start=Begin
+lecture.status.enabled=Lectures status
+lecture.status.partially.done.enabled=Allow holding partial lectures
+lecture.taxonomy=Taxonomy
+lecture.teacher=Teacher
+lecture.teacher.can.authorize.absence=Teachers can authorize absences
+lecture.teacher.can.authorize.appeal=Teachers can authorize appeals
 lecture.teacher.can.see.appeal=Teachers can see appeals
-appeal=Appeal
-info.lecture.block.optional=This lecture block is optional.
-notice.start.date=Start date
-table.header.presence=Present
+lecture.teacher.reminder.body=Reminder lectures block "{0}" in course {3}
+lecture.teacher.reminder.subject=Reminder lectures block "{0}"
+lecture.time=Time
+lecture.time.from=from
+lecture.time.until=until
+lecture.title=Title
+lectures.admin.absences.categories=Reasons absences
+lectures.admin.permissions=Permissions
+lectures.admin.permissions.title=Teachers / master coaches permissions
+lectures.admin.reasons=Reasons lectures
+lectures.admin.report=Lectures report
+lectures.admin.settings=Settings lectures and absence management
+lectures.print.title=Lectures and absences of {0}
+lectures.repository.print.title=Lectures and absences of {1} in course {0}
+lectures.table.closed=Closed lecture blocks
+lectures.table.current=Current lecture block
+lectures.table.next=Next lecture blocks
+lectures.table.pending=Pending lecture blocks
+lectures.with.curriculum=Absences within a curriculum
+lectures.without.curriculum=Absences outside of a curriculum
+log=Log
+log.add.admission.date=Add admission date {0}
+log.add.rate=Add attendance rate {0}
+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
+managed.flags.lecture.block.delete=Delete lectures block
+managed.flags.lecture.block.description=Description
 managed.flags.lecture.block.details=Title, description...
-table.header.compulsory=<i class\='o_icon o_icon_compulsory o_icon-lg'> </i>
-num.warnings.dispensation.explain={0} of unauthorized dispensation
-closed=Closed
-appeal.from=From {0}
-appeal.form.explain=The decision need to be motivated.
-repo.participants=Participants
-managed.flags.lecture.block.title=Title
-open=Open
-table.header.comment=Comment
-add.notice.absence.title=Record notice of absence
-noticed.duration.exact=Exact (with daytime)
-rollcall.comment=Comment
-cockpit.date=for {0}
-error.collision=There is already an absence at these dates.
-noticed.reason=Comment
-table.header.details=<i class\='o_icon o_icon_lecture o_icon-lg'> </i>
-lecture.block=Lectures block
-table.header.start.time=From
-lecture.block.copy={0} (Copy)
-edit.type.notice.absence=Edit notice of absence
-details=Details
-add.lecture=New lecture block
-table.header.notice.type=Type
-results=Results
-table.header.identifier=Identifier
-reason.title=Reason
-date.start=$org.olat.repository\:cif.date.start
-lecture.assessment.mode.leading.time=Prep time
-table.header.num.presences=Number of present participants
-reopen=Reopen
+managed.flags.lecture.block.groups=Course / groups
 managed.flags.lecture.block.location=Location
-remove.custom.rate=Remove custom rate
-interceptor.start=You have now a roll call for the course "{0}" {1} from {4} until {5}.
-filter.warning=Warnings
-export.header.lectureblocks=Lectures block\: {0} the {1} at {2} until {3}
-alert.appeal.pending=<strong>A</strong> pending appeal was found.
-sync.teachers.calendar.enabled=Synchronize teachers calendars
-contact.teachers.list.name=Teachers
-lecture.rollcall.default.enabled=Roll call enabled (default)
-lectures.admin.settings=Settings lectures and absence management
-table.header.actions=<i class\='o_icon o_icon_actions o_icon-lg'> </i>
-all.desc=Mark all lectures as absent
-add.dispensation=Record new dispensation
+managed.flags.lecture.block.plannedLectures=Planned lectures
+managed.flags.lecture.block.preparation=Preparation
+managed.flags.lecture.block.settings=Configuration
+managed.flags.lecture.block.teachers=Teacher
+managed.flags.lecture.block.title=Title
+menu.my.lectures=Absences
+menu.my.lectures.alt=Lectures and absences
+morning=Morning
+multi.rollcall.callee.title=Daily overview
+multi.rollcall.callee.title.for=for {0}
+multi.rollcall.title=Multi-lectures recording
+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
+notice.search=Search
+notice.start.date=Start date
 noticed.absence.authorized=Authorized
-wizard.lectureblock.label=<strong>{0}</strong> <small>{1}</small><br>{2} {3} - {4} {5} lessons\: "{6}" with {7}
-cockpit.pending.days.plural=There is some lectures which are not already closed. Please record the absences for the following days\:
-table.header.description=Description
+noticed.absence.unauthorized=Absent
+noticed.autorized.yes=Authorized
 noticed.category=Justification
-lecture.block.effective.end=Effective end
-edit.type.absence=Edit absence
-participant.rate=Rate
-log.add.rate=Add attendance rate {0}
-empty.appeals.list=There is no appeal which meets your criteria.
-export.header.teachers=Teachers\: {0}
-log.remove.admission.date=Remove admission date
-table.header.log.effective.end.date=Effective end date
-lectures.admin.absences.categories=Reasons absences
-table.header.edit=<i class\='o_icon o_icon_edit o_icon-lg'> </i>
-admin.menu.title=Lectures
-confirm.delete.lectures=Do you really want to delete these lectures "{0}"?
-export.footer.lectures.hint=x \= lecture absent
-lecture.deleted=Lectures was successfully deleted.
-table.header.rate.warning=<i class\="o_icon o_midwarn"> </i>
+noticed.dispensation=Dispensation
+noticed.duration=Duration
+noticed.duration.days=Day choice
+noticed.duration.exact=Exact (with daytime)
+noticed.duration.today=Today
+noticed.entries=Courses
+noticed.identity=Absent person
+noticed.lectures=Lectures
+noticed.notice.absence=Notice of absence
+noticed.reason=Comment
+noticed.target.all=All courses
+noticed.target.courses=Selected courses
+noticed.target.lectureblocks=Selected lecture blocks
+noticed.targets=Absence for
+noticed.teachers=Teachers
+noticed.till=till
+noticed.type=Type
+noticed.type.absence=Without notification
+noticed.type.dispensation=Dispensation
+noticed.type.notified=Notice of absence
+num.alert.absence.explain={0} of unauthorized absence(s)
+num.warnings.dispensation.explain={0} of unauthorized dispensation
+num.warnings.notice.absence.explain={0} of unauthorized notice(s) of absence
+open=Open
+open.course=Open course
 open.specific.course=Open "{0}"
+override.lecture=Override external management
+partiallydone=Partially done
+participant.rate=Rate
+participant.rate.edit=Personal rate
+pdf.table.dates={0} from {1} to {2}
+pdf.table.header.all=All
+pdf.table.header.authorised=Auth.
+pdf.table.header.comment=Comment
+pdf.table.header.lectures=Lectures
+pdf.table.header.participants=First name / last name
+pdf.table.header.signature=Signature
+planned.lectures=Planned lectures
+previous.participant=Back to previous participant
+private.dates=$org.olat.repository\:cif.private.dates
+profile=Profile
+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.
-table.header.effective.lectures=Lectures
-lectures.table.closed=Closed lecture blocks
+reason=Reason
+reason.copied=Reason was successfully copied.
+reason.copy={0} (Copy)
+reason.deleted=Reason was successfully deleted.
+reason.description=Description
+reason.id=ID
+reason.in.use=This reason is still used by some lectures and cannot be deleted.
+reason.title=Reason
+remove.custom.rate=Remove custom rate
+reopen=Reopen
 reopen.lecture.blocks=Reopen lectures
-table.header.attended.current.rate=% Attended
-noticed.target.lectureblocks=Selected lecture blocks
-table.header.location=Location
-config.override.yes=Yes
-lectures.without.curriculum=Absences outside of a curriculum
-close.lecture.blocks.confirmation={0} lectures at {1} will be closed.
-search.form.status.closed=$\:closed
-new.appeal.title=New appeal
-empty.absences.list=There isn't any absences/dispensations with the wished criteria.
-appeal.tooltip=Appeal possible from {0} until {1}
-managed.flags.lecture.block.all=Fully externally managed
-pdf.table.header.authorised=Auth.
-dates=$org.olat.repository\:cif.dates
-managed.flags.lecture.block.delete=Delete lectures block
-error.integer.positive=The number must be positive.
-menu.my.lectures=Absences
+repo.lectures=Lectures
+repo.lectures.appeals=Appeals
+repo.lectures.block=Lecture blocks
+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
-lecture.end=End
-add.absence.category=Add absences reason
-managed.flags.lecture.block.dates=Dates
-log.change.admission.date=Update admission date {0}
-table.header.log.author=Changed by
+rollcall.tooltip.ok=Present
+rollcall.tooltip.unauthorized.absence=Not authorized 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
+search.form.start=Start
+search.form.status=Status
+search.form.status.autoclosed=$\:autoclosed
+search.form.status.closed=$\:closed
+search.form.status.open=$\:open
+search.form.status.reopen=$\:reopen
+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.participants=Search by participants
 search.teachers=Search by teachers
-lecture.teacher.can.authorize.appeal=Teachers can authorize appeals
-reason.description=Description
-lecture.compulsory=Compulsory
-planned.lectures=Planned lectures
+send=Send
+several.entries=Several
+site.title=Lectures management
+site.title.alt=Lectures management
+start.desktop=Desktop
 start.label=Roll call
-error.unauthorized.absences.msg=<strong>{0}</strong> unauthorised absences was found.
-noticed.entries=Courses
+start.mobile=Mobile
 start.wizard=Start wizard
-log=Log
-table.header.username=Username
-search.form.start=Start
-config.calculate.attendance.rate=Calculate attendance rate
-tools=Action
-lectures.admin.report=Lectures report
-table.header.lecture.11=11
+sync.course.calendar.enabled=Synchronize courses calendars
+sync.participants.calendar.enabled=Synchronize participants calendars
+sync.teachers.calendar.enabled=Synchronize teachers calendars
+table.header.absence=Absence
+table.header.absences.alert=Number of unauthorized absences
+table.header.absences.warning=Number of unauthorized dispensation and notices
+table.header.absent.lectures=Absent
+table.header.actions=<i class\='o_icon o_icon_actions o_icon-lg'> </i>
+table.header.appeal.status=Appeal
+table.header.assessment.mode=Exam
+table.header.attended.current.rate=% Attended
+table.header.attended.lectures=Attended
+table.header.authorized.absence=Excused
+table.header.auto.close.date=Auto closed at
+table.header.comment=Comment
+table.header.compulsory=<i class\='o_icon o_icon_compulsory o_icon-lg'> </i>
+table.header.compulsory.long=Compulsory presence
+table.header.date=Date
+table.header.description=Description
+table.header.details=<i class\='o_icon o_icon_lecture o_icon-lg'> </i>
+table.header.edit=<i class\='o_icon o_icon_edit o_icon-lg'> </i>
+table.header.effective.lectures=Lectures
+table.header.end.time=To
+table.header.entry=Course
+table.header.export=Export
+table.header.external.ref=Ext. ref.
+table.header.id=ID
+table.header.identifier=Identifier
+table.header.import.status=Status
+table.header.infos=<i class\='o_icon o_icon-lg o_icon_info'>  </i>
+table.header.lecture.1=1
 table.header.lecture.10=10
-table.header.lecture.13=13
+table.header.lecture.11=11
 table.header.lecture.12=12
-lecture.daily.batch.absence=Daily recording absences
-private.dates=$org.olat.repository\:cif.private.dates
+table.header.lecture.13=13
 table.header.lecture.14=14
-copy=Copy
-managed.flags.lecture.block.teachers=Teacher
-noticed.target.courses=Selected courses
-add.notice.absence=Record new notice of absence
-appeal.contact.list=Teacher
-table.header.teachers=Coaches
-warning.edit.lecture=Roll call ist deactivated.
-table.header.absences.warning=Number of unauthorized dispensation and notices
-bulk.hint=You can give a list of user names or email addresses separated by a return.
+table.header.lecture.2=2
+table.header.lecture.3=3
+table.header.lecture.4=4
+table.header.lecture.5=5
+table.header.lecture.6=6
+table.header.lecture.7=7
+table.header.lecture.8=8
+table.header.lecture.9=9
+table.header.lecture.block=Lecture block
+table.header.location=Location
 table.header.log.action=Action
-add.absence.title=Record an absence
-dates.none=$org.olat.repository\:cif.dates.none
-repo.lectures.block=Lecture blocks
-rollcall.tooltip.unauthorized.absence=Not authorized absence
-lecture.from.to.format={0} until {1}
-appeals.title=List of appeals
-lecture.block.status=Status
-user.overview.dispensation=Dispensation
-warning.teachers.at.least.one.contact=There isn't any teacher to contact
-lecture.appeal.absence.period=Appeal absence period in days
-next.participant=To the next participant
-lectures.admin.permissions.title=Teachers / master coaches permissions
-table.header.assessment.mode=Exam
-lecture.autoclose.notification.body=<p>Dear course administrator</p><p>We want inform you that the lecture block was closed automatically. With the following link, you can access the lecture block\:<br><a href\='{3}'>{3}</a></p>
-alert.appeals.pending=<strong>{0}</strong> pending appeals was found.
-table.header.entry=Course
-table.header.end.time=To
-lectures.table.next=Next lecture blocks
-table.header.times=Time
-dates.private=$org.olat.repository\:cif.dates.private
-from=from {0}
-lectures.print.title=Lectures and absences of {0}
-lecture.mastercoach.can.record.notice=Master coaches can record notice of absences
-config.sync.participant.calendar=Synchronize participants calendar
-table.header.auto.close.date=Auto closed at
-config.sync.teacher.calendar=Synchronize teacher calendar
+table.header.log.author=Changed by
+table.header.log.effective.end.date=Effective end date
+table.header.log.effective.lectures=Effective lectures
+table.header.log.planned.lectures=Planned lectures
+table.header.log.user=User
+table.header.notice.type=Type
+table.header.num.absences=Number of absent participants
+table.header.num.lecture.block=Lectures
+table.header.num.participants=\#
+table.header.num.presences=Number of present participants
+table.header.owners=Course owners
+table.header.participants=Participants
+table.header.planned.lectures=Lectures
+table.header.preparation=Preparation
+table.header.presence=Present
+table.header.progress=Grafik
+table.header.rate=Presence
+table.header.rate.warning=<i class\="o_icon o_midwarn"> </i>
 table.header.reason=Reason
-done=Done
-config.override=Override default configuration
-cockpit.day.overview=Daily overview
-lecture.from.to=Time from\:
-notice.end.date=End date
-lecture.reminder.enabled=Reminder enabled
-all.teachers.switch=All teachers
-search.form.end=Until
-log.change.rate=Update attendance rate {0}
-archive.entry=Archive
-send=Send
-noticed.autorized.yes=Authorized
-lecture.show.all.teachers=Default display in course
+table.header.start.time=From
 table.header.status=Status
-lecture.authorized.absence.enabled=Authorized absences
-attendance.list.title=Absence list\: {0}
-managed.flags.lecture.block.description=Description
-cockpit.pending.day={0} {1} ({2} lectures)
-coach.appeals=Appeals
-empty.table.lectures.blocks.admin=No lecture blocks have been created for this course so far.
-edit.type.dispensation=Edit dispensation
-autoclosed=Auto-closed
-wizard.entries.label.block=<strong>{0}</strong> <small>{1}</small> ({2} lectures block)
-lecture.assessment.mode.followup.time=Follow-up
-lecture.daily.batch.absence.day=Yes, recording of the absences of all lectures blocks of the day
-delete.title=Delete reason
-effective.lectures=Effective lectures
-empty.lectures.list=The table is empty
-lecture.admin.enabled=Enable lectures and absence management
+table.header.teachers=Coaches
+table.header.times=Time
+table.header.tools=<i class\='o_icon o_icon_actions o_icon-lg'> </i>
+table.header.unauthorized.absence=Not excused
+table.header.username=Username
+table.legend.absent=Absent
+table.legend.attended=Attended
+table.legend.authorized=Authorized absence
+table.legend.free=Free lecture
+table.legend.unauthorized=Not authorized absence
+today=Today
+tool.participant=As participant
+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
+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
+warning.teachers.at.least.one.contact=There isn't any teacher to contact
 whole.day=Whole day
-search.form.status.autoclosed=$\:autoclosed
-all.teachers.switch.tooltip.on=Show only my lecture blocks
-afternoon=Afternoon
-absence.category.description=Description
-site.title=Lectures management
-table.header.export=Export
-config.rollcall.enabled=Roll call enabled
-confirm.delete.reason=Do you really want to delete this reason "{0}"?
-lecture.location=Location
+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}
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 4485066225edd2dc36ad92306548ff986c6c0cee..c562a6d29bfa320e12c5dce7a5cd88b5506e974c 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,405 +1,405 @@
-#Mon Aug 19 18:49:44 CEST 2019
-edit.reason=Editer la justification
-table.legend.free=Le\u00E7on facultative
-config.override.no=Non
-table.header.tools=<i class\='o_icon o_icon_actions o_icon-lg'> </i>
-lecture.block.effective.reason=Justification
-authorized.absence.reason=Justification
-table.header.date=Date
-noticed.teachers=Charg\u00E9s de cours
-table.header.participants=Participants
-participant.rate.edit=Valeur seuil personelle
-empty.table.lectures.blocks=Aucun cours bloc n'a \u00E9t\u00E9 trouv\u00E9.
-infos.participant.attendance.rate=Valeur seuil personelle\: {0}%
-table.header.attended.lectures=Pr\u00E9sent
-coach.absence=Absences
-add.reason=Cr\u00E9er une justification
-search.form.string.hint=Vous pouvez chercher les titres d'un bloc de cours ou sa r\u00E9f\u00E9rence externe. Lors de la recherche avec la r\u00E9f\u00E9rence externe, seuls les r\u00E9sultats exacts sont affich\u00E9s.
-lecture.calculate.attendance.rate.default.enabled=Calcul du taux de pr\u00E9sence
-lecture.course.admin.title=Configuration des cours blocs et absences du cours
-appeal.approved=Approuv\u00E9
-add.assessment.mode=Marqu\u00E9 comme \u00E9valuation
+#Tue Aug 20 13:54:17 CEST 2019
+absence.category=Raison de l'absence
 absence.category.copied=La raison de l'absence a \u00E9t\u00E9 copi\u00E9 avec succ\u00E8s.
-user.overview.appeals=Recours
-profile=Profil
+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.title=Liste d'absences
 active=Actif
-pdf.table.header.signature=Signature
-absence.category=Raison de l'absence
+add.assessment.mode=Marqu\u00E9 comme \u00E9valuation
+add.lecture=Cr\u00E9er un nouveau cours bloc
+add.reason=Cr\u00E9er une justification
+admin.menu.title=Cours blocs
+admin.menu.title.alt=Administration des cours blocs et absences
+afternoon=Apr\u00E8s-midi
+aggregated.list=Liste consolid\u00E9e
+alert.appeal.pending=<strong>Un</strong> recours en attente a \u00E9t\u00E9 trouv\u00E9.
+alert.appeals.pending=<strong>{0}</strong> recours en attente ont \u00E9t\u00E9 trouv\u00E9s.
+all=Tous
+all.desc=Marqu\u00E9 toutes les le\u00E7ons comme absence
+all.teachers.switch=Tous les charg\u00E9s de cours
 all.teachers.switch.tooltip.off=Montrer tous les cours blocs
-sync.course.calendar.enabled=Synchroniser le calendrier du cours
-no.teachers=Pas encore de charg\u00E9 de cours disponible
-table.header.lecture.9=9
-lectures.with.curriculum=Absences du curriculum
-table.header.lecture.1=1
-partiallydone=En partie termin\u00E9
-table.header.absent.lectures=Absences
-table.header.lecture.2=2
-table.header.lecture.3=3
-pdf.table.header.all=Tous
-table.header.lecture.4=4
-table.header.lecture.5=5
-rate.error.title=Le taux de pr\u00E9sence se situe sous la limite obligatoire.
-export.header.location=Salle\: {0}
-table.header.lecture.6=6
-table.header.lecture.7=7
-table.header.lecture.8=8
-noticed.identity=Personne absente
-config.sync.course.calendar=Synchroniser le calendrier du cours
-table.legend.authorized=Absence autoris\u00E9e
-log.remove.rate=Valeur seuil enlev\u00E9e
-assessment.tool=Outil d'\u00E9valuation
-lecture.absence.default.authorized=Compter les absences par d\u00E9faut comme excus\u00E9es
-lecture.block.dateAndTime={2} de {3} jusqu'\u00E0 {4} heure
-absence.category.in.use=Cette raison d'absence est encore utilis\u00E9 par certaines notices d'absences et ne peut pas \u00EAtre effac\u00E9e.
-lecture.teacher.can.authorize.absence=Les charg\u00E9s de cours peuvent excuser les absences
-import.lectures=Importer des cours blocs
-date.end=$org.olat.repository\:cif.date.end
-lecture.groups=Cours / groupes / curriculum
-search.form.login=Nom d'utilisateur
-appeals.update.title=Edit {0} recours
-attendance.list=Liste d'absences
-coach.lectures=Cours
-detailled.list=Liste d\u00E9taill\u00E9e
-lecture.admin.global.title=Configuration globale
-table.header.authorized.absence=Excus\u00E9
-delete.assessment.mode=Effacer l'\u00E9valuation
-lecture.block.copied=Le cours bloc a \u00E9t\u00E9 copi\u00E9 avec succ\u00E8s.
-dates.public=$org.olat.repository\:cif.dates.public
-start.desktop=Bureau
+all.teachers.switch.tooltip.on=Montrer seulement mes cours blocs
+appeal=Recours
+appeal.approved=Approuv\u00E9
+appeal.batch.update=Changer le status
 appeal.body=<p>Ch\u00E8re / Cher {1}</p><p>J'aimerais signaler que les absences de {2} ont \u00E9t\u00E9 \u00E0 mon avis saisies de mani\u00E8re incorrecte.</p><p>Raisons\:</p><p><span style\="color\: \#ff0000;">(entrez les raisons ici)</span></p><p>Merci d'avance de les v\u00E9rifier et pour les \u00E9ventuelles corrections.</p><p>Avec mes salutations distingu\u00E9es</p>
-lecture.teacher=Charg\u00E9s de cours
-table.header.owners=Propri\u00E9taire de cours
-lecture.start=D\u00E9but
-noticed.type=Type
-cockpit.lectures.day.list=Vous n'avez pas de cours ce jour-l\u00E0.
-user.profil=Profil de l'utilisateur
-save.next=Sauver et continuer
-managed.flags.lecture.block.preparation=Pr\u00E9paration/suivi
-noticed.lectures=Cours-blocs
-table.header.num.lecture.block=Cours
-search.form.status.open=$\:open
-table.header.log.user=Utilisateur
-tool.teacher=Comme charg\u00E9 de cours
-rollcall.tooltip.absence=Absence
-lecture.show.all.teachers.mine=Seulement mes cours blocs
-lecture.can.override.standard.configuration=Permettre de modifier la configuration standard
-close.lecture.blocks=Termin\u00E9 le cours bloc
-pdf.table.header.comment=Commentaire
-search.form.till=jusqu'\u00E0
-first.admission=Premi\u00E8re admission
-pdf.table.header.lectures=Cours bloc
-attendance.list.to.sign=Liste de pr\u00E9sence
-multi.rollcall.callee.title.for=pour {0}
-appeal.rejected=Rejet\u00E9
-save.temporary=Sauver temporairement
-search.form.category=Raisons
 appeal.body.title=<h4>Demande de recours pour le cours bloc suivant\:</h4><p><a href\="{3}">{3}</a></p>
-absences.title=Liste d'absences
-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>
-previous.participant=Participant pr\u00E9c\u00E9dent
-rollcall=Contr\u00F4le de pr\u00E9sence
-managed.flags.lecture.block.plannedLectures=Cours blocs pr\u00E9vus
-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.
+appeal.closed=Termin\u00E9
+appeal.contact.list=Charg\u00E9 de cours
+appeal.form.explain=La d\u00E9cision doit \u00EAtre motiv\u00E9e.
+appeal.from=Depuis le {0}
 appeal.pending=Pendant
-noticed.absence.unauthorized=Absent
-repo.lectures.appeals=Appels
-cockpit.lectures=Cours
-info.no.lectures=Vous ne suivez pour l'instant aucun cours bloc.
-entry.rate=Valeur seuil pour le cours
-table.header.unauthorized.absence=Non excus\u00E9es
-lecture.assessment.mode.enabled=Activer les \u00E9valuations pour cours blocs
-pdf.table.dates={0} de {1} jusqu'\u00E0 {2}
-public.dates=$org.olat.repository\:cif.public.dates
-table.header.external.ref=R\u00E9f. ext.
-lecture.assessment.mode.seb=Cl\u00E9s Safe Exam Browser
-lecture.time.until=jusqu'\u00E0
-search.date=Date
-lecture.teacher.reminder.subject=Rappel cours bloc "{0}"
-reason.id=ID
-sync.participants.calendar.enabled=Synchroniser le calendrier des participants
-warning.choose.at.least.one.appeal=S'il-vous-pla\u00EEt, s\u00E9lectionnez au moins un recours.
-lecture.time=Temps
-filter.showAll=Tout montrer
-table.header.planned.lectures=Le\u00E7ons
-confirm.delete.assessment.mode.title=Effacer l'examen
-lecture.taxonomy=Taxonomie
-lecture.status.enabled=Status
-in.progress=En cours
-empty.table.participant.list=Aucun contr\u00F4le de pr\u00E9sence n'a \u00E9t\u00E9 effectu\u00E9 pour ce cours jusqu'\u00E0 maintenant.
-lecture.count.authorized.absence.attendant=Compter les absences excus\u00E9es comme pr\u00E9sent
-lectures.table.pending=Cours blocs en attente
-search.form.type=Type
-notice.reason.title=Raison de l'absence
-several.entries=Plusieurs
-override.lecture=Passer outre la gestion ext\u00E9rieure du cours
-export.header.lectures=Cours blocs
-managed.flags.lecture.block.groups=Cours / groupes
-lecture.descr=Description
-bulk.example=test01<br>author02<br>test@openolat.org
-noticed.target.all=Tous les cours
-cancelled=Annul\u00E9
+appeal.rejected=Rejet\u00E9
+appeal.sent=Envoy\u00E9 le {0}
+appeal.sent.tooltip=Recours envoy\u00E9 le {0}
+appeal.status=Statut
+appeal.subject=Recours cours bloc "{0}"
 appeal.title=Recours pour\: "{0}"
-bulk=Nom d'utilisateur, $org.olat.user.propertyhandlers\:table.name.email ou $org.olat.user.propertyhandlers\:table.name.institutionalUserIdentifier
-lectures.admin.reasons=Justifications absences
-absence.category.title=Raison de l'absence
-table.legend.attended=Pr\u00E9sent
-lecture.autoclose.notification.subject=Cours bloc "{0}" boucl\u00E9 automatiquement
+appeal.tooltip=Recours possible du {0} au {1}
+appeals.title=Liste de recours
+appeals.update.title=Edit {0} recours
+archive.entry=Archivage
+assessment.tool=Outil d'\u00E9valuation
+attendance.list=Liste d'absences
+attendance.list.title=Liste d'absence\: {0}
+attendance.list.to.sign=Liste de pr\u00E9sence
+attendance.list.to.sign.title=Liste de pr\u00E9sence\: {0}
 authorized.absence=Excus\u00E9
-lecture.admin.course.override.title=Configuration - modifiable au niveau du cours
-appeal.batch.update=Changer le status
-search.form.status.reopen=$\:reopen
-lecture.assessment.mode.ips=Adresses IP autoris\u00E9es
-table.header.absence=Pr\u00E9sences
-lecture.block.comment=Remarques
-lectures.table.current=Cours blocs en cours
-repo.lectures=Cours blocs
-admin.menu.title.alt=Administration des cours blocs et absences
-managed.flags.lecture.block.settings=Configuration
-menu.my.lectures.alt=Cours blocs et absences
-search.curriculums=Recherche par curriculums
-edit.participant.rate=Editer la valeur seuil personalis\u00E9e
-form.managedflags.intro.short=Ce cours bloc a \u00E9t\u00E9 cr\u00E9\u00E9 par un outil externe. Ses param\u00E8tres ne peuvent donc pas \u00EAtre chang\u00E9s dans OpenOlat.
-appeal.closed=Termin\u00E9
-lecture.status.partially.done.enabled=Activer la possibilit\u00E9 de le\u00E7ons partielles
-delete.lectures.title=Effacer un cours bloc
-evening=Soir\u00E9e
-lectures.repository.print.title=Cours blocs et absences de {1} pour le cours\: {0}
-rollcall.status=Status du cours bloc
-table.header.preparation=En pr\u00E9paration
-confirm.delete.assessment.mode.text=Voulez-vous vraiment effacer l'examen de ce cours bloc "{0}"?
-tool.participant=Comme participant
-noticed.duration=Dur\u00E9e
-reason.copied=La justification a \u00E9t\u00E9 copi\u00E9e avec succ\u00E8s.
-table.header.progress=Graphe
-open.course=Cours ouvert
-error.atleastone.lecture=Choisissez au moins un cours bloc s'il vous pla\u00EEt.
-lecture.appeal.absence.enabled=Activer la possibilit\u00E9 de recours
-all=Tous
+authorized.absence.reason=Justification
+autoclosed=Termin\u00E9 automatiquement
+bulk=Nom d'utilisateur, $org.olat.user.propertyhandlers\:table.name.email ou $org.olat.user.propertyhandlers\:table.name.institutionalUserIdentifier
+bulk.example=test01<br>author02<br>test@openolat.org
+bulk.hint=Vous pouvez entrer une liste de noms d'utilisateurs ou d'adresses courriels dans ce champ de recherche.
 cancel.lecture.blocks=Annuler le cours bloc
-table.header.infos=<i class\='o_icon o_icon-lg o_icon_info'>  </i>
-table.legend.absent=Absent
-export.header.entry=Cours\: {0}
-table.header.id=ID
-search.form.string=Recherche
-start.mobile=Mobile
-log.add.admission.date=Date d'inscription ajout\u00E9e\: {0}
-table.header.rate=Pr\u00E9sence
-lecture.time.from=de
-managed.flags.lecture.block.compulsory=Obligatoire
-reason.deleted=La justification a \u00E9t\u00E9 effac\u00E9e avec succ\u00E8s.
-search.participants=Recherche par participants
-empty.table.current.lectures.blocks=Vous n'avez aucun cours bloc actuellement.
-lecture.show.all.teachers.all=Cours blocs de tous les charg\u00E9s de cours
-attendance.list.to.sign.title=Liste de pr\u00E9sence\: {0}
-total=Total
-table.header.log.effective.lectures=Le\u00E7ons effectives
-lecture.auto.close.period=D\u00E9lai pour bloquer le cours bloc
-rollcall.tooltip.authorized.absence=Absence excus\u00E9e
-today=Aujourd'hui
-lecture.reminder.period=D\u00E9lai de rappel
-search.form.status=Status
-table.header.log.planned.lectures=Le\u00E7ons pr\u00E9vues
-unoverride.lecture=Retour en gestion ext\u00E9rieur
-appeal.subject=Recours cours bloc "{0}"
-table.header.import.status=Status
+cancelled=Annul\u00E9
+close.lecture.blocks=Termin\u00E9 le cours bloc
+closed=Termin\u00E9
+coach.absence=Absences
+coach.appeals=Recours
 coach.cockpit=Cockpit
-noticed.till=jusqu'\u00E0
-lecture.attendance.rate.default=Taux de pr\u00E9sence global en %
-reason.copy={0} (copie)
-reason=Justification
-error.search.form.notempty=Veuillez remplir au minimum un champ du formulaire avec deux caract\u00E8res s'il vous pla\u00EEt. 
-pdf.table.header.participants=Pr\u00E9nom / nom de famille
-table.header.num.participants=Nombre de participants
-tools.import.table=Importer des cours blocs depuis Excel
-lecture.date=Date
-search.entries=Recherche par cours
-table.legend.unauthorized=Absence non excus\u00E9e
-table.header.appeal.status=Recours
-wizard.entries.label.blocks=<strong>{0}</strong> <small>{1}</small> ({2} cours blocs)
-noticed.duration.today=Aujourd'hui
+coach.lectures=Cours
+cockpit.absences=Absences
+cockpit.date=pour {0}
+cockpit.lectures=Cours
+cockpit.lectures.day.list=Vous n'avez pas de cours ce jour-l\u00E0.
+cockpit.pending.day={0} {1} ({2} cours)
+config.calculate.attendance.rate=Calculer le taux de pr\u00E9sence
+config.override=Permettre de modifier la configuration standard
+config.override.no=Non
+config.override.yes=Oui
+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.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}"?
+copy=Copier
 current.lecture=Cours bloc actuel
+date.end=$org.olat.repository\:cif.date.end
+date.start=$org.olat.repository\:cif.date.start
+dates=$org.olat.repository\:cif.dates
+dates.none=$org.olat.repository\:cif.dates.none
+dates.private=$org.olat.repository\:cif.dates.private
+dates.public=$org.olat.repository\:cif.dates.public
+delete.assessment.mode=Effacer l'\u00E9valuation
+delete.lectures.title=Effacer un cours bloc
+delete.title=Effacer une justification
+detailled.list=Liste d\u00E9taill\u00E9e
+details=D\u00E9tails
+done=Termin\u00E9
 edit.assessment.mode=Editer la configuration d'\u00E9valuation
-reason.in.use=Cette justification est encore utilis\u00E9e par un ou plusieurs cours blocs et ne peut pas \u00EAtre effac\u00E9e.
+edit.participant.rate=Editer la valeur seuil personalis\u00E9e
+edit.reason=Editer la justification
+effective.lectures=Le\u00E7ons effectives
+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.
+empty.table.lectures.blocks=Aucun cours bloc n'a \u00E9t\u00E9 trouv\u00E9.
+empty.table.lectures.blocks.admin=Aucun cours bloc n'a \u00E9t\u00E9 cr\u00E9\u00E9 pour ce cours.
+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.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. 
+evening=Soir\u00E9e
+export.footer.lectures.hint=x \= Absence
+export.header.entry=Cours\: {0}
+export.header.lectureblocks=Cours bloc\: {0} de {1} de {2} \u00E0 {3}
+export.header.lectures=Cours blocs
+export.header.location=Salle\: {0}
+export.header.teachers=Charg\u00E9s de cours\: {0}
 filter.mandatory=Pr\u00E9sence obligatoire
-table.header.compulsory.long=Pr\u00E9sence obligatoire
-morning=Matin\u00E9e
-appeal.sent.tooltip=Recours envoy\u00E9 le {0}
-rollcall.tooltip.ok=Pr\u00E9sent
+filter.showAll=Tout montrer
+filter.warning=Avertissements
+first.admission=Premi\u00E8re admission
 form.managedflags.intro=Ce bloc de le\u00E7ons a \u00E9t\u00E9 cr\u00E9\u00E9 par un outil externe. Certains r\u00E9glages et modules ne peuvent pas \u00EAtre modifi\u00E9s et utilis\u00E9s dans OpenOlat. Les \u00E9l\u00E9ments suivants sont bloqu\u00E9s dans OpenOlat\: {0}
-repo.settings=Configuration
-empty.repository.entry.lectures=Vous n'avez pas encore de le\u00E7ons dans ce cours.
-rollcall.absence=Absence
-cockpit.absences=Absences
-absence.category.copy={0} (copie)
-appeal.sent=Envoy\u00E9 le {0}
-aggregated.list=Liste consolid\u00E9e
-warning.repositoryentry.deleted=$org.olat.repository\:repositoryentry.deleted
-appeal.status=Statut
+form.managedflags.intro.short=Ce cours bloc a \u00E9t\u00E9 cr\u00E9\u00E9 par un outil externe. Ses param\u00E8tres ne peuvent donc pas \u00EAtre chang\u00E9s dans OpenOlat.
+from=de {0}
+import.lectures=Importer des cours blocs
+in.progress=En cours
+info.lecture.block.optional=Ce cours bloc n'est <strong>pas</strong> obligatoire.
+info.no.lectures=Vous ne suivez pour l'instant aucun cours bloc.
+infos.participant.attendance.rate=Valeur seuil personelle\: {0}%
+interceptor.start=Vous avez un cours bloc pour le cours "{0}" {1} de {4} \u00E0 {5}.
+lecture.absence.default.authorized=Compter les absences par d\u00E9faut comme excus\u00E9es
+lecture.admin.course.override.title=Configuration - modifiable au niveau du cours
+lecture.admin.enabled=Activer l'administration des cours blocs et des absences
+lecture.admin.global.title=Configuration globale
+lecture.appeal.absence.enabled=Activer la possibilit\u00E9 de recours
+lecture.appeal.absence.period=D\u00E9lai de recours
+lecture.assessment.mode.enabled=Activer les \u00E9valuations pour cours blocs
+lecture.assessment.mode.followup.time=P\u00E9riode de temporisation
+lecture.assessment.mode.ips=Adresses IP autoris\u00E9es
+lecture.assessment.mode.leading.time=Pr\u00E9paration
+lecture.assessment.mode.seb=Cl\u00E9s Safe Exam Browser
+lecture.attendance.rate.default=Taux de pr\u00E9sence global en %
+lecture.authorized.absence.enabled=Absences excus\u00E9es
+lecture.auto.close.period=D\u00E9lai pour bloquer le cours bloc
+lecture.autoclose.notification.body=<p>Ch\u00E8re administratrice de cours<br>Cher administrateur de cours</p><p>Nous vous informons que le cours bloc a \u00E9t\u00E9 ferm\u00E9 automatiquement sans intervention du charg\u00E9 de cours. Avec le lien ci-dessous, vous pouvez acc\u00E9der \u00E0 ce cours bloc\:<br><a href\='{3}'>{3}</a></p>
+lecture.autoclose.notification.subject=Cours bloc "{0}" boucl\u00E9 automatiquement
+lecture.block=Cours blocs
+lecture.block.comment=Remarques
+lecture.block.copied=Le cours bloc a \u00E9t\u00E9 copi\u00E9 avec succ\u00E8s.
+lecture.block.copy={0} (copie)
+lecture.block.dateAndTime={2} de {3} jusqu'\u00E0 {4} heure
+lecture.block.effective.end=Fin effective
+lecture.block.effective.reason=Justification
+lecture.block.status=Status
+lecture.calculate.attendance.rate.default.enabled=Calcul du taux de pr\u00E9sence
+lecture.can.override.standard.configuration=Permettre de modifier la configuration standard
+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.date=Date
+lecture.deleted=Cours bloc a \u00E9t\u00E9 effac\u00E9 avec succ\u00E8s.
+lecture.descr=Description
+lecture.end=Fin
+lecture.from.to=Depuis
+lecture.from.to.format={0} jusqu'\u00E0 {1}
+lecture.groups=Cours / groupes / curriculum
+lecture.location=Lieu
 lecture.owner.can.view.all.curriculum.elements=Les propri\u00E9taires peuvent voir tous les cours de l'\u00E9l\u00E9ment de curriculum
-table.header.lecture.block=Cours bloc
-error.integer.between=La valeur doit \u00EAtre un nombre entre {0} et {1}
 lecture.preparation=Pr\u00E9paration/suivi
-upto=jusqu'\u00E0 {0}
+lecture.reminder.enabled=Activ\u00E9 la fonction de rappel
+lecture.reminder.period=D\u00E9lai de rappel
+lecture.rollcall.default.enabled=Activer le contr\u00F4le de pr\u00E9sence
+lecture.show.all.teachers=Affichage par d\u00E9faut dans le cours
+lecture.show.all.teachers.all=Cours blocs de tous les charg\u00E9s de cours
+lecture.show.all.teachers.mine=Seulement mes cours blocs
+lecture.start=D\u00E9but
+lecture.status.enabled=Status
+lecture.status.partially.done.enabled=Activer la possibilit\u00E9 de le\u00E7ons partielles
+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.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
-appeal=Recours
-info.lecture.block.optional=Ce cours bloc n'est <strong>pas</strong> obligatoire.
-table.header.presence=Pr\u00E9sence
+lectures.admin.reasons=Justifications absences
+lectures.admin.report=Rapport cours blocs
+lectures.admin.settings=Configuration de l'administration des cours blocs et des absences
+lectures.print.title=Cours blocs et absences de {0}
+lectures.repository.print.title=Cours blocs et absences de {1} pour le cours\: {0}
+lectures.table.closed=Cours blocs termin\u00E9s
+lectures.table.current=Cours blocs en cours
+lectures.table.next=Prochains cours blocs
+lectures.table.pending=Cours blocs en attente
+lectures.with.curriculum=Absences du curriculum
+lectures.without.curriculum=Absences hors curriculum
+log=Log
+log.add.admission.date=Date d'inscription ajout\u00E9e\: {0}
+log.add.rate=Valeur seuil ajout\u00E9e\: {0}
+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
+managed.flags.lecture.block.all=Gestion externe compl\u00E8te
+managed.flags.lecture.block.compulsory=Obligatoire
+managed.flags.lecture.block.dates=Date
+managed.flags.lecture.block.delete=Effacer le cours bloc
+managed.flags.lecture.block.description=Description
 managed.flags.lecture.block.details=Titre, description...
-table.header.compulsory=<i class\='o_icon o_icon_compulsory o_icon-lg'> </i>
-closed=Termin\u00E9
-appeal.form.explain=La d\u00E9cision doit \u00EAtre motiv\u00E9e.
-appeal.from=Depuis le {0}
-repo.participants=Participants
+managed.flags.lecture.block.groups=Cours / groupes
+managed.flags.lecture.block.location=Lieu
+managed.flags.lecture.block.plannedLectures=Cours blocs pr\u00E9vus
+managed.flags.lecture.block.preparation=Pr\u00E9paration/suivi
+managed.flags.lecture.block.settings=Configuration
+managed.flags.lecture.block.teachers=Charg\u00E9s de cours
 managed.flags.lecture.block.title=Titre
-open=Ouvert
-table.header.comment=Commentaire
-rollcall.comment=Remarque
-cockpit.date=pour {0}
+menu.my.lectures=Absences
+menu.my.lectures.alt=Cours blocs et absences
+morning=Matin\u00E9e
+multi.rollcall.callee.title.for=pour {0}
+new.appeal.title=Nouvelle notification de recours
+next.participant=Participant suivant
+no.teachers=Pas encore de charg\u00E9 de cours disponible
+notice.reason.title=Raison de l'absence
+noticed.absence.unauthorized=Absent
+noticed.duration=Dur\u00E9e
+noticed.duration.today=Aujourd'hui
+noticed.entries=Cours
+noticed.identity=Personne absente
+noticed.lectures=Cours-blocs
 noticed.reason=Commentaire
-table.header.details=<i class\='o_icon o_icon_lecture o_icon-lg'> </i>
-lecture.block=Cours blocs
-table.header.start.time=De
-lecture.block.copy={0} (copie)
-details=D\u00E9tails
-add.lecture=Cr\u00E9er un nouveau cours bloc
-table.header.notice.type=Type
-results=R\u00E9sultats
-table.header.identifier=Identifiant
-reason.title=Justification
-date.start=$org.olat.repository\:cif.date.start
-lecture.assessment.mode.leading.time=Pr\u00E9paration
-table.header.num.presences=Nombre de participants pr\u00E9sents
-reopen=R\u00E9ouvert
-managed.flags.lecture.block.location=Lieu
-remove.custom.rate=Enlever la valeur seuil personnelle
-filter.warning=Avertissements
-interceptor.start=Vous avez un cours bloc pour le cours "{0}" {1} de {4} \u00E0 {5}.
-export.header.lectureblocks=Cours bloc\: {0} de {1} de {2} \u00E0 {3}
-sync.teachers.calendar.enabled=Synchroniser le calendrier des charg\u00E9s de cours
-alert.appeal.pending=<strong>Un</strong> recours en attente a \u00E9t\u00E9 trouv\u00E9.
-lecture.rollcall.default.enabled=Activer le contr\u00F4le de pr\u00E9sence
-lectures.admin.settings=Configuration de l'administration des cours blocs et des absences
-table.header.actions=<i class\='o_icon o_icon_actions o_icon-lg'> </i>
-all.desc=Marqu\u00E9 toutes les le\u00E7ons comme absence
-wizard.lectureblock.label=<strong>{0}</strong> <small>{1}</small><br>{2} {3} - {4} {5} cours\: "{6}" avec {7}
-table.header.description=Description
-lecture.block.effective.end=Fin effective
+noticed.target.all=Tous les cours
+noticed.target.courses=Cours choisis
+noticed.target.lectureblocks=Cours-blocs choisis
+noticed.teachers=Charg\u00E9s de cours
+noticed.till=jusqu'\u00E0
+noticed.type=Type
+open=Ouvert
+open.course=Cours ouvert
+override.lecture=Passer outre la gestion ext\u00E9rieure du cours
+partiallydone=En partie termin\u00E9
 participant.rate=Valeur seuil
-log.add.rate=Valeur seuil ajout\u00E9e\: {0}
-export.header.teachers=Charg\u00E9s de cours\: {0}
-log.remove.admission.date=Date d'inscription enlev\u00E9e
-table.header.log.effective.end.date=Date effective de fin
-table.header.edit=<i class\='o_icon o_icon_edit o_icon-lg'> </i>
-admin.menu.title=Cours blocs
-confirm.delete.lectures=Voulez-vous vraiment effacer ce cours block "{0}"?
-export.footer.lectures.hint=x \= Absence
-lecture.deleted=Cours bloc a \u00E9t\u00E9 effac\u00E9 avec succ\u00E8s.
-table.header.rate.warning=<i class\="o_icon o_midwarn"> </i>
+participant.rate.edit=Valeur seuil personelle
+pdf.table.dates={0} de {1} jusqu'\u00E0 {2}
+pdf.table.header.all=Tous
+pdf.table.header.authorised=Exc.
+pdf.table.header.comment=Commentaire
+pdf.table.header.lectures=Cours bloc
+pdf.table.header.participants=Pr\u00E9nom / nom de famille
+pdf.table.header.signature=Signature
+planned.lectures=Cours blocs pr\u00E9vus
+previous.participant=Participant pr\u00E9c\u00E9dent
+private.dates=$org.olat.repository\:cif.private.dates
+profile=Profil
+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.
-table.header.effective.lectures=Le\u00E7ons
-lectures.table.closed=Cours blocs termin\u00E9s
+reason=Justification
+reason.copied=La justification a \u00E9t\u00E9 copi\u00E9e avec succ\u00E8s.
+reason.copy={0} (copie)
+reason.deleted=La justification a \u00E9t\u00E9 effac\u00E9e avec succ\u00E8s.
+reason.description=Description
+reason.id=ID
+reason.in.use=Cette justification est encore utilis\u00E9e par un ou plusieurs cours blocs et ne peut pas \u00EAtre effac\u00E9e.
+reason.title=Justification
+remove.custom.rate=Enlever la valeur seuil personnelle
+reopen=R\u00E9ouvert
 reopen.lecture.blocks=R\u00E9ouvrir un cours bloc
-table.header.attended.current.rate=% pr\u00E9sent
-noticed.target.lectureblocks=Cours-blocs choisis
-table.header.location=Lieu
-config.override.yes=Oui
-lectures.without.curriculum=Absences hors curriculum
-search.form.status.closed=$\:closed
-new.appeal.title=Nouvelle notification de recours
-appeal.tooltip=Recours possible du {0} au {1}
-managed.flags.lecture.block.all=Gestion externe compl\u00E8te
-pdf.table.header.authorised=Exc.
-dates=$org.olat.repository\:cif.dates
-managed.flags.lecture.block.delete=Effacer le cours bloc
-error.integer.positive=La valeur doit \u00EAtre un nombre positif.
-menu.my.lectures=Absences
+repo.lectures=Cours blocs
+repo.lectures.appeals=Appels
+repo.lectures.block=Cours blocs
+repo.participants=Participants
+repo.settings=Configuration
+results=R\u00E9sultats
+rollcall=Contr\u00F4le de pr\u00E9sence
+rollcall.absence=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.status=Status du cours bloc
+rollcall.tooltip.absence=Absence
+rollcall.tooltip.authorized.absence=Absence excus\u00E9e
 rollcall.tooltip.free=Facultatif
-lecture.end=Fin
-managed.flags.lecture.block.dates=Date
-log.change.admission.date=Date d'inscription modifi\u00E9e\: {0}
-table.header.log.author=Changements
+rollcall.tooltip.ok=Pr\u00E9sent
+rollcall.tooltip.unauthorized.absence=Absence non excus\u00E9e
+save.next=Sauver et continuer
+save.temporary=Sauver temporairement
+search.curriculums=Recherche par curriculums
+search.date=Date
+search.entries=Recherche par cours
+search.form.category=Raisons
+search.form.end=Jusqu'\u00E0
+search.form.login=Nom d'utilisateur
+search.form.start=De
+search.form.status=Status
+search.form.status.autoclosed=$\:autoclosed
+search.form.status.closed=$\:closed
+search.form.status.open=$\:open
+search.form.status.reopen=$\:reopen
+search.form.string=Recherche
+search.form.string.hint=Vous pouvez chercher les titres d'un bloc de cours ou sa r\u00E9f\u00E9rence externe. Lors de la recherche avec la r\u00E9f\u00E9rence externe, seuls les r\u00E9sultats exacts sont affich\u00E9s.
+search.form.till=jusqu'\u00E0
+search.form.type=Type
+search.participants=Recherche par participants
 search.teachers=Recherche par charg\u00E9s de cours
-reason.description=Description
-lecture.compulsory=Pr\u00E9sence obligatoire
-planned.lectures=Cours blocs pr\u00E9vus
+send=Envoyer
+several.entries=Plusieurs
+site.title=Gestion des cours blocs
+start.desktop=Bureau
 start.label=Noter les absences
-noticed.entries=Cours
+start.mobile=Mobile
 start.wizard=D\u00E9marrer l'assistant
-log=Log
-table.header.username=Nom d'utilisateur
-search.form.start=De
-config.calculate.attendance.rate=Calculer le taux de pr\u00E9sence
-tools=Action
-lectures.admin.report=Rapport cours blocs
-table.header.lecture.11=11
+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.absent.lectures=Absences
+table.header.actions=<i class\='o_icon o_icon_actions o_icon-lg'> </i>
+table.header.appeal.status=Recours
+table.header.assessment.mode=Evaluations
+table.header.attended.current.rate=% pr\u00E9sent
+table.header.attended.lectures=Pr\u00E9sent
+table.header.authorized.absence=Excus\u00E9
+table.header.auto.close.date=Termin\u00E9 automatiquement le
+table.header.comment=Commentaire
+table.header.compulsory=<i class\='o_icon o_icon_compulsory o_icon-lg'> </i>
+table.header.compulsory.long=Pr\u00E9sence obligatoire
+table.header.date=Date
+table.header.description=Description
+table.header.details=<i class\='o_icon o_icon_lecture o_icon-lg'> </i>
+table.header.edit=<i class\='o_icon o_icon_edit o_icon-lg'> </i>
+table.header.effective.lectures=Le\u00E7ons
+table.header.end.time=Jusqu'\u00E0
+table.header.entry=Cours
+table.header.export=Exporter
+table.header.external.ref=R\u00E9f. ext.
+table.header.id=ID
+table.header.identifier=Identifiant
+table.header.import.status=Status
+table.header.infos=<i class\='o_icon o_icon-lg o_icon_info'>  </i>
+table.header.lecture.1=1
 table.header.lecture.10=10
-table.header.lecture.13=13
+table.header.lecture.11=11
 table.header.lecture.12=12
-private.dates=$org.olat.repository\:cif.private.dates
+table.header.lecture.13=13
 table.header.lecture.14=14
-copy=Copier
-managed.flags.lecture.block.teachers=Charg\u00E9s de cours
-noticed.target.courses=Cours choisis
-appeal.contact.list=Charg\u00E9 de cours
-table.header.teachers=Charg\u00E9s de cours
-warning.edit.lecture=Le contr\u00F4le d'absence est d\u00E9sactiv\u00E9.
-bulk.hint=Vous pouvez entrer une liste de noms d'utilisateurs ou d'adresses courriels dans ce champ de recherche.
+table.header.lecture.2=2
+table.header.lecture.3=3
+table.header.lecture.4=4
+table.header.lecture.5=5
+table.header.lecture.6=6
+table.header.lecture.7=7
+table.header.lecture.8=8
+table.header.lecture.9=9
+table.header.lecture.block=Cours bloc
+table.header.location=Lieu
 table.header.log.action=Action
-dates.none=$org.olat.repository\:cif.dates.none
-repo.lectures.block=Cours blocs
-rollcall.tooltip.unauthorized.absence=Absence non excus\u00E9e
-lecture.from.to.format={0} jusqu'\u00E0 {1}
-appeals.title=Liste de recours
-lecture.block.status=Status
-warning.teachers.at.least.one.contact=Il n'y a pas de charg\u00E9s de cours \u00E0 contacter.
-lecture.appeal.absence.period=D\u00E9lai de recours
-next.participant=Participant suivant
-table.header.assessment.mode=Evaluations
-lecture.autoclose.notification.body=<p>Ch\u00E8re administratrice de cours<br>Cher administrateur de cours</p><p>Nous vous informons que le cours bloc a \u00E9t\u00E9 ferm\u00E9 automatiquement sans intervention du charg\u00E9 de cours. Avec le lien ci-dessous, vous pouvez acc\u00E9der \u00E0 ce cours bloc\:<br><a href\='{3}'>{3}</a></p>
-table.header.entry=Cours
-alert.appeals.pending=<strong>{0}</strong> recours en attente ont \u00E9t\u00E9 trouv\u00E9s.
-table.header.end.time=Jusqu'\u00E0
-lectures.table.next=Prochains cours blocs
-table.header.times=P\u00E9riode
-dates.private=$org.olat.repository\:cif.dates.private
-from=de {0}
-lectures.print.title=Cours blocs et absences de {0}
-config.sync.participant.calendar=Synchroniser le calendrier des participants
-table.header.auto.close.date=Termin\u00E9 automatiquement le
-config.sync.teacher.calendar=Synchroniser le calendrier des charg\u00E9s de cours
+table.header.log.author=Changements
+table.header.log.effective.end.date=Date effective de fin
+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.lecture.block=Cours
+table.header.num.participants=Nombre de participants
+table.header.num.presences=Nombre de participants pr\u00E9sents
+table.header.owners=Propri\u00E9taire de cours
+table.header.participants=Participants
+table.header.planned.lectures=Le\u00E7ons
+table.header.preparation=En pr\u00E9paration
+table.header.presence=Pr\u00E9sence
+table.header.progress=Graphe
+table.header.rate=Pr\u00E9sence
+table.header.rate.warning=<i class\="o_icon o_midwarn"> </i>
 table.header.reason=Justification
-done=Termin\u00E9
-config.override=Permettre de modifier la configuration standard
-lecture.from.to=Depuis
-lecture.reminder.enabled=Activ\u00E9 la fonction de rappel
-all.teachers.switch=Tous les charg\u00E9s de cours
-search.form.end=Jusqu'\u00E0
-log.change.rate=Valeur seuil modifi\u00E9e\: {0}
-archive.entry=Archivage
-send=Envoyer
-lecture.show.all.teachers=Affichage par d\u00E9faut dans le cours
+table.header.start.time=De
 table.header.status=Status
-lecture.authorized.absence.enabled=Absences excus\u00E9es
-attendance.list.title=Liste d'absence\: {0}
-managed.flags.lecture.block.description=Description
-cockpit.pending.day={0} {1} ({2} cours)
-coach.appeals=Recours
-empty.table.lectures.blocks.admin=Aucun cours bloc n'a \u00E9t\u00E9 cr\u00E9\u00E9 pour ce cours.
-autoclosed=Termin\u00E9 automatiquement
-wizard.entries.label.block=<strong>{0}</strong> <small>{1}</small> ({2} cours bloc)
-lecture.assessment.mode.followup.time=P\u00E9riode de temporisation
-delete.title=Effacer une justification
-effective.lectures=Le\u00E7ons effectives
-empty.lectures.list=La liste est vide
-lecture.admin.enabled=Activer l'administration des cours blocs et des absences
+table.header.teachers=Charg\u00E9s de cours
+table.header.times=P\u00E9riode
+table.header.tools=<i class\='o_icon o_icon_actions o_icon-lg'> </i>
+table.header.unauthorized.absence=Non excus\u00E9es
+table.header.username=Nom d'utilisateur
+table.legend.absent=Absent
+table.legend.attended=Pr\u00E9sent
+table.legend.authorized=Absence autoris\u00E9e
+table.legend.free=Le\u00E7on facultative
+table.legend.unauthorized=Absence non excus\u00E9e
+today=Aujourd'hui
+tool.participant=Comme participant
+tool.teacher=Comme charg\u00E9 de cours
+tools=Action
+tools.import.table=Importer des cours blocs depuis Excel
+total=Total
+unoverride.lecture=Retour en gestion ext\u00E9rieur
+upto=jusqu'\u00E0 {0}
+user.overview.appeals=Recours
+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.
+warning.repositoryentry.deleted=$org.olat.repository\:repositoryentry.deleted
+warning.teachers.at.least.one.contact=Il n'y a pas de charg\u00E9s de cours \u00E0 contacter.
 whole.day=Journ\u00E9e enti\u00E8re
-search.form.status.autoclosed=$\:autoclosed
-all.teachers.switch.tooltip.on=Montrer seulement mes cours blocs
-absence.category.description=Description
-afternoon=Apr\u00E8s-midi
-site.title=Gestion des cours blocs
-table.header.export=Exporter
-config.rollcall.enabled=Activer le contr\u00F4le du taux de pr\u00E9sence
-confirm.delete.reason=Voulez-vous vraiment effacer cette justification "{0}"?
-lecture.location=Lieu
+wizard.entries.label.block=<strong>{0}</strong> <small>{1}</small> ({2} cours bloc)
+wizard.entries.label.blocks=<strong>{0}</strong> <small>{1}</small> ({2} cours blocs)
+wizard.lectureblock.label=<strong>{0}</strong> <small>{1}</small><br>{2} {3} - {4} {5} cours\: "{6}" avec {7}
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 7a5c17c2259bcc38c96b2de17ba6d7178847f41a..9744dbd22f3750abc5cbefd1717bdb09aa3d754f 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
@@ -19,7 +19,6 @@
  */
 package org.olat.modules.lecture.ui.coach;
 
-import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 
@@ -35,18 +34,8 @@ import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.controller.BasicController;
 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.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.AbsenceNoticeSearchParameters;
 import org.olat.modules.lecture.AbsenceNoticeType;
 import org.olat.modules.lecture.LectureService;
@@ -56,6 +45,8 @@ import org.olat.modules.lecture.ui.LectureRepositoryAdminController;
 import org.olat.modules.lecture.ui.LecturesSecurityCallback;
 import org.olat.modules.lecture.ui.event.SearchAbsenceNoticeEvent;
 import org.olat.modules.lecture.ui.wizard.AbsenceNotice1UserSearchStep;
+import org.olat.modules.lecture.ui.wizard.AbsenceNoticeCancelStepCallback;
+import org.olat.modules.lecture.ui.wizard.AbsenceNoticeFinishStepCallback;
 import org.springframework.beans.factory.annotation.Autowired;
 
 /**
@@ -76,8 +67,6 @@ public class AbsencesController extends BasicController {
 	private AbsenceNoticeSearchController searchCtrl;
 	private AbsenceNoticesListController noticesListCtlr;
 
-	@Autowired
-	private MailManager mailService;
 	@Autowired
 	private LectureService lectureService;
 	
@@ -176,56 +165,14 @@ public class AbsencesController extends BasicController {
 	private void doAddNotice(UserRequest ureq) {
 		final EditAbsenceNoticeWrapper noticeWrapper = new EditAbsenceNoticeWrapper(AbsenceNoticeType.absence);
 		AbsenceNotice1UserSearchStep step = new AbsenceNotice1UserSearchStep(ureq, noticeWrapper, secCallback);
-		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(), getIdentity());
-			}
-			
-			if(noticeWrapper.getIdentitiesToContact() != null && !noticeWrapper.getIdentitiesToContact().isEmpty()) {
-				inform(ureq, noticeWrapper);
-			}
-			return StepsMainRunController.DONE_MODIFIED;
-		};
-		
+		StepRunnerCallback stop = new AbsenceNoticeFinishStepCallback(noticeWrapper, getTranslator());
+		StepRunnerCallback cancel = new AbsenceNoticeCancelStepCallback(noticeWrapper);
+
 		removeAsListenerAndDispose(addNoticeCtrl);
 		String title = translate("add.absence.title");
-		addNoticeCtrl = new StepsMainRunController(ureq, getWindowControl(), step, stop, null, title, "");
+		addNoticeCtrl = new StepsMainRunController(ureq, getWindowControl(), step, stop, cancel, 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/coach/DispensationsController.java b/src/main/java/org/olat/modules/lecture/ui/coach/DispensationsController.java
index 216dd591c797032e24374ee976cf35f432961150..bece847b09feb9e03de5f5b8e7a5833401179369 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
@@ -19,9 +19,7 @@
  */
 package org.olat.modules.lecture.ui.coach;
 
-import java.util.ArrayList;
 import java.util.Date;
-import java.util.List;
 
 import org.olat.commons.calendar.CalendarUtils;
 import org.olat.core.gui.UserRequest;
@@ -35,27 +33,16 @@ import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.controller.BasicController;
 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.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.AbsenceNoticeSearchParameters;
 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.LecturesSecurityCallback;
 import org.olat.modules.lecture.ui.event.SearchAbsenceNoticeEvent;
 import org.olat.modules.lecture.ui.wizard.AbsenceNotice1UserSearchStep;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.olat.modules.lecture.ui.wizard.AbsenceNoticeCancelStepCallback;
+import org.olat.modules.lecture.ui.wizard.AbsenceNoticeFinishStepCallback;
 
 /**
  * 
@@ -76,11 +63,6 @@ public class DispensationsController extends BasicController {
 	private StepsMainRunController addNoticeCtrl;
 	private AbsenceNoticeSearchController searchCtrl;
 	private AbsenceNoticesListController noticesListCtlr;
-
-	@Autowired
-	private MailManager mailService;
-	@Autowired
-	private LectureService lectureService;
 	
 	public DispensationsController(UserRequest ureq, WindowControl wControl, Date currentDate,
 			LecturesSecurityCallback secCallback, boolean withSearch, boolean withAddAbsence) {
@@ -174,20 +156,8 @@ public class DispensationsController extends BasicController {
 		
 		final EditAbsenceNoticeWrapper noticeWrapper = new EditAbsenceNoticeWrapper(type);
 		AbsenceNotice1UserSearchStep step = new AbsenceNotice1UserSearchStep(ureq, noticeWrapper, secCallback);
-		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(), getIdentity());
-			}
-			
-			if(noticeWrapper.getIdentitiesToContact() != null && !noticeWrapper.getIdentitiesToContact().isEmpty()) {
-				inform(ureq, noticeWrapper);
-			}
-			return StepsMainRunController.DONE_MODIFIED;
-		};
+		StepRunnerCallback stop = new AbsenceNoticeFinishStepCallback(noticeWrapper, getTranslator());
+		StepRunnerCallback cancel = new AbsenceNoticeCancelStepCallback(noticeWrapper);
 		
 		String title = translate("add.dispensation.title");
 		if(type == AbsenceNoticeType.notified) {
@@ -195,39 +165,8 @@ public class DispensationsController extends BasicController {
 		}
 		
 		removeAsListenerAndDispose(addNoticeCtrl);
-		addNoticeCtrl = new StepsMainRunController(ureq, getWindowControl(), step, stop, null, title, "");
+		addNoticeCtrl = new StepsMainRunController(ureq, getWindowControl(), step, stop, cancel, 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/coach/EditNoticeController.java b/src/main/java/org/olat/modules/lecture/ui/coach/EditNoticeController.java
index ad38d9a9c9d6561393d50c5478cc926af6cff41d..40f394e8cc9310f1b642e5e8f938d3689335e954 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
@@ -19,6 +19,7 @@
  */
 package org.olat.modules.lecture.ui.coach;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -29,6 +30,8 @@ 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.id.Identity;
+import org.olat.core.util.vfs.VFSItem;
+import org.olat.core.util.vfs.filters.VFSSystemItemFilter;
 import org.olat.modules.lecture.AbsenceNotice;
 import org.olat.modules.lecture.AbsenceNoticeTarget;
 import org.olat.modules.lecture.AbsenceNoticeToLectureBlock;
@@ -95,7 +98,7 @@ public class EditNoticeController extends FormBasicController {
 
 	@Override
 	protected void doDispose() {
-		//
+		editReasonCtrl.deleteTempStorage();
 	}
 
 	@Override
@@ -128,6 +131,11 @@ public class EditNoticeController extends FormBasicController {
 		}
 		
 		absenceNotice = lectureService.updateAbsenceNotice(absenceNotice, authorizer, entries, lectureBlocks);
+		List<VFSItem> newFiles = new ArrayList<>();
+		if(noticeWrapper.getTempUploadFolder() != null) {
+			newFiles.addAll(noticeWrapper.getTempUploadFolder().getItems(new VFSSystemItemFilter()));
+		}
+		lectureService.updateAbsenceNoticeAttachments(absenceNotice, newFiles, noticeWrapper.getAttachmentsToDelete());
 		fireEvent(ureq, Event.CHANGED_EVENT);
 	}
 
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 f7c094b0dcf0c1a1ba4e3ac504d9c5094c89da80..333f069391203c9693acccdf02b0a3e0bc3d1112 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
@@ -19,23 +19,45 @@
  */
 package org.olat.modules.lecture.ui.coach;
 
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.List;
 
+import javax.servlet.http.HttpServletRequest;
+
+import org.olat.core.dispatcher.mapper.Mapper;
 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.FileElement;
+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.elements.TextElement;
 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.form.flexible.impl.FormLayoutContainer;
+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;
+import org.olat.core.gui.media.MediaResource;
 import org.olat.core.id.Identity;
+import org.olat.core.util.CodeHelper;
 import org.olat.core.util.StringHelper;
 import org.olat.core.util.Util;
+import org.olat.core.util.vfs.VFSContainer;
+import org.olat.core.util.vfs.VFSItem;
+import org.olat.core.util.vfs.VFSLeaf;
+import org.olat.core.util.vfs.VFSManager;
+import org.olat.core.util.vfs.VFSMediaResource;
+import org.olat.core.util.vfs.filters.VFSSystemItemFilter;
 import org.olat.modules.lecture.AbsenceCategory;
 import org.olat.modules.lecture.AbsenceNoticeType;
 import org.olat.modules.lecture.LectureService;
@@ -61,11 +83,16 @@ public class EditReasonController extends FormBasicController {
 	
 	private TextElement reasonEl;
 	private SingleSelection typeEl;
+	private FileElement documentUploadEl;
+	private FormLayoutContainer filesLayout;
 	private SingleSelection absenceCategoriesEl;
 	private MultipleSelectionElement authorizedEl;
-	
+
+	private String mapperUri;
 	private final boolean wizard;
 	private final Identity noticedIdentity;
+	private VFSContainer tempUploadFolder;
+	private final VFSContainer documentContainer;
 	private final EditAbsenceNoticeWrapper noticeWrapper;
 	private final LecturesSecurityCallback secCallback;
 	private List<AbsenceCategory> absenceCategories;
@@ -83,12 +110,16 @@ public class EditReasonController extends FormBasicController {
 		this.secCallback = secCallback;
 		this.noticeWrapper = noticeWrapper;
 		this.noticedIdentity = noticeWrapper.getIdentity();
+		documentContainer = lectureService.getAbsenceNoticeAttachmentsContainer(noticeWrapper.getAbsenceNotice());
 		absenceCategories = lectureService.getAllAbsencesCategories();
 		initForm(ureq);
+		updateAttachments(ureq);
 	}
 
 	@Override
 	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
+		mainForm.setMultipartEnabled(true);
+		
 		if(wizard) {
 			formLayout.setElementCssClass("o_sel_absence_edit_reason");
 			setFormTitle("notice.reason.title");
@@ -133,6 +164,14 @@ public class EditReasonController extends FormBasicController {
 
 		String currentReason = noticeWrapper.getAbsenceReason();
 		reasonEl = uifactory.addTextAreaElement("reason", "noticed.reason", 2048, 4, 36, false, false, currentReason, formLayout);
+		
+		String editPage = Util.getPackageVelocityRoot(getClass()) + "/notice_files.html";
+		filesLayout = FormLayoutContainer.createCustomFormLayout("filesLayout", getTranslator(), editPage);
+		filesLayout.setLabel("attachment.upload", null);
+		formLayout.add(filesLayout);
+
+		documentUploadEl = uifactory.addFileElement(getWindowControl(), "attachment.upload", formLayout);
+		documentUploadEl.addActionListener(FormEvent.ONCHANGE);
 	}
 
 	@Override
@@ -140,6 +179,12 @@ public class EditReasonController extends FormBasicController {
 		//
 	}
 	
+	protected void deleteTempStorage() {
+		if(tempUploadFolder != null) {
+			tempUploadFolder.delete();
+		}
+	}
+	
 	public AbsenceCategory getAbsenceCategory() {
 		if(!absenceCategoriesEl.isVisible() || !absenceCategoriesEl.isOneSelected()) return null;
 		
@@ -155,6 +200,59 @@ public class EditReasonController extends FormBasicController {
 		return null;
 	}
 	
+	private void updateAttachments(UserRequest ureq) {
+		if(mapperUri == null) {
+			mapperUri = registerCacheableMapper(ureq, "assigment-" + CodeHelper.getRAMUniqueID(), new DocumentMapper());
+			filesLayout.contextPut("mapperUri", mapperUri);
+		}
+		
+		List<VFSItem> files = new ArrayList<>();
+		if(documentContainer != null) {
+			List<VFSItem> currentItems = documentContainer.getItems(new VFSSystemItemFilter());
+			List<VFSItem> deletedItems = noticeWrapper.getAttachmentsToDelete();
+			for(VFSItem currentItem:currentItems) {
+				boolean deleted = false;
+				for(VFSItem deletedItem:deletedItems) {
+					if(deletedItem.isSame(currentItem)) {
+						deleted = true;
+					}
+				}
+				if(!deleted) {
+					files.add(currentItem);
+				}
+			}
+			
+		}
+		// add files from TempFolder
+		if(tempUploadFolder != null) {
+			files.addAll(tempUploadFolder.getItems(new VFSSystemItemFilter()));
+		}
+		
+		Collections.sort(files, new Comparator<VFSItem>(){
+			final Collator c = Collator.getInstance(getLocale());
+			@Override
+			public int compare(final VFSItem o1, final VFSItem o2) {
+				return c.compare((o1).getName(), (o2).getName());
+			}
+		});		
+
+		filesLayout.contextPut("files", files);
+
+		// add delete links for each attachment if user is allowed to see them
+		int count = 0;
+		for (VFSItem file : files) {
+			FormLink deleteLink = uifactory.addFormLink("delete_" + (++count), filesLayout, Link.BUTTON_XSMALL);
+			deleteLink.setUserObject(file);
+			deleteLink.setI18nKey("delete");
+		}
+
+		boolean hasFile = !files.isEmpty();
+		filesLayout.setVisible(hasFile);
+		filesLayout.showLabel(hasFile);
+		documentUploadEl.showLabel(!hasFile);
+		documentUploadEl.getComponent().setDirty(true);
+	}
+	
 	@Override
 	protected boolean validateFormLogic(UserRequest ureq) {
 		boolean allOk = super.validateFormLogic(ureq);
@@ -183,6 +281,22 @@ public class EditReasonController extends FormBasicController {
 				authorizedEl.select(authorizedKeys[0], true);
 			}
 			authorizedEl.setEnabled(!forceAuthorized);
+		} else if (source == documentUploadEl) {
+			if (documentUploadEl.isUploadSuccess()) {
+				doUploadDocument(ureq);
+			}
+		} else if (source instanceof FormLink) {
+			FormLink activeLink = (FormLink) source;
+			Object uobject = activeLink.getUserObject();
+			if (uobject instanceof VFSLeaf) {
+				VFSLeaf file = (VFSLeaf)uobject;
+				if(tempUploadFolder != null && tempUploadFolder.resolve(file.getName()) != null) {
+					file.delete();
+				} else {
+					noticeWrapper.getAttachmentsToDelete().add(file);
+				}
+			}
+			updateAttachments(ureq);
 		}
 		super.formInnerEvent(ureq, source, event);
 	}
@@ -202,4 +316,56 @@ public class EditReasonController extends FormBasicController {
 			noticeWrapper.setAbsenceNoticeType(noticeWrapper.getAbsenceNoticeType());
 		}
 	}
+	
+	private void doUploadDocument(UserRequest ureq) {
+		String fileName = documentUploadEl.getUploadFileName();
+		// checking tmp-folder and msg-container for filename
+		boolean fileExists = false;
+		if ((tempUploadFolder != null && tempUploadFolder.resolve(fileName) != null)
+				|| (documentContainer != null && documentContainer.resolve(fileName) != null)) {
+			fileExists = true;
+		}
+
+		if (fileExists) {
+			try {
+				Files.delete(documentUploadEl.getUploadFile().toPath());
+				documentUploadEl.setErrorKey("attachments.error.file.exists", null);
+				documentUploadEl.showError(true);
+			} catch (IOException e) {
+				logError("Cannot delete uploaded file", e);
+			}
+		} else {
+			// files got stored in an extra tempFolder, to use the same
+			// fileUploader multiple times
+			if(tempUploadFolder == null) {
+				tempUploadFolder = VFSManager.olatRootContainer(File.separator + "tmp/" + CodeHelper.getGlobalForeverUniqueID() + "/", null);
+				noticeWrapper.setTempUploadFolder(tempUploadFolder);
+			}
+			documentUploadEl.moveUploadFileTo(tempUploadFolder);
+			documentUploadEl.showError(false);
+			documentUploadEl.reset();
+			updateAttachments(ureq);
+			showInfo("attachments.upload.successful", fileName);
+		}
+	}
+	
+	public class DocumentMapper implements Mapper {
+		@Override
+		public MediaResource handle(String relPath, HttpServletRequest request) {
+			if(relPath.startsWith("/")) {
+				relPath = relPath.substring(1, relPath.length());
+			}
+			
+			@SuppressWarnings("unchecked")
+			List<VFSItem> files = (List<VFSItem>)filesLayout.contextGet("files");
+			if(files != null) {
+				for(VFSItem file:files) {
+					if(relPath.equalsIgnoreCase(file.getName()) && file instanceof VFSLeaf) {
+						return new VFSMediaResource((VFSLeaf)file);
+					}
+				}
+			}
+			return null;
+		}
+	}
 }
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 52bed771106ae6c76d1f887361a86f2764bc8443..1a1a66d0a411daa681fc0a2f99efeba2b747336f 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
@@ -75,6 +75,8 @@ import org.olat.modules.lecture.ui.coach.IdentitiesLecturesRollCallTableModel.Id
 import org.olat.modules.lecture.ui.component.LectureBlockRollCallStatusItem;
 import org.olat.modules.lecture.ui.profile.IdentityProfileController;
 import org.olat.modules.lecture.ui.wizard.AbsenceNotice3LecturesEntriesStep;
+import org.olat.modules.lecture.ui.wizard.AbsenceNoticeCancelStepCallback;
+import org.olat.modules.lecture.ui.wizard.AbsenceNoticeFinishStepCallback;
 import org.olat.user.UserManager;
 import org.olat.user.propertyhandlers.UserPropertyHandler;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -444,16 +446,8 @@ public class IdentitiesLecturesRollCallController extends FormBasicController {
 		noticeWrapper.setCurrentDate(currentDate);
 		
 		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(), getIdentity());
-			}
-			return StepsMainRunController.DONE_MODIFIED;
-		};
+		StepRunnerCallback stop = new AbsenceNoticeFinishStepCallback(noticeWrapper, getTranslator());
+		StepRunnerCallback cancel = new AbsenceNoticeCancelStepCallback(noticeWrapper);
 		
 		String title = translate("add.dispensation.title");
 		if(type == AbsenceNoticeType.notified) {
@@ -463,7 +457,7 @@ public class IdentitiesLecturesRollCallController extends FormBasicController {
 		}
 		
 		removeAsListenerAndDispose(addNoticeCtrl);
-		addNoticeCtrl = new StepsMainRunController(ureq, getWindowControl(), step, stop, null, title, "");
+		addNoticeCtrl = new StepsMainRunController(ureq, getWindowControl(), step, stop, cancel, title, "");
 		listenTo(addNoticeCtrl);
 		getWindowControl().pushAsModalDialog(addNoticeCtrl.getInitialComponent());
 	}
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 ba544d2ccec741dd8785ded1e438fd921620ac70..b1c3c330a60f5b4abc2cce9e5ae230605f642231 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
@@ -135,6 +135,7 @@ 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);
diff --git a/src/main/java/org/olat/modules/lecture/ui/coach/_content/edit_notice.html b/src/main/java/org/olat/modules/lecture/ui/coach/_content/edit_notice.html
index e24ff1f21319ad7cce16897d2d09d5ef6e8f472b..b3814056fc578bf3aa15dcd49a3ea0f4d91d8f8f 100644
--- a/src/main/java/org/olat/modules/lecture/ui/coach/_content/edit_notice.html
+++ b/src/main/java/org/olat/modules/lecture/ui/coach/_content/edit_notice.html
@@ -1,6 +1,9 @@
 $r.render("reason")
 $r.render("datesAndLectures")
-<div class="o_button_group">
-	$r.render("cancel")
-	$r.render("save")
-</div>
\ No newline at end of file
+<div class="o_form form-horizontal"><div class="form-group clearfix">
+	<div class="col-sm-9 col-sm-offset-3 ">
+		$r.render("cancel")
+		$r.render("save")
+	</div>
+</div></div>
+
diff --git a/src/main/java/org/olat/modules/lecture/ui/coach/_content/notice_files.html b/src/main/java/org/olat/modules/lecture/ui/coach/_content/notice_files.html
new file mode 100644
index 0000000000000000000000000000000000000000..bfa8c511d7e3d580128b9c01b3544447030362b6
--- /dev/null
+++ b/src/main/java/org/olat/modules/lecture/ui/coach/_content/notice_files.html
@@ -0,0 +1,13 @@
+#if($files && $files.size() > 0)
+<table class="table table-condensed table-striped"><tbody>		
+	#foreach ($file in $files)
+		#set( $fname = $file.getName() )
+		<tr>
+			<td style="width:1%"><i class="o_icon o_icon-fw $r.getFiletypeIconCss($fname)"> </i></td>
+			<td><a href="$mapperUri/$fname" target="_blank">$r.escapeHtml($fname)</a></td>
+			<td>$r.formatBytes($file.getSize())</td>
+			<td style="width:1%">$r.render("delete_$foreach.count")</td>
+		</tr>
+	#end
+</tbody></table>
+#end
\ No newline at end of file
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 fded61848a9be53a36c5d845c42437738823b689..70c231a1519d23000a76c8fe0247896eabac3397 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,7 +19,6 @@
  */
 package org.olat.modules.lecture.ui.profile;
 
-import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 
@@ -39,21 +38,10 @@ 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;
@@ -61,8 +49,9 @@ 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.modules.lecture.ui.wizard.AbsenceNoticeCancelStepCallback;
+import org.olat.modules.lecture.ui.wizard.AbsenceNoticeFinishStepCallback;
 import org.olat.user.DisplayPortraitController;
-import org.springframework.beans.factory.annotation.Autowired;
 
 /**
  * 
@@ -89,11 +78,6 @@ public class IdentityProfileController extends BasicController implements Activa
 	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()));
@@ -222,21 +206,9 @@ public class IdentityProfileController extends BasicController implements Activa
 		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(), getIdentity());
-			}
-			
-			if(noticeWrapper.getIdentitiesToContact() != null && !noticeWrapper.getIdentitiesToContact().isEmpty()) {
-				inform(ureq, noticeWrapper);
-			}
-			return StepsMainRunController.DONE_MODIFIED;
-		};
-		
+		StepRunnerCallback stop = new AbsenceNoticeFinishStepCallback(noticeWrapper, getTranslator());
+		StepRunnerCallback cancel = new AbsenceNoticeCancelStepCallback(noticeWrapper);
+
 		String title = translate("add.dispensation.title");
 		if(type == AbsenceNoticeType.notified) {
 			title = translate("add.notice.absence.title");
@@ -245,40 +217,8 @@ public class IdentityProfileController extends BasicController implements Activa
 		}
 		
 		removeAsListenerAndDispose(addNoticeCtrl);
-		addNoticeCtrl = new StepsMainRunController(ureq, getWindowControl(), step, stop, null, title, "");
+		addNoticeCtrl = new StepsMainRunController(ureq, getWindowControl(), step, stop, cancel, 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 fcdcc184452519b6cc0d9777e058b6a9859b363b..7d91fb0e89b566d27a4e3cc166092fa07fa4b30d 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
@@ -54,6 +54,7 @@ public class AbsenceNotice1UserSearchStep extends BasicStep {
 	@Override
 	public StepFormController getStepController(UserRequest ureq, WindowControl wControl, StepsRunContext runContext, Form form) {
 		runContext.put("absence", noticeWrapper);
+		form.setMultipartEnabled(true);
 		return new UserSearchController(ureq, wControl, form, runContext);
 	}
 }
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 a643267199eb4a3c7d36143ee02bdc373177f919..592c8879b21c3c11d488508bc0e9bd7ad55d3934 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
@@ -69,6 +69,7 @@ public class AbsenceNotice3LecturesEntriesStep extends BasicStep {
 		if(noticeWrapper != null) {
 			runContext.put("absence", noticeWrapper);
 		}
+		form.setMultipartEnabled(true);
 		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 12bd855f418e98a2551888742806aabb33b424ca..842b5d04df640bf6e8387e645b2026a1c6a105b2 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
@@ -52,6 +52,7 @@ public class AbsenceNotice4ReasonStep extends BasicStep {
 
 	@Override
 	public StepFormController getStepController(UserRequest ureq, WindowControl wControl, StepsRunContext runContext, Form form) {
+		form.setMultipartEnabled(true);
 		return new ReasonStepController(ureq, wControl, form, runContext, secCallback);
 	}
 }
diff --git a/src/main/java/org/olat/modules/lecture/ui/wizard/AbsenceNoticeCancelStepCallback.java b/src/main/java/org/olat/modules/lecture/ui/wizard/AbsenceNoticeCancelStepCallback.java
new file mode 100644
index 0000000000000000000000000000000000000000..119de09380362dfc24f53c9ef903665252c7d31b
--- /dev/null
+++ b/src/main/java/org/olat/modules/lecture/ui/wizard/AbsenceNoticeCancelStepCallback.java
@@ -0,0 +1,51 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.modules.lecture.ui.wizard;
+
+import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.control.WindowControl;
+import org.olat.core.gui.control.generic.wizard.Step;
+import org.olat.core.gui.control.generic.wizard.StepRunnerCallback;
+import org.olat.core.gui.control.generic.wizard.StepsMainRunController;
+import org.olat.core.gui.control.generic.wizard.StepsRunContext;
+import org.olat.modules.lecture.model.EditAbsenceNoticeWrapper;
+
+/**
+ * 
+ * Initial date: 20 août 2019<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class AbsenceNoticeCancelStepCallback implements StepRunnerCallback {
+	
+	private final EditAbsenceNoticeWrapper noticeWrapper;
+	
+	public AbsenceNoticeCancelStepCallback(EditAbsenceNoticeWrapper noticeWrapper) {
+		this.noticeWrapper = noticeWrapper;
+	}
+
+	@Override
+	public Step execute(UserRequest ureq, WindowControl wControl, StepsRunContext runContext) {
+		if(noticeWrapper.getTempUploadFolder() != null) {
+			noticeWrapper.getTempUploadFolder().deleteSilently();
+		}
+		return StepsMainRunController.DONE_UNCHANGED;
+	}
+}
diff --git a/src/main/java/org/olat/modules/lecture/ui/wizard/AbsenceNoticeFinishStepCallback.java b/src/main/java/org/olat/modules/lecture/ui/wizard/AbsenceNoticeFinishStepCallback.java
new file mode 100644
index 0000000000000000000000000000000000000000..9fc274c0dfa94d8229bf9334980fa32f0d6b8ebe
--- /dev/null
+++ b/src/main/java/org/olat/modules/lecture/ui/wizard/AbsenceNoticeFinishStepCallback.java
@@ -0,0 +1,132 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.modules.lecture.ui.wizard;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.logging.log4j.Logger;
+import org.olat.core.CoreSpringFactory;
+import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.control.WindowControl;
+import org.olat.core.gui.control.generic.wizard.Step;
+import org.olat.core.gui.control.generic.wizard.StepRunnerCallback;
+import org.olat.core.gui.control.generic.wizard.StepsMainRunController;
+import org.olat.core.gui.control.generic.wizard.StepsRunContext;
+import org.olat.core.gui.translator.Translator;
+import org.olat.core.id.Identity;
+import org.olat.core.id.Roles;
+import org.olat.core.logging.Tracing;
+import org.olat.core.logging.activity.ThreadLocalUserActivityLogger;
+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.core.util.vfs.VFSItem;
+import org.olat.core.util.vfs.filters.VFSSystemItemFilter;
+import org.olat.modules.lecture.AbsenceNotice;
+import org.olat.modules.lecture.LectureService;
+import org.olat.modules.lecture.model.EditAbsenceNoticeWrapper;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * 
+ * Initial date: 20 août 2019<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+public class AbsenceNoticeFinishStepCallback implements StepRunnerCallback {
+	
+	private static final Logger log = Tracing.createLoggerFor(AbsenceNoticeFinishStepCallback.class);
+	
+	private final Translator translator;
+	private final EditAbsenceNoticeWrapper noticeWrapper;
+	
+	@Autowired
+	private MailManager mailService;
+	@Autowired
+	private LectureService lectureService;
+	
+	public AbsenceNoticeFinishStepCallback(EditAbsenceNoticeWrapper noticeWrapper, Translator translator) {
+		CoreSpringFactory.autowireObject(this);
+		this.translator = translator;
+		this.noticeWrapper = noticeWrapper;
+	}
+
+	@Override
+	public Step execute(UserRequest ureq, WindowControl wControl, StepsRunContext runContext) {
+		if(noticeWrapper.getAbsenceNotice() == null) {
+			Identity absentIdentity = noticeWrapper.getIdentity();
+			AbsenceNotice notice = lectureService.createAbsenceNotice(absentIdentity, noticeWrapper.getAbsenceNoticeType(),
+					noticeWrapper.getAbsenceNoticeTarget(), noticeWrapper.getStartDate(), noticeWrapper.getEndDate(),
+					noticeWrapper.getAbsenceCategory(), noticeWrapper.getAbsenceReason(), noticeWrapper.getAuthorized(),
+					noticeWrapper.getEntries(), noticeWrapper.getLectureBlocks(), ureq.getIdentity());
+			
+			List<VFSItem> newFiles = new ArrayList<>();
+			if(noticeWrapper.getTempUploadFolder() != null) {
+				newFiles.addAll(noticeWrapper.getTempUploadFolder().getItems(new VFSSystemItemFilter()));
+			}
+			lectureService.updateAbsenceNoticeAttachments(notice, newFiles, noticeWrapper.getAttachmentsToDelete());
+
+		}
+		
+		if(noticeWrapper.getTempUploadFolder() != null) {
+			noticeWrapper.getTempUploadFolder().deleteSilently();
+		}
+
+		if(noticeWrapper.getIdentitiesToContact() != null && !noticeWrapper.getIdentitiesToContact().isEmpty()) {
+			inform(ureq, wControl);
+		}
+		return StepsMainRunController.DONE_MODIFIED;
+	}
+
+	private void inform(UserRequest ureq, WindowControl wControl) {
+		boolean success = false;
+		try {
+			List<ContactList> contactList = new ArrayList<>();
+			ContactList memberList = new ContactList(translator.translate("contact.teachers.list.name"));
+			memberList.addAllIdentites(noticeWrapper.getIdentitiesToContact());
+			MailContext context = new MailContextImpl(wControl.getBusinessControl().getAsString());
+			MailBundle bundle = new MailBundle();
+			bundle.setContext(context);
+			bundle.setFromId(ureq.getIdentity());						
+			bundle.setContactLists(contactList);
+			bundle.setContent(noticeWrapper.getContactSubject(), noticeWrapper.getContactSubject());
+			MailerResult result = mailService.sendMessage(bundle);
+			success = result.isSuccessful();
+			if (success) {
+				wControl.setInfo(translator.translate("msg.send.ok"));
+				// do logging
+				ThreadLocalUserActivityLogger.log(MailLoggingAction.MAIL_SENT, getClass());
+			} else {
+				Roles roles = ureq.getUserSession().getRoles();
+				boolean admin = roles.isAdministrator() || roles.isSystemAdmin();
+				MailHelper.printErrorsAndWarnings(result, wControl, admin, ureq.getLocale());
+			}
+		} catch (Exception e) {
+			log.error("", e);
+			wControl.setWarning(translator.translate("error.msg.send.nok"));
+		}
+	}
+}