diff --git a/classes/page_with_filter_controls.php b/classes/page_with_filter_controls.php
index 9617e8f..cadc9f1 100644
--- a/classes/page_with_filter_controls.php
+++ b/classes/page_with_filter_controls.php
@@ -124,6 +124,10 @@ class mod_attendance_page_with_filter_controls {
$this->startdate = 0;
$this->enddate = 0;
break;
+ case ATT_VIEW_SUMMARY:
+ $this->startdate = 1;
+ $this->enddate = 1;
+ break;
}
}
@@ -221,4 +225,4 @@ class mod_attendance_page_with_filter_controls {
public function set_current_sesstype($sesstype) {
$this->sesstype = $sesstype;
}
-}
\ No newline at end of file
+}
diff --git a/classes/structure.php b/classes/structure.php
index 67d67ff..4acc3a7 100644
--- a/classes/structure.php
+++ b/classes/structure.php
@@ -61,10 +61,6 @@ class mod_attendance_structure {
// Array by sessionid.
private $sessioninfo = array();
- // Arrays by userid.
- private $usertakensesscount = array();
- private $userstatusesstat = array();
-
/**
* Initializes the attendance API instance using the data from DB
*
@@ -233,6 +229,7 @@ class mod_attendance_structure {
'edate' => $this->pageparams->enddate,
'cgroup' => $this->pageparams->get_current_sesstype());
$sessions = $DB->get_records_select('attendance_sessions', $where, $params, 'sessdate asc');
+ $statussetmaxpoints = attendance_get_statusset_maxpoints($this->get_statuses(true, true));
foreach ($sessions as $sess) {
if (empty($sess->description)) {
$sess->description = get_string('nodescription', 'attendance');
@@ -240,6 +237,7 @@ class mod_attendance_structure {
$sess->description = file_rewrite_pluginfile_urls($sess->description,
'pluginfile.php', $this->context->id, 'mod_attendance', 'session', $sess->id);
}
+ $sess->maxpoints = $statussetmaxpoints[$sess->statusset];
}
return $sessions;
@@ -746,138 +744,8 @@ class mod_attendance_structure {
return $DB->get_records('attendance_log', array('sessionid' => $sessionid), '', 'studentid,statusid,remarks,id');
}
- public function get_user_stat($userid) {
- $ret = array();
- $ret['completed'] = $this->get_user_taken_sessions_count($userid);
- $ret['statuses'] = $this->get_user_statuses_stat($userid);
-
- return $ret;
- }
-
- public function get_user_taken_sessions_count($userid) {
- if (!array_key_exists($userid, $this->usertakensesscount)) {
- if (!empty($this->pageparams->startdate) && !empty($this->pageparams->enddate)) {
- $this->usertakensesscount[$userid] = attendance_get_user_taken_sessions_count($this->id, $this->course->startdate,
- $userid, $this->cm, $this->pageparams->startdate, $this->pageparams->enddate);
- } else {
- $this->usertakensesscount[$userid] = attendance_get_user_taken_sessions_count($this->id, $this->course->startdate,
- $userid, $this->cm);
- }
- }
- return $this->usertakensesscount[$userid];
- }
-
- /**
- *
- * @param type $userid
- * @param type $filters - An array things to filter by. For now only enddate is valid.
- * @return type
- */
- public function get_user_statuses_stat($userid, array $filters = null) {
- global $DB;
- $params = array(
- 'aid' => $this->id,
- 'cstartdate' => $this->course->startdate,
- 'uid' => $userid);
-
- $processedfilters = array();
-
- // We test for any valid filters sent.
- if (isset($filters['enddate'])) {
- $processedfilters[] = 'ats.sessdate <= :enddate';
- $params['enddate'] = $filters['enddate'];
- }
-
- // Make the filter array into a SQL string.
- if (!empty($processedfilters)) {
- $processedfilters = ' AND '.implode(' AND ', $processedfilters);
- } else {
- $processedfilters = '';
- }
-
- $period = '';
- if (!empty($this->pageparams->startdate) && !empty($this->pageparams->enddate)) {
- $period = ' AND ats.sessdate >= :sdate AND ats.sessdate < :edate ';
- $params['sdate'] = $this->pageparams->startdate;
- $params['edate'] = $this->pageparams->enddate;
- }
-
- if ($this->get_group_mode()) {
- $qry = "SELECT al.statusid, count(al.statusid) AS stcnt
- FROM {attendance_log} al
- JOIN {attendance_sessions} ats ON al.sessionid = ats.id
- LEFT JOIN {groups_members} gm ON gm.userid = al.studentid AND gm.groupid = ats.groupid
- WHERE ats.attendanceid = :aid AND
- ats.sessdate >= :cstartdate AND
- al.studentid = :uid AND
- (ats.groupid = 0 or gm.id is NOT NULL)".$period.$processedfilters."
- GROUP BY al.statusid";
- } else {
- $qry = "SELECT al.statusid, count(al.statusid) AS stcnt
- FROM {attendance_log} al
- JOIN {attendance_sessions} ats
- ON al.sessionid = ats.id
- WHERE ats.attendanceid = :aid AND
- ats.sessdate >= :cstartdate AND
- al.studentid = :uid".$period.$processedfilters."
- GROUP BY al.statusid";
- }
-
- // We do not want to cache, or use a cached version of the results when a filter is set.
- if ($filters !== null) {
- return $DB->get_records_sql($qry, $params);
- } else if (!array_key_exists($userid, $this->userstatusesstat)) {
- // Not filtered so if we do not already have them do the query.
- $this->userstatusesstat[$userid] = $DB->get_records_sql($qry, $params);
- }
-
- // Return the cached stats.
- return $this->userstatusesstat[$userid];
- }
-
- /**
- *
- * @param type $userid
- * @param type $filters - An array things to filter by. For now only enddate is valid.
- * @return type
- */
- public function get_user_grade($userid, array $filters = null) {
- return attendance_get_user_grade($this->get_user_statuses_stat($userid, $filters), $this->get_statuses(true, true));
- }
-
- // For getting sessions count implemented simplest method - taken sessions.
- // It can have error if users don't have attendance info for some sessions.
- // In the future we can implement another methods:
- // * all sessions between user start enrolment date and now;
- // * all sessions between user start and end enrolment date.
- // While implementing those methods we need recalculate grades of all users
- // on session adding.
- public function get_user_max_grade($userid) {
- return attendance_get_user_max_grade($this->get_user_taken_sessions_count($userid), $this->get_statuses(true, true));
- }
-
public function update_users_grade($userids) {
- global $DB;
- $grades = array();
-
- if ($this->grade < 0) {
- $dbparams = array('id' => -($this->grade));
- $this->scale = $DB->get_record('scale', $dbparams);
- $scalearray = explode(',', $this->scale->scale);
- $attendancegrade = count($scalearray);
- } else {
- $attendancegrade = $this->grade;
- }
-
- foreach ($userids as $userid) {
- $grades[$userid] = new stdClass();
- $grades[$userid]->userid = $userid;
- $grades[$userid]->rawgrade = attendance_calc_user_grade_fraction($this->get_user_grade($userid),
- $this->get_user_max_grade($userid)) * $attendancegrade;
- }
-
- return grade_update('mod/attendance', $this->course->id, 'mod', 'attendance',
- $this->id, 0, $grades);
+ attendance_update_users_grade($this, $userids);
}
public function get_user_filtered_sessions_log($userid) {
@@ -950,7 +818,7 @@ class mod_attendance_structure {
WHERE $where AND (ats.groupid = 0 or gm.id is NOT NULL)
ORDER BY ats.sessdate ASC";
} else {
- $sql = "SELECT $id, ats.id, ats.groupid, ats.sessdate, ats.duration, ats.description,
+ $sql = "SELECT $id, ats.id, ats.groupid, ats.sessdate, ats.duration, ats.description, ats.statusset,
al.statusid, al.remarks, ats.studentscanmark
FROM {attendance_sessions} ats
RIGHT JOIN {attendance_log} al
@@ -981,7 +849,7 @@ class mod_attendance_structure {
$where = "ats.attendanceid = :aid AND ats.sessdate >= :csdate AND ats.groupid $gsql";
}
- $sql = "SELECT $id, ats.id, ats.groupid, ats.sessdate, ats.duration, ats.description,
+ $sql = "SELECT $id, ats.id, ats.groupid, ats.sessdate, ats.duration, ats.description, ats.statusset,
al.statusid, al.remarks, ats.studentscanmark
FROM {attendance_sessions} ats
LEFT JOIN {attendance_log} al
diff --git a/classes/summary.php b/classes/summary.php
new file mode 100644
index 0000000..9b5cf2b
--- /dev/null
+++ b/classes/summary.php
@@ -0,0 +1,268 @@
+.
+
+/**
+ * Class that computes summary of users points
+ *
+ * @package mod_attendance
+ * @copyright 2016 Antonio Carlos Mariani http://antonio.c.mariani@gmail.com
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once($CFG->dirroot . '/mod/attendance/locallib.php');
+
+class mod_attendance_summary {
+
+ /** @var int attendance instance identifier */
+ private $attendanceid;
+
+ /** @var stdclass course course data*/
+ private $course;
+
+ /** @var int groupmode*/
+ private $groupmode;
+
+ /** @var array userspoints (userid, numtakensessions, points, maxpoints) */
+ private $userspoints;
+
+ /** @var array pointsbygroup (groupid, numsessions, maxpoints) */
+ private $maxpointsbygroupsessions;
+
+ /**
+ * Initializes the class
+ *
+ * @param int attendance instance identifier
+ * @param array userids user instances identifier
+ * @param int $startdate Attendance sessions startdate
+ * @param int $enddate Attendance sessions enddate
+ */
+ public function __construct($attendanceid, $userids=array(), $startdate = '', $enddate = '') {
+ $this->attendanceid = $attendanceid;
+
+ $this->compute_users_points($userids, $startdate, $enddate);
+ }
+
+ /**
+ * Returns true if the user has some session with points
+ *
+ * @param int userid User instance id
+ *
+ * @return boolean
+ */
+ public function has_taken_sessions($userid) {
+ return isset($this->userspoints[$userid]);
+ }
+
+ /**
+ * Returns true if the corresponding attendance instance is currently configure to work with grades (points)
+ *
+ * @return boolean
+ */
+ public function with_groups() {
+ return $this->groupmode > 0;
+ }
+
+ /**
+ * Returns the groupmode of the corresponding attendance instance
+ *
+ * @return int
+ */
+ public function get_groupmode() {
+ return $this->groupmode;
+ }
+
+ /**
+ * Returns the percentages of each user related to the taken sessions
+ *
+ * @return array
+ */
+ public function get_user_taken_sessions_percentages() {
+ $percentages = array();
+
+ foreach ($this->userspoints as $userid => $userpoints) {
+ $percentages[$userid] = attendance_calc_fraction($userpoints->points, $userpoints->maxpoints);
+ }
+
+ return $percentages;
+ }
+
+ /**
+ * Returns a summary of the points assigned to the user related to the taken sessions
+ *
+ * @param int userid User instance id
+ *
+ * @return array
+ */
+ public function get_taken_sessions_summary_for($userid) {
+ $usersummary = new stdClass();
+ if ($this->has_taken_sessions($userid)) {
+ $usersummary->numtakensessions = $this->userspoints[$userid]->numtakensessions;
+ $usersummary->takensessionspoints = $this->userspoints[$userid]->points;
+ $usersummary->takensessionsmaxpoints = $this->userspoints[$userid]->maxpoints;
+ } else {
+ $usersummary->numtakensessions = 0;
+ $usersummary->takensessionspoints = 0;
+ $usersummary->takensessionsmaxpoints = 0;
+ }
+ $usersummary->takensessionspercentage = attendance_calc_fraction($usersummary->takensessionspoints,
+ $usersummary->takensessionsmaxpoints);
+
+ return $usersummary;
+ }
+
+ /**
+ * Returns a summary of the points assigned to the user, both related to taken sessions and related to all sessions
+ *
+ * @param int userid User instance id
+ *
+ * @return array
+ */
+ public function get_all_sessions_summary_for($userid) {
+ $usersummary = $this->get_taken_sessions_summary_for($userid);
+
+ if (!isset($this->maxpointsbygroupsessions)) {
+ $this->compute_maxpoints_by_group_session();
+ }
+
+ $usersummary->numallsessions = $this->maxpointsbygroupsessions[0]->numsessions;
+ $usersummary->allsessionsmaxpoints = $this->maxpointsbygroupsessions[0]->maxpoints;
+
+ if ($this->with_groups()) {
+ $groupids = array_keys(groups_get_all_groups($this->course->id, $userid));
+ foreach ($groupids as $gid) {
+ if (isset($this->maxpointsbygroupsessions[$gid])) {
+ $usersummary->numallsessions += $this->maxpointsbygroupsessions[$gid]->numsessions;
+ $usersummary->allsessionsmaxpoints += $this->maxpointsbygroupsessions[$gid]->maxpoints;
+ }
+ }
+ }
+ $usersummary->allsessionspercentage = attendance_calc_fraction($usersummary->takensessionspoints,
+ $usersummary->allsessionsmaxpoints);
+
+ $deltapoints = $usersummary->allsessionsmaxpoints - $usersummary->takensessionsmaxpoints;
+ $usersummary->maxpossiblepoints = $usersummary->takensessionspoints + $deltapoints;
+ $usersummary->maxpossiblepercentage = attendance_calc_fraction($usersummary->maxpossiblepoints,
+ $usersummary->allsessionsmaxpoints);
+
+ return $usersummary;
+ }
+
+ /**
+ * Computes the summary of points for the users that have some taken session
+ *
+ * @param array userids user instances identifier
+ * @param int $startdate Attendance sessions startdate
+ * @param int $enddate Attendance sessions enddate
+ * @return (userid, numtakensessions, points, maxpoints)
+ */
+ private function compute_users_points($userids=array(), $startdate = '', $enddate = '') {
+ global $DB;
+
+ list($this->course, $cm) = get_course_and_cm_from_instance($this->attendanceid, 'attendance');
+ $this->groupmode = $cm->effectivegroupmode;
+
+ $params = array(
+ 'attid' => $this->attendanceid,
+ 'attid2' => $this->attendanceid,
+ 'cstartdate' => $this->course->startdate,
+ );
+
+ $where = '';
+ if (!empty($userids)) {
+ list($insql, $inparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
+ $where .= ' AND atl.studentid ' . $insql;
+ $params = array_merge($params, $inparams);
+ }
+ if (!empty($startdate)) {
+ $where .= ' AND ats.sessdate >= :startdate';
+ $params['startdate'] = $startdate;
+ }
+ if (!empty($enddate)) {
+ $where .= ' AND ats.sessdate < :enddate ';
+ $params['enddate'] = $enddate;
+ }
+
+ $joingroup = '';
+ if ($this->with_groups()) {
+ $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)';
+ } else {
+ $where .= ' AND ats.groupid = 0';
+ }
+
+ $sql = " SELECT atl.studentid AS userid, COUNT(DISTINCT ats.id) AS numtakensessions,
+ SUM(stg.grade) AS points, SUM(stm.maxgrade) AS maxpoints
+ FROM {attendance_sessions} ats
+ JOIN {attendance_log} atl ON (atl.sessionid = ats.id)
+ JOIN {attendance_statuses} stg ON (stg.id = atl.statusid AND stg.deleted = 0 AND stg.visible = 1)
+ JOIN (SELECT setnumber, MAX(grade) AS maxgrade
+ FROM {attendance_statuses}
+ WHERE attendanceid = :attid2
+ AND deleted = 0
+ AND visible = 1
+ GROUP BY setnumber) stm
+ ON (stm.setnumber = ats.statusset)
+ {$joingroup}
+ WHERE ats.attendanceid = :attid
+ AND ats.sessdate >= :cstartdate
+ AND ats.lasttakenby != 0
+ {$where}
+ GROUP BY atl.studentid";
+ $this->userspoints = $DB->get_records_sql($sql, $params);
+ }
+
+ /**
+ * Computes and store the maximum points possible for each group session
+ *
+ * @return null
+ */
+ private function compute_maxpoints_by_group_session() {
+ global $DB;
+
+ $params = array(
+ 'attid' => $this->attendanceid,
+ 'attid2' => $this->attendanceid,
+ 'cstartdate' => $this->course->startdate,
+ );
+
+ $where = '';
+ if (!$this->with_groups()) {
+ $where = 'AND sess.groupid = 0';
+ }
+
+ $sql = "SELECT sess.groupid, COUNT(*) AS numsessions, SUM(stamax.maxgrade) AS maxpoints
+ FROM {attendance_sessions} sess
+ JOIN (SELECT setnumber, MAX(grade) AS maxgrade
+ FROM {attendance_statuses}
+ WHERE attendanceid = :attid2
+ AND deleted = 0
+ AND visible = 1
+ GROUP BY setnumber) stamax
+ ON (stamax.setnumber = sess.statusset)
+ WHERE sess.attendanceid = :attid
+ AND sess.sessdate >= :cstartdate
+ {$where}
+ GROUP BY sess.groupid";
+ $this->maxpointsbygroupsessions = $DB->get_records_sql($sql, $params);
+
+ if (!isset($this->maxpointsbygroupsessions[0])) {
+ $gpoints = new stdClass();
+ $gpoints->numsessions = 0;
+ $gpoints->maxpoints = 0;
+ $this->maxpointsbygroupsessions[0] = $gpoints;
+ }
+ }
+}
diff --git a/export.php b/export.php
index e270487..ead107a 100644
--- a/export.php
+++ b/export.php
@@ -123,10 +123,9 @@ if ($formdata = $mform->get_data()) {
} else {
print_error('sessionsnotfound', 'attendance', $att->url_manage());
}
- if ($reportdata->gradable) {
- $data->tabhead[] = get_string('grade');
- $data->tabhead[] = get_string('percentage', 'attendance');
- }
+ $data->tabhead[] = get_string('takensessions', 'attendance');
+ $data->tabhead[] = get_string('points', 'attendance');
+ $data->tabhead[] = get_string('percentage', 'attendance');
$i = 0;
$data->table = array();
@@ -158,16 +157,13 @@ if ($formdata = $mform->get_data()) {
}
$cellsgenerator = new user_sessions_cells_text_generator($reportdata, $user);
$data->table[$i] = array_merge($data->table[$i], $cellsgenerator->get_cells(isset($formdata->includeremarks)));
- if ($reportdata->gradable) {
- $data->table[$i][] = format_float($reportdata->grades[$user->id]).' / '.
- format_float($reportdata->maxgrades[$user->id]);
- if ($reportdata->maxgrades[$user->id]) {
- $percent = $reportdata->grades[$user->id] * 100.0 / $reportdata->maxgrades[$user->id];
- } else {
- $percent = 0.0;
- }
- $data->table[$i][] = $percent;
- }
+
+ $usersummary = $reportdata->summary->get_taken_sessions_summary_for($user->id);
+ $data->table[$i][] = $usersummary->numtakensessions;
+ $data->table[$i][] = format_float($usersummary->takensessionspoints, 1, true, true) . ' / ' .
+ format_float($usersummary->takensessionsmaxpoints, 1, true, true);
+ $data->table[$i][] = format_float($usersummary->takensessionspercentage * 100);
+
$i++;
}
diff --git a/lang/en/attendance.php b/lang/en/attendance.php
index 8c1f312..18f6889 100644
--- a/lang/en/attendance.php
+++ b/lang/en/attendance.php
@@ -133,6 +133,8 @@ $string['indetail'] = 'In detail...';
$string['invalidsessionenddate'] = 'This date can not be earlier than the session date';
$string['invalidaction'] = 'You must select an action';
$string['jumpto'] = 'Jump to';
+$string['maxpossiblepoints'] = 'Maximum possible points';
+$string['maxpossiblepercentage'] = 'Maximum possible percentage';
$string['mergeuser'] = 'Merge user';
$string['modulename'] = 'Attendance';
$string['modulename_help'] = 'The attendance activity module enables a teacher to take attendance during class and students to view their own attendance record.
@@ -165,6 +167,8 @@ $string['olddate'] = 'Old date';
$string['onlyselectedusers'] = 'Export specific users';
$string['participant'] = 'Participant';
$string['percentage'] = 'Percentage';
+$string['percentagesessionscompleted'] = 'Percentage over taked sessions';
+$string['percentageallsessions'] = 'Percentage over all sessions';
$string['pluginname'] = 'Attendance';
$string['pluginadministration'] = 'Attendance administration';
$string['remark'] = 'Remark for: {$a}';
@@ -221,7 +225,8 @@ $string['sessiondays'] = 'Session Days';
$string['sessiondeleted'] = 'Session successfully deleted';
$string['sessionexist'] = 'Session not added (already exists)!';
$string['sessions'] = 'Sessions';
-$string['sessionscompleted'] = 'Sessions completed';
+$string['sessionscompleted'] = 'Taked sessions';
+$string['sessionstotal'] = 'Total number of sessions';
$string['sessionsids'] = 'IDs of sessions: ';
$string['sessiongenerated'] = 'One session was successfully generated';
$string['sessionsgenerated'] = '{$a} sessions were successfully generated';
@@ -255,7 +260,9 @@ $string['strftimedmyw'] = '%d.%m.%y (%a)';
$string['strftimehm'] = '%H:%M'; // Line added to allow display of time.
$string['strftimeshortdate'] = '%d.%m.%Y';
$string['studentid'] = 'Student ID';
+$string['summary'] = 'Summary';
$string['takeattendance'] = 'Take attendance';
+$string['takensessions'] = 'Taken sessions';
$string['tempaddform'] = 'Add temporary user';
$string['tempexists'] = 'There is already a temporary user with this email address';
$string['tempusers'] = 'Temporary users';
@@ -301,6 +308,8 @@ $string['submitattendance'] = 'Submit attendance';
$string['attendancenotset'] = 'You must set your attendance';
$string['export'] = 'Export';
$string['points'] = 'Points';
+$string['pointssessionscompleted'] = 'Points over taked sessions';
+$string['pointsallsessions'] = 'Points over all sessions';
$string['unknowngroup'] = 'Unknown group';
$string['notmember'] = 'not member';
diff --git a/lib.php b/lib.php
index eeb9d03..dad7d2f 100644
--- a/lib.php
+++ b/lib.php
@@ -250,7 +250,7 @@ function attendance_user_complete($course, $user, $mod, $attendance) {
require_once($CFG->libdir.'/gradelib.php');
if (has_capability('mod/attendance:canbelisted', $mod->context, $user->id)) {
- echo construct_full_user_stat_html_table($attendance, $course, $user, $mod);
+ echo construct_full_user_stat_html_table($attendance, $user);
}
}
@@ -276,7 +276,7 @@ function attendance_grade_item_update($attendance, $grades=null) {
if (!isset($attendance->courseid)) {
$attendance->courseid = $attendance->course;
}
- if (! $course = $DB->get_record('course', array('id' => $attendance->course))) {
+ if (!$DB->get_record('course', array('id' => $attendance->course))) {
error("Course is misconfigured");
}
@@ -284,7 +284,6 @@ function attendance_grade_item_update($attendance, $grades=null) {
$params = array('itemname' => $attendance->name, 'idnumber' => $attendance->cmidnumber);
} else {
// MDL-14303.
- $cm = get_coursemodule_from_instance('attendance', $attendance->id);
$params = array('itemname' => $attendance->name/*, 'idnumber'=>$attendance->id*/);
}
diff --git a/locallib.php b/locallib.php
index 9cd860e..22a5c1e 100644
--- a/locallib.php
+++ b/locallib.php
@@ -33,6 +33,7 @@ define('ATT_VIEW_MONTHS', 3);
define('ATT_VIEW_ALLPAST', 4);
define('ATT_VIEW_ALL', 5);
define('ATT_VIEW_NOTPRESENT', 6);
+define('ATT_VIEW_SUMMARY', 7);
define('ATT_SORT_LASTNAME', 1);
define('ATT_SORT_FIRSTNAME', 2);
@@ -88,86 +89,6 @@ function attendance_get_setname($attid, $statusset, $includevalues = true) {
return $statusname;
}
-function attendance_get_user_taken_sessions_count($attid, $coursestartdate, $userid, $coursemodule, $startdate = '', $enddate = '') {
- global $DB, $COURSE;
- $groupmode = groups_get_activity_groupmode($coursemodule, $COURSE);
- if (!empty($groupmode)) {
- $qry = "SELECT count(*) as cnt
- FROM {attendance_log} al
- JOIN {attendance_sessions} ats ON al.sessionid = ats.id
- LEFT JOIN {groups_members} gm ON gm.userid = al.studentid AND gm.groupid = ats.groupid
- WHERE ats.attendanceid = :aid AND
- ats.sessdate >= :cstartdate AND
- al.studentid = :uid AND
- (ats.groupid = 0 or gm.id is NOT NULL)";
- } else {
- $qry = "SELECT count(*) as cnt
- FROM {attendance_log} al
- JOIN {attendance_sessions} ats
- ON al.sessionid = ats.id
- WHERE ats.attendanceid = :aid AND
- ats.sessdate >= :cstartdate AND
- al.studentid = :uid";
- }
- $params = array(
- 'aid' => $attid,
- 'cstartdate' => $coursestartdate,
- 'uid' => $userid);
-
- if (!empty($startdate) && !empty($enddate)) {
- $qry .= ' AND sessdate >= :sdate AND sessdate < :edate ';
- $params['sdate'] = $startdate;
- $params['edate'] = $enddate;
- }
-
- return $DB->count_records_sql($qry, $params);
-}
-
-function attendance_get_user_statuses_stat($attid, $coursestartdate, $userid, $coursemodule) {
- global $DB, $COURSE;
- $groupmode = groups_get_activity_groupmode($coursemodule, $COURSE);
- if (!empty($groupmode)) {
- $qry = "SELECT al.statusid, count(al.statusid) AS stcnt
- FROM {attendance_log} al
- JOIN {attendance_sessions} ats ON al.sessionid = ats.id
- LEFT JOIN {groups_members} gm ON gm.userid = al.studentid AND gm.groupid = ats.groupid
- WHERE ats.attendanceid = :aid AND
- ats.sessdate >= :cstartdate AND
- al.studentid = :uid AND
- (ats.groupid = 0 or gm.id is NOT NULL)
- GROUP BY al.statusid";
- } else {
- $qry = "SELECT al.statusid, count(al.statusid) AS stcnt
- FROM {attendance_log} al
- JOIN {attendance_sessions} ats
- ON al.sessionid = ats.id
- WHERE ats.attendanceid = :aid AND
- ats.sessdate >= :cstartdate AND
- al.studentid = :uid
- GROUP BY al.statusid";
- }
- $params = array(
- 'aid' => $attid,
- 'cstartdate' => $coursestartdate,
- 'uid' => $userid);
-
- return $DB->get_records_sql($qry, $params);
-}
-
-function attendance_get_user_grade($userstatusesstat, $statuses) {
- $sum = 0;
- foreach ($userstatusesstat as $stat) {
- $sum += $stat->stcnt * $statuses[$stat->statusid]->grade;
- }
-
- return $sum;
-}
-
-function attendance_get_user_max_grade($sesscount, $statuses) {
- reset($statuses);
- return current($statuses)->grade * $sesscount;
-}
-
function attendance_get_user_courses_attendances($userid) {
global $DB;
@@ -189,71 +110,18 @@ function attendance_get_user_courses_attendances($userid) {
}
/**
- * Used to caclulate usergrade based on rawgrade and max grade.
+ * Used to calculate a fraction based on the part and total values
*
- * @param float $grade - raw grade for user
- * @param float $maxgrade - maxgrade for this session.
- * @return float the calculated grade.
+ * @param float $part - part of the total value
+ * @param float $total - total value.
+ * @return float the calculated fraction.
*/
-function attendance_calc_user_grade_fraction($grade, $maxgrade) {
- if ($maxgrade == 0) {
+function attendance_calc_fraction($part, $total) {
+ if ($total == 0) {
return 0;
} else {
- return $grade / $maxgrade;
- }
-}
-
-/**
- * Update all user grades - used when settings have changed.
- *
- * @param mod_attendance_structure $attendance - Full attendance class.
- * @param stdclass $coursemodule - full coursemodule record
- * @return float the calculated grade.
- */
-function attendance_update_all_users_grades(mod_attendance_structure $attendance, $coursemodule) {
- global $DB;
- $grades = array();
- $course = $attendance->course;
-
- $userids = array_keys(get_enrolled_users($attendance->context, 'mod/attendance:canbelisted', 0, 'u.id'));
- $attgrades = grade_get_grades($course->id, 'mod', 'attendance', $attendance->id, $userids);
-
- $usergrades = [];
- if (!empty($attgrades->items[0]) and !empty($attgrades->items[0]->grades)) {
- $usergrades = $attgrades->items[0]->grades;
- }
- $statuses = attendance_get_statuses($attendance->id);
- if ($attendance->grade < 0) {
- $dbparams = array('id' => -($attendance->grade));
- $scale = $DB->get_record('scale', $dbparams);
- $scalearray = explode(',', $scale->scale);
- $gradebookmaxgrade = count($scalearray);
- } else {
- $gradebookmaxgrade = $attendance->grade;
- }
- foreach ($usergrades as $userid => $existinggrade) {
- if (is_null($existinggrade->grade)) {
- // Don't update grades where one doesn't exist yet.
- continue;
- }
- $grade = new stdClass;
- $grade->userid = $userid;
- $userstatusesstat = attendance_get_user_statuses_stat($attendance->id, $course->startdate, $userid, $coursemodule);
- $usertakensesscount = attendance_get_user_taken_sessions_count($attendance->id, $course->startdate, $userid, $coursemodule);
- $usergrade = attendance_get_user_grade($userstatusesstat, $statuses);
- $usermaxgrade = attendance_get_user_max_grade($usertakensesscount, $statuses);
- $grade->rawgrade = attendance_calc_user_grade_fraction($usergrade, $usermaxgrade) * $gradebookmaxgrade;
- $grades[$userid] = $grade;
- }
-
- if (!empty($grades)) {
- $result = grade_update('mod/attendance', $course->id, 'mod', 'attendance',
- $attendance->id, 0, $grades);
- } else {
- $result = true;
+ return $part / $total;
}
-
- return $result;
}
/**
@@ -308,3 +176,66 @@ function attendance_get_max_statusset($attendanceid) {
}
return 0;
}
+
+/**
+ * Returns the maxpoints for each statusset
+ *
+ * @param array statuses
+ * @return array
+ */
+function attendance_get_statusset_maxpoints($statuses) {
+ $statussetmaxpoints = array();
+ foreach ($statuses as $st) {
+ if (!isset($statussetmaxpoints[$st->setnumber])) {
+ $statussetmaxpoints[$st->setnumber] = $st->grade;
+ }
+ }
+ return $statussetmaxpoints;
+}
+
+/**
+ * Update user grades
+ *
+ * @param mixed mod_attendance_structure|stdClass $attendance
+ * @param array $userids
+ */
+function attendance_update_users_grade($attendance, $userids=array()) {
+ global $DB;
+
+ if (empty($attendance->grade)) {
+ return false;
+ }
+
+ list($course, $cm) = get_course_and_cm_from_instance($attendance->id, 'attendance');
+
+ $summary = new mod_attendance_summary($attendance->id, $userids);
+
+ if (empty($userids)) {
+ $context = context_module::instance($cm->id);
+ $userids = array_keys(get_enrolled_users($context, 'mod/attendance:canbelisted', 0, 'u.id'));
+ }
+
+ if ($attendance->grade < 0) {
+ $dbparams = array('id' => -($attendance->grade));
+ $scale = $DB->get_record('scale', $dbparams);
+ $scalearray = explode(',', $scale->scale);
+ $attendancegrade = count($scalearray);
+ } else {
+ $attendancegrade = $attendance->grade;
+ }
+
+ $grades = array();
+ foreach ($userids as $userid) {
+ $grades[$userid] = new stdClass();
+ $grades[$userid]->userid = $userid;
+
+ if ($summary->has_taken_sessions($userid)) {
+ $usersummary = $summary->get_taken_sessions_summary_for($userid);
+ $grades[$userid]->rawgrade = $usersummary->takensessionspercentage * $attendancegrade;
+ } else {
+ $grades[$userid]->rawgrade = null;
+ }
+ }
+
+ return grade_update('mod/attendance', $course->id, 'mod', 'attendance', $attendance->id, 0, $grades);
+}
diff --git a/preferences.php b/preferences.php
index 061912a..194dd54 100644
--- a/preferences.php
+++ b/preferences.php
@@ -122,9 +122,7 @@ switch ($att->pageparams->action) {
$status = $statuses[$id];
$errors[$id] = $att->update_status($status, $acronym[$id], $description[$id], $grade[$id], null);
}
- if ($att->grade > 0) {
- attendance_update_all_users_grades($att, $cm);
- }
+ attendance_update_users_grade($att);
break;
}
diff --git a/renderables.php b/renderables.php
index 0c7f764..1131573 100644
--- a/renderables.php
+++ b/renderables.php
@@ -128,7 +128,7 @@ class attendance_filter_controls implements renderable {
private $urlpath;
private $urlparams;
- private $att;
+ public $att;
public function __construct(mod_attendance_structure $att, $report = false) {
global $PAGE;
@@ -138,7 +138,7 @@ class attendance_filter_controls implements renderable {
$this->cm = $att->cm;
// This is a report control only if $reports is true and the attendance block can be graded.
- $this->reportcontrol = $report && ($att->grade > 0);
+ $this->reportcontrol = $report;
$this->curdate = $att->pageparams->curdate;
@@ -336,17 +336,9 @@ class attendance_user_data implements renderable {
public $pageparams;
- public $stat;
-
public $statuses;
- public $gradable;
-
- public $grade;
-
- public $maxgrade;
-
- public $decimalpoints;
+ public $summary;
public $filtercontrols;
@@ -360,26 +352,15 @@ class attendance_user_data implements renderable {
private $urlparams;
public function __construct(mod_attendance_structure $att, $userid) {
- global $CFG;
-
$this->user = $att->get_user($userid);
$this->pageparams = $att->pageparams;
- if (!$this->decimalpoints = grade_get_setting($att->course->id, 'decimalpoints')) {
- $this->decimalpoints = $CFG->grade_decimalpoints;
- }
-
if ($this->pageparams->mode == mod_attendance_view_page_params::MODE_THIS_COURSE) {
$this->statuses = $att->get_statuses(true, true);
- $this->stat = $att->get_user_stat($userid);
-
- $this->gradable = $att->grade > 0;
- if ($this->gradable) {
- $this->grade = $att->get_user_grade($userid);
- $this->maxgrade = $att->get_user_max_grade($userid);
- }
+ $this->summary = new mod_attendance_summary($att->id, array($userid), $att->pageparams->startdate,
+ $att->pageparams->enddate);
$this->filtercontrols = new attendance_filter_controls($att);
@@ -389,40 +370,15 @@ class attendance_user_data implements renderable {
} else {
$this->coursesatts = attendance_get_user_courses_attendances($userid);
$this->statuses = array();
- $this->stat = array();
- $this->gradable = array();
- $this->grade = array();
- $this->maxgrade = array();
+ $this->summary = array();
foreach ($this->coursesatts as $atid => $ca) {
// Check to make sure the user can view this cm.
if (!get_fast_modinfo($ca->courseid)->instances['attendance'][$ca->attid]->uservisible) {
unset($this->courseatts[$atid]);
continue;
}
- $statuses = attendance_get_statuses($ca->attid);
- $usertakensessionscount = attendance_get_user_taken_sessions_count($ca->attid, $ca->coursestartdate, $userid, $att->cm);
- $userstatusesstat = attendance_get_user_statuses_stat($ca->attid, $ca->coursestartdate, $userid, $att->cm);
-
- $this->statuses[$ca->attid] = $statuses;
-
- $this->stat[$ca->attid]['completed'] = $usertakensessionscount;
- $this->stat[$ca->attid]['statuses'] = $userstatusesstat;
-
- $this->gradable[$ca->attid] = $ca->attgrade > 0;
-
- if ($this->gradable[$ca->attid]) {
- $this->grade[$ca->attid] = attendance_get_user_grade($userstatusesstat, $statuses);
- // For getting sessions count implemented simplest method - taken sessions.
- // It can have error if users don't have attendance info for some sessions.
- // In the future we can implement another methods:
- // * all sessions between user start enrolment date and now;
- // * all sessions between user start and end enrolment date.
- $this->maxgrade[$ca->attid] = attendance_get_user_max_grade($usertakensessionscount, $statuses);
- } else {
- // For more comfortable and universal work with arrays.
- $this->grade[$ca->attid] = null;
- $this->maxgrade[$ca->attid] = null;
- }
+ $this->statuses[$ca->attid] = attendance_get_statuses($ca->attid);
+ $this->summary[$ca->attid] = new mod_attendance_summary($ca->attid, array($userid));
}
}
$this->urlpath = $att->url_view()->out_omit_querystring();
@@ -449,25 +405,15 @@ class attendance_report_data implements renderable {
// Includes disablrd/deleted statuses.
public $allstatuses;
- public $gradable;
-
- public $decimalpoints;
-
public $usersgroups = array();
public $sessionslog = array();
- public $usersstats = array();
-
- public $grades = array();
-
- public $maxgrades = array();
+ public $summary = array();
public $att;
public function __construct(mod_attendance_structure $att) {
- global $CFG;
-
$currenttime = time();
if ($att->pageparams->view == ATT_VIEW_NOTPRESENT) {
$att->pageparams->enddate = $currenttime;
@@ -492,32 +438,21 @@ class attendance_report_data implements renderable {
$this->statuses = $att->get_statuses(true, true);
$this->allstatuses = $att->get_statuses(false, true);
- $this->gradable = $att->grade > 0;
-
- if (!$this->decimalpoints = grade_get_setting($att->course->id, 'decimalpoints')) {
- $this->decimalpoints = $CFG->grade_decimalpoints;
+ if ($att->pageparams->view == ATT_VIEW_SUMMARY) {
+ $this->summary = new mod_attendance_summary($att->id);
+ } else {
+ $this->summary = new mod_attendance_summary($att->id, array_keys($this->users),
+ $att->pageparams->startdate, $att->pageparams->enddate);
}
- $maxgrade = attendance_get_user_max_grade(count($this->sessions), $this->statuses);
-
foreach ($this->users as $key => $user) {
- $grade = 0;
- if ($this->gradable) {
- $grade = $att->get_user_grade($user->id, array('enddate' => $currenttime));
- $totalgrade = $att->get_user_grade($user->id);
- }
-
- if ($att->pageparams->view != ATT_VIEW_NOTPRESENT || $grade < $maxgrade) {
+ $usersummary = $this->summary->get_taken_sessions_summary_for($user->id);
+ if ($att->pageparams->view != ATT_VIEW_NOTPRESENT ||
+ $usersummary->takensessionspoints < $usersummary->takensessionsmaxpoints ||
+ $usersummary->takensessionsmaxpoints == 0) {
$this->usersgroups[$user->id] = groups_get_all_groups($att->course->id, $user->id);
$this->sessionslog[$user->id] = $att->get_user_filtered_sessions_log($user->id);
-
- $this->usersstats[$user->id] = $att->get_user_statuses_stat($user->id);
-
- if ($this->gradable) {
- $this->grades[$user->id] = $totalgrade;
- $this->maxgrades[$user->id] = $att->get_user_max_grade($user->id);;
- }
} else {
unset($this->users[$key]);
}
diff --git a/renderer.php b/renderer.php
index fe86450..e8c7b36 100644
--- a/renderer.php
+++ b/renderer.php
@@ -176,12 +176,15 @@ class mod_attendance_renderer extends plugin_renderer_base {
protected function render_view_controls(attendance_filter_controls $fcontrols) {
$views[ATT_VIEW_ALL] = get_string('all', 'attendance');
$views[ATT_VIEW_ALLPAST] = get_string('allpast', 'attendance');
- if ($fcontrols->reportcontrol) {
+ if ($fcontrols->reportcontrol && $fcontrols->att->grade > 0) {
$views[ATT_VIEW_NOTPRESENT] = get_string('lowgrade', 'attendance');
}
$views[ATT_VIEW_MONTHS] = get_string('months', 'attendance');
$views[ATT_VIEW_WEEKS] = get_string('weeks', 'attendance');
$views[ATT_VIEW_DAYS] = get_string('days', 'attendance');
+ if ($fcontrols->reportcontrol) {
+ $views[ATT_VIEW_SUMMARY] = get_string('summary', 'attendance');
+ }
$viewcontrols = '';
foreach ($views as $key => $sview) {
if ($key != $fcontrols->pageparams->view) {
@@ -299,8 +302,6 @@ class mod_attendance_renderer extends plugin_renderer_base {
}
protected function render_sess_manage_control(attendance_manage_data $sessdata) {
- global $OUTPUT;
-
$table = new html_table();
$table->attributes['class'] = ' ';
$table->width = '100%';
@@ -735,8 +736,8 @@ class mod_attendance_renderer extends plugin_renderer_base {
if ($userdata->pageparams->mode == mod_attendance_view_page_params::MODE_THIS_COURSE) {
$o .= html_writer::empty_tag('hr');
- $o .= construct_user_data_stat($userdata->stat, $userdata->statuses,
- $userdata->gradable, $userdata->grade, $userdata->maxgrade, $userdata->decimalpoints);
+ $o .= construct_user_data_stat($userdata->summary->get_all_sessions_summary_for($userdata->user->id),
+ $userdata->pageparams->view);
$o .= $this->render_attendance_filter_controls($userdata->filtercontrols);
@@ -752,9 +753,12 @@ class mod_attendance_renderer extends plugin_renderer_base {
}
$o .= html_writer::tag('h4', $ca->attname);
- $o .= construct_user_data_stat($userdata->stat[$ca->attid], $userdata->statuses[$ca->attid],
- $userdata->gradable[$ca->attid], $userdata->grade[$ca->attid],
- $userdata->maxgrade[$ca->attid], $userdata->decimalpoints);
+ if (isset($userdata->summary[$ca->attid])) {
+ $usersummary = $userdata->summary[$ca->attid]->get_all_sessions_summary_for($userdata->user->id);
+ } else {
+ $usersummary = null;
+ }
+ $o .= construct_user_data_stat($usersummary, ATT_VIEW_ALL);
}
}
@@ -771,10 +775,13 @@ class mod_attendance_renderer extends plugin_renderer_base {
get_string('time'),
get_string('description', 'attendance'),
get_string('status', 'attendance'),
+ get_string('points', 'attendance'),
get_string('remarks', 'attendance')
);
- $table->align = array('', '', '', 'left', 'left', 'center', 'left', 'center');
- $table->size = array('1px', '1px', '1px', '1px', '*', '1px', '1px', '*');
+ $table->align = array('', '', '', 'left', 'left', 'center', 'center', 'center');
+ $table->size = array('1px', '1px', '1px', '1px', '*', '*', '1px', '*');
+
+ $statussetmaxpoints = attendance_get_statusset_maxpoints($userdata->statuses);
$i = 0;
foreach ($userdata->sessionslog as $sess) {
@@ -793,7 +800,10 @@ class mod_attendance_renderer extends plugin_renderer_base {
$row->cells[] = $this->construct_time($sess->sessdate, $sess->duration);
$row->cells[] = $sess->description;
if (isset($sess->statusid)) {
- $row->cells[] = $userdata->statuses[$sess->statusid]->description;
+ $status = $userdata->statuses[$sess->statusid];
+ $row->cells[] = $status->description;
+ $row->cells[] = format_float($status->grade, 1, true, true) . ' / ' .
+ format_float($statussetmaxpoints[$status->setnumber], 1, true, true);
$row->cells[] = $sess->remarks;
} else if ($sess->sessdate < $userdata->user->enrolmentstart) {
$cell = new html_table_cell(get_string('enrolmentstart', 'attendance',
@@ -815,6 +825,7 @@ class mod_attendance_renderer extends plugin_renderer_base {
$row->cells[] = $cell;
} else { // Student cannot mark their own attendace.
$row->cells[] = '?';
+ $row->cells[] = '? / ' . format_float($statussetmaxpoints[$sess->statusset], 1, true, true);
$row->cells[] = '';
}
}
@@ -843,6 +854,9 @@ class mod_attendance_renderer extends plugin_renderer_base {
$table = new html_table();
$table->attributes['class'] = 'generaltable attwidth';
+ if ($reportdata->pageparams->view == ATT_VIEW_SUMMARY) {
+ $table->attributes['class'] .= ' summaryreport';
+ }
// User picture.
$table->head[] = '';
@@ -882,15 +896,36 @@ class mod_attendance_renderer extends plugin_renderer_base {
$table->size[] = '1px';
}
- foreach ($reportdata->statuses as $status) {
- $table->head[] = $status->acronym;
+ $table->head[] = get_string('takensessions', 'attendance');
+ $table->align[] = 'center';
+ $table->size[] = '1px';
+
+ $table->head[] = get_string('points', 'attendance');
+ $table->align[] = 'center';
+ $table->size[] = '1px';
+
+ $table->head[] = get_string('percentage', 'attendance');
+ $table->align[] = 'center';
+ $table->size[] = '1px';
+
+ if ($reportdata->pageparams->view == ATT_VIEW_SUMMARY) {
+ $table->head[] = get_string('sessionstotal', 'attendance');
$table->align[] = 'center';
$table->size[] = '1px';
- $sessionstats[$status->id] = 0;
- }
- if ($reportdata->gradable) {
- $table->head[] = get_string('grade');
+ $table->head[] = get_string('pointsallsessions', 'attendance');
+ $table->align[] = 'center';
+ $table->size[] = '1px';
+
+ $table->head[] = get_string('percentageallsessions', 'attendance');
+ $table->align[] = 'center';
+ $table->size[] = '1px';
+
+ $table->head[] = get_string('maxpossiblepoints', 'attendance');
+ $table->align[] = 'center';
+ $table->size[] = '1px';
+
+ $table->head[] = get_string('maxpossiblepercentage', 'attendance');
$table->align[] = 'center';
$table->size[] = '1px';
}
@@ -910,17 +945,25 @@ class mod_attendance_renderer extends plugin_renderer_base {
$cellsgenerator = new user_sessions_cells_html_generator($reportdata, $user);
$row->cells = array_merge($row->cells, $cellsgenerator->get_cells(true));
- foreach ($reportdata->statuses as $status) {
- if (array_key_exists($status->id, $reportdata->usersstats[$user->id])) {
- $row->cells[] = $reportdata->usersstats[$user->id][$status->id]->stcnt;
- } else {
- // No attendance data for this $status => no statistic for this status.
- $row->cells[] = 0;
- }
+ if ($reportdata->pageparams->view == ATT_VIEW_SUMMARY) {
+ $usersummary = $reportdata->summary->get_all_sessions_summary_for($user->id);
+ } else {
+ $usersummary = $reportdata->summary->get_taken_sessions_summary_for($user->id);
}
-
- if ($reportdata->gradable) {
- $row->cells[] = format_float($reportdata->grades[$user->id]).' / '.format_float($reportdata->maxgrades[$user->id]);
+ $row->cells[] = $usersummary->numtakensessions;
+ $row->cells[] = format_float($usersummary->takensessionspoints, 1, true, true) . ' / ' .
+ format_float($usersummary->takensessionsmaxpoints, 1, true, true);
+ $row->cells[] = format_float($usersummary->takensessionspercentage * 100) . '%';
+
+ if ($reportdata->pageparams->view == ATT_VIEW_SUMMARY) {
+ $row->cells[] = $usersummary->numallsessions;
+ $row->cells[] = format_float($usersummary->takensessionspoints, 1, true, true) . ' / ' .
+ format_float($usersummary->allsessionsmaxpoints, 1, true, true);
+ $row->cells[] = format_float($usersummary->allsessionspercentage * 100) . '%';
+
+ $row->cells[] = format_float($usersummary->maxpossiblepoints, 1, true, true) . ' / ' .
+ format_float($usersummary->allsessionsmaxpoints, 1, true, true);
+ $row->cells[] = format_float($usersummary->maxpossiblepercentage * 100) . '%';
}
if ($bulkmessagecapability) { // Create the checkbox for bulk messaging.
@@ -936,22 +979,30 @@ class mod_attendance_renderer extends plugin_renderer_base {
$statrow->cells[] = '';
$statrow->cells[] = get_string('summary');
foreach ($reportdata->sessions as $sess) {
+ $sessionstats = array();
+ foreach ($reportdata->statuses as $status) {
+ if ($status->setnumber == $sess->statusset) {
+ $status->count = 0;
+ $sessionstats[$status->id] = $status;
+ }
+ }
+
foreach ($reportdata->users as $user) {
- foreach ($reportdata->statuses as $status) {
- if (!empty($reportdata->sessionslog[$user->id][$sess->id])) {
- if ($reportdata->sessionslog[$user->id][$sess->id]->statusid == $status->id) {
- $sessionstats[$status->id]++;
- }
+ if (!empty($reportdata->sessionslog[$user->id][$sess->id])) {
+ $statusid = $reportdata->sessionslog[$user->id][$sess->id]->statusid;
+ if (isset($sessionstats[$statusid]->count)) {
+ $sessionstats[$statusid]->count++;
}
}
}
$statsoutput = '
';
- foreach ($reportdata->statuses as $status) {
- $statsoutput .= "$status->description:".$sessionstats[$status->id]."
";
+ foreach ($sessionstats as $status) {
+ $statsoutput .= "$status->description: {$status->count}
";
}
- $statrow->cells[] = $statsoutput;
-
+ $cell = new html_table_cell($statsoutput);
+ $cell->style = 'white-space:nowrap;';
+ $statrow->cells[] = $cell;
}
$table->data[] = $statrow;
@@ -1008,7 +1059,7 @@ class mod_attendance_renderer extends plugin_renderer_base {
$table->head = array('#',
get_string('acronym', 'attendance'),
get_string('description'),
- get_string('grade'),
+ get_string('points', 'attendance'),
get_string('action'));
$table->align = array('center', 'center', 'center', 'center', 'center', 'center');
diff --git a/renderhelpers.php b/renderhelpers.php
index e89dbbb..bf07176 100644
--- a/renderhelpers.php
+++ b/renderhelpers.php
@@ -49,7 +49,10 @@ class user_sessions_cells_generator {
if (array_key_exists($sess->id, $this->reportdata->sessionslog[$this->user->id])) {
$statusid = $this->reportdata->sessionslog[$this->user->id][$sess->id]->statusid;
if (array_key_exists($statusid, $this->reportdata->statuses)) {
- $this->construct_existing_status_cell($this->reportdata->statuses[$statusid]->acronym);
+ $points = format_float($this->reportdata->statuses[$statusid]->grade, 1, true, true);
+ $maxpoints = format_float($sess->maxpoints, 1, true, true);
+ $this->construct_existing_status_cell($this->reportdata->statuses[$statusid]->acronym .
+ " ({$points}/{$maxpoints})");
} else {
$this->construct_hidden_status_cell($this->reportdata->allstatuses[$statusid]->acronym);
}
@@ -228,65 +231,66 @@ function construct_session_full_date_time($datetime, $duration) {
return $sessinfo;
}
-function construct_user_data_stat($stat, $statuses, $gradable, $grade, $maxgrade, $decimalpoints) {
- global $OUTPUT;
-
+function construct_user_data_stat($usersummary, $view) {
$stattable = new html_table();
$stattable->attributes['class'] = 'attlist';
$row = new html_table_row();
- $row->cells[] = get_string('sessionscompleted', 'attendance').':';
- $row->cells[] = $stat['completed'];
+ $row->attributes['class'] = 'normal';
+ $row->cells[] = get_string('sessionscompleted', 'attendance') . ':';
+ $row->cells[] = $usersummary->numtakensessions;
$stattable->data[] = $row;
- foreach ($statuses as $st) {
+ $row = new html_table_row();
+ $row->attributes['class'] = 'normal';
+ $row->cells[] = get_string('pointssessionscompleted', 'attendance') . ':';
+ $row->cells[] = format_float($usersummary->takensessionspoints, 1, true, true) . ' / ' .
+ format_float($usersummary->takensessionsmaxpoints, 1, true, true);
+ $stattable->data[] = $row;
+
+ $row = new html_table_row();
+ $row->attributes['class'] = 'normal';
+ $row->cells[] = get_string('percentagesessionscompleted', 'attendance') . ':';
+ $row->cells[] = format_float($usersummary->takensessionspercentage * 100) . '%';
+ $stattable->data[] = $row;
+
+ if ($view == ATT_VIEW_ALL) {
+ $row = new html_table_row();
+ $row->attributes['class'] = 'highlight';
+ $row->cells[] = get_string('sessionstotal', 'attendance') . ':';
+ $row->cells[] = $usersummary->numallsessions;
+ $stattable->data[] = $row;
+
$row = new html_table_row();
- $row->cells[] = $st->description . ':';
- $row->cells[] = array_key_exists($st->id, $stat['statuses']) ? $stat['statuses'][$st->id]->stcnt : 0;
+ $row->attributes['class'] = 'highlight';
+ $row->cells[] = get_string('pointsallsessions', 'attendance') . ':';
+ $row->cells[] = format_float($usersummary->takensessionspoints, 1, true, true) . ' / ' .
+ format_float($usersummary->allsessionsmaxpoints, 1, true, true);
+ $stattable->data[] = $row;
+ $row = new html_table_row();
+ $row->attributes['class'] = 'highlight';
+ $row->cells[] = get_string('percentageallsessions', 'attendance') . ':';
+ $row->cells[] = format_float($usersummary->allsessionspercentage * 100) . '%';
$stattable->data[] = $row;
- }
- if ($gradable) {
$row = new html_table_row();
- $row->cells[] = get_string('attendancegrade', 'attendance') .
- $OUTPUT->help_icon('gradebookexplanation', 'attendance') . ':';
- $row->cells[] = format_float($grade) . ' / ' . format_float($maxgrade);
+ $row->attributes['class'] = 'normal';
+ $row->cells[] = get_string('maxpossiblepoints', 'attendance') . ':';
+ $row->cells[] = format_float($usersummary->maxpossiblepoints, 1, true, true) . ' / ' .
+ format_float($usersummary->allsessionsmaxpoints, 1, true, true);
$stattable->data[] = $row;
$row = new html_table_row();
- $row->cells[] = get_string('attendancepercent', 'attendance') . ':';
- if ($maxgrade == 0) {
- $percent = 0;
- } else {
- $percent = $grade / $maxgrade * 100;
- }
- $row->cells[] = format_float(sprintf("%0.{$decimalpoints}f", $percent));
+ $row->attributes['class'] = 'normal';
+ $row->cells[] = get_string('maxpossiblepercentage', 'attendance') . ':';
+ $row->cells[] = format_float($usersummary->maxpossiblepercentage * 100) . '%';
$stattable->data[] = $row;
}
return html_writer::table($stattable);
}
-function construct_full_user_stat_html_table($attendance, $course, $user, $coursemodule) {
- global $CFG;
- $gradeable = $attendance->grade > 0;
- $statuses = attendance_get_statuses($attendance->id);
- $userstatusesstat = attendance_get_user_statuses_stat($attendance->id, $course->startdate, $user->id, $coursemodule);
- $stat['completed'] = attendance_get_user_taken_sessions_count($attendance->id, $course->startdate, $user->id, $coursemodule);
- $stat['statuses'] = $userstatusesstat;
- if ($gradeable) {
- $grade = attendance_get_user_grade($userstatusesstat, $statuses);
- $maxgrade = attendance_get_user_max_grade(attendance_get_user_taken_sessions_count($attendance->id, $course->startdate,
- $user->id, $coursemodule), $statuses);
- if (!$decimalpoints = grade_get_setting($course->id, 'decimalpoints')) {
- $decimalpoints = $CFG->grade_decimalpoints;
- }
- } else {
- $grade = 0;
- $maxgrade = 0;
- $decimalpoints = 0;
- }
-
- return construct_user_data_stat($stat, $statuses,
- $gradeable, $grade, $maxgrade, $decimalpoints);
+function construct_full_user_stat_html_table($attendance, $user) {
+ $summary = new mod_attendance_summary($attendance->id, $user->id);
+ return construct_user_data_stat($summary->get_all_sessions_summary_for($user->id), ATT_VIEW_ALL);
}
diff --git a/sessions.php b/sessions.php
index dc790f8..f879a1a 100644
--- a/sessions.php
+++ b/sessions.php
@@ -113,9 +113,7 @@ switch ($att->pageparams->action) {
if (isset($confirm) && confirm_sesskey()) {
$att->delete_sessions(array($sessionid));
- if ($att->grade > 0) {
- attendance_update_all_users_grades($att, $cm);
- }
+ attendance_update_users_grade($att);
redirect($att->url_manage(), get_string('sessiondeleted', 'attendance'));
}
@@ -142,9 +140,7 @@ switch ($att->pageparams->action) {
$sessionsids = explode('_', $sessionsids);
$att->delete_sessions($sessionsids);
- if ($att->grade > 0) {
- attendance_update_all_users_grades($att, $cm);
- }
+ attendance_update_users_grade($att);
redirect($att->url_manage(), get_string('sessiondeleted', 'attendance'));
}
$sessid = optional_param_array('sessid', '', PARAM_SEQUENCE);
diff --git a/styles.css b/styles.css
index 4186842..52a860a 100644
--- a/styles.css
+++ b/styles.css
@@ -17,7 +17,7 @@
}
.path-mod-attendance .attfiltercontrols {
- margin-bottom: 10px;
+ margin-bottom: 10px !important;
margin-right:auto;
margin-left:auto;
}
@@ -164,4 +164,16 @@
.path-mod-attendance .attendancestatus-A {
color: red;
-}
\ No newline at end of file
+}
+
+.path-mod-attendance .summaryreport .c5 {
+ background-color: #EAEAEA;
+}
+
+.path-mod-attendance .summaryreport .c6 {
+ background-color: #EAEAEA;
+}
+
+.path-mod-attendance .summaryreport .c7 {
+ background-color: #EAEAEA;
+}
diff --git a/tests/behat/report.feature b/tests/behat/report.feature
new file mode 100644
index 0000000..26f41fa
--- /dev/null
+++ b/tests/behat/report.feature
@@ -0,0 +1,240 @@
+@javascript @mod @uon @mod_attendance
+Feature: Visiting reports
+ As a teacher I visit the reports
+
+ Background:
+ Given the following "courses" exist:
+ | fullname | shortname | summary | category |
+ | Course 1 | C101 | Prove the attendance activity works | 0 |
+ And the following "users" exist:
+ | username | firstname | lastname | email | idnumber | department | institution |
+ | student1 | Student | 1 | student1@asd.com | 1234 | computer science | University of Nottingham |
+ | teacher1 | Teacher | 1 | teacher1@asd.com | 5678 | computer science | University of Nottingham |
+ And the following "course enrolments" exist:
+ | user | course | role |
+ | student1 | C101 | student |
+ | teacher1 | C101 | editingteacher |
+
+ And I log in as "teacher1"
+ And I follow "Course 1"
+ And I turn editing mode on
+ Then I add a "Attendance" to section "1"
+ And I press "Save and display"
+ And I follow "Attendance"
+ And I follow "Add session"
+ And I set the following fields to these values:
+ | id_sestime_starthour | 01 |
+ | id_sestime_endhour | 02 |
+ And I click on "id_submitbutton" "button"
+
+ And I log out
+
+ Scenario: Teacher takes attendance
+ When I log in as "teacher1"
+ And I follow "Course 1"
+ And I follow "Attendance"
+ And I follow "Edit settings"
+ Then I set the following fields to these values:
+ | id_grade_modgrade_type | Point |
+ | id_grade_modgrade_point | 50 |
+ And I press "Save and display"
+
+ When I follow "Report"
+ Then "0 / 0" "text" should exist in the "Student 1" "table_row"
+ And "0.0%" "text" should exist in the "Student 1" "table_row"
+
+ When I follow "Grades" in the user menu
+ And I follow "Course 1"
+ And "-" "text" should exist in the "Student 1" "table_row"
+
+ When I follow "Attendance"
+ Then I click on "Take attendance" "link" in the "01:00 - 02:00" "table_row"
+ # Late
+ And I click on "td.c3 input" "css_element" in the "Student 1" "table_row"
+ And I press "Save attendance"
+
+ When I follow "Report"
+ Then "1 / 2" "text" should exist in the "Student 1" "table_row"
+ And "50.0%" "text" should exist in the "Student 1" "table_row"
+
+ When I follow "Grades" in the user menu
+ And I follow "Course 1"
+ And "25.00" "text" should exist in the "Student 1" "table_row"
+
+ And I log out
+
+ Scenario: Teacher changes the maximum points in the attendance settings
+ When I log in as "teacher1"
+ And I follow "Course 1"
+ And I follow "Attendance"
+ And I follow "Edit settings"
+ Then I set the following fields to these values:
+ | id_grade_modgrade_type | Point |
+ | id_grade_modgrade_point | 50 |
+ And I press "Save and display"
+
+ When I follow "Attendance"
+ Then I click on "Take attendance" "link" in the "01:00 - 02:00" "table_row"
+ # Excused
+ And I click on "td.c3 input" "css_element" in the "Student 1" "table_row"
+ And I press "Save attendance"
+
+ When I follow "Attendance"
+ And I follow "Edit settings"
+ Then I set the following fields to these values:
+ | id_grade_modgrade_type | Point |
+ | id_grade_modgrade_point | 70 |
+ And I press "Save and display"
+
+ When I follow "Report"
+ Then "1 / 2" "text" should exist in the "Student 1" "table_row"
+ And "50.0%" "text" should exist in the "Student 1" "table_row"
+
+ When I follow "Grades" in the user menu
+ And I follow "Course 1"
+ Then "35.00" "text" should exist in the "Student 1" "table_row"
+
+ And I log out
+
+ Scenario: Teacher take attendance of group session
+ Given the following "groups" exist:
+ | course | name | idnumber |
+ | C101 | Group1 | Group1 |
+ And the following "group members" exist:
+ | group | user |
+ | Group1 | student1 |
+
+ When I log in as "teacher1"
+ And I follow "Course 1"
+ And I follow "Attendance"
+ And I follow "Edit settings"
+ And I set the following fields to these values:
+ | id_grade_modgrade_type | Point |
+ | id_grade_modgrade_point | 50 |
+ | id_groupmode | Visible groups |
+ And I press "Save and display"
+
+ When I follow "Attendance"
+ Then I click on "Take attendance" "link" in the "01:00 - 02:00" "table_row"
+ # Excused
+ And I click on "td.c3 input" "css_element" in the "Student 1" "table_row"
+ And I press "Save attendance"
+
+ When I follow "Add session"
+ And I set the following fields to these values:
+ | id_sestime_starthour | 03 |
+ | id_sestime_endhour | 04 |
+ | id_sessiontype_1 | 1 |
+ | id_groups | Group1 |
+ And I click on "id_submitbutton" "button"
+ Then I should see "03:00 - 04:00"
+ And "Group: Group1" "text" should exist in the "03:00 - 04:00" "table_row"
+
+ When I click on "Take attendance" "link" in the "03:00 - 04:00" "table_row"
+ # Present
+ And I click on "td.c2 input" "css_element" in the "Student 1" "table_row"
+ And I press "Save attendance"
+
+ When I follow "Report"
+ Then "Student 1" row "Points" column of "generaltable" table should contain "3 / 4"
+ And "Student 1" row "Percentage" column of "generaltable" table should contain "75.0%"
+
+ When I follow "Grades" in the user menu
+ And I follow "Course 1"
+ Then "37.50" "text" should exist in the "Student 1" "table_row"
+
+ And I log out
+
+ Scenario: Teacher visit summary report
+ When I log in as "teacher1"
+ And I follow "Course 1"
+ And I follow "Attendance"
+ And I follow "Edit settings"
+ And I set the following fields to these values:
+ | id_grade_modgrade_type | Point |
+ | id_grade_modgrade_point | 50 |
+ And I press "Save and display"
+
+ When I click on "Take attendance" "link" in the "01:00 - 02:00" "table_row"
+ # Late
+ And I click on "td.c3 input" "css_element" in the "Student 1" "table_row"
+ And I press "Save attendance"
+
+ When I follow "Add session"
+ And I set the following fields to these values:
+ | id_sestime_starthour | 03 |
+ | id_sestime_endhour | 04 |
+ And I click on "id_submitbutton" "button"
+ Then I should see "03:00 - 04:00"
+
+ When I click on "Take attendance" "link" in the "03:00 - 04:00" "table_row"
+ # Present
+ And I click on "td.c2 input" "css_element" in the "Student 1" "table_row"
+ And I press "Save attendance"
+
+ When I follow "Add session"
+ And I set the following fields to these values:
+ | id_sestime_starthour | 05 |
+ | id_sestime_endhour | 06 |
+ And I click on "id_submitbutton" "button"
+ Then I should see "05:00 - 06:00"
+
+ When I follow "Report"
+ And I click on "Summary" "link" in the "All" "table_row"
+ Then "Student 1" row "Total number of sessions" column of "generaltable" table should contain "3"
+ And "Student 1" row "Points over all sessions" column of "generaltable" table should contain "3 / 6"
+ And "Student 1" row "Percentage over all sessions" column of "generaltable" table should contain "50.0%"
+ And "Student 1" row "Maximum possible points" column of "generaltable" table should contain "5 / 6"
+ And "Student 1" row "Maximum possible percentage" column of "generaltable" table should contain "83.3%"
+
+ And I log out
+
+ Scenario: Student visit user report
+ When I log in as "teacher1"
+ And I follow "Course 1"
+ And I follow "Attendance"
+ And I follow "Edit settings"
+ And I set the following fields to these values:
+ | id_grade_modgrade_type | Point |
+ | id_grade_modgrade_point | 50 |
+ And I press "Save and display"
+
+ When I click on "Take attendance" "link" in the "01:00 - 02:00" "table_row"
+ # Late
+ And I click on "td.c3 input" "css_element" in the "Student 1" "table_row"
+ And I press "Save attendance"
+
+ When I follow "Add session"
+ And I set the following fields to these values:
+ | id_sestime_starthour | 03 |
+ | id_sestime_endhour | 04 |
+ And I click on "id_submitbutton" "button"
+
+ When I click on "Take attendance" "link" in the "03:00 - 04:00" "table_row"
+ # Present
+ And I click on "td.c2 input" "css_element" in the "Student 1" "table_row"
+ And I press "Save attendance"
+
+ When I follow "Add session"
+ And I set the following fields to these values:
+ | id_sestime_starthour | 05 |
+ | id_sestime_endhour | 06 |
+ And I click on "id_submitbutton" "button"
+
+ Then I log out
+
+ When I log in as "student1"
+ And I follow "Course 1"
+ And I follow "Attendance"
+ And I follow "All"
+
+ Then "2" "text" should exist in the "Taked sessions" "table_row"
+ And "3 / 4" "text" should exist in the "Points over taked sessions:" "table_row"
+ And "75.0%" "text" should exist in the "Percentage over taked sessions:" "table_row"
+ And "3" "text" should exist in the "Total number of sessions:" "table_row"
+ And "3 / 6" "text" should exist in the "Points over all sessions:" "table_row"
+ And "50.0%" "text" should exist in the "Percentage over all sessions:" "table_row"
+ And "5 / 6" "text" should exist in the "Maximum possible points:" "table_row"
+ And "83.3%" "text" should exist in the "Maximum possible percentage:" "table_row"
+
+ And I log out