From 5500e663cb2a57665a26c2571a5c574f17216035 Mon Sep 17 00:00:00 2001
From: srosse <none@none>
Date: Wed, 14 Jun 2017 14:23:27 +0200
Subject: [PATCH] OO-2636: add reason to cancel panel, beautify the Excel
 export

---
 .../CancelRollCallConfirmationController.java |  58 +++++++-
 .../lecture/ui/LectureBlockExport.java        | 139 ++++++++++++++----
 .../ui/TeacherLecturesTableController.java    |   4 +-
 .../lecture/ui/TeacherRollCallController.java |   2 +-
 .../ui/_i18n/LocalStrings_de.properties       |   5 +
 .../ui/_i18n/LocalStrings_en.properties       |   5 +
 6 files changed, 179 insertions(+), 34 deletions(-)

diff --git a/src/main/java/org/olat/modules/lecture/ui/CancelRollCallConfirmationController.java b/src/main/java/org/olat/modules/lecture/ui/CancelRollCallConfirmationController.java
index ba5cf27eabc..7dcbb32466b 100644
--- a/src/main/java/org/olat/modules/lecture/ui/CancelRollCallConfirmationController.java
+++ b/src/main/java/org/olat/modules/lecture/ui/CancelRollCallConfirmationController.java
@@ -19,8 +19,12 @@
  */
 package org.olat.modules.lecture.ui;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.form.flexible.FormItemContainer;
+import org.olat.core.gui.components.form.flexible.elements.SingleSelection;
 import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
 import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer;
 import org.olat.core.gui.control.Controller;
@@ -30,6 +34,8 @@ import org.olat.modules.lecture.LectureBlock;
 import org.olat.modules.lecture.LectureBlockStatus;
 import org.olat.modules.lecture.LectureRollCallStatus;
 import org.olat.modules.lecture.LectureService;
