Index: /main/waeup.kofa/trunk/src/waeup/kofa/students/browser.py
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/students/browser.py	(revision 9843)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/students/browser.py	(revision 9844)
@@ -2810,7 +2810,7 @@
 
     def _set_exporter_values(self):
-        # We provide only the students exporter.
+        # We provide only two exporters.
         exporters = []
-        for name in ('students',):
+        for name in ('students', 'coursetickets'):
             util = getUtility(ICSVExporter, name=name)
             exporters.append((util.title, name),)
Index: /main/waeup.kofa/trunk/src/waeup/kofa/students/export.py
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/students/export.py	(revision 9843)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/students/export.py	(revision 9844)
@@ -56,11 +56,21 @@
     return levels
 
-def get_tickets(students):
-    """Get all course tickets of `students`.
+def get_tickets(students, **kw):
+    """Get course tickets of `students`.
+
+    If code is passed through filter course tickets
+    which belong to this course code.
     """
     tickets = []
-    for level in get_levels(students):
-        for ticket in level.values():
-            tickets.append(ticket)
+    code = kw.get('code', None)
+    if code is None:
+        for level in get_levels(students):
+            for ticket in level.values():
+                tickets.append(ticket)
+    else:
+        for level in get_levels(students):
+            for ticket in level.values():
+                if ticket.code == code:
+                    tickets.append(ticket)
     return tickets
 
@@ -92,5 +102,5 @@
     grok.provides(ICSVStudentExporter)
 
-    def filter_func(self, x):
+    def filter_func(self, x, **kw):
         return x
 
@@ -149,5 +159,5 @@
         """
         data = self.get_filtered(site, **kw)
-        return self.export(self.filter_func(data), filepath=filepath)
+        return self.export(self.filter_func(data, **kw), filepath=filepath)
 
 
@@ -189,5 +199,5 @@
     title = _(u'Student Study Courses')
 
-    def filter_func(self, x):
+    def filter_func(self, x, **kw):
         return get_studycourses(x)
 
@@ -219,5 +229,5 @@
     title = _(u'Student Study Levels')
 
-    def filter_func(self, x):
+    def filter_func(self, x, **kw):
         return get_levels(x)
 
@@ -244,6 +254,6 @@
     title = _(u'Course Tickets')
 
-    def filter_func(self, x):
-        return get_tickets(x)
+    def filter_func(self, x, **kw):
+        return get_tickets(x, **kw)
 
     def mangle_value(self, value, name, context=None):
@@ -275,5 +285,5 @@
     title = _(u'Student Payments')
 
-    def filter_func(self, x):
+    def filter_func(self, x, **kw):
         return get_payments(x)
 
@@ -303,5 +313,5 @@
     title = _(u'Bed Tickets')
 
-    def filter_func(self, x):
+    def filter_func(self, x, **kw):
         return get_bedtickets(x)
 
Index: /main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py	(revision 9843)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py	(revision 9844)
@@ -2835,5 +2835,5 @@
             )
 
-    def test_course_export(self):
+    def test_course_export_students(self):
         self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
         course1_path = 'http://localhost/app/faculties/fac1/dep1/courses/COURSE1'
@@ -2880,2 +2880,48 @@
             '- discarded: job_id=%s' % job_id in logcontent
             )
+
+    def test_course_export_coursetickets(self):
+        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
+        course1_path = 'http://localhost/app/faculties/fac1/dep1/courses/COURSE1'
+        self.browser.open(course1_path)
+        self.browser.getLink("Export student data").click()
+        self.browser.getControl("Configure new export").click()
+        self.browser.getControl(name="exporter").value = ['coursetickets']
+        self.browser.getControl(name="session").value = ['2004']
+        self.browser.getControl(name="level").value = ['100']
+        self.browser.getControl("Create CSV file").click()
+
+        # When the job is finished and we reload the page...
+        job_id = self.wait_for_export_job_completed()
+        self.browser.open(course1_path + '/exports')
+        # ... the csv file can be downloaded ...
+        self.browser.getLink("Download").click()
+        self.assertEqual(self.browser.headers['content-type'],
+            'text/csv; charset=UTF-8')
+        self.assertTrue(
+            'filename="WAeUP.Kofa_coursetickets_%s.csv' % job_id in
+            self.browser.headers['content-disposition'])
+        self.assertEqual(len(self.app['datacenter'].running_exports), 1)
+        job_id = self.app['datacenter'].running_exports[0][0]
+        # ... and discarded
+        self.browser.open(course1_path + '/exports')
+        self.browser.getControl("Discard").click()
+        self.assertEqual(len(self.app['datacenter'].running_exports), 0)
+        # Creation, downloading and discarding is logged
+        logfile = os.path.join(
+            self.app['datacenter'].storage, 'logs', 'datacenter.log')
+        logcontent = open(logfile).read()
+        self.assertTrue(
+            'zope.mgr - students.browser.CourseExportJobContainerJobConfig '
+            '- exported: coursetickets (2004, 100, COURSE1), job_id=%s'
+            % job_id in logcontent
+            )
+        self.assertTrue(
+            'zope.mgr - students.browser.ExportJobContainerDownload '
+            '- downloaded: WAeUP.Kofa_coursetickets_%s.csv, job_id=%s'
+            % (job_id, job_id) in logcontent
+            )
+        self.assertTrue(
+            'zope.mgr - students.browser.ExportJobContainerOverview '
+            '- discarded: job_id=%s' % job_id in logcontent
+            )
Index: /main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_export.py
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_export.py	(revision 9843)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_export.py	(revision 9844)
@@ -554,5 +554,5 @@
 
     def test_export_filtered(self):
-        # we can export studylevels of a filtered set of students
+        # we can export course tickets of a filtered set of students
         self.setup_student(self.student)
         self.app['students'].addStudent(self.student)
@@ -568,4 +568,24 @@
             'passmark,score,semester,title,student_id,certcode\r\n'
             '1,1,CRS1,100,DEP1,FAC1,100,0,100,,2,Course 1,A111111,CERT1\r\n'
+            )
+        # if the coursetickets catalog is used to filter students
+        # and (course) code is not None
+        # only course tickets which belong to this course are exported
+        exporter.export_filtered(
+            self.student, self.outfile, cat='coursetickets', code='CRS1')
+        result = open(self.outfile, 'rb').read()
+        self.assertEqual(
+            result,
+            'automatic,carry_over,code,credits,dcode,fcode,level,mandatory,'
+            'passmark,score,semester,title,student_id,certcode\r\n'
+            '1,1,CRS1,100,DEP1,FAC1,100,0,100,,2,Course 1,A111111,CERT1\r\n'
+            )
+        exporter.export_filtered(
+            self.student, self.outfile, cat='coursetickets', code='any code')
+        result = open(self.outfile, 'rb').read()
+        self.assertEqual(
+            result,
+            'automatic,carry_over,code,credits,dcode,fcode,level,mandatory,'
+            'passmark,score,semester,title,student_id,certcode\r\n'
             )
         return
