Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/sakaiproject/sakai
Browse files Browse the repository at this point in the history
  • Loading branch information
steveswinsburg committed Mar 26, 2018
2 parents 8bfd8e8 + a074011 commit bb04355
Show file tree
Hide file tree
Showing 40 changed files with 795 additions and 97 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -896,7 +896,7 @@
# DEFAULT: true (enabled)
# sakai.cookieHttpOnly=false

# Property to disable or alter the SameSite attribute on the cookie
# Property to disable or alter the SameSite attribute on the cookie. Set to empty to disable.
# DEFAULT: lax
# sakai.cookieSameSite=strict

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ public class GradeDefinition {
private String gradeComment;
private int gradeEntryType;
private boolean gradeReleased;
private boolean gradeIgnored;
private Boolean gradeExcluded;

public String getStudentUid() {
return studentUid;
Expand Down Expand Up @@ -114,6 +116,36 @@ public boolean isGradeReleased() {
public void setGradeReleased(boolean gradeReleased) {
this.gradeReleased = gradeReleased;
}



/**
*
* @return true if this grade is being ignored in grading
*/
public boolean isGradeIgnored() {
return gradeIgnored;
}

/**
* true if this grade is being ignored in grading
* @param gradeIgnored
*/
public void setGradeIgnored(boolean gradeIgnored) {
this.gradeIgnored = gradeIgnored;
}

/**
* Returns true if this assignmentGradeRecord is being excluded from grading
* @return gradeExcluded
*/
public Boolean isGradeExcluded() {
return this.gradeExcluded == null ? false : this.gradeExcluded;
}

/**
* Sets the assignmentGradeRecord to be excluded from grading
* @param gradeExcluded
*/
public void setGradeExcluded(Boolean gradeExcluded) {
this.gradeExcluded = gradeExcluded;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,21 @@ public List<String> identifyStudentsWithInvalidGrades(String gradebookUid, Map<S
public void saveGradeAndCommentForStudent(String gradebookUid, Long assignmentId, String studentId, String grade, String comment)
throws InvalidGradeException, GradebookNotFoundException, AssessmentNotFoundException;

/**
* Save a excluded status for a gradebook item. The input score must
* be valid according to the given gradebook's grade entry type.
* @param gradebookUid
* @param assignmentId
* @param studentId
* @param excludedStatus
* @throws InvalidGradeException - if grade is invalid. grade and comment will not be saved
* @throws GradebookNotFoundException
* @throws AssessmentNotFoundException
* @throws SecurityException if current user is not authorized to grade student
*/
public void saveExcludedStatusForStudentGrade(String gradebookUid, Long assignmentId, String studentId, Boolean excludedStatus)
throws InvalidGradeException, GradebookNotFoundException, AssessmentNotFoundException;

/**
* Given a list of GradeDefinitions for students for a given gradebook and gradable object, will save the associated scores and
* comments. Scores must be in a format according to the gradebook's grade entry type (ie points, %, letter).
Expand All @@ -650,7 +665,22 @@ public void saveGradesAndComments(String gradebookUid, Long assignmentId, List<G
throws InvalidGradeException, GradebookNotFoundException, AssessmentNotFoundException;

/**
*
* Given a list of GradeDefinitions for students for a given gradebook and gradable object,
* will save the excluded status for each student's assignment.
* @param gradebookUid
* @param assignmentId
* @param gradeDefList
* @throws InvalidGradeException if any of the grades are not valid - none will be saved
* @throws SecurityException if the user does not have access to a student in the list -
* no grades or comments will be saved for any student
* @throws GradebookNotFoundException
* @throws AssessmentNotFoundException
*/
public void saveExcludedStatusForStudentGrade(String gradebookUid, Long assignmentId, List<GradeDefinition> gradeDefList)
throws InvalidGradeException, GradebookNotFoundException, AssessmentNotFoundException;

/**
*
* @param gradebookUid
* @return the constant representation of the grade entry type (ie points, %, letter grade)
* @throws GradebookNotFoundException if no gradebook exists w/ the given uid
Expand Down Expand Up @@ -913,4 +943,11 @@ Double calculateCategoryScore(Object gradebook, String studentUuid, CategoryDefi
*/
List getGradingEvents(final List<Long> assignmentIds, final Date since);

/**
*
* @param gradebookUid
* @param assignmentId
* @param studentUid
*/
void toggleGradeRecordExcluded(final String gradebookUid, final Long assignmentId, final String studentUid, final boolean isExcluded);
}
Original file line number Diff line number Diff line change
Expand Up @@ -209,11 +209,12 @@ public AssignmentGradeRecord clone()
agr.setPointsEarned(pointsEarned);
agr.setPercentEarned(percentEarned);
agr.setStudentId(studentId);
agr.setExcludedFromGrade(excludedFromGrade);
return agr;
}

public Boolean isExcludedFromGrade() {
return excludedFromGrade;
return this.excludedFromGrade == null ? false : this.excludedFromGrade;
}

public void setExcludedFromGrade(Boolean isExcludedFromGrade) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
import org.sakaiproject.service.gradebook.shared.InvalidGradeException;
import org.sakaiproject.service.gradebook.shared.SortType;
import org.sakaiproject.service.gradebook.shared.StaleObjectModificationException;
import org.sakaiproject.service.gradebook.shared.*;
import org.sakaiproject.service.gradebook.shared.exception.UnmappableCourseGradeOverrideException;
import org.sakaiproject.site.api.Group;
import org.sakaiproject.site.api.Site;
Expand Down Expand Up @@ -1098,7 +1099,7 @@ private double getTotalPointsInternal(final Gradebook gradebook, final List cate
}

if (assign.isCounted() && !assign.getUngraded() && !assign.isRemoved() && countedSet.contains(assign) &&
assign.getPointsPossible() != null && assign.getPointsPossible() > 0 && !gradeRec.getDroppedFromGrade() && !extraCredit) {
assign.getPointsPossible() != null && assign.getPointsPossible() > 0 && !gradeRec.getDroppedFromGrade() && !extraCredit && !gradeRec.isExcludedFromGrade()) {
countedGradeRecs.add(gradeRec);
}
}
Expand Down Expand Up @@ -1218,7 +1219,7 @@ private List getTotalPointsEarnedInternal(final String studentId, final Gradeboo
final Set assignmentsTaken = new HashSet();
for (final AssignmentGradeRecord gradeRec : gradeRecs)
{
if(gradeRec.getPointsEarned() != null && !gradeRec.getPointsEarned().equals("") && !gradeRec.getDroppedFromGrade())
if(gradeRec.getPointsEarned() != null && !gradeRec.getPointsEarned().equals("") && !gradeRec.getDroppedFromGrade() && !gradeRec.isExcludedFromGrade())
{
final GradebookAssignment go = gradeRec.getAssignment();
if (go.isIncludedInCalculations() && countedAssigns.contains(go))
Expand Down Expand Up @@ -1962,6 +1963,8 @@ else if (gradeEntryType == GradebookService.GRADE_TYPE_PERCENTAGE)
gradeDef.setGradeComment(commentText);
}

gradeDef.setGradeExcluded(gradeRecord.isExcludedFromGrade());

return gradeDef;
}

Expand Down Expand Up @@ -2310,6 +2313,123 @@ public Object doInHibernate(Session session) throws HibernateException {
});
}


@Override
public void saveExcludedStatusForStudentGrade(String gradebookUid, Long gradableObjectId, String studentUid, Boolean excludedStatus) {
if (gradebookUid == null || gradableObjectId == null || studentUid == null) {
throw new IllegalArgumentException("Null gradebookUid or gradableObjectId or studentUid passed to saveExcludedStatusForStudentGrade");
}

GradeDefinition gradeDef = new GradeDefinition();
gradeDef.setStudentUid(studentUid);
gradeDef.setGradeExcluded(excludedStatus);

List<GradeDefinition> gradeDefList = new ArrayList<GradeDefinition>();
gradeDefList.add(gradeDef);

saveExcludedStatusForStudentGrade(gradebookUid, gradableObjectId, gradeDefList);
}

@Override
public void saveExcludedStatusForStudentGrade(final String gradebookUid, final Long gradableObjectId, List<GradeDefinition> gradeDefList) {
if (gradebookUid == null || gradableObjectId == null) {
throw new IllegalArgumentException("Null gradebookUid or gradableObjectId passed to saveExcludedStatusForStudentGrade");
}

if (gradeDefList != null) {
Gradebook gradebook;

try {
gradebook = getGradebook(gradebookUid);
} catch (GradebookNotFoundException gnfe) {
throw new GradebookNotFoundException("No gradebook exists with the given gradebookUid: " +
gradebookUid + "Error: " + gnfe.getMessage());
}

GradebookAssignment assignment = (GradebookAssignment) getHibernateTemplate().execute(new HibernateCallback() {
@Override
public Object doInHibernate(Session session) throws HibernateException {
return getAssignmentWithoutStats(gradebookUid, gradableObjectId);
}
});

if (assignment == null) {
throw new AssessmentNotFoundException("No gradebook item exists with gradable object id = " + gradableObjectId);
}

if (!currentUserHasGradingPerm(gradebookUid)) {
log.warn("User attempted to save grades and comments without authorization");
throw new SecurityException("Current user is not authorized to save grades or comments in gradebook " + gradebookUid);
}

// let's identify all of the students being updated first
Map<String, GradeDefinition> studentIdGradeDefMap = new HashMap<String, GradeDefinition>();

for (GradeDefinition gradeDef : gradeDefList) {
studentIdGradeDefMap.put(gradeDef.getStudentUid(), gradeDef);
}

// let's retrieve all of the existing grade recs for the given students
// and assignments
List<AssignmentGradeRecord> allGradeRecs =
getAllAssignmentGradeRecordsForGbItem(gradableObjectId, studentIdGradeDefMap.keySet());

// put in map for easier accessibility
Map<String, AssignmentGradeRecord> studentIdToAgrMap = new HashMap<String, AssignmentGradeRecord>();
if (allGradeRecs != null) {
for (AssignmentGradeRecord rec : allGradeRecs) {
studentIdToAgrMap.put(rec.getStudentId(), rec);
}
}

// these are the records that will need to be updated. iterate through
// everything and then we'll save it all at once
Set<AssignmentGradeRecord> agrToUpdate = new HashSet<AssignmentGradeRecord>();

Set<GradingEvent> eventsToAdd = new HashSet<GradingEvent>();

for (GradeDefinition gradeDef : gradeDefList) {

String studentId = gradeDef.getStudentUid();
boolean excludedStatus = gradeDef.isGradeExcluded();
String graderUid = getAuthn().getUserUid();

// let's see if this agr needs to be updated
AssignmentGradeRecord gradeRec = studentIdToAgrMap.get(studentId);
if (gradeRec != null) {
gradeRec.setExcludedFromGrade(excludedStatus);
agrToUpdate.add(gradeRec);

// we also need to add a GradingEvent
// the event stores the actual input grade, not the converted one
GradingEvent event = new GradingEvent(assignment, graderUid, studentId, gradeDef.getGrade());
eventsToAdd.add(event);
}
}

// now let's save them
try {
for (AssignmentGradeRecord assignmentGradeRecord : agrToUpdate) {
System.out.println("saveorupdate:_ " + assignmentGradeRecord);
getHibernateTemplate().saveOrUpdate(assignmentGradeRecord);
}
for (GradingEvent gradingEvent : eventsToAdd) {
getHibernateTemplate().saveOrUpdate(gradingEvent);
}
} catch (HibernateOptimisticLockingFailureException holfe) {
if (log.isInfoEnabled()){
log.info("An optimistic locking failure occurred while attempting to save scores and comments for gb Item " + gradableObjectId);
}
throw new StaleObjectModificationException(holfe);
} catch (StaleObjectStateException sose) {
if (log.isInfoEnabled()) {
log.info("An optimistic locking failure occurred while attempting to save scores and comments for gb Item " + gradableObjectId);
}
throw new StaleObjectModificationException(sose);
}
}
}

/**
*
* @param gradeEntryType
Expand Down Expand Up @@ -3178,8 +3298,18 @@ public Double calculateCategoryScore(final Object gradebook, final String studen
a.setCategory(c);

//create the AGR
final AssignmentGradeRecord gradeRecord = new AssignmentGradeRecord(a, studentUuid, grade);
AssignmentGradeRecord gradeRecord = new AssignmentGradeRecord(a, studentUuid, grade);

//Add Excluded Status to the AGR
GradebookAssignment assignmentForGradeRecord = getAssignmentWithoutStats(((Gradebook) gradebook).getUid(), assignmentId);
AssignmentGradeRecord tempAGR = getAssignmentGradeRecord(assignmentForGradeRecord, studentUuid);
if(tempAGR != null){
gradeRecord.setExcludedFromGrade(tempAGR.isExcludedFromGrade());
} else {
gradeRecord.setExcludedFromGrade(false);
}

//Add the AGR
gradeRecords.add(gradeRecord);
}

Expand Down Expand Up @@ -3245,6 +3375,7 @@ private Double calculateCategoryScore(final String studentUuid, final Long categ
// Rule 5. the assignment is released to the student (safety check against condition 3)
// Rule 6. the grade is not dropped from the calc
// Rule 7. extra credit items have their grade value counted only. Their total points possible does not apply to the calculations
// Rule 8. the grade has not been excluded from being counted in the final grade
log.debug("categoryId: {}", categoryId);

gradeRecords.removeIf(gradeRecord -> {
Expand All @@ -3257,12 +3388,16 @@ private Double calculateCategoryScore(final String studentUuid, final Long categ
if(categoryId.longValue() != assignment.getCategory().getId().longValue()){
return true;
}

//remove if the assignment/graderecord doesn't meet the criteria for the calculation (rule 2-6)
if(assignment.getPointsPossible() == null || gradeRecord.getPointsEarned() == null || !assignment.isCounted() || !assignment.isReleased() || gradeRecord.getDroppedFromGrade()) {
return true;
}

//remove if the assignment/graderecord is excluded (rule 8)
if(gradeRecord.isExcludedFromGrade() != null){
if (gradeRecord.isExcludedFromGrade()){
return true;
}
}
return false;
});

Expand Down Expand Up @@ -3430,9 +3565,9 @@ public void updateGradebookSettings(final String gradebookUid, final GradebookIn
}
});

//set grade type, but only if sakai.property is false OR sakai.property is true and user is admin
boolean onlyAdminsSetGradeType = ServerConfigurationService.getBoolean("gradebook.settings.gradeEntry.showToNonAdmins", true);
if(!onlyAdminsSetGradeType || (onlyAdminsSetGradeType && SecurityService.isSuperUser())) {
//set grade type, but only if sakai.property is true OR user is admin
boolean gradeTypeAvailForNonAdmins = ServerConfigurationService.getBoolean("gradebook.settings.gradeEntry.showToNonAdmins", true);
if(gradeTypeAvailForNonAdmins || SecurityService.isSuperUser()) {
gradebook.setGrade_type(gbInfo.getGradeType());
}

Expand Down Expand Up @@ -3876,4 +4011,22 @@ private void excludeUncategorisedItemsFromCourseGradeCalculations(final Gradeboo
assignments.forEach(a -> a.setCounted(false));
batchPersistEntities(assignments);
}

/**
* Toggles the excluded status for an assignment grade record
*/
public void toggleGradeRecordExcluded(final String gradebookUid, final Long assignmentId, final String studentUid, final boolean isExcluded){
GradebookAssignment assignment = getAssignmentWithoutStats(gradebookUid, assignmentId);
AssignmentGradeRecord gradeRecord = getAssignmentGradeRecord(assignment, studentUid);
if(gradeRecord != null) {
if (gradeRecord.isExcludedFromGrade() == null) {
gradeRecord.setExcludedFromGrade(true);
} else if (isExcluded) {
gradeRecord.setExcludedFromGrade(false);
} else {
gradeRecord.setExcludedFromGrade(true);
}
getHibernateTemplate().saveOrUpdate(gradeRecord);
}
}
}
Loading

0 comments on commit bb04355

Please sign in to comment.