From a3e20df2ffc9ba8c43742fab6b12be3232fc00e1 Mon Sep 17 00:00:00 2001
From: srosse <none@none>
Date: Tue, 11 Dec 2012 09:04:56 +0100
Subject: [PATCH] OO-377: send invitation to coach of repository entries

---
 .../member/MembersOverviewController.java     |  2 +
 .../wizard/ImportMemberMailController.java    | 31 ++++++---
 .../ImportMember_3_ChoosePermissionStep.java  |  2 +-
 .../wizard/ImportMember_4_MailStep.java       |  8 ++-
 .../olat/repository/RepositoryMailing.java    | 41 +++++++++---
 .../olat/repository/RepositoryManager.java    | 67 ++++++++++++++-----
 .../repository/RepositoryEntryResource.java   |  2 +-
 .../olat/restapi/RepositoryEntriesTest.java   |  8 ++-
 8 files changed, 119 insertions(+), 42 deletions(-)

diff --git a/src/main/java/org/olat/course/member/MembersOverviewController.java b/src/main/java/org/olat/course/member/MembersOverviewController.java
index f908ab7b357..34cb592f8a5 100644
--- a/src/main/java/org/olat/course/member/MembersOverviewController.java
+++ b/src/main/java/org/olat/course/member/MembersOverviewController.java
@@ -210,6 +210,8 @@ public class MembersOverviewController extends BasicController implements Activa
 					}
 				}
 			}
+		} else if (source == cmc) {
+			cleanUp();
 		}
 		super.event(ureq, source, event);
 	}
diff --git a/src/main/java/org/olat/course/member/wizard/ImportMemberMailController.java b/src/main/java/org/olat/course/member/wizard/ImportMemberMailController.java
index 3f06d0113c6..8018db9f727 100644
--- a/src/main/java/org/olat/course/member/wizard/ImportMemberMailController.java
+++ b/src/main/java/org/olat/course/member/wizard/ImportMemberMailController.java
@@ -40,6 +40,8 @@ import org.olat.group.manager.BusinessGroupMailing.MailType;
 import org.olat.group.model.BusinessGroupMembershipChange;
 import org.olat.group.ui.main.MemberPermissionChangeEvent;
 import org.olat.group.ui.wizard.BGMailTemplateController;
