Better configurable backend for couse competency aggregation

This commit is contained in:
PMKuipers 2023-11-24 23:00:53 +01:00
parent 54a8823bbd
commit 932587d2af
13 changed files with 302 additions and 85 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

@ -3467,7 +3467,7 @@ export default {
return cgroup.completion?'completed':'incomplete'; return cgroup.completion?'completed':'incomplete';
}, },
pathtags(competency,use_idnumber=false) { pathtags(competency) {
const path = competency.path; const path = competency.path;
let s = ""; let s = "";
for (const ix in path) { for (const ix in path) {
@ -3475,8 +3475,16 @@ export default {
if ( ix > 0) { if ( ix > 0) {
s += " / "; s += " / ";
} }
s += `<a href="/admin/tool/lp/competencies.php?competencyid=${p.id}">${(use_idnumber)?p.idnumber:p.shortname}</a>`; let url;
if (p.type =='competency') {
url = `/admin/tool/lp/competencies.php?competencyid=${p.id}`;
} else {
url = `/admin/tool/lp/competencies.php?competencyframeworkid=${p.id}&pagecontextid=${p.contextid}`;
} }
s += `<a href="${url}">${p.title}</a>`;
}
return s;
}, },
}, },
@ -3489,12 +3497,11 @@ export default {
</tr> </tr>
<template v-else> <template v-else>
<tr v-for='c in value.competencies'> <tr v-for='c in value.competencies'>
<td><a href='#' v-b-modal="'modal-competency-id-'+c.id"><span v-html='c.shortname'></span></a></td> <td><a href='#' v-b-modal="'modal-competency-id-'+c.id"><span v-html='c.title'></span></a></td>
<td v-if="c.description"> <td v-if="c.details">
<span v-html='c.description'></span> <span v-html='c.details'></span>
</td> </td>
<b-modal :id="'modal-competency-id-'+c.id" <b-modal :id="'modal-competency-id-'+c.id"
:title="c.path.join(' / ')"
size="lg" size="lg"
ok-only ok-only
centered centered
@ -3502,14 +3509,21 @@ export default {
> >
<template #modal-header> <template #modal-header>
<div> <div>
<h1><i class="fa fa-certificate"></i> <h1><i class="fa fa-puzzle-piece"></i>
<a :href="'/admin/tool/lp/competencies.php?competencyid='+c.id'" target="_blank" <a :href="'/admin/tool/lp/competencies.php?competencyid='+c.id" target="_blank"
>{{c.shortname}}</a >{{c.title}} {{c.details}} </a
></h1> ></h1>
<div>{{ pathtags(c) }}</div> <div><span v-html="pathtags(c)"></span></div>
</div> </div>
</template> </template>
<span v-html='c.description'></span>
<table v-if="c.children">
<tr v-for="cc in c.children">
<td><span v-html='cc.displayfield'></span>
</td><td><span v-html='cc.description'></span>
</td>
</tr>
</table>
</b-modal> </b-modal>
</tr> </tr>
</template> </template>

View file

@ -226,10 +226,6 @@ class badgeinfo {
$badge['issuedlink'] = (new \moodle_url('/badges/badge.php', ['hash' => $issueinfo->uniquehash]))->out(false); $badge['issuedlink'] = (new \moodle_url('/badges/badge.php', ['hash' => $issueinfo->uniquehash]))->out(false);
} }
$f = fopen("/tmp/badgedebug","a");
fputs($f,date("Y-m-d H:M:S")." Badge info\n");
fputs($f,print_r($badge,true)."\n\n");
fclose($f);
return $badge; return $badge;
} }
@ -532,10 +528,6 @@ class badgeinfo {
if(isset($userid)) { if(isset($userid)) {
$coursecompletion = new \completion_completion(["userid" => $userid, "course" => $course->id]); $coursecompletion = new \completion_completion(["userid" => $userid, "course" => $course->id]);
$coursecompleted = $coursecompletion->is_complete(); $coursecompleted = $coursecompletion->is_complete();
$f = fopen("/tmp/debug","a+");
fputs($f,$course->fullname." ".($coursecompleted?"(COMPLETED)":"(NOT completed)")."\n");
fputs($f,print_r($coursecompletion,true));
fclose($f);
$subcrit["requirements"]["completion"]["completed"] = (bool) $coursecompleted; $subcrit["requirements"]["completion"]["completed"] = (bool) $coursecompleted;
$check_grade = true; $check_grade = true;

View file

@ -30,6 +30,7 @@ require_once($CFG->dirroot.'/course/lib.php');
use core_competency\course_competency; use core_competency\course_competency;
use core_competency\competency; use core_competency\competency;
use core_competency\api as c_api; use core_competency\api as c_api;
use core_competency\competency_rule_points;
use stdClass; use stdClass;
/** /**
@ -69,13 +70,15 @@ class coursecompetencyinfo {
public static function competencyinfo_structure($recurse=true) : \external_description { public static function competencyinfo_structure($recurse=true) : \external_description {
$struct = [ $struct = [
"id" => new \external_value(PARAM_INT, 'competency id'), "id" => new \external_value(PARAM_INT, 'competency id'),
"shortname" => new \external_value(PARAM_RAW, 'competency short name'), "title" => new \external_value(PARAM_RAW, 'competency display title'),
"idnumber" => new \external_value(PARAM_TEXT, 'competency ID number'), "details" => new \external_value(PARAM_RAW, 'competency details'),
"description" => new \external_value(PARAM_RAW, 'competency description'), "description" => new \external_value(PARAM_RAW, 'competency description'),
"ruleoutcome" => new \external_value(PARAM_TEXT, 'competency rule outcome text', VALUE_OPTIONAL),
"rule" => new \external_value(PARAM_RAW, 'competency rule description', VALUE_OPTIONAL),
"path" => new \external_multiple_structure(new \external_single_structure([ "path" => new \external_multiple_structure(new \external_single_structure([
"id" => new \external_value(PARAM_INT), "id" => new \external_value(PARAM_INT),
"shortname" => new \external_value(PARAM_RAW), "title" => new \external_value(PARAM_RAW),
"idnumber" => new \external_value(PARAM_TEXT), "type" => new \external_value(PARAM_TEXT),
]), 'competency path'), ]), 'competency path'),
"grade" => new \external_value(PARAM_TEXT, 'competency grade', VALUE_OPTIONAL), "grade" => new \external_value(PARAM_TEXT, 'competency grade', VALUE_OPTIONAL),
"coursegrade" => new \external_value(PARAM_TEXT, 'course competency grade', VALUE_OPTIONAL), "coursegrade" => new \external_value(PARAM_TEXT, 'course competency grade', VALUE_OPTIONAL),
@ -84,6 +87,8 @@ class coursecompetencyinfo {
"nproficient" => new \external_value(PARAM_INT, 'number of students with proficiency',VALUE_OPTIONAL), "nproficient" => new \external_value(PARAM_INT, 'number of students with proficiency',VALUE_OPTIONAL),
"ncourseproficient" => new \external_value(PARAM_INT, 'number of students with course proficiency',VALUE_OPTIONAL), "ncourseproficient" => new \external_value(PARAM_INT, 'number of students with course proficiency',VALUE_OPTIONAL),
"count" => new \external_value(PARAM_INT, 'number of students in stats',VALUE_OPTIONAL), "count" => new \external_value(PARAM_INT, 'number of students in stats',VALUE_OPTIONAL),
"required" => new \external_value(PARAM_BOOL, 'if required in parent competency rule',VALUE_OPTIONAL),
"points" => new \external_value(PARAM_INT, 'number of points in parent competency rule',VALUE_OPTIONAL),
]; ];
if($recurse) { if($recurse) {
$struct["children"] = new \external_multiple_structure(self::competencyinfo_structure(false),'child competencies',VALUE_OPTIONAL); $struct["children"] = new \external_multiple_structure(self::competencyinfo_structure(false),'child competencies',VALUE_OPTIONAL);
@ -120,27 +125,54 @@ class coursecompetencyinfo {
* @param Object $competency * @param Object $competency
*/ */
private function competencyinfo_model($competency) : array { private function competencyinfo_model($competency) : array {
$displayfield = get_config("local_treestudyplan","competency_displayname");
$detailfield = get_config("local_treestudyplan","competency_detailfield");
$headingfield = ($displayfield != 'description')?$displayfield:"shortname";
$framework = $competency->get_framework();
$path = []; $heading = $framework->get($headingfield);
if(empty(trim($heading))) {
$heading = $framework->get('shortname'); // Fall back to shortname if heading field is empty
}
$path = [[
'id' => $framework->get('id'),
'title' => $heading,
'contextid' => $framework->get('contextid'),
'type' => 'framework',
]];
foreach ($competency->get_ancestors() as $c) { foreach ($competency->get_ancestors() as $c) {
$competencypath[] = $c->get('shortname'); $competencypath[] = $c->get('shortname');
$heading = $c->get($headingfield);
if(empty(trim($heading))) {
$heading = $c->get('shortname'); // Fall back to shortname if heading field is empty
}
$path[] = [ $path[] = [
'id' => $c->get('id'), 'id' => $c->get('id'),
'shortname' => $c->get('shortname'), 'title' => $heading,
'idnumber' => $c->get('idnumber'), 'contextid' => $framework->get('contextid'),
'type' => 'competency',
]; ];
} }
$heading = $competency->get($headingfield);
if(empty(trim($heading))) {
$heading = $competency->get('shortname'); // Fall back to shortname if heading field is empty
}
$path[] = [ $path[] = [
'id' => $competency->get('id'), 'id' => $competency->get('id'),
'shortname' => $competency->get('shortname'), 'title' => $heading,
'idnumber' => $competency->get('idnumber'), 'contextid' => $framework->get('contextid'),
'type' => 'competency',
]; ];
$title = $competency->get($displayfield);
if(empty(trim($title))) {
$title = $competency->get('shortname'); // Fall back to shortname if heading field is empty
}
$model = [ $model = [
'id' => $competency->get('id'), 'id' => $competency->get('id'),
'shortname' => $competency->get('shortname'), 'title' => $title,
'idnumber' => $competency->get('idnumber'), 'details' => $competency->get($detailfield),
'description' => $competency->get('description'), 'description' => $competency->get('description'),
'path' => $path, 'path' => $path,
]; ];
@ -162,16 +194,50 @@ class coursecompetencyinfo {
$ncourseproficient = 0; $ncourseproficient = 0;
foreach($coursecompetencies as $c) { foreach($coursecompetencies as $c) {
if(!empty($studentslist)){
$stats = $this->proficiency_stats($c,$studentlist); $stats = $this->proficiency_stats($c,$studentlist);
$count += $stats->count; $count += $stats->count;
$nproficient += $stats->nproficient; $nproficient += $stats->nproficient;
$ncourseproficient += $stats->ncourseproficient; $ncourseproficient += $stats->ncourseproficient;
}
$ci = $this->competencyinfo_model($c); $ci = $this->competencyinfo_model($c);
// Copy proficiency stats to model. // Copy proficiency stats to model.
foreach ((array)$stats as $key => $value) { foreach ((array)$stats as $key => $value) {
$ci[$key] = $value; $ci[$key] = $value;
} }
$ci['required'] = $this->is_required($c);
$rule = $c->get_rule_object();
$ruleoutcome = $c->get('ruleoutcome');
if($rule && $ruleoutcome != competency::OUTCOME_NONE) {
$ruletext = $rule->get_name();
$ruleconfig = $c->get('ruleconfig');
if ($ruleoutcome == competency::OUTCOME_EVIDENCE) {
$outcometag = "evidence";
} else if ($ruleoutcome == competency::OUTCOME_COMPLETE) {
$outcometag = "complete";
} else if ($ruleoutcome == competency::OUTCOME_RECOMMEND) {
$outcometag = "recommend";
} else {
$outcometag = "none";
}
$model["ruleoutcome"] = get_string("coursemodulecompetencyoutcome_{$outcometag}","core_competency");
if ($rule instanceof competency_rule_points) {
$ruleconfig = json_decode($ruleconfig);
$points = $ruleconfig->base->points;
// Make a nice map of the competency rule config
$crlist = [];
foreach($ruleconfig->competencies as $cr){
$crlist[$cr->id] = $cr;
}
$model["rule"] = $ruletext . " ({$points} ".get_string("points","core_grades").")";
} else {
$model["rule"] = $ruletext;
}
// get one level of children // get one level of children
$dids = competency::get_descendants_ids($c); $dids = competency::get_descendants_ids($c);
@ -180,19 +246,28 @@ class coursecompetencyinfo {
foreach($dids as $did) { foreach($dids as $did) {
$cc = new competency($did); $cc = new competency($did);
$cci = $this->competencyinfo_model($cc); $cci = $this->competencyinfo_model($cc);
if($rule instanceof competency_rule_points) {
if(array_key_exists($did,$crlist)) {
$cr = $crlist[$did];
$cci["points"] = (int) $cr->points;
$cci["required"] = (int) $cr->required;
}
}
$children[] = $cci; $children[] = $cci;
} }
$ci["children"] = $children; $ci["children"] = $children;
} }
}
$cis[] = $ci; $cis[] = $ci;
} }
$info = [ $info = [
"competencies" => $cis, "competencies" => $cis,
"fproficient" => (float)($nproficient)/(float)($count),
"fcourseproficient" => (float)($ncourseproficient)/(float)($count),
]; ];
if(!empty($studentslist)){
$info["fproficient"] = (float)($nproficient)/(float)($count);
$info["fcourseproficient"] = (float)($ncourseproficient)/(float)($count);
}
return $info; return $info;
} }
@ -218,6 +293,35 @@ class coursecompetencyinfo {
$progress += 1; $progress += 1;
} }
$rule = $c->get_rule_object();
$ruleoutcome = $c->get('ruleoutcome');
if($rule && $ruleoutcome != competency::OUTCOME_NONE) {
$ruletext = $rule->get_name();
$ruleconfig = $c->get('ruleconfig');
if ($ruleoutcome == competency::OUTCOME_EVIDENCE) {
$outcometag = "evidence";
} else if ($ruleoutcome == competency::OUTCOME_COMPLETE) {
$outcometag = "complete";
} else if ($ruleoutcome == competency::OUTCOME_RECOMMEND) {
$outcometag = "recommend";
} else {
$outcometag = "none";
}
$model["ruleoutcome"] = get_string("coursemodulecompetencyoutcome_{$outcometag}","core_competency");
if ($rule instanceof competency_rule_points) {
$ruleconfig = json_decode($ruleconfig);
$pointsreq = $ruleconfig->base->points;
$points = 0;
// Make a nice map of the competency rule config
$crlist = [];
foreach($ruleconfig->competencies as $cr){
$crlist[$cr->id] = $cr;
}
}
// get one level of children // get one level of children
$dids = competency::get_descendants_ids($c); $dids = competency::get_descendants_ids($c);
if(count($dids) > 0) { if(count($dids) > 0) {
@ -225,17 +329,35 @@ class coursecompetencyinfo {
foreach($dids as $did) { foreach($dids as $did) {
$cc = new competency($did); $cc = new competency($did);
$cci = $this->competencyinfo_model($cc); $cci = $this->competencyinfo_model($cc);
$cp = $this->proficiency($cc,$userid); if($rule instanceof competency_rule_points) {
$cp = $p = $this->proficiency($cc,$userid);
// Copy proficiency info to model. // Copy proficiency info to model.
foreach ((array)$cp as $key => $value) { foreach ((array)$cp as $key => $value) {
$cci[$key] = $value; $cci[$key] = $value;
} }
if(array_key_exists($did,$crlist)) {
$cr = $crlist[$did];
$cci["points"] = (int) $cr->points;
$cci["required"] = (int) $cr->required;
if($cp->proficient) {
$points += (int) $cr->points;
}
}
}
$children[] = $cci; $children[] = $cci;
} }
$ci["children"] = $children; $ci["children"] = $children;
} }
if ($rule instanceof competency_rule_points) {
$model["rule"] = $ruletext . " ({$points} / {$pointsreq} ".get_string("points","core_grades").")";
} else {
$model["rule"] = $ruletext;
}
}
$cis[] = $ci; $cis[] = $ci;
} }
@ -299,4 +421,63 @@ class coursecompetencyinfo {
$r->coursegrade = $scale->get_nearest_item($ucc->get('grade')); $r->coursegrade = $scale->get_nearest_item($ucc->get('grade'));
return $r; return $r;
} }
/**
* Webservice executor to mark competency as required
* @param int $competencyid ID of the competency
* @param int $itemid ID of the study item
* @param bool $required Mark competency as required or not
* @return success Always returns successful success object
*/
public static function require_competency(int $competencyid, int $itemid, bool $required) {
global $DB;
$item = studyitem::find_by_id($itemid);
// Make sure conditions are properly configured;
$conditions = [];
try {
$conditions = json_decode($item->conditions(),true);
} catch (\Exception $x) {}
// Make sure the competencied field exists
if (!isset($conditions["competencies"]) || !is_array($conditions["competencies"])) {
$conditions["competencies"] = [];
}
// Make sure a record exits.
if (!array_key_exists($competencyid,$conditions["competencies"])){
$conditions["competencies"][$competencyid] = [
"required" => boolval($required),
];
} else {
$conditions["competencies"][$competencyid]["required"] = boolval($required);
}
// Store conditions;
$item->edit(["conditions" => json_encode($conditions)]);
return success::success();
}
/**
* Check if this gradable item is marked required in the studyitem
* @return bool
*/
public function is_required($competency) {
if ($this->studyitem) {
$conditions = [];
try {
$conditions = json_decode($this->studyitem->conditions(),true);
} catch (\Exception $x) {}
// Make sure the competencied field exists
if ( isset($conditions["competencies"])
&& is_array($conditions["competencies"])
&& isset($conditions["competencies"][$competency->get("id")])
&& isset($conditions["competencies"][$competency->get("id")]["required"])
) {
return boolval($conditions["competencies"][$competency->get("id")]["required"]);
}
}
return(false);
}
} }

