Index: lams_build/lib/lams/lams-gradebook.jar =================================================================== diff -u -r85722e8849d945a8fe3c034d74fca74706eab6e5 -r8daec7e047f7ea8404c6f16218b63a8e855a15b2 Binary files differ Index: lams_build/lib/lams/lams-monitoring.jar =================================================================== diff -u -r83005805dfe5847c8578b56911f7e9f8ce08ff9f -r8daec7e047f7ea8404c6f16218b63a8e855a15b2 Binary files differ Index: lams_build/lib/lams/lams.jar =================================================================== diff -u -r87bf2cc06957fe5c7b14834e52042552124b3bbd -r8daec7e047f7ea8404c6f16218b63a8e855a15b2 Binary files differ Index: lams_common/conf/hibernate/mappings/org/lamsfoundation/lams/gradebook/GradebookUserActivityArchive.hbm.xml =================================================================== diff -u --- lams_common/conf/hibernate/mappings/org/lamsfoundation/lams/gradebook/GradebookUserActivityArchive.hbm.xml (revision 0) +++ lams_common/conf/hibernate/mappings/org/lamsfoundation/lams/gradebook/GradebookUserActivityArchive.hbm.xml (revision 8daec7e047f7ea8404c6f16218b63a8e855a15b2) @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file Index: lams_common/conf/hibernate/mappings/org/lamsfoundation/lams/gradebook/GradebookUserLessonArchive.hbm.xml =================================================================== diff -u --- lams_common/conf/hibernate/mappings/org/lamsfoundation/lams/gradebook/GradebookUserLessonArchive.hbm.xml (revision 0) +++ lams_common/conf/hibernate/mappings/org/lamsfoundation/lams/gradebook/GradebookUserLessonArchive.hbm.xml (revision 8daec7e047f7ea8404c6f16218b63a8e855a15b2) @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file Index: lams_common/src/java/org/lamsfoundation/lams/dbupdates/patch20170323.sql =================================================================== diff -u --- lams_common/src/java/org/lamsfoundation/lams/dbupdates/patch20170323.sql (revision 0) +++ lams_common/src/java/org/lamsfoundation/lams/dbupdates/patch20170323.sql (revision 8daec7e047f7ea8404c6f16218b63a8e855a15b2) @@ -0,0 +1,38 @@ +-- Turn off autocommit, so nothing is committed if there is an error +SET AUTOCOMMIT = 0; +SET FOREIGN_KEY_CHECKS=0; +----------------------Put all sql statements below here------------------------- + +-- LDEV-4288 Create tables to store archived gradebook entries + +CREATE TABLE lams_gradebook_user_lesson_archive ( + uid bigint(20) NOT NULL, + lesson_id bigint(20) NOT NULL, + user_id bigint(20) NOT NULL, + mark double, + feedback text, + PRIMARY KEY (uid), + KEY lesson_id (lesson_id, user_id), + CONSTRAINT FK_lams_gradebook_user_lesson_archive_1 FOREIGN KEY (lesson_id) REFERENCES lams_lesson (lesson_id) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT FK_lams_gradebook_user_lesson_archive_2 FOREIGN KEY (user_id) REFERENCES lams_user (user_id) ON DELETE CASCADE ON UPDATE CASCADE +); + +CREATE TABLE lams_gradebook_user_activity_archive ( + uid bigint(20) NOT NULL, + activity_id bigint(20) NOT NULL, + user_id bigint(20) NOT NULL, + mark double, + feedback text, + marked_in_gradebook tinyint(1) NOT NULL DEFAULT 0, + update_date datetime, + PRIMARY KEY (uid), + KEY activity_id (activity_id, user_id), + CONSTRAINT FK_lams_gradebook_user_activity_archive_1 FOREIGN KEY (activity_id) REFERENCES lams_learning_activity (activity_id) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT FK_lams_gradebook_user_activity_archive_2 FOREIGN KEY (user_id) REFERENCES lams_user (user_id) ON DELETE CASCADE ON UPDATE CASCADE +); +----------------------Put all sql statements above here------------------------- + +-- If there were no errors, commit and restore autocommit to on +COMMIT; +SET AUTOCOMMIT = 1; +SET FOREIGN_KEY_CHECKS=1; Index: lams_common/src/java/org/lamsfoundation/lams/gradebook/GradebookUserActivityArchive.java =================================================================== diff -u --- lams_common/src/java/org/lamsfoundation/lams/gradebook/GradebookUserActivityArchive.java (revision 0) +++ lams_common/src/java/org/lamsfoundation/lams/gradebook/GradebookUserActivityArchive.java (revision 8daec7e047f7ea8404c6f16218b63a8e855a15b2) @@ -0,0 +1,108 @@ +/**************************************************************** + * 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 + * **************************************************************** + */ + +package org.lamsfoundation.lams.gradebook; + +import java.util.Date; + +import org.lamsfoundation.lams.learningdesign.ToolActivity; +import org.lamsfoundation.lams.usermanagement.User; + +public class GradebookUserActivityArchive { + + private long uid; + private ToolActivity activity; + private User learner; + private Double mark; + private String feedback; + private Boolean markedInGradebook; + private Date updateDate; + + public GradebookUserActivityArchive() { + } + + public GradebookUserActivityArchive(GradebookUserActivity source) { + this.uid = source.getUid(); + this.activity = source.getActivity(); + this.learner = source.getLearner(); + this.mark = source.getMark(); + this.feedback = source.getFeedback(); + this.markedInGradebook = source.getMarkedInGradebook(); + this.updateDate = source.getUpdateDate(); + } + + public long getUid() { + return uid; + } + + public void setUid(long uid) { + this.uid = uid; + } + + public ToolActivity getActivity() { + return activity; + } + + public void setActivity(ToolActivity activity) { + this.activity = activity; + } + + public User getLearner() { + return learner; + } + + public void setLearner(User learner) { + this.learner = learner; + } + + public Double getMark() { + return mark; + } + + public void setMark(Double mark) { + this.mark = mark; + } + + public String getFeedback() { + return feedback; + } + + public void setFeedback(String feedback) { + this.feedback = feedback; + } + + public Boolean getMarkedInGradebook() { + return markedInGradebook; + } + + public void setMarkedInGradebook(Boolean markedInGradebook) { + this.markedInGradebook = markedInGradebook; + } + + public Date getUpdateDate() { + return updateDate; + } + + public void setUpdateDate(Date updateDate) { + this.updateDate = updateDate; + } +} \ No newline at end of file Index: lams_common/src/java/org/lamsfoundation/lams/gradebook/GradebookUserLessonArchive.java =================================================================== diff -u --- lams_common/src/java/org/lamsfoundation/lams/gradebook/GradebookUserLessonArchive.java (revision 0) +++ lams_common/src/java/org/lamsfoundation/lams/gradebook/GradebookUserLessonArchive.java (revision 8daec7e047f7ea8404c6f16218b63a8e855a15b2) @@ -0,0 +1,85 @@ +/**************************************************************** + * 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 + * **************************************************************** + */ + +package org.lamsfoundation.lams.gradebook; + +import org.lamsfoundation.lams.lesson.Lesson; +import org.lamsfoundation.lams.usermanagement.User; + +public class GradebookUserLessonArchive { + private long uid; + private Lesson lesson; + private User learner; + private Double mark; + private String feedback; + + public GradebookUserLessonArchive() { + } + + public GradebookUserLessonArchive(GradebookUserLesson source) { + this.uid = source.getUid(); + this.lesson = source.getLesson(); + this.learner = source.getLearner(); + this.mark = source.getMark(); + this.feedback = source.getFeedback(); + } + + public long getUid() { + return uid; + } + + public void setUid(long uid) { + this.uid = uid; + } + + public Lesson getLesson() { + return lesson; + } + + public void setLesson(Lesson lesson) { + this.lesson = lesson; + } + + public User getLearner() { + return learner; + } + + public void setLearner(User learner) { + this.learner = learner; + } + + public Double getMark() { + return mark; + } + + public void setMark(Double mark) { + this.mark = mark; + } + + public String getFeedback() { + return feedback; + } + + public void setFeedback(String feedback) { + this.feedback = feedback; + } +} \ No newline at end of file Index: lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/gradebookApplicationContext.xml =================================================================== diff -u -r0aad94a28574176ae783da37b50e4108c0882e90 -r8daec7e047f7ea8404c6f16218b63a8e855a15b2 --- lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/gradebookApplicationContext.xml (.../gradebookApplicationContext.xml) (revision 0aad94a28574176ae783da37b50e4108c0882e90) +++ lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/gradebookApplicationContext.xml (.../gradebookApplicationContext.xml) (revision 8daec7e047f7ea8404c6f16218b63a8e855a15b2) @@ -36,6 +36,8 @@ + PROPAGATION_REQUIRED + PROPAGATION_REQUIRED PROPAGATION_REQUIRED PROPAGATION_REQUIRED PROPAGATION_REQUIRED Index: lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/service/GradebookService.java =================================================================== diff -u -r723b5bcbdf0db6b9a4fbeacdc55f7336992ac935 -r8daec7e047f7ea8404c6f16218b63a8e855a15b2 --- lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/service/GradebookService.java (.../GradebookService.java) (revision 723b5bcbdf0db6b9a4fbeacdc55f7336992ac935) +++ lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/service/GradebookService.java (.../GradebookService.java) (revision 8daec7e047f7ea8404c6f16218b63a8e855a15b2) @@ -20,7 +20,6 @@ * **************************************************************** */ - package org.lamsfoundation.lams.gradebook.service; import java.text.SimpleDateFormat; @@ -43,7 +42,9 @@ import org.apache.log4j.Logger; import org.lamsfoundation.lams.dao.IBaseDAO; import org.lamsfoundation.lams.gradebook.GradebookUserActivity; +import org.lamsfoundation.lams.gradebook.GradebookUserActivityArchive; import org.lamsfoundation.lams.gradebook.GradebookUserLesson; +import org.lamsfoundation.lams.gradebook.GradebookUserLessonArchive; import org.lamsfoundation.lams.gradebook.dao.IGradebookDAO; import org.lamsfoundation.lams.gradebook.dto.GBActivityGridRowDTO; import org.lamsfoundation.lams.gradebook.dto.GBLessonGridRowDTO; @@ -95,7 +96,6 @@ import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; - /** * * This service handles all gradebook-related service calls @@ -121,8 +121,6 @@ private MessageService messageService; private IAuditService auditService; private static ICoreLearnerService learnerService; - - @Override public List getGBActivityRowsForLearner(Long lessonId, Integer userId, TimeZone userTimezone) { @@ -189,7 +187,6 @@ } @Override - @SuppressWarnings("unchecked") public List getGBActivityRowsForLesson(Long lessonId, TimeZone userTimezone) { GradebookService.logger.debug("Getting gradebook data for lesson: " + lessonId); @@ -222,7 +219,6 @@ } @Override - @SuppressWarnings("unchecked") public List getGBUserRowsForActivity(Lesson lesson, ToolActivity activity, Long groupId, int page, int size, String sortBy, String sortOrder, String searchString, TimeZone timezone) { Long lessonId = lesson.getLessonId(); @@ -349,20 +345,20 @@ if (learnerProgress != null) { Date startDate = learnerProgress.getStartDate(); Date finishDate = learnerProgress.getFinishDate(); - + if (startDate != null && finishDate != null) { gradebookUserDTO.setTimeTaken(finishDate.getTime() - startDate.getTime()); } - if ( startDate != null ) { - if ( userTimeZone != null ) + if (startDate != null) { + if (userTimeZone != null) startDate = DateUtil.convertToTimeZoneFromDefault(userTimeZone, startDate); gradebookUserDTO.setStartDate(startDate); } - - if ( learnerProgress.getFinishDate() != null ) { - if ( userTimeZone != null ) - finishDate = DateUtil.convertToTimeZoneFromDefault(userTimeZone, finishDate); + + if (learnerProgress.getFinishDate() != null) { + if (userTimeZone != null) + finishDate = DateUtil.convertToTimeZoneFromDefault(userTimeZone, finishDate); gradebookUserDTO.setFinishDate(finishDate); } @@ -475,7 +471,7 @@ if (lesson == null) { return; } - + Map userToGradebookUserLessonMap = getUserToGradebookUserLessonMap(lesson, null); //update for all users in activity @@ -486,7 +482,7 @@ Double totalMark = gradebookDAO.getGradebookUserActivityMarkSum(lessonId, userId); if (totalMark != null) { - + if (totalMark > 0 && gradebookUserLesson == null) { throw new Exception("An error detected: user (userId:" + userId + ") has total mark that equals to " + totalMark + " but no assocciated gradebookUserLesson exist "); @@ -499,7 +495,7 @@ } } } - + @Override public void recalculateGradebookMarksForActivity(Activity activity) { Long activityId = activity.getActivityId(); @@ -515,7 +511,7 @@ // Getting the first activity evaluation ActivityEvaluation eval = toolActivity.getActivityEvaluations().iterator().next(); String toolOutputDefinition = eval.getToolOutputDefinition(); - + Map userToGradebookUserActivityMap = getUserToGradebookUserActivityMap(activity, null); Map userToGradebookUserLessonMap = getUserToGradebookUserLessonMap(lesson, null); @@ -545,7 +541,7 @@ gradebookUserActivity, gradebookUserLesson); } } - } + } @Override public void updateUserActivityGradebookMark(Lesson lesson, Activity activity, User learner) { @@ -600,7 +596,7 @@ updateUserActivityGradebookMark(lesson, learner, activity, mark, markedInGradebook, isAuditLogRequired, gradebookUserActivity, gradebookUserLesson); } - + /** * It's the same method as above, it only also accepts gradebookUserActivity and gradebookUserLesson as parameters. */ @@ -691,7 +687,6 @@ } @Override - @SuppressWarnings("unchecked") public List getGBLessonRows(Organisation organisation, User user, User viewer, GBGridView view, int page, int size, String sortBy, String sortOrder, String searchString, TimeZone userTimeZone) { List lessonRows = new ArrayList(); @@ -735,14 +730,13 @@ String gbMonURL = Configuration.get(ConfigurationKeys.SERVER_URL) + "gradebook/gradebookMonitoring.do?lessonID=" + lesson.getLessonId().toString(); lessonRow.setGradebookMonitorURL(gbMonURL); - + Date startDate = lesson.getStartDateTime(); - if ( startDate != null ) { - if ( userTimeZone != null ) + if (startDate != null) { + if (userTimeZone != null) startDate = DateUtil.convertToTimeZoneFromDefault(userTimeZone, startDate); lessonRow.setStartDate(startDate); } - } else if ((view == GBGridView.LRN_COURSE) || (view == GBGridView.MON_USER)) { @@ -763,20 +757,20 @@ if (learnerProgress != null) { Date startDate = learnerProgress.getStartDate(); Date finishDate = learnerProgress.getFinishDate(); - + if (startDate != null && finishDate != null) { lessonRow.setTimeTaken(finishDate.getTime() - startDate.getTime()); } - if ( startDate != null ) { - if ( userTimeZone != null ) + if (startDate != null) { + if (userTimeZone != null) startDate = DateUtil.convertToTimeZoneFromDefault(userTimeZone, startDate); lessonRow.setStartDate(startDate); } - - if ( learnerProgress.getFinishDate() != null ) { - if ( userTimeZone != null ) - finishDate = DateUtil.convertToTimeZoneFromDefault(userTimeZone, finishDate); + + if (learnerProgress.getFinishDate() != null) { + if (userTimeZone != null) + finishDate = DateUtil.convertToTimeZoneFromDefault(userTimeZone, finishDate); lessonRow.setFinishDate(finishDate); } } @@ -818,9 +812,8 @@ } @SuppressWarnings("unchecked") - private void getActivityDataForLessonGradebookExport( - Map> activityToUserDTOMap, Set learners, - Map userToLearnerProgressMap, Activity activity) { + private void getActivityDataForLessonGradebookExport(Map> activityToUserDTOMap, + Set learners, Map userToLearnerProgressMap, Activity activity) { if (activity.isToolActivity()) { List userDTOs = getToolActivityDataForLessonGradebookExport(learners, @@ -836,9 +829,8 @@ complexLearners = new TreeSet(new UserComparator()); for (User learner : learners) { LearnerProgress learnerProgress = userToLearnerProgressMap.get(learner.getUserId()); - if (learnerProgress != null - && (learnerProgress.getCompletedActivities().get(activity) != null || learnerProgress - .getAttemptedActivities().get(activity) != null)) { + if (learnerProgress != null && (learnerProgress.getCompletedActivities().get(activity) != null + || learnerProgress.getAttemptedActivities().get(activity) != null)) { complexLearners.add(learner); } } @@ -847,8 +839,8 @@ ComplexActivity sequence = (ComplexActivity) activity; Set childActivities = (Set) sequence.getActivities(); for (Activity childActivity : childActivities) { - getActivityDataForLessonGradebookExport(activityToUserDTOMap, complexLearners, - userToLearnerProgressMap, activityDAO.getActivityByActivityId(childActivity.getActivityId())); + getActivityDataForLessonGradebookExport(activityToUserDTOMap, complexLearners, userToLearnerProgressMap, + activityDAO.getActivityByActivityId(childActivity.getActivityId())); } } } @@ -902,7 +894,8 @@ ExcelCell[] lessonMedianTimeTaken = new ExcelCell[2]; lessonMedianTimeTaken[0] = new ExcelCell(getMessage("gradebook.export.average.lesson.time.taken"), true); - lessonMedianTimeTaken[1] = new ExcelCell(gradebookDAO.getMedianTimeTakenLesson(lesson.getLessonId()) / 1000, false); + lessonMedianTimeTaken[1] = new ExcelCell(gradebookDAO.getMedianTimeTakenLesson(lesson.getLessonId()) / 1000, + false); rowList.add(lessonMedianTimeTaken); rowList.add(GradebookService.EMPTY_ROW); @@ -976,7 +969,7 @@ ExcelCell[] activityTitleRow = new ExcelCell[7]; activityTitleRow[0] = new ExcelCell(activity.getTitle(), true); rowList1.add(activityTitleRow); - + int count = 0; ExcelCell[] titleRow = new ExcelCell[7]; titleRow[count++] = new ExcelCell(getMessage("gradebook.export.last.name"), true); @@ -1049,7 +1042,7 @@ } // userDto will be null if this tool activity was within a branch and the user has not attempted that branch - if ( userDto != null ) { + if (userDto != null) { //construct activityRowName String groupName = null; Long groupId = null; @@ -1062,7 +1055,7 @@ } String activityRowName = (groupName != null && groupId != null) ? StringEscapeUtils.escapeHtml(activity.getTitle()) + " (" + groupName + ")" - : StringEscapeUtils.escapeHtml(activity.getTitle()); + : StringEscapeUtils.escapeHtml(activity.getTitle()); String startDate = (userDto.getStartDate() == null) ? "" : cellDateFormat.format(userDto.getStartDate()); @@ -1307,18 +1300,20 @@ activityTouserToGradebookUserActivityMap.put(activity.getActivityId(), userToGradebookUserActivityMap); } - int numberCellsPerRow = simplified ? 3 + selectedLessons.size() + 3 : - (selectedLessons.size() * 9) + (allActivities.size() * 2) + 5; + int numberCellsPerRow = simplified ? 3 + selectedLessons.size() + 3 + : (selectedLessons.size() * 9) + (allActivities.size() * 2) + 5; // Lesson names row---------------------- ExcelCell[] lessonsNames = new ExcelCell[numberCellsPerRow]; - if ( simplified ) { + if (simplified) { int i = 3; for (Lesson lesson : selectedLessons) { - lessonsNames[i++] = new ExcelCell(lesson.getLessonName(), true).setAlignment(ExcelCell.ALIGN_CENTER); + lessonsNames[i++] = new ExcelCell(lesson.getLessonName(), true) + .setAlignment(ExcelCell.ALIGN_CENTER); } lessonsNames[i++] = new ExcelCell("", ExcelCell.BORDER_STYLE_LEFT_THICK); - lessonsNames[i++] = new ExcelCell(getMessage("label.overall.totals"), true).setAlignment(ExcelCell.ALIGN_CENTER); + lessonsNames[i++] = new ExcelCell(getMessage("label.overall.totals"), true) + .setAlignment(ExcelCell.ALIGN_CENTER); lessonsNames[i++] = new ExcelCell("", ExcelCell.BORDER_STYLE_RIGHT_THICK); } else { int i = 4; @@ -1336,11 +1331,10 @@ rowList.add(lessonsNames); // Headers row---------------------- - if ( simplified ) + if (simplified) rowList.add(createSelectedLessonsHeaderSimplified(selectedLessons, numberCellsPerRow)); - else - rowList.add(createSelectedLessonsHeaderFull(selectedLessons, lessonActivitiesMap, - numberCellsPerRow)); + else + rowList.add(createSelectedLessonsHeaderFull(selectedLessons, lessonActivitiesMap, numberCellsPerRow)); // Actual data rows---------------------- for (User learner : allLearners) { @@ -1350,17 +1344,17 @@ ExcelCell[] userRow = new ExcelCell[numberCellsPerRow]; int i = 0; - if ( simplified ) { + if (simplified) { i = addUsernameCells(learner, userRow, i); } - + for (Lesson lesson : selectedLessons) { Double lessonTotal = 0d; Double lessonMaxMark = 0d; List activities = lessonActivitiesMap.get(lesson.getLessonId()); - if ( ! simplified ) { + if (!simplified) { i = addUsernameCells(learner, userRow, i); // check if learner is participating in this lesson @@ -1397,7 +1391,7 @@ : cellDateFormat.format(learnerProgress.getFinishDate()); userRow[i++] = new ExcelCell(finishDate, false); } - + for (ToolActivity activity : activities) { Map userToGradebookUserActivityMap = activityTouserToGradebookUserActivityMap .get(activity.getActivityId()); @@ -1406,16 +1400,16 @@ Double mark = 0d; if (gradebookUserActivity != null) { mark = gradebookUserActivity.getMark(); - if ( ! simplified ) + if (!simplified) userRow[i++] = new ExcelCell(mark, false); } else { - if ( ! simplified ) + if (!simplified) userRow[i++] = new ExcelCell("", false); } Long activityTotalMarks = (activityToTotalMarkMap.get(activity.getActivityId()) != null) ? activityToTotalMarkMap.get(activity.getActivityId()) : 0l; - if ( ! simplified ) + if (!simplified) userRow[i++] = new ExcelCell(activityTotalMarks, false); lessonTotal += mark; @@ -1424,13 +1418,13 @@ overallMaxMark += activityTotalMarks; } - if ( simplified ) { - userRow[i++] = new ExcelCell(lessonTotal, ExcelCell.BORDER_STYLE_LEFT_THIN); + if (simplified) { + userRow[i++] = new ExcelCell(lessonTotal, ExcelCell.BORDER_STYLE_LEFT_THIN); } else { - userRow[i++] = new ExcelCell(lessonTotal, ExcelCell.BORDER_STYLE_LEFT_THIN); - userRow[i++] = new ExcelCell(lessonMaxMark, false); - Double percentage = (lessonMaxMark != 0) ? lessonTotal / lessonMaxMark : 0d; - userRow[i++] = new ExcelCell(percentage, ExcelCell.BORDER_STYLE_RIGHT_THICK); + userRow[i++] = new ExcelCell(lessonTotal, ExcelCell.BORDER_STYLE_LEFT_THIN); + userRow[i++] = new ExcelCell(lessonMaxMark, false); + Double percentage = (lessonMaxMark != 0) ? lessonTotal / lessonMaxMark : 0d; + userRow[i++] = new ExcelCell(percentage, ExcelCell.BORDER_STYLE_RIGHT_THICK); } } @@ -1446,7 +1440,7 @@ userRow[i++] = new ExcelCell(overallMaxMark, false); userRow[i++] = new ExcelCell(percentage, true, ExcelCell.BORDER_STYLE_RIGHT_THICK); } - + rowList.add(userRow); } } @@ -1508,14 +1502,17 @@ for (Lesson lesson : selectedLessons) { headerRow[i++] = new ExcelCell(getMessage("label.total.actuals"), false, ExcelCell.BORDER_STYLE_LEFT_THIN) - .setAlignment(ExcelCell.ALIGN_CENTER); + .setAlignment(ExcelCell.ALIGN_CENTER); } - headerRow[i++] = new ExcelCell(getMessage("label.actuals"), true, ExcelCell.BORDER_STYLE_LEFT_THICK).setAlignment(ExcelCell.ALIGN_CENTER); + headerRow[i++] = new ExcelCell(getMessage("label.actuals"), true, ExcelCell.BORDER_STYLE_LEFT_THICK) + .setAlignment(ExcelCell.ALIGN_CENTER); headerRow[i++] = new ExcelCell(getMessage("label.max"), false).setAlignment(ExcelCell.ALIGN_CENTER); - headerRow[i++] = new ExcelCell("%", false, ExcelCell.BORDER_STYLE_RIGHT_THICK).setAlignment(ExcelCell.ALIGN_CENTER); + headerRow[i++] = new ExcelCell("%", false, ExcelCell.BORDER_STYLE_RIGHT_THICK) + .setAlignment(ExcelCell.ALIGN_CENTER); return headerRow; } + @Override public void updateActivityMark(Double mark, String feedback, Integer userID, Long toolSessionID, Boolean markedInGradebook) { @@ -1539,55 +1536,94 @@ public Activity getActivityById(Long activityID) { return activityDAO.getActivityByActivityId(activityID); } - - + + @Override + public void removeLearnerFromLesson(Long lessonId, Integer learnerId) { + if (logger.isDebugEnabled()) { + logger.debug( + "Removing activity and lesson entries for learner ID " + learnerId + " and lesson ID " + lessonId); + } + Lesson lesson = getLessonService().getLesson(lessonId); + List activities = getLessonActivitiesForLearner(lesson, learnerId); + for (ToolActivity activity : activities) { + GradebookUserActivity gradebookUserActivity = getGradebookUserActivity(activity.getActivityId(), learnerId); + if (gradebookUserActivity != null) { + gradebookDAO.delete(gradebookUserActivity); + } + } + GradebookUserLesson gradebookUserLesson = getGradebookUserLesson(lesson.getLessonId(), learnerId); + if (gradebookUserLesson != null) { + gradebookDAO.delete(gradebookUserLesson); + } + } + + @Override + public void archiveLearnerMarks(Long lessonId, Integer learnerId) { + if (logger.isDebugEnabled()) { + logger.debug( + "Archiving activity and lesson entries for learner ID " + learnerId + " and lesson ID " + lessonId); + } + Lesson lesson = getLessonService().getLesson(lessonId); + List activities = getLessonActivitiesForLearner(lesson, learnerId); + for (ToolActivity activity : activities) { + GradebookUserActivity gradebookUserActivity = getGradebookUserActivity(activity.getActivityId(), learnerId); + if (gradebookUserActivity != null) { + gradebookDAO.insert(new GradebookUserActivityArchive(gradebookUserActivity)); + } + } + GradebookUserLesson gradebookUserLesson = getGradebookUserLesson(lesson.getLessonId(), learnerId); + if (gradebookUserLesson != null) { + gradebookDAO.insert(new GradebookUserLessonArchive(gradebookUserLesson)); + } + } + /** - * Returns a completely flat list of lesson activities for the whole lesson. + * Returns a completely flat list of lesson activities for the whole lesson. */ private List getLessonToolActivitiesForLesson(Lesson lesson) { List toolActivities = new ArrayList(); - List activityUrls = getLearnerService().getStructuredActivityURLs(lesson.getLessonId()); + List activityUrls = getLearnerService().getStructuredActivityURLs(lesson.getLessonId()); for (ActivityURL activityUrl : activityUrls) { processLessonToolActivity(activityUrl, toolActivities); } return toolActivities; } private void processLessonToolActivity(ActivityURL activityUrl, List toolActivities) { - Activity activity = activityDAO.getActivityByActivityId(activityUrl.getActivityId()); - if (activity instanceof ToolActivity) { - ToolActivity toolActivity = (ToolActivity) activity; - toolActivities.add(toolActivity); - } else if (activity instanceof ComplexActivity ) { - for (ActivityURL childUrl : activityUrl.getChildActivities()) { - processLessonToolActivity(childUrl, toolActivities); - } - } - } - + Activity activity = activityDAO.getActivityByActivityId(activityUrl.getActivityId()); + if (activity instanceof ToolActivity) { + ToolActivity toolActivity = (ToolActivity) activity; + toolActivities.add(toolActivity); + } else if (activity instanceof ComplexActivity) { + for (ActivityURL childUrl : activityUrl.getChildActivities()) { + processLessonToolActivity(childUrl, toolActivities); + } + } + } + /** - * Returns a list of lesson activities made up of tool activities and sequence activities for the whole lesson. + * Returns a list of lesson activities made up of tool activities and sequence activities for the whole lesson. * The sequence activities allow the export to tweak the learner out. */ private List getLessonActivitiesForLesson(Lesson lesson) { List activities = new ArrayList(); - List activityUrls = getLearnerService().getStructuredActivityURLs(lesson.getLessonId()); + List activityUrls = getLearnerService().getStructuredActivityURLs(lesson.getLessonId()); for (ActivityURL activityUrl : activityUrls) { processLessonActivity(activityUrl, activities); } return activities; } private void processLessonActivity(ActivityURL activityUrl, List activities) { - Activity activity = activityDAO.getActivityByActivityId(activityUrl.getActivityId()); - if (activity instanceof ToolActivity || activity instanceof SequenceActivity) { - activities.add(activity); - } else if (activity instanceof ComplexActivity ) { - for (ActivityURL childUrl : activityUrl.getChildActivities()) { - processLessonActivity(childUrl, activities); - } - } - } + Activity activity = activityDAO.getActivityByActivityId(activityUrl.getActivityId()); + if (activity instanceof ToolActivity || activity instanceof SequenceActivity) { + activities.add(activity); + } else if (activity instanceof ComplexActivity) { + for (ActivityURL childUrl : activityUrl.getChildActivities()) { + processLessonActivity(childUrl, activities); + } + } + } /** * Returns lesson activities for a particular user @@ -1597,32 +1633,33 @@ List toolActivities = new ArrayList(); Object[] objs = getLearnerService().getStructuredActivityURLs(learnerId, lesson.getLessonId()); // will be null if learner has not started the lesson. - if ( objs != null ) { - List activityUrls = (List) objs[0]; + if (objs != null) { + List activityUrls = (List) objs[0]; for (ActivityURL activityUrl : activityUrls) { processLearnerActivity(activityUrl, toolActivities, false); } } return toolActivities; } - - private void processLearnerActivity(ActivityURL activityUrl, List toolActivities, boolean includeOnlyAttemptedCompleted) { + + private void processLearnerActivity(ActivityURL activityUrl, List toolActivities, + boolean includeOnlyAttemptedCompleted) { Activity activity = activityDAO.getActivityByActivityId(activityUrl.getActivityId()); if (activity instanceof ToolActivity) { - if ( ! includeOnlyAttemptedCompleted || activityUrl.getStatus() != LearnerProgress.ACTIVITY_NOT_ATTEMPTED ) { - ToolActivity toolActivity = (ToolActivity) activity; - toolActivities.add(toolActivity); + if (!includeOnlyAttemptedCompleted || activityUrl.getStatus() != LearnerProgress.ACTIVITY_NOT_ATTEMPTED) { + ToolActivity toolActivity = (ToolActivity) activity; + toolActivities.add(toolActivity); } } else if (activity instanceof ParallelActivity || activity instanceof FloatingActivity) { for (ActivityURL childUrl : activityUrl.getChildActivities()) { processLearnerActivity(childUrl, toolActivities, false); } - } else if ( activity instanceof OptionsActivity ) { + } else if (activity instanceof OptionsActivity) { for (ActivityURL childUrl : activityUrl.getChildActivities()) { processLearnerActivity(childUrl, toolActivities, true); } - } + } } /** @@ -1651,17 +1688,18 @@ * * @param gradebookUserLesson */ - private void aggregateTotalMarkForLesson(GradebookUserLesson gradebookUserLesson, Double newActivityMark, Double oldActivityMark) { + private void aggregateTotalMarkForLesson(GradebookUserLesson gradebookUserLesson, Double newActivityMark, + Double oldActivityMark) { newActivityMark = newActivityMark == null ? 0 : newActivityMark; - + Double totalMark; if (oldActivityMark == null || gradebookUserLesson.getMark() == null) { totalMark = gradebookDAO.getGradebookUserActivityMarkSum(gradebookUserLesson.getLesson().getLessonId(), - gradebookUserLesson.getLearner().getUserId()); + gradebookUserLesson.getLearner().getUserId()); } else { totalMark = gradebookUserLesson.getMark() - oldActivityMark + newActivityMark; } - + gradebookUserLesson.setMark(totalMark); gradebookDAO.insertOrUpdate(gradebookUserLesson); } @@ -1951,16 +1989,15 @@ return map; } - - + private ICoreLearnerService getLearnerService() { - if (GradebookService.learnerService== null) { - WebApplicationContext ctx = WebApplicationContextUtils - .getWebApplicationContext(SessionManager.getServletContext()); - GradebookService.learnerService = (ICoreLearnerService) ctx.getBean("learnerService"); - } - return GradebookService.learnerService; - } + if (GradebookService.learnerService == null) { + WebApplicationContext ctx = WebApplicationContextUtils + .getWebApplicationContext(SessionManager.getServletContext()); + GradebookService.learnerService = (ICoreLearnerService) ctx.getBean("learnerService"); + } + return GradebookService.learnerService; + } @Override public String getMessage(String key) { Index: lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/service/IGradebookService.java =================================================================== diff -u -r723b5bcbdf0db6b9a4fbeacdc55f7336992ac935 -r8daec7e047f7ea8404c6f16218b63a8e855a15b2 --- lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/service/IGradebookService.java (.../IGradebookService.java) (revision 723b5bcbdf0db6b9a4fbeacdc55f7336992ac935) +++ lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/service/IGradebookService.java (.../IGradebookService.java) (revision 8daec7e047f7ea8404c6f16218b63a8e855a15b2) @@ -20,7 +20,6 @@ * **************************************************************** */ - package org.lamsfoundation.lams.gradebook.service; import java.util.ArrayList; @@ -118,14 +117,15 @@ String sortOrder, String searchString); int getCountUsersByOrganisation(Integer orgId, String searchString); - + /** - * Updates all user marks in specified activity. It recalculates all UserActivityGradebooks and UserLessonGradebooks. + * Updates all user marks in specified activity. It recalculates all UserActivityGradebooks and + * UserLessonGradebooks. * * @param activity */ void recalculateGradebookMarksForActivity(Activity activity); - + /** * Recalculates total marks for all users in a lesson. Then stores that mark in a gradebookUserLesson. Doesn't * affect anyhow gradebookUserActivity objects. If total mark is positive but there is no gradebookUserLesson @@ -272,6 +272,10 @@ */ Activity getActivityById(Long activityID); + void removeLearnerFromLesson(Long lessonId, Integer learnerId); + + void archiveLearnerMarks(Long lessonId, Integer learnerId); + /** * Get a language label * Index: lams_learning/src/java/org/lamsfoundation/lams/learning/service/LearnerServiceProxy.java =================================================================== diff -u -r0ddeb3a1dcf29cbbba6ed0fccbd139f9c31c347f -r8daec7e047f7ea8404c6f16218b63a8e855a15b2 --- lams_learning/src/java/org/lamsfoundation/lams/learning/service/LearnerServiceProxy.java (.../LearnerServiceProxy.java) (revision 0ddeb3a1dcf29cbbba6ed0fccbd139f9c31c347f) +++ lams_learning/src/java/org/lamsfoundation/lams/learning/service/LearnerServiceProxy.java (.../LearnerServiceProxy.java) (revision 8daec7e047f7ea8404c6f16218b63a8e855a15b2) @@ -25,8 +25,10 @@ import javax.servlet.ServletContext; +import org.lamsfoundation.lams.gradebook.service.IGradebookService; import org.lamsfoundation.lams.learning.web.util.ActivityMapping; import org.lamsfoundation.lams.lesson.service.ILessonService; +import org.lamsfoundation.lams.monitoring.service.IMonitoringService; import org.lamsfoundation.lams.tool.service.ILamsToolService; import org.lamsfoundation.lams.usermanagement.service.IUserManagementService; import org.lamsfoundation.lams.util.MessageService; @@ -86,6 +88,14 @@ return (ILessonService) LearnerServiceProxy.getDomainService(servletContext, "lessonService"); } + public static final IGradebookService getGradebookService(ServletContext servletContext) { + return (IGradebookService) LearnerServiceProxy.getDomainService(servletContext, "gradebookService"); + } + + public static final IMonitoringService getMonitoringService(ServletContext servletContext) { + return (IMonitoringService) LearnerServiceProxy.getDomainService(servletContext, "monitoringService"); + } + public static final MessageService getMessageService(ServletContext servletContext) { return (MessageService) LearnerServiceProxy.getDomainService(servletContext, "learningMessageService"); } Index: lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/LearnerAction.java =================================================================== diff -u -rfd1c6c450376476c752e6be5cb6048a2e370bd42 -r8daec7e047f7ea8404c6f16218b63a8e855a15b2 --- lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/LearnerAction.java (.../LearnerAction.java) (revision fd1c6c450376476c752e6be5cb6048a2e370bd42) +++ lams_learning/src/java/org/lamsfoundation/lams/learning/web/action/LearnerAction.java (.../LearnerAction.java) (revision 8daec7e047f7ea8404c6f16218b63a8e855a15b2) @@ -41,6 +41,7 @@ import org.apache.struts.action.ActionMapping; import org.apache.tomcat.util.json.JSONException; import org.apache.tomcat.util.json.JSONObject; +import org.lamsfoundation.lams.gradebook.service.IGradebookService; import org.lamsfoundation.lams.learning.presence.PresenceWebsocketServer; import org.lamsfoundation.lams.learning.service.ICoreLearnerService; import org.lamsfoundation.lams.learning.service.LearnerServiceProxy; @@ -54,6 +55,7 @@ import org.lamsfoundation.lams.lesson.LearnerProgressArchive; import org.lamsfoundation.lams.lesson.Lesson; import org.lamsfoundation.lams.lesson.service.ILessonService; +import org.lamsfoundation.lams.monitoring.service.IMonitoringService; import org.lamsfoundation.lams.tool.ToolSession; import org.lamsfoundation.lams.usermanagement.User; import org.lamsfoundation.lams.usermanagement.dto.UserDTO; @@ -224,14 +226,21 @@ attemptID, attemptedActivities, completedActivities, learnerProgress.getCurrentActivity(), learnerProgress.getLessonComplete(), learnerProgress.getStartDate(), learnerProgress.getFinishDate()); - // remove learner progress - ILessonService lessonService = LearnerServiceProxy.getLessonService(getServlet().getServletContext()); - lessonService.removeLearnerProgress(lessonID, userID); - IUserManagementService userManagementService = LearnerServiceProxy .getUserManagementService(getServlet().getServletContext()); userManagementService.save(learnerProgressArchive); + IGradebookService gradebookService = LearnerServiceProxy.getGradebookService(getServlet().getServletContext()); + gradebookService.archiveLearnerMarks(lessonID, userID); + gradebookService.removeLearnerFromLesson(lessonID, userID); + + IMonitoringService monitoringService = LearnerServiceProxy + .getMonitoringService(getServlet().getServletContext()); + monitoringService.removeLearnerContent(lessonID, userID); + // remove learner progress + ILessonService lessonService = LearnerServiceProxy.getLessonService(getServlet().getServletContext()); + lessonService.removeLearnerProgress(lessonID, userID); + // display Learner interface with updated data return joinLesson(mapping, form, request, response); } Index: lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/IMonitoringService.java =================================================================== diff -u -rae5e9eacbfbf13097410637b6e8990dfb909177a -r8daec7e047f7ea8404c6f16218b63a8e855a15b2 --- lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/IMonitoringService.java (.../IMonitoringService.java) (revision ae5e9eacbfbf13097410637b6e8990dfb909177a) +++ lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/IMonitoringService.java (.../IMonitoringService.java) (revision 8daec7e047f7ea8404c6f16218b63a8e855a15b2) @@ -649,8 +649,11 @@ Long cloneLesson(Long lessonId, Integer creatorId, Boolean addAllStaff, Boolean addAllLearners, String[] staffIds, String[] learnerIds, Organisation group) throws MonitoringServiceException; + + void removeLearnerContent(Long lessonId, Integer learnerId); + /** * Get list of users who completed the given lesson. */ List getUsersCompletedLesson(Long lessonId, Integer limit, Integer offset, boolean orderAscending); -} +} \ No newline at end of file Index: lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/MonitoringService.java =================================================================== diff -u -r75765d2caf035efe57e40cad41337756253d488f -r8daec7e047f7ea8404c6f16218b63a8e855a15b2 --- lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/MonitoringService.java (.../MonitoringService.java) (revision 75765d2caf035efe57e40cad41337756253d488f) +++ lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/service/MonitoringService.java (.../MonitoringService.java) (revision 8daec7e047f7ea8404c6f16218b63a8e855a15b2) @@ -762,14 +762,13 @@ securityService.isLessonMonitor(lessonId, userId, "archive lesson", true); Lesson requestedLesson = lessonDAO.getLesson(new Long(lessonId)); Integer lessonState = requestedLesson.getLessonStateId(); - + // if lesson has 'suspended'('disabled') state - then unsuspend it first so its previous lesson state will be 'started' if (Lesson.SUSPENDED_STATE.equals(lessonState)) { unsuspendLesson(lessonId, userId); } - - if (!Lesson.ARCHIVED_STATE.equals(lessonState) - && !Lesson.REMOVED_STATE.equals(lessonState)) { + + if (!Lesson.ARCHIVED_STATE.equals(lessonState) && !Lesson.REMOVED_STATE.equals(lessonState)) { setLessonState(requestedLesson, Lesson.ARCHIVED_STATE); } } @@ -825,21 +824,21 @@ */ private void revertLessonState(Lesson requestedLesson) { Integer currentStatus = requestedLesson.getLessonStateId(); - + if (requestedLesson.getPreviousLessonStateId() != null) { if (requestedLesson.getPreviousLessonStateId().equals(Lesson.NOT_STARTED_STATE) && requestedLesson.getScheduleStartDate().before(new Date())) { requestedLesson.setLessonStateId(Lesson.STARTED_STATE); - + } else { requestedLesson.setLessonStateId(requestedLesson.getPreviousLessonStateId()); } requestedLesson.setPreviousLessonStateId(null); - + } else { if ((requestedLesson.getStartDateTime() != null) && (requestedLesson.getScheduleStartDate() != null)) { requestedLesson.setLessonStateId(Lesson.STARTED_STATE); - + } else if (requestedLesson.getScheduleStartDate() != null) { if (requestedLesson.getScheduleStartDate().after(new Date())) { requestedLesson.setLessonStateId(Lesson.NOT_STARTED_STATE); @@ -2244,6 +2243,19 @@ } @Override + public void removeLearnerContent(Long lessonId, Integer learnerId) { + User learner = (User) userManagementService.findById(User.class, learnerId); + LearnerProgress learnerProgress = getLearnerProgress(learnerId, lessonId); + Set activities = new HashSet(); + activities.addAll(learnerProgress.getAttemptedActivities().keySet()); + activities.addAll(learnerProgress.getCompletedActivities().keySet()); + boolean resetReadOnly = true; + for (Activity activity : activities) { + resetReadOnly = removeLearnerContent(activity, learner, resetReadOnly); + } + } + + @Override public Long cloneLesson(Long lessonId, Integer creatorId, Boolean addAllStaff, Boolean addAllLearners, String[] staffIds, String[] learnerIds, Organisation group) throws MonitoringServiceException { Lesson newLesson = null; Index: lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/MonitoringAction.java =================================================================== diff -u -r75765d2caf035efe57e40cad41337756253d488f -r8daec7e047f7ea8404c6f16218b63a8e855a15b2 --- lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/MonitoringAction.java (.../MonitoringAction.java) (revision 75765d2caf035efe57e40cad41337756253d488f) +++ lams_monitoring/src/java/org/lamsfoundation/lams/monitoring/web/MonitoringAction.java (.../MonitoringAction.java) (revision 8daec7e047f7ea8404c6f16218b63a8e855a15b2) @@ -210,7 +210,7 @@ * The Struts dispatch method that starts a lesson that has been created beforehand. Most likely, the request to * start lesson should be triggered by the Monitoring This method will delegate to the Spring service bean to * complete all the steps for starting a lesson. - * + * * @throws IOException * @throws ServletException */ @@ -419,7 +419,7 @@ /** * The Struts dispatch method to archive a lesson. - * + * * @throws IOException * @throws ServletException */ @@ -432,13 +432,13 @@ } catch (SecurityException e) { response.sendError(HttpServletResponse.SC_FORBIDDEN, "User is not a monitor in the lesson"); } - + return null; } /** * The Struts dispatch method to "unarchive" a lesson. Returns it back to its previous state. - * + * * @throws IOException * @throws ServletException */ @@ -508,7 +508,7 @@ *

* This action need a lession ID as input. *

- * + * * @throws IOException * @throws ServletException */ @@ -1144,7 +1144,7 @@ String monitorUrl = getMonitoringService().getActivityMonitorURL(lessonId, activityId, contentFolderId, monitorUserId); - if (monitorUrl != null && ! activity.isBranchingActivity()) { + if (monitorUrl != null && !activity.isBranchingActivity()) { // whole activity monitor URL activityJSON.put("url", monitorUrl); }