From af12e6b9c04d64457ea6be7742a6e2606c68f13e Mon Sep 17 00:00:00 2001 From: kunaljaykam Date: Wed, 19 Nov 2025 23:41:22 +0530 Subject: [PATCH 1/3] SAK-52173 SCORM Import from site does not retain GB setting --- .../service/impl/ScormEntityProducer.java | 43 +++++++++++++++++++ .../service/impl/spring-scorm-services.xml | 1 + 2 files changed, 44 insertions(+) diff --git a/scormplayer/scorm-impl/service/src/java/org/sakaiproject/scorm/service/impl/ScormEntityProducer.java b/scormplayer/scorm-impl/service/src/java/org/sakaiproject/scorm/service/impl/ScormEntityProducer.java index 1dc0af2bc6be..39c28fbff28a 100644 --- a/scormplayer/scorm-impl/service/src/java/org/sakaiproject/scorm/service/impl/ScormEntityProducer.java +++ b/scormplayer/scorm-impl/service/src/java/org/sakaiproject/scorm/service/impl/ScormEntityProducer.java @@ -55,6 +55,7 @@ import org.sakaiproject.exception.PermissionException; import org.sakaiproject.exception.ServerOverloadException; import org.sakaiproject.exception.TypeException; +import org.sakaiproject.grading.api.GradingService; import org.sakaiproject.scorm.api.ScormConstants; import org.sakaiproject.scorm.dao.api.ContentPackageDao; import org.sakaiproject.scorm.dao.api.ContentPackageManifestDao; @@ -95,6 +96,10 @@ public class ScormEntityProducer implements EntityProducer, EntityTransferrer, H private SecurityService securityService; private SessionManager sessionManager; + protected GradingService gradingService() { + return null; // Overridden by Spring lookup-method + } + public void init() { try { entityManager.registerEntityProducer(this, REFERENCE_ROOT); @@ -177,6 +182,9 @@ public Map transferCopyEntities(String fromContext, String toCon recordReferenceMapping(transversalMap, fromContext, toContext, source, copy); updateCollectionDisplayName(newResourceId, copy.getTitle()); + + // Copy gradebook settings for SCOs + copyGradebookSettings(fromContext, toContext, source, copy); } catch (Exception e) { log.error("Failed to copy SCORM package {} from {} to {}", source.getContentPackageId(), fromContext, toContext, e); } @@ -347,6 +355,41 @@ private void updateCollectionDisplayName(String resourceId, String title) { } } + private void copyGradebookSettings(String fromContext, String toContext, ContentPackage source, ContentPackage copy) { + GradingService gs = gradingService(); + if (gs == null) { + return; + } + + ContentPackageManifest manifest = contentPackageManifestDao.load(copy.getManifestId()); + if (manifest == null || manifest.getLaunchData() == null) { + return; + } + + for (LaunchData launchData : manifest.getLaunchData()) { + if (!"sco".equalsIgnoreCase(launchData.getSCORMType())) { + continue; + } + + String itemIdentifier = launchData.getItemIdentifier(); + String sourceExternalId = source.getContentPackageId() + ":" + itemIdentifier; + String destExternalId = copy.getContentPackageId() + ":" + itemIdentifier; + + // Only copy if source had gradebook sync enabled + if (!gs.isExternalAssignmentDefined(fromContext, sourceExternalId)) { + continue; + } + + try { + String title = StringUtils.defaultIfBlank(copy.getTitle(), launchData.getItemTitle()); + gs.addExternalAssessment(toContext, toContext, destExternalId, null, title, + 100.0, copy.getDueOn(), ScormConstants.SCORM_DFLT_TOOL_NAME, null, false, null, null); + } catch (Exception e) { + log.debug("Could not copy gradebook item for SCO {}: {}", itemIdentifier, e.getMessage()); + } + } + } + private T runWithAdvisor(Callable task) throws Exception { SecurityAdvisor advisor = createScormContentAdvisor(); securityService.pushAdvisor(advisor); diff --git a/scormplayer/scorm-impl/service/src/java/org/sakaiproject/scorm/service/impl/spring-scorm-services.xml b/scormplayer/scorm-impl/service/src/java/org/sakaiproject/scorm/service/impl/spring-scorm-services.xml index 06b42b03a3d8..95355fb29df9 100644 --- a/scormplayer/scorm-impl/service/src/java/org/sakaiproject/scorm/service/impl/spring-scorm-services.xml +++ b/scormplayer/scorm-impl/service/src/java/org/sakaiproject/scorm/service/impl/spring-scorm-services.xml @@ -99,6 +99,7 @@ + From a36856e3221e4566555eeefab4911cf989fd5ccf Mon Sep 17 00:00:00 2001 From: kunaljaykam Date: Sat, 29 Nov 2025 21:34:36 +0530 Subject: [PATCH 2/3] improve --- .../scorm/service/impl/ScormEntityProducer.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/scormplayer/scorm-impl/service/src/java/org/sakaiproject/scorm/service/impl/ScormEntityProducer.java b/scormplayer/scorm-impl/service/src/java/org/sakaiproject/scorm/service/impl/ScormEntityProducer.java index 39c28fbff28a..e857d3654f1d 100644 --- a/scormplayer/scorm-impl/service/src/java/org/sakaiproject/scorm/service/impl/ScormEntityProducer.java +++ b/scormplayer/scorm-impl/service/src/java/org/sakaiproject/scorm/service/impl/ScormEntityProducer.java @@ -55,6 +55,7 @@ import org.sakaiproject.exception.PermissionException; import org.sakaiproject.exception.ServerOverloadException; import org.sakaiproject.exception.TypeException; +import org.sakaiproject.grading.api.Assignment; import org.sakaiproject.grading.api.GradingService; import org.sakaiproject.scorm.api.ScormConstants; import org.sakaiproject.scorm.dao.api.ContentPackageDao; @@ -381,9 +382,16 @@ private void copyGradebookSettings(String fromContext, String toContext, Content } try { - String title = StringUtils.defaultIfBlank(copy.getTitle(), launchData.getItemTitle()); - gs.addExternalAssessment(toContext, toContext, destExternalId, null, title, - 100.0, copy.getDueOn(), ScormConstants.SCORM_DFLT_TOOL_NAME, null, false, null, null); + // Get the source gradebook assignment to copy all its properties + Assignment sourceAssignment = gs.getExternalAssignment(fromContext, sourceExternalId); + if (sourceAssignment == null) { + log.debug("Skipping gradebook copy for SCO {} - source assignment not found", itemIdentifier); + continue; + } + + gs.addExternalAssessment(toContext, toContext, destExternalId, null, sourceAssignment.getName(), + sourceAssignment.getPoints(), copy.getDueOn(), ScormConstants.SCORM_DFLT_TOOL_NAME, + null, false, sourceAssignment.getCategoryId(), null); } catch (Exception e) { log.debug("Could not copy gradebook item for SCO {}: {}", itemIdentifier, e.getMessage()); } From 6d21833db2a368123fd09ace361e25296e2f9231 Mon Sep 17 00:00:00 2001 From: kunaljaykam Date: Tue, 2 Dec 2025 21:08:01 +0530 Subject: [PATCH 3/3] add coderabbit suggestion --- .../sakaiproject/scorm/service/impl/ScormEntityProducer.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scormplayer/scorm-impl/service/src/java/org/sakaiproject/scorm/service/impl/ScormEntityProducer.java b/scormplayer/scorm-impl/service/src/java/org/sakaiproject/scorm/service/impl/ScormEntityProducer.java index e857d3654f1d..4bd81e49e046 100644 --- a/scormplayer/scorm-impl/service/src/java/org/sakaiproject/scorm/service/impl/ScormEntityProducer.java +++ b/scormplayer/scorm-impl/service/src/java/org/sakaiproject/scorm/service/impl/ScormEntityProducer.java @@ -362,6 +362,10 @@ private void copyGradebookSettings(String fromContext, String toContext, Content return; } + if (copy.getManifestId() == null) { + return; + } + ContentPackageManifest manifest = contentPackageManifestDao.load(copy.getManifestId()); if (manifest == null || manifest.getLaunchData() == null) { return;