Skip to content

SAK-51218 Assignments ui shows correct state of GB integration after import #13550

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@
import org.sakaiproject.util.api.FormattedText;
import org.sakaiproject.util.api.LinkMigrationHelper;
import org.sakaiproject.util.comparator.UserSortNameComparator;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
Expand Down Expand Up @@ -989,7 +990,6 @@ public String getTimeSpent(AssignmentSubmission submission) {
return submission.getSubmitters().stream().findAny().get().getTimeSpent();
}

@Transactional
private Assignment mergeAssignment(final String siteId, final Element element, final StringBuilder results, Set<String> assignmentTitles, MergeConfig mcx) throws PermissionException {

if (!allowAddAssignment(siteId)) {
Expand Down Expand Up @@ -4455,89 +4455,111 @@ public Map<String, String> transferCopyEntities(String fromContext, String toCon
}

// gradebook-integration link
String associatedGradebookAssignment = nProperties.get(PROP_ASSIGNMENT_ASSOCIATE_GRADEBOOK_ASSIGNMENT);
String nAssignmentRef = AssignmentReferenceReckoner.reckoner().assignment(nAssignment).reckon().getReference();
if (StringUtils.isBlank(associatedGradebookAssignment)) {
// if the association property is empty then set gradebook integration to not integrated
nProperties.put(NEW_ASSIGNMENT_ADD_TO_GRADEBOOK, GRADEBOOK_INTEGRATION_NO);
} else {
// see if the old assignment's associated gradebook item is an internal gradebook entry or externally defined
boolean isExternalAssignmentDefined = gradingService.isExternalAssignmentDefined(oAssignment.getContext(), associatedGradebookAssignment);
String siteId = nAssignment.getContext();
String gradebookUid = siteId;
if (isExternalAssignmentDefined) {
if (!nAssignment.getDraft()) {
// This assignment has been published, make sure the associated gb item is available
org.sakaiproject.grading.api.Assignment gbAssignment
= gradingService.getAssignmentByNameOrId(gradebookUid, siteId, associatedGradebookAssignment);

if (gbAssignment == null) {
// The associated gb item hasn't been created here yet.
gbAssignment = gradingService.getExternalAssignment(
oAssignment.getContext(), associatedGradebookAssignment);

Optional<Long> categoryId
= createCategoryForGbAssignmentIfNecessary(
gbAssignment, oAssignment.getContext(), nAssignment.getContext());

gradingService.addExternalAssessment(gradebookUid, siteId
, nAssignmentRef, null, nAssignment.getTitle()
, nAssignment.getMaxGradePoint() / (double) nAssignment.getScaleFactor()
, Date.from(nAssignment.getDueDate()), this.getToolId()
, null, false, categoryId.isPresent() ? categoryId.get() : null, null);
final String associatedGradebookAssignment = nProperties.get(PROP_ASSIGNMENT_ASSOCIATE_GRADEBOOK_ASSIGNMENT);
// always clear the old assignments gradebook link
nProperties.remove(PROP_ASSIGNMENT_ASSOCIATE_GRADEBOOK_ASSIGNMENT);
final String assignmentAddToGradebookChoice = nProperties.get(NEW_ASSIGNMENT_ADD_TO_GRADEBOOK);
final String nAssignmentRef = AssignmentReferenceReckoner.reckoner().assignment(nAssignment).reckon().getReference();

switch (assignmentAddToGradebookChoice) {
case GRADEBOOK_INTEGRATION_ADD, GRADEBOOK_INTEGRATION_ASSOCIATE -> {
org.sakaiproject.grading.api.Assignment originalGBAssignment = null;
org.sakaiproject.grading.api.Assignment newGbAssignment = null;

boolean isOriginalAssignmentExternal = gradingService.isExternalAssignmentDefined(oAssignment.getContext(), associatedGradebookAssignment);
if (!isOriginalAssignmentExternal) {
// load the assignment for internal gb link
try {
originalGBAssignment = gradingService.getAssignmentByNameOrId(
oAssignment.getContext(),
oAssignment.getContext(),
associatedGradebookAssignment);
} catch (AssessmentNotFoundException anfe) {
// strange if couldn't load the original gb assignment
log.debug("Original assignment {} not found in gradebook for site {}", associatedGradebookAssignment, nAssignment.getContext(), anfe);
}

nProperties.put(PROP_ASSIGNMENT_ASSOCIATE_GRADEBOOK_ASSIGNMENT, nAssignmentRef);
if (originalGBAssignment != null) {
try {
// because the the association points to the original gb (ID) we can only look up by it's Name
newGbAssignment = gradingService.getAssignmentByNameOrId(
nAssignment.getContext(),
nAssignment.getContext(),
originalGBAssignment.getName());
} catch (AssessmentNotFoundException anfe) {
// couldn't load the new gb item so the user didn't import gradebook items
log.debug("Assignment {} not found in gradebook for site {}", originalGBAssignment.getName(), nAssignment.getContext(), anfe);
}
}
} else {
// if this is an external defined (came from assignment)
// mark the link as "add to gradebook" for the new imported assignment, since the assignment is still of draft state
// later when user posts the assignment, the corresponding assignment will be created in gradebook.
nProperties.remove(PROP_ASSIGNMENT_ASSOCIATE_GRADEBOOK_ASSIGNMENT);
nProperties.put(NEW_ASSIGNMENT_ADD_TO_GRADEBOOK, GRADEBOOK_INTEGRATION_NO);
originalGBAssignment = gradingService.getExternalAssignment(oAssignment.getContext(), associatedGradebookAssignment);
}
} else {
// If this is an internal gradebook item then it should be associated with the assignment
try {
org.sakaiproject.grading.api.Assignment gbAssignment
= gradingService.getAssignmentByNameOrId(
gradebookUid, siteId, associatedGradebookAssignment);

if (gbAssignment == null) {
if (!nAssignment.getDraft()) {
// The target gb item doesn't exist and we're in publish mode, so copy it over.
gbAssignment = gradingService.getAssignmentByNameOrId(
gradebookUid, siteId, associatedGradebookAssignment);
gbAssignment.setId(null);

Optional<Long> categoryId = createCategoryForGbAssignmentIfNecessary(
gbAssignment, oAssignment.getContext(), nAssignment.getContext());

if (categoryId.isPresent()) {
gbAssignment.setCategoryId(categoryId.get());
}

gradingService.addAssignment(gradebookUid, siteId, gbAssignment);
nProperties.put(PROP_ASSIGNMENT_ASSOCIATE_GRADEBOOK_ASSIGNMENT, gbAssignment.getId().toString());
} else {
nProperties.put(NEW_ASSIGNMENT_ADD_TO_GRADEBOOK, GRADEBOOK_INTEGRATION_NO);
nProperties.remove(PROP_ASSIGNMENT_ASSOCIATE_GRADEBOOK_ASSIGNMENT);
}
if (nAssignment.getDraft()) {
// assignment is in the draft state
if (isOriginalAssignmentExternal) {
// if this is an external defined assignments will create when publishing
nProperties.remove(PROP_ASSIGNMENT_ASSOCIATE_GRADEBOOK_ASSIGNMENT);
nProperties.put(NEW_ASSIGNMENT_ADD_TO_GRADEBOOK, GRADEBOOK_INTEGRATION_ADD);
} else {
if (!nAssignment.getDraft()) {
// migrate to gradebook assignment id (vs title)
if (newGbAssignment != null) {
nProperties.put(PROP_ASSIGNMENT_ASSOCIATE_GRADEBOOK_ASSIGNMENT, newGbAssignment.getId().toString());
nProperties.put(NEW_ASSIGNMENT_ADD_TO_GRADEBOOK, GRADEBOOK_INTEGRATION_ASSOCIATE);
associatedGradebookAssignment = gbAssignment.getId().toString();
nProperties.put(PROP_ASSIGNMENT_ASSOCIATE_GRADEBOOK_ASSIGNMENT, associatedGradebookAssignment );
} else {
nProperties.remove(PROP_ASSIGNMENT_ASSOCIATE_GRADEBOOK_ASSIGNMENT);
nProperties.put(NEW_ASSIGNMENT_ADD_TO_GRADEBOOK, GRADEBOOK_INTEGRATION_NO);
}
}
} else {
// not in draft state
if (isOriginalAssignmentExternal) {
// external gradebook items are created by assignments and linked using the assignments reference
Long categoryId = null;
if (originalGBAssignment != null) {
categoryId = createCategoryForGbAssignmentIfNecessary(originalGBAssignment, oAssignment.getContext(), nAssignment.getContext())
.orElse(null);
}

gradingService.addExternalAssessment(
nAssignment.getContext(),
nAssignment.getContext(),
nAssignmentRef,
null,
nAssignment.getTitle(),
nAssignment.getMaxGradePoint() / (double) nAssignment.getScaleFactor(),
Date.from(nAssignment.getDueDate()),
this.getToolId(),
null,
false,
categoryId,
null);
nProperties.put(PROP_ASSIGNMENT_ASSOCIATE_GRADEBOOK_ASSIGNMENT, nAssignmentRef);
nProperties.put(NEW_ASSIGNMENT_ADD_TO_GRADEBOOK, GRADEBOOK_INTEGRATION_ASSOCIATE);
} else {
// internal gradebook items should have already been created and are linked using a Long or a title
if (newGbAssignment == null) {
// no existing gb item, only thing to do set assignment as draft and clear the link
nProperties.remove(PROP_ASSIGNMENT_ASSOCIATE_GRADEBOOK_ASSIGNMENT);
// change the integration to no so that they my choose
nProperties.put(NEW_ASSIGNMENT_ADD_TO_GRADEBOOK, GRADEBOOK_INTEGRATION_NO);
} else {
// gb item found just link it
nProperties.put(PROP_ASSIGNMENT_ASSOCIATE_GRADEBOOK_ASSIGNMENT, newGbAssignment.getId().toString());
nProperties.put(NEW_ASSIGNMENT_ADD_TO_GRADEBOOK, GRADEBOOK_INTEGRATION_ASSOCIATE);
}
}
} catch (AssessmentNotFoundException anfe) {
log.info("While importing assignment {} the associated gradebook item {} was missing, " +
"switching assignment linkage to added by assignments", nAssignmentId, associatedGradebookAssignment);
}
}
case GRADEBOOK_INTEGRATION_NO -> {
// disables gradebook integration
nProperties.put(NEW_ASSIGNMENT_ADD_TO_GRADEBOOK, GRADEBOOK_INTEGRATION_NO);
nProperties.remove(PROP_ASSIGNMENT_ASSOCIATE_GRADEBOOK_ASSIGNMENT);
}
default -> {
// in a future jdk this can be combined with previous
nProperties.put(NEW_ASSIGNMENT_ADD_TO_GRADEBOOK, GRADEBOOK_INTEGRATION_NO);
nProperties.remove(PROP_ASSIGNMENT_ASSOCIATE_GRADEBOOK_ASSIGNMENT);
}
}

updateAssignment(nAssignment);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ This section contains the options for grading this assignment, including rubrics
#if ($isGradebookGroupEnabled)
<sakai-multi-gradebook id="gb-selector" site-id='$siteId' selected-temp="$!selectedGradebook" app-name="sakai.assignment.grades" ></sakai-multi-gradebook>
<input type="hidden" id="gb_selector" name="$!gb_selector" value="$!selectedGradebook" />
#elseif (!$isGradebookGroupEnabled)
#else
<select name="$!name_AssociateGradebookAssignment" id="gradebookItemSelect">
<option value="">$tlang.getString("grading.select")</option>
#set($gAssignmentSet = $!gradebookAssignmentsLabel.keySet())
Expand Down
Loading