Index: /main/waeup.aaue/trunk/src/waeup/aaue/students/reports/raw_score_report.py
===================================================================
--- /main/waeup.aaue/trunk/src/waeup/aaue/students/reports/raw_score_report.py	(revision 14629)
+++ /main/waeup.aaue/trunk/src/waeup/aaue/students/reports/raw_score_report.py	(revision 14630)
@@ -18,6 +18,9 @@
 
 import grok
+from zope.interface import implementer, Interface, Attribute
 from waeup.kofa.students.reports.raw_score_report import (
-    RawScoreReport, RawScoreReportGenerator)
+    RawScoreReport, RawScoreReportGenerator,
+    IRawScoreReport, RawScoreReportGeneratorPage,
+    RawScoreReportPDFView)
 
 
@@ -38,5 +41,5 @@
 
 
-class RawScoreReportGenerator(RawScoreReportGenerator):
+class CustomRawScoreReportGenerator(RawScoreReportGenerator):
 
     def generate(self, site, faccode=None, depcode=None, certcode=None,
@@ -45,2 +48,57 @@
             certcode=certcode, session=session, level=level, author=author)
         return result
+
+# Raw Score Report for graduating students only
+
+class IGradRawScoreReport(IRawScoreReport):
+    """Marker interface to distuingish graduating students raw score reports
+    from ordinary raw score reports.
+    """
+
+@implementer(IGradRawScoreReport)
+class GradRawScoreReport(CustomRawScoreReport):
+    """
+    """
+
+    title = 'RAW Score Report'
+
+    @property
+    def right_footer(self):
+        return self.title + ' (graduating students only) - %s -' % self.session
+
+    def _excluded(self, level_obj):
+        """
+        """
+        final_level = max(level_obj.student['studycourse'].keys())
+        final_level_obj = level_obj.student['studycourse'][final_level]
+        if final_level_obj.remark not in (
+            'Pass', '3s_rd_s', '2s_2_s', '2s_1_s', '1s_st_s'):
+            return True
+        return False
+
+class GradRawScoreReportGenerator(RawScoreReportGenerator):
+
+    title = 'Graduating Students RAW Score Report'
+    grok.name('grad_raw_score_report')
+
+    def generate(self, site, faccode=None, depcode=None, certcode=None,
+                 session=None, level=None, author=None):
+        result = GradRawScoreReport(faccode=faccode, depcode=depcode,
+            certcode=certcode, session=session, level=level, author=author)
+        return result
+
+class GradRawScoreReportGeneratorPage(RawScoreReportGeneratorPage):
+
+    grok.context(GradRawScoreReportGenerator)
+
+class GradRawScoreReportPDFView(RawScoreReportPDFView):
+
+    grok.context(IGradRawScoreReport)
+    grok.name('pdf')
+    grok.require('waeup.handleReports')
+
+    def _filename(self):
+        return 'GradRawScoreReport_rno%s_%s.pdf' % (
+            self.context.__name__,
+            self.context.creation_dt_string)
+
Index: /main/waeup.aaue/trunk/src/waeup/aaue/students/reports/tests/test_raw_score_report.py
===================================================================
--- /main/waeup.aaue/trunk/src/waeup/aaue/students/reports/tests/test_raw_score_report.py	(revision 14629)
+++ /main/waeup.aaue/trunk/src/waeup/aaue/students/reports/tests/test_raw_score_report.py	(revision 14630)
@@ -9,5 +9,6 @@
 from waeup.kofa.browser.tests.test_pdf import samples_dir
 from waeup.kofa.students.reports.raw_score_report import IRawScoreReport
-from waeup.aaue.students.reports.raw_score_report import CustomRawScoreReport
+from waeup.aaue.students.reports.raw_score_report import (
+    CustomRawScoreReport, GradRawScoreReport, IGradRawScoreReport)
 from waeup.aaue.testing import FunctionalLayer
 
@@ -98,2 +99,97 @@
         print "Sample raw_score_report.pdf written to %s" % path
         return
