From 29d509f59a2793ec2b736e0fecc2ee83b5ec883c Mon Sep 17 00:00:00 2001
From: skodak <skodak>
Date: Mon, 6 Aug 2007 12:05:45 +0000
Subject: [PATCH] MDL-10109 optional aggregation of outcomes together with
 grades

---
 backup/backuplib.php                 |  1 +
 backup/restorelib.php                |  1 +
 grade/edit/tree/category_form.php    |  4 ++++
 grade/edit/tree/outcomeitem_form.php |  1 +
 lang/en_utf8/grades.php              |  1 +
 lib/db/upgrade.php                   | 24 ++++++++++++++++++++++++
 lib/grade/grade_category.php         | 22 +++++++++++++++++-----
 lib/grade/grade_item.php             | 22 ++++++++++++++++++++--
 version.php                          |  2 +-
 9 files changed, 70 insertions(+), 8 deletions(-)

diff --git a/backup/backuplib.php b/backup/backuplib.php
index cba89b94cab..1befa83451f 100644
--- a/backup/backuplib.php
+++ b/backup/backuplib.php
@@ -1386,6 +1386,7 @@
                 fwrite ($bf,full_tag("AGGREGATION",5,false,$grade_category->aggregation));
                 fwrite ($bf,full_tag("KEEPHIGH",5,false,$grade_category->keephigh));
                 fwrite ($bf,full_tag("DROPLOW",5,false,$grade_category->droplow));
+                fwrite ($bf,full_tag("AGGREGATEOUTCOMES",5,false,$grade_category->aggregateoutcomes));
 
                 //End grade_category
                 fwrite ($bf,end_tag("GRADE_CATEGORY",4,true));
diff --git a/backup/restorelib.php b/backup/restorelib.php
index 5017abf60ee..708d4b69b0b 100644
--- a/backup/restorelib.php
+++ b/backup/restorelib.php
@@ -1283,6 +1283,7 @@
                             $dbrec->aggregation = backup_todb($info['GRADE_CATEGORY']['#']['AGGREGATION']['0']['#']);
                             $dbrec->keephigh = backup_todb($info['GRADE_CATEGORY']['#']['KEEPHIGH']['0']['#']);
                             $dbrec->droplow = backup_todb($info['GRADE_CATEGORY']['#']['DROPLOW']['0']['#']);
+                            $dbrec->aggregateoutcomes = backup_todb($info['GRADE_CATEGORY']['#']['AGGREGATEOUTCOMES']['0']['#']);
                             $dbrec->hidden = backup_todb($info['GRADE_CATEGORY']['#']['HIDDEN']['0']['#']);
 
                             //Structure is equal to db, insert record
