From 1de0b18010a4c3cf6a5711ef1a9d3f0895f2bc3e Mon Sep 17 00:00:00 2001
From: uhensler <none@none>
Date: Mon, 18 Sep 2017 15:25:02 +0200
Subject: [PATCH] OO-2893: Show the orders and the advance orders in the user
 managment module

---
 .../olat/admin/user/UserAdminController.java  | 101 +++++++++-------
 .../user/_i18n/LocalStrings_de.properties     |   9 +-
 .../user/_i18n/LocalStrings_en.properties     |   9 +-
 .../auto/ui/AdvanceOrderController.java       | 100 ++++++++++++++++
 .../auto/ui/AdvanceOrderDataModel.java        | 113 ++++++++++++++++++
 .../provider/auto/ui/AdvanceOrderRow.java     |  42 +++++++
 .../auto/ui/_content/advance_order_table.html |   1 +
 .../auto/ui/_i18n/LocalStrings_de.properties  |   5 +
 .../auto/ui/_i18n/LocalStrings_en.properties  |   5 +
 .../accesscontrol/ui/OrdersController.java    |  50 +++++---
 .../accesscontrol/ui/UserOrderController.java | 107 +++++++++++++++++
 .../accesscontrol/ui/_content/segments.html   |   7 ++
 .../ui/_i18n/LocalStrings_de.properties       |   3 +
 .../ui/_i18n/LocalStrings_en.properties       |   3 +
 14 files changed, 488 insertions(+), 67 deletions(-)
 create mode 100644 src/main/java/org/olat/resource/accesscontrol/provider/auto/ui/AdvanceOrderController.java
 create mode 100644 src/main/java/org/olat/resource/accesscontrol/provider/auto/ui/AdvanceOrderDataModel.java
 create mode 100644 src/main/java/org/olat/resource/accesscontrol/provider/auto/ui/AdvanceOrderRow.java
 create mode 100644 src/main/java/org/olat/resource/accesscontrol/provider/auto/ui/_content/advance_order_table.html
 create mode 100644 src/main/java/org/olat/resource/accesscontrol/provider/auto/ui/_i18n/LocalStrings_de.properties
 create mode 100644 src/main/java/org/olat/resource/accesscontrol/provider/auto/ui/_i18n/LocalStrings_en.properties
 create mode 100644 src/main/java/org/olat/resource/accesscontrol/ui/UserOrderController.java
 create mode 100644 src/main/java/org/olat/resource/accesscontrol/ui/_content/segments.html

diff --git a/src/main/java/org/olat/admin/user/UserAdminController.java b/src/main/java/org/olat/admin/user/UserAdminController.java
index b40e743ef21..94fc6d70e2f 100644
--- a/src/main/java/org/olat/admin/user/UserAdminController.java
+++ b/src/main/java/org/olat/admin/user/UserAdminController.java
@@ -64,6 +64,7 @@ import org.olat.ldap.LDAPLoginModule;
 import org.olat.modules.lecture.LectureModule;
 import org.olat.modules.lecture.ui.ParticipantLecturesOverviewController;
 import org.olat.properties.Property;
+import org.olat.resource.accesscontrol.ui.UserOrderController;
 import org.olat.user.ChangePrefsController;
 import org.olat.user.DisplayPortraitController;
 import org.olat.user.ProfileAndHomePageEditController;
@@ -76,11 +77,11 @@ import org.springframework.beans.factory.annotation.Autowired;
  *  @author Sabina Jeger
  *  <pre>
  *  Complete rebuild on 17. jan 2006 by Florian Gnaegi
- *  
- *  Functionality to change or view all kind of things for this user 
- *  based on the configuration for the user manager. 
+ *
+ *  Functionality to change or view all kind of things for this user
+ *  based on the configuration for the user manager.
  *  This controller should only be used by the UserAdminMainController.
