Bugfixed in completion reporting for users and teachers

This commit is contained in:
PMKuipers 2023-09-01 23:13:50 +02:00
parent 3614fa852f
commit 39e1e14dcd
10 changed files with 168 additions and 75 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1151,6 +1151,23 @@ export default {
}
return false;
},
requirementHTML(requirements) {
const rqs = requirements.split(/, */);
let html = "";
for(const ix in rqs) {
const rq = rqs[ix];
html += `${rq}<br>`;
}
return html;
},
addTargetBlank(html) {
const m = /^([^<]*\< *a +)(.*)/.exec(html);
if(m){
return `${m[1]} target="_blank" ${m[2]}`;
} else {
return html;
}
}
},
template: `
<table class="r-item-course-grade-details">
@ -1184,13 +1201,21 @@ export default {
</tr>
<tr v-for='ci in cgroup.items'>
<td><span v-if='guestmode'>{{ci.title}}</span>
<span v-else v-html='ci.details.criteria'></span>
<a href="#" v-b-tooltip.click="{ customClass: 'r-tooltip ' + ci.status}"
:title="ci.details.requirement"
:class="'s-required ' + ci.status"><i v-if="ci.details.requirement"
<span v-else v-html='addTargetBlank(ci.details.criteria)'></span>
<a href="#" v-b-tooltip.click.hover.right.html="{ customClass: 'r-tooltip ' + ci.status}"
:title="requirementHTML(ci.details.requirement)"
class="text-primary"><i v-if="ci.details.requirement"
class='fa fa-question-circle'
></i></a>
<td><span :class="' r-completion-'+ci.status">{{ci.grade}}</span></td>
<td
><span :class="' r-completion-'+ci.status">{{ci.grade}}</span>
<span v-if="ci.warning"
><i class="text-primary fa fa-exclamation-triangle"
v-b-tooltip.hover.right.click="{ customClass: 'r-tooltip info' }"
:title="ci.warning"
></i
></span
></td>
<td><i :class="'fa fa-'+completion_icon(ci.status)+' r-completion-'+ci.status"
:title="text['completion_'+ci.status]"></i>
<i v-if='ci.pending' :title="text['completion_pending']"
@ -1305,7 +1330,7 @@ export default {
status.completed += itm.progress.completed;
status.completed_pass += itm.progress.completed_pass;
status.completed_fail += itm.progress.completed_fail;
status.ungraded += itm.progress.completed;
status.ungraded += itm.progress.ungraded;
}
}
}

View File

@ -172,27 +172,28 @@ class completionscanner {
$completedpass = 0;
$completedfail = 0;
foreach ($students as $userid) {
if ($this->pending($userid)) {
// First check if the completion needs grading.
$ungraded++;
$completion = $this->completioninfo->get_user_completion($userid, $this->crit);
if ($this->crit->criteriatype == COMPLETION_CRITERIA_TYPE_ACTIVITY) {
// If it's an activity completion, add all the relevant activities as sub-items.
// Retrieve data for this object.
$data = $this->completioninfo->get_data($this->cm, false, $userid);
// If it's an activity completion, add all the relevant activities as sub-items.
$completionstatus = $data->completionstate;
if ($completionstatus == COMPLETION_COMPLETE_PASS) {
$completedpass++;
} else if ($completionstatus == COMPLETION_COMPLETE_FAIL) {
$completedfail++;
} else if ($completionstatus == COMPLETION_COMPLETE) {
$completed++;
} else if ($this->pending($userid)) {
// Check if the completion needs grading.
$ungraded++;
}
} else {
$completion = $this->completioninfo->get_user_completion($userid, $this->crit);
if ($this->crit->criteriatype == COMPLETION_CRITERIA_TYPE_ACTIVITY) {
// If it's an activity completion, add all the relevant activities as sub-items.
$completionstatus = $this->completioninfo->get_grade_completion($this->cm, $userid);
if ($completionstatus == COMPLETION_COMPLETE_PASS) {
$completedpass++;
} else if ($completionstatus == COMPLETION_COMPLETE_FAIL) {
$completedfail++;
} else if ($completionstatus == COMPLETION_COMPLETE) {
$completed++;
}
} else {
if ($completion->is_complete()) {
$completed++;
}
if ($completion->is_complete()) {
$completed++;
}
}
}

View File

@ -190,6 +190,7 @@ class corecompletioninfo {
'optional pending state, for submitted but not yet reviewed activities', VALUE_OPTIONAL),
"grade" => new \external_value(PARAM_TEXT, 'optional grade result for this subitem', VALUE_OPTIONAL),
"feedback" => new \external_value(PARAM_RAW, 'optional feedback for this subitem ', VALUE_OPTIONAL),
"warning" => new \external_value(PARAM_TEXT, 'optional warning text', VALUE_OPTIONAL),
], 'completion type', $value);
}
@ -465,10 +466,6 @@ class corecompletioninfo {
foreach ($completions as $completion) {
$criteria = $completion->get_criteria();
if ($completion->is_complete()) {
$progress += 1; // Add a point to the progress counter.
}
$iinfo = [
"id" => $criteria->id,
"title" => $criteria->get_title_detailed(),
@ -480,11 +477,42 @@ class corecompletioninfo {
if ($type == COMPLETION_CRITERIA_TYPE_ACTIVITY) {
$cm = $this->modinfo->get_cm($criteria->moduleinstance);
// Retrieve data for this object.
$data = $this->completion->get_data($cm, false, $userid);
// If it's an activity completion, add all the relevant activities as sub-items.
$completionstatus = $this->completion->get_grade_completion($cm, $userid);
$iinfo['status'] = self::completion_handle($completionstatus);
$completionstatus = $data->completionstate;
$gradecompletion = $this->completion->get_grade_completion($cm, $userid);
/* To comply with the moodle completion report, only count COMPLETED_PASS as completed if
the completion is marked as complete by the system. Occasinally those don't match
and we want to show similar behaviour. This happens when completion data is reset
in a module
*/
if(!$completion->is_complete() && in_array($gradecompletion, [COMPLETION_COMPLETE, COMPLETION_COMPLETE_PASS])) {
/* If a passing grade was provided, but the activity was not completed,
* most likely the completion data was erased.
*/
/*$completionstatus = COMPLETION_INCOMPLETE; */
if ( !is_null($cm->completiongradeitemnumber) || ($cm->completionpassgrade) ) {
// Show a warning if this activity has grade completions to help make sense of the completion.
$iinfo["warning"] = get_string("warning_incomplete_pass","local_treestudyplan");
} else {
// Show a warning if this activity has no grade requirment for completion.
$iinfo["warning"] = get_string("warning_incomplete_nograderq","local_treestudyplan");
}
}
$iinfo['status'] = self::completion_handle($data->completionstate);
// Re-evaluate the completed value, to make sure COMPLETE_FAIL doesn't creep in as completed.
$iinfo['completed'] = in_array($completionstatus, [COMPLETION_COMPLETE, COMPLETION_COMPLETE_PASS]);
if (($data->completionstate == COMPLETION_INCOMPLETE) || ($data->completionstate == COMPLETION_COMPLETE_FAIL)) {
$iinfo['completed'] = false;
} else {
$iinfo['completed'] = true;
$progress += 1; // Add a point to the progress counter.
}
// Determine the grade (retrieve from grade item, not from completion).
$grade = $this->get_grade($cm, $userid);
$iinfo['grade'] = $grade->grade;
@ -510,6 +538,15 @@ class corecompletioninfo {
$cinfo["status"] = "progress";
}
}
if ($completion->is_complete()) {
$progress += 1; // Add a point to the progress counter.
}
}
else {
if ($completion->is_complete()) {
$progress += 1; // Add a point to the progress counter.
}
}
// Finally add the item to the items list.
$cinfo["items"][] = $iinfo;

View File

@ -1232,13 +1232,29 @@
.features-treestudyplan .s-required.neutral {
color: #aaa;
}
.path-local-treestudyplan .r-tooltip.warning .tooltip-inner,
.features-treestudyplan .r-tooltip.warning .tooltip-inner {
background-color: color-mix(in srgb, var(--warning) 60%, #000);
}
.path-local-treestudyplan .r-tooltip.warning .arrow::before,
.features-treestudyplan .r-tooltip.warning .arrow::before {
border-right-color: color-mix(in srgb, var(--warning) 60%, #000);
}
.path-local-treestudyplan .r-tooltip.info .tooltip-inner,
.features-treestudyplan .r-tooltip.info .tooltip-inner {
background-color: color-mix(in srgb, var(--info) 60%, #000);
}
.path-local-treestudyplan .r-tooltip.info .arrow::before,
.features-treestudyplan .r-tooltip.info .arrow::before {
border-right-color: color-mix(in srgb, var(--info) 60%, #000);
}
.path-local-treestudyplan .r-tooltip.incomplete .tooltip-inner,
.path-local-treestudyplan .r-tooltip.complete-fail .tooltip-inner,
.path-local-treestudyplan .r-tooltip.completed-fail .tooltip-inner,
.features-treestudyplan .r-tooltip.incomplete .tooltip-inner,
.features-treestudyplan .r-tooltip.complete-fail .tooltip-inner,
.features-treestudyplan .r-tooltip.completed-fail .tooltip-inner {
background-color: var(--danger);
background-color: color-mix(in srgb, var(--info) 60%, #000);
}
.path-local-treestudyplan .r-tooltip.incomplete .arrow::before,
.path-local-treestudyplan .r-tooltip.complete-fail .arrow::before,
@ -1246,19 +1262,19 @@
.features-treestudyplan .r-tooltip.incomplete .arrow::before,
.features-treestudyplan .r-tooltip.complete-fail .arrow::before,
.features-treestudyplan .r-tooltip.completed-fail .arrow::before {
border-top-color: var(--danger);
border-right-color: color-mix(in srgb, var(--info) 60%, #000);
}
.path-local-treestudyplan .r-tooltip.complete .tooltip-inner,
.path-local-treestudyplan .r-tooltip.completed .tooltip-inner,
.features-treestudyplan .r-tooltip.complete .tooltip-inner,
.features-treestudyplan .r-tooltip.completed .tooltip-inner {
background-color: var(--info);
background-color: color-mix(in srgb, var(--info) 60%, #000);
}
.path-local-treestudyplan .r-tooltip.complete .arrow::before,
.path-local-treestudyplan .r-tooltip.completed .arrow::before,
.features-treestudyplan .r-tooltip.complete .arrow::before,
.features-treestudyplan .r-tooltip.completed .arrow::before {
border-top-color: var(--info);
border-right-color: color-mix(in srgb, var(--info) 60%, #000);
}
.path-local-treestudyplan .r-tooltip.complete-pass .tooltip-inner,
.path-local-treestudyplan .r-tooltip.completed-pass .tooltip-inner,
@ -1270,15 +1286,7 @@
.path-local-treestudyplan .r-tooltip.completed-pass .arrow::before,
.features-treestudyplan .r-tooltip.complete-pass .arrow::before,
.features-treestudyplan .r-tooltip.completed-pass .arrow::before {
border-top-color: var(--success);
}
.path-local-treestudyplan .r-tooltip.incomplete .tooltip-inner,
.features-treestudyplan .r-tooltip.incomplete .tooltip-inner {
background-color: var(--danger);
}
.path-local-treestudyplan .r-tooltip.incomplete .arrow::before,
.features-treestudyplan .r-tooltip.incomplete .arrow::before {
border-top-color: var(--danger);
border-right-color: var(--success);
}
.path-local-treestudyplan .m-buttonbar,
.features-treestudyplan .m-buttonbar {

View File

@ -335,4 +335,7 @@ $string["student_not_tracked"] = 'Not enrolled in this course';
$string["completion_not_enabled"] = 'Completion is not enabled in this course';
$string["student_from_plan_enrolled"] = 'student in this study plan is enrolled in the course';
$string["students_from_plan_enrolled"] = 'students in this study plan are enrolled in the course';
$string["not_enrolled"] = "Not enrolled";
$string["not_enrolled"] = "Not enrolled";
$string["warning_incomplete_pass"] = 'Completion data was reset for this activity, causing your passing grade not to be registered. Ask your teacher to re-grade this grade to remedy this.';
$string["warning_incomplete_nograderq"] = 'Because the grade is not marked as a requirement, your passing grade is not registering completion.';

View File

@ -336,4 +336,7 @@ $string["student_not_tracked"] = 'Niet ingeschreven in deze cursus';
$string["completion_not_enabled"] = 'Cursusvoltooiing is niet ingeschakeld';
$string["student_from_plan_enrolled"] = 'student in dit studieplan is in deze cursus ingeschreven';
$string["students_from_plan_enrolled"] = 'studenten in dit studieplan zijn in deze cursus ingeschreven';
$string["not_enrolled"] = "Niet ingeschreven";
$string["not_enrolled"] = "Niet ingeschreven";
$string["warning_incomplete_pass"] = 'Door een storing wordt je voldoende resultaat niet als voltooid meegenomen. Vraag je docent om opnieuw je beoordeling vast te stellen. ';
$string["warning_incomplete_nograderq"] = 'Omdat het behalen van een cijfer niet als voorwaarde is aangegeven, telt het behalen van een voldoende resultaat niet mee voor voitooiing';

View File

@ -1064,24 +1064,39 @@
color: #aaa;
}
.r-tooltip.warning .tooltip-inner
{
background-color: color-mix(in srgb, var(--warning) 60%, #000);
}
.r-tooltip.warning .arrow::before {
border-right-color: color-mix(in srgb, var(--warning) 60%, #000);
}
.r-tooltip.info .tooltip-inner
{
background-color: color-mix(in srgb, var(--info) 60%, #000);
}
.r-tooltip.info .arrow::before {
border-right-color: color-mix(in srgb, var(--info) 60%, #000);
}
.r-tooltip.incomplete .tooltip-inner,
.r-tooltip.complete-fail .tooltip-inner,
.r-tooltip.completed-fail .tooltip-inner {
background-color: var(--danger);
background-color: color-mix(in srgb, var(--info) 60%, #000);
}
.r-tooltip.incomplete .arrow::before,
.r-tooltip.complete-fail .arrow::before,
.r-tooltip.completed-fail .arrow::before {
border-top-color: var(--danger);
border-right-color: color-mix(in srgb, var(--info) 60%, #000);
}
.r-tooltip.complete .tooltip-inner,
.r-tooltip.completed .tooltip-inner {
background-color: var(--info);
background-color: color-mix(in srgb, var(--info) 60%, #000);
}
.r-tooltip.complete .arrow::before,
.r-tooltip.completed .arrow::before {
border-top-color: var(--info);
border-right-color: color-mix(in srgb, var(--info) 60%, #000);
}
.r-tooltip.complete-pass .tooltip-inner,
@ -1090,14 +1105,7 @@
}
.r-tooltip.complete-pass .arrow::before,
.r-tooltip.completed-pass .arrow::before {
border-top-color: var(--success);
}
.r-tooltip.incomplete .tooltip-inner {
background-color: var(--danger);
}
.r-tooltip.incomplete .arrow::before {
border-top-color: var(--danger);
border-right-color: var(--success);
}
.m-buttonbar {

View File

@ -1232,13 +1232,29 @@
.features-treestudyplan .s-required.neutral {
color: #aaa;
}
.path-local-treestudyplan .r-tooltip.warning .tooltip-inner,
.features-treestudyplan .r-tooltip.warning .tooltip-inner {
background-color: color-mix(in srgb, var(--warning) 60%, #000);
}
.path-local-treestudyplan .r-tooltip.warning .arrow::before,
.features-treestudyplan .r-tooltip.warning .arrow::before {
border-right-color: color-mix(in srgb, var(--warning) 60%, #000);
}
.path-local-treestudyplan .r-tooltip.info .tooltip-inner,
.features-treestudyplan .r-tooltip.info .tooltip-inner {
background-color: color-mix(in srgb, var(--info) 60%, #000);
}
.path-local-treestudyplan .r-tooltip.info .arrow::before,
.features-treestudyplan .r-tooltip.info .arrow::before {
border-right-color: color-mix(in srgb, var(--info) 60%, #000);
}
.path-local-treestudyplan .r-tooltip.incomplete .tooltip-inner,
.path-local-treestudyplan .r-tooltip.complete-fail .tooltip-inner,
.path-local-treestudyplan .r-tooltip.completed-fail .tooltip-inner,
.features-treestudyplan .r-tooltip.incomplete .tooltip-inner,
.features-treestudyplan .r-tooltip.complete-fail .tooltip-inner,
.features-treestudyplan .r-tooltip.completed-fail .tooltip-inner {
background-color: var(--danger);
background-color: color-mix(in srgb, var(--info) 60%, #000);
}
.path-local-treestudyplan .r-tooltip.incomplete .arrow::before,
.path-local-treestudyplan .r-tooltip.complete-fail .arrow::before,
@ -1246,19 +1262,19 @@
.features-treestudyplan .r-tooltip.incomplete .arrow::before,
.features-treestudyplan .r-tooltip.complete-fail .arrow::before,
.features-treestudyplan .r-tooltip.completed-fail .arrow::before {
border-top-color: var(--danger);
border-right-color: color-mix(in srgb, var(--info) 60%, #000);
}
.path-local-treestudyplan .r-tooltip.complete .tooltip-inner,
.path-local-treestudyplan .r-tooltip.completed .tooltip-inner,
.features-treestudyplan .r-tooltip.complete .tooltip-inner,
.features-treestudyplan .r-tooltip.completed .tooltip-inner {
background-color: var(--info);
background-color: color-mix(in srgb, var(--info) 60%, #000);
}
.path-local-treestudyplan .r-tooltip.complete .arrow::before,
.path-local-treestudyplan .r-tooltip.completed .arrow::before,
.features-treestudyplan .r-tooltip.complete .arrow::before,
.features-treestudyplan .r-tooltip.completed .arrow::before {
border-top-color: var(--info);
border-right-color: color-mix(in srgb, var(--info) 60%, #000);
}
.path-local-treestudyplan .r-tooltip.complete-pass .tooltip-inner,
.path-local-treestudyplan .r-tooltip.completed-pass .tooltip-inner,
@ -1270,15 +1286,7 @@
.path-local-treestudyplan .r-tooltip.completed-pass .arrow::before,
.features-treestudyplan .r-tooltip.complete-pass .arrow::before,
.features-treestudyplan .r-tooltip.completed-pass .arrow::before {
border-top-color: var(--success);
}
.path-local-treestudyplan .r-tooltip.incomplete .tooltip-inner,
.features-treestudyplan .r-tooltip.incomplete .tooltip-inner {
background-color: var(--danger);
}
.path-local-treestudyplan .r-tooltip.incomplete .arrow::before,
.features-treestudyplan .r-tooltip.incomplete .arrow::before {
border-top-color: var(--danger);
border-right-color: var(--success);
}
.path-local-treestudyplan .m-buttonbar,
.features-treestudyplan .m-buttonbar {