Index: /main/waeup.kofa/trunk/CHANGES.txt
===================================================================
--- /main/waeup.kofa/trunk/CHANGES.txt	(revision 16661)
+++ /main/waeup.kofa/trunk/CHANGES.txt	(revision 16662)
@@ -4,4 +4,7 @@
 1.7.2.dev0 (unreleased)
 =======================
+
+* `OutstandingCoursesExporter`: Remove passed courses from outstanding
+  courses lists.
 
 * Enable students and officers to upload scanned signature in the same
Index: /main/waeup.kofa/trunk/src/waeup/kofa/students/export.py
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/students/export.py	(revision 16661)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/students/export.py	(revision 16662)
@@ -148,16 +148,25 @@
             student.get('studycourse', None), 'certificate', None)
         if certificate:
-            allticketcodes = []
-            failedticketcodes = '' # taken but failed
-            nottakenticketcodes = '' # registered but not taken
-            missedticketcodes = '' # not registered
+            allticketcodes = list()
+            failedticketcodes = list() # taken but failed
+            nottakenticketcodes = list() # registered but not taken
+            missedticketcodes = list() # not registered
+            # collect failed, not taken and all courses
             for level in student['studycourse'].values():
-                failedticketcodes += level.passed_params[4]
-                nottakenticketcodes += level.passed_params[5]
+                failedticketcodes += level.passed_params[4].split()
+                nottakenticketcodes += level.passed_params[5].split()
                 for ticket in level.values():
                     allticketcodes.append(ticket.code)
+            # check if failed or not taken courses have been passed later
+            for code in failedticketcodes:
+                if code in level.passed_params[6]:
+                    failedticketcodes.remove(code) 
+            for code in nottakenticketcodes:
+                if code in level.passed_params[6]:
+                    nottakenticketcodes.remove(code)
+            # collect missed tickets
             for certcourse in certificate.values():
                 if certcourse.getCourseCode() not in allticketcodes:
-                    missedticketcodes += '%s ' % certcourse.__name__
+                    missedticketcodes.append(certcourse.__name__)
             student_wo = (student, missedticketcodes,
                           failedticketcodes, nottakenticketcodes)
@@ -602,9 +611,9 @@
                 value = getattr(context[0], name, None)
             elif name == 'missed':
-                value = context[1]
+                value = ' '.join(context[1])
             elif name == 'failed':
-                value = context[2]
+                value = ' '.join(context[2])
             elif name == 'nottaken':
-                value = context[3]
+                value = ' '.join(context[3])
         return super(
             OutstandingCoursesExporter, self).mangle_value(
Index: /main/waeup.kofa/trunk/src/waeup/kofa/students/studylevel.py
===================================================================
--- /main/waeup.kofa/trunk/src/waeup/kofa/students/studylevel.py	(revision 16661)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/students/studylevel.py	(revision 16662)
@@ -164,4 +164,5 @@
         credits_passed = 0
         courses_not_taken = ''
+        courses_passed = ''
         for ticket in self.values():
             if ticket.total_score is not None:
@@ -176,9 +177,10 @@
                     passed += 1
                     credits_passed += ticket.credits
+                    courses_passed += '%s ' % ticket.code
             else:
                 courses_not_taken += '%s ' % ticket.code
         return (passed, failed, credits_passed,
                 credits_failed, courses_failed,
-                courses_not_taken)
+                courses_not_taken, courses_passed)
 
     @property
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 16661)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py	(revision 16662)
@@ -1062,8 +1062,8 @@
         self.assertEqual(
             self.student['studycourse']['100'].passed_params,
-            (1, 1, 13, 10, 'COURSE1 ', ''))
+            (1, 1, 13, 10, 'COURSE1 ', '', 'ANYCODE '))
         self.assertEqual(
             self.student['studycourse']['200'].passed_params,
-            (0, 0, 0, 0, '', 'COURSE1 '))
+            (0, 0, 0, 0, '', 'COURSE1 ', ''))
         # And also cumulative params can be calculated. Meanwhile we have the
         # following courses: COURSE1 and COURSE2 in level 100 and
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 16661)
+++ /main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_export.py	(revision 16662)
@@ -890,5 +890,5 @@
             result,
             'student_id,matric_number,certcode,display_fullname,missed,failed,nottaken\r\n'
-            'A111111,234,CERT1,Anna M. Tester,C2_400 ,C3 ,C1 CRS1 \r\n'
+            'A111111,234,CERT1,Anna M. Tester,C2_400,C3,C1 CRS1\r\n'
             )
         return
