Index: main/waeup.uniben/trunk/src/waeup/uniben/students/browser.py
===================================================================
--- main/waeup.uniben/trunk/src/waeup/uniben/students/browser.py	(revision 12566)
+++ main/waeup.uniben/trunk/src/waeup/uniben/students/browser.py	(revision 12845)
@@ -30,5 +30,9 @@
     CourseTicketDisplayFormPage, StudentTriggerTransitionFormPage,
     msave, emit_lock_message,
-    StudentActivatePage, StudentDeactivatePage)
+    StudentActivatePage, StudentDeactivatePage,
+    ExportPDFTranscriptPage)
+from waeup.kofa.students.workflow import (CREATED, ADMITTED, PAID,
+    CLEARANCE, REQUESTED, RETURNING, CLEARED, REGISTERED, VALIDATED,
+    GRADUATED, TRANSCRIPT, FORBIDDEN_POSTGRAD_TRANS)
 from waeup.kofa.students.interfaces import IStudentsUtils, ICourseTicket
 from waeup.kofa.students.workflow import FORBIDDEN_POSTGRAD_TRANS
@@ -118,4 +122,12 @@
     omit_fields = ('password', 'suspended', 'suspended_comment',
         'phone', 'adm_code', 'email', 'date_of_birth')
+
+    def _signatures(self):
+        isStudent = getattr(
+            self.request.principal, 'user_type', None) == 'student'
+        if not isStudent and self.context.state in (CLEARED, RETURNING):
+            return ([_('Student Signature')],
+                    [_('Clearance Officer Signature')])
+        return
 
     def render(self):
@@ -387,2 +399,44 @@
         self.redirect(self.url(self.context))
         return
+
+class CustomExportPDFTranscriptPage(ExportPDFTranscriptPage):
+    """Deliver a PDF slip of the context.
+    """
+
+    def _sigsInFooter(self):
+        return []
+        #return (_('CERTIFIED TRUE COPY'),)
+
+    def _signatures(self):
+        return ([(
+            'Current HD<br /> D. R. (Exams & Records)<br /> '
+            'For: Registrar')],)
+
+    def render(self):
+        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
+        Term = translate(_('Term'), 'waeup.kofa', target_language=portal_language)
+        Code = translate(_('Code'), 'waeup.kofa', target_language=portal_language)
+        Title = translate(_('Title'), 'waeup.kofa', target_language=portal_language)
+        Cred = translate(_('Credits'), 'waeup.kofa', target_language=portal_language)
+        #Score = translate(_('Score'), 'waeup.kofa', target_language=portal_language)
+        Grade = translate(_('Grade'), 'waeup.kofa', target_language=portal_language)
+        studentview = StudentBasePDFFormPage(self.context.student,
+            self.request, self.omit_fields)
+        students_utils = getUtility(IStudentsUtils)
+
+        tableheader = [(Code,'code', 2.5),
+                         (Title,'title', 8.5),
+                         (Term, 'semester', 1.5),
+                         (Cred, 'credits', 1.5),
+                         #(Score, 'score', 1.5),
+                         (Grade, 'grade', 1.5),
+                         ]
+
+        return students_utils.renderPDFTranscript(
+            self, 'transcript.pdf',
+            self.context.student, studentview,
+            omit_fields=self.omit_fields,
+            tableheader=tableheader,
+            signatures=self._signatures(),
+            sigs_in_footer=self._sigsInFooter(),
+            )
Index: main/waeup.uniben/trunk/src/waeup/uniben/students/student.py
===================================================================
--- main/waeup.uniben/trunk/src/waeup/uniben/students/student.py	(revision 12566)
+++ main/waeup.uniben/trunk/src/waeup/uniben/students/student.py	(revision 12845)
@@ -39,5 +39,5 @@
     def transcript_enabled(self):
         user = get_current_principal()
-        if user.id in ('admin', 'isouaba', 'niyi', 'delejason'):
+        if user.id in ('admin', 'isouaba', 'med', 'delejason', 'zope.mgr'):
             return True
         return False
Index: main/waeup.uniben/trunk/src/waeup/uniben/students/tests/test_browser.py
===================================================================
--- main/waeup.uniben/trunk/src/waeup/uniben/students/tests/test_browser.py	(revision 12566)
+++ main/waeup.uniben/trunk/src/waeup/uniben/students/tests/test_browser.py	(revision 12845)
@@ -839,2 +839,52 @@
         self.browser.open(self.student_path + '/clear')
         self.assertTrue('Student has been cleared' in self.browser.contents)
+
+    def test_transcripts(self):
+        studylevel = createObject(u'waeup.StudentStudyLevel')
+        studylevel.level = 100
+        studylevel.level_session = 2005
+        self.student['studycourse'].entry_mode = 'ug_ft'
+        self.student['studycourse'].addStudentStudyLevel(
+            self.certificate, studylevel)
+        studylevel2 = createObject(u'waeup.StudentStudyLevel')
+        studylevel2.level = 110
+        studylevel2.level_session = 2006
+        self.student['studycourse'].addStudentStudyLevel(
+            self.certificate, studylevel2)
+        # Add second course (COURSE has been added automatically)
+        courseticket = createObject('waeup.CourseTicket')
+        courseticket.code = 'ANYCODE'
+        courseticket.title = u'Any TITLE'
+        courseticket.credits = 13
+        courseticket.score = 66
+        courseticket.semester = 1
+        courseticket.dcode = u'ANYDCODE'
+        courseticket.fcode = u'ANYFCODE'
+        self.student['studycourse']['110']['COURSE2'] = courseticket
+        self.student['studycourse']['100']['COURSE1'].score = 55
+        self.assertEqual(self.student['studycourse']['100'].gpa_params_rectified[0], 3.0)
+        self.assertEqual(self.student['studycourse']['110'].gpa_params_rectified[0], 4.0)
+        # Get transcript data
+        td = self.student['studycourse'].getTranscriptData()
+        self.assertEqual(td[0][0]['level_key'], '100')
+        self.assertEqual(td[0][0]['sgpa'], 3.0)
+        self.assertEqual(td[0][0]['level'].level, 100)
+        self.assertEqual(td[0][0]['level'].level_session, 2005)
+        self.assertEqual(td[0][0]['tickets_1'][0].code, 'COURSE1')
+        self.assertEqual(td[0][1]['level_key'], '110')
+        self.assertEqual(td[0][1]['sgpa'], 4.0)
+        self.assertEqual(td[0][1]['level'].level, 110)
+        self.assertEqual(td[0][1]['level'].level_session, 2006)
+        self.assertEqual(td[0][1]['tickets_1'][0].code, 'ANYCODE')
+        self.assertEqual(td[1], 3.57)
+        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
+        self.browser.open(self.student_path + '/studycourse/transcript')
+        self.assertEqual(self.browser.headers['Status'], '200 Ok')
+        self.assertTrue('Transcript' in self.browser.contents)
+        # Officers can open the pdf transcript
+        self.browser.open(self.student_path + '/studycourse/transcript.pdf')
+        self.assertEqual(self.browser.headers['Status'], '200 Ok')
+        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
+        path = os.path.join(samples_dir(), 'transcript.pdf')
+        open(path, 'wb').write(self.browser.contents)
+        print "Sample PDF transcript.pdf written to %s" % path
