Index: main/waeup.kofa/trunk/src/waeup/kofa/students/utils.py
===================================================================
--- main/waeup.kofa/trunk/src/waeup/kofa/students/utils.py	(revision 15873)
+++ main/waeup.kofa/trunk/src/waeup/kofa/students/utils.py	(revision 15879)
@@ -675,4 +675,179 @@
         return sorted_beds[0]
 
+    def GPABoundaries(self, faccode=None, depcode=None, certcode=None):
+        return ((1, 'Fail'),
+               (1.5, 'Pass'),
+               (2.4, '3rd Class'),
+               (3.5, '2nd Class Lower'),
+               (4.5, '2nd Class Upper'),
+               (5, '1st Class'))
+
+    def getClassFromCGPA(self, gpa, student):
+        """Determine the class of degree. In some custom packages
+        this class depends on e.g. the entry session of the student. In the
+        base package, it does not.
+        """
+        if gpa < self.GPABoundaries()[0][0]:
+            return 0, self.GPABoundaries()[0][1]
+        if gpa < self.GPABoundaries()[1][0]:
+            return 1, self.GPABoundaries()[1][1]
+        if gpa < self.GPABoundaries()[2][0]:
+            return 2, self.GPABoundaries()[2][1]
+        if gpa < self.GPABoundaries()[3][0]:
+            return 3, self.GPABoundaries()[3][1]
+        if gpa < self.GPABoundaries()[4][0]:
+            return 4, self.GPABoundaries()[4][1]
+        if gpa <= self.GPABoundaries()[5][0]:
+            return 5, self.GPABoundaries()[5][1]
+        return
+
+    def getDegreeClassNumber(self, level_obj):
+        """Get degree class number (used for SessionResultsPresentation
+        reports).
+        """
+        if level_obj.gpa_params[1] == 0:
+            # No credits weighted
+            return 6
+        return self.getClassFromCGPA(
+            level_obj.cumulative_params[0], level_obj.student)[0]
+
+    def _saveTranscriptPDF(self, student, transcript):
+        """Create a transcript PDF file and store it in student folder.
+        """
+        file_store = getUtility(IExtFileStore)
+        file_id = IFileStoreNameChooser(student).chooseName(
+            attr="final_transcript.pdf")
+        file_store.createFile(file_id, StringIO(transcript))
+        return
+
+    def warnCreditsOOR(self, studylevel, course=None):
+        """Return message if credits are out of range. In the base
+        package only maximum credits is set.
+        """
+        if course and studylevel.total_credits + course.credits > 50:
+            return _('Maximum credits exceeded.')
+        elif studylevel.total_credits > 50:
+            return _('Maximum credits exceeded.')
+        return
+
+    def getBedCoordinates(self, bedticket):
+        """Return descriptive bed coordinates.
+        This method can be used to customize the `display_coordinates`
+        property method in order to  display a
+        customary description of the bed space.
+        """
+        return bedticket.bed_coordinates
+
+    def clearance_disabled_message(self, student):
+        """Render message if clearance is disabled.
+        """
+        try:
+            session_config = grok.getSite()[
+                'configuration'][str(student.current_session)]
+        except KeyError:
+            return _('Session configuration object is not available.')
+        if not session_config.clearance_enabled:
+            return _('Clearance is disabled for this session.')
+        return None
+
+    def getPDFCreator(self, context):
+        """Get a pdf creator suitable for `context`.
+        The default implementation always returns the default creator.
+        """
+        return getUtility(IPDFCreator)
+
+    def renderPDF(self, view, filename='slip.pdf', student=None,
+                  studentview=None,
+                  tableheader=[], tabledata=[],
+                  note=None, signatures=None, sigs_in_footer=(),
+                  show_scans=True, topMargin=1.5,
+                  omit_fields=()):
+        """Render pdf slips for various pages (also some pages
+        in the applicants module).
+        """
+        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
+        # XXX: tell what the different parameters mean
+        style = getSampleStyleSheet()
+        creator = self.getPDFCreator(student)
+        data = []
+        doc_title = view.label
+        author = '%s (%s)' % (view.request.principal.title,
+                              view.request.principal.id)
+        footer_text = view.label.split('\n')
+        if len(footer_text) > 1:
+            # We can add a department in first line, second line is used
+            footer_text = footer_text[1]
+        else:
+            # Only the first line is used for the footer
+            footer_text = footer_text[0]
+        if getattr(student, 'student_id', None) is not None:
+            footer_text = "%s - %s - " % (student.student_id, footer_text)
+
+        # Insert student data table
+        if student is not None:
+            bd_translation = trans(_('Base Data'), portal_language)
+            data.append(Paragraph(bd_translation, HEADING_STYLE))
+            data.append(render_student_data(
+                studentview, view.context, omit_fields, lang=portal_language,
+                slipname=filename))
+
+        # Insert widgets
+        if view.form_fields:
+            data.append(Paragraph(view.title, HEADING_STYLE))
+            separators = getattr(self, 'SEPARATORS_DICT', {})
+            table = creator.getWidgetsTable(
+                view.form_fields, view.context, None, lang=portal_language,
+                separators=separators)
+            data.append(table)
+
+        # Insert scanned docs
+        if show_scans:
+            data.extend(docs_as_flowables(view, portal_language))
+
+        # Insert history
+        if filename == 'clearance_slip.pdf':
+            hist_translation = trans(_('Workflow History'), portal_language)
+            data.append(Paragraph(hist_translation, HEADING_STYLE))
+            data.extend(creator.fromStringList(student.history.messages))
+
+        # Insert content tables (optionally on second page)
+        if hasattr(view, 'tabletitle'):
+            for i in range(len(view.tabletitle)):
+                if tabledata[i] and tableheader[i]:
+                    #data.append(PageBreak())
+                    #data.append(Spacer(1, 20))
+                    data.append(Paragraph(view.tabletitle[i], HEADING_STYLE))
+                    data.append(Spacer(1, 8))
+                    contenttable = render_table_data(tableheader[i],tabledata[i])
+                    data.append(contenttable)
+
+        # Insert signatures
+        # XXX: We are using only sigs_in_footer in waeup.kofa, so we
+        # do not have a test for the following lines.
+        if signatures and not sigs_in_footer:
+            data.append(Spacer(1, 20))
+            # Render one signature table per signature to
+            # get date and signature in line.
+            for signature in signatures:
+                signaturetables = get_signature_tables(signature)
+                data.append(signaturetables[0])
+
+        view.response.setHeader(
+            'Content-Type', 'application/pdf')
+        try:
+            pdf_stream = creator.create_pdf(
+                data, None, doc_title, author=author, footer=footer_text,
+                note=note, sigs_in_footer=sigs_in_footer, topMargin=topMargin)
+        except IOError:
+            view.flash('Error in image file.')
+            return view.redirect(view.url(view.context))
+        except LayoutError, err:
+            view.flash(
+                'PDF file could not be created. Reportlab error message: %s'
+                % escape(err.message),
+                type="danger")
+            return view.redirect(view.url(view.context))
+        return pdf_stream
+
     def _admissionText(self, student, portal_language):
         inst_name = grok.getSite()['configuration'].name
