MOBILE-4362 scorm: Fix grade calculation when using LASTATTEMPT

The app always used the last attempt, but LMS uses the last attempt that has at least 1 SCO with completed or passed status
main
Dani Palou 2023-10-05 17:00:04 +02:00
parent 8af557bbc6
commit 77bd638fb1
2 changed files with 34 additions and 24 deletions

View File

@ -301,12 +301,7 @@ export class AddonModScormIndexComponent extends CoreCourseModuleMainActivityCom
return;
}
const grade = await AddonModScorm.getAttemptGrade(this.scorm, attempt, offline);
attempts[attempt] = {
num: attempt,
grade: grade,
};
attempts[attempt] = await AddonModScorm.getAttemptGrade(this.scorm, attempt, offline);
}
/**
@ -344,10 +339,10 @@ export class AddonModScormIndexComponent extends CoreCourseModuleMainActivityCom
// Now format the grades.
this.onlineAttempts.forEach((attempt) => {
attempt.gradeFormatted = AddonModScorm.formatGrade(scorm, attempt.grade);
attempt.gradeFormatted = AddonModScorm.formatGrade(scorm, attempt.score);
});
this.offlineAttempts.forEach((attempt) => {
attempt.gradeFormatted = AddonModScorm.formatGrade(scorm, attempt.grade);
attempt.gradeFormatted = AddonModScorm.formatGrade(scorm, attempt.score);
});
this.gradeFormatted = AddonModScorm.formatGrade(scorm, this.grade);

View File

@ -119,17 +119,22 @@ export class AddonModScormProvider {
switch (scorm.whatgrade) {
case AddonModScormProvider.FIRSTATTEMPT:
return onlineAttempts[1] ? onlineAttempts[1].grade : -1;
return onlineAttempts[1] ? onlineAttempts[1].score : -1;
case AddonModScormProvider.LASTATTEMPT: {
// Search the last attempt number.
let max = 0;
Object.keys(onlineAttempts).forEach((attemptNumber) => {
max = Math.max(Number(attemptNumber), max);
});
// Search the last completed attempt number.
let lastCompleted = 0;
for (const attemptNumber in onlineAttempts) {
if (onlineAttempts[attemptNumber].hasCompletedPassedSCO) {
lastCompleted = Math.max(onlineAttempts[attemptNumber].num, lastCompleted);
}
}
if (max > 0) {
return onlineAttempts[max].grade;
if (lastCompleted > 0) {
return onlineAttempts[lastCompleted].score;
} else if (onlineAttempts[1]) {
// If no completed attempt found, use the first attempt for consistency with LMS.
return onlineAttempts[1].score;
}
return -1;
@ -139,7 +144,7 @@ export class AddonModScormProvider {
// Search the highest grade.
let grade = 0;
for (const attemptNumber in onlineAttempts) {
grade = Math.max(onlineAttempts[attemptNumber].grade, grade);
grade = Math.max(onlineAttempts[attemptNumber].score, grade);
}
return grade;
@ -151,7 +156,7 @@ export class AddonModScormProvider {
let total = 0;
for (const attemptNumber in onlineAttempts) {
sumGrades += onlineAttempts[attemptNumber].grade;
sumGrades += onlineAttempts[attemptNumber].score;
total++;
}
@ -589,8 +594,8 @@ export class AddonModScormProvider {
}
/**
* Get the grade for a certain SCORM and attempt.
* Based on Moodle's scorm_grade_user_attempt.
* Get the grade data for a certain attempt.
* Mostly based on Moodle's scorm_grade_user_attempt.
*
* @param scorm SCORM.
* @param attempt Attempt number.
@ -598,7 +603,12 @@ export class AddonModScormProvider {
* @param siteId Site ID. If not defined, current site.
* @returns Promise resolved with the grade. If the attempt hasn't reported grade/completion, it will be -1.
*/
async getAttemptGrade(scorm: AddonModScormScorm, attempt: number, offline?: boolean, siteId?: string): Promise<number> {
async getAttemptGrade(
scorm: AddonModScormScorm,
attempt: number,
offline?: boolean,
siteId?: string,
): Promise<AddonModScormAttemptGrade> {
const attemptScore = {
scos: 0,
values: 0,
@ -654,7 +664,11 @@ export class AddonModScormProvider {
score = attemptScore.max; // Remote Learner GRADEHIGHEST is default.
}
return score;
return {
num: attempt,
score,
hasCompletedPassedSCO: attemptScore.scos > 0,
};
}
/**
@ -2052,11 +2066,12 @@ export type AddonModScormOrganization = {
};
/**
* Grade for an attempt.
* Grade data for an attempt.
*/
export type AddonModScormAttemptGrade = {
num: number;
grade: number;
score: number;
hasCompletedPassedSCO: boolean; // Whether it has at least 1 SCO with status completed or passed.
};
/**