- *  
+ *
  * </pre>
  */
 public class UserAdminController extends BasicController implements Activateable2 {
@@ -97,12 +98,13 @@ public class UserAdminController extends BasicController implements Activateable
 	private static final String NLS_EDIT_UQUOTA			= "edit.uquota";
 	private static final String NLS_VIEW_GROUPS 		= "view.groups";
 	private static final String NLS_VIEW_COURSES		= "view.courses";
+	private static final String NLS_VIEW_ACCESS			= "view.access";
 	private static final String NLS_VIEW_EFF_STATEMENTS = "view.effStatements";
 	private static final String NLS_VIEW_SUBSCRIPTIONS 	= "view.subscriptions";
 	private static final String NLS_VIEW_LECTURES		= "view.lectures";
-	
+
 	private VelocityContainer myContent;
-		
+
 	private Identity myIdentity = null;
 
 	// controllers used in tabbed pane
@@ -118,7 +120,7 @@ public class UserAdminController extends BasicController implements Activateable
 	private CertificateAndEfficiencyStatementListController efficicencyCtrl;
 
 	private final boolean isOlatAdmin;
-	
+
 	@Autowired
 	private BaseSecurity securityManager;
 	@Autowired
@@ -139,36 +141,36 @@ public class UserAdminController extends BasicController implements Activateable
 		isOlatAdmin = ureq.getUserSession().getRoles().isOLATAdmin();
 
 		if (!securityManager.isIdentityPermittedOnResourceable(
-				ureq.getIdentity(), 
-				Constants.PERMISSION_ACCESS, 
+				ureq.getIdentity(),
+				Constants.PERMISSION_ACCESS,
 				OresHelper.lookupType(this.getClass()))) {
 			throw new OLATSecurityException("Insufficient permissions to access UserAdminController");
 		}
-		
+
 		myIdentity = identity;
-				
-		if (allowedToManageUser(ureq, myIdentity)) {			
+
+		if (allowedToManageUser(ureq, myIdentity)) {
 			myContent = createVelocityContainer("udispatcher");
 			backLink = LinkFactory.createLinkBack(myContent, this);
 			userShortDescrCtr = new UserShortDescription(ureq, wControl, identity);
 			listenTo(userShortDescrCtr);
 			myContent.put("userShortDescription", userShortDescrCtr.getInitialComponent());
-			
+
 			setBackButtonEnabled(true); // default
 			initTabbedPane(myIdentity, ureq);
-			exposeUserDataToVC(ureq, myIdentity);					
+			exposeUserDataToVC(ureq, myIdentity);
 			putInitialPanel(myContent);
 		} else {
-			String supportAddr = WebappHelper.getMailConfig("mailSupport");			
-			showWarning(NLS_ERROR_NOACCESS_TO_USER, supportAddr);			
+			String supportAddr = WebappHelper.getMailConfig("mailSupport");
+			showWarning(NLS_ERROR_NOACCESS_TO_USER, supportAddr);
 			putInitialPanel(new Panel("empty"));
 		}
 	}
-	
+
 	@Override
 	public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) {
 		if(entries == null || entries.isEmpty()) return;
-		
+
 		String entryPoint = entries.get(0).getOLATResourceable().getResourceableTypeName();
 		if("tab".equals(entryPoint)) {
 			userTabP.activate(ureq, entries, state);
@@ -188,7 +190,7 @@ public class UserAdminController extends BasicController implements Activateable
 			myContent.contextPut("showButton", Boolean.valueOf(backButtonEnabled));
 		}
 	}
-	
+
 	/**
 	 * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest, org.olat.core.gui.components.Component, org.olat.core.gui.control.Event)
 	 */