+import org.olat.repository.RepositoryEntry;
+import org.olat.repository.RepositoryMailing;
 
 /**
  * 
@@ -50,23 +52,28 @@ public class ImportMemberMailController extends StepFormBasicController {
 	private MailTemplate mailTemplate;
 	private final BGMailTemplateController mailTemplateForm;
 
-	public ImportMemberMailController(UserRequest ureq, WindowControl wControl, Form rootForm, StepsRunContext runContext) {
+	public ImportMemberMailController(UserRequest ureq, WindowControl wControl, RepositoryEntry repoEntry,
+			Form rootForm, StepsRunContext runContext) {
 		super(ureq, wControl, rootForm, runContext, LAYOUT_CUSTOM, "mail_template");
-
+		
 		MemberPermissionChangeEvent e = (MemberPermissionChangeEvent)runContext.get("permissions");
 		boolean mandatoryEmail = CoreSpringFactory.getImpl(BusinessGroupModule.class).isMandatoryEnrolmentEmail(ureq.getUserSession().getRoles());
 		if(mandatoryEmail) {
-			boolean includeParticipantsRights = hasParticipantRightsChanges(e);
-			if(!includeParticipantsRights) {
-				mandatoryEmail = false;//only mandatory for participants
+			boolean includeParticipantsOrTutorsRights = hasParticipantOrTutorsRightsChanges(e);
+			if(!includeParticipantsOrTutorsRights) {
+				mandatoryEmail = false;//only mandatory for participants and tutors
 			}
 		}
 		
 		boolean customizing = e.size() == 1;
-		MailType defaultType = BusinessGroupMailing.getDefaultTemplateType(e);
-		if(defaultType != null && e.getGroups().size() == 1) {
+		MailType defaultGroupType = BusinessGroupMailing.getDefaultTemplateType(e);
+		RepositoryMailing.Type defaultRepoType = RepositoryMailing.getDefaultTemplateType(e);
+
+		if(defaultGroupType != null && e.getGroups().size() == 1) {
 			BusinessGroupShort group = e.getGroups().get(0);
-			mailTemplate = BusinessGroupMailing.getDefaultTemplate(defaultType, group, getIdentity());
+			mailTemplate = BusinessGroupMailing.getDefaultTemplate(defaultGroupType, group, getIdentity());
+		} else if(defaultRepoType != null) {
+			mailTemplate = RepositoryMailing.getDefaultTemplate(defaultRepoType, repoEntry, getIdentity());
 		} else {
 			mailTemplate = new TestMailTemplate();
 		}
@@ -75,8 +82,9 @@ public class ImportMemberMailController extends StepFormBasicController {
 		initForm (ureq);
 	}
 	
-	private boolean hasParticipantRightsChanges(MemberPermissionChangeEvent e) {
-		if(e.getRepoParticipant() != null && e.getRepoParticipant().booleanValue()) {
+	private boolean hasParticipantOrTutorsRightsChanges(MemberPermissionChangeEvent e) {
+		if((e.getRepoParticipant() != null && e.getRepoParticipant().booleanValue())
+				|| (e.getRepoTutor() != null && e.getRepoTutor().booleanValue())){
 			return true;
 		}
 		
@@ -85,6 +93,9 @@ public class ImportMemberMailController extends StepFormBasicController {
 			if(change.getParticipant() != null && change.getParticipant().booleanValue()) {
 				return true;
 			}
+			if(change.getTutor() != null && change.getTutor().booleanValue()) {
+				return true;
+			}
 		}
 		return false;
 	}
diff --git a/src/main/java/org/olat/course/member/wizard/ImportMember_3_ChoosePermissionStep.java b/src/main/java/org/olat/course/member/wizard/ImportMember_3_ChoosePermissionStep.java
index 1fd04e22e47..738d372194c 100644
--- a/src/main/java/org/olat/course/member/wizard/ImportMember_3_ChoosePermissionStep.java
+++ b/src/main/java/org/olat/course/member/wizard/ImportMember_3_ChoosePermissionStep.java
@@ -43,7 +43,7 @@ public class ImportMember_3_ChoosePermissionStep extends BasicStep {
 		super(ureq);
 		this.group = group;
 		this.repoEntry = repoEntry;
-		setNextStep(new ImportMember_4_MailStep(ureq));
+		setNextStep(new ImportMember_4_MailStep(ureq, repoEntry));
 		setI18nTitleAndDescr("import.permission.title", "import.permission.title");
 	}
 
diff --git a/src/main/java/org/olat/course/member/wizard/ImportMember_4_MailStep.java b/src/main/java/org/olat/course/member/wizard/ImportMember_4_MailStep.java
index 2462129c9de..51696a78c3e 100644
--- a/src/main/java/org/olat/course/member/wizard/ImportMember_4_MailStep.java
+++ b/src/main/java/org/olat/course/member/wizard/ImportMember_4_MailStep.java
@@ -26,15 +26,19 @@ import org.olat.core.gui.control.generic.wizard.BasicStep;
 import org.olat.core.gui.control.generic.wizard.PrevNextFinishConfig;
 import org.olat.core.gui.control.generic.wizard.StepFormController;
 import org.olat.core.gui.control.generic.wizard.StepsRunContext;
+import org.olat.repository.RepositoryEntry;
 
 /**
  * 
  * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
  */
 public class ImportMember_4_MailStep extends BasicStep {
+
+	private final RepositoryEntry repoEntry;
 	
-	public ImportMember_4_MailStep(UserRequest ureq) {
+	public ImportMember_4_MailStep(UserRequest ureq, RepositoryEntry repoEntry) {
 		super(ureq);
+		this.repoEntry = repoEntry;
 		setNextStep(NOSTEP);
 		setI18nTitleAndDescr("import.mail.title", "import.mail.title");
 	}
@@ -46,7 +50,7 @@ public class ImportMember_4_MailStep extends BasicStep {
 
 	@Override
 	public StepFormController getStepController(UserRequest ureq, WindowControl wControl, StepsRunContext runContext, Form form) {
-		ImportMemberMailController controller = new ImportMemberMailController(ureq, wControl, form, runContext);
+		ImportMemberMailController controller = new ImportMemberMailController(ureq, wControl, repoEntry, form, runContext);
 		return controller;
 	}
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/repository/RepositoryMailing.java b/src/main/java/org/olat/repository/RepositoryMailing.java
index 39a0bc48eb3..df5e3611df0 100644
--- a/src/main/java/org/olat/repository/RepositoryMailing.java
+++ b/src/main/java/org/olat/repository/RepositoryMailing.java
@@ -35,6 +35,7 @@ import org.olat.core.util.mail.MailPackage;
 import org.olat.core.util.mail.MailTemplate;
 import org.olat.core.util.mail.MailerResult;
 import org.olat.core.util.mail.MailerWithTemplate;
+import org.olat.group.ui.main.MemberPermissionChangeEvent;
 
 /**
  * 
@@ -42,10 +43,19 @@ import org.olat.core.util.mail.MailerWithTemplate;
  */
 public class RepositoryMailing {
 	
+	public static Type getDefaultTemplateType(MemberPermissionChangeEvent event) {
+		if(event.size() == 1) {
+			if(event.getRepoTutor() != null && event.getRepoTutor().booleanValue()) {
+				return Type.addTutor;
+			} else if(event.getRepoParticipant() != null && event.getRepoTutor().booleanValue()) {
+				return Type.addParticipant;
+			}
+		}
+		return null;
+	}
+	
 	/**
-	 * The mail template when adding users to a group. The method chooses
-	 * automatically the right translator for the given group type to customize
-	 * the template text
+	 * The mail template when adding users to a group.
 	 * 
 	 * @param re
 	 * @param actor
@@ -58,9 +68,20 @@ public class RepositoryMailing {
 	}
 	
 	/**
-	 * The mail template when removing users from a repository entry. The method chooses
-	 * automatically the right translator for the given group type to customize
-	 * the template text
+	 * The mail template when adding tutors to a group.
+	 * 
+	 * @param re
+	 * @param actor
+	 * @return the generated MailTemplate
+	 */
+	public static MailTemplate createAddTutorMailTemplate(RepositoryEntry re, Identity actor) {
+		String subjectKey = "notification.mail.added.subject";
+		String bodyKey = "notification.mail.added.body";
+		return createMailTemplate(re, actor, subjectKey, bodyKey);
+	}
+	
+	/**
+	 * The mail template when removing users from a repository entry.
 	 * 
 	 * @param re
 	 * @param actor
@@ -80,6 +101,8 @@ public class RepositoryMailing {
 				return createAddParticipantMailTemplate(re, ureqIdentity);
 			case removeParticipant:
 				return createRemoveParticipantMailTemplate(re, ureqIdentity);
+			case addTutor:
+				return createAddTutorMailTemplate(re, ureqIdentity);
 		}
 		return null;
 	}
@@ -100,8 +123,6 @@ public class RepositoryMailing {
 		if(context == null) {
 			context = new MailContextImpl(null, null, "[RepositoryEntry:" + re.getKey() + "]");
 		}
-		
-		System.out.println("***************************** Send mail");
 
 		MailerResult result = mailer.sendMailAsSeparateMails(context, Collections.singletonList(identity), null, template, null);
 		if(mailing != null) {
@@ -112,6 +133,7 @@ public class RepositoryMailing {
 	public enum Type {
 		addParticipant,
 		removeParticipant,
+		addTutor,
 	}
 	
 	private static MailTemplate createMailTemplate(RepositoryEntry re, Identity actor, String subjectKey, String bodyKey) {
@@ -151,5 +173,4 @@ public class RepositoryMailing {
 		};
 		return mailTempl;
 	}
-
-}
+}
\ No newline at end of file
diff --git a/src/main/java/org/olat/repository/RepositoryManager.java b/src/main/java/org/olat/repository/RepositoryManager.java
index 9e1fbf36144..803b2394b30 100644
--- a/src/main/java/org/olat/repository/RepositoryManager.java
+++ b/src/main/java/org/olat/repository/RepositoryManager.java
@@ -1641,28 +1641,65 @@ public class RepositoryManager extends BasicManager {
 	 * @param re
 	 * @param userActivityLogger
 	 */
-	public void addTutors(Identity ureqIdentity, IdentitiesAddEvent iae, RepositoryEntry re) {
+	public void addTutors(Identity ureqIdentity, Roles ureqRoles, IdentitiesAddEvent iae, RepositoryEntry re, MailPackage mailing) {
 		List<Identity> addIdentities = iae.getAddIdentities();
 		List<Identity> reallyAddedId = new ArrayList<Identity>();
-		for (Identity identity : addIdentities) {
-			if (!securityManager.isIdentityInSecurityGroup(identity, re.getTutorGroup())) {
-				securityManager.addIdentityToSecurityGroup(identity, re.getTutorGroup());
-				reallyAddedId.add(identity);
-				ActionType actionType = ThreadLocalUserActivityLogger.getStickyActionType();
-				ThreadLocalUserActivityLogger.setStickyActionType(ActionType.admin);
-				try{
-					ThreadLocalUserActivityLogger.log(GroupLoggingAction.GROUP_OWNER_ADDED, getClass(),
-							LoggingResourceable.wrap(re, OlatResourceableType.genRepoEntry), LoggingResourceable.wrap(identity));
-				} finally {
-					ThreadLocalUserActivityLogger.setStickyActionType(actionType);
+		for (Identity identityToAdd : addIdentities) {
+			if (!securityManager.isIdentityInSecurityGroup(identityToAdd, re.getTutorGroup())) {
+				
+				boolean mustAccept = true;
+				if(ureqIdentity != null && ureqIdentity.equals(identityToAdd)) {
+					mustAccept = false;//adding itself, we hope that he knows what he makes
+				} else if(ureqRoles == null || ureqIdentity == null) {
+					mustAccept = false;//administrative task
+				} else {
+					mustAccept = repositoryModule.isAcceptMembership(ureqRoles);
 				}
-				logAudit("Idenitity(.key):" + ureqIdentity.getKey() + " added identity '" + identity.getName()
-						+ "' to securitygroup with key " + re.getTutorGroup().getKey());
+				
+				if(mustAccept) {
+					ResourceReservation olderReservation = reservationDao.loadReservation(identityToAdd, re.getOlatResource());
+					if(olderReservation == null) {
+						Calendar cal = Calendar.getInstance();
+						cal.add(Calendar.MONTH, 6);
+						Date expiration = cal.getTime();
+						ResourceReservation reservation =
+								reservationDao.createReservation(identityToAdd, "repo_tutors", expiration, re.getOlatResource());
+						if(reservation != null) {
+							RepositoryMailing.sendEmail(ureqIdentity, identityToAdd, re, RepositoryMailing.Type.addTutor, mailing, mailer);
+						}
+					}
+				} else {
+					addInternalTutors(ureqIdentity, identityToAdd, re, reallyAddedId);
+					RepositoryMailing.sendEmail(ureqIdentity, identityToAdd, re, RepositoryMailing.Type.addTutor, mailing, mailer);
+				}
+
 			}//else silently ignore already owner identities
 		}
 		iae.setIdentitiesAddedEvent(reallyAddedId);
 	}
 	
+	/**
+	 * Internal method to add tutors, it makes no check.
+	 * @param ureqIdentity
+	 * @param identity
+	 * @param re
+	 * @param reallyAddedId
+	 */
+	private void addInternalTutors(Identity ureqIdentity, Identity identity, RepositoryEntry re, List<Identity> reallyAddedId) {
+		securityManager.addIdentityToSecurityGroup(identity, re.getTutorGroup());
+		reallyAddedId.add(identity);
+		ActionType actionType = ThreadLocalUserActivityLogger.getStickyActionType();
+		ThreadLocalUserActivityLogger.setStickyActionType(ActionType.admin);
+		try{
+			ThreadLocalUserActivityLogger.log(GroupLoggingAction.GROUP_OWNER_ADDED, getClass(),
+					LoggingResourceable.wrap(re, OlatResourceableType.genRepoEntry), LoggingResourceable.wrap(identity));
+		} finally {
+			ThreadLocalUserActivityLogger.setStickyActionType(actionType);
+		}
+		logAudit("Idenitity(.key):" + ureqIdentity.getKey() + " added identity '" + identity.getName()
+				+ "' to securitygroup with key " + re.getTutorGroup().getKey());
+	}
+	
 	/**
 	 * remove list of identities as tutor of given repository entry.
 	 * @param ureqIdentity
@@ -1979,7 +2016,7 @@ public class RepositoryManager extends BasicManager {
 			
 			if(e.getRepoTutor() != null) {
 				if(e.getRepoTutor().booleanValue()) {
-					addTutors(ureqIdentity, new IdentitiesAddEvent(e.getMember()), re);
+					addTutors(ureqIdentity, ureqRoles, new IdentitiesAddEvent(e.getMember()), re, mailing);
 				} else {
 					removeTutors(ureqIdentity, Collections.singletonList(e.getMember()), re);
 				}
diff --git a/src/main/java/org/olat/restapi/repository/RepositoryEntryResource.java b/src/main/java/org/olat/restapi/repository/RepositoryEntryResource.java
index 0ed97d28e13..8d559dd26a2 100644
--- a/src/main/java/org/olat/restapi/repository/RepositoryEntryResource.java
+++ b/src/main/java/org/olat/restapi/repository/RepositoryEntryResource.java
@@ -298,7 +298,7 @@ public class RepositoryEntryResource {
 
 			UserRequest ureq = RestSecurityHelper.getUserRequest(request);
 			IdentitiesAddEvent iae = new IdentitiesAddEvent(identityToAdd);
-			repositoryManager.addTutors(ureq.getIdentity(), iae, repoEntry);
+			repositoryManager.addTutors(ureq.getIdentity(), ureq.getUserSession().getRoles(), iae, repoEntry, null);
 			return Response.ok().build();
 		} catch (Exception e) {
 			log.error("Trying to add a coach to a repository entry", e);
diff --git a/src/test/java/org/olat/restapi/RepositoryEntriesTest.java b/src/test/java/org/olat/restapi/RepositoryEntriesTest.java
index 3dbc768cf3f..31d6ed4650f 100644
--- a/src/test/java/org/olat/restapi/RepositoryEntriesTest.java
+++ b/src/test/java/org/olat/restapi/RepositoryEntriesTest.java
@@ -404,13 +404,15 @@ public class RepositoryEntriesTest extends OlatJerseyTestCase {
 		Assert.assertFalse(owners.contains(owner));
 	}
 	
+	private static final Roles ADMIN_ROLES = new Roles(true, false, false, false, false, false, false);
+	
 	@Test
 	public void testGetCoaches() throws IOException, URISyntaxException {
 		Identity coach1 = JunitTestHelper.createAndPersistIdentityAsAuthor("coach-1-" + UUID.randomUUID().toString());
 		Identity coach2 = JunitTestHelper.createAndPersistIdentityAsAuthor("coach-2-" + UUID.randomUUID().toString());
 		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry();
-		repositoryManager.addTutors(coach1, new IdentitiesAddEvent(coach1), re);
-		repositoryManager.addTutors(coach1, new IdentitiesAddEvent(coach2), re);
+		repositoryManager.addTutors(coach1, ADMIN_ROLES, new IdentitiesAddEvent(coach1), re, null);
+		repositoryManager.addTutors(coach1, ADMIN_ROLES, new IdentitiesAddEvent(coach2), re, null);
 		dbInstance.commitAndCloseSession();
 
 		//get the coaches
@@ -470,7 +472,7 @@ public class RepositoryEntriesTest extends OlatJerseyTestCase {
 	public void testRemoveCoach() throws IOException, URISyntaxException {
 		Identity coach = JunitTestHelper.createAndPersistIdentityAsAuthor("coach-4-" + UUID.randomUUID().toString());
 		RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry();
-		repositoryManager.addTutors(coach, new IdentitiesAddEvent(coach), re);
+		repositoryManager.addTutors(coach, ADMIN_ROLES, new IdentitiesAddEvent(coach), re, null);
 		dbInstance.commitAndCloseSession();
 
 		//remove the owner
-- 
GitLab