diff --git a/grade/edit/tree/category_form.php b/grade/edit/tree/category_form.php
index 0b0890ca0fd..189465cd960 100644
--- a/grade/edit/tree/category_form.php
+++ b/grade/edit/tree/category_form.php
@@ -29,6 +29,10 @@ class edit_category_form extends moodleform {
         $mform->addElement('select', 'aggregation', get_string('aggregation', 'grades'), $options);
         $mform->setDefault('gradetype', GRADE_AGGREGATE_MEAN_ALL);
 
+        if (!empty($CFG->enableoutcomes)) {
+            $mform->addElement('advcheckbox', 'aggregateoutcomes', get_string('aggregateoutcomes', 'grades'));
+        }
+
         $options = array();
         $options[0] = get_string('none');
         for ($i=1; $i<=20; $i++) {
diff --git a/grade/edit/tree/outcomeitem_form.php b/grade/edit/tree/outcomeitem_form.php
index 570c87a6244..8d2771c5367 100644
--- a/grade/edit/tree/outcomeitem_form.php
+++ b/grade/edit/tree/outcomeitem_form.php
@@ -26,6 +26,7 @@ class edit_outcomeitem_form extends moodleform {
             }
         }
         $mform->addElement('select', 'outcomeid', get_string('outcome', 'grades'), $options);
+        $mform->addRule('outcomeid', get_string('required'), 'required');
 
         $options = array(0=>get_string('none'));
         if ($coursemods = get_course_mods($COURSE->id)) {
diff --git a/lang/en_utf8/grades.php b/lang/en_utf8/grades.php
index af9ef0c85c9..216c92162f6 100644
--- a/lang/en_utf8/grades.php
+++ b/lang/en_utf8/grades.php
@@ -21,6 +21,7 @@ $string['aggregatemaxall'] = 'Highest grade of all grades';
 $string['aggregatemaxgraded'] = 'Highest grade of non-empty grades';
 $string['aggregatemodeall'] = 'Mode of all grades';
 $string['aggregatemodegraded'] = 'Mode of non-empty grades';
+$string['aggregateoutcomes'] = 'Aggregate also outcomes';
 $string['aggregateweightedmeanall'] = 'Weighted mean of all grades';
 $string['aggregateweightedmeangraded'] = 'Weighted mean of non-empty grades';
 $string['aggregation'] = 'Aggregation';
diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php
index 52e08292b69..928ee62df52 100644
--- a/lib/db/upgrade.php
+++ b/lib/db/upgrade.php
@@ -1073,6 +1073,7 @@ function xmldb_main_upgrade($oldversion=0) {
         $table->addFieldInfo('aggregation', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
         $table->addFieldInfo('keephigh', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
         $table->addFieldInfo('droplow', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
+        $table->addFieldInfo('aggregateoutcomes', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
         $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
         $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
 
@@ -1232,6 +1233,7 @@ function xmldb_main_upgrade($oldversion=0) {
         $table->addFieldInfo('aggregation', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
         $table->addFieldInfo('keephigh', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
         $table->addFieldInfo('droplow', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
+        $table->addFieldInfo('aggregateoutcomes', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
 
     /// Adding keys to table grade_categories_history
         $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
@@ -1598,6 +1600,28 @@ function xmldb_main_upgrade($oldversion=0) {
 
     }
 
+    if ($result && $oldversion < 2007080300) {
+
+    /// Define field aggregateoutcomes to be added to grade_categories
+        $table = new XMLDBTable('grade_categories');
+        $field = new XMLDBField('aggregateoutcomes');
+        if (!field_exists($table, $field)) {
+            $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'droplow');
+
+        /// Launch add field aggregateoutcomes
+            $result = $result && add_field($table, $field);
+        }
+
+    /// Define field aggregateoutcomes to be added to grade_categories
+        $table = new XMLDBTable('grade_categories_history');
+        $field = new XMLDBField('aggregateoutcomes');
+        if (!field_exists($table, $field)) {
+            $field->setAttributes(XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'droplow');
+
+        /// Launch add field aggregateoutcomes
+            $result = $result && add_field($table, $field);
+        }
+    }
 
 /*
     /// drop old gradebook tables
diff --git a/lib/grade/grade_category.php b/lib/grade/grade_category.php
index 2bfad2337c3..3348b5109a9 100644
--- a/lib/grade/grade_category.php
+++ b/lib/grade/grade_category.php
@@ -93,6 +93,12 @@ class grade_category extends grade_object {
      */
     var $droplow = 0;
 
+    /**
+     * Aggregate outcomes together with normal items
+     * @$aggregateoutcomes
+     */
+    var $aggregateoutcomes = 0;
+
     /**
      * Array of grade_items or grade_categories nested exactly 1 level below this category
      * @var array $children
@@ -308,11 +314,12 @@ class grade_category extends grade_object {
 
         $db_item = grade_category::fetch(array('id'=>$this->id));
 
-        $aggregationdiff = $db_item->aggregation != $this->aggregation;
-        $keephighdiff    = $db_item->keephigh    != $this->keephigh;
-        $droplowdiff     = $db_item->droplow     != $this->droplow;
+        $aggregationdiff = $db_item->aggregation       != $this->aggregation;
+        $keephighdiff    = $db_item->keephigh          != $this->keephigh;
+        $droplowdiff     = $db_item->droplow           != $this->droplow;
+        $aggoutcomesdiff = $db_item->aggregateoutcomes != $this->aggregateoutcomes;
 
-        return ($aggregationdiff || $keephighdiff || $droplowdiff);
+        return ($aggregationdiff || $keephighdiff || $droplowdiff || $aggoutcomesdiff);
     }
 
     /**
@@ -668,10 +675,15 @@ class grade_category extends grade_object {
         // recursively resort children
         if (!empty($category_array['children'])) {
             $result['children'] = array();
+            //process the category item first
+            $cat_item_id = null;
             foreach($category_array['children'] as $oldorder=>$child_array) {
                 if ($child_array['type'] == 'courseitem' or $child_array['type'] == 'categoryitem') {
                     $result['children'][$sortorder] = grade_category::_fetch_course_tree_recursion($child_array, $sortorder);
-                } else {
+                }
+            }            
+            foreach($category_array['children'] as $oldorder=>$child_array) {
+                if ($child_array['type'] != 'courseitem' and $child_array['type'] != 'categoryitem') {
                     $result['children'][++$sortorder] = grade_category::_fetch_course_tree_recursion($child_array, $sortorder);
                 }
             }
diff --git a/lib/grade/grade_item.php b/lib/grade/grade_item.php
index f096574adbd..69050b99be9 100644
--- a/lib/grade/grade_item.php
+++ b/lib/grade/grade_item.php
@@ -232,6 +232,11 @@ class grade_item extends grade_object {
         // Retrieve scale and infer grademax/min from it if needed
         $this->load_scale();
 
+        // make sure there is not 0 in outcomeid
+        if (empty($this->outcomeid)) {
+            $this->outcomeid = null;
+        }
+
         if ($this->qualifies_for_regrading()) {
             $this->force_regrading();
         }
@@ -349,6 +354,11 @@ class grade_item extends grade_object {
             }
         }
 
+        // make sure there is not 0 in outcomeid
+        if (empty($this->outcomeid)) {
+            $this->outcomeid = null;
+        }
+
         if (parent::insert($source)) {
             // force regrading of items if needed
             $this->force_regrading();
@@ -1127,10 +1137,17 @@ class grade_item extends grade_object {
                 return array();
             }
 
+            if (!empty($CFG->enableoutcomes) or $grade_category->aggregateoutcomes) {
+                $outcomes_sql = "";
+            } else {
+                $outcomes_sql = "AND gi.outcomeid IS NULL";
+            }
+
             $sql = "SELECT gi.id
                       FROM {$CFG->prefix}grade_items gi
                      WHERE gi.categoryid = {$grade_category->id}
-                           AND (gi.gradetype = ".GRADE_TYPE_VALUE." OR gi.gradetype = ".GRADE_TYPE_SCALE.")  
+                           AND (gi.gradetype = ".GRADE_TYPE_VALUE." OR gi.gradetype = ".GRADE_TYPE_SCALE.")
+                           $outcomes_sql
 
                     UNION
 
@@ -1138,7 +1155,8 @@ class grade_item extends grade_object {
                       FROM {$CFG->prefix}grade_items gi, {$CFG->prefix}grade_categories gc
                      WHERE (gi.itemtype = 'category' OR gi.itemtype = 'course') AND gi.iteminstance=gc.id
                            AND gc.parent = {$grade_category->id}
-                           AND (gi.gradetype = ".GRADE_TYPE_VALUE." OR gi.gradetype = ".GRADE_TYPE_SCALE.")";  
+                           AND (gi.gradetype = ".GRADE_TYPE_VALUE." OR gi.gradetype = ".GRADE_TYPE_SCALE.")
+                           $outcomes_sql";
 
             if ($children = get_records_sql($sql)) {
                 return array_keys($children);
diff --git a/version.php b/version.php
index c9d1123b1a5..8b64385c75e 100644
--- a/version.php
+++ b/version.php
@@ -6,7 +6,7 @@
 // This is compared against the values stored in the database to determine
 // whether upgrades should be performed (see lib/db/*.php)
 
-    $version = 2007080202;  // YYYYMMDD = date
+    $version = 2007080300;  // YYYYMMDD = date
                             //       XY = increments within a single day
 
     $release = '1.9 dev';   // Human-friendly version name