@@ -209,8 +211,8 @@ public class UserAdminController extends BasicController implements Activateable
 		if (source == propertiesCtr) {
 			if (event.getCommand().equals("PropFound")){
 				PropFoundEvent foundEvent = (PropFoundEvent) event;
-				Property myfoundProperty = foundEvent.getProperty();				
-				showInfo(NLS_FOUND_PROPERTY, myfoundProperty.getKey().toString());								
+				Property myfoundProperty = foundEvent.getProperty();
+				showInfo(NLS_FOUND_PROPERTY, myfoundProperty.getKey().toString());
 			}
 		} else if (source == pwdCtr) {
 			if (event == Event.DONE_EVENT) {
@@ -279,7 +281,7 @@ public class UserAdminController extends BasicController implements Activateable
 		// passed all tests, current user is allowed to edit given identity
 		return true;
 	}
-	
+
 	/**
 	 * Initialize the tabbed pane according to the users rights and the system
 	 * configuration
@@ -290,7 +292,7 @@ public class UserAdminController extends BasicController implements Activateable
 		// first Initialize the user details tabbed pane
 		userTabP = new TabbedPane("userTabP", ureq.getLocale());
 		userTabP.addListener(this);
-		
+
 		/**
 		 *  Determine, whether the user admin is or is not able to edit all fields in user
 		 *  profile form. The system admin is always able to do so.
@@ -303,7 +305,7 @@ public class UserAdminController extends BasicController implements Activateable
 		userProfileCtr = new ProfileAndHomePageEditController(ureq, getWindowControl(), identity, canEditAllFields.booleanValue());
 		listenTo(userProfileCtr);
 		userTabP.addTab(translate(NLS_EDIT_UPROFILE), userProfileCtr.getInitialComponent());
-		
+
 		userTabP.addTab(translate(NLS_EDIT_UPREFS), new TabCreator() {
 			@Override
 			public Component create(UserRequest uureq) {
@@ -317,13 +319,13 @@ public class UserAdminController extends BasicController implements Activateable
 			userTabP.addTab(translate(NLS_EDIT_UPWD), new TabCreator() {
 				@Override
 				public Component create(UserRequest uureq) {
-					pwdCtr =  new UserChangePasswordController(uureq, getWindowControl(), identity);				
-					listenTo(pwdCtr); 
+					pwdCtr =  new UserChangePasswordController(uureq, getWindowControl(), identity);
+					listenTo(pwdCtr);
 					return pwdCtr.getInitialComponent();
 				}
 			});
 		}
-		
+
 		Boolean canAuth = BaseSecurityModule.USERMANAGER_ACCESS_TO_AUTH;
 		if (canAuth.booleanValue() || isOlatAdmin) {
 			userTabP.addTab(translate(NLS_EDIT_UAUTH), new TabCreator() {
@@ -335,19 +337,19 @@ public class UserAdminController extends BasicController implements Activateable
 				}
 			});
 		}
-		
+
 		Boolean canProp = BaseSecurityModule.USERMANAGER_ACCESS_TO_PROP;
 		if (canProp.booleanValue() || isOlatAdmin) {
 			userTabP.addTab(translate(NLS_EDIT_UPROP), new TabCreator() {
 				@Override
 				public Component create(UserRequest uureq) {
-					propertiesCtr = new UserPropertiesController(uureq, getWindowControl(), identity);			
+					propertiesCtr = new UserPropertiesController(uureq, getWindowControl(), identity);
 					listenTo(propertiesCtr);
 					return propertiesCtr.getInitialComponent();
 				}
 			});
 		}
-		
+
 		Boolean canStartGroups = BaseSecurityModule.USERMANAGER_CAN_START_GROUPS;
 		userTabP.addTab(translate(NLS_VIEW_GROUPS), new TabCreator() {
 			@Override
@@ -366,8 +368,19 @@ public class UserAdminController extends BasicController implements Activateable
 				return courseCtr.getInitialComponent();
 			}
 		});
-		
-		if (isOlatAdmin) {	
+
+		if (isOlatAdmin) {
+			userTabP.addTab(translate(NLS_VIEW_ACCESS), new TabCreator() {
+				@Override
+				public Component create(UserRequest uureq) {
+					Controller accessCtr = new UserOrderController(ureq, getWindowControl(), identity);
+					listenTo(accessCtr);
+					return accessCtr.getInitialComponent();
+				}
+			});
+		}
+
+		if (isOlatAdmin) {
 			userTabP.addTab(translate(NLS_VIEW_EFF_STATEMENTS), new TabCreator() {
 				@Override
 				public Component create(UserRequest uureq) {
@@ -391,10 +404,10 @@ public class UserAdminController extends BasicController implements Activateable
 					listenTo(subscriptionsCtr);
 					return subscriptionsCtr.getInitialComponent();
 				}
-				
-			});			
+
+			});
 		}
-		
+
 		userTabP.addTab(translate(NLS_EDIT_UROLES), new TabCreator() {
 			@Override
 			public Component create(UserRequest uureq) {
@@ -403,7 +416,7 @@ public class UserAdminController extends BasicController implements Activateable
 				return rolesCtr.getInitialComponent();
 			}
 		});
-		
+
 		Boolean canQuota = BaseSecurityModule.USERMANAGER_ACCESS_TO_QUOTA;
 		if (canQuota.booleanValue() || isOlatAdmin) {
 			userTabP.addTab(translate(NLS_EDIT_UQUOTA), new TabCreator() {
@@ -415,7 +428,7 @@ public class UserAdminController extends BasicController implements Activateable
 				}
 			});
 		}
-		
+
 		if(lectureModule.isEnabled()) {
 			userTabP.addTab(translate(NLS_VIEW_LECTURES), new TabCreator() {
 				@Override
@@ -430,11 +443,11 @@ public class UserAdminController extends BasicController implements Activateable
 				}
 			});
 		}
-		
+
 		// now push to velocity
 		myContent.put("userTabP", userTabP);
 	}
-	
+
 	private boolean isPasswordChangesAllowed(Identity identity) {
 		Boolean canChangePwd = BaseSecurityModule.USERMANAGER_CAN_MODIFY_PWD;
 		if (canChangePwd.booleanValue()  || isOlatAdmin) {
@@ -444,14 +457,14 @@ public class UserAdminController extends BasicController implements Activateable
 				// it's an ldap-user
 				return ldapLoginModule.isPropagatePasswordChangedOnLdapServer();
 			}
-			
+
 			Boolean canCreatePwd = BaseSecurityModule.USERMANAGER_CAN_CREATE_PWD;
 			Authentication olatAuth = securityManager.findAuthentication(identity, BaseSecurityModule.getDefaultAuthProviderIdentifier());
 			if (olatAuth != null || canCreatePwd.booleanValue() || isOlatAdmin) {
 				return true;
 			}
 		}
-		
+
 		return false;
 	}
 
@@ -460,7 +473,7 @@ public class UserAdminController extends BasicController implements Activateable
 	 * @param ureq
 	 * @param identity
 	 */
-	private void exposeUserDataToVC(UserRequest ureq, Identity identity) {		
+	private void exposeUserDataToVC(UserRequest ureq, Identity identity) {
 		removeAsListenerAndDispose(portraitCtr);
 		portraitCtr = new DisplayPortraitController(ureq, getWindowControl(), identity, true, true);
 		myContent.put("portrait", portraitCtr.getInitialComponent());
@@ -468,9 +481,9 @@ public class UserAdminController extends BasicController implements Activateable
 		userShortDescrCtr = new UserShortDescription(ureq, getWindowControl(), identity);
 		myContent.put("userShortDescription", userShortDescrCtr.getInitialComponent());
 	}
-	
+
 	/**
-	 * 
+	 *
 	 * @see org.olat.core.gui.control.DefaultController#doDispose(boolean)
 	 */
 	@Override
diff --git a/src/main/java/org/olat/admin/user/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/admin/user/_i18n/LocalStrings_de.properties
index 86047f2db73..e28d4459250 100644
--- a/src/main/java/org/olat/admin/user/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/admin/user/_i18n/LocalStrings_de.properties
@@ -56,13 +56,13 @@ msg.selectionempty=Bitte min. einen User ausw\u00E4hlen.
 new.error.email.choosen=Diese E-Mail-Adresse ist bereits vorhanden, Sie k\u00F6nnen f\u00FCr diese Person kein neues Benutzerkonto erstellen. Es wurden keine Daten gespeichert.
 new.error.loginname.choosen=Dieser Benutzername ist bereits vergeben. Versuchen Sie es mit einem anderen Benutzernamen.
 new.error.loginname.empty=$org.olat.user\:form.checkUsername
-new.error.password.nomatch=Die beiden Passw\u00F6rter stimmen nicht \u00FCberein. 
+new.error.password.nomatch=Die beiden Passw\u00F6rter stimmen nicht \u00FCberein.
 new.error.property.invalid=Invalid input\!
 new.form.auth=OLAT-Passwort
 new.form.auth.false=nicht jetzt anlegen
 new.form.auth.true=anlegen
 new.form.language=Sprache
-new.form.mandatory=Dieses Feld muss aufgef\u00FCllt werden. 
+new.form.mandatory=Dieses Feld muss aufgef\u00FCllt werden.
 new.form.password.new1=Passwort
 new.form.password.new2=Passwort verifizieren
 new.form.please.enter=Angaben zur Person des neuen Benutzerkontos
@@ -119,7 +119,7 @@ search.form.title.user=Einschr\u00E4nkung auf Benutzer
 search.form.userLoginAfterDate=Nutzer hat sich zuletzt angemeldet nach
 search.form.userLoginBeforeDate=Nutzer hat sich zuletzt angemeldet vor
 selectall=$org.olat.core.gui.components.table\:checkall
-sendtoken.wrong.auth=Dieser Benutzer verf\u00FCgt \u00FCber Authentifizierungsmethoden, welche nicht \u00FCber diesen Passwortlink ge\u00E4ndert werden k\u00F6nnen. Bitte pr\u00FCfen und l\u00F6schen Sie diese Authentifizierungsmethoden zuerst. 
+sendtoken.wrong.auth=Dieser Benutzer verf\u00FCgt \u00FCber Authentifizierungsmethoden, welche nicht \u00FCber diesen Passwortlink ge\u00E4ndert werden k\u00F6nnen. Bitte pr\u00FCfen und l\u00F6schen Sie diese Authentifizierungsmethoden zuerst.
 submit.cancel=Abbrechen
 submit.save=Speichern
 submit.search=Suchen
@@ -131,7 +131,7 @@ table.header.vcard=Visitenkarte
 table.identity.action=Aktion
 table.identity.vcard=<i class\='o_icon o_icon-lg o_icon_home'> </i>
 table.identity.creationdate=Erstellt
-table.identity.lastlogin=letzter Login 
+table.identity.lastlogin=letzter Login
 table.identity.name=Benutzername
 table.name.firstName=Vorname
 table.name.lastName=Nachname
@@ -151,6 +151,7 @@ title.userlist=Liste der Benutzer
 title.usersearch=Benutzersuche
 user.found=Benutzer wurde gefunden
 view.courses=Lernressourcen
+view.access=Buchungen
 view.effStatements=Statements
 view.groups=Gruppen
 view.lectures=Lektionen
diff --git a/src/main/java/org/olat/admin/user/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/admin/user/_i18n/LocalStrings_en.properties
index 2b9c5c6e304..d27e6e965a0 100644
--- a/src/main/java/org/olat/admin/user/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/admin/user/_i18n/LocalStrings_en.properties
@@ -65,7 +65,7 @@ new.form.language=Language
 new.form.mandatory=This field is mandatory.
 new.form.password.new1=Password
 new.form.password.new2=Verify password
-new.form.please.enter=Please enter information on new user 
+new.form.please.enter=Please enter information on new user
 new.form.please.enter.pwd=Choose a password for new user
 new.form.username=User name
 new.user.cancel=Action cancelled. No new user account created.
@@ -98,9 +98,9 @@ search.form.afterDate=User created after
 search.form.beforeDate=User created before
 search.form.constraint.admin=Administrator
 search.form.constraint.auth.LDAP=LDAP password
-search.form.constraint.auth.OLAT=OLAT/WebDAV password 
+search.form.constraint.auth.OLAT=OLAT/WebDAV password
 search.form.constraint.auth.OAuth=Social network authentication / Single-Sign-On (OAuth)
-search.form.constraint.auth.Shib=Shibboleth password 
+search.form.constraint.auth.Shib=Shibboleth password
 search.form.constraint.auth.ShibGeneric=$\:search.form.constraint.auth.Shib
 search.form.constraint.auth.WEBDAV=WebDAV password
 search.form.constraint.auth.none=No authentication
@@ -119,7 +119,7 @@ search.form.title.user=User restrictions
 search.form.userLoginAfterDate=Last user login after
 search.form.userLoginBeforeDate=Last user login before
 selectall=$org.olat.core.gui.components.table\:checkall
-sendtoken.wrong.auth=This user has authentication tokens which can not be changed using this password link. Please review and delete this additional authentication tokens first. 
+sendtoken.wrong.auth=This user has authentication tokens which can not be changed using this password link. Please review and delete this additional authentication tokens first.
 submit.cancel=Cancel
 submit.save=Save
 submit.search=Search
@@ -151,6 +151,7 @@ title.userlist=User list
 title.usersearch=User search
 user.found=User was found
 view.courses=Learning resources
+view.access=Bookings
 view.effStatements=Statements
 view.groups=Groups
 view.lectures=Lectures
diff --git a/src/main/java/org/olat/resource/accesscontrol/provider/auto/ui/AdvanceOrderController.java b/src/main/java/org/olat/resource/accesscontrol/provider/auto/ui/AdvanceOrderController.java
new file mode 100644
index 00000000000..a8e19ced83d
--- /dev/null
+++ b/src/main/java/org/olat/resource/accesscontrol/provider/auto/ui/AdvanceOrderController.java
@@ -0,0 +1,100 @@
+/**
+ * <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.resource.accesscontrol.provider.auto.ui;
+
+import java.util.ArrayList;
+import java.util.Collection;
+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.FlexiTableElement;
+import org.olat.core.gui.components.form.flexible.impl.FormBasicController;
+import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiColumnModel;
+import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel;
+import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableDataModelFactory;
+import org.olat.core.gui.control.Controller;
+import org.olat.core.gui.control.WindowControl;
+import org.olat.core.id.Identity;
+import org.olat.resource.accesscontrol.AccessControlModule;
+import org.olat.resource.accesscontrol.provider.auto.AdvanceOrder;
+import org.olat.resource.accesscontrol.provider.auto.AutoAccessManager;
+import org.olat.resource.accesscontrol.provider.auto.ui.AdvanceOrderDataModel.AdvanceOrderCol;
+import org.olat.resource.accesscontrol.ui.AccessMethodRenderer;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ *
+ * Initial date: 08.09.2017<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+public class AdvanceOrderController extends FormBasicController {
+
+	private FlexiTableElement tableEl;
+	private AdvanceOrderDataModel dataModel;
+	private Identity identity;
+
+	@Autowired
+	private AutoAccessManager autoAccessManager;
+	@Autowired
+	private AccessControlModule acModule;
+
+	public AdvanceOrderController(UserRequest ureq, WindowControl wControl, Identity identity) {
+		super(ureq, wControl, "advance_order_table");
+		this.identity = identity;
+
+		initForm(ureq);
+		loadModel();
+	}
+
+	@Override
+	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
+		FlexiTableColumnModel columnsModel = FlexiTableDataModelFactory.createFlexiTableColumnModel();
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(AdvanceOrderCol.creationDate));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(AdvanceOrderCol.identifierKey));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(AdvanceOrderCol.identifierValue));
+		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(AdvanceOrderCol.method, new AccessMethodRenderer(acModule)));
+		dataModel = new AdvanceOrderDataModel(columnsModel, getLocale());
+		tableEl = uifactory.addTableElement(getWindowControl(), "table", dataModel, getTranslator(), formLayout);
+		tableEl.setEmtpyTableMessageKey("table.advanceOrder.empty");
+	}
+
+	private void loadModel() {
+		Collection<AdvanceOrder> advanceOrders = autoAccessManager.loadPendingAdvanceOrders(identity);
+		List<AdvanceOrderRow> rows = new ArrayList<>(advanceOrders.size());
+		for(AdvanceOrder advanceOrder: advanceOrders) {
+			rows.add(new AdvanceOrderRow(advanceOrder));
+		}
+		dataModel.setObjects(rows);
+		tableEl.reset(true, true, true);
+	}
+
+	@Override
+	protected void formOK(UserRequest ureq) {
+		//
+	}
+
+	@Override
+	protected void doDispose() {
+		//
+	}
+
+}
diff --git a/src/main/java/org/olat/resource/accesscontrol/provider/auto/ui/AdvanceOrderDataModel.java b/src/main/java/org/olat/resource/accesscontrol/provider/auto/ui/AdvanceOrderDataModel.java
new file mode 100644
index 00000000000..499318cf848
--- /dev/null
+++ b/src/main/java/org/olat/resource/accesscontrol/provider/auto/ui/AdvanceOrderDataModel.java
@@ -0,0 +1,113 @@
+/**
+ * <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.resource.accesscontrol.provider.auto.ui;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+
+import org.olat.core.commons.persistence.SortKey;
+import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiTableDataModel;
+import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiSortableColumnDef;
+import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel;
+import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFlexiTableDataModel;
+import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFlexiTableModelDelegate;
+
+
+/**
+ *
+ * Initial date: 08.09.2017<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+public class AdvanceOrderDataModel extends DefaultFlexiTableDataModel<AdvanceOrderRow>
+		implements SortableFlexiTableDataModel<AdvanceOrderRow> {
+
+	private final Locale locale;
+
+	public AdvanceOrderDataModel(FlexiTableColumnModel columnModel, Locale locale) {
+		super(columnModel);
+		this.locale = locale;
+	}
+
+	@Override
+	public void sort(SortKey orderBy) {
+		List<AdvanceOrderRow> rows = new SortableFlexiTableModelDelegate<>(orderBy, this, locale).sort();
+		super.setObjects(rows);
+	}
+
+	@Override
+	public Object getValueAt(int row, int col) {
+		AdvanceOrderRow advanceOrder = getObject(row);
+		return getValueAt(advanceOrder, col);
+	}
+
+	@Override
+	public Object getValueAt(AdvanceOrderRow row, int col) {
+		switch(AdvanceOrderCol.values()[col]) {
+			case creationDate:
+				return row.getAdvanceOrder().getCreationDate();
+			case identifierKey:
+				return row.getAdvanceOrder().getIdentifierKey().toString();
+			case identifierValue:
+				return row.getAdvanceOrder().getIdentifierValue();
+			case method:
+				return Arrays.asList(row.getAdvanceOrder().getMethod());
+			default:
+				return row.getAdvanceOrder();
+		}
+	}
+
+	@Override
+	public DefaultFlexiTableDataModel<AdvanceOrderRow> createCopyWithEmptyList() {
+		return new AdvanceOrderDataModel(getTableColumnModel(), locale);
+	}
+
+	public enum AdvanceOrderCol implements FlexiSortableColumnDef {
+		creationDate("advanceOrder.creationDate", "creationdate"),
+		identifierKey("advanceOrder.identitfier.key", "a_identitfier_key"),
+		identifierValue("advanceOrder.identitfier.value", "a_identitfier_value"),
+		method("advanceOrder.method", "trxMethodIds");
+
+		private final String i18nKey;
+		private final String sortKey;
+
+		private AdvanceOrderCol(String i18nKey, String sortKey) {
+			this.i18nKey = i18nKey;
+			this.sortKey = sortKey;
+		}
+
+		@Override
+		public String i18nHeaderKey() {
+			return i18nKey;
+		}
+
+		@Override
+		public boolean sortable() {
+			return true;
+		}
+
+		@Override
+		public String sortKey() {
+			return sortKey;
+		}
+	}
+
+}
diff --git a/src/main/java/org/olat/resource/accesscontrol/provider/auto/ui/AdvanceOrderRow.java b/src/main/java/org/olat/resource/accesscontrol/provider/auto/ui/AdvanceOrderRow.java
new file mode 100644
index 00000000000..cbedf2468cd
--- /dev/null
+++ b/src/main/java/org/olat/resource/accesscontrol/provider/auto/ui/AdvanceOrderRow.java
@@ -0,0 +1,42 @@
+/**
+ * <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.resource.accesscontrol.provider.auto.ui;
+
+import org.olat.resource.accesscontrol.provider.auto.AdvanceOrder;
+
+/**
+ *
+ * Initial date: 08.09.2017<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+public class AdvanceOrderRow {
+
+	private final AdvanceOrder advanceOrder;
+
+	public AdvanceOrderRow(AdvanceOrder advanceOrder) {
+		this.advanceOrder = advanceOrder;
+	}
+
+	public AdvanceOrder getAdvanceOrder() {
+		return advanceOrder;
+	}
+
+}
diff --git a/src/main/java/org/olat/resource/accesscontrol/provider/auto/ui/_content/advance_order_table.html b/src/main/java/org/olat/resource/accesscontrol/provider/auto/ui/_content/advance_order_table.html
new file mode 100644
index 00000000000..bade9402acd
--- /dev/null
+++ b/src/main/java/org/olat/resource/accesscontrol/provider/auto/ui/_content/advance_order_table.html
@@ -0,0 +1 @@
+$r.render("table")
\ No newline at end of file
diff --git a/src/main/java/org/olat/resource/accesscontrol/provider/auto/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/resource/accesscontrol/provider/auto/ui/_i18n/LocalStrings_de.properties
new file mode 100644
index 00000000000..7270a485c46
--- /dev/null
+++ b/src/main/java/org/olat/resource/accesscontrol/provider/auto/ui/_i18n/LocalStrings_de.properties
@@ -0,0 +1,5 @@
+advanceOrder.creationDate=Erstellungsdatum
+advanceOrder.identitfier.key=Schlüssel
+advanceOrder.identitfier.value=Wert
+advanceOrder.method=Buchungsmethode
+table.advanceOrder.empty=Es sind keine Vorbestelllungen vorhanden.
\ No newline at end of file
diff --git a/src/main/java/org/olat/resource/accesscontrol/provider/auto/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/resource/accesscontrol/provider/auto/ui/_i18n/LocalStrings_en.properties
new file mode 100644
index 00000000000..c56fba9171a
--- /dev/null
+++ b/src/main/java/org/olat/resource/accesscontrol/provider/auto/ui/_i18n/LocalStrings_en.properties
@@ -0,0 +1,5 @@
+advanceOrder.creationDate=Creation date
+advanceOrder.identitfier.key=Key
+advanceOrder.identitfier.value=Value
+advanceOrder.method=Booking method
+table.advanceOrder.empty=There are no advance orders at this time to display.
\ No newline at end of file
diff --git a/src/main/java/org/olat/resource/accesscontrol/ui/OrdersController.java b/src/main/java/org/olat/resource/accesscontrol/ui/OrdersController.java
index b2e6a29cc34..261d7641b1b 100644
--- a/src/main/java/org/olat/resource/accesscontrol/ui/OrdersController.java
+++ b/src/main/java/org/olat/resource/accesscontrol/ui/OrdersController.java
@@ -40,7 +40,9 @@ import org.olat.core.gui.components.stack.BreadcrumbPanelAware;
 import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.Event;
 import org.olat.core.gui.control.WindowControl;
+import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController;
 import org.olat.core.gui.control.generic.dtabs.Activateable2;
+import org.olat.core.id.Identity;
 import org.olat.core.id.OLATResourceable;
 import org.olat.core.id.context.ContextEntry;
 import org.olat.core.id.context.StateEntry;
@@ -54,35 +56,45 @@ import org.olat.user.UserManager;
 import org.springframework.beans.factory.annotation.Autowired;
 
 /**
- * 
+ *
  * Description:<br>
  * List the orders
- * 
+ *
  * <P>
  * Initial Date:  20 avr. 2011 <br>
  * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
  */
 public class OrdersController extends FormBasicController implements Activateable2, BreadcrumbPanelAware {
-	
+
 	private static final String CMD_SELECT = "sel";
-	
+
 
 	private FlexiTableElement tableEl;
 	private OrdersDataSource dataSource;
 	private OrdersDataModel dataModel;
 	private BreadcrumbPanel stackPanel;
+	private CloseableModalController cmc;
+
+	private Identity identity;
 
 	private OrderDetailController detailController;
-	
+
 	@Autowired
 	private ACService acService;
 	@Autowired
 	private UserManager userManager;
 	@Autowired
 	private AccessControlModule acModule;
-	
+
 	public OrdersController(UserRequest ureq, WindowControl wControl) {
 		super(ureq, wControl, LAYOUT_BAREBONE);
+		this.identity = getIdentity();
+		initForm(ureq);
+	}
+
+	public OrdersController(UserRequest ureq, WindowControl wControl, Identity identity) {
+		super(ureq, wControl, LAYOUT_BAREBONE);
+		this.identity = identity;
 		initForm(ureq);
 	}
 
@@ -101,8 +113,8 @@ public class OrdersController extends FormBasicController implements Activateabl
 		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(OrderCol.methods, new AccessMethodRenderer(acModule)));
 		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(OrderCol.total));
 		columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("table.order.details", translate("select"), CMD_SELECT));