View file

@ -173,6 +173,8 @@ class competency_aggregator extends \local_treestudyplan\aggregator {
$count = 0; $count = 0;
$courseproficient = 0; $courseproficient = 0;
$proficient = 0; $proficient = 0;
$requiredmet = 0;
$requiredcount = 0;
foreach ($competencies as $c) { foreach ($competencies as $c) {
$count += 1; $count += 1;
$p = $cci->proficiency($c,$userid); $p = $cci->proficiency($c,$userid);
@ -182,19 +184,26 @@ class competency_aggregator extends \local_treestudyplan\aggregator {
if ($p->courseproficient) { if ($p->courseproficient) {
$courseproficient += 1; $courseproficient += 1;
} }
if ($cci->is_required(($c))){
$requiredcount += 1;
if ($p->proficient) {
$requiredmet += 1;
}
}
} }
// Determine minimum for // Determine minimum for
$limit = $this->cfg()->thresh_completed * $count; $limit = $this->cfg()->thresh_completed * $count;
$coursefinished = ($course->enddate) ? ($course->enddate < time()) : false; $coursefinished = ($course->enddate) ? ($course->enddate < time()) : false;
if ($courseproficient >= $count) { if ($courseproficient >= $count && $requiredmet >= $requiredcount) {
if ($limit < $count) { if ($limit < $count) {
return completion::EXCELLENT; return completion::EXCELLENT;
} else { } else {
return completion::COMPLETED; return completion::COMPLETED;
} }
} else if ($courseproficient > $limit) { } else if ($courseproficient > $limit && $requiredmet >= $requiredcount) {
return completion::COMPLETED; return completion::COMPLETED;
} else if ($courseproficient > 0) { } else if ($courseproficient > 0) {
if ( $this->cfg()->use_failed && $coursefinished) { if ( $this->cfg()->use_failed && $coursefinished) {

View file

@ -132,10 +132,8 @@ class tristate_aggregator extends \local_treestudyplan\aggregator {
* @return int Aggregated completion as completion class constant * @return int Aggregated completion as completion class constant
*/ */
public function aggregate_course(courseinfo $courseinfo, studyitem $studyitem, $userid) { public function aggregate_course(courseinfo $courseinfo, studyitem $studyitem, $userid) {
$condition = $studyitem->conditions();
if (empty($condition)) {
$condition = self::DEFAULT_CONDITION; $condition = self::DEFAULT_CONDITION;
}
$list = []; $list = [];
foreach (gradeinfo::list_studyitem_gradables($studyitem) as $gi) { foreach (gradeinfo::list_studyitem_gradables($studyitem) as $gi) {
$list[] = $this->grade_completion($gi, $userid); $list[] = $this->grade_completion($gi, $userid);

View file

@ -84,8 +84,12 @@ class studyitem {
* Return the condition string for this item * Return the condition string for this item
*/ */
public function conditions() : string { public function conditions() : string {
if($this->r->type == self::COURSE) {
return (!empty($this->r->conditions)) ? $this->r->conditions : "";
} else {
return (!empty($this->r->conditions)) ? $this->r->conditions : "ALL"; return (!empty($this->r->conditions)) ? $this->r->conditions : "ALL";
} }
}
/** /**
* Find record in database and return management object * Find record in database and return management object

View file

@ -288,6 +288,10 @@ $string["settingdesc_bistate_thresh_progress"] = 'Minimum percentage of outcomes
$string["setting_bistate_accept_pending_submitted"] = 'Accept submitted but ungraded result as "progress"'; $string["setting_bistate_accept_pending_submitted"] = 'Accept submitted but ungraded result as "progress"';
$string["settingdesc_bistate_accept_pending_submitted"] = 'If enabled, submitted but ungraded outcomes will still count toward progress. If disabled, only graded outcomes will count'; $string["settingdesc_bistate_accept_pending_submitted"] = 'If enabled, submitted but ungraded outcomes will still count toward progress. If disabled, only graded outcomes will count';
$string["setting_competency_displayname"] = 'Competency display title';
$string["settingdesc_competency_displayname"] = 'The competency field used as it\'s title in the studyplan';
$string["setting_competency_detailfield"] = 'Competency detail field';
$string["settingdesc_competency_detailfield"] = 'The competency field used for competency details';
$string["setting_competency_heading"] = 'Defults for course competencies '; $string["setting_competency_heading"] = 'Defults for course competencies ';
$string["settingdesc_competency_heading"] = 'Set the defaults for this aggregation method'; $string["settingdesc_competency_heading"] = 'Set the defaults for this aggregation method';
$string["setting_competency_thresh_completed"] = 'Threshold for good (%)'; $string["setting_competency_thresh_completed"] = 'Threshold for good (%)';

View file

@ -287,6 +287,10 @@ $string["settingdesc_bistate_thresh_progress"] = 'Minimumpercentage van doelen d
$string["setting_bistate_accept_pending_submitted"] = 'Accepteer nog niet beoordeelde doelen als "in ontwikkeling"'; $string["setting_bistate_accept_pending_submitted"] = 'Accepteer nog niet beoordeelde doelen als "in ontwikkeling"';
$string["settingdesc_bistate_accept_pending_submitted"] = 'Neem leerdoelen waarbij bewijs is ingeleverd, maar wat nog niet is beoordeeld mee als "in ontwikkeling", zolang er nog geen beoordeling is'; $string["settingdesc_bistate_accept_pending_submitted"] = 'Neem leerdoelen waarbij bewijs is ingeleverd, maar wat nog niet is beoordeeld mee als "in ontwikkeling", zolang er nog geen beoordeling is';
$string["setting_competency_displayname"] = 'Weergavetitel competentie';
$string["settingdesc_competency_displayname"] = 'Veld dat wordt gebruikt als titel voor een competentie';
$string["setting_competency_detailfield"] = 'Detailinfo competentie';
$string["settingdesc_competency_detailfield"] = 'Veld dat wordt gebruikt voor korte competentie details. ';
$string["setting_competency_heading"] = 'Standaardwaarden voor cursuscompetenties '; $string["setting_competency_heading"] = 'Standaardwaarden voor cursuscompetenties ';
$string["settingdesc_competency_heading"] = 'Stel de standaardwaarden in voor deze verzamelmethode'; $string["settingdesc_competency_heading"] = 'Stel de standaardwaarden in voor deze verzamelmethode';
$string["setting_competency_thresh_completed"] = 'Drempelwaarde voor voltooid (%)'; $string["setting_competency_thresh_completed"] = 'Drempelwaarde voor voltooid (%)';

View file

@ -405,15 +405,6 @@ function local_treestudyplan_pluginfile(
): bool { ): bool {
global $DB,$USER; global $DB,$USER;
$fp = fopen("/tmp/debug","a+");
fputs($fp, print_r([
'context' => $context,
'filearea' => $filearea,
'args' => $args,
'forcedownload' => $forcedownload,
'options' => $options,
],true)."\n\n");
fclose($fp);
$studyplan_filecaps = ["local/treestudyplan:editstudyplan","local/treestudyplan:viewuserreports"]; $studyplan_filecaps = ["local/treestudyplan:editstudyplan","local/treestudyplan:viewuserreports"];

View file

@ -107,7 +107,27 @@ if ($hassiteconfig) {
$displayfields $displayfields
)); ));
// BISTATE AGGREGATON DEFAULTS. // COMPETENCY AGGREGATON DEFAULTS.
$page->add(new admin_setting_configselect('local_treestudyplan/competency_displayname',
get_string('setting_competency_displayname', 'local_treestudyplan'),
get_string('settingdesc_competency_displayname', 'local_treestudyplan'),
"idnumber",
["shortname" => get_string("name","core",),
"idnumber" => get_string("idnumber","core",),
"description" => get_string("description","core",)]
));
$page->add(new admin_setting_configselect('local_treestudyplan/competency_detailfield',
get_string('setting_competency_detailfield', 'local_treestudyplan'),
get_string('settingdesc_competency_detailfield', 'local_treestudyplan'),
"shortname",
["" => get_string("none","core",),
"shortname" => get_string("name","core",),
"idnumber" => get_string("idnumber","core",),
"description" => get_string("description","core",)]
));
$page->add(new admin_setting_heading('local_treestudyplan/competency_aggregation_heading', $page->add(new admin_setting_heading('local_treestudyplan/competency_aggregation_heading',
get_string('setting_competency_heading', 'local_treestudyplan'), get_string('setting_competency_heading', 'local_treestudyplan'),
get_string('settingdesc_competency_heading', 'local_treestudyplan') get_string('settingdesc_competency_heading', 'local_treestudyplan')

View file

@ -22,7 +22,7 @@
defined('MOODLE_INTERNAL') || die(); defined('MOODLE_INTERNAL') || die();
$plugin->component = 'local_treestudyplan'; // Recommended since 2.0.2 (MDL-26035). Required since 3.0 (MDL-48494). $plugin->component = 'local_treestudyplan'; // Recommended since 2.0.2 (MDL-26035). Required since 3.0 (MDL-48494).
$plugin->version = 2023111700; // YYYYMMDDHH (year, month, day, iteration). $plugin->version = 2023112301; // YYYYMMDDHH (year, month, day, iteration).
$plugin->requires = 2021051700; // YYYYMMDDHH (This is the release version for Moodle 3.11). $plugin->requires = 2021051700; // YYYYMMDDHH (This is the release version for Moodle 3.11).
$plugin->release = "1.1.0-b"; $plugin->release = "1.1.0-b";