Changeset 10250 for main


Ignore:
Timestamp:
30 May 2013, 11:30:31 (11 years ago)
Author:
Henrik Bettermann
Message:

Implement ExportPDFTranscriptPage.

Location:
main/waeup.kofa/trunk/src/waeup/kofa/students
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • main/waeup.kofa/trunk/src/waeup/kofa/students/browser.py

    r10248 r10250  
    7070    IUGStudentClearance,IPGStudentClearance,
    7171    IStudentPersonal, IStudentPersonalEdit, IStudentBase, IStudentStudyCourse,
    72     IStudentStudyCourseTransfer,
     72    IStudentStudyCourseTransfer, IStudentStudyCourseTranscript,
    7373    IStudentAccommodation, IStudentStudyLevel,
    7474    ICourseTicket, ICourseTicketAdd, IStudentPaymentsContainer,
     
    433433    """
    434434
    435     def __init__(self, context, request, omit_fields):
     435    def __init__(self, context, request, omit_fields=()):
    436436        self.omit_fields = omit_fields
    437437        super(StudentBasePDFFormPage, self).__init__(context, request)
     
    720720            self, 'clearance_slip.pdf',
    721721            self.context.student, studentview, signatures=self._signatures(),
    722             sigs_in_footer=self._sigsInFooter())
     722            sigs_in_footer=self._sigsInFooter(),
     723            omit_fields=self.omit_fields)
    723724
    724725class StudentClearanceManageFormPage(KofaEditFormPage):
     
    10491050    """ Page to display the student's transcript.
    10501051    """
    1051     grok.context(IStudentStudyCourse)
     1052    grok.context(IStudentStudyCourseTranscript)
    10521053    grok.name('transcript')
    10531054    grok.require('waeup.viewStudent')
     
    10701071        return _('${a}: Transcript Data', mapping = {
    10711072            'a':self.context.student.display_fullname})
     1073
     1074class ExportPDFTranscriptPage(UtilityView, grok.View):
     1075    """Deliver a PDF slip of the context.
     1076    """
     1077    grok.context(IStudentStudyCourse)
     1078    grok.name('transcript.pdf')
     1079    grok.require('waeup.viewStudent')
     1080    form_fields = grok.AutoFields(IStudentStudyCourseTranscript)
     1081    prefix = 'form'
     1082    omit_fields = (
     1083        'department', 'faculty', 'entry_session', 'certificate',
     1084        'password', 'suspended', 'phone', 'email',
     1085        'adm_code', 'sex', 'suspended_comment')
     1086
     1087    def update(self):
     1088        super(ExportPDFTranscriptPage, self).update()
     1089        self.semester_dict = getUtility(IKofaUtils).SEMESTER_DICT
     1090        self.session_dict = dict(
     1091            [(item[1], item[0]) for item in academic_sessions()])
     1092        self.course_levels = course_levels
     1093        self.studymode_dict = getUtility(IKofaUtils).STUDY_MODES_DICT
     1094        return
     1095
     1096    @property
     1097    def label(self):
     1098        # Here we know that the cookie has been set
     1099        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
     1100        return translate(_('Academic Transcript'),
     1101            'waeup.kofa', target_language=portal_language)
     1102
     1103    def render(self):
     1104        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
     1105        Sem = translate(_('Sem.'), 'waeup.kofa', target_language=portal_language)
     1106        Code = translate(_('Code'), 'waeup.kofa', target_language=portal_language)
     1107        Title = translate(_('Title'), 'waeup.kofa', target_language=portal_language)
     1108        Cred = translate(_('Credits'), 'waeup.kofa', target_language=portal_language)
     1109        Score = translate(_('Score'), 'waeup.kofa', target_language=portal_language)
     1110        Grade = translate(_('Grade'), 'waeup.kofa', target_language=portal_language)
     1111        studentview = StudentBasePDFFormPage(self.context.student,
     1112            self.request, self.omit_fields)
     1113        students_utils = getUtility(IStudentsUtils)
     1114
     1115        tableheader = [(Code,'code', 2.5),
     1116                         (Title,'title', 7),
     1117                         (Sem, 'semester', 1.5),
     1118                         (Cred, 'credits', 1.5),
     1119                         (Score, 'score', 1.5),
     1120                         (Grade, 'grade', 1.5),
     1121                         ]
     1122
     1123        return students_utils.renderPDFTranscript(
     1124            self, 'transcript.pdf',
     1125            self.context.student, studentview,
     1126            omit_fields=self.omit_fields,
     1127            tableheader=tableheader
     1128            )
    10721129
    10731130class StudentTransferFormPage(KofaAddFormPage):
     
    12431300            tabledata_2=tabledata_2,
    12441301            tableheader_3=tableheader,
    1245             tabledata_3=tabledata_3
     1302            tabledata_3=tabledata_3,
     1303            omit_fields=self.omit_fields
    12461304            )
    12471305
     
    17401798        students_utils = getUtility(IStudentsUtils)
    17411799        return students_utils.renderPDF(self, 'payment_slip.pdf',
    1742             self.context.student, studentview, note=self.note)
     1800            self.context.student, studentview, note=self.note,
     1801            omit_fields=self.omit_fields)
    17431802
    17441803
     
    19842043        return students_utils.renderPDF(
    19852044            self, 'bed_allocation_slip.pdf',
    1986             self.context.student, studentview)
     2045            self.context.student, studentview,
     2046            omit_fields=self.omit_fields)
    19872047
    19882048class BedTicketRelocationPage(UtilityView, grok.View):
  • main/waeup.kofa/trunk/src/waeup/kofa/students/browser_templates/studycoursepage.pt

    r9140 r10250  
    55    <tal:block repeat="widget view/widgets">
    66      <tr>
    7         <td class="filedname">
     7        <td class="fieldname">
    88          <span tal:content="widget/label">label</span>:
    99        </td>
  • main/waeup.kofa/trunk/src/waeup/kofa/students/browser_templates/transcript.pt

    r10179 r10250  
    55  <tbody>
    66    <tal:block repeat="widget view/widgets">
    7       <tr tal:condition="python: 'current' not in widget.name and 'verdict' not in widget.name">
    8         <td class="filedname">
     7      <tr>
     8        <td class="fieldname">
    99          <span tal:content="widget/label">label</span>:
    1010        </td>
  • main/waeup.kofa/trunk/src/waeup/kofa/students/interfaces.py

    r9984 r10250  
    474474    'current_level'].order
    475475
     476class IStudentStudyCourseTranscript(IKofaObject):
     477    """An interface for student transcripts.
     478
     479    """
     480
     481    entry_mode = schema.Choice(
     482        title = _(u'Entry Mode'),
     483        source = StudyModeSource(),
     484        required = True,
     485        readonly = False,
     486        )
     487
     488    entry_session = schema.Choice(
     489        title = _(u'Entry Session'),
     490        source = academic_sessions_vocab,
     491        #default = datetime.now().year,
     492        required = True,
     493        readonly = False,
     494        )
     495
    476496class IStudentVerdictUpdate(IKofaObject):
    477497    """A interface for verdict imports.
  • main/waeup.kofa/trunk/src/waeup/kofa/students/studycourse.py

    r10178 r10250  
    2525from zope.interface import implementedBy
    2626from waeup.kofa.students.interfaces import (
    27     IStudentStudyCourse, IStudentNavigation, IStudentStudyLevel)
     27    IStudentStudyCourse, IStudentNavigation, IStudentStudyLevel,
     28    IStudentStudyCourseTranscript)
    2829from waeup.kofa.students.studylevel import CourseTicket
    2930from waeup.kofa.students.workflow import CLEARED, RETURNING, PAID
     
    3334    """This is a container for study levels.
    3435    """
    35     grok.implements(IStudentStudyCourse, IStudentNavigation)
     36    grok.implements(IStudentStudyCourse, IStudentNavigation,
     37        IStudentStudyCourseTranscript)
    3638    grok.provides(IStudentStudyCourse)
    3739
     
    130132            tickets_2 = []
    131133            tickets_3 = []
    132             for ticket in level_val.values():
     134            tickets = sorted(level_val.values(), key=lambda ticket: ticket.code)
     135            for ticket in tickets:
    133136                if ticket.semester == 1:
    134137                    tickets_1.append(ticket)
  • main/waeup.kofa/trunk/src/waeup/kofa/students/utils.py

    r10021 r10250  
    107107        )
    108108
    109 def render_student_data(studentview):
     109def render_student_data(studentview, omit_fields=()):
    110110    """Render student table for an existing frame.
    111111    """
     
    143143
    144144    if getattr(studentview.context, 'certcode', None):
    145         f_label = _('Study Course:')
    146         f_label = Paragraph(f_label, ENTRY1_STYLE)
    147         f_text = formatted_text(
    148             studentview.context['studycourse'].certificate.longtitle())
    149         f_text = Paragraph(f_text, ENTRY1_STYLE)
    150         data_right.append([f_label,f_text])
    151 
    152         f_label = _('Department:')
    153         f_label = Paragraph(f_label, ENTRY1_STYLE)
    154         f_text = formatted_text(
    155             studentview.context[
    156             'studycourse'].certificate.__parent__.__parent__.longtitle(),
    157             )
    158         f_text = Paragraph(f_text, ENTRY1_STYLE)
    159         data_right.append([f_label,f_text])
    160 
    161         f_label = _('Faculty:')
    162         f_label = Paragraph(f_label, ENTRY1_STYLE)
    163         f_text = formatted_text(
    164             studentview.context[
    165             'studycourse'].certificate.__parent__.__parent__.__parent__.longtitle(),
    166             )
    167         f_text = Paragraph(f_text, ENTRY1_STYLE)
    168         data_right.append([f_label,f_text])
    169 
    170         f_label = _('Entry Session: ')
    171         f_label = Paragraph(f_label, ENTRY1_STYLE)
    172         entry_session = studentview.context['studycourse'].entry_session
    173         entry_session = academic_sessions_vocab.getTerm(entry_session).title
    174         f_text = formatted_text(entry_session)
    175         f_text = Paragraph(f_text, ENTRY1_STYLE)
    176         data_right.append([f_label,f_text])
     145        if not 'certificate' in omit_fields:
     146            f_label = _('Study Course:')
     147            f_label = Paragraph(f_label, ENTRY1_STYLE)
     148            f_text = formatted_text(
     149                studentview.context['studycourse'].certificate.longtitle())
     150            f_text = Paragraph(f_text, ENTRY1_STYLE)
     151            data_right.append([f_label,f_text])
     152        if not 'department' in omit_fields:
     153            f_label = _('Department:')
     154            f_label = Paragraph(f_label, ENTRY1_STYLE)
     155            f_text = formatted_text(
     156                studentview.context[
     157                'studycourse'].certificate.__parent__.__parent__.longtitle(),
     158                )
     159            f_text = Paragraph(f_text, ENTRY1_STYLE)
     160            data_right.append([f_label,f_text])
     161        if not 'faculty' in omit_fields:
     162            f_label = _('Faculty:')
     163            f_label = Paragraph(f_label, ENTRY1_STYLE)
     164            f_text = formatted_text(
     165                studentview.context[
     166                'studycourse'].certificate.__parent__.__parent__.__parent__.longtitle(),
     167                )
     168            f_text = Paragraph(f_text, ENTRY1_STYLE)
     169            data_right.append([f_label,f_text])
     170        if not 'entry_session' in omit_fields:
     171            f_label = _('Entry Session: ')
     172            f_label = Paragraph(f_label, ENTRY1_STYLE)
     173            entry_session = studentview.context['studycourse'].entry_session
     174            entry_session = academic_sessions_vocab.getTerm(entry_session).title
     175            f_text = formatted_text(entry_session)
     176            f_text = Paragraph(f_text, ENTRY1_STYLE)
     177            data_right.append([f_label,f_text])
    177178
    178179    table_left = Table(data_left,style=SLIP_STYLE)
     
    203204        element[2]*cm for element in tableheader], style=CONTENT_STYLE)
    204205    return table
     206
     207def render_transcript_data(view,tableheader,levels_data):
     208    """Render children table for an existing frame.
     209    """
     210    data = []
     211    line = []
     212    style = getSampleStyleSheet()
     213
     214    for level in levels_data:
     215        level_obj = level['level']
     216        subheader = 'Session %s, Level %s' % (
     217            view.session_dict[level_obj.level_session],
     218            view.course_levels.getTerm(level_obj.level).title)
     219        data.append(Paragraph(subheader, HEADING_STYLE))
     220
     221        tabledata = []
     222        for element in tableheader:
     223            field = '<strong>%s</strong>' % formatted_text(element[0])
     224            field = Paragraph(field, style["Normal"])
     225            line.append(field)
     226        tabledata.append(line)
     227        tickets = []
     228        tickets += level['tickets_1']
     229        tickets += level['tickets_2']
     230        tickets += level['tickets_3']
     231        for ticket in tickets:
     232            line = []
     233            for element in tableheader:
     234                  field = formatted_text(getattr(ticket,element[1],u' '))
     235                  field = Paragraph(field, style["Normal"])
     236                  line.append(field)
     237            tabledata.append(line)
     238        table = Table(tabledata,colWidths=[
     239            element[2]*cm for element in tableheader], style=CONTENT_STYLE)
     240        data.append(table)
     241    return data
    205242
    206243def docs_as_flowables(view, lang='en'):
     
    478515        return text
    479516
    480     def renderPDFAdmissionLetter(self, view, student=None):
     517    def renderPDFAdmissionLetter(self, view, student=None, omit_fields=()):
    481518        """Render pdf admission letter.
    482519        """
     
    506543
    507544        # Student data
    508         data.append(render_student_data(view))
     545        data.append(render_student_data(view, omit_fields))
    509546
    510547        # Insert history
     
    540577                  tableheader_3=None, tabledata_3=None,
    541578                  note=None, signatures=None, sigs_in_footer=(),
    542                   show_scans=True, topMargin=1.5):
     579                  show_scans=True, topMargin=1.5,
     580                  omit_fields=()):
    543581        """Render pdf slips for various pages.
    544582        """
     
    565603            bd_translation = trans(_('Base Data'), portal_language)
    566604            data.append(Paragraph(bd_translation, HEADING_STYLE))
    567             data.append(render_student_data(studentview))
     605            data.append(render_student_data(studentview, omit_fields))
    568606
    569607        # Insert widgets
     
    636674        return pdf_stream
    637675
     676    def renderPDFTranscript(self, view, filename='transcript.pdf',
     677                  student=None,
     678                  studentview=None,
     679                  note=None, signatures=None, sigs_in_footer=(),
     680                  show_scans=True, topMargin=1.5,
     681                  omit_fields=(),
     682                  tableheader=None):
     683        """Render pdf slips for transcript.
     684        """
     685        # XXX: tell what the different parameters mean
     686        style = getSampleStyleSheet()
     687        creator = self.getPDFCreator(student)
     688        data = []
     689        doc_title = view.label
     690        author = '%s (%s)' % (view.request.principal.title,
     691                              view.request.principal.id)
     692        footer_text = view.label.split('\n')
     693        if len(footer_text) > 2:
     694            # We can add a department in first line
     695            footer_text = footer_text[1]
     696        else:
     697            # Only the first line is used for the footer
     698            footer_text = footer_text[0]
     699        if getattr(student, 'student_id', None) is not None:
     700            footer_text = "%s - %s - " % (student.student_id, footer_text)
     701
     702        # Insert student data table
     703        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
     704        if student is not None:
     705            #bd_translation = trans(_('Base Data'), portal_language)
     706            #data.append(Paragraph(bd_translation, HEADING_STYLE))
     707            data.append(render_student_data(studentview, omit_fields))
     708
     709
     710        transcript_data = view.context.getTranscriptData()
     711        levels_data = transcript_data[0]
     712        gpa = transcript_data[1]
     713
     714        contextdata = []
     715        f_label = _('Course of Study:')
     716        f_label = Paragraph(f_label, ENTRY1_STYLE)
     717        f_text = formatted_text(view.context.certificate.longtitle())
     718        f_text = Paragraph(f_text, ENTRY1_STYLE)
     719        contextdata.append([f_label,f_text])
     720
     721        f_label = _('Faculty:')
     722        f_label = Paragraph(f_label, ENTRY1_STYLE)
     723        f_text = formatted_text(
     724            view.context.certificate.__parent__.__parent__.__parent__.longtitle())
     725        f_text = Paragraph(f_text, ENTRY1_STYLE)
     726        contextdata.append([f_label,f_text])
     727
     728        f_label = _('Department:')
     729        f_label = Paragraph(f_label, ENTRY1_STYLE)
     730        f_text = formatted_text(
     731            view.context.certificate.__parent__.__parent__.longtitle())
     732        f_text = Paragraph(f_text, ENTRY1_STYLE)
     733        contextdata.append([f_label,f_text])
     734
     735        f_label = _('Entry Session:')
     736        f_label = Paragraph(f_label, ENTRY1_STYLE)
     737        f_text = formatted_text(view.session_dict[view.context.entry_session])
     738        f_text = Paragraph(f_text, ENTRY1_STYLE)
     739        contextdata.append([f_label,f_text])
     740
     741        f_label = _('Entry Mode:')
     742        f_label = Paragraph(f_label, ENTRY1_STYLE)
     743        f_text = formatted_text(view.studymode_dict[view.context.entry_mode])
     744        f_text = Paragraph(f_text, ENTRY1_STYLE)
     745        contextdata.append([f_label,f_text])
     746
     747        f_label = _('Final GPA:')
     748        f_label = Paragraph(f_label, ENTRY1_STYLE)
     749        f_text = formatted_text(gpa)
     750        f_text = Paragraph(f_text, ENTRY1_STYLE)
     751        contextdata.append([f_label,f_text])
     752
     753        contexttable = Table(contextdata,style=SLIP_STYLE)
     754        data.append(contexttable)
     755
     756        transcripttables = render_transcript_data(
     757            view, tableheader, levels_data)
     758        data.extend(transcripttables)
     759
     760        # Insert signatures
     761        # XXX: We are using only sigs_in_footer in waeup.kofa, so we
     762        # do not have a test for the following lines.
     763        if signatures and not sigs_in_footer:
     764            data.append(Spacer(1, 20))
     765            # Render one signature table per signature to
     766            # get date and signature in line.
     767            for signature in signatures:
     768                signaturetables = get_signature_tables(signature)
     769                data.append(signaturetables[0])
     770
     771        view.response.setHeader(
     772            'Content-Type', 'application/pdf')
     773        try:
     774            pdf_stream = creator.create_pdf(
     775                data, None, doc_title, author=author, footer=footer_text,
     776                note=note, sigs_in_footer=sigs_in_footer, topMargin=topMargin)
     777        except IOError:
     778            view.flash('Error in image file.')
     779            return view.redirect(view.url(view.context))
     780        return pdf_stream
     781
    638782    def maxCredits(self, studylevel):
    639783        """Return maximum credits.
Note: See TracChangeset for help on using the changeset viewer.