Index: lams_central/src/java/org/lamsfoundation/lams/gradebook/service/GradeBookService.java =================================================================== diff -u -rc6305f2e45a7888fb8ea3522d3f2324addd5dd36 -rfc2b6751efa103ff475378442632b752c01c2736 --- lams_central/src/java/org/lamsfoundation/lams/gradebook/service/GradeBookService.java (.../GradeBookService.java) (revision c6305f2e45a7888fb8ea3522d3f2324addd5dd36) +++ lams_central/src/java/org/lamsfoundation/lams/gradebook/service/GradeBookService.java (.../GradeBookService.java) (revision fc2b6751efa103ff475378442632b752c01c2736) @@ -23,10 +23,12 @@ /* $Id$ */ package org.lamsfoundation.lams.gradebook.service; +import java.text.DateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Set; import java.util.SortedMap; import java.util.SortedSet; @@ -113,32 +115,34 @@ long firstActivityTime = 0; if (learnerProgress != null) { if (learnerProgress.getCompletedActivities().get(firstActivity) != null) { - firstActivityTime = ((Date) learnerProgress.getCompletedActivities().get(firstActivity)) - .getTime()- startTime - accumulatedTime; + firstActivityTime = ((Date) learnerProgress.getCompletedActivities().get(firstActivity)).getTime() + - startTime - accumulatedTime; accumulatedTime += firstActivityTime; } } - GBActivityGridRowDTO activityDTO = getGradeBookActivityDTO(firstActivity, learner, learnerProgress, firstActivityTime); + GBActivityGridRowDTO activityDTO = getGradeBookActivityDTO(firstActivity, learner, learnerProgress, + firstActivityTime); gradeBookActivityDTOs.add(activityDTO); } SortedSet sortedActivities = new TreeSet(activities); - + for (Activity activity : sortedActivities) { if (activity.getActivityId().longValue() != firstActivity.getActivityId().longValue()) { - + long activityTime = 0; if (learnerProgress != null) { if (learnerProgress.getCompletedActivities().get(activity) != null) { - activityTime = ((Date) learnerProgress.getCompletedActivities().get(activity)) - .getTime() - startTime - accumulatedTime; - accumulatedTime += activityTime; - } - + activityTime = ((Date) learnerProgress.getCompletedActivities().get(activity)).getTime() + - startTime - accumulatedTime; + accumulatedTime += activityTime; + } + } - GBActivityGridRowDTO activityDTO = getGradeBookActivityDTO(activity, learner, learnerProgress, activityTime); + GBActivityGridRowDTO activityDTO = getGradeBookActivityDTO(activity, learner, learnerProgress, + activityTime); gradeBookActivityDTOs.add(activityDTO); } } @@ -260,10 +264,16 @@ gradeBookUserDTO.setFirstName(learner.getFirstName()); gradeBookUserDTO.setLastName(learner.getLastName()); - // Setting the status for the user's lesson + // Setting the status and time taken for the user's lesson LearnerProgress learnerProgress = monitoringService.getLearnerProgress(learner.getUserId(), lesson .getLessonId()); gradeBookUserDTO.setStatus(getLessonStatusStr(learnerProgress)); + if (learnerProgress != null) { + if (learnerProgress.getStartDate() != null && learnerProgress.getFinishDate() != null) { + gradeBookUserDTO.setTimeTaken(learnerProgress.getFinishDate().getTime() + - learnerProgress.getStartDate().getTime()); + } + } GradeBookUserLesson gradeBookUserLesson = gradeBookDAO.getGradeBookUserDataForLesson(lesson .getLessonId(), learner.getUserId()); @@ -382,6 +392,9 @@ GBLessonGridRowDTO lessonRow = new GBLessonGridRowDTO(); lessonRow.setLessonName(lesson.getLessonName()); lessonRow.setLessonId(lesson.getLessonId()); + lessonRow.setStartDate(getLocaleDateString(user, lesson.getStartDateTime())); + lessonRow.setAverageTime(gradeBookDAO.getAverageDurationLesson(lesson.getLessonId())); + lessonRow.setLessonDescription(lesson.getLessonDescription()); lessonRow.setMark(gradeBookDAO.getAverageMarkForLesson(lesson.getLessonId())); @@ -408,6 +421,12 @@ return lessonRows; } + private String getLocaleDateString(User user, Date date) { + Locale locale = new Locale(user.getLocale().getLanguageIsoCode(), user.getLocale().getCountryIsoCode()); + String dateStr = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM, locale).format(date); + return dateStr; + } + /** * Adds a mark to the aggregated total and saves it * @@ -497,7 +516,7 @@ GBActivityGridRowDTO gactivityDTO = new GBActivityGridRowDTO(); gactivityDTO.setActivityId(activity.getActivityId()); gactivityDTO.setActivityTitle(activity.getTitle()); - gactivityDTO.setTimeTakenInMillis(activityTime); + gactivityDTO.setTimeTaken(activityTime); GradeBookUserActivity gradeBookActivity = gradeBookDAO.getGradeBookUserDataForActivity( activity.getActivityId(), learner.getUserId()); @@ -675,5 +694,6 @@ public void setLessonService(ILessonService lessonService) { this.lessonService = lessonService; } + // ------------------------------------------------------------------------- } Index: lams_central/src/java/org/lamsfoundation/lams/gradebook/web/action/GradeBookAction.java =================================================================== diff -u -rc6305f2e45a7888fb8ea3522d3f2324addd5dd36 -rfc2b6751efa103ff475378442632b752c01c2736 --- lams_central/src/java/org/lamsfoundation/lams/gradebook/web/action/GradeBookAction.java (.../GradeBookAction.java) (revision c6305f2e45a7888fb8ea3522d3f2324addd5dd36) +++ lams_central/src/java/org/lamsfoundation/lams/gradebook/web/action/GradeBookAction.java (.../GradeBookAction.java) (revision fc2b6751efa103ff475378442632b752c01c2736) @@ -40,6 +40,7 @@ import org.lamsfoundation.lams.gradebook.dto.GBLessonGridRowDTO; import org.lamsfoundation.lams.gradebook.dto.GBUserGridRowDTO; import org.lamsfoundation.lams.gradebook.dto.GradeBookGridRowDTO; +import org.lamsfoundation.lams.gradebook.dto.comparators.GBLessonIDComparator; import org.lamsfoundation.lams.gradebook.dto.comparators.GBLessonMarkComparator; import org.lamsfoundation.lams.gradebook.dto.comparators.GBLessonNameComparator; import org.lamsfoundation.lams.gradebook.dto.comparators.GBUserFullNameComparator; @@ -339,10 +340,10 @@ } else if (sortBy.equals("mark")) { Collections.sort(gradeBookLessonDTOs, new GBLessonMarkComparator()); } else { - Collections.sort(gradeBookLessonDTOs, new GBLessonNameComparator()); + Collections.sort(gradeBookLessonDTOs, new GBLessonIDComparator()); } } else { - Collections.sort(gradeBookLessonDTOs, new GBLessonNameComparator()); + Collections.sort(gradeBookLessonDTOs, new GBLessonIDComparator()); } // Reverse the order if requested Index: lams_common/src/java/org/lamsfoundation/lams/gradebook/dao/IGradeBookDAO.java =================================================================== diff -u -r662af4c9490c6c67127cda6c29d7d806a9e9eaca -rfc2b6751efa103ff475378442632b752c01c2736 --- lams_common/src/java/org/lamsfoundation/lams/gradebook/dao/IGradeBookDAO.java (.../IGradeBookDAO.java) (revision 662af4c9490c6c67127cda6c29d7d806a9e9eaca) +++ lams_common/src/java/org/lamsfoundation/lams/gradebook/dao/IGradeBookDAO.java (.../IGradeBookDAO.java) (revision fc2b6751efa103ff475378442632b752c01c2736) @@ -40,6 +40,8 @@ public List getAllGradeBookUserActivitiesForActivity(Long activityID); public Double getAverageMarkForLesson(Long lessonID); + + public long getAverageDurationLesson(Long lessonID); } \ No newline at end of file Index: lams_common/src/java/org/lamsfoundation/lams/gradebook/dao/hibernate/GradeBookDAO.java =================================================================== diff -u -r662af4c9490c6c67127cda6c29d7d806a9e9eaca -rfc2b6751efa103ff475378442632b752c01c2736 --- lams_common/src/java/org/lamsfoundation/lams/gradebook/dao/hibernate/GradeBookDAO.java (.../GradeBookDAO.java) (revision 662af4c9490c6c67127cda6c29d7d806a9e9eaca) +++ lams_common/src/java/org/lamsfoundation/lams/gradebook/dao/hibernate/GradeBookDAO.java (.../GradeBookDAO.java) (revision fc2b6751efa103ff475378442632b752c01c2736) @@ -23,6 +23,7 @@ /* $Id$ */ package org.lamsfoundation.lams.gradebook.dao.hibernate; +import java.util.Date; import java.util.List; import org.lamsfoundation.lams.dao.hibernate.BaseDAO; @@ -47,6 +48,9 @@ private static final String GET_AVERAGE_MARK_FOR_LESSON = "select avg(gles.mark) from GradeBookUserLesson gles where " + "gles.lesson.lessonId=:lessonID"; + private static final String GET_AVERAGE_COMPLETION_TIME = "select prog.finishDate, prog.startDate as x from LearnerProgress prog where " + + "prog.lesson.lessonId=:lessonID"; + @SuppressWarnings("unchecked") public GradeBookUserActivity getGradeBookUserDataForActivity(Long activityID, Integer userID) { List result = getSession().createQuery(GET_GRADEBOOK_USER_ACTIVITY).setInteger("userID", userID.intValue()) @@ -55,8 +59,8 @@ if (result != null) { if (result.size() > 0) return (GradeBookUserActivity) result.get(0); - } - + } + return null; } @@ -68,10 +72,10 @@ if (result != null) { if (result.size() > 0) return (GradeBookUserLesson) result.get(0); - } - + } + return null; - + } @SuppressWarnings("unchecked") @@ -82,10 +86,9 @@ if (result != null) { if (result.size() > 0) return (Double) result.get(0); - } - + } + return 0.0; - } @@ -106,7 +109,39 @@ if (result.size() > 0) return (Double) result.get(0); } - + return 0.0; } + + @SuppressWarnings("unchecked") + public long getAverageDurationLesson(Long lessonID) { + List result = (List) getSession().createQuery(GET_AVERAGE_COMPLETION_TIME).setLong( + "lessonID", lessonID.longValue()).list(); + + if (result != null) { + if (result.size() > 0) { + + long sum = 0; + long count = 0; + for (Object[] dateObjs : result) { + if (dateObjs != null && dateObjs.length == 2) { + Date finishDate = (Date) dateObjs[0]; + Date startDate = (Date) dateObjs[1]; + + if (startDate != null && finishDate != null) { + + sum += finishDate.getTime() - startDate.getTime(); + count++; + } + } + } + + if (count > 0) { + return sum / count; + } + } + + } + return 0; + } } Index: lams_common/src/java/org/lamsfoundation/lams/gradebook/dto/GBActivityGridRowDTO.java =================================================================== diff -u -r8e0af661d84b765d167c4b982f2f1f7d3c34e78f -rfc2b6751efa103ff475378442632b752c01c2736 --- lams_common/src/java/org/lamsfoundation/lams/gradebook/dto/GBActivityGridRowDTO.java (.../GBActivityGridRowDTO.java) (revision 8e0af661d84b765d167c4b982f2f1f7d3c34e78f) +++ lams_common/src/java/org/lamsfoundation/lams/gradebook/dto/GBActivityGridRowDTO.java (.../GBActivityGridRowDTO.java) (revision fc2b6751efa103ff475378442632b752c01c2736) @@ -42,7 +42,7 @@ //double timeTaken; Double mark; String feedback; - String timeTaken = "-"; + Long timeTaken; // Properties for activity view Double average; @@ -67,7 +67,11 @@ ret.add(output); ret.add(competences); - ret.add(timeTaken); + if (timeTaken != null) { + ret.add(convertTimeToString(timeTaken)); + } else { + ret.add("-"); + } ret.add(feedback); @@ -93,7 +97,6 @@ ret.add("-"); } } - return ret; } @@ -186,33 +189,11 @@ this.monitorUrl = monitorUrl; } - - - public void setTimeTakenInMillis(long timeTakenInMillis) { - if (timeTakenInMillis > 1000) { - long totalTimeInSeconds = timeTakenInMillis / 1000; - - long seconds = (totalTimeInSeconds >= 60 ? totalTimeInSeconds % 60 : totalTimeInSeconds); - long minutes = (totalTimeInSeconds = (totalTimeInSeconds / 60)) >= 60 ? totalTimeInSeconds % 60 : totalTimeInSeconds; - long hours = (totalTimeInSeconds = (totalTimeInSeconds / 60)) >= 24 ? totalTimeInSeconds % 24 : totalTimeInSeconds; - long days = (totalTimeInSeconds = (totalTimeInSeconds / 24)); - - StringBuilder sb = new StringBuilder(); - - if (days != 0 ) { sb.append("" + days + "d, "); } - if (hours != 0 ) { sb.append("" + hours + "h, "); } - if (minutes != 0 ) { sb.append("" + minutes + "m, "); } - if (seconds != 0 ) { sb.append("" + seconds + "s"); } - - this.timeTaken = sb.toString(); - } - } - - public String getTimeTaken() { + public Long getTimeTaken() { return timeTaken; } - public void setTimeTaken(String timeTaken) { + public void setTimeTaken(Long timeTaken) { this.timeTaken = timeTaken; } Index: lams_common/src/java/org/lamsfoundation/lams/gradebook/dto/GBLessonGridRowDTO.java =================================================================== diff -u -r8e0af661d84b765d167c4b982f2f1f7d3c34e78f -rfc2b6751efa103ff475378442632b752c01c2736 --- lams_common/src/java/org/lamsfoundation/lams/gradebook/dto/GBLessonGridRowDTO.java (.../GBLessonGridRowDTO.java) (revision 8e0af661d84b765d167c4b982f2f1f7d3c34e78f) +++ lams_common/src/java/org/lamsfoundation/lams/gradebook/dto/GBLessonGridRowDTO.java (.../GBLessonGridRowDTO.java) (revision fc2b6751efa103ff475378442632b752c01c2736) @@ -35,6 +35,8 @@ String lessonDescription; Double mark; String subGroup; + String startDate; + Long averageTime; // Only for monitor view String gradeBookMonitorURL; @@ -66,6 +68,14 @@ ret.add(lessonName); } ret.add(subGroup); + ret.add(startDate); + + if (averageTime != null) { + ret.add(convertTimeToString(averageTime)); + } else { + ret.add("-"); + } + ret.add(lessonDescription); if (mark != null) { ret.add(mark.toString()); @@ -144,4 +154,22 @@ public void setSubGroup(String subGroup) { this.subGroup = subGroup; } + + public String getStartDate() { + return startDate; + } + + public void setStartDate(String startDate) { + this.startDate = startDate; + } + + public Long getAverageTime() { + return averageTime; + } + + public void setAverageTime(Long averageTime) { + this.averageTime = averageTime; + } + + } Index: lams_common/src/java/org/lamsfoundation/lams/gradebook/dto/GBUserGridRowDTO.java =================================================================== diff -u -r8e0af661d84b765d167c4b982f2f1f7d3c34e78f -rfc2b6751efa103ff475378442632b752c01c2736 --- lams_common/src/java/org/lamsfoundation/lams/gradebook/dto/GBUserGridRowDTO.java (.../GBUserGridRowDTO.java) (revision 8e0af661d84b765d167c4b982f2f1f7d3c34e78f) +++ lams_common/src/java/org/lamsfoundation/lams/gradebook/dto/GBUserGridRowDTO.java (.../GBUserGridRowDTO.java) (revision fc2b6751efa103ff475378442632b752c01c2736) @@ -40,10 +40,15 @@ // For user view, this represents total lesson mark in the grid // For activity view, this represents an activity mark Double mark; + + // For user view and courseMonitor view, this represents the time taken for a lesson + // For activity view this represents time taken for an activity + Long timeTaken; // For activity view String output; String activityUrl; + public GBUserGridRowDTO() { } @@ -58,6 +63,11 @@ if (view.equals(VIEW_USER)) { ret.add(fullName); ret.add(status); + if (timeTaken != null) { + ret.add(convertTimeToString(timeTaken)); + } else { + ret.add("-"); + } ret.add(feedback); } else if (view.equals(VIEW_ACTIVITY)) { if (activityUrl != null && activityUrl.length() != 0) { @@ -73,8 +83,12 @@ } else if (view.equals(VIEW_COURSE_MONITOR)){ ret.add(fullName); ret.add(status); + if (timeTaken != null) { + ret.add(convertTimeToString(timeTaken)); + } else { + ret.add("-"); + } ret.add(feedback); - } if (mark != null) { @@ -154,4 +168,12 @@ public void setActivityUrl(String activityUrl) { this.activityUrl = activityUrl; } + + public Long getTimeTaken() { + return timeTaken; + } + + public void setTimeTaken(Long timeTaken) { + this.timeTaken = timeTaken; + } } Index: lams_common/src/java/org/lamsfoundation/lams/gradebook/dto/GradeBookGridRowDTO.java =================================================================== diff -u -r662af4c9490c6c67127cda6c29d7d806a9e9eaca -rfc2b6751efa103ff475378442632b752c01c2736 --- lams_common/src/java/org/lamsfoundation/lams/gradebook/dto/GradeBookGridRowDTO.java (.../GradeBookGridRowDTO.java) (revision 662af4c9490c6c67127cda6c29d7d806a9e9eaca) +++ lams_common/src/java/org/lamsfoundation/lams/gradebook/dto/GradeBookGridRowDTO.java (.../GradeBookGridRowDTO.java) (revision fc2b6751efa103ff475378442632b752c01c2736) @@ -30,5 +30,34 @@ public abstract ArrayList toStringArray(String view); public abstract String getRowId(); + + /** + * A shared function to convert milliseconds into a readable string + * + * @param timeInMillis + * @return + */ + protected String convertTimeToString(Long timeInMillis) { + StringBuilder sb = new StringBuilder(); + if (timeInMillis != null && timeInMillis > 1000) { + long totalTimeInSeconds = timeInMillis / 1000; + + long seconds = (totalTimeInSeconds >= 60 ? totalTimeInSeconds % 60 : totalTimeInSeconds); + long minutes = (totalTimeInSeconds = (totalTimeInSeconds / 60)) >= 60 ? totalTimeInSeconds % 60 : totalTimeInSeconds; + long hours = (totalTimeInSeconds = (totalTimeInSeconds / 60)) >= 24 ? totalTimeInSeconds % 24 : totalTimeInSeconds; + long days = (totalTimeInSeconds = (totalTimeInSeconds / 24)); + + if (days != 0 ) { sb.append("" + days + "d, "); } + if (hours != 0 ) { sb.append("" + hours + "h, "); } + if (minutes != 0 ) { sb.append("" + minutes + "m, "); } + if (seconds != 0 ) { sb.append("" + seconds + "s"); } + } + + if (sb.length() > 0) { + return sb.toString(); + } else { + return null; + } + } } \ No newline at end of file Index: lams_common/src/java/org/lamsfoundation/lams/gradebook/dto/comparators/GBLessonIDComparator.java =================================================================== diff -u --- lams_common/src/java/org/lamsfoundation/lams/gradebook/dto/comparators/GBLessonIDComparator.java (revision 0) +++ lams_common/src/java/org/lamsfoundation/lams/gradebook/dto/comparators/GBLessonIDComparator.java (revision fc2b6751efa103ff475378442632b752c01c2736) @@ -0,0 +1,49 @@ +/**************************************************************** + * Copyright (C) 2008 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * License Information: http://lamsfoundation.org/licensing/lams/2.0/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2.0 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 * USA + * + * http://www.gnu.org/licenses/gpl.txt + * **************************************************************** + */ + +/* $Id$ */ +package org.lamsfoundation.lams.gradebook.dto.comparators; + +import java.util.Comparator; + +import org.lamsfoundation.lams.gradebook.dto.GBLessonGridRowDTO; + +@SuppressWarnings("unchecked") +public class GBLessonIDComparator implements Comparator{ + public int compare(Object gbLessonRowDTO, Object anotherGbLessonRowDTO) { + + if (gbLessonRowDTO instanceof GBLessonGridRowDTO && anotherGbLessonRowDTO instanceof GBLessonGridRowDTO) { + + Long lessonID1 = ((GBLessonGridRowDTO) gbLessonRowDTO).getLessonId(); + Long lessonID2 = ((GBLessonGridRowDTO) anotherGbLessonRowDTO).getLessonId(); + + if (lessonID1 == null || lessonID2 == null) { + return 0; + } + Long ret = lessonID1 - lessonID2; + return ret.intValue(); + } else { + return 0; + } + } +} + \ No newline at end of file Index: lams_learning/src/java/org/lamsfoundation/lams/learning/progress/ProgressEngine.java =================================================================== diff -u -r08b386301829247edc2cd6fe275a1b04a37ea407 -rfc2b6751efa103ff475378442632b752c01c2736 --- lams_learning/src/java/org/lamsfoundation/lams/learning/progress/ProgressEngine.java (.../ProgressEngine.java) (revision 08b386301829247edc2cd6fe275a1b04a37ea407) +++ lams_learning/src/java/org/lamsfoundation/lams/learning/progress/ProgressEngine.java (.../ProgressEngine.java) (revision fc2b6751efa103ff475378442632b752c01c2736) @@ -24,6 +24,7 @@ /* $$Id$$ */ package org.lamsfoundation.lams.learning.progress; +import java.util.Date; import java.util.Iterator; import java.util.LinkedList; import java.util.List; @@ -33,7 +34,6 @@ import org.lamsfoundation.lams.learningdesign.ComplexActivity; import org.lamsfoundation.lams.learningdesign.LearningDesign; import org.lamsfoundation.lams.learningdesign.ParallelActivity; -import org.lamsfoundation.lams.learningdesign.SequenceActivity; import org.lamsfoundation.lams.learningdesign.Transition; import org.lamsfoundation.lams.learningdesign.dao.IActivityDAO; import org.lamsfoundation.lams.lesson.LearnerProgress; @@ -95,7 +95,8 @@ completedActivityList.add(parentActivity.getActivityId()); } populateCurrentCompletedActivityList(learnerProgress, completedActivityList); - return setLessonComplete(learnerProgress, LearnerProgress.LESSON_IN_DESIGN_COMPLETE); + learnerProgress.setFinishDate(new Date()); + return setLessonComplete(learnerProgress, LearnerProgress.LESSON_IN_DESIGN_COMPLETE); } else if ( completedActivity.isFloating() && !completedActivity.getParentActivity().isParallelActivity()) { // special case - floating activity and not parallel activity (floating) child. return learnerProgress; @@ -346,7 +347,8 @@ } //lesson is meant to be completed if there is no transition and no parent. else { - learnerProgress = setLessonComplete(learnerProgress, LearnerProgress.LESSON_END_OF_DESIGN_COMPLETE); + learnerProgress.setFinishDate(new Date()); + learnerProgress = setLessonComplete(learnerProgress, LearnerProgress.LESSON_END_OF_DESIGN_COMPLETE); } return learnerProgress;