Index: lams_build/lib/lams/lams-gradebook.jar =================================================================== diff -u -r2485ce33e55a921bdcde94e4f242da5da3cf1fc4 -r0ed9749f00a1e1f92b989b270857d7f3c3f237cb Binary files differ Index: lams_build/lib/lams/lams.jar =================================================================== diff -u -raf839eeb85f37cf68092401ad23a4613ca7cd001 -r0ed9749f00a1e1f92b989b270857d7f3c3f237cb Binary files differ Index: lams_common/conf/hibernate/mappings/org/lamsfoundation/lams/lesson/LearnerProgressArchive.hbm.xml =================================================================== diff -u -r9ab6da017a5180a0ee0e766740571644972ce628 -r0ed9749f00a1e1f92b989b270857d7f3c3f237cb --- lams_common/conf/hibernate/mappings/org/lamsfoundation/lams/lesson/LearnerProgressArchive.hbm.xml (.../LearnerProgressArchive.hbm.xml) (revision 9ab6da017a5180a0ee0e766740571644972ce628) +++ lams_common/conf/hibernate/mappings/org/lamsfoundation/lams/lesson/LearnerProgressArchive.hbm.xml (.../LearnerProgressArchive.hbm.xml) (revision 0ed9749f00a1e1f92b989b270857d7f3c3f237cb) @@ -23,7 +23,13 @@ - + + + Index: lams_common/src/java/org/lamsfoundation/lams/dbupdates/patch20180628.sql =================================================================== diff -u -rbfc093eb87907e66a284fd1c30cf0f212122f706 -r0ed9749f00a1e1f92b989b270857d7f3c3f237cb --- lams_common/src/java/org/lamsfoundation/lams/dbupdates/patch20180628.sql (.../patch20180628.sql) (revision bfc093eb87907e66a284fd1c30cf0f212122f706) +++ lams_common/src/java/org/lamsfoundation/lams/dbupdates/patch20180628.sql (.../patch20180628.sql) (revision 0ed9749f00a1e1f92b989b270857d7f3c3f237cb) @@ -10,6 +10,12 @@ ALTER TABLE lams_gradebook_user_lesson_archive ADD COLUMN archive_date DATETIME; ALTER TABLE lams_gradebook_user_activity_archive ADD COLUMN archive_date DATETIME; +DELETE FROM lams_progress_attempted_archive; +DELETE FROM lams_progress_completed_archive; +DELETE FROM lams_learner_progress_archive; + +ALTER TABLE lams_learner_progress_archive ADD COLUMN archive_date DATETIME; + ----------------------Put all sql statements above here------------------------- -- If there were no errors, commit and restore autocommit to on Index: lams_common/src/java/org/lamsfoundation/lams/lesson/LearnerProgress.java =================================================================== diff -u -r60355e9a91260c605e1a55e1f2329dd69fea08b9 -r0ed9749f00a1e1f92b989b270857d7f3c3f237cb --- lams_common/src/java/org/lamsfoundation/lams/lesson/LearnerProgress.java (.../LearnerProgress.java) (revision 60355e9a91260c605e1a55e1f2329dd69fea08b9) +++ lams_common/src/java/org/lamsfoundation/lams/lesson/LearnerProgress.java (.../LearnerProgress.java) (revision 0ed9749f00a1e1f92b989b270857d7f3c3f237cb) @@ -25,7 +25,6 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.Date; -import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; Index: lams_common/src/java/org/lamsfoundation/lams/lesson/LearnerProgressArchive.java =================================================================== diff -u -r14c33274b785517e5e3f6a7642dc7c6752a34411 -r0ed9749f00a1e1f92b989b270857d7f3c3f237cb --- lams_common/src/java/org/lamsfoundation/lams/lesson/LearnerProgressArchive.java (.../LearnerProgressArchive.java) (revision 14c33274b785517e5e3f6a7642dc7c6752a34411) +++ lams_common/src/java/org/lamsfoundation/lams/lesson/LearnerProgressArchive.java (.../LearnerProgressArchive.java) (revision 0ed9749f00a1e1f92b989b270857d7f3c3f237cb) @@ -71,6 +71,8 @@ private Date startDate; private Date finishDate; + private Date archiveDate; + //--------------------------------------------------------------------- // Constructors //--------------------------------------------------------------------- @@ -80,7 +82,7 @@ public LearnerProgressArchive(User user, Lesson lesson, Integer attemptId, Map attemptedActivities, Map completedActivities, Activity currentActivity, - Byte lessonComplete, Date startDate, Date finishDate) { + Byte lessonComplete, Date startDate, Date finishDate, Date archiveDate) { this.user = user; this.lesson = lesson; this.attemptId = attemptId; @@ -90,6 +92,7 @@ this.lessonComplete = lessonComplete; this.startDate = startDate; this.finishDate = finishDate; + this.archiveDate = archiveDate; } //--------------------------------------------------------------------- @@ -173,6 +176,16 @@ this.currentActivity = currentActivity; } + public byte getProgressState(Activity activity) { + if (getCompletedActivities().containsKey(activity)) { + return LearnerProgress.ACTIVITY_COMPLETED; + } else if (getAttemptedActivities().containsKey(activity)) { + return LearnerProgress.ACTIVITY_ATTEMPTED; + } else { + return LearnerProgress.ACTIVITY_NOT_ATTEMPTED; + } + } + /** * Has the user completed the lesson? We don't care how (ie at end of * sequence or after a "stop after activity") @@ -217,4 +230,12 @@ public void setStartDate(Date startDate) { this.startDate = startDate; } + + public Date getArchiveDate() { + return archiveDate; + } + + public void setArchiveDate(Date archiveDate) { + this.archiveDate = archiveDate; + } } \ No newline at end of file Index: lams_common/src/java/org/lamsfoundation/lams/lesson/dao/ILearnerProgressDAO.java =================================================================== diff -u -r225d293907a5e2976e367ee3aa790239bad38699 -r0ed9749f00a1e1f92b989b270857d7f3c3f237cb --- lams_common/src/java/org/lamsfoundation/lams/lesson/dao/ILearnerProgressDAO.java (.../ILearnerProgressDAO.java) (revision 225d293907a5e2976e367ee3aa790239bad38699) +++ lams_common/src/java/org/lamsfoundation/lams/lesson/dao/ILearnerProgressDAO.java (.../ILearnerProgressDAO.java) (revision 0ed9749f00a1e1f92b989b270857d7f3c3f237cb) @@ -23,11 +23,13 @@ package org.lamsfoundation.lams.lesson.dao; +import java.util.Date; import java.util.List; import java.util.Map; import org.lamsfoundation.lams.learningdesign.Activity; import org.lamsfoundation.lams.lesson.LearnerProgress; +import org.lamsfoundation.lams.lesson.LearnerProgressArchive; import org.lamsfoundation.lams.usermanagement.User; /** @@ -204,4 +206,6 @@ /** Get the number of learners who are in a particular activity at the moment */ Integer getNumUsersCurrentActivity(Activity activity); + + LearnerProgressArchive getLearnerProgressArchive(Long lessonId, Integer userId, Date archiveDate); } \ No newline at end of file Index: lams_common/src/java/org/lamsfoundation/lams/lesson/dao/hibernate/LearnerProgressDAO.java =================================================================== diff -u -r225d293907a5e2976e367ee3aa790239bad38699 -r0ed9749f00a1e1f92b989b270857d7f3c3f237cb --- lams_common/src/java/org/lamsfoundation/lams/lesson/dao/hibernate/LearnerProgressDAO.java (.../LearnerProgressDAO.java) (revision 225d293907a5e2976e367ee3aa790239bad38699) +++ lams_common/src/java/org/lamsfoundation/lams/lesson/dao/hibernate/LearnerProgressDAO.java (.../LearnerProgressDAO.java) (revision 0ed9749f00a1e1f92b989b270857d7f3c3f237cb) @@ -23,6 +23,7 @@ package org.lamsfoundation.lams.lesson.dao.hibernate; +import java.util.Date; import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -33,6 +34,7 @@ import org.lamsfoundation.lams.dao.hibernate.LAMSBaseDAO; import org.lamsfoundation.lams.learningdesign.Activity; import org.lamsfoundation.lams.lesson.LearnerProgress; +import org.lamsfoundation.lams.lesson.LearnerProgressArchive; import org.lamsfoundation.lams.lesson.dao.ILearnerProgressDAO; import org.lamsfoundation.lams.usermanagement.User; import org.springframework.stereotype.Repository; @@ -119,6 +121,9 @@ private final static String FIND_PROGRESS_ARCHIVE_MAX_ATTEMPT = "SELECT MAX(p.attemptId) FROM LearnerProgressArchive p " + "WHERE p.user.id = :learnerId AND p.lesson.id = :lessonId"; + private final static String FIND_PROGRESS_ARCHIVE_BY_DATE = "FROM LearnerProgressArchive a " + + "WHERE a.lesson.lessonId = :lessonId AND a.user.userId = :learnerId AND a.archiveDate = :archiveDate"; + @Override public LearnerProgress getLearnerProgress(Long learnerProgressId) { return (LearnerProgress) getSession().get(LearnerProgress.class, learnerProgressId); @@ -348,19 +353,24 @@ return result; } - @SuppressWarnings("unchecked") @Override public Integer getNumUsersCurrentActivity(Activity activity) { Object value = getSession().createQuery(LearnerProgressDAO.COUNT_SINGLE_CURRENT_ACTIVITY) .setLong("activityId", activity.getActivityId().longValue()).uniqueResult(); return new Integer(((Number) value).intValue()); } - @Override public Integer getLearnerProgressArchiveMaxAttemptID(Integer userId, Long lessonId) { Object value = getSession().createQuery(LearnerProgressDAO.FIND_PROGRESS_ARCHIVE_MAX_ATTEMPT) .setInteger("learnerId", userId).setLong("lessonId", lessonId).uniqueResult(); return value == null ? null : ((Number) value).intValue(); } + + @Override + public LearnerProgressArchive getLearnerProgressArchive(Long lessonId, Integer userId, Date archiveDate) { + return (LearnerProgressArchive) getSession().createQuery(LearnerProgressDAO.FIND_PROGRESS_ARCHIVE_BY_DATE) + .setInteger("learnerId", userId).setLong("lessonId", lessonId).setTimestamp("archiveDate", archiveDate) + .uniqueResult(); + } } \ No newline at end of file Index: lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/service/GradebookService.java =================================================================== diff -u -raf839eeb85f37cf68092401ad23a4613ca7cd001 -r0ed9749f00a1e1f92b989b270857d7f3c3f237cb --- lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/service/GradebookService.java (.../GradebookService.java) (revision af839eeb85f37cf68092401ad23a4613ca7cd001) +++ lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/service/GradebookService.java (.../GradebookService.java) (revision 0ed9749f00a1e1f92b989b270857d7f3c3f237cb) @@ -67,7 +67,9 @@ import org.lamsfoundation.lams.learningdesign.ToolActivity; import org.lamsfoundation.lams.learningdesign.dao.IActivityDAO; import org.lamsfoundation.lams.lesson.CompletedActivityProgress; +import org.lamsfoundation.lams.lesson.CompletedActivityProgressArchive; import org.lamsfoundation.lams.lesson.LearnerProgress; +import org.lamsfoundation.lams.lesson.LearnerProgressArchive; import org.lamsfoundation.lams.lesson.Lesson; import org.lamsfoundation.lams.lesson.dao.ILearnerProgressDAO; import org.lamsfoundation.lams.lesson.dao.ILessonDAO; @@ -199,7 +201,8 @@ GradebookService.logger .debug("Getting archive gradebook user data for activity: " + activityId + ". For user: " + userId); - Lesson lesson = (Lesson) getActivityById(activityId).getLearningDesign().getLessons().iterator().next(); + Activity activity = getActivityById(activityId); + Lesson lesson = (Lesson) activity.getLearningDesign().getLessons().iterator().next(); List gradebookActivityDTOs = new ArrayList(); List lessonArchives = gradebookDAO.getArchivedLessonMarks(lesson.getLessonId(), @@ -213,6 +216,15 @@ if (lessonArchive.getArchiveDate().equals(activityArchive.getArchiveDate())) { activityDTO.setMark(activityArchive.getMark()); activityDTO.setFeedback(activityArchive.getFeedback()); + + LearnerProgressArchive learnerProgress = learnerProgressDAO + .getLearnerProgressArchive(lesson.getLessonId(), userId, lessonArchive.getArchiveDate()); + // Setting status + activityDTO.setStartDate(getActivityStartDate(learnerProgress, activity, userTimezone)); + activityDTO.setFinishDate(getActivityFinishDate(learnerProgress, activity, userTimezone)); + activityDTO.setTimeTaken(getActivityDuration(learnerProgress, activity)); + activityDTO.setStatus(getActivityStatusStr(learnerProgress, activity)); + break; } } @@ -1833,8 +1845,7 @@ } @Override - public void archiveLearnerMarks(Long lessonId, Integer learnerId) { - Date archiveDate = new Date(); + public void archiveLearnerMarks(Long lessonId, Integer learnerId, Date archiveDate) { if (logger.isDebugEnabled()) { logger.debug("Archiving activity and lesson entries for learner ID " + learnerId + " and lesson ID " + lessonId + " with archive date " + archiveDate); @@ -2094,15 +2105,31 @@ * @param timeZone * @return */ - private Date getActivityStartDate(LearnerProgress learnerProgress, Activity activity, TimeZone timeZone) { + private Date getActivityStartDate(Object learnerProgress, Activity activity, TimeZone timeZone) { Date startDate = null; if (learnerProgress != null) { - startDate = learnerProgress.getAttemptedActivities().get(activity); + + // this construct looks bad but see LDEV-4609 commit for explanation + if (learnerProgress instanceof LearnerProgressArchive) { + startDate = ((LearnerProgressArchive) learnerProgress).getStartDate(); + } else { + startDate = ((LearnerProgress) learnerProgress).getStartDate(); + } if (startDate == null) { - CompletedActivityProgress compProg = learnerProgress.getCompletedActivities().get(activity); - if (compProg != null) { - startDate = compProg.getStartDate(); + if (learnerProgress instanceof LearnerProgressArchive) { + CompletedActivityProgressArchive compProg = ((LearnerProgressArchive) learnerProgress) + .getCompletedActivities().get(activity); + if (compProg != null) { + startDate = compProg.getStartDate(); + } + } else { + CompletedActivityProgress compProg = ((LearnerProgress) learnerProgress).getCompletedActivities() + .get(activity); + if (compProg != null) { + startDate = compProg.getStartDate(); + } } + } } @@ -2127,12 +2154,22 @@ * @param timeZone * @return */ - private Date getActivityFinishDate(LearnerProgress learnerProgress, Activity activity, TimeZone timeZone) { + private Date getActivityFinishDate(Object learnerProgress, Activity activity, TimeZone timeZone) { Date finishDate = null; if (learnerProgress != null) { - CompletedActivityProgress compProg = learnerProgress.getCompletedActivities().get(activity); - if (compProg != null) { - finishDate = compProg.getFinishDate(); + // this construct looks bad but see LDEV-4609 commit for explanation + if (learnerProgress instanceof LearnerProgressArchive) { + CompletedActivityProgressArchive compProg = ((LearnerProgressArchive) learnerProgress) + .getCompletedActivities().get(activity); + if (compProg != null) { + finishDate = compProg.getFinishDate(); + } + } else { + CompletedActivityProgress compProg = ((LearnerProgress) learnerProgress).getCompletedActivities() + .get(activity); + if (compProg != null) { + finishDate = compProg.getFinishDate(); + } } } @@ -2149,18 +2186,31 @@ return finishDate; } - private Long getActivityDuration(LearnerProgress learnerProgress, Activity activity) { + private Long getActivityDuration(Object learnerProgress, Activity activity) { if (learnerProgress != null) { - if (learnerProgress.getCompletedActivities().get(activity) != null) { - CompletedActivityProgress compProg = learnerProgress.getCompletedActivities().get(activity); + // this construct looks bad but see LDEV-4609 commit for explanation + if (learnerProgress instanceof LearnerProgressArchive) { + CompletedActivityProgressArchive compProg = ((LearnerProgressArchive) learnerProgress) + .getCompletedActivities().get(activity); if (compProg != null) { Date startTime = compProg.getStartDate(); Date endTime = compProg.getFinishDate(); if ((startTime != null) && (endTime != null)) { return endTime.getTime() - startTime.getTime(); } } + } else { + CompletedActivityProgress compProg = ((LearnerProgress) learnerProgress).getCompletedActivities() + .get(activity); + if (compProg != null) { + Date startTime = compProg.getStartDate(); + Date endTime = compProg.getFinishDate(); + if ((startTime != null) && (endTime != null)) { + return endTime.getTime() - startTime.getTime(); + } + } } + } return null; } @@ -2197,14 +2247,19 @@ * @param activity * @return */ - private String getActivityStatusStr(LearnerProgress learnerProgress, Activity activity) { + private String getActivityStatusStr(Object learnerProgress, Activity activity) { final String IMAGES_DIR = Configuration.get(ConfigurationKeys.SERVER_URL) + "images"; if (learnerProgress != null) { - byte statusByte = learnerProgress.getProgressState(activity); - if (statusByte == LearnerProgress.ACTIVITY_ATTEMPTED && learnerProgress.getCurrentActivity() != null) { - return ""; + // this construct looks bad but see LDEV-4609 commit for explanation + byte statusByte = learnerProgress instanceof LearnerProgressArchive + ? ((LearnerProgressArchive) learnerProgress).getProgressState(activity) + : ((LearnerProgress) learnerProgress).getProgressState(activity); + Activity currentActivity = learnerProgress instanceof LearnerProgressArchive + ? ((LearnerProgressArchive) learnerProgress).getCurrentActivity() + : ((LearnerProgress) learnerProgress).getCurrentActivity(); + if (statusByte == LearnerProgress.ACTIVITY_ATTEMPTED && currentActivity != null) { + return ""; } else if (statusByte == LearnerProgress.ACTIVITY_COMPLETED) { return ""; } Index: lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/service/IGradebookService.java =================================================================== diff -u -raf839eeb85f37cf68092401ad23a4613ca7cd001 -r0ed9749f00a1e1f92b989b270857d7f3c3f237cb --- lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/service/IGradebookService.java (.../IGradebookService.java) (revision af839eeb85f37cf68092401ad23a4613ca7cd001) +++ lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/service/IGradebookService.java (.../IGradebookService.java) (revision 0ed9749f00a1e1f92b989b270857d7f3c3f237cb) @@ -23,6 +23,7 @@ package org.lamsfoundation.lams.gradebook.service; import java.util.ArrayList; +import java.util.Date; import java.util.LinkedHashMap; import java.util.List; import java.util.TimeZone; @@ -300,7 +301,7 @@ void removeLearnerFromLesson(Long lessonId, Integer learnerId); - void archiveLearnerMarks(Long lessonId, Integer learnerId); + void archiveLearnerMarks(Long lessonId, Integer learnerId, Date archiveDate); /** * Get a language label Index: lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/LearnerAction.java =================================================================== diff -u -r36f567f41d6be3f1894cbd1648baffff0438e622 -r0ed9749f00a1e1f92b989b270857d7f3c3f237cb --- lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/LearnerAction.java (.../LearnerAction.java) (revision 36f567f41d6be3f1894cbd1648baffff0438e622) +++ lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/LearnerAction.java (.../LearnerAction.java) (revision 0ed9749f00a1e1f92b989b270857d7f3c3f237cb) @@ -210,6 +210,7 @@ attemptID++; // make a copy of attempted and completed activities + Date archiveDate = new Date(); LearnerProgress learnerProgress = learnerService.getProgress(userID, lessonID); Map attemptedActivities = new HashMap(learnerProgress.getAttemptedActivities()); Map completedActivities = new HashMap(); @@ -222,14 +223,15 @@ // save the historic attempt LearnerProgressArchive learnerProgressArchive = new LearnerProgressArchive(user, learnerProgress.getLesson(), attemptID, attemptedActivities, completedActivities, learnerProgress.getCurrentActivity(), - learnerProgress.getLessonComplete(), learnerProgress.getStartDate(), learnerProgress.getFinishDate()); + learnerProgress.getLessonComplete(), learnerProgress.getStartDate(), learnerProgress.getFinishDate(), + archiveDate); IUserManagementService userManagementService = LearnerServiceProxy .getUserManagementService(getServlet().getServletContext()); userManagementService.save(learnerProgressArchive); IGradebookService gradebookService = LearnerServiceProxy.getGradebookService(getServlet().getServletContext()); - gradebookService.archiveLearnerMarks(lessonID, userID); + gradebookService.archiveLearnerMarks(lessonID, userID, archiveDate); gradebookService.removeLearnerFromLesson(lessonID, userID); IMonitoringService monitoringService = LearnerServiceProxy