diff --git a/coursesummary.php b/coursesummary.php new file mode 100644 index 0000000..6e6628f --- /dev/null +++ b/coursesummary.php @@ -0,0 +1,104 @@ +. + +/** + * Attendance course summary report. + * + * @package mod_attendance + * @copyright 2017 onwards Dan Marsden http://danmarsden.com + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +require_once('../../config.php'); +require_once($CFG->dirroot.'/mod/attendance/lib.php'); +require_once($CFG->dirroot.'/mod/attendance/locallib.php'); +require_once($CFG->libdir.'/tablelib.php'); +require_once($CFG->libdir.'/coursecatlib.php'); + +$category = optional_param('category', 0, PARAM_INT); +$download = optional_param('download', '', PARAM_ALPHA); +$sort = optional_param('tsort', '', PARAM_ALPHA); + +require_login(); +if (empty($category)) { + $context = context_system::instance(); + $courses = array(); // Show all courses. +} else { + $context = context_coursecat::instance($category); + $coursecat = coursecat::get($category); + $courses = $coursecat->get_courses(array('recursive' => true, 'idonly' => true)); +} +// Check permissions. +require_capability('mod/attendance:viewsummaryreports', $context); + +$exportfilename = 'attendancecoursesummary.csv'; + +$PAGE->set_url('/mod/attendance/coursesummary.php', array('category' => $category)); +$PAGE->set_context(context_system::instance()); +$PAGE->set_heading($SITE->fullname); + +$table = new flexible_table('attendancecoursesummary'); +$table->define_baseurl($PAGE->url); + +if (!$table->is_downloading($download, $exportfilename)) { + echo $OUTPUT->header(); + echo $OUTPUT->heading(get_string('coursesummary', 'mod_attendance')); + if (empty($category)) { + // Only show tabs if displaying via the admin page. + $tabmenu = attendance_print_settings_tabs('coursesummary'); + echo $tabmenu; + } +} + +$table->define_columns(array('course', 'percentage')); +$table->define_headers(array(get_string('course'), + get_string('averageattendance', 'attendance'))); +$table->sortable(true); +$table->no_sorting('course'); +$table->set_attribute('cellspacing', '0'); +$table->set_attribute('class', 'generaltable generalbox'); +$table->show_download_buttons_at(array(TABLE_P_BOTTOM)); +$table->setup(); + +// Work out direction of sort required. +$sortcolumns = $table->get_sort_columns(); +// Now do sorting if specified. + +$orderby = ' ORDER BY percentage ASC'; +if (!empty($sort)) { + $direction = ' DESC'; + if (!empty($sortcolumns[$sort]) && $sortcolumns[$sort] == SORT_ASC) { + $direction = ' ASC'; + } + $orderby = " ORDER BY $sort $direction"; + +} + +$records = attendance_course_users_points($courses, $orderby); +foreach ($records as $record) { + if (!$table->is_downloading($download, $exportfilename)) { + $url = new moodle_url('/mod/attendance/index.php', array('id' => $record->courseid)); + $name = html_writer::link($url, $record->coursename); + } else { + $name = $record->coursename; + } + $table->add_data(array($name, round($record->percentage * 100)."%")); +} +$table->finish_output(); + +if (!$table->is_downloading()) { + echo $OUTPUT->footer(); +} \ No newline at end of file diff --git a/db/access.php b/db/access.php index dc9359f..25a2bf0 100644 --- a/db/access.php +++ b/db/access.php @@ -132,4 +132,13 @@ $capabilities = array( 'manager' => CAP_ALLOW ) ), + // Allow access to site level reports. + 'mod/attendance:viewsummaryreports' => array( + 'riskbitmask' => RISK_PERSONAL, + 'captype' => 'read', + 'contextlevel' => CONTEXT_COURSECAT, + 'archetypes' => array( + 'manager' => CAP_ALLOW + ) + ), ); diff --git a/lang/en/attendance.php b/lang/en/attendance.php index 51a5c91..d286ba7 100644 --- a/lang/en/attendance.php +++ b/lang/en/attendance.php @@ -57,6 +57,7 @@ $string['attendance:managetemporaryusers'] = 'Manage temporary users'; $string['attendance:takeattendances'] = 'Taking Attendances'; $string['attendance:view'] = 'Viewing Attendances'; $string['attendance:viewreports'] = 'Viewing Reports'; +$string['attendance:viewsummaryreports'] = 'View course summary reports'; $string['attforblockdirstillexists'] = 'old mod/attforblock directory still exists - you must delete this directory on your server before running this upgrade.'; $string['attrecords'] = 'Attendances records'; $string['calclose'] = 'Close'; @@ -395,4 +396,6 @@ $string['automark'] = 'Automatically set status on close of session.'; $string['automark_help'] = 'When session closes, automatically set status for unreported students as configured by status set.'; $string['studentmarking'] = 'Student recording'; $string['automarktask'] = 'Check for closed attendance sessions that require auto marking'; -$string['autorecorded'] = 'system auto recorded'; \ No newline at end of file +$string['autorecorded'] = 'system auto recorded'; +$string['coursesummary'] = 'Course summary report'; +$string['averageattendance'] = 'Average attendance'; \ No newline at end of file diff --git a/lib.php b/lib.php index cae35bb..c777247 100644 --- a/lib.php +++ b/lib.php @@ -452,6 +452,9 @@ function attendance_print_settings_tabs($selected = 'settings') { $tabs[] = new tabobject('defaultstatus', $CFG->wwwroot.'/mod/attendance/defaultstatus.php', get_string('defaultstatus', 'attendance'), get_string('defaultstatus', 'attendance'), false); + $tabs[] = new tabobject('coursesummary', $CFG->wwwroot.'/mod/attendance/coursesummary.php', + get_string('coursesummary', 'attendance'), get_string('coursesummary', 'attendance'), false); + ob_start(); print_tabs(array($tabs), $selected); $tabmenu = ob_get_contents(); diff --git a/locallib.php b/locallib.php index 05257b8..40b40d5 100644 --- a/locallib.php +++ b/locallib.php @@ -649,3 +649,51 @@ function attendance_fill_groupid($formdata, &$sessions, $sess) { } } } + +/** + * Generates a summary of points for the courses selected. + * + * @param array $courseids optional list of courses to return + * @param string $orderby - optional order by param + * @return stdClass + */ +function attendance_course_users_points($courseids = array(), $orderby = '') { + global $DB; + + $where = ''; + $params = array(); + $where .= ' AND ats.sessdate < :enddate '; + $params['enddate'] = time(); + + $joingroup = 'LEFT JOIN {groups_members} gm ON (gm.userid = atl.studentid AND gm.groupid = ats.groupid)'; + $where .= ' AND (ats.groupid = 0 or gm.id is NOT NULL)'; + + if (!empty($courseids)) { + list($insql, $inparams) = $DB->get_in_or_equal($courseids, SQL_PARAMS_NAMED); + $where .= ' AND c.id ' . $insql; + $params = array_merge($params, $inparams); + } + + $sql = "SELECT courseid, coursename, sum(points) / sum(maxpoints) as percentage FROM ( +SELECT a.id, a.course as courseid, c.fullname as coursename, atl.studentid AS userid, COUNT(DISTINCT ats.id) AS numtakensessions, + SUM(stg.grade) AS points, SUM(stm.maxgrade) AS maxpoints + FROM mdl_attendance_sessions ats + JOIN mdl_attendance a ON a.id = ats.attendanceid + JOIN mdl_course c ON c.id = a.course + JOIN mdl_attendance_log atl ON (atl.sessionid = ats.id) + JOIN mdl_attendance_statuses stg ON (stg.id = atl.statusid AND stg.deleted = 0 AND stg.visible = 1) + JOIN (SELECT attendanceid, setnumber, MAX(grade) AS maxgrade + FROM mdl_attendance_statuses + WHERE deleted = 0 + AND visible = 1 + GROUP BY attendanceid, setnumber) stm + ON (stm.setnumber = ats.statusset AND stm.attendanceid = ats.attendanceid) + {$joingroup} + WHERE ats.sessdate >= c.startdate + AND ats.lasttaken != 0 + {$where} + GROUP BY a.id, a.course, c.fullname, atl.studentid + ) p GROUP by courseid, coursename {$orderby}"; + + return $DB->get_records_sql($sql, $params); +} \ No newline at end of file diff --git a/version.php b/version.php index 491864d..5f0e12a 100644 --- a/version.php +++ b/version.php @@ -23,9 +23,9 @@ */ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2016121311; +$plugin->version = 2016121312; $plugin->requires = 2016111800; -$plugin->release = '3.2.10'; +$plugin->release = '3.2.11'; $plugin->maturity = MATURITY_STABLE; $plugin->cron = 0; $plugin->component = 'mod_attendance';