Index: /main/waeup.kofa/trunk/src/waeup/kofa/students/reports/level_report.py
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/students/reports/level_report.py	(revision 10573)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/students/reports/level_report.py	(revision 10574)
@@ -1,5 +1,5 @@
 ## $Id$
 ##
-## Copyright (C) 2012 Uli Fouquet & Henrik Bettermann
+## Copyright (C) 2013 Uli Fouquet & Henrik Bettermann
 ## This program is free software; you can redistribute it and/or modify
 ## it under the terms of the GNU General Public License as published by
@@ -35,5 +35,5 @@
     creation_dt_string = Attribute('Human readable report creation datetime')
 
-def get_students_by(faccode, depcode, session, level):
+def get_students(faccode, depcode, session, level):
     """Get students in a certain department who registered courses
     in a certain session at a certain level.
@@ -42,6 +42,4 @@
     """
     site = grok.getSite()
-    faccodes = tuple(sorted([x for x in site['faculties'].keys()],
-                             key=lambda x: x.lower()))
     cat = queryUtility(ICatalog, name="students_catalog")
     result = cat.searchResults(
@@ -142,5 +140,5 @@
         self.creation_dt_string = self.creation_dt.astimezone(
             getUtility(IKofaUtils).tzinfo).strftime("%Y-%m-%d %H:%M:%S %Z")
-        self.data = get_students_by(faccode, depcode, session, level)
+        self.data = get_students(faccode, depcode, session, level)
 
     def create_pdf(self):
Index: /main/waeup.kofa/trunk/src/waeup/kofa/students/reports/level_results_presentation.py
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/students/reports/level_results_presentation.py	(revision 10574)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/students/reports/level_results_presentation.py	(revision 10574)
@@ -0,0 +1,74 @@
+## $Id$
+##
+## Copyright (C) 2013 Uli Fouquet & Henrik Bettermann
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+import grok
+from zope.catalog.interfaces import ICatalog
+from zope.component import queryUtility, getUtility
+from zope.interface import implementer, Interface, Attribute
+from waeup.kofa.interfaces import (
+    IKofaUtils,
+    academic_sessions_vocab, registration_states_vocab)
+from waeup.kofa.students.interfaces import IStudentsUtils
+from waeup.kofa.interfaces import MessageFactory as _
+from waeup.kofa.reports import IReport
+from waeup.kofa.browser.pdf import get_signature_tables
+
+
+def get_students(faccode, depcode, session, level=None):
+    """Get students in a certain department who registered courses
+    in a certain session at a certain level.
+
+    Returns a list of lists of student data tuples.
+    """
+    site = grok.getSite()
+    cat = queryUtility(ICatalog, name="students_catalog")
+    result = cat.searchResults(
+        depcode = (depcode, depcode), faccode = (faccode, faccode)
+        )
+    students_utils = getUtility(IStudentsUtils)
+    table = []
+    for i in range(len(students_utils.gpa_boundaries)+1):
+        # The last list is reserved for students with more than one
+        # level in the same session.
+        table.append([])
+    for stud in result:
+        line = (stud.student_id,
+                stud.matric_number,
+                stud.display_fullname,
+                )
+        if level is not None:
+            if not stud['studycourse'].has_key(str(level)):
+                continue
+            level_obj = stud['studycourse'][str(level)]
+            if level_obj.level_session != session:
+                continue
+        else:
+            itemcount = 0
+            for item in stud['studycourse'].values():
+                if item.level_session == session:
+                    level_obj = item
+                    itemcount += 1
+            if itemcount == 0:
+                # No level registered in this session
+                continue
+            if itemcount > 1:
+                # More than one session registered in this session
+                table[len(students_utils.gpa_boundaries)].append(line)
+                continue
+        table[students_utils.getClassFromCGPA(level_obj.gpa)[0]].append(line)
+    return table
+
Index: /main/waeup.kofa/trunk/src/waeup/kofa/students/reports/tests/test_level_report.py
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/students/reports/tests/test_level_report.py	(revision 10573)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/students/reports/tests/test_level_report.py	(revision 10574)
@@ -5,5 +5,5 @@
 from waeup.kofa.interfaces import IJobManager
 from waeup.kofa.students.reports.level_report import (
-    get_students_by, LevelReport, ILevelReport)
+    get_students, LevelReport, ILevelReport)
 from waeup.kofa.students.tests.test_catalog import CatalogTestSetup
 from waeup.kofa.students.tests.test_browser import StudentsFullSetup
