unchanged: --- assignment-api/api/src/java/org/sakaiproject/assignment/api/AssignmentSubmission.java (revision 133970) +++ assignment-api/api/src/java/org/sakaiproject/assignment/api/AssignmentSubmission.java (revision 133971) @@ -176,6 +176,12 @@ public boolean getGraded(); /** + * Get the grader id (this can be used to track between auto grades or instructor grades) + * + * @return + */ + public String getGradedBy(); + /** * Get whether the grade has been released. * * @return True if the Submissions's grade has been released, false otherwise. unchanged: --- assignment-api/api/src/java/org/sakaiproject/assignment/api/AssignmentSubmissionEdit.java (revision 133970) +++ assignment-api/api/src/java/org/sakaiproject/assignment/api/AssignmentSubmissionEdit.java (revision 133971) @@ -186,6 +186,12 @@ * true if the submission has been graded, false otherwise. */ public void setGraded(boolean graded); + + /** + * Set the grader id (this can be used to track between auto grades or instructor grades) + * @param id + */ + public void setGradedBy(String id); /** * Set the review Score for this assignment diff -u assignment-tool/tool/src/java/org/sakaiproject/assignment/tool/AssignmentAction.java assignment-tool/tool/src/java/org/sakaiproject/assignment/tool/AssignmentAction.java --- assignment-tool/tool/src/java/org/sakaiproject/assignment/tool/AssignmentAction.java (revision 133971) +++ assignment-tool/tool/src/java/org/sakaiproject/assignment/tool/AssignmentAction.java (revision 134081) @@ -5106,6 +5106,18 @@ AssignmentSubmissionEdit sEdit = editSubmission(sId, "grade_submission_option", state); if (sEdit != null) { + //This logic could be done in one line, but would be harder to read, so break it out to make it easier to follow + boolean gradeChanged = false; + if((sEdit.getGrade() == null || "".equals(sEdit.getGrade().trim())) + && (grade == null || "".equals(grade.trim()))){ + //both are null, keep grade changed = false + }else if((sEdit.getGrade() == null || "".equals(sEdit.getGrade().trim()) + || (grade == null || "".equals(grade.trim())))){ + //one is null the other isn't + gradeChanged = true; + }else if(!grade.trim().equals(sEdit.getGrade().trim())){ + gradeChanged = true; + } Assignment a = sEdit.getAssignment(); int typeOfGrade = a.getContent().getTypeOfGrade(); @@ -5113,6 +5125,9 @@ { // no grade input needed for the without-grade version of assignment tool sEdit.setGraded(true); + if(gradeChanged){ + sEdit.setGradedBy(UserDirectoryService.getCurrentUser() == null ? null : UserDirectoryService.getCurrentUser().getId()); + } if ("return".equals(gradeOption) || "release".equals(gradeOption)) { sEdit.setGradeReleased(true); @@ -5122,19 +5137,28 @@ { sEdit.setGrade(""); sEdit.setGraded(false); + if(gradeChanged){ + sEdit.setGradedBy(null); + } sEdit.setGradeReleased(false); } else { sEdit.setGrade(grade); - + if (grade.length() != 0) { sEdit.setGraded(true); + if(gradeChanged){ + sEdit.setGradedBy(UserDirectoryService.getCurrentUser() == null ? null : UserDirectoryService.getCurrentUser().getId()); + } } else { sEdit.setGraded(false); + if(gradeChanged){ + sEdit.setGradedBy(null); + } } } @@ -5151,6 +5175,9 @@ { sEdit.setGradeReleased(true); sEdit.setGraded(true); + if(gradeChanged){ + sEdit.setGradedBy(UserDirectoryService.getCurrentUser() == null ? null : UserDirectoryService.getCurrentUser().getId()); + } // clear the returned flag sEdit.setReturned(false); sEdit.setTimeReturned(null); @@ -5159,6 +5186,9 @@ { sEdit.setGradeReleased(true); sEdit.setGraded(true); + if(gradeChanged){ + sEdit.setGradedBy(UserDirectoryService.getCurrentUser() == null ? null : UserDirectoryService.getCurrentUser().getId()); + } sEdit.setReturned(true); sEdit.setTimeReturned(TimeService.newTime()); sEdit.setHonorPledgeFlag(Boolean.FALSE.booleanValue()); @@ -5532,6 +5562,7 @@ // clear the current grade and make the submission ungraded sEdit.setGraded(false); + sEdit.setGradedBy(null); sEdit.setGrade(""); sEdit.setGradeReleased(false); @@ -7091,6 +7122,7 @@ // set the grade to be empty for now sEdit.setGrade(""); sEdit.setGraded(false); + sEdit.setGradedBy(null); sEdit.setGradeReleased(false); sEdit.setReturned(false); } @@ -13620,6 +13652,7 @@ { sEdit.setGrade(grade); sEdit.setGraded(true); + sEdit.setGradedBy(UserDirectoryService.getCurrentUser() == null ? null : UserDirectoryService.getCurrentUser().getId()); AssignmentService.commitEdit(sEdit); } } @@ -13709,6 +13742,7 @@ sEdit.setGrade(grade); sEdit.setSubmitted(true); sEdit.setGraded(true); + sEdit.setGradedBy(UserDirectoryService.getCurrentUser() == null ? null : UserDirectoryService.getCurrentUser().getId()); AssignmentService.commitEdit(sEdit); } } @@ -13719,6 +13753,7 @@ if (sEdit != null) { sEdit.setGraded(true); + sEdit.setGradedBy(UserDirectoryService.getCurrentUser() == null ? null : UserDirectoryService.getCurrentUser().getId()); AssignmentService.commitEdit(sEdit); } } @@ -14425,8 +14460,10 @@ // set grade String grade = StringUtils.trimToNull(w.getGrade()); sEdit.setGrade(grade); - if (grade != null && !grade.equals(rb.getString("gen.nograd")) && !"ungraded".equals(grade)) + if (grade != null && !grade.equals(rb.getString("gen.nograd")) && !"ungraded".equals(grade)){ sEdit.setGraded(true); + sEdit.setGradedBy(UserDirectoryService.getCurrentUser() == null ? null : UserDirectoryService.getCurrentUser().getId()); + } } // release or not unchanged: --- assignment-impl/impl/src/java/org/sakaiproject/assignment/impl/BaseAssignmentService.java (revision 133970) +++ assignment-impl/impl/src/java/org/sakaiproject/assignment/impl/BaseAssignmentService.java (revision 133971) @@ -10192,6 +10192,8 @@ protected boolean m_returned; protected boolean m_graded; + + protected String m_gradedBy; protected boolean m_gradeReleased; @@ -10449,6 +10451,7 @@ m_submitted = false; m_returned = false; m_graded = false; + m_gradedBy = null; m_gradeReleased = false; m_submittedText = ""; m_feedbackComment = ""; @@ -10533,6 +10536,7 @@ m_submitted = getBool(el.getAttribute("submitted")); m_returned = getBool(el.getAttribute("returned")); m_graded = getBool(el.getAttribute("graded")); + m_gradedBy = el.getAttribute("gradedBy"); m_gradeReleased = getBool(el.getAttribute("gradereleased")); m_honorPledgeFlag = getBool(el.getAttribute("pledgeflag")); m_hideDueDate = getBool(el.getAttribute("hideduedate")); @@ -10864,6 +10868,7 @@ m_submitted = getBool(attributes.getValue("submitted")); m_returned = getBool(attributes.getValue("returned")); m_graded = getBool(attributes.getValue("graded")); + m_gradedBy = attributes.getValue("gradedBy"); m_gradeReleased = getBool(attributes.getValue("gradereleased")); m_honorPledgeFlag = getBool(attributes.getValue("pledgeflag")); m_hideDueDate = getBool(attributes.getValue("hideduedate")); @@ -11038,6 +11043,7 @@ submission.setAttribute("submitted", getBoolString(m_submitted)); submission.setAttribute("returned", getBoolString(m_returned)); submission.setAttribute("graded", getBoolString(m_graded)); + submission.setAttribute("gradedBy", m_gradedBy == null ? "" : m_gradedBy); submission.setAttribute("gradereleased", getBoolString(m_gradeReleased)); submission.setAttribute("pledgeflag", getBoolString(m_honorPledgeFlag)); submission.setAttribute("hideduedate", getBoolString(m_hideDueDate)); @@ -11166,6 +11172,7 @@ m_feedbackText = submission.getFeedbackText(); m_returned = submission.getReturned(); m_graded = submission.getGraded(); + m_gradedBy = submission.getGradedBy(); m_gradeReleased = submission.getGradeReleased(); m_honorPledgeFlag = submission.getHonorPledgeFlag(); m_properties = new BaseResourcePropertiesEdit(); @@ -11746,6 +11753,13 @@ { return m_graded; } + + /** + * Get the grader id (used to determine auto or instructor grading) + */ + public String getGradedBy(){ + return m_gradedBy; + } /** * Get the time on which the graded submission was returned; null means the response is not yet graded. @@ -12280,6 +12294,13 @@ { m_graded = value; } + + /** + * set the grader id (used to distinguish between auto and instructor grading) + */ + public void setGradedBy(String gradedBy){ + m_gradedBy = gradedBy; + } /** * Set the time at which the graded Submission was returned; setting it to null means it is not yet graded. unchanged: --- assignment-impl/impl/src/java/org/sakaiproject/assignment/impl/conversion/impl/AssignmentSubmissionAccess.java (revision 133970) +++ assignment-impl/impl/src/java/org/sakaiproject/assignment/impl/conversion/impl/AssignmentSubmissionAccess.java (revision 133971) @@ -82,6 +82,8 @@ protected String feedbacktext_html = null; protected String graded = null; + + protected String gradedBy = null; protected String gradereleased = null; @@ -149,6 +151,7 @@ submission.setAttribute("submitterid", this.submitterid); submission.setAttribute("returned",this.returned); submission.setAttribute("graded", this.graded); + submission.setAttribute("gradedBy", this.gradedBy); submission.setAttribute("gradereleased", this.gradereleased); submission.setAttribute("pledgeflag", this.pledgeflag); @@ -418,6 +421,7 @@ setGrade(grade); setGraded(StringUtil.trimToNull(attributes.getValue("graded"))); + setGradedBy(StringUtil.trimToNull(attributes.getValue("gradedBy"))); setGradereleased(StringUtil.trimToNull(attributes.getValue("gradereleased"))); setLastmod(StringUtil.trimToNull(attributes.getValue("lastmod"))); String numberoffeedbackattachments = StringUtil.trimToNull(attributes.getValue("numberoffeedbackattachments")); @@ -699,6 +703,9 @@ return graded; } + public String getGradedBy(){ + return gradedBy; + } /* (non-Javadoc) * @see org.sakaiproject.assignment.impl.conversion.impl.SerializableSubmissionAccess#setGraded(java.lang.String) @@ -708,6 +715,9 @@ this.graded = graded; } + public void setGradedBy(String gradedBy){ + this.gradedBy = gradedBy; + } /* (non-Javadoc) * @see org.sakaiproject.assignment.impl.conversion.impl.SerializableSubmissionAccess#getGradereleased() unchanged: --- assignment-impl/impl/src/java/org/sakaiproject/assignment/impl/AssignmentPeerAssessmentServiceImpl.java (revision 133970) +++ assignment-impl/impl/src/java/org/sakaiproject/assignment/impl/AssignmentPeerAssessmentServiceImpl.java (revision 133971) @@ -371,58 +371,71 @@ } public void updateScore(String submissionId){ - List items = getPeerAssessmentItems(submissionId); - if(items != null){ - //scores are stored w/o decimal points, so a score of 3.4 is stored as 34 in the DB - //add all the scores together and divide it by the number of scores added. Then round. - Integer totalScore = 0; - int denominator = 0; - for(PeerAssessmentItem item : items){ - if(!item.isRemoved() && item.getScore() != null){ - totalScore += item.getScore(); - denominator++; + SecurityAdvisor sa = new SecurityAdvisor() { + public SecurityAdvice isAllowed(String userId, String function, String reference) + { + if(AssignmentService.SECURE_GRADE_ASSIGNMENT_SUBMISSION.equals(function) + || AssignmentService.SECURE_UPDATE_ASSIGNMENT.equals(function) + || AssignmentService.SECURE_ACCESS_ASSIGNMENT.equals(function) + || AssignmentService.SECURE_ACCESS_ASSIGNMENT_SUBMISSION.equals(function)){ + return SecurityAdvice.ALLOWED; + }else{ + return SecurityAdvice.PASS; } } - if(denominator > 0){ - totalScore = Math.round(totalScore/denominator); - }else{ - totalScore = null; + }; + try { + securityService.pushAdvisor(sa); + //first check that submission exists and that it can be graded/override score + AssignmentSubmission submission = assignmentService.getSubmission(submissionId); + //only override grades that have never been graded or was last graded by this service + //this prevents this service from overriding instructor set grades, which take precedent. + if(submission != null && + (submission.getGraded() == false || submission.getGradedBy() == null || "".equals(submission.getGradedBy().trim()) + || AssignmentPeerAssessmentService.class.getName().equals(submission.getGradedBy().trim()))){ + List items = getPeerAssessmentItems(submissionId); + if(items != null){ + //scores are stored w/o decimal points, so a score of 3.4 is stored as 34 in the DB + //add all the scores together and divide it by the number of scores added. Then round. + Integer totalScore = 0; + int denominator = 0; + for(PeerAssessmentItem item : items){ + if(!item.isRemoved() && item.getScore() != null){ + totalScore += item.getScore(); + denominator++; + } + } + if(denominator > 0){ + totalScore = Math.round(totalScore/denominator); + }else{ + totalScore = null; + } + AssignmentSubmissionEdit edit = assignmentService.editSubmission(submissionId); + String totleScoreStr = null; + if(totalScore != null){ + totleScoreStr = totalScore.toString(); + } + edit.setGrade(totleScoreStr); + edit.setGraded(true); + edit.setGradedBy(AssignmentPeerAssessmentService.class.getName()); + edit.setGradeReleased(false); + assignmentService.commitEdit(edit); + } } - - SecurityAdvisor sa = new SecurityAdvisor() { - public SecurityAdvice isAllowed(String userId, String function, String reference) - { - if(AssignmentService.SECURE_GRADE_ASSIGNMENT_SUBMISSION.equals(function) - || AssignmentService.SECURE_UPDATE_ASSIGNMENT.equals(function)){ - return SecurityAdvice.ALLOWED; - }else{ - return SecurityAdvice.PASS; - } - } - }; - try { - securityService.pushAdvisor(sa); - AssignmentSubmissionEdit edit = assignmentService.editSubmission(submissionId); - String totleScoreStr = null; - if(totalScore != null){ - totleScoreStr = totalScore.toString(); - } - edit.setGrade(totleScoreStr); - edit.setGraded(true); - edit.setGradeReleased(false); - assignmentService.commitEdit(edit); - } catch (IdUnusedException e) { - log.error(e.getMessage(), e); - } catch (InUseException e) { - log.error(e.getMessage(), e); - } catch (PermissionException e) { - log.error(e.getMessage(), e); - }finally - { - // remove advisor - securityService.popAdvisor(sa); - } + } catch (IdUnusedException e) { + log.error(e.getMessage(), e); + } catch (InUseException e) { + log.error(e.getMessage(), e); + } catch (PermissionException e) { + log.error(e.getMessage(), e); + }finally + { + // remove advisor + if(sa != null){ + securityService.popAdvisor(sa); + } } + } public void setScheduledInvocationManager(