source: main/waeup.kofa/trunk/src/waeup/kofa/applicants/pdf.py @ 8042

Last change on this file since 8042 was 8013, checked in by Henrik Bettermann, 13 years ago

Use FriendlyDateDisplayWidget? for date of birth.

  • Property svn:keywords set to Id
File size: 9.0 KB
Line 
1## $Id: pdf.py 8013 2012-04-02 09:18:53Z henrik $
2##
3## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
18"""
19Generate PDF docs for applicants.
20"""
21import grok
22from datetime import datetime
23from zope.component import getUtility
24from zope.i18n import translate
25from reportlab.pdfgen import canvas
26from reportlab.lib.units import cm
27from reportlab.lib.pagesizes import A4
28from reportlab.lib.styles import getSampleStyleSheet
29from reportlab.platypus import Frame, Paragraph, Image, Table, Spacer
30from reportlab.platypus.tables import TableStyle
31from zope.component import getUtility
32from zope.formlib.form import setUpEditWidgets
33from zope.publisher.browser import TestRequest
34from waeup.kofa.widgets.datewidget import FriendlyDateDisplayWidget
35from waeup.kofa.applicants.interfaces import IApplicant
36from waeup.kofa.browser import DEFAULT_PASSPORT_IMAGE_PATH
37from waeup.kofa.interfaces import IExtFileStore, IPDF, IKofaUtils
38from waeup.kofa.interfaces import MessageFactory as _
39
40SLIP_STYLE = TableStyle(
41    [('VALIGN',(0,0),(-1,-1),'TOP')]
42    )
43
44
45class PDFApplicationSlip(grok.Adapter):
46
47    grok.context(IApplicant)
48    grok.implements(IPDF)
49    grok.name('application_slip')
50
51    form_fields =  grok.AutoFields(IApplicant).omit(
52        'locked', 'course_admitted')
53    form_fields['date_of_birth'].custom_widget = FriendlyDateDisplayWidget('le')
54
55    @property
56    def title(self):
57        container_title = self.context.__parent__.title
58        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
59        ar_translation = translate(_('Application Record'),
60            'waeup.kofa', target_language=portal_language)
61        return '%s - %s %s' % (container_title,
62            ar_translation, self.context.application_number)
63
64    def _setUpWidgets(self):
65        """Setup simple display widgets.
66
67        Returns the list of widgets.
68        """
69        request = TestRequest()
70        return setUpEditWidgets(
71            self.form_fields, 'form', self.context, request, {},
72            for_display=True, ignore_request=True
73            )
74
75    def _getCourseAdmittedLink(self, view):
76        """Return link, title and code in html format to the certificate
77           admitted.
78        """
79        course_admitted = self.context.course_admitted
80        if view is not None and getattr(course_admitted, '__parent__',None):
81            url = view.url(course_admitted)
82            title = course_admitted.title
83            code = course_admitted.code
84            return '<a href="%s">%s - %s</a>' %(url,code,title)
85        return ''
86
87    def _addPassportImage(self, data):
88        """Add passport image to data stream.
89
90        If no image exists yet the default image is added.
91        """
92        img = getUtility(IExtFileStore).getFileByContext(self.context)
93        if img is None:
94            img = open(DEFAULT_PASSPORT_IMAGE_PATH, 'rb')
95        doc_img = Image(img.name, width=4*cm, height=3*cm, kind='bound')
96        data.append([doc_img])
97        data.append([Spacer(1, 18)])
98        return data
99
100    def _addDeptAndFaculty(self, data):
101        """If we have a valid course admitted, add dept. and faculty to data
102           stream.
103        """
104        style = getSampleStyleSheet()
105        course_admitted = self.context.course_admitted
106        dept = getattr(
107                getattr(course_admitted, '__parent__', None),
108                '__parent__', None)
109        if dept is None:
110            return data
111        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
112        dp_translation = translate(_('Department:'),
113            'waeup.kofa', target_language=portal_language)
114        f_label = '<font size=12>%s</font>' % dp_translation
115        f_text = '<font size=12>%s</font>' % dept.longtitle()
116        f_label = Paragraph(f_label, style["Normal"])
117        f_text = Paragraph(f_text, style["Normal"])
118        data.append([f_label,f_text])
119
120        faculty = getattr(dept, '__parent__', None)
121        if faculty is None:
122            return data
123        fc_translation = translate(_('Faculty:'),
124            'waeup.kofa', target_language=portal_language)
125        f_label = '<font size=12>%s</font>' % fc_translation
126        f_text = '<font size=12>%s</font>' % faculty.longtitle()
127        f_label = Paragraph(f_label, style["Normal"])
128        f_text = Paragraph(f_text, style["Normal"])
129        data.append([f_label,f_text])
130        return data
131
132    def __call__(self, view=None):
133        """Return a PDF representation of the context applicant.
134
135        If no `view` is given, the course admitted field will be an
136        empty string and author will be set as ``'unknown'``.
137
138        If a `view` is given, author will be set as the calling
139        principal.
140        """
141        pdf = canvas.Canvas('application_slip.pdf',pagesize=A4)
142        pdf.setTitle(self.title)
143        pdf.setSubject('Application')
144        if view is None:
145            pdf.setAuthor('unknown')
146        if view is not None:
147            pdf.setAuthor('%s (%s)' % (view.request.principal.title,
148                view.request.principal.id))
149        pdf.setCreator('Kofa')
150        width, height = A4
151        style = getSampleStyleSheet()
152        pdf.line(1*cm,height-(1.8*cm),width-(1*cm),height-(1.8*cm))
153
154        story = []
155        frame_header = Frame(1*cm,1*cm,width-(1.7*cm),height-(1.7*cm))
156        header_title = getattr(grok.getSite(), 'name', u'Sample University')
157        story.append(Paragraph(header_title, style["Heading1"]))
158        frame_header.addFromList(story,pdf)
159
160        story = []
161        frame_body = Frame(1*cm,1*cm,width-(2*cm),height-(3.5*cm))
162        story.append(Paragraph(self.title, style["Heading2"]))
163        story.append(Spacer(1, 18))
164        for msg in self.context.history.messages:
165            f_msg = '<font face="Courier" size=10>%s</font>' % msg
166            story.append(Paragraph(f_msg, style["Normal"]))
167        story.append(Spacer(1, 24))
168
169        # Setup table data
170        data = []
171        # Insert passport photograph
172        data = self._addPassportImage(data)
173        # Render widget fields
174        widgets = self._setUpWidgets()
175        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
176        for widget in widgets: # self.widgets:
177            f_label = '<font size=12>%s</font>:' % translate(
178                widget.label.strip(), 'waeup.kofa',
179                target_language=portal_language)
180            f_label = Paragraph(f_label, style["Normal"])
181            f_text = '<font size=12>%s</font>' % widget()
182            # Add br tag if widgets contain div tags
183            # which are not supported by reportlab
184            f_text = f_text.replace('</div>', '</div><br />')
185            f_text = f_text.replace('\n', '')
186            f_text = Paragraph(f_text, style["Normal"])
187            data.append([f_label,f_text])
188        adm_translation = translate(_('Admitted Course of Study:'),
189                'waeup.kofa', target_language=portal_language)
190        f_label = '<font size=12>%s</font>' % adm_translation
191        f_text = '<font size=12>%s</font>' % (
192            self._getCourseAdmittedLink(view),)
193        f_label = Paragraph(f_label, style["Normal"])
194        f_text = Paragraph(f_text, style["Normal"])
195        data.append([f_label,f_text])
196
197        # Add dept. and faculty if applicable
198        data = self._addDeptAndFaculty(data)
199
200        # Create table
201        table = Table(data,style=SLIP_STYLE)
202        story.append(table)
203
204        # Add some comments
205        if self.context.state == 'created':
206            comment1 = _(
207                '<font size=10>Proceed to the login page of the portal' +
208                ' and enter your new credentials:' +
209                ' user name= ${a}, password = ${b}.</font>', mapping = {
210                'a':self.context.student_id, 'b':self.context.application_number}
211                )
212            comment2 = _(
213                '<font size=10>Change your password when you have ' +
214                ' logged in.</font>'
215                )
216            comment1 = Paragraph(comment1, style["Normal"])
217            comment2 = Paragraph(comment2, style["Normal"])
218            story.append(Spacer(1, 18))
219            story.append(comment1)
220            story.append(comment2)
221
222        frame_body.addFromList(story,pdf)
223
224        story = []
225        frame_footer = Frame(1*cm,0,width-(2*cm),1*cm)
226        timestamp = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
227        f_text = '<font size=10>%s</font>' % timestamp
228        story.append(Paragraph(f_text, style["Normal"]))
229        frame_footer.addFromList(story,pdf)
230        return pdf.getpdfdata()
Note: See TracBrowser for help on using the repository browser.