diff --git a/scripts/langindex.json b/scripts/langindex.json
index 64a23a98d..f3d2bc96c 100644
--- a/scripts/langindex.json
+++ b/scripts/langindex.json
@@ -346,6 +346,7 @@
"addon.mod_assign.cannotsubmitduetostatementsubmission": "local_moodlemobileapp",
"addon.mod_assign.confirmstart": "assign",
"addon.mod_assign.confirmsubmission": "assign",
+ "addon.mod_assign.currentassigngrade": "assign",
"addon.mod_assign.currentattempt": "assign",
"addon.mod_assign.currentattemptof": "assign",
"addon.mod_assign.currentgrade": "assign",
@@ -702,8 +703,8 @@
"addon.mod_glossary.entrydeleted": "glossary",
"addon.mod_glossary.entrypendingapproval": "local_moodlemobileapp",
"addon.mod_glossary.entryusedynalink": "glossary",
- "addon.mod_glossary.errordeleting": "local_moodlemobileapp",
"addon.mod_glossary.errconceptalreadyexists": "glossary",
+ "addon.mod_glossary.errordeleting": "local_moodlemobileapp",
"addon.mod_glossary.errorloadingentries": "local_moodlemobileapp",
"addon.mod_glossary.errorloadingentry": "local_moodlemobileapp",
"addon.mod_glossary.errorloadingglossary": "local_moodlemobileapp",
diff --git a/src/addons/mod/assign/components/submission/addon-mod-assign-submission.html b/src/addons/mod/assign/components/submission/addon-mod-assign-submission.html
index 6a1777f15..1aa153367 100644
--- a/src/addons/mod/assign/components/submission/addon-mod-assign-submission.html
+++ b/src/addons/mod/assign/components/submission/addon-mod-assign-submission.html
@@ -308,6 +308,15 @@
{{ outcome.selected }}
+
+
+
+ {{ 'addon.mod_assign.currentassigngrade' | translate }}
+ {{ grade.unreleasedGrade}} / {{ gradeInfo.grade }}
+ {{ grade.unreleasedGrade }}
+
+
+
diff --git a/src/addons/mod/assign/components/submission/submission.ts b/src/addons/mod/assign/components/submission/submission.ts
index 3715161ef..c045ff47a 100644
--- a/src/addons/mod/assign/components/submission/submission.ts
+++ b/src/addons/mod/assign/components/submission/submission.ts
@@ -59,6 +59,7 @@ import { AddonModAssignSubmissionPluginComponent } from '../submission-plugin/su
import { AddonModAssignModuleHandlerService } from '../../services/handlers/module';
import { CanLeave } from '@guards/can-leave';
import { CoreTime } from '@singletons/time';
+import { isSafeNumber, SafeNumber } from '@/core/utils/types';
/**
* Component that displays an assignment submission.
@@ -476,6 +477,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
));
promises.push(AddonModAssign.invalidateAssignmentUserMappingsData(this.assign.id));
promises.push(AddonModAssign.invalidateListParticipantsData(this.assign.id));
+ promises.push(AddonModAssign.invalidateAssignmentGradesData(this.assign.id));
}
promises.push(CoreGradesHelper.invalidateGradeModuleItems(this.courseId, this.submitId));
promises.push(CoreCourse.invalidateModule(this.moduleId));
@@ -691,7 +693,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
}
// Treat the grade info.
- await this.treatGradeInfo();
+ await this.treatGradeInfo(assign);
const isManual = assign.attemptreopenmethod == AddonModAssignAttemptReopenMethodValues.MANUAL;
const isUnlimited = assign.maxattempts == AddonModAssignProvider.UNLIMITED_ATTEMPTS;
@@ -708,7 +710,10 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
AddonModAssign.getSubmissionGradingStatusTranslationId(this.grade.gradingStatus);
}
- if (this.lastAttempt?.gradingstatus == 'graded' && !assign.markingworkflow && this.userSubmission && feedback) {
+ if (
+ this.lastAttempt?.gradingstatus === AddonModAssignGradingStates.GRADED && !assign.markingworkflow &&
+ this.userSubmission && feedback
+ ) {
if (feedback.gradeddate < this.userSubmission.timemodified) {
this.lastAttempt.gradingstatus = AddonModAssignGradingStates.GRADED_FOLLOWUP_SUBMIT;
@@ -975,9 +980,10 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
/**
* Treat the grade info.
*
+ * @param assign Assign info.
* @returns Promise resolved when done.
*/
- protected async treatGradeInfo(): Promise {
+ protected async treatGradeInfo(assign: AddonModAssignAssign): Promise {
if (!this.gradeInfo) {
return;
}
@@ -997,12 +1003,33 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
this.canSaveGrades = this.grade.method == 'simple'; // Grades can be saved if simple grading.
+ const gradeNotReleased = assign.markingworkflow &&
+ this.grade.gradingStatus !== AddonModAssignGradingStates.MARKING_WORKFLOW_STATE_RELEASED;
+
+ const [gradebookGrades, assignGrades] = await Promise.all([
+ CoreGradesHelper.getGradeModuleItems(this.courseId, this.moduleId, this.submitId),
+ gradeNotReleased ?
+ CoreUtils.ignoreErrors(AddonModAssign.getAssignmentGrades(assign.id, { cmId: assign.cmid })) :
+ undefined,
+ ]);
+
+ const unreleasedGrade = Number(assignGrades?.find(grade => grade.userid === this.submitId)?.grade);
+ this.grade.unreleasedGrade = undefined;
+
if (gradeInfo.scale) {
- this.grade.scale =
- CoreUtils.makeMenuFromList(gradeInfo.scale, Translate.instant('core.nograde'));
+ this.grade.scale = CoreUtils.makeMenuFromList(gradeInfo.scale, Translate.instant('core.nograde'));
+
+ if (isSafeNumber(unreleasedGrade)) {
+ const scaleItem = this.grade.scale.find(scaleItem => scaleItem.value === unreleasedGrade);
+ this.grade.unreleasedGrade = scaleItem?.label;
+ this.grade.grade = (scaleItem ?? this.grade.scale[0])?.value;
+ this.originalGrades.grade = this.grade.grade;
+ }
} else {
+ this.grade.unreleasedGrade = isSafeNumber(unreleasedGrade) ? unreleasedGrade : undefined;
+
// Format the grade.
- this.grade.grade = CoreUtils.formatFloat(this.grade.grade);
+ this.grade.grade = CoreUtils.formatFloat(this.grade.unreleasedGrade ?? this.grade.grade);
this.originalGrades.grade = this.grade.grade;
// Get current language to format grade input field.
@@ -1024,12 +1051,9 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can
});
}
- // Get grade items.
- const grades = await CoreGradesHelper.getGradeModuleItems(this.courseId, this.moduleId, this.submitId);
-
const outcomes: AddonModAssignGradeOutcome[] = [];
- grades.forEach((grade: CoreGradesFormattedItem) => {
+ gradebookGrades.forEach((grade: CoreGradesFormattedItem) => {
if (!grade.outcomeid && !grade.scaleid) {
// Clean HTML tags, grade can contain an icon.
@@ -1245,6 +1269,7 @@ type AddonModAssignSubmissionGrade = {
scale?: CoreMenuItem[];
lang: string;
disabled: boolean;
+ unreleasedGrade?: SafeNumber | string;
};
type AddonModAssignSubmissionOriginalGrades = {
diff --git a/src/addons/mod/assign/lang.json b/src/addons/mod/assign/lang.json
index 050cb5d21..de0b0cc9d 100644
--- a/src/addons/mod/assign/lang.json
+++ b/src/addons/mod/assign/lang.json
@@ -22,6 +22,7 @@
"cannotsubmitduetostatementsubmission": "You can't make a submission in the app because the submission statement could not be retrieved from the site.",
"confirmstart": "You have {{$a}} to complete this assignment. When you begin, the timer will start to count down and can't be paused.",
"confirmsubmission": "Are you sure you want to submit your work for grading? You will not be able to make any more changes.",
+ "currentassigngrade": "Current grade in assignment",
"currentattempt": "This is attempt {{$a}}.",
"currentattemptof": "This is attempt {{$a.attemptnumber}} ( {{$a.maxattempts}} attempts allowed ).",
"currentgrade": "Current grade in gradebook",
diff --git a/src/addons/mod/assign/services/handlers/prefetch.ts b/src/addons/mod/assign/services/handlers/prefetch.ts
index 29d6afbfd..0cb4fc2f4 100644
--- a/src/addons/mod/assign/services/handlers/prefetch.ts
+++ b/src/addons/mod/assign/services/handlers/prefetch.ts
@@ -374,10 +374,7 @@ export class AddonModAssignPrefetchHandlerService extends CoreCourseActivityPref
return this.prefetchSubmission(assign, courseId, moduleId, submissionOptions, true);
});
- if (!assign.markingworkflow) {
- // Get assignment grades only if workflow is not enabled to check grading date.
- subPromises.push(AddonModAssign.getAssignmentGrades(assign.id, modOptions));
- }
+ subPromises.push(AddonModAssign.getAssignmentGrades(assign.id, modOptions));
// Prefetch the submission of the current user even if it does not exist, this will be create it.
if (!submissions || !submissions.find((subm: AddonModAssignSubmissionFormatted) => subm.submitid == userId)) {
diff --git a/src/addons/mod/assign/tests/behat/marking_workflow.feature b/src/addons/mod/assign/tests/behat/marking_workflow.feature
index e834ee1ee..f3359b460 100755
--- a/src/addons/mod/assign/tests/behat/marking_workflow.feature
+++ b/src/addons/mod/assign/tests/behat/marking_workflow.feature
@@ -9,6 +9,7 @@ Feature: Test marking workflow in assignment activity in app
| student2 | Student2 | student2 | student2@example.com |
| student3 | Student3 | student3 | student3@example.com |
| student4 | Student4 | student4 | student4@example.com |
+ | student5 | Student5 | student5 | student5@example.com |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
@@ -19,15 +20,18 @@ Feature: Test marking workflow in assignment activity in app
| student2 | C1 | student |
| student3 | C1 | student |
| student4 | C1 | student |
+ | student5 | C1 | student |
And the following "groups" exist:
| name | course | idnumber |
| Group 1 | C1 | G1 |
| Group 2 | C1 | G2 |
+ | Group 3 | C1 | G3 |
And the following "group members" exist:
| user | group |
| student1 | G1 |
| student2 | G1 |
| student3 | G2 |
+ | student4 | G3 |
And the following "activities" exist:
| activity | course | idnumber | name | assignsubmission_onlinetext_enabled | assignfeedback_comments_enabled | markingworkflow | teamsubmission | groupmode | submissiondrafts |
| assign | C1 | assign1 | Group Assign | 1 | 1 | 1 | 1 | 1 | 0 |
@@ -35,7 +39,8 @@ Feature: Test marking workflow in assignment activity in app
| assign | user | onlinetext |
| assign1 | student1 | Lorem |
| assign1 | student3 | Ipsum |
- # Mark a submission.
+ | assign1 | student4 | Dolor |
+ # Mark submissions.
And I am on the "Group Assign" "assign activity" page logged in as teacher1
And I follow "View all submissions"
And I click on "Grade" "link" in the "Student1" "table_row"
@@ -44,16 +49,72 @@ Feature: Test marking workflow in assignment activity in app
And I set the field "Feedback comments" to "Great job! Lol, not really."
And I set the field "Notify student" to "0"
And I press "Save changes"
+ And I am on the "Group Assign" "assign activity" page
+ And I follow "View all submissions"
+ And I click on "Grade" "link" in the "Student3" "table_row"
+ And I set the field "Grade out of 100" to "30"
+ And I set the field "Marking workflow state" to "Released"
+ And I set the field "Feedback comments" to "Needs to be improved."
+ And I set the field "Notify student" to "0"
+ And I press "Save changes"
And I log out
- Scenario: View submissions with marking workflow as teacher
+ Scenario: View submissions with marking workflow and using points as teacher
Given I entered the assign activity "Group Assign" on course "Course 1" as "teacher1" in the app
- And I press "Groups" in the app
+ When I press "Groups" in the app
Then I should find "Submitted for grading" within "Student1" "ion-item" in the app
And I should find "In review" within "Student1" "ion-item" in the app
And I should find "Submitted for grading" within "Student2" "ion-item" in the app
And I should find "In review" within "Student2" "ion-item" in the app
And I should find "Submitted for grading" within "Student3" "ion-item" in the app
- And I should find "Not marked" within "Student3" "ion-item" in the app
- And I should find "No submission" within "Student4" "ion-item" in the app
- And I should not find "Not marked" within "Student4" "ion-item" in the app
+ And I should find "Released" within "Student3" "ion-item" in the app
+ And I should find "Submitted for grading" within "Student4" "ion-item" in the app
+ And I should find "Not marked" within "Student4" "ion-item" in the app
+ And I should find "No submission" within "Student5" "ion-item" in the app
+ And I should not find "Not marked" within "Student5" "ion-item" in the app
+
+ When I press "Student1" in the app
+ And I press "Grade" in the app
+ Then I should find "Submitted for grading" in the app
+ And I should find "50 / 100" within "Current grade in assignment" "ion-item" in the app
+ And I should find "-" within "Current grade in gradebook" "ion-item" in the app
+ And I should find "In review" within "Marking workflow state" "ion-item" in the app
+ And the field "Grade out of 100" matches value "50" in the app
+ And I should not find "Graded by" in the app
+
+ When I press the back button in the app
+ And I press "Student3" in the app
+ And I press "Grade" in the app
+ Then I should find "Submitted for grading" in the app
+ And I should find "30" within "Current grade in gradebook" "ion-item" in the app
+ And I should find "Released" within "Marking workflow state" "ion-item" in the app
+ And I should find "Teacher teacher" within "Graded by" "ion-item" in the app
+ And the field "Grade out of 100" matches value "30" in the app
+ And I should not find "Current grade in assignment" in the app
+
+ Scenario: Grade submissions with marking workflow and using points
+ Given I entered the assign activity "Group Assign" on course "Course 1" as "teacher1" in the app
+ And I press "Groups" in the app
+ And I press "Student1" in the app
+ And I press "Grade" in the app
+ When I set the field "Grade out of 100" to "60" in the app
+ And I press "Done" in the app
+ And I press "Student1" in the app
+ And I press "Grade" in the app
+ Then I should find "60 / 100" within "Current grade in assignment" "ion-item" in the app
+ And I should find "-" within "Current grade in gradebook" "ion-item" in the app
+ And I should find "In review" within "Marking workflow state" "ion-item" in the app
+ And the field "Grade out of 100" matches value "60" in the app
+
+ When I press the back button in the app
+ And I press "Student3" in the app
+ And I press "Grade" in the app
+ When I set the field "Grade out of 100" to "80" in the app
+ And I press "Done" in the app
+ And I press "Student3" in the app
+ And I press "Grade" in the app
+ Then I should find "80" within "Current grade in gradebook" "ion-item" in the app
+ And I should find "Released" within "Marking workflow state" "ion-item" in the app
+ And I should find "Teacher teacher" within "Graded by" "ion-item" in the app
+ And the field "Grade out of 100" matches value "80" in the app
+ And I should not find "Current grade in assignment" in the app