Index: main/kofacustom.dspg/trunk/src/kofacustom/dspg/students/reports/__init__.py
===================================================================
--- main/kofacustom.dspg/trunk/src/kofacustom/dspg/students/reports/__init__.py	(revision 15040)
+++ main/kofacustom.dspg/trunk/src/kofacustom/dspg/students/reports/__init__.py	(revision 15040)
@@ -0,0 +1,1 @@
+# Make this a package.
Index: main/kofacustom.dspg/trunk/src/kofacustom/dspg/students/reports/raw_score_report.py
===================================================================
--- main/kofacustom.dspg/trunk/src/kofacustom/dspg/students/reports/raw_score_report.py	(revision 15040)
+++ main/kofacustom.dspg/trunk/src/kofacustom/dspg/students/reports/raw_score_report.py	(revision 15040)
@@ -0,0 +1,41 @@
+## $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.interface import implementer, Interface, Attribute
+from reportlab.lib.units import cm
+from waeup.kofa.students.reports.raw_score_report import (
+    RawScoreReport, RawScoreReportGenerator,
+    IRawScoreReport, RawScoreReportGeneratorPage,
+    RawScoreReportPDFView)
+
+class CustomRawScoreReport(RawScoreReport):
+    fontsize = 12
+
+    @property
+    def col_width(self):
+        return [1*cm, 4*cm, 5*cm] + [1.5*cm] * len(self.certcourses)
+
+
+class CustomRawScoreReportGenerator(RawScoreReportGenerator):
+
+    def generate(self, site, faccode=None, depcode=None, certcode=None,
+                 session=None, level=None, author=None):
+        result = CustomRawScoreReport(faccode=faccode, depcode=depcode,
+            certcode=certcode, session=session, level=level, author=author)
+        return result
Index: main/kofacustom.dspg/trunk/src/kofacustom/dspg/students/reports/tests/__init__.py
===================================================================
--- main/kofacustom.dspg/trunk/src/kofacustom/dspg/students/reports/tests/__init__.py	(revision 15040)
+++ main/kofacustom.dspg/trunk/src/kofacustom/dspg/students/reports/tests/__init__.py	(revision 15040)
@@ -0,0 +1,1 @@
+# Make this a package.
Index: main/kofacustom.dspg/trunk/src/kofacustom/dspg/students/reports/tests/test_raw_score_report.py
===================================================================
--- main/kofacustom.dspg/trunk/src/kofacustom/dspg/students/reports/tests/test_raw_score_report.py	(revision 15040)
+++ main/kofacustom.dspg/trunk/src/kofacustom/dspg/students/reports/tests/test_raw_score_report.py	(revision 15040)
@@ -0,0 +1,106 @@
+import os
+from zc.async.testing import wait_for_result
+from zope.interface.verify import verifyClass, verifyObject
+from zope.component import getUtility, createObject
+from waeup.kofa.interfaces import IJobManager
+from waeup.kofa.students.tests.test_catalog import CatalogTestSetup
+from waeup.kofa.students.tests.test_browser import StudentsFullSetup
+from waeup.kofa.tests.test_async import FunctionalAsyncTestCase
+from waeup.kofa.browser.tests.test_pdf import samples_dir
+from waeup.kofa.students.reports.raw_score_report import IRawScoreReport
+from kofacustom.dspg.students.reports.raw_score_report import CustomRawScoreReport
+from kofacustom.dspg.testing import FunctionalLayer
+
+class RawScoreReportTests(CatalogTestSetup):
+
+    layer = FunctionalLayer
+
+    def setUp(self):
+        super(RawScoreReportTests, 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 = CustomRawScoreReport('fac1', 'dep1', 'CERT1', 2010, 100)
+        verifyClass(IRawScoreReport, CustomRawScoreReport)
+        verifyObject(IRawScoreReport, obj)
+        return
+
+    def test_get_courses(self):
+        # we can get a list with one course code
+        rsr =  CustomRawScoreReport('fac1', 'dep1', 'CERT1', 2010, 100)
+        result = rsr._get_courses('fac1', 'dep1', 'CERT1', 2010, 100)
+        self.assertEqual(result, [self.certificate.values()[0]])
+        self.assertEqual(
+            result,
+            [self.app['faculties']['fac1']['dep1'].certificates[
+                'CERT1']['Course1_100']])
+        return
+
+    def test_get_students(self):
+        # we can get a table with one student
+        self.student['studycourse']['100']['Course1'].ca = 0
+        rsr =  CustomRawScoreReport('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,
+            [(u'1234', u'Bob Tester', {'Course1': (70, 'AB')})])
+        self.student['studycourse']['100']['Course1'].ca = None
+        result = rsr._get_students('fac1', 'dep1', 'CERT1', 2010, 100, course_codes)
+        self.assertEqual(result,
+            [(u'1234', u'Bob Tester', {'Course1': (70, 'AB')})])
+        return
+
+    def test_create_pdf(self):
+        self.app['faculties']['fac1']['dep1'].certificates[
+                'CERT1']['Course1_100'].course_category = 'xyz'
+        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 = 30
+        ticket.score = 50
+        #ticket.ca = 10
+        self.student['studycourse']['200']['Course2'] = ticket
+        ticket = createObject('waeup.CourseTicket')
+        ticket.code = 'Course3'
+        ticket.credits = 30
+        ticket.score = None
+        #ticket.ca = 0
+        self.student['studycourse']['200']['Course3'] = ticket
+        self.assertEqual(ticket.grade, None)
+        self.student.firstname = u'Osahenokese Tessy'
+        self.student.lastname = u'Emwinyomwanru'
+        report = CustomRawScoreReport('fac1', 'dep1', 'CERT1', 2011, 200)
+        result = report.create_pdf('JOB_ID')
+        self.assertTrue(result.startswith('%PDF-'))
+        path = os.path.join(samples_dir(), 'raw_score_report.pdf')
+        open(path, 'wb').write(result)
+        print "Sample raw_score_report.pdf written to %s" % path
+        return
+
+
