Index: lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/MonitoringConstants.java =================================================================== RCS file: /usr/local/cvsroot/lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/MonitoringConstants.java,v diff -u -r1.13.10.1.4.2 -r1.13.10.1.4.3 --- lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/MonitoringConstants.java 14 Oct 2011 17:55:09 -0000 1.13.10.1.4.2 +++ lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/MonitoringConstants.java 20 Oct 2011 16:55:16 -0000 1.13.10.1.4.3 @@ -28,26 +28,41 @@ public class MonitoringConstants { - public static final String MONITORING_SERVICE_BEAN_NAME = "monitoringService"; - public static final String CREATE_LESSON_MESSAGE_KEY = "createLessonClass"; - public static final String INIT_LESSON_MESSAGE_KEY = "initializeLesson"; - public static final String PERFORM_CHOSEN_GROUPING_KEY = "performChosenGrouping"; - public static final String KEY_ORGANISATION_ID = "organisationID"; - public static final String KEY_LESSON_ID = "lessonID"; - public static final String KEY_USER_ID = "userID"; - public static final String KEY_STAFF = "staff"; - public static final String KEY_LEARNER = "learners"; - public static final String JOB_START_LESSON = "startScheduleLessonJob"; - public static final String JOB_FINISH_LESSON = "finishScheduleLessonJob"; - public static final String JOB_EMAIL_MESSAGE = "emailScheduleMessageJob"; - public static final String PARAM_LESSON_START_DATE = "lessonStartDate"; - public static final String PARAM_SCHEDULED_NUMBER_DAYS_TO_LESSON_FINISH = "scheduledNumberDaysToLessonFinish"; - public static final String PARAM_LEARNER_ID = "learnerID"; - public static final String KEY_GROUPING_ACTIVITY = "groupingActivityID"; - public static final String KEY_GROUPS = "groups"; - public static final String KEY_GROUP_NAME = "groupName"; - public static final String KEY_GROUP_ORDER_ID = "orderID"; - public static final String KEY_GROUP_LEARNERS = "learners"; - public static final Object KEY_USERS = "users"; - public static final String PARAM_SCHEDULE_TIME_ZONE_IDX = "scheduleTimeZoneIdx"; + public static final String MONITORING_SERVICE_BEAN_NAME = "monitoringService"; + public static final String CREATE_LESSON_MESSAGE_KEY = "createLessonClass"; + public static final String INIT_LESSON_MESSAGE_KEY = "initializeLesson"; + public static final String PERFORM_CHOSEN_GROUPING_KEY = "performChosenGrouping"; + public static final String KEY_ORGANISATION_ID = "organisationID"; + public static final String KEY_LESSON_ID = "lessonID"; + public static final String KEY_USER_ID = "userID"; + public static final String KEY_STAFF = "staff"; + public static final String KEY_LEARNER = "learners"; + public static final String JOB_START_LESSON = "startScheduleLessonJob"; + public static final String JOB_FINISH_LESSON = "finishScheduleLessonJob"; + public static final String JOB_EMAIL_MESSAGE = "emailScheduleMessageJob"; + public static final String PARAM_LESSON_START_DATE = "lessonStartDate"; + public static final String PARAM_SCHEDULED_NUMBER_DAYS_TO_LESSON_FINISH = "scheduledNumberDaysToLessonFinish"; + public static final String PARAM_LEARNER_ID = "learnerID"; + public static final String KEY_GROUPING_ACTIVITY = "groupingActivityID"; + public static final String KEY_GROUPS = "groups"; + public static final String KEY_GROUP_NAME = "groupName"; + public static final String KEY_GROUP_ORDER_ID = "orderID"; + public static final String KEY_GROUP_LEARNERS = "learners"; + public static final Object KEY_USERS = "users"; + public static final String PARAM_SCHEDULE_TIME_ZONE_IDX = "scheduleTimeZoneIdx"; + + // --------------------------------------------------------------------- + // Search type constants used in EmailNotificationsAction + // --------------------------------------------------------------------- + public static final int LESSON_TYPE_ASSIGNED_TO_LESSON = 0; + public static final int LESSON_TYPE_HAVENT_FINISHED_LESSON = 1; + public static final int LESSON_TYPE_HAVE_FINISHED_LESSON = 2; + public static final int LESSON_TYPE_HAVENT_STARTED_LESSON = 3; + public static final int LESSON_TYPE_HAVE_STARTED_LESSON = 4; + public static final int LESSON_TYPE_HAVENT_REACHED_PARTICULAR_ACTIVITY = 5; + public static final int LESSON_TYPE_LESS_THAN_X_DAYS_TO_DEADLINE = 6; + public static final int COURSE_TYPE_HAVE_FINISHED_PARTICULAR_LESSON = 7; + public static final int COURSE_TYPE_HAVENT_STARTED_PARTICULAR_LESSON = 8; + public static final int COURSE_TYPE_HAVENT_STARTED_ANY_LESSONS = 9; + public static final int COURSE_TYPE_HAVE_FINISHED_THESE_LESSONS = 10; } Index: lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/monitoringApplicationContext.xml =================================================================== RCS file: /usr/local/cvsroot/lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/monitoringApplicationContext.xml,v diff -u -r1.30.6.2 -r1.30.6.3 --- lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/monitoringApplicationContext.xml 14 Oct 2011 17:55:09 -0000 1.30.6.2 +++ lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/monitoringApplicationContext.xml 20 Oct 2011 16:55:16 -0000 1.30.6.3 @@ -32,6 +32,7 @@ + Index: lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/dto/EmailScheduleMessageJobDTO.java =================================================================== RCS file: /usr/local/cvsroot/lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/dto/EmailScheduleMessageJobDTO.java,v diff -u -r1.1.2.1 -r1.1.2.2 --- lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/dto/EmailScheduleMessageJobDTO.java 14 Oct 2011 17:55:10 -0000 1.1.2.1 +++ lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/dto/EmailScheduleMessageJobDTO.java 20 Oct 2011 16:55:16 -0000 1.1.2.2 @@ -33,7 +33,7 @@ private Date triggerDate; private String emailBody; - private String[] userIdStrs; + private int searchType; public Date getTriggerDate() { return triggerDate; @@ -49,22 +49,22 @@ this.emailBody = emailBody; } - public String[] getUserIdStrs() { - return userIdStrs; + public int getSearchType() { + return searchType; } - public void setUserIdStrs(String[] userIdStrs) { - this.userIdStrs = userIdStrs; + public void setSearchType(int searchType) { + this.searchType = searchType; } public String toString() { return new ToStringBuilder(this).append("emailBody", emailBody).append("triggerDate", triggerDate) - .append("userIdStrs", userIdStrs).toString(); + .append("searchType", searchType).toString(); } public int compareTo(Object other) { EmailScheduleMessageJobDTO otherDto = (EmailScheduleMessageJobDTO) other; return new CompareToBuilder().append(triggerDate, otherDto.triggerDate).append(emailBody, otherDto.emailBody) - .append(userIdStrs, otherDto.userIdStrs).toComparison(); + .append(searchType, otherDto.searchType).toComparison(); } } Index: lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/quartz/job/EmailScheduleMessageJob.java =================================================================== RCS file: /usr/local/cvsroot/lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/quartz/job/EmailScheduleMessageJob.java,v diff -u -r1.1.2.1 -r1.1.2.2 --- lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/quartz/job/EmailScheduleMessageJob.java 14 Oct 2011 17:55:11 -0000 1.1.2.1 +++ lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/quartz/job/EmailScheduleMessageJob.java 20 Oct 2011 16:55:16 -0000 1.1.2.2 @@ -23,19 +23,27 @@ /* $Id$ */ package org.lamsfoundation.lams.monitoring.quartz.job; +import java.util.Collection; import java.util.Map; import org.apache.log4j.Logger; import org.lamsfoundation.lams.events.DeliveryMethodMail; import org.lamsfoundation.lams.events.IEventNotificationService; -import org.lamsfoundation.lams.monitoring.MonitoringConstants; import org.lamsfoundation.lams.monitoring.service.IMonitoringService; +import org.lamsfoundation.lams.usermanagement.User; +import org.lamsfoundation.lams.web.util.AttributeNames; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.quartz.SchedulerContext; import org.quartz.SchedulerException; import org.springframework.context.ApplicationContext; +/** + * Email messages at the specified date. List of recipients is being constructed real time based on specified search + * criterias. + * + * @author Andey Balan + */ public class EmailScheduleMessageJob extends MonitoringJob { // --------------------------------------------------------------------- // Instance variables @@ -46,24 +54,33 @@ IMonitoringService monitoringService = getMonitoringService(context); IEventNotificationService eventNotificationService = getEventNotificationService(context); - // getting gate id set from scheduler Map properties = context.getJobDetail().getJobDataMap(); String emailBody = (String) properties.get("emailBody"); - String[] userIdStrs = (String[]) properties.get(MonitoringConstants.KEY_USER_ID); - - for (String userIdStr : userIdStrs) { - long userId = Long.parseLong(userIdStr); + + //get users to whom send emails + int searchType = (Integer) properties.get("searchType"); + Long lessonId = (Long) properties.get(AttributeNames.PARAM_LESSON_ID); + Integer orgId = (Integer) properties.get(AttributeNames.PARAM_ORGANISATION_ID); + Long activityId = (Long) properties.get(AttributeNames.PARAM_ACTIVITY_ID); + Integer xDaystoFinish = (Integer) properties.get("daysToDeadline"); + String[] lessonIds = (String[]) properties.get("lessonIDs"); + Collection users = getMonitoringService(context).getUsersByEmailNotificationSearchType(searchType, + lessonId, lessonIds, activityId, xDaystoFinish, orgId); + + for (User user : users) { + long userId = user.getUserId(); log.debug("Sending scheduled email to user [" + userId + "]."); eventNotificationService.sendMessage(userId, DeliveryMethodMail.getInstance(), monitoringService .getMessageService().getMessage("event.emailnotifications.email.subject", new Object[] {}), emailBody); } } - - private IEventNotificationService getEventNotificationService(JobExecutionContext context) throws JobExecutionException { - final String CONTEXT_NAME = "context.central"; - + + private IEventNotificationService getEventNotificationService(JobExecutionContext context) + throws JobExecutionException { try { + final String CONTEXT_NAME = "context.central"; + SchedulerContext sc = context.getScheduler().getContext(); ApplicationContext cxt = (ApplicationContext) sc.get(CONTEXT_NAME); return (IEventNotificationService) cxt.getBean("eventNotificationService"); Index: lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/IMonitoringService.java =================================================================== RCS file: /usr/local/cvsroot/lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/IMonitoringService.java,v diff -u -r1.85.4.1.4.6 -r1.85.4.1.4.7 --- lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/IMonitoringService.java 5 Sep 2011 19:14:48 -0000 1.85.4.1.4.6 +++ lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/IMonitoringService.java 20 Oct 2011 16:55:16 -0000 1.85.4.1.4.7 @@ -25,6 +25,7 @@ package org.lamsfoundation.lams.monitoring.service; import java.io.IOException; +import java.util.Collection; import java.util.Date; import java.util.List; import java.util.SortedSet; @@ -442,6 +443,20 @@ * @throws IOException */ public String getLessonStaff(Long lessonID, Integer userID) throws IOException; + + + /** + * Returns users by search type criteria. It's sorted by first and last user names. + * + * @param searchType one of 11 constants from MonitoringConstants defining search type + * @param lessonId + * @param lessonIds + * @param activityId + * @param xDaystoFinish + * @param org + * @return + */ + Collection getUsersByEmailNotificationSearchType(int searchType, Long lessonId, String[] lessonIds, Long activityId, Integer xDaystoFinish, Integer orgId); /** * This method returns the LearningDesign details for a given Lesson Index: lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/MonitoringService.java =================================================================== RCS file: /usr/local/cvsroot/lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/MonitoringService.java,v diff -u -r1.149.2.7.2.15 -r1.149.2.7.2.16 --- lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/MonitoringService.java 14 Oct 2011 17:55:12 -0000 1.149.2.7.2.15 +++ lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/MonitoringService.java 20 Oct 2011 16:55:16 -0000 1.149.2.7.2.16 @@ -29,6 +29,7 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; +import java.util.Collection; import java.util.Comparator; import java.util.Date; import java.util.HashSet; @@ -47,6 +48,7 @@ import javax.servlet.http.HttpSession; +import org.apache.commons.collections.CollectionUtils; import org.apache.log4j.Logger; import org.lamsfoundation.lams.authoring.service.IAuthoringService; import org.lamsfoundation.lams.dao.IBaseDAO; @@ -66,6 +68,7 @@ import org.lamsfoundation.lams.learningdesign.ToolActivity; import org.lamsfoundation.lams.learningdesign.dao.IActivityDAO; import org.lamsfoundation.lams.learningdesign.dao.IGroupDAO; +import org.lamsfoundation.lams.learningdesign.dao.IGroupUserDAO; import org.lamsfoundation.lams.learningdesign.dao.IGroupingDAO; import org.lamsfoundation.lams.learningdesign.dao.ILearningDesignDAO; import org.lamsfoundation.lams.learningdesign.dao.ITransitionDAO; @@ -168,6 +171,8 @@ private IGroupingDAO groupingDAO; private IGroupDAO groupDAO; + + private IGroupUserDAO groupUserDAO; private ILearnerProgressDAO learnerProgressDAO; @@ -308,6 +313,13 @@ } /** + * @param groupDAO + */ + public void setGroupUserDAO(IGroupUserDAO groupUserDAO) { + this.groupUserDAO = groupUserDAO; + } + + /** * @param groupingDAO */ public void setGroupingDAO(IGroupingDAO groupingDAO) { @@ -1583,8 +1595,124 @@ } return flashMessage.serializeMessage(); } + + public Collection getUsersByEmailNotificationSearchType(int searchType, Long lessonId, String[] lessonIds, Long activityId, Integer xDaystoFinish, Integer orgId) { + + Lesson lesson = null; + if (lessonId != null) { + lesson = learnerService.getLesson(lessonId); + } + + Collection users = new LinkedList(); + switch (searchType) { + case MonitoringConstants.LESSON_TYPE_ASSIGNED_TO_LESSON: + users = lesson.getAllLearners(); + break; + + case MonitoringConstants.LESSON_TYPE_HAVENT_FINISHED_LESSON: + Set allUsers = lesson.getAllLearners(); + List usersCompletedLesson = getUsersCompletedLesson(lessonId); + users = CollectionUtils.subtract(allUsers, usersCompletedLesson); + break; + + case MonitoringConstants.LESSON_TYPE_HAVE_FINISHED_LESSON: + case MonitoringConstants.COURSE_TYPE_HAVE_FINISHED_PARTICULAR_LESSON: + users = getUsersCompletedLesson(lessonId); + break; + + case MonitoringConstants.LESSON_TYPE_HAVENT_STARTED_LESSON: + case MonitoringConstants.COURSE_TYPE_HAVENT_STARTED_PARTICULAR_LESSON: + allUsers = lesson.getAllLearners(); + List usersStartedLesson = lessonService.getActiveLessonLearners(lessonId); + users = CollectionUtils.subtract(allUsers, usersStartedLesson); + break; + + case MonitoringConstants.LESSON_TYPE_HAVE_STARTED_LESSON: + users = lessonService.getActiveLessonLearners(lessonId); + break; + case MonitoringConstants.LESSON_TYPE_HAVENT_REACHED_PARTICULAR_ACTIVITY: + Activity activity = learnerService.getActivity(activityId); + allUsers = lesson.getAllLearners(); + List usersAttemptedActivity = lessonService.getLearnersHaveAttemptedActivity(activity); + users = CollectionUtils.subtract(allUsers, usersAttemptedActivity); + break; + + case MonitoringConstants.LESSON_TYPE_LESS_THAN_X_DAYS_TO_DEADLINE: + Date now = new Date(); + Calendar currentTimePlusXDays = Calendar.getInstance(); + currentTimePlusXDays.setTime(now); + currentTimePlusXDays.add(Calendar.DATE, xDaystoFinish); + + Date scheduleEndDate = lesson.getScheduleEndDate(); + if (scheduleEndDate != null) { + if (now.before(scheduleEndDate) && currentTimePlusXDays.getTime().after(scheduleEndDate)) { + users = lesson.getAllLearners(); + } + + } else if (lesson.isScheduledToCloseForIndividuals()) { + users = groupUserDAO.getUsersWithLessonEndingSoonerThan(lesson, currentTimePlusXDays.getTime()); + } + break; + + case MonitoringConstants.COURSE_TYPE_HAVENT_STARTED_ANY_LESSONS: + List allUSers = learnerService.getUserManagementService().getUsersFromOrganisation(orgId); + Set usersStartedAtLest1Lesson = new TreeSet(); + + Organisation org = (Organisation) learnerService.getUserManagementService().findById(Organisation.class, orgId); + Set lessons = org.getLessons(); + for (Lesson les : lessons) { + Activity firstActivity = les.getLearningDesign().getFirstActivity(); + List usersStartedFirstActivity = learnerProgressDAO.getLearnersHaveAttemptedActivity(firstActivity); + usersStartedAtLest1Lesson.addAll(usersStartedFirstActivity); + } + + users = CollectionUtils.subtract(allUSers, usersStartedAtLest1Lesson); + + break; + + case MonitoringConstants.COURSE_TYPE_HAVE_FINISHED_THESE_LESSONS: + int i = 0; + for (String lessonIdStr : lessonIds) { + lessonId = Long.parseLong(lessonIdStr); + List completedLesson = getUsersCompletedLesson(lessonId); + if (i++ == 0) { + users = completedLesson; + } else { + users = CollectionUtils.intersection(users, completedLesson); + } + } + break; + } + + Set sortedUsers = new TreeSet(new Comparator() { + public int compare(User usr0, User usr1) { + return ((usr0.getFirstName() + usr0.getLastName() + usr0.getLogin()).compareTo(usr1.getFirstName() + usr1.getLastName() + usr1.getLogin())); + } + }); + sortedUsers.addAll(users); + + return sortedUsers; + } + /** + * Returns list of users who has already finished specified lesson. + * + * @param lessonId specified lesson + * @return + */ + private List getUsersCompletedLesson(Long lessonId) { + List usersCompletedLesson = new LinkedList(); + + List completedLearnerProgresses = learnerProgressDAO.getCompletedLearnerProgressForLesson(lessonId); + for (LearnerProgress learnerProgress : completedLearnerProgresses) { + usersCompletedLesson.add(learnerProgress.getUser()); + } + return usersCompletedLesson; + } + + + /** * (non-Javadoc) * * @see org.lamsfoundation.lams.monitoring.service.IMonitoringService#getLearningDesignDetails(java.lang.Long) Index: lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/EmailNotificationsAction.java =================================================================== RCS file: /usr/local/cvsroot/lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/EmailNotificationsAction.java,v diff -u -r1.1.2.4 -r1.1.2.5 --- lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/EmailNotificationsAction.java 14 Oct 2011 17:55:11 -0000 1.1.2.4 +++ lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/EmailNotificationsAction.java 20 Oct 2011 16:55:16 -0000 1.1.2.5 @@ -26,11 +26,10 @@ import java.io.IOException; import java.util.Calendar; import java.util.Collection; -import java.util.Comparator; import java.util.Date; +import java.util.HashMap; import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; +import java.util.Map; import java.util.Set; import java.util.TimeZone; import java.util.TreeSet; @@ -40,7 +39,6 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; -import org.apache.commons.collections.CollectionUtils; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; @@ -50,21 +48,18 @@ import org.lamsfoundation.lams.events.DeliveryMethodMail; import org.lamsfoundation.lams.events.IEventNotificationService; import org.lamsfoundation.lams.learning.service.ICoreLearnerService; -import org.lamsfoundation.lams.learningdesign.Activity; import org.lamsfoundation.lams.learningdesign.dao.IGroupUserDAO; -import org.lamsfoundation.lams.lesson.LearnerProgress; import org.lamsfoundation.lams.lesson.Lesson; import org.lamsfoundation.lams.lesson.dao.ILearnerProgressDAO; import org.lamsfoundation.lams.lesson.service.ILessonService; import org.lamsfoundation.lams.monitoring.MonitoringConstants; import org.lamsfoundation.lams.monitoring.dto.EmailScheduleMessageJobDTO; import org.lamsfoundation.lams.monitoring.service.IMonitoringService; -import org.lamsfoundation.lams.monitoring.service.MonitoringService; -import org.lamsfoundation.lams.monitoring.service.MonitoringServiceException; import org.lamsfoundation.lams.monitoring.service.MonitoringServiceProxy; import org.lamsfoundation.lams.usermanagement.Organisation; import org.lamsfoundation.lams.usermanagement.User; import org.lamsfoundation.lams.usermanagement.dto.UserDTO; +import org.lamsfoundation.lams.usermanagement.service.IUserManagementService; import org.lamsfoundation.lams.util.DateUtil; import org.lamsfoundation.lams.util.WebUtil; import org.lamsfoundation.lams.web.action.LamsDispatchAction; @@ -76,6 +71,7 @@ import org.quartz.SchedulerException; import org.quartz.SimpleTrigger; import org.quartz.Trigger; +import org.springframework.util.Assert; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; @@ -97,29 +93,14 @@ * ----------------XDoclet Tags-------------------- */ public class EmailNotificationsAction extends LamsDispatchAction { - + // --------------------------------------------------------------------- // Class level constants // --------------------------------------------------------------------- - private static final int LESSON_TYPE_ASSIGNED_TO_LESSON = 0; - private static final int LESSON_TYPE_HAVENT_FINISHED_LESSON = 1; - private static final int LESSON_TYPE_HAVE_FINISHED_LESSON = 2; - private static final int LESSON_TYPE_HAVENT_STARTED_LESSON = 3; - private static final int LESSON_TYPE_HAVE_STARTED_LESSON = 4; - private static final int LESSON_TYPE_HAVENT_REACHED_PARTICULAR_ACTIVITY = 5; - private static final int LESSON_TYPE_LESS_THAN_X_DAYS_TO_DEADLINE = 6; - private static final int COURSE_TYPE_HAVE_FINISHED_PARTICULAR_LESSON = 7; - private static final int COURSE_TYPE_HAVENT_STARTED_PARTICULAR_LESSON = 8; - private static final int COURSE_TYPE_HAVENT_STARTED_ANY_LESSONS = 9; - private static final int COURSE_TYPE_HAVE_FINISHED_THESE_LESSONS = 10; - private static final String TRIGGER_PREFIX_NAME = "emailMessageOnScheduleTrigger:"; - - private static ILessonService lessonService; - private static IGroupUserDAO groupUserDAO; - private static ILearnerProgressDAO learnerProgressDAO; private static IEventNotificationService eventNotificationService; + private static IUserManagementService userManagementService; // --------------------------------------------------------------------- // Struts Dispatch Method @@ -177,30 +158,47 @@ */ public ActionForward showScheduledEmails(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException, SchedulerException { + getUserManagementService(); Scheduler scheduler = getScheduler(); TreeSet scheduleList = new TreeSet(); + Long lessonId = WebUtil.readLongParam(request, AttributeNames.PARAM_LESSON_ID, true); + boolean isLessonNotifications = (lessonId != null); + Integer organisationId = WebUtil.readIntParam(request, AttributeNames.PARAM_ORGANISATION_ID, true); String[] triggerNames = scheduler.getTriggerNames(Scheduler.DEFAULT_GROUP); for (String triggerName : triggerNames) { if (triggerName.startsWith(TRIGGER_PREFIX_NAME)) { Trigger trigger = scheduler.getTrigger(triggerName, Scheduler.DEFAULT_GROUP); JobDetail jobDetail = scheduler.getJobDetail(trigger.getJobName(), Scheduler.DEFAULT_GROUP); JobDataMap jobDataMap = jobDetail.getJobDataMap(); - Date triggerDate = trigger.getNextFireTime(); - String emailBody = (String) jobDataMap.get("emailBody"); - String[] userIdStrs = (String[]) jobDataMap.get(MonitoringConstants.KEY_USER_ID); + //filter triggers + if (isLessonNotifications) { + Object jobLessonId = jobDataMap.get(AttributeNames.PARAM_LESSON_ID); + if ((jobLessonId == null) || (! lessonId.equals(jobLessonId))) { + continue; + } + } else { + Object jobOrganisationId = jobDataMap.get(AttributeNames.PARAM_ORGANISATION_ID); + if ((jobOrganisationId == null) || (! organisationId.equals(jobOrganisationId))) { + continue; + } + } + + Date triggerDate = trigger.getNextFireTime(); + String emailBody = WebUtil.convertNewlines((String) jobDataMap.get("emailBody")); + int searchType = (Integer) jobDataMap.get("searchType"); EmailScheduleMessageJobDTO emailScheduleJobDTO = new EmailScheduleMessageJobDTO(); emailScheduleJobDTO.setTriggerDate(triggerDate); emailScheduleJobDTO.setEmailBody(emailBody); - emailScheduleJobDTO.setUserIdStrs(userIdStrs); + emailScheduleJobDTO.setSearchType(searchType); scheduleList.add(emailScheduleJobDTO); } } request.setAttribute("scheduleList", scheduleList); - request.setAttribute(AttributeNames.PARAM_LESSON_ID, request.getParameter(AttributeNames.PARAM_LESSON_ID)); - request.setAttribute(AttributeNames.PARAM_ORGANISATION_ID, request.getParameter(AttributeNames.PARAM_ORGANISATION_ID)); + request.setAttribute(AttributeNames.PARAM_LESSON_ID, lessonId); + request.setAttribute(AttributeNames.PARAM_ORGANISATION_ID, organisationId); return mapping.findForward("scheduledEmailList"); } @@ -215,34 +213,14 @@ IMonitoringService monitoringService = MonitoringServiceProxy.getMonitoringService(getServlet() .getServletContext()); getEventNotificationService(); - String[] userIdStrs = request.getParameterValues("userId"); + String emailBody = WebUtil.readStrParam(request, "emailBody"); Long scheduleDateParameter = WebUtil.readLongParam(request, "scheduleDate", true); - boolean isScheduledForToday = false; - Calendar now = Calendar.getInstance(); - - //calculate scheduleDate - Date scheduleDate = null; - if (scheduleDateParameter != null) { - Date scheduleDateTeacherTimezone = new Date(scheduleDateParameter); - HttpSession ss = SessionManager.getSession(); - UserDTO teacher = (UserDTO) ss.getAttribute(AttributeNames.USER); - TimeZone teacherTimeZone = teacher.getTimeZone(); - scheduleDate = DateUtil.convertFromTimeZoneToDefault(teacherTimeZone, scheduleDateTeacherTimezone); - - // check whether email sending is scheduled for today - - Calendar scheduleDateCalendar = Calendar.getInstance(); - scheduleDateCalendar.setTime(scheduleDate); - isScheduledForToday = (now.get(Calendar.DATE) == scheduleDateCalendar.get(Calendar.DATE) - && now.get(Calendar.MONTH) == scheduleDateCalendar.get(Calendar.MONTH) - && now.get(Calendar.YEAR) == scheduleDateCalendar.get(Calendar.YEAR)); - } - //check if we send email instantly - if ((scheduleDate == null) || isScheduledForToday) { + if (scheduleDateParameter == null) { boolean isSuccessfullySent = true; + String[] userIdStrs = request.getParameterValues("userId"); for (String userIdStr : userIdStrs) { long userId = Long.parseLong(userIdStr); isSuccessfullySent &= eventNotificationService.sendMessage( @@ -254,15 +232,22 @@ JSONObject.put("isSuccessfullySent", isSuccessfullySent); } else { - // schedule email to be sent try { + Calendar now = Calendar.getInstance(); + + // calculate scheduleDate + Date scheduleDateTeacherTimezone = new Date(scheduleDateParameter); + HttpSession ss = SessionManager.getSession(); + UserDTO teacher = (UserDTO) ss.getAttribute(AttributeNames.USER); + TimeZone teacherTimeZone = teacher.getTimeZone(); + Date scheduleDate = DateUtil.convertFromTimeZoneToDefault(teacherTimeZone, scheduleDateTeacherTimezone); + JobDetail emailScheduleMessageJob = getEmailScheduleMessageJob(); - // setup the message for scheduling job emailScheduleMessageJob.setName("emailScheduleMessageJob:" + now.getTimeInMillis()); - emailScheduleMessageJob.setDescription("schedule email message to user(s)"); emailScheduleMessageJob.getJobDataMap().put("emailBody", emailBody); - emailScheduleMessageJob.getJobDataMap().put(MonitoringConstants.KEY_USER_ID, userIdStrs); + + copySearchParametersFromRequestToMap(request, emailScheduleMessageJob.getJobDataMap()); // create customized triggers Trigger startLessonTrigger = new SimpleTrigger(TRIGGER_PREFIX_NAME + now.getTimeInMillis(), @@ -271,7 +256,7 @@ Scheduler scheduler = getScheduler(); scheduler.scheduleJob(emailScheduleMessageJob, startLessonTrigger); JSONObject.put("isSuccessfullyScheduled", true); - log.debug("Email message to users [" + userIdStrs + "] on schedule is configured"); + log.debug("Emails have been successfully scheduled to be sent on " + scheduleDate + " [search type is " + request.getParameter("searchType") + "]"); } catch (SchedulerException e) { log.error("Error occurred at " + "[emailScheduleMessage]- fail to email scheduling", e); } @@ -287,70 +272,31 @@ */ public ActionForward getUsers(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException, JSONException { + IMonitoringService monitoringService = MonitoringServiceProxy.getMonitoringService(getServlet() + .getServletContext()); ICoreLearnerService learnerService = MonitoringServiceProxy.getLearnerService(getServlet() .getServletContext()); - JSONObject responcedata = new JSONObject(); - int searchType = WebUtil.readIntParam(request, "searchType"); - Lesson lesson = null; - Integer orgId; - Long activityId = null; - int xDaystoFinish = 0; - String[] lessonIds = null; - Organisation org = null; - //TODO check checkOwnerOrStaffMember - //validate request - switch (searchType) { - case LESSON_TYPE_ASSIGNED_TO_LESSON: - case LESSON_TYPE_HAVENT_FINISHED_LESSON: - case LESSON_TYPE_HAVE_FINISHED_LESSON: - case LESSON_TYPE_HAVENT_STARTED_LESSON: - case LESSON_TYPE_HAVE_STARTED_LESSON: - case LESSON_TYPE_HAVENT_REACHED_PARTICULAR_ACTIVITY: - case LESSON_TYPE_LESS_THAN_X_DAYS_TO_DEADLINE: - Long lessonId = WebUtil.readLongParam(request, "lessonId"); - lesson = learnerService.getLesson(lessonId); - break; - - case COURSE_TYPE_HAVENT_STARTED_ANY_LESSONS: - case COURSE_TYPE_HAVE_FINISHED_THESE_LESSONS: - case COURSE_TYPE_HAVE_FINISHED_PARTICULAR_LESSON: - case COURSE_TYPE_HAVENT_STARTED_PARTICULAR_LESSON: - orgId = WebUtil.readIntParam(request, "orgId"); - org = (Organisation) learnerService.getUserManagementService().findById(Organisation.class, orgId); - break; - } + Map map = new HashMap(); + copySearchParametersFromRequestToMap(request, map); - switch (searchType) { - case LESSON_TYPE_HAVENT_REACHED_PARTICULAR_ACTIVITY: - activityId = WebUtil.readLongParam(request, "activityId"); - break; - case LESSON_TYPE_LESS_THAN_X_DAYS_TO_DEADLINE: - xDaystoFinish = WebUtil.readIntParam(request, "daysToDeadline"); - break; - - case COURSE_TYPE_HAVE_FINISHED_PARTICULAR_LESSON: - case COURSE_TYPE_HAVENT_STARTED_PARTICULAR_LESSON: - Long lessonId = WebUtil.readLongParam(request, "lessonId"); - lesson = learnerService.getLesson(lessonId); - break; - case COURSE_TYPE_HAVE_FINISHED_THESE_LESSONS: - lessonIds = request.getParameterValues("lessonId"); - break; - } + int searchType = (Integer) map.get("searchType"); + Long lessonId = (Long) map.get(AttributeNames.PARAM_LESSON_ID); + Integer orgId = (Integer) map.get(AttributeNames.PARAM_ORGANISATION_ID); + Long activityId = (Long) map.get(AttributeNames.PARAM_ACTIVITY_ID); + Integer xDaystoFinish = (Integer) map.get("daysToDeadline"); + String[] lessonIds = (String[]) map.get("lessonIDs"); + Collection users = monitoringService.getUsersByEmailNotificationSearchType(searchType, lessonId, lessonIds, activityId, xDaystoFinish, orgId); - Collection users = getUsers(searchType, lesson, lessonIds, activityId, xDaystoFinish, org); - - JSONArray cellarray = new JSONArray(); + JSONObject responcedata = new JSONObject(); responcedata.put("total", "" + users.size()); responcedata.put("page", "" + 1); responcedata.put("records", "" + users.size()); - for (User user : users) { JSONArray cell=new JSONArray(); cell.put(user.getFirstName() + " " + user.getLastName() + " [" + user.getLogin() + "]"); @@ -366,155 +312,86 @@ return null; } - private Collection getUsers(int searchType, Lesson lesson, String[] lessonIds, Long activityId, int xDaystoFinish, Organisation org) { - getLessonService(); - ICoreLearnerService learnerService = MonitoringServiceProxy.getLearnerService(getServlet() - .getServletContext()); + /** + * Copies search parameters from request to specified map. Validates parameters along the way. + * + * @param request + * @param map specified map + */ + private void copySearchParametersFromRequestToMap(HttpServletRequest request, Map map) { + int searchType = WebUtil.readIntParam(request, "searchType"); + Assert.notNull(searchType); + map.put("searchType", searchType); - Long lessonId = null; - if (lesson != null) { - lessonId = lesson.getLessonId(); - } - - Collection users = new LinkedList(); switch (searchType) { - case LESSON_TYPE_ASSIGNED_TO_LESSON: - users = lesson.getAllLearners(); + case MonitoringConstants.LESSON_TYPE_ASSIGNED_TO_LESSON: + case MonitoringConstants.LESSON_TYPE_HAVENT_FINISHED_LESSON: + case MonitoringConstants.LESSON_TYPE_HAVE_FINISHED_LESSON: + case MonitoringConstants.LESSON_TYPE_HAVENT_STARTED_LESSON: + case MonitoringConstants.LESSON_TYPE_HAVE_STARTED_LESSON: + case MonitoringConstants.LESSON_TYPE_HAVENT_REACHED_PARTICULAR_ACTIVITY: + case MonitoringConstants.LESSON_TYPE_LESS_THAN_X_DAYS_TO_DEADLINE: + Long lessonId = (Long) WebUtil.readLongParam(request, AttributeNames.PARAM_LESSON_ID); + Assert.notNull(lessonId); + map.put(AttributeNames.PARAM_LESSON_ID, lessonId); break; - - case LESSON_TYPE_HAVENT_FINISHED_LESSON: - Set allUsers = lesson.getAllLearners(); - List usersCompletedLesson = getUsersCompletedLesson(lessonId); - users = CollectionUtils.subtract(allUsers, usersCompletedLesson); + + case MonitoringConstants.COURSE_TYPE_HAVENT_STARTED_ANY_LESSONS: + case MonitoringConstants.COURSE_TYPE_HAVE_FINISHED_THESE_LESSONS: + case MonitoringConstants.COURSE_TYPE_HAVE_FINISHED_PARTICULAR_LESSON: + case MonitoringConstants.COURSE_TYPE_HAVENT_STARTED_PARTICULAR_LESSON: + Integer organisationId = WebUtil.readIntParam(request, AttributeNames.PARAM_ORGANISATION_ID); + Assert.notNull(organisationId); + map.put(AttributeNames.PARAM_ORGANISATION_ID, organisationId); break; + } - case LESSON_TYPE_HAVE_FINISHED_LESSON: - case COURSE_TYPE_HAVE_FINISHED_PARTICULAR_LESSON: - users = getUsersCompletedLesson(lessonId); + switch (searchType) { + case MonitoringConstants.LESSON_TYPE_HAVENT_REACHED_PARTICULAR_ACTIVITY: + Long activityId = WebUtil.readLongParam(request, AttributeNames.PARAM_ACTIVITY_ID); + Assert.notNull(activityId); + map.put(AttributeNames.PARAM_ACTIVITY_ID, activityId); break; - case LESSON_TYPE_HAVENT_STARTED_LESSON: - case COURSE_TYPE_HAVENT_STARTED_PARTICULAR_LESSON: - allUsers = lesson.getAllLearners(); - List usersStartedLesson = lessonService.getActiveLessonLearners(lessonId); - users = CollectionUtils.subtract(allUsers, usersStartedLesson); + case MonitoringConstants.LESSON_TYPE_LESS_THAN_X_DAYS_TO_DEADLINE: + Integer xDaystoFinish = WebUtil.readIntParam(request, "daysToDeadline"); + Assert.notNull(xDaystoFinish); + map.put("daysToDeadline", xDaystoFinish); break; - - case LESSON_TYPE_HAVE_STARTED_LESSON: - users = lessonService.getActiveLessonLearners(lessonId); - break; - case LESSON_TYPE_HAVENT_REACHED_PARTICULAR_ACTIVITY: - Activity activity = learnerService.getActivity(activityId); - allUsers = lesson.getAllLearners(); - List usersAttemptedActivity = lessonService.getLearnersHaveAttemptedActivity(activity); - users = CollectionUtils.subtract(allUsers, usersAttemptedActivity); + case MonitoringConstants.COURSE_TYPE_HAVE_FINISHED_PARTICULAR_LESSON: + case MonitoringConstants.COURSE_TYPE_HAVENT_STARTED_PARTICULAR_LESSON: + Long lessonId = (Long) WebUtil.readLongParam(request, AttributeNames.PARAM_LESSON_ID); + Assert.notNull(lessonId); + map.put(AttributeNames.PARAM_LESSON_ID, lessonId); break; - - case LESSON_TYPE_LESS_THAN_X_DAYS_TO_DEADLINE: - Date now = new Date(); - Calendar currentTimePlusXDays = Calendar.getInstance(); - currentTimePlusXDays.setTime(now); - currentTimePlusXDays.add(Calendar.DATE, xDaystoFinish); - - Date scheduleEndDate = lesson.getScheduleEndDate(); - if (scheduleEndDate != null) { - if (now.before(scheduleEndDate) && currentTimePlusXDays.getTime().after(scheduleEndDate)) { - users = lesson.getAllLearners(); - } - - } else if (lesson.isScheduledToCloseForIndividuals()) { - users = getGroupUserDAO().getUsersWithLessonEndingSoonerThan(lesson, currentTimePlusXDays.getTime()); - } + case MonitoringConstants.COURSE_TYPE_HAVE_FINISHED_THESE_LESSONS: + String[] lessonIds = request.getParameterValues(AttributeNames.PARAM_LESSON_ID); + Assert.notNull(lessonIds); + map.put("lessonIDs", lessonIds); break; + } - case COURSE_TYPE_HAVENT_STARTED_ANY_LESSONS: - getLearnerProgressDAO(); - - List allUSers = learnerService.getUserManagementService().getUsersFromOrganisation(org.getOrganisationId()); - Set usersStartedAtLest1Lesson = new TreeSet(); - - Set lessons = org.getLessons(); - for (Lesson les : lessons) { - Activity firstActivity = les.getLearningDesign().getFirstActivity(); - List usersStartedFirstActivity = learnerProgressDAO.getLearnersHaveAttemptedActivity(firstActivity); - usersStartedAtLest1Lesson.addAll(usersStartedFirstActivity); - } - - users = CollectionUtils.subtract(allUSers, usersStartedAtLest1Lesson); - - break; - - case COURSE_TYPE_HAVE_FINISHED_THESE_LESSONS: - int i = 0; - for (String lessonIdStr : lessonIds) { - lessonId = Long.parseLong(lessonIdStr); - List completedLesson = getUsersCompletedLesson(lessonId); - if (i++ == 0) { - users = completedLesson; - } else { - users = CollectionUtils.intersection(users, completedLesson); - } - } - break; - } - - Set sortedUsers = new TreeSet(new Comparator() { - public int compare(User usr0, User usr1) { - return ((usr0.getFirstName() + usr0.getLastName() + usr0.getLogin()).compareTo(usr1.getFirstName() + usr1.getLastName() + usr1.getLogin())); - } - }); - sortedUsers.addAll(users); - - return sortedUsers; } - private List getUsersCompletedLesson(Long lessonId) { - List usersCompletedLesson = new LinkedList(); - - List completedLearnerProgresses = getLearnerProgressDAO().getCompletedLearnerProgressForLesson(lessonId); - for (LearnerProgress learnerProgress : completedLearnerProgresses) { - usersCompletedLesson.add(learnerProgress.getUser()); - } - return usersCompletedLesson; - } - - private ILessonService getLessonService() { - if (lessonService == null) { + private IEventNotificationService getEventNotificationService() { + if (eventNotificationService == null) { WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(getServlet() .getServletContext()); - lessonService = (ILessonService) ctx.getBean("lessonService"); + eventNotificationService = (IEventNotificationService) ctx.getBean("eventNotificationService"); } - return lessonService; + return eventNotificationService; } - private IGroupUserDAO getGroupUserDAO() { - if (groupUserDAO == null) { + private IUserManagementService getUserManagementService() { + if (userManagementService == null) { WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(getServlet() .getServletContext()); - groupUserDAO = (IGroupUserDAO) ctx.getBean("groupUserDAO"); + userManagementService = (IUserManagementService) ctx.getBean("userManagementService"); } - return groupUserDAO; + return userManagementService; } - private ILearnerProgressDAO getLearnerProgressDAO() { - if (learnerProgressDAO == null) { - WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(getServlet() - .getServletContext()); - learnerProgressDAO = (ILearnerProgressDAO) ctx.getBean("learnerProgressDAO"); - } - return learnerProgressDAO; - } - - private IEventNotificationService getEventNotificationService() { - if (eventNotificationService == null) { - WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(getServlet() - .getServletContext()); - eventNotificationService = (IEventNotificationService) ctx.getBean("eventNotificationService"); - } - return eventNotificationService; - } - /** * * @return the bean that defines emailScheduleMessageJob. Fisheye: Tag 1.1 refers to a dead (removed) revision in file `lams_monitoring/web/emailnotifications/additionalSettings.jsp'. Fisheye: No comparison available. Pass `N' to diff? Index: lams_monitoring/web/emailnotifications/courseNotifications.jsp =================================================================== RCS file: /usr/local/cvsroot/lams_monitoring/web/emailnotifications/courseNotifications.jsp,v diff -u -r1.1.2.5 -r1.1.2.6 --- lams_monitoring/web/emailnotifications/courseNotifications.jsp 14 Oct 2011 17:55:11 -0000 1.1.2.5 +++ lams_monitoring/web/emailnotifications/courseNotifications.jsp 20 Oct 2011 16:55:16 -0000 1.1.2.6 @@ -17,15 +17,27 @@ @@ -37,9 +49,10 @@ @@ -183,19 +225,13 @@
?method=emailUsers" method="post" id="emailNotificationsForm" >
- - - -

- <%@ include file="scheduleOptions.jsp"%> - ${lesson.lessonName} home.do?method=learner&lessonID=${lesson.lessonId} - +

" /> @@ -229,17 +265,14 @@
- " onclick="getUsers();" /> +
+ " onclick="getUsers();" />
-
-
+ <%@ include file="additionalSettings.jsp"%>
-
-
- Index: lams_monitoring/web/emailnotifications/lessonNotifications.jsp =================================================================== RCS file: /usr/local/cvsroot/lams_monitoring/web/emailnotifications/lessonNotifications.jsp,v diff -u -r1.1.2.4 -r1.1.2.5 --- lams_monitoring/web/emailnotifications/lessonNotifications.jsp 14 Oct 2011 17:55:11 -0000 1.1.2.4 +++ lams_monitoring/web/emailnotifications/lessonNotifications.jsp 20 Oct 2011 16:55:16 -0000 1.1.2.5 @@ -18,15 +18,26 @@ @@ -39,8 +50,9 @@
@@ -204,17 +240,9 @@
-
-
- - + <%@ include file="additionalSettings.jsp"%> -
- - - - - + Fisheye: Tag 1.1.2.2 refers to a dead (removed) revision in file `lams_monitoring/web/emailnotifications/scheduleOptions.jsp'. Fisheye: No comparison available. Pass `N' to diff? Index: lams_monitoring/web/emailnotifications/scheduledEmailList.jsp =================================================================== RCS file: /usr/local/cvsroot/lams_monitoring/web/emailnotifications/scheduledEmailList.jsp,v diff -u -r1.1.2.1 -r1.1.2.2 --- lams_monitoring/web/emailnotifications/scheduledEmailList.jsp 14 Oct 2011 17:55:11 -0000 1.1.2.1 +++ lams_monitoring/web/emailnotifications/scheduledEmailList.jsp 20 Oct 2011 16:55:16 -0000 1.1.2.2 @@ -26,7 +26,7 @@ -

+

@@ -36,27 +36,36 @@ - - + + Notify students that - + - + - - - + + + + + + + + + + + + + + - - - ${userIdStr}, - + + ${emailJob.emailBody} @@ -70,7 +79,7 @@ ?method=getCourseView&organisationID=${organisationID} - +