+import org.olat.modules.lecture.Reason;
+import org.olat.modules.lecture.RollCallSecurityCallback;
 import org.springframework.beans.factory.annotation.Autowired;
 
 /**
@@ -39,15 +45,20 @@ import org.springframework.beans.factory.annotation.Autowired;
  *
  */
 public class CancelRollCallConfirmationController extends FormBasicController {
+
+	private SingleSelection effectiveEndReasonEl;
 	
 	private LectureBlock lectureBlock;
+	private RollCallSecurityCallback secCallback;
 	
 	@Autowired
 	private LectureService lectureService;
 	
-	public CancelRollCallConfirmationController(UserRequest ureq, WindowControl wControl, LectureBlock lectureBlock) {
+	public CancelRollCallConfirmationController(UserRequest ureq, WindowControl wControl,
+			LectureBlock lectureBlock, RollCallSecurityCallback secCallback) {
 		super(ureq, wControl);
 		this.lectureBlock = lectureBlock;
+		this.secCallback = secCallback;
 		
 		initForm(ureq);
 	}
@@ -59,6 +70,34 @@ public class CancelRollCallConfirmationController extends FormBasicController {
 	@Override
 	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
 		
+		List<String> reasonKeyList = new ArrayList<>();
+		List<String> reasonValueList = new ArrayList<>();
+		
+		List<Reason> allReasons = lectureService.getAllReasons();
+		for(Reason reason:allReasons) {
+			reasonKeyList.add(reason.getKey().toString());
+			reasonValueList.add(reason.getTitle());
+		}
+		
+		effectiveEndReasonEl = uifactory.addDropdownSingleselect("effective.reason", "lecture.block.effective.reason", formLayout,
+				reasonKeyList.toArray(new String[reasonKeyList.size()]), reasonValueList.toArray(new String[reasonValueList.size()]), null);
+		effectiveEndReasonEl.setEnabled(secCallback.canEdit());
+		boolean found = false;
+		if(lectureBlock.getReasonEffectiveEnd() != null) {
+			String selectedReasonKey = lectureBlock.getReasonEffectiveEnd().getKey().toString();
+			for(String reasonKey:reasonKeyList) {
+				if(reasonKey.equals(selectedReasonKey)) {
+					effectiveEndReasonEl.select(reasonKey, true);
+					found = true;
+					break;
+				}
+			}
+		}
+		if(!found) {
+			effectiveEndReasonEl.select(reasonKeyList.get(0), true);
+		}
+
+		
 		FormLayoutContainer buttonsCont = FormLayoutContainer.createButtonLayout("buttons", getTranslator());
 		buttonsCont.setRootForm(mainForm);
 		formLayout.add(buttonsCont);
@@ -70,9 +109,26 @@ public class CancelRollCallConfirmationController extends FormBasicController {
 	protected void doDispose() {
 		//
 	}
+	
+	@Override
+	protected boolean validateFormLogic(UserRequest ureq) {
+		boolean allOk = true;
+		
+		effectiveEndReasonEl.clearError();
+		if(!effectiveEndReasonEl.isOneSelected()) {
+			effectiveEndReasonEl.setErrorKey("error.reason.mandatory", null);
+			allOk &= false;
+		}
+
+		return allOk & super.validateFormLogic(ureq);
+	}
 
 	@Override
 	protected void formOK(UserRequest ureq) {
+		Long reasonKey = new Long(effectiveEndReasonEl.getSelectedKey());
+		Reason selectedReason = lectureService.getReason(reasonKey);
+		lectureBlock.setReasonEffectiveEnd(selectedReason);
+
 		lectureBlock.setStatus(LectureBlockStatus.cancelled);
 		lectureBlock.setRollCallStatus(LectureRollCallStatus.closed);
 		lectureBlock.setEffectiveLecturesNumber(0);
diff --git a/src/main/java/org/olat/modules/lecture/ui/LectureBlockExport.java b/src/main/java/org/olat/modules/lecture/ui/LectureBlockExport.java
index 5dfc2e8c877..c74b265db23 100644
--- a/src/main/java/org/olat/modules/lecture/ui/LectureBlockExport.java
+++ b/src/main/java/org/olat/modules/lecture/ui/LectureBlockExport.java
@@ -56,18 +56,22 @@ public class LectureBlockExport extends OpenXMLWorkbookResource {
 	private final Translator translator;
 	private final LectureBlock lectureBlock;
 	private final LectureService lectureService;
+	private final List<Identity> teachers;
 	
 	private final boolean authorizedAbsence;
 	private final boolean isAdministrativeUser;
 	private List<UserPropertyHandler> userPropertyHandlers;
 	
-	public LectureBlockExport(LectureBlock lectureBlock, boolean isAdministrativeUser, Translator translator) {
+	private final UserManager userManager;
+	
+	public LectureBlockExport(LectureBlock lectureBlock, List<Identity> teachers, boolean isAdministrativeUser, Translator translator) {
 		super(label(lectureBlock));
+		this.teachers = teachers;
 		this.lectureBlock = lectureBlock;
 		lectureService = CoreSpringFactory.getImpl(LectureService.class);
 		this.isAdministrativeUser = isAdministrativeUser;
 		this.authorizedAbsence = true;
-		UserManager userManager = CoreSpringFactory.getImpl(UserManager.class);
+		userManager = CoreSpringFactory.getImpl(UserManager.class);
 		userPropertyHandlers = userManager.getUserPropertyHandlersFor(ParticipantListRepositoryController.USER_PROPS_ID, isAdministrativeUser);
 		this.translator = userManager.getPropertyHandlerTranslator(translator);
 	}
@@ -82,13 +86,114 @@ public class LectureBlockExport extends OpenXMLWorkbookResource {
 	protected void generate(OutputStream out) {
 		try(OpenXMLWorkbook workbook = new OpenXMLWorkbook(out, 1)) {
 			OpenXMLWorksheet exportSheet = workbook.nextWorksheet();
-			addHeaders(exportSheet);
+			exportSheet.setHeaderRows(3);
+			addHeaders_1(exportSheet);
+			addHeaders_2(exportSheet);
+			addHeaders_3(exportSheet);
 			addContent(exportSheet);
+			addFooter(exportSheet);
 		} catch (IOException e) {
 			log.error("", e);
 		}
 	}
 	
+	private void addFooter(OpenXMLWorksheet exportSheet) {
+		exportSheet.newRow();
+		exportSheet.newRow();
+		Row footerRow = exportSheet.newRow();
+
+		int pos = 0;
+		if(isAdministrativeUser) {
+			pos++;
+		}
+		for (UserPropertyHandler userPropertyHandler : userPropertyHandlers) {
+			if (userPropertyHandler == null) continue;
+			pos++;
+		}
+
+		footerRow.addCell(pos, translator.translate("export.footer.lectures.hint"));
+	}
+
+	private void addHeaders_1(OpenXMLWorksheet exportSheet) {
+		Row headerRow = exportSheet.newRow();
+		int pos = 0;
+		
+		Formatter formatter = Formatter.getInstance(translator.getLocale());
+		String[] args = new String[] {
+			lectureBlock.getTitle(),
+			formatter.formatDate(lectureBlock.getStartDate()),
+			formatter.formatTimeShort(lectureBlock.getStartDate()),
+			formatter.formatTimeShort(lectureBlock.getEndDate())
+		};
+		headerRow.addCell(pos, translator.translate("export.header.lectureblocks", args));
+		
+		if(isAdministrativeUser) {
+			pos++;
+		}
+		for (UserPropertyHandler userPropertyHandler : userPropertyHandlers) {
+			if (userPropertyHandler == null) continue;
+			pos++;
+		}
+		
+		if(teachers != null && teachers.size() > 0) {
+			StringBuilder sb = new StringBuilder();
+			for(Identity teacher:teachers) {
+				if(sb.length() > 0) sb.append(", ");
+				sb.append(userManager.getUserDisplayName(teacher));
+			}
+			
+			headerRow.addCell(pos, translator.translate("export.header.teachers", new String[]{ sb.toString() }));
+		}
+		
+		if(StringHelper.containsNonWhitespace(lectureBlock.getLocation())) {
+			pos += lectureBlock.getPlannedLecturesNumber();
+			headerRow.addCell(pos, translator.translate("export.header.location", new String[]{ lectureBlock.getLocation() }));
+		}
+	}
+
+	private void addHeaders_2(OpenXMLWorksheet exportSheet) {
+		Row headerRow = exportSheet.newRow();
+		int pos = 0;
+		if(isAdministrativeUser) {
+			pos++;
+		}
+		for (UserPropertyHandler userPropertyHandler : userPropertyHandlers) {
+			if (userPropertyHandler == null) continue;
+			pos++;
+		}
+		headerRow.addCell(pos++, translator.translate("export.header.lectures"));
+	}
+	
+	private void addHeaders_3(OpenXMLWorksheet exportSheet) {
+		Row headerRow = exportSheet.newRow();
+		
+		int pos = 0;
+		if(isAdministrativeUser) {
+			headerRow.addCell(pos++, translator.translate("table.header.username"));
+		}
+		
+		for (UserPropertyHandler userPropertyHandler : userPropertyHandlers) {
+			if (userPropertyHandler == null) continue;
+
+			String propName = userPropertyHandler.getName();
+			headerRow.addCell(pos++, translator.translate("form.name." + propName));
+		}
+		
+		for(int i=0; i<lectureBlock.getPlannedLecturesNumber(); i++) {
+			headerRow.addCell(pos++, Integer.toString(i + 1));	
+		}
+		
+		if(authorizedAbsence) {
+			//authorized absence
+			headerRow.addCell(pos++, translator.translate("table.header.authorized.absence"));
+			//authorized absence reason
+			headerRow.addCell(pos++, translator.translate("authorized.absence.reason"));
+		}
+		
+		//comment
+		headerRow.addCell(pos++, translator.translate("table.header.comment"));
+	}
+	
 	private void addContent(OpenXMLWorksheet exportSheet) {
 		List<Identity> participants = lectureService.getParticipants(lectureBlock);
 		List<LectureBlockRollCall> rollCalls = lectureService.getRollCalls(lectureBlock);
@@ -126,33 +231,5 @@ public class LectureBlockExport extends OpenXMLWorkbookResource {
 		}
 	}
 	
-	private void addHeaders(OpenXMLWorksheet exportSheet) {
-		Row headerRow = exportSheet.newRow();
-		
-		int pos = 0;
-		if(isAdministrativeUser) {
-			headerRow.addCell(pos++, translator.translate("table.header.username"));
-		}
-		
-		for (UserPropertyHandler userPropertyHandler : userPropertyHandlers) {
-			if (userPropertyHandler == null) continue;
 
-			String propName = userPropertyHandler.getName();
-			headerRow.addCell(pos++, translator.translate("form.name." + propName));
-		}
-		
-		for(int i=0; i<lectureBlock.getPlannedLecturesNumber(); i++) {
-			headerRow.addCell(pos++, Integer.toString(i + 1));	
-		}
-		
-		if(authorizedAbsence) {
-			//authorized absence
-			headerRow.addCell(pos++, translator.translate("table.header.authorized.absence"));
-			//authorized absence reason
-			headerRow.addCell(pos++, translator.translate("authorized.absence.reason"));
-		}
-		
-		//comment
-		headerRow.addCell(pos++, translator.translate("table.header.comment"));
-	}
 }
diff --git a/src/main/java/org/olat/modules/lecture/ui/TeacherLecturesTableController.java b/src/main/java/org/olat/modules/lecture/ui/TeacherLecturesTableController.java
index 8429c2a4453..74699c51fd6 100644
--- a/src/main/java/org/olat/modules/lecture/ui/TeacherLecturesTableController.java
+++ b/src/main/java/org/olat/modules/lecture/ui/TeacherLecturesTableController.java
@@ -154,7 +154,9 @@ public class TeacherLecturesTableController extends FormBasicController {
 	}
 	
 	private void doExportLectureBlock(UserRequest ureq, LectureBlock row) {
-		LectureBlockExport export = new LectureBlockExport(row, true, getTranslator());
+		LectureBlock lectureBlock = lectureService.getLectureBlock(row);
+		List<Identity> teachers = lectureService.getTeachers(lectureBlock);
+		LectureBlockExport export = new LectureBlockExport(lectureBlock, teachers, true, getTranslator());
 		ureq.getDispatchResult().setResultingMediaResource(export);
 	}
 	
diff --git a/src/main/java/org/olat/modules/lecture/ui/TeacherRollCallController.java b/src/main/java/org/olat/modules/lecture/ui/TeacherRollCallController.java
index 46dcc8448ea..dd4a82618ad 100644
--- a/src/main/java/org/olat/modules/lecture/ui/TeacherRollCallController.java
+++ b/src/main/java/org/olat/modules/lecture/ui/TeacherRollCallController.java
@@ -559,7 +559,7 @@ public class TeacherRollCallController extends FormBasicController {
 	private void doConfirmCancelLectureBlock(UserRequest ureq) {
 		if(closeRollCallCtrl != null) return;
 		
-		cancelRollCallCtrl = new CancelRollCallConfirmationController(ureq, getWindowControl(), lectureBlock);
+		cancelRollCallCtrl = new CancelRollCallConfirmationController(ureq, getWindowControl(), lectureBlock, secCallback);
 		listenTo(cancelRollCallCtrl);
 		
 		cmc = new CloseableModalController(getWindowControl(), "close", cancelRollCallCtrl.getInitialComponent(), true, translate("cancel.lecture.blocks"));
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 aa5cd9a9ffa..e570ad734a7 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
@@ -44,6 +44,11 @@ error.atleastone.lecture=Bitte w\u00E4hlen Sie mindestens ein Lektionenblock.
 error.integer.between=Der Eingabe muss ein Zahl zwischen {0} und {1}
 error.integer.positive=Der Eingabe muss ein positives Zahl sein.
 error.reason.mandatory=Begr\u00FCndung ist erforderlich
+export.footer.lectures.hint=x = Lektion abwesend
+export.header.lectures=Lectures
+export.header.lectureblocks=Lektionenblock: {0} vom {1} von {2} bis {2}
+export.header.location=Raum: {0}
+export.header.teachers=Dozenten: {0}
 first.admission=Erstzulassung
 form.managedflags.intro=Diese LektionBlock wurde von einem externen Werkzeug erstellt. Einige Einstellungen und Module k\u00F6nnen daher in OpenOLAT nicht ver\u00E4ndert und benutzt werden. Folgende Elemente sind in OpenOLAT gesperrt\: {0}
 info.no.lectures=Sie folgen zur Zeit kein Lektionen
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 92bc3fa279e..608fefed713 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
@@ -44,6 +44,11 @@ error.atleastone.lecture=Please, choose at least one lectures block.
 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
+export.footer.lectures.hint=x = lecture absent
+export.header.lectures=Lektionen
+export.header.lectureblocks=Lectures block: {0} the {1} at {2} until {2}
+export.header.location=Room: {0}
+export.header.teachers=Teachers: {0}
 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}
 info.no.lectures=You don't follow any lectures for the moment.
-- 
GitLab