Skip to content

Commit

Permalink
Merge pull request #36 from ucl-isd/CTP-3102
Browse files Browse the repository at this point in the history
CTP-2516, CTP-3046, CTP-3057, CTP-3094, CTP-3095, CTP-3102
  • Loading branch information
aspark21 authored Feb 11, 2024
2 parents 3e69f34 + 37c6875 commit f81768e
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 215 deletions.
2 changes: 1 addition & 1 deletion apiclients/easikit/classes/requests/getcomponentgrade.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public function process_response($response): array {
'MAB_SEQ' => $value['sequence_number'],
'AST_CODE' => $value['assessment_component_type']['code'],
'MAB_PERC' => $matches[1],
'MAB_NAME' => $value['name'],
'MAB_NAME' => preg_replace('/\s*\(\d+%?\)$/', '', $value['name']),
'MKS_CODE' => $value['mark_scheme']['code'],
'APA_ROMC' => $value['schedule']['location']['room']['identifier'],
];
Expand Down
69 changes: 33 additions & 36 deletions classes/manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -140,35 +140,35 @@ public static function get_manager(): ?manager {
* Fetch component grades data (MAB) from SITS.
*
* @param array $modocc module occurrences of the current course.
* @return bool
* @return void
*/
public function fetch_component_grades_from_sits(array $modocc): bool {
try {
if (!empty($modocc)) {
foreach ($modocc as $occ) {
// Get the cache.
$key = implode('_',
[
cachemanager::CACHE_AREA_COMPONENTGRADES,
$occ->mod_code,
$occ->mod_occ_mav,
$occ->mod_occ_psl_code,
$occ->mod_occ_year_code,
]
);

// Replace '/' with '_' for simple key.
$key = str_replace('/', '_', $key);

// This cache is not really used.
// It is only used to check if the component grades have been fetched for this module occurrence.
$cache = cachemanager::get_cache(cachemanager::CACHE_AREA_COMPONENTGRADES, $key);

// Skip if cache exists.
if (!empty($cache)) {
continue;
}
public function fetch_component_grades_from_sits(array $modocc): void {
if (!empty($modocc)) {
foreach ($modocc as $occ) {
// Get the cache.
$key = implode('_',
[
cachemanager::CACHE_AREA_COMPONENTGRADES,
$occ->mod_code,
$occ->mod_occ_mav,
$occ->mod_occ_psl_code,
$occ->mod_occ_year_code,
]
);

// Replace '/' with '_' for simple key.
$key = str_replace('/', '_', $key);

// This cache is not really used.
// It is only used to check if the component grades have been fetched for this module occurrence.
$cache = cachemanager::get_cache(cachemanager::CACHE_AREA_COMPONENTGRADES, $key);

// Skip if cache exists.
if (!empty($cache)) {
continue;
}

try {
// Get component grades from SITS.
$request = $this->apiclient->build_request(self::GET_COMPONENT_GRADE, $occ);
$response = $this->apiclient->send_request($request);
Expand All @@ -179,20 +179,16 @@ public function fetch_component_grades_from_sits(array $modocc): bool {
// Filter out unwanted component grades by marking scheme.
$response = $this->filter_out_invalid_component_grades($response);

// Set cache expiry to 30 days.
cachemanager::set_cache(cachemanager::CACHE_AREA_COMPONENTGRADES, $key, $response, 30 * 24 * 60 * 60);
// Set cache expiry to 1 hour.
cachemanager::set_cache(cachemanager::CACHE_AREA_COMPONENTGRADES, $key, $response, 3600);

// Save component grades to DB.
$this->save_component_grades($response);
} catch (\moodle_exception $e) {
$this->apierrors[] = $e->getMessage();
}

return true;
}
} catch (\moodle_exception $e) {
$this->apierrors[] = $e->getMessage();
}

return false;
}

/**
Expand Down Expand Up @@ -854,7 +850,8 @@ public function get_transfer_logs (int $assessmentmappingid, int $userid, string
}

// Get the latest record for each push type, e.g. grade push, submission log push.
$sql = "SELECT t1.id, t1.type, t1.request, t1.response, t1.timecreated, t1.errlogid, errlog.errortype, errlog.message
$sql = "SELECT t1.id, t1.type, t1.request, t1.response, t1.requestbody, t1.timecreated, t1.errlogid,
errlog.errortype, errlog.message
FROM {" . self::TABLE_TRANSFER_LOG . "} t1
INNER JOIN (
SELECT type, assessmentmappingid, MAX(timecreated) AS latest_time
Expand Down
12 changes: 12 additions & 0 deletions classes/output/pushrecord.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ class pushrecord {
/** @var bool Is submission log pushed */
public bool $issublogpushed = false;

/** @var bool Is marks updated after transfer */
public bool $marksupdatedaftertransfer = false;

/** @var string Transferred mark */
public string $transferredmark = '-';

/** @var manager|null Grade push manager */
protected ?manager $manager;

Expand Down Expand Up @@ -188,6 +194,12 @@ protected function set_transfer_records(int $assessmentmappingid, int $studentid
$this->componentgrade = $matches[1];
}
if ($log->type == manager::PUSH_GRADE) {
// Check if marks updated after transfer.
if ($response->code == '0') {
$requestbody = json_decode($log->requestbody);
$this->transferredmark = $requestbody->actual_mark;
$this->marksupdatedaftertransfer = $this->marks != $requestbody->actual_mark;
}
$this->lastgradepushresult = $result;
$this->lastgradepusherrortype = $errortype;
$this->lastgradepushtime = $timecreated;
Expand Down
2 changes: 2 additions & 0 deletions lang/en/local_sitsgradepush.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
$string['index:submissiondate'] = 'Submission date';
$string['index:lastmarktransfer'] = 'Mark Transferred';
$string['index:lastsublogtransfer'] = 'Submission Date recorded in SITS';
$string['index:mark_changed_to'] = 'Mark changed to {$a}';

// Marks transfer dashboard page.
$string['dashboard:header'] = 'SITS assessment mapping and mark transfer';
Expand All @@ -92,6 +93,7 @@
$string['dashboard:seq'] = 'SEQ';
$string['dashboard:sits_assessment'] = 'SITS assessment';
$string['dashboard:weight'] = 'Weight';
$string['dashboard:mab_perc'] = '{$a}%';
$string['dashboard:asttype'] = 'AST TYPE';
$string['dashboard:source'] = 'Source';
$string['dashboard:moodle_activity'] = 'Moodle activity';
Expand Down
171 changes: 0 additions & 171 deletions lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,177 +25,6 @@

use local_sitsgradepush\manager;

/**
* Display settings in activity's settings.
*
* @param moodleform $formwrapper
* @param MoodleQuickForm $mform
* @return void
* @throws coding_exception
* @throws dml_exception
*/
function local_sitsgradepush_coursemodule_standard_elements($formwrapper, $mform) {
// Do not add settings if the plugin is disabled.
if (get_config('local_sitsgradepush', 'enabled') !== '1') {
return;
}

// Do not show settings if user does not have the capability.
if (!has_capability(
'local/sitsgradepush:mapassessment',
context_course::instance($formwrapper->get_course()->id))) {
return;
}

$manager = manager::get_manager();
// Display settings for certain type of activities only.
$modulename = $formwrapper->get_current()->modulename;
if (in_array($modulename, $manager->get_allowed_activities())) {
// Add setting header.
$mform->addElement('header', 'gradepushheader', 'Grade Push');

// Autocomplete options.
$options = [
'multiple' => true,
'noselectionstring' => get_string('option:none', 'local_sitsgradepush'),
];

// Add autocomplete element to form.
$select = $mform->addElement(
'autocomplete',
'gradepushassessmentselect',
get_string('label:gradepushassessmentselect', 'local_sitsgradepush'),
[],
$options
);

// Add component grades options to the dropdown list.
if (empty($manager->get_api_errors())) {
// Get module deliveries with component grades data.
$moduledeliveries = $manager->get_component_grade_options(
$formwrapper->get_course()->id,
$formwrapper->get_current()->coursemodule
);

$options = [];
// Combine all component grades into a single array.
if (!empty($moduledeliveries)) {
foreach ($moduledeliveries as $moduledelivery) {
if (empty($moduledelivery->componentgrades)) {
continue;
}
$options = array_merge($options, $moduledelivery->componentgrades);
}
}

if (empty($options)) {
$mform->addElement(
'html',
"<p class=\"alert-info alert\">". get_string('form:alert_no_mab_found', 'local_sitsgradepush') ."</p>"
);
} else {
foreach ($options as $option) {
$select->addOption($option->text, $option->value, [$option->selected]);
}

// Notify user multiple parts Turnitin assignment is not supported by Grade Push.
if ($modulename === 'turnitintooltwo') {
$mform->addElement(
'html',
"<p class=\"alert-info alert\">". get_string('form:info_turnitin_numparts', 'local_sitsgradepush') ."</p>"
);
}

// Notify user this activity is not in the current academic year.
if (!$manager->is_current_academic_year_activity($formwrapper->get_course()->id)) {
$mform->addElement(
'html',
"<p class=\"alert-info alert\">" . get_string('error:pastactivity', 'local_sitsgradepush') . "</p>"
);
}
}
}

// Disable the settings if this user does not have permission to map assessment.
if (!has_capability(
'local/sitsgradepush:mapassessment',
context_course::instance($formwrapper->get_course()->id))) {
$mform->addElement(
'html',
"<p class=\"alert-info alert\">" .
get_string('error:mapassessment', 'local_sitsgradepush') .
"</p>"
);
$select->updateAttributes(['disabled' => 'disabled']);
}

// Display any API error.
foreach ($manager->get_api_errors() as $msg) {
$mform->addElement('html', "<p class=\"alert alert-danger\">" . $msg . "</p>");
}
}
}

/**
* Process data from submitted form.
*
* @param stdClass $data
* @param stdClass $course
* @return mixed
* @throws dml_exception
*/
function local_sitsgradepush_coursemodule_edit_post_actions($data, $course) {
$manager = manager::get_manager();
// Save grade push settings if 'gradepushassessmentselect' is set.
if (isset($data->gradepushassessmentselect) && is_array($data->gradepushassessmentselect)) {
$manager->save_assessment_mappings($data);
}

return $data;
}

/**
* Validate the data in the new field when the form is submitted
*
* @param moodleform_mod $fromform
* @param array $fields
* @return string[]|void
* @throws dml_exception
*/
function local_sitsgradepush_coursemodule_validation($fromform, $fields) {
$manager = manager::get_manager();
// Extract activity type from form class name e.g. assign, quiz etc.
$activitytype = explode('_', get_class($fromform));

// Exit if the activity type is not allowed.
if (!in_array($activitytype[1], $manager->get_allowed_activities())) {
return;
}

// This field should be set if grade push is enabled and settings loaded.
if (!isset($fields['gradepushassessmentselect']) || !is_array($fields['gradepushassessmentselect'])) {
return;
}

// Remove any empty values.
$componentgrades = array_filter($fields['gradepushassessmentselect']);

// Validate component grades and return any error message.
// Course module id is empty if this is a new activity.
$coursemoduleid = $fields['coursemodule'] ?? null;
$result = $manager->validate_component_grades($componentgrades, $coursemoduleid);
if ($result->errormessages) {
return ['gradepushassessmentselect' => implode('<br>', $result->errormessages)];
}

// For Turnitin assignment, check if the number of parts is greater than 1.
if ($activitytype[1] === 'turnitintooltwo' && !empty($componentgrades)) {
if ($fields['numparts'] > 1) {
return ['numparts' => get_string('error:turnitin_numparts', 'local_sitsgradepush')];
}
}
}

/**
* Attach a grade push link in the activity's settings menu.
*
Expand Down
9 changes: 4 additions & 5 deletions templates/dashboard.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@
<table class="module-delivery-table table table-bordered mb-5">
<thead class="thead-light">
<tr class="small">
<th>{{#str}} dashboard:seq, local_sitsgradepush {{/str}}</th>
<th>{{#str}} dashboard:sits_assessment, local_sitsgradepush {{/str}}</th>
<th>{{#str}} dashboard:weight, local_sitsgradepush {{/str}}</th>
<th>{{#str}} dashboard:moodle_activity, local_sitsgradepush {{/str}}</th>
Expand All @@ -138,11 +139,9 @@
<tbody>
{{#componentgrades}}
<tr>
<th scope="row">
<span class="badge badge-dark">{{mabseq}}</span>
{{mabname}}
</th>
<td>{{mabperc}}</td>
<td>{{mabseq}}</td>
<td>{{mabname}}</td>
<td>{{#str}} dashboard:mab_perc, local_sitsgradepush, {{mabperc}} {{/str}}</td>
<td>
{{#assessmentmapping}}
<p>
Expand Down
11 changes: 9 additions & 2 deletions templates/marks_transfer_history_table.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@
"firstname":"Test",
"lastname":"User",
"idnumber":"1234567",
"marks":"0",
"marksupdatedaftertransfer":"true",
"transferredmark":"77",
"marks":"66",
"handindatetime":"2019-01-01 00:00:00",
"lastgradepushresultlabel":"<span class=\"badge badge-success\">Success</span> ",
"lastgradepushtime":"2019-01-01 00:00:00",
Expand Down Expand Up @@ -80,7 +82,12 @@
<tr>
<th scope="row">{{firstname}} {{lastname}}</th>
<td>{{idnumber}}</td>
<td>{{marks}}</td>
<td>{{^marksupdatedaftertransfer}}{{marks}}{{/marksupdatedaftertransfer}}
{{#marksupdatedaftertransfer}}
{{transferredmark}}<br>
<span class="badge badge-danger">{{#str}} index:mark_changed_to, local_sitsgradepush, {{marks}} {{/str}}</span>
{{/marksupdatedaftertransfer}}
</td>
<td>{{handindatetime}}</td>
<td>{{{lastgradepushresultlabel}}}{{lastgradepushtime}}</td>
{{#showsublogcolumn}}
Expand Down

0 comments on commit f81768e

Please sign in to comment.