source: main/waeup.sirp/trunk/src/waeup/sirp/applicants/pdf.py @ 7742

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

Continue internat. of applicants package including pdf exports.

  • Property svn:keywords set to Id
File size: 8.7 KB
Line 
1## $Id: pdf.py 7714 2012-02-28 10:34:16Z 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.sirp.applicants.interfaces import IApplicant
35from waeup.sirp.browser import DEFAULT_PASSPORT_IMAGE_PATH
36from waeup.sirp.interfaces import IExtFileStore, IPDF, ISIRPUtils
37from waeup.sirp.interfaces import MessageFactory as _
38
39SLIP_STYLE = TableStyle(
40    [('VALIGN',(0,0),(-1,-1),'TOP')]
41    )
42
43
44class PDFApplicationSlip(grok.Adapter):
45
46    grok.context(IApplicant)
47    grok.implements(IPDF)
48    grok.name('application_slip')
49
50    form_fields =  grok.AutoFields(IApplicant).omit(
51        'locked', 'course_admitted')
52
53    @property
54    def title(self):
55        container_title = self.context.__parent__.title
56        portal_language = getUtility(ISIRPUtils).PORTAL_LANGUAGE
57        ar_translation = translate(_('Application Record'),
58            'waeup.sirp', target_language=portal_language)
59        return '%s - %s %s' % (container_title,
60            ar_translation, self.context.application_number)
61
62    def _setUpWidgets(self):
63        """Setup simple display widgets.
64
65        Returns the list of widgets.
66        """
67        request = TestRequest()
68        return setUpEditWidgets(
69            self.form_fields, 'form', self.context, request, {},
70            for_display=True, ignore_request=True
71            )
72
73    def _getCourseAdmittedLink(self, view):
74        """Return link, title and code in html format to the certificate
75           admitted.
76        """
77        course_admitted = self.context.course_admitted
78        if view is not None and getattr(course_admitted, '__parent__',None):
79            url = view.url(course_admitted)
80            title = course_admitted.title
81            code = course_admitted.code
82            return '<a href="%s">%s - %s</a>' %(url,code,title)
83        return ''
84
85    def _addPassportImage(self, data):
86        """Add passport image to data stream.
87
88        If no image exists yet the default image is added.
89        """
90        img = getUtility(IExtFileStore).getFileByContext(self.context)
91        if img is None:
92            img = open(DEFAULT_PASSPORT_IMAGE_PATH, 'rb')
93        doc_img = Image(img.name, width=4*cm, height=3*cm, kind='bound')
94        data.append([doc_img])
95        data.append([Spacer(1, 18)])
96        return data
97
98    def _addDeptAndFaculty(self, data):
99        """If we have a valid course admitted, add dept. and faculty to data
100           stream.
101        """
102        style = getSampleStyleSheet()
103        course_admitted = self.context.course_admitted
104        dept = getattr(
105                getattr(course_admitted, '__parent__', None),
106                '__parent__', None)
107        if dept is None:
108            return data
109        portal_language = getUtility(ISIRPUtils).PORTAL_LANGUAGE
110        dp_translation = translate(_('Department:'),
111            'waeup.sirp', target_language=portal_language)
112        f_label = '<font size=12>%s</font>' % dp_translation
113        f_text = '<font size=12>%s</font>' % dept.longtitle()
114        f_label = Paragraph(f_label, style["Normal"])
115        f_text = Paragraph(f_text, style["Normal"])
116        data.append([f_label,f_text])
117
118        faculty = getattr(dept, '__parent__', None)
119        if faculty is None:
120            return data
121        fc_translation = translate(_('Faculty:'),
122            'waeup.sirp', target_language=portal_language)
123        f_label = '<font size=12>%s</font>' % fc_translation
124        f_text = '<font size=12>%s</font>' % faculty.longtitle()
125        f_label = Paragraph(f_label, style["Normal"])
126        f_text = Paragraph(f_text, style["Normal"])
127        data.append([f_label,f_text])
128        return data
129
130    def __call__(self, view=None):
131        """Return a PDF representation of the context applicant.
132
133        If no `view` is given, the course admitted field will be an
134        empty string and author will be set as ``'unknown'``.
135
136        If a `view` is given, author will be set as the calling
137        principal.
138        """
139        pdf = canvas.Canvas('application_slip.pdf',pagesize=A4)
140        pdf.setTitle(self.title)
141        pdf.setSubject('Application')
142        if view is None:
143            pdf.setAuthor('unknown')
144        if view is not None:
145            pdf.setAuthor('%s (%s)' % (view.request.principal.title,
146                view.request.principal.id))
147        pdf.setCreator('SIRP')
148        width, height = A4
149        style = getSampleStyleSheet()
150        pdf.line(1*cm,height-(1.8*cm),width-(1*cm),height-(1.8*cm))
151
152        story = []
153        frame_header = Frame(1*cm,1*cm,width-(1.7*cm),height-(1.7*cm))
154        header_title = getattr(grok.getSite(), 'name', u'Sample University')
155        story.append(Paragraph(header_title, style["Heading1"]))
156        frame_header.addFromList(story,pdf)
157
158        story = []
159        frame_body = Frame(1*cm,1*cm,width-(2*cm),height-(3.5*cm))
160        story.append(Paragraph(self.title, style["Heading2"]))
161        story.append(Spacer(1, 18))
162        for msg in self.context.history.messages:
163            f_msg = '<font face="Courier" size=10>%s</font>' % msg
164            story.append(Paragraph(f_msg, style["Normal"]))
165        story.append(Spacer(1, 24))
166
167        # Setup table data
168        data = []
169        # Insert passport photograph
170        data = self._addPassportImage(data)
171        # Render widget fields
172        widgets = self._setUpWidgets()
173        portal_language = getUtility(ISIRPUtils).PORTAL_LANGUAGE
174        for widget in widgets: # self.widgets:
175            f_label = '<font size=12>%s</font>:' % translate(
176                widget.label.strip(), 'waeup.sirp',
177                target_language=portal_language)
178            f_label = Paragraph(f_label, style["Normal"])
179            f_text = '<font size=12>%s</font>' % widget()
180            f_text = Paragraph(f_text, style["Normal"])
181            data.append([f_label,f_text])
182        adm_translation = translate(_('Admitted Course of Study:'),
183                'waeup.sirp', target_language=portal_language)
184        f_label = '<font size=12>%s</font>' % adm_translation
185        f_text = '<font size=12>%s</font>' % (
186            self._getCourseAdmittedLink(view),)
187        f_label = Paragraph(f_label, style["Normal"])
188        f_text = Paragraph(f_text, style["Normal"])
189        data.append([f_label,f_text])
190
191        # Add dept. and faculty if applicable
192        data = self._addDeptAndFaculty(data)
193
194        # Create table
195        table = Table(data,style=SLIP_STYLE)
196        story.append(table)
197
198        # Add some comments
199        if self.context.state == 'created':
200            comment1 = _(
201                '<font size=10>Proceed to the login page of the portal' +
202                ' and enter your new credentials:' +
203                ' user name= ${a}, password = ${b}.</font>', mapping = {
204                'a':self.context.student_id, 'b':self.context.application_number}
205                )
206            comment2 = _(
207                '<font size=10>Change your password when you have ' +
208                ' logged in.</font>'
209                )
210            comment1 = Paragraph(comment1, style["Normal"])
211            comment2 = Paragraph(comment2, style["Normal"])
212            story.append(Spacer(1, 18))
213            story.append(comment1)
214            story.append(comment2)
215
216        frame_body.addFromList(story,pdf)
217
218        story = []
219        frame_footer = Frame(1*cm,0,width-(2*cm),1*cm)
220        timestamp = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
221        f_text = '<font size=10>%s</font>' % timestamp
222        story.append(Paragraph(f_text, style["Normal"]))
223        frame_footer.addFromList(story,pdf)
224        return pdf.getpdfdata()
Note: See TracBrowser for help on using the repository browser.