@@ -23,7 +23,7 @@
         return
 
-    def test_get_students_by(self):
+    def test_get_students(self):
         # we can get a table with one student
-        result = get_students_by('fac1', 'dep1', 2010, 100)
+        result = get_students('fac1', 'dep1', 2010, 100)
         self.assertEqual(result,
             [(u'K1000000', u'1234', u'Bob Tester', 30, 30, 5.0, [])])
Index: /main/waeup.kofa/trunk/src/waeup/kofa/students/reports/tests/test_level_results_presentation.py
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/students/reports/tests/test_level_results_presentation.py	(revision 10574)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/students/reports/tests/test_level_results_presentation.py	(revision 10574)
@@ -0,0 +1,49 @@
+import os
+from zc.async.testing import wait_for_result
+from zope.event import notify
+from zope.interface.verify import verifyClass, verifyObject
+from zope.component import getUtility
+from waeup.kofa.interfaces import IJobManager
+from waeup.kofa.students.reports.level_results_presentation import (
+    get_students)
+from waeup.kofa.students.tests.test_catalog import CatalogTestSetup
+from waeup.kofa.students.tests.test_browser import StudentsFullSetup
+from waeup.kofa.testing import FunctionalLayer
+from waeup.kofa.tests.test_async import FunctionalAsyncTestCase
+from waeup.kofa.browser.tests.test_pdf import samples_dir
+from waeup.kofa.students.studylevel import StudentStudyLevel
+
+class LevelReportTests(CatalogTestSetup):
+
+    layer = FunctionalLayer
+
+    def test_get_students(self):
+        result = get_students('fac1', 'dep1', 2010, 100)
+        self.assertEqual(result,
+            [[], [], [], [], [], [(u'K1000000', u'1234', u'Bob Tester')], []])
+        return
+
+    def test_get_students_at_all_levels(self):
+        result = get_students('fac1', 'dep1', 2010)
+        self.assertEqual(result,
+            [[], [], [], [], [], [(u'K1000000', u'1234', u'Bob Tester')], []])
+        return
+
+    def test_get_students_with_two_levels_in_session(self):
+        # Register second level in the same session (which shouldn't be!)
+        studylevel = StudentStudyLevel()
+        studylevel.level = 200
+        studylevel.level_session = 2010
+        self.student['studycourse']['200'] = studylevel
+        result = get_students('fac1', 'dep1', 2010)
+        self.assertEqual(result,
+            [[], [], [], [], [], [], [(u'K1000000', u'1234', u'Bob Tester')]])
+        return
+
+    def test_get_students_without_level_in_session(self):
+        self.student['studycourse']['100'].level_session = 2011
+        result = get_students('fac1', 'dep1', 2010)
+        self.assertEqual(result,
+            [[], [], [], [], [], [], []])
+        return
+
Index: /main/waeup.kofa/trunk/src/waeup/kofa/students/reports/tests/test_student_statistics.py
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/students/reports/tests/test_student_statistics.py	(revision 10573)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/students/reports/tests/test_student_statistics.py	(revision 10574)
@@ -29,5 +29,5 @@
         return
 
-    def test_get_student_stats_by_session_simple(self):
+    def test_get_student_stats_session_simple(self):
         # we can get a table with one student
         result1 = get_student_stats(2010, 'Undergraduate Full-Time')
@@ -47,5 +47,5 @@
         return
 
-    def test_get_student_stats_by_session_multiple(self):
+    def test_get_student_stats_session_multiple(self):
         # we can get a table with several students
         self.create_cert('fac2', 'dept2', 'CERT2')