-		
-		dataSource = new OrdersDataSource(acService, null, getIdentity(), null);
+
+		dataSource = new OrdersDataSource(acService, null, identity, null);
 		dataModel = new OrdersDataModel(dataSource, getLocale(), userManager, columnsModel);
 		tableEl = uifactory.addTableElement(getWindowControl(), "orderList", dataModel, 25, true, getTranslator(), formLayout);
 		tableEl.setExportEnabled(true);
@@ -112,7 +124,7 @@ public class OrdersController extends FormBasicController implements Activateabl
 		filters.add(new FlexiTableFilter(translate("order.status.payed"), OrderStatus.PAYED.name()));
 		filters.add(new FlexiTableFilter(translate("order.status.error"), OrderStatus.ERROR.name()));
 		tableEl.setFilters("", filters, false);
-		
+
 		if(formLayout instanceof FormLayoutContainer) {
 			FormLayoutContainer layoutCont = (FormLayoutContainer)formLayout;
 			layoutCont.contextPut("title", translate("orders.my"));
@@ -122,9 +134,10 @@ public class OrdersController extends FormBasicController implements Activateabl
 
 	@Override
 	protected void doDispose() {
-		//
+		removeAsListenerAndDispose(cmc);
+		cmc = null;
 	}
-	
+
 	@Override
 	protected void formOK(UserRequest ureq) {
 		//
@@ -144,7 +157,7 @@ public class OrdersController extends FormBasicController implements Activateabl
 		super.formInnerEvent(ureq, source, event);
 	}
 
-	
+
 	@Override
 	protected void event(UserRequest ureq, Controller source, Event event) {
 		if (source == detailController) {
@@ -154,11 +167,11 @@ public class OrdersController extends FormBasicController implements Activateabl
 			}
 		}
 	}
