diff --git a/src/main/java/org/olat/admin/user/course/CourseOverviewController.java b/src/main/java/org/olat/admin/user/course/CourseOverviewController.java index 83e448a55311d86475dae3f6462f0ee4a03cc405..334ede2dccfba60ea72250d936b17282caa7c5e4 100644 --- a/src/main/java/org/olat/admin/user/course/CourseOverviewController.java +++ b/src/main/java/org/olat/admin/user/course/CourseOverviewController.java @@ -26,6 +26,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; import org.olat.NewControllerFactory; import org.olat.admin.user.course.CourseOverviewMembershipDataModel.MSCols; @@ -430,7 +431,27 @@ public class CourseOverviewController extends FormBasicController { * @param ureq * @param views */ - private void doLeave(UserRequest ureq, Collection<CourseMemberView> views) { + private void doLeave(UserRequest ureq, Collection<CourseMemberView> selectedViews) { + List<CourseMemberView> views = selectedViews.stream() + .filter(view -> !view.isFullyManaged()) + .collect(Collectors.toList()); + + if(views.isEmpty()) { + boolean groupWarning = false; + for(CourseMemberView selectedView:selectedViews) { + if(selectedView.getMembership().isBusinessGroupMember()) { + groupWarning = true; + } + } + + if(groupWarning) { + showWarning("warning.cannot.leave.group"); + } else { + showWarning("warning.cannot.leave.entry"); + } + return; + } + List<Long> groupKeys = new ArrayList<>(); List<RepositoryEntry> repoEntryToLeave = new ArrayList<>(); for(CourseMemberView view:views) { @@ -465,6 +486,7 @@ public class CourseOverviewController extends FormBasicController { groupsToDelete.add(group); } } + removeFromCourseDlg = new CourseLeaveDialogBoxController(ureq, getWindowControl(), editedIdentity, repoEntryToLeave, groupsToLeave, groupsToDelete); listenTo(removeFromCourseDlg); diff --git a/src/main/java/org/olat/admin/user/course/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/admin/user/course/_i18n/LocalStrings_de.properties index 6b1bafb488f3051c716e1710eec8787f410dafeb..17797d5f4c3923731e19f6bb83e718b17ef1ad27 100644 --- a/src/main/java/org/olat/admin/user/course/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/admin/user/course/_i18n/LocalStrings_de.properties @@ -14,3 +14,5 @@ error.atleastone=Es muss mindestens einen Besitzer im Kurs "{0}" geben. dialog.modal.bg.mail.text=$org.olat.group.ui.main\:dialog.modal.bg.mail.text group.delete.confirmation=$org.olat.admin.user.groups\:group.delete.confirmation dialog.modal.bg.mail.text=Wollen Sie den Benutzer per Mail benachrichtigen? +warning.cannot.leave.entry=Die Lernressource wird extern verwaltet ('managed'), die Zuordnung der Mitglieder erfolgt automatisch. +warning.cannot.leave.group=Der Benutzer ist \u00FCber eine Gruppe zugeordnet und das Verlassen der Gruppe ist nicht erlaubt. diff --git a/src/main/java/org/olat/admin/user/course/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/admin/user/course/_i18n/LocalStrings_en.properties index d51a320fd173ab1caa520c55f36e5c41d85d2441..fa87f6b3d5397e1c6e6a6c8071b70579aaee2870 100644 --- a/src/main/java/org/olat/admin/user/course/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/admin/user/course/_i18n/LocalStrings_en.properties @@ -12,4 +12,6 @@ unsubscribe.text=Do you really want to unsubscribe the user "{0}" from the cours unsubscribe.withgroups.text=Do you really want to unsubscribe the user "{0}" from the course "{1}" and from the groups "{2}"? error.atleastone=The course "{0}" must have at least one owner. dialog.modal.bg.mail.text=Do you want to inform this user by email? -group.delete.confirmation=$org.olat.admin.user.groups\:group.delete.confirmation \ No newline at end of file +group.delete.confirmation=$org.olat.admin.user.groups\:group.delete.confirmation +warning.cannot.leave.entry=The learning resource is externally managed, member assignment is carried out automatically. +warning.cannot.leave.group=The user is assigned via a group and leaving the group is not allowed. diff --git a/src/main/java/org/olat/admin/user/course/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/admin/user/course/_i18n/LocalStrings_fr.properties index 437e732ad41f1ecacd152cb54c6d4b8db2529f86..421458fd6ad027887fd97fead16d5d111bd3650b 100644 --- a/src/main/java/org/olat/admin/user/course/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/admin/user/course/_i18n/LocalStrings_fr.properties @@ -13,3 +13,5 @@ unsubscribe.successful=Utilisateur retir\u00E9 avec succ\u00E8s unsubscribe.text=Voulez-vous vraiment retirer l'utilisateur "{0}" du cours "{1}"? unsubscribe.title=Retirer l'utilisateur du cours unsubscribe.withgroups.text=Voulez-vous vraiment retirer l'utilisateur "{0}" du cours "{1}" et des groupes "{2}"? +warning.cannot.leave.entry=L'objet didactique est g\u00E9r\u00E9 de l'ext\u00E9rieur et l'affectation du participant se passe automatiquement. +warning.cannot.leave.group=Le participant est assign\u00E9 \u00E0 un groupe et le quitter n'est pas autoris\u00E9. diff --git a/src/main/java/org/olat/core/util/mail/MailTemplate.java b/src/main/java/org/olat/core/util/mail/MailTemplate.java index e818259e0bda4df190d4dcf9c45aa3c001d1db07..7c150f0468526dae4392905e1d89858b8f8023a3 100644 --- a/src/main/java/org/olat/core/util/mail/MailTemplate.java +++ b/src/main/java/org/olat/core/util/mail/MailTemplate.java @@ -26,9 +26,14 @@ package org.olat.core.util.mail; import java.io.File; +import java.util.Locale; import org.apache.velocity.VelocityContext; import org.olat.core.id.Identity; +import org.olat.core.id.User; +import org.olat.core.id.UserConstants; +import org.olat.core.util.i18n.I18nManager; +import org.olat.user.UserManager; /** * Description:<br> @@ -157,4 +162,24 @@ public abstract class MailTemplate { public VelocityContext getContext() { return context; } + + protected static void fillContextWithStandardIdentityValues(VelocityContext vContext, Identity identity, Locale locale) { + if(identity == null) return; + + User user = identity.getUser(); + if(locale == null) { + locale = I18nManager.getInstance().getLocaleOrDefault(user.getPreferences().getLanguage()); + } + + vContext.put("login", identity.getName()); + vContext.put("username", identity.getName()); + vContext.put("userName", identity.getName()); + vContext.put("first", user.getProperty(UserConstants.FIRSTNAME, locale)); + vContext.put("firstname", user.getProperty(UserConstants.FIRSTNAME, locale)); + vContext.put("firstName", user.getProperty(UserConstants.FIRSTNAME, locale)); + vContext.put("last", user.getProperty(UserConstants.LASTNAME, locale)); + vContext.put("lastname", user.getProperty(UserConstants.LASTNAME, locale)); + vContext.put("lastName", user.getProperty(UserConstants.LASTNAME, locale)); + vContext.put("email", UserManager.getInstance().getUserDisplayEmail(identity, locale)); + } } diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTAMailTemplate.java b/src/main/java/org/olat/course/nodes/gta/ui/GTAMailTemplate.java index fb3f77a6cc46e0448c7531a1796310ffe0b8f9c2..82118ecc857b8f7024cbc1effbc5b22cd7a8ef03 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/GTAMailTemplate.java +++ b/src/main/java/org/olat/course/nodes/gta/ui/GTAMailTemplate.java @@ -26,10 +26,8 @@ import java.util.Locale; import org.apache.velocity.VelocityContext; import org.olat.core.gui.translator.Translator; import org.olat.core.id.Identity; -import org.olat.core.id.UserConstants; import org.olat.core.util.Formatter; import org.olat.core.util.mail.MailTemplate; -import org.olat.user.UserManager; /** * @@ -54,12 +52,7 @@ public class GTAMailTemplate extends MailTemplate { public void putVariablesInMailContext(VelocityContext context, Identity recipient) { Locale locale = translator.getLocale(); //compatibility with the old TA - context.put("login", identity.getName()); - context.put("first", identity.getUser().getProperty(UserConstants.FIRSTNAME, locale)); - context.put("firstName", identity.getUser().getProperty(UserConstants.FIRSTNAME, locale)); - context.put("last", identity.getUser().getProperty(UserConstants.LASTNAME, locale)); - context.put("lastName", identity.getUser().getProperty(UserConstants.LASTNAME, locale)); - context.put("email", UserManager.getInstance().getUserDisplayEmail(identity, locale)); + fillContextWithStandardIdentityValues(context, identity, translator.getLocale()); context.put("numberOfFiles", files == null ? "0" : Integer.toString(files.length)); if(files != null && files.length > 0) { diff --git a/src/main/java/org/olat/group/BusinessGroupService.java b/src/main/java/org/olat/group/BusinessGroupService.java index 7f17aadf83243fd5a3140be6950823b7101c3bdf..8dbb063456d4f412e4271c6ddbb13b27816b5a42 100644 --- a/src/main/java/org/olat/group/BusinessGroupService.java +++ b/src/main/java/org/olat/group/BusinessGroupService.java @@ -373,9 +373,6 @@ public interface BusinessGroupService { public List<Identity> getMembers(List<BusinessGroup> businessGroups, String... roles); - public List<Identity> getMembersOf(RepositoryEntryRef entry, List<BusinessGroupRef> businesGroups, String role); - - public int countMembers(BusinessGroup businessGroup, String... roles); diff --git a/src/main/java/org/olat/group/manager/BusinessGroupMailing.java b/src/main/java/org/olat/group/manager/BusinessGroupMailing.java index 4168d1e3a48f8560fb5747aeae3bc817bfd1ebbf..f79ce1a9127cc13aa9336af0909700a238918461 100644 --- a/src/main/java/org/olat/group/manager/BusinessGroupMailing.java +++ b/src/main/java/org/olat/group/manager/BusinessGroupMailing.java @@ -193,6 +193,8 @@ public class BusinessGroupMailing { @Override public void putVariablesInMailContext(VelocityContext vContext, Identity recipient) { + fillContextWithStandardIdentityValues(vContext, recipient, null); + delegate.putVariablesInMailContext(vContext, recipient); if(StringHelper.containsNonWhitespace(infos.getCourseList())) { diff --git a/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java b/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java index e2e61f2afcf5dba2497ce795681171c101c78d68..679dbedc7b9bcdf8e1061aa4d1b881ddc6dadc9d 100644 --- a/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java +++ b/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java @@ -730,7 +730,7 @@ public class BusinessGroupServiceImpl implements BusinessGroupService { Map<String,DeletableGroupData> deleteListeners = CoreSpringFactory.getBeansOfType(DeletableGroupData.class); for (DeletableGroupData deleteListener : deleteListeners.values()) { if(log.isDebugEnabled()) { - log.debug("deleteBusinessGroup: call deleteListener=" + deleteListener); + log.debug("deleteBusinessGroup: call deleteListener={}", deleteListener); } deleteListener.deleteGroupDataFor(group); } @@ -867,7 +867,8 @@ public class BusinessGroupServiceImpl implements BusinessGroupService { if(reservation != null) { BusinessGroupMailing.sendEmail(ureqIdentity, identityToAdd, group, MailType.addCoach, mailing); // logging - log.info(Tracing.M_AUDIT, "Identity(.key):" + ureqIdentity.getKey() + " added identity '" + identityToAdd.getKey() + "' to group with key " + group.getKey()); + log.info(Tracing.M_AUDIT, "Identity(.key):{} added identity '{}' to group with key {}", + ureqIdentity.getKey(), identityToAdd.getKey(), group.getKey()); } } } else { @@ -890,7 +891,8 @@ public class BusinessGroupServiceImpl implements BusinessGroupService { } // do logging ThreadLocalUserActivityLogger.log(GroupLoggingAction.GROUP_OWNER_ADDED, getClass(), LoggingResourceable.wrap(group), LoggingResourceable.wrap(identityToAdd)); - log.info(Tracing.M_AUDIT, "Identity(.key):" + ureqIdentity.getKey() + " added identity '" + identityToAdd.getKey() + "' to group with key " + group.getKey()); + log.info(Tracing.M_AUDIT, "Identity(.key):{} added identity '{}' to group with key {}", + ureqIdentity.getKey(), identityToAdd.getKey(), group.getKey()); } private boolean addParticipant(Identity ureqIdentity, Roles ureqRoles, Identity identityToAdd, BusinessGroup group, @@ -947,7 +949,8 @@ public class BusinessGroupServiceImpl implements BusinessGroupService { } // do logging ThreadLocalUserActivityLogger.log(GroupLoggingAction.GROUP_PARTICIPANT_ADDED, getClass(), LoggingResourceable.wrap(group), LoggingResourceable.wrap(identityToAdd)); - log.info(Tracing.M_AUDIT, "Identity(.key):" + ureqIdentity.getKey() + " added identity '" + identityToAdd.getKey() + "' to group with key " + group.getKey()); + log.info(Tracing.M_AUDIT, "Identity(.key):{} added identity '{}' to group with key {}", + ureqIdentity.getKey(), identityToAdd.getKey(), group.getKey()); // send notification mail in your controller! } @@ -1020,7 +1023,8 @@ public class BusinessGroupServiceImpl implements BusinessGroupService { } // do logging ThreadLocalUserActivityLogger.log(GroupLoggingAction.GROUP_PARTICIPANT_REMOVED, getClass(), LoggingResourceable.wrap(identity), LoggingResourceable.wrap(group)); - log.info(Tracing.M_AUDIT, "Identity(.key):" + ureqIdentity.getKey() + " removed identity '" + identity.getKey() + "' from group with key " + group.getKey()); + log.info(Tracing.M_AUDIT, "Identity(.key):{} removed identity '{}' from group with key {}", + ureqIdentity.getKey(), identity.getKey(), group.getKey()); // Check if a waiting-list with auto-close-ranks is configurated if ( group.getWaitingListEnabled().booleanValue() && group.getAutoCloseRanksEnabled().booleanValue() ) { // even when doOnlyPostRemovingStuff is set to true we really transfer the first Identity here @@ -1256,7 +1260,8 @@ public class BusinessGroupServiceImpl implements BusinessGroupService { } // do logging ThreadLocalUserActivityLogger.log(GroupLoggingAction.GROUP_TO_WAITING_LIST_ADDED, getClass(), LoggingResourceable.wrap(identity)); - log.info(Tracing.M_AUDIT, "Identity(.key):" + ureqIdentity.getKey() + " added identity '" + identity.getKey() + "' to group with key " + group.getKey()); + log.info(Tracing.M_AUDIT, "Identity(.key):{} added identity '{}' to group with key {}", + ureqIdentity.getKey(), identity.getKey(), group.getKey()); // send mail BusinessGroupMailing.sendEmail(ureqIdentity, identity, group, MailType.addToWaitingList, mailing); } @@ -1300,7 +1305,8 @@ public class BusinessGroupServiceImpl implements BusinessGroupService { } // do logging ThreadLocalUserActivityLogger.log(GroupLoggingAction.GROUP_FROM_WAITING_LIST_REMOVED, getClass(), LoggingResourceable.wrap(identity)); - log.info(Tracing.M_AUDIT, "Identity(.key):" + ureqIdentity.getKey() + " removed identity '" + identity.getKey() + "' from group with key " + group.getKey()); + log.info(Tracing.M_AUDIT, "Identity(.key):{} removed identity '{}' from group with key {}", + ureqIdentity.getKey(), identity.getKey(), group.getKey()); // send mail BusinessGroupMailing.sendEmail(ureqIdentity, identity, group, MailType.removeToWaitingList, mailing); } @@ -1365,7 +1371,7 @@ public class BusinessGroupServiceImpl implements BusinessGroupService { MailPackage mailing) { final BusinessGroup reloadedGroup = businessGroupDAO.loadForUpdate(group); - log.info("doEnroll start: group=" + OresHelper.createStringRepresenting(group), identity.getKey().toString()); + log.info("doEnroll start: group={} for {}", OresHelper.createStringRepresenting(group), identity.getKey()); EnrollState enrollStatus = new EnrollState(); List<BusinessGroupModifiedEvent.Deferred> events = new ArrayList<>(); @@ -1375,15 +1381,14 @@ public class BusinessGroupServiceImpl implements BusinessGroupService { if(reservation != null) { addParticipant(ureqIdentity, ureqRoles, identity, reloadedGroup, mailing, events); enrollStatus.setEnrolled(GroupRoles.participant); - log.info("doEnroll (reservation) - setIsEnrolled ", identity.getKey().toString()); - if(reservation != null) { - reservationDao.deleteReservation(reservation); - } + log.info("doEnroll (reservation) - setIsEnrolled {}", identity.getKey()); + reservationDao.deleteReservation(reservation); } else if (reloadedGroup.getMaxParticipants() != null) { int participantsCounter = businessGroupRelationDAO.countEnrollment(reloadedGroup); int reservations = reservationDao.countReservations(reloadedGroup.getResource()); - log.info("doEnroll - participantsCounter: " + participantsCounter + ", reservations: " + reservations + " maxParticipants: " + reloadedGroup.getMaxParticipants().intValue(), identity.getKey().toString()); + log.info("doEnroll - participantsCounter: {}, reservations: {} maxParticipants: {} for {}", + participantsCounter, reservations, reloadedGroup.getMaxParticipants(), identity.getKey()); if ((participantsCounter + reservations) >= reloadedGroup.getMaxParticipants().intValue()) { // already full, show error and updated choose page again if (reloadedGroup.getWaitingListEnabled().booleanValue()) { @@ -1398,7 +1403,7 @@ public class BusinessGroupServiceImpl implements BusinessGroupService { //enough place addParticipant(ureqIdentity, ureqRoles, identity, reloadedGroup, mailing, events); enrollStatus.setEnrolled(GroupRoles.participant); - log.info("doEnroll - setIsEnrolled ", identity.getKey().toString()); + log.info("doEnroll - setIsEnrolled {}", identity.getKey()); } } else { log.debug("doEnroll as participant beginTransaction"); @@ -1409,7 +1414,7 @@ public class BusinessGroupServiceImpl implements BusinessGroupService { dbInstance.commit(); BusinessGroupModifiedEvent.fireDeferredEvents(events); - log.info("doEnroll end", identity.getKey().toString()); + log.info("doEnroll end {}", identity.getKey()); return enrollStatus; } @@ -1491,7 +1496,8 @@ public class BusinessGroupServiceImpl implements BusinessGroupService { } // do logging - log.info(Tracing.M_AUDIT, "Identity(.key):" + ureqIdentity.getKey() + " removed identiy '" + identityToRemove.getKey() + "' from group with key " + group.getKey()); + log.info(Tracing.M_AUDIT, "Identity(.key):{} removed identiy '{}' from group with key {}", + ureqIdentity.getKey(), identityToRemove.getKey(), group.getKey()); ThreadLocalUserActivityLogger.log(GroupLoggingAction.GROUP_OWNER_REMOVED, getClass(), LoggingResourceable.wrap(group), LoggingResourceable.wrap(identityToRemove)); } @@ -1711,13 +1717,6 @@ public class BusinessGroupServiceImpl implements BusinessGroupService { } return ids; } - - @Override - public List<Identity> getMembersOf(RepositoryEntryRef entry, List<BusinessGroupRef> businesGroups, String role) { - // TODO Auto-generated method stub - return null; - } - @Override public int countMembers(BusinessGroup businessGroup, String... roles) { @@ -1731,7 +1730,7 @@ public class BusinessGroupServiceImpl implements BusinessGroupService { if(roles == null || roles.isEmpty() || (roles.size() == 1 && GroupRoles.waiting.name().equals(roles.get(0)))) { return false; } - return roles.size() > 0; + return !roles.isEmpty(); } @Override diff --git a/src/main/java/org/olat/group/ui/BGMailHelper.java b/src/main/java/org/olat/group/ui/BGMailHelper.java index 6886017bd39f06fd13df13010b66eb80839d07ae..c85e4d39b1a54d40025ad4c57fa6ddfe24179f32 100644 --- a/src/main/java/org/olat/group/ui/BGMailHelper.java +++ b/src/main/java/org/olat/group/ui/BGMailHelper.java @@ -231,13 +231,13 @@ public class BGMailHelper { } // create a mail template which all these data - MailTemplate mailTempl = new MailTemplate(subject, body, null) { + return new MailTemplate(subject, body, null) { @Override public void putVariablesInMailContext(VelocityContext context, Identity identity) { + fillContextWithStandardIdentityValues(context, identity, locale); + // Put user variables into velocity context User user = identity.getUser(); - context.put("firstname", user.getProperty(UserConstants.FIRSTNAME, null)); - context.put("lastname", user.getProperty(UserConstants.LASTNAME, null)); //the email of the user, needs to stay named 'login' context.put("login", user.getProperty(UserConstants.EMAIL, null)); // Put variables from greater context @@ -251,7 +251,6 @@ public class BGMailHelper { context.put("courselistempty", trans.translate("notification.mail.no.ressource", null)); } }; - return mailTempl; } public static BGMailTemplateInfos getTemplateInfos(BusinessGroupShort group, List<RepositoryEntryShort> repoEntries) { diff --git a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_fr.properties index 3cbab04a7bd78c29b8425e3fc2a77643b0fda834..3c8b670216ffe9719903d5fd153d74f0b3962e27 100644 --- a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_fr.properties @@ -107,7 +107,7 @@ reservation.coach=comme coach role.curriculum.coach=Coach curses role.curriculum.owner=Propri\u00E9taire de cours (cursus) role.curriculum.participant=Participant cursus -role.group.participant=Participant au groupe +role.group.participant=Participant du groupe role.group.tutor=Coach du groupe role.group.waiting=Liste d'attente role.pending=En attente de confirmation diff --git a/src/main/java/org/olat/repository/RepositoryMailing.java b/src/main/java/org/olat/repository/RepositoryMailing.java index b0293c3a6a39053ac204f6092b41fa1b5ed81a35..90432edb0ca78b2db63b83055738893377b698c3 100644 --- a/src/main/java/org/olat/repository/RepositoryMailing.java +++ b/src/main/java/org/olat/repository/RepositoryMailing.java @@ -244,9 +244,8 @@ public class RepositoryMailing { @Override public void putVariablesInMailContext(VelocityContext context, Identity identity) { // Put user variables into velocity context + fillContextWithStandardIdentityValues(context, identity, locale); User user = identity.getUser(); - context.put("firstname", user.getProperty(UserConstants.FIRSTNAME, null)); - context.put("lastname", user.getProperty(UserConstants.LASTNAME, null)); context.put("login", UserManager.getInstance().getUserDisplayEmail(user, locale)); // Put variables from greater context context.put("coursename", reName);