+
+
+class GradRawScoreReportTests(CatalogTestSetup):
+
+    layer = FunctionalLayer
+
+    def setUp(self):
+        super(GradRawScoreReportTests, self).setUp()
+        self.course = createObject('waeup.Course')
+        self.course.code = 'Course1'
+        self.course.credits = 25
+        self.app['faculties']['fac1']['dep1'].courses.addCourse(
+            self.course)
+        self.app['faculties']['fac1']['dep1'].certificates[
+            'CERT1'].addCertCourse(self.course, level=100)
+
+    def test_iface(self):
+        # ensure we fullfill interface contracts
+        obj = GradRawScoreReport('fac1', 'dep1', 'CERT1', 2010, 100)
+        verifyClass(IGradRawScoreReport, GradRawScoreReport)
+        verifyObject(IGradRawScoreReport, obj)
+        return
+
+    def test_get_courses(self):
+        # we can get a list with one course code
+        rsr =  GradRawScoreReport('fac1', 'dep1', 'CERT1', 2010, 100)
+        result = rsr._get_courses('fac1', 'dep1', 'CERT1', 2010, 100)
+        self.assertEqual(result, [u'Course1'])
+        return
+
+    def test_get_students(self):
+        # we can get a table with one student
+        self.student['studycourse']['100']['Course1'].ca = 0
+        rsr =  GradRawScoreReport('fac1', 'dep1', 'CERT1', 2010, 100)
+        course_codes = rsr._get_courses('fac1', 'dep1', 'CERT1', 2010, 100)
+        result = rsr._get_students('fac1', 'dep1', 'CERT1', 2010, 100, course_codes)
+        self.assertEqual(result, [])
+        # if end level is 100, the student seems graduating and
+        # we can get a table with one student
+        self.certificate.end_level = 100
+        self.student['studycourse']['100']['Course1'].credits = 91
+        result = rsr._get_students('fac1', 'dep1', 'CERT1', 2010, 100, course_codes)
+        self.assertEqual(result,
+            [(u'1234', u'TESTER, Bob', {'Course1': (70, 'A')})])
+        self.student['studycourse']['100']['Course1'].ca = None
+        result = rsr._get_students('fac1', 'dep1', 'CERT1', 2010, 100, course_codes)
+        # NER
+        self.assertEqual(result, [])
+        return
+
+    def test_create_pdf(self):
+        self.certificate.end_level = 200
+        self.course2 = createObject('waeup.Course')
+        self.course2.code = 'Course2'
+        self.course2.credits = 30
+        self.app['faculties']['fac1']['dep1'].courses.addCourse(
+            self.course2)
+        self.app['faculties']['fac1']['dep1'].certificates[
+            'CERT1'].addCertCourse(self.course2, level=100)
+        self.course3 = createObject('waeup.Course')
+        self.course3.code = 'Course3'
+        self.course3.credits = 30
+        self.app['faculties']['fac1']['dep1'].courses.addCourse(
+            self.course3)
+        self.app['faculties']['fac1']['dep1'].certificates[
+            'CERT1'].addCertCourse(self.course3, level=100)
+        self.app['faculties']['fac1'].officer_1 = 'Rosa Moonshine - Dean of Faculty'
+        self.app['faculties']['fac1']['dep1'].officer_1 = 'Amalia Sunshine - Head of Department'
+        studylevel = createObject('waeup.StudentStudyLevel')
+        studylevel.level = 200
+        studylevel.level_session = 2011
+        self.student['studycourse']['200'] = studylevel
+        ticket = createObject('waeup.CourseTicket')
+        ticket.code = 'Course2'
+        ticket.credits = 61
+        ticket.score = 50
+        ticket.ca = 10
+        self.student['studycourse']['200']['Course2'] = ticket
+        ticket = createObject('waeup.CourseTicket')
+        ticket.code = 'Course3'
+        ticket.credits = 30
+        ticket.score = 70
+        ticket.ca = 0
+        self.student['studycourse']['200']['Course3'] = ticket
+        self.assertEqual(ticket.grade, 'A')
+        self.student.firstname = u'Osahenokese Tessy'
+        self.student.lastname = u'Emwinyomwanru'
+        report = GradRawScoreReport('fac1', 'dep1', 'CERT1', 2011, 200)
+        result = report.create_pdf('JOB_ID')
+        self.assertTrue(result.startswith('%PDF-'))
+        path = os.path.join(samples_dir(), 'grad_raw_score_report.pdf')
+        open(path, 'wb').write(result)
+        print "Sample grad_raw_score_report.pdf written to %s" % path
+        return
+