-	
+
 	@Override
 	public void activate(UserRequest ureq, List<ContextEntry> entries, StateEntry state) {
 		/*if(entries == null || entries.isEmpty()) return;
-		
+
 		ContextEntry entry = entries.get(0);
 		String type = entry.getOLATResourceable().getResourceableTypeName();
 		if(Order.class.getSimpleName().equals(type)) {
@@ -180,6 +193,13 @@ public class OrdersController extends FormBasicController implements Activateabl
 		detailController = new OrderDetailController(ureq, bwControl, order.getOrderKey());
 		detailController.hideBackLink();
 		listenTo(detailController);
-		stackPanel.pushController(order.getOrderNr(), detailController);
+		if (stackPanel != null) {
+			stackPanel.pushController(order.getOrderNr(), detailController);
+		} else {
+			cmc = new CloseableModalController(getWindowControl(), translate("close"), detailController.getInitialComponent(),
+					true, translate("order.booking"));
+			cmc.activate();
+			listenTo(cmc);
+		}
 	}
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/resource/accesscontrol/ui/UserOrderController.java b/src/main/java/org/olat/resource/accesscontrol/ui/UserOrderController.java
new file mode 100644
index 00000000000..15b4af5457c
--- /dev/null
+++ b/src/main/java/org/olat/resource/accesscontrol/ui/UserOrderController.java
@@ -0,0 +1,107 @@
+/**
+ * <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.resource.accesscontrol.ui;
+
+import org.olat.core.gui.UserRequest;
+import org.olat.core.gui.components.Component;
+import org.olat.core.gui.components.link.Link;
+import org.olat.core.gui.components.link.LinkFactory;
+import org.olat.core.gui.components.segmentedview.SegmentViewComponent;
+import org.olat.core.gui.components.segmentedview.SegmentViewEvent;
+import org.olat.core.gui.components.segmentedview.SegmentViewFactory;
+import org.olat.core.gui.components.velocity.VelocityContainer;
+import org.olat.core.gui.control.Event;
+import org.olat.core.gui.control.WindowControl;
+import org.olat.core.gui.control.controller.BasicController;
+import org.olat.core.id.Identity;
+import org.olat.resource.accesscontrol.provider.auto.ui.AdvanceOrderController;
+
+/**
+ *
+ * Initial date: 08.09.2017<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+public class UserOrderController extends BasicController {
+
+	private final VelocityContainer mainVC;
+	private final Link ordersLink, advanceOrdersLink;
+	private final SegmentViewComponent segmentView;
+
+	private OrdersController ordersCtrl;
+	private AdvanceOrderController advanceOrdersCtrl;
+
+	private Identity identity;
+
+	public UserOrderController(UserRequest ureq, WindowControl wControl, Identity identity) {
+		super(ureq, wControl);
+		this.identity = identity;
+
+		mainVC = createVelocityContainer("segments");
+
+		segmentView = SegmentViewFactory.createSegmentView("segments", mainVC, this);
+		ordersLink = LinkFactory.createLink("segment.orders", mainVC, this);
+		segmentView.addSegment(ordersLink, true);
+		advanceOrdersLink = LinkFactory.createLink("segment.advance.orders", mainVC, this);
+		segmentView.addSegment(advanceOrdersLink, false);
+
+		doOpenOrders(ureq);
+		putInitialPanel(mainVC);
+	}
+
+	@Override
+	protected void doDispose() {
+		//
+	}
+
+	@Override
+	protected void event(UserRequest ureq, Component source, Event event) {
+		if(source == segmentView) {
+			if(event instanceof SegmentViewEvent) {
+				SegmentViewEvent sve = (SegmentViewEvent)event;
+				String segmentCName = sve.getComponentName();
+				Component clickedLink = mainVC.getComponent(segmentCName);
+				if (clickedLink == ordersLink) {
+					doOpenOrders(ureq);
+				} else if (clickedLink == advanceOrdersLink){
+					doOpenAdvanceOrders(ureq);
+				}
+			}
+		}
+	}
+
+	private void doOpenOrders(UserRequest ureq) {
+		if(ordersCtrl == null) {
+			ordersCtrl = new OrdersController(ureq, getWindowControl(), identity);
+			listenTo(ordersCtrl);
+		}
+		mainVC.put("segmentCmp", ordersCtrl.getInitialComponent());
+	}
+
+	private void doOpenAdvanceOrders(UserRequest ureq) {
+		if(advanceOrdersCtrl == null) {
+			advanceOrdersCtrl = new AdvanceOrderController(ureq, getWindowControl(), identity);
+			listenTo(advanceOrdersCtrl);
+		}
+		mainVC.put("segmentCmp", advanceOrdersCtrl.getInitialComponent());
+	}
+
+
+}
diff --git a/src/main/java/org/olat/resource/accesscontrol/ui/_content/segments.html b/src/main/java/org/olat/resource/accesscontrol/ui/_content/segments.html
new file mode 100644
index 00000000000..1d39f332e91
--- /dev/null
+++ b/src/main/java/org/olat/resource/accesscontrol/ui/_content/segments.html
@@ -0,0 +1,7 @@
+<div class="clearfix">
+	$r.render("segments")<br/>
+
+	#if($r.available("segmentCmp"))
+		$r.render("segmentCmp")
+	#end
+</div>
\ No newline at end of file
diff --git a/src/main/java/org/olat/resource/accesscontrol/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/resource/accesscontrol/ui/_i18n/LocalStrings_de.properties
index f58e5ddd911..be5ad639800 100644
--- a/src/main/java/org/olat/resource/accesscontrol/ui/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/resource/accesscontrol/ui/_i18n/LocalStrings_de.properties
@@ -67,6 +67,7 @@ membership.delete.title=Benutzer entfernen
 menu.orders=Buchungen
 menu.orders.alt=Buchungen
 offer.description=Beschreibung
+order.booking=Buchung
 order.creationDate=Datum
 order.delivery=Gebucht von
 order.details=Detailinformationen
@@ -97,3 +98,5 @@ to=Bis\:
 to.hint=$:from.hint
 transaction.date=Erstellt am
 transaction.details.title=Details \u00FCber Transaktion
+segment.orders=Buchungen
+segment.advance.orders=Vorbestellungen
diff --git a/src/main/java/org/olat/resource/accesscontrol/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/resource/accesscontrol/ui/_i18n/LocalStrings_en.properties
index baa5865578c..701fa5425c9 100644
--- a/src/main/java/org/olat/resource/accesscontrol/ui/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/resource/accesscontrol/ui/_i18n/LocalStrings_en.properties
@@ -90,6 +90,7 @@ membership.delete.title=Remove user
 menu.orders=Bookings
 menu.orders.alt=Bookings
 offer.description=Description
+order.booking=Booking
 order.creationDate=Date
 order.delivery=Booked by
 order.details=Detail information
@@ -120,3 +121,5 @@ to=To\:
 to.hint=$:from.hint
 transaction.date=Created at
 transaction.details.title=Transation details
+segment.orders=Bookings
+segment.advance.orders=Advance bookings
\ No newline at end of file
-- 
GitLab