@@ -739,149 +914,4 @@
             note=post_text)
         return pdf_stream
-
-    def getPDFCreator(self, context):
-        """Get a pdf creator suitable for `context`.
-        The default implementation always returns the default creator.
-        """
-        return getUtility(IPDFCreator)
-
-    def renderPDF(self, view, filename='slip.pdf', student=None,
-                  studentview=None,
-                  tableheader=[], tabledata=[],
-                  note=None, signatures=None, sigs_in_footer=(),
-                  show_scans=True, topMargin=1.5,
-                  omit_fields=()):
-        """Render pdf slips for various pages (also some pages
-        in the applicants module).
-        """
-        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
-        # XXX: tell what the different parameters mean
-        style = getSampleStyleSheet()
-        creator = self.getPDFCreator(student)
-        data = []
-        doc_title = view.label
-        author = '%s (%s)' % (view.request.principal.title,
-                              view.request.principal.id)
-        footer_text = view.label.split('\n')
-        if len(footer_text) > 1:
-            # We can add a department in first line, second line is used
-            footer_text = footer_text[1]
-        else:
-            # Only the first line is used for the footer
-            footer_text = footer_text[0]
-        if getattr(student, 'student_id', None) is not None:
-            footer_text = "%s - %s - " % (student.student_id, footer_text)
-
-        # Insert student data table
-        if student is not None:
-            bd_translation = trans(_('Base Data'), portal_language)
-            data.append(Paragraph(bd_translation, HEADING_STYLE))
-            data.append(render_student_data(
-                studentview, view.context, omit_fields, lang=portal_language,
-                slipname=filename))
-
-        # Insert widgets
-        if view.form_fields:
-            data.append(Paragraph(view.title, HEADING_STYLE))
-            separators = getattr(self, 'SEPARATORS_DICT', {})
-            table = creator.getWidgetsTable(
-                view.form_fields, view.context, None, lang=portal_language,
-                separators=separators)
-            data.append(table)
-
-        # Insert scanned docs
-        if show_scans:
-            data.extend(docs_as_flowables(view, portal_language))
-
-        # Insert history
-        if filename == 'clearance_slip.pdf':
-            hist_translation = trans(_('Workflow History'), portal_language)
-            data.append(Paragraph(hist_translation, HEADING_STYLE))
-            data.extend(creator.fromStringList(student.history.messages))
-
-        # Insert content tables (optionally on second page)
-        if hasattr(view, 'tabletitle'):
-            for i in range(len(view.tabletitle)):
-                if tabledata[i] and tableheader[i]:
-                    #data.append(PageBreak())
-                    #data.append(Spacer(1, 20))
-                    data.append(Paragraph(view.tabletitle[i], HEADING_STYLE))
-                    data.append(Spacer(1, 8))
-                    contenttable = render_table_data(tableheader[i],tabledata[i])
-                    data.append(contenttable)
-
-        # Insert signatures
-        # XXX: We are using only sigs_in_footer in waeup.kofa, so we
-        # do not have a test for the following lines.
-        if signatures and not sigs_in_footer:
-            data.append(Spacer(1, 20))
-            # Render one signature table per signature to
-            # get date and signature in line.
-            for signature in signatures:
-                signaturetables = get_signature_tables(signature)
-                data.append(signaturetables[0])
-
-        view.response.setHeader(
-            'Content-Type', 'application/pdf')
-        try:
-            pdf_stream = creator.create_pdf(
-                data, None, doc_title, author=author, footer=footer_text,
-                note=note, sigs_in_footer=sigs_in_footer, topMargin=topMargin)
-        except IOError:
-            view.flash('Error in image file.')
-            return view.redirect(view.url(view.context))
-        except LayoutError, err:
-            view.flash(
-                'PDF file could not be created. Reportlab error message: %s'
-                % escape(err.message),
-                type="danger")
-            return view.redirect(view.url(view.context))
-        return pdf_stream
-
-    def GPABoundaries(self, faccode=None, depcode=None, certcode=None):
-        return ((1, 'Fail'),
-               (1.5, 'Pass'),
-               (2.4, '3rd Class'),
-               (3.5, '2nd Class Lower'),
-               (4.5, '2nd Class Upper'),
-               (5, '1st Class'))
-
-    def getClassFromCGPA(self, gpa, student):
-        """Determine the class of degree. In some custom packages
-        this class depends on e.g. the entry session of the student. In the
-        base package, it does not.
-        """
-        if gpa < self.GPABoundaries()[0][0]:
-            return 0, self.GPABoundaries()[0][1]
-        if gpa < self.GPABoundaries()[1][0]:
-            return 1, self.GPABoundaries()[1][1]
-        if gpa < self.GPABoundaries()[2][0]:
-            return 2, self.GPABoundaries()[2][1]
-        if gpa < self.GPABoundaries()[3][0]:
-            return 3, self.GPABoundaries()[3][1]
-        if gpa < self.GPABoundaries()[4][0]:
-            return 4, self.GPABoundaries()[4][1]
-        if gpa <= self.GPABoundaries()[5][0]:
-            return 5, self.GPABoundaries()[5][1]
-        return
-
-    def getDegreeClassNumber(self, level_obj):
-        """Get degree class number (used for SessionResultsPresentation
-        reports).
-        """
-        if level_obj.gpa_params[1] == 0:
-            # No credits weighted
-            return 6
-        return self.getClassFromCGPA(
-            level_obj.cumulative_params[0], level_obj.student)[0]
-
-    def _saveTranscriptPDF(self, student, transcript):
-        """Create a transcript PDF file and store it in student folder.
-        """
-        file_store = getUtility(IExtFileStore)
-        file_id = IFileStoreNameChooser(student).chooseName(
-            attr="final_transcript.pdf")
-        file_store.createFile(file_id, StringIO(transcript))
-        return
 
     def renderPDFTranscript(self, view, filename='transcript.pdf',
@@ -1093,34 +1123,4 @@
         return pdf_stream
 
-    def warnCreditsOOR(self, studylevel, course=None):
-        """Return message if credits are out of range. In the base
-        package only maximum credits is set.
-        """
-        if course and studylevel.total_credits + course.credits > 50:
-            return _('Maximum credits exceeded.')
-        elif studylevel.total_credits > 50:
-            return _('Maximum credits exceeded.')
-        return
-
-    def getBedCoordinates(self, bedticket):
-        """Return descriptive bed coordinates.
-        This method can be used to customize the `display_coordinates`
-        property method in order to  display a
-        customary description of the bed space.
-        """
-        return bedticket.bed_coordinates
-
-    def clearance_disabled_message(self, student):
-        """Render message if clearance is disabled.
-        """
-        try:
-            session_config = grok.getSite()[
-                'configuration'][str(student.current_session)]
-        except KeyError:
-            return _('Session configuration object is not available.')
-        if not session_config.clearance_enabled:
-            return _('Clearance is disabled for this session.')
-        return None
-
     #: A dictionary which maps widget names to headlines. The headline
     #: is rendered in forms and on pdf slips above the respective
