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

Last change on this file since 10319 was 10319, checked in by Henrik Bettermann, 11 years ago

Render two-column table of tables (not yet tested in custom packages).

  • Property svn:keywords set to Id
File size: 7.1 KB
Line 
1## $Id: pdf.py 10319 2013-06-20 19:41:56Z 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 reportlab.platypus import Paragraph, Spacer, Table
23from reportlab.lib.units import cm
24from zope.component import getUtility
25from zope.i18n import translate
26from waeup.kofa.applicants.interfaces import IApplicant, IApplicantsUtils
27from waeup.kofa.browser import DEFAULT_PASSPORT_IMAGE_PATH
28from waeup.kofa.browser.interfaces import IPDFCreator
29from waeup.kofa.browser.pdf import SMALL_PARA_STYLE, ENTRY1_STYLE
30from waeup.kofa.interfaces import IExtFileStore, IPDF, IKofaUtils
31from waeup.kofa.interfaces import MessageFactory as _
32from waeup.kofa.widgets.datewidget import FriendlyDateDisplayWidget
33
34SLIP_STYLE = [
35    ('VALIGN',(0,0),(-1,-1),'TOP'),
36    #('FONT', (0,0), (-1,-1), 'Helvetica', 11),
37    ]
38
39class PDFApplicationSlip(grok.Adapter):
40    """Create a PDF application slip for applicants.
41    """
42    # XXX: Many things in here are reusable. We might want to split
43    # things. Possibly move parts to IPDFCreator?
44    grok.context(IApplicant)
45    grok.implements(IPDF)
46    grok.name('application_slip')
47    note = None
48
49    form_fields =  grok.AutoFields(IApplicant).omit(
50        'locked', 'course_admitted', 'suspended',
51        )
52    form_fields['date_of_birth'].custom_widget = FriendlyDateDisplayWidget('le')
53    column_two_fields = ('applicant_id', 'reg_number',
54        'firstname', 'middlename', 'lastname')
55    two_columns_design_fields = []
56
57    @property
58    def target(self):
59        return getattr(self.context.__parent__, 'prefix', None)
60
61    @property
62    def title(self):
63        container_title = self.context.__parent__.title
64        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
65        ar_translation = translate(_('Application Record'),
66            'waeup.kofa', target_language=portal_language)
67        return '%s - %s %s' % (container_title,
68            ar_translation, self.context.application_number)
69
70    def _getCourseAdmittedLink(self, view):
71        """Return link, title and code in html format to the certificate
72           admitted.
73        """
74        course_admitted = self.context.course_admitted
75        if view is not None and getattr(course_admitted, '__parent__',None):
76            url = view.url(course_admitted)
77            title = course_admitted.title
78            code = course_admitted.code
79            return '<a href="%s">%s - %s</a>' %(url,code,title)
80        return ''
81
82    def _getDeptAndFaculty(self):
83        """Return long titles of department and faculty.
84
85        Returns a list [department_title, faculty_title]
86
87        If the context applicant has no course admitted or dept. and
88        faculty cannot be determined, ``None`` is returned.
89        """
90        course_admitted = self.context.course_admitted
91        dept = getattr(
92                getattr(course_admitted, '__parent__', None),
93                '__parent__', None)
94        faculty = getattr(dept, '__parent__', None)
95        return [x is not None and x.longtitle() or x for x in dept, faculty]
96
97    def _addComments(self, data):
98        if self.context.state == 'created':
99            comment = translate(_(
100                'Proceed to the login page of the portal' +
101                ' and enter your new credentials:' +
102                ' user name= ${a}, password = ${b}. ' +
103                'Change your password when you have logged in.',
104                mapping = {
105                    'a':self.context.student_id,
106                    'b':self.context.application_number}
107                ))
108            comment = Paragraph(comment, SMALL_PARA_STYLE)
109            data.extend([Spacer(1, 18), comment])
110        return data
111
112    def _getPDFCreator(self):
113        return getUtility(IPDFCreator)
114
115    def __call__(self, view=None, note=None):
116        """Return a PDF representation of the context applicant.
117
118        If no `view` is given, the course admitted field will be an
119        empty string and author will be set as ``'unknown'``.
120
121        If a `view` is given, author will be set as the calling
122        principal.
123        """
124        doc_title = '\n'.join([x.strip() for x in self.title.split(' - ')])
125        data = []
126        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
127        separators = getUtility(IApplicantsUtils).SEPARATORS_DICT
128        creator = self._getPDFCreator()
129
130        # append history
131        data.extend(creator.fromStringList(self.context.history.messages))
132        data.append(Spacer(1, 20))
133
134        # create two-column header table
135        # append photograph to the left
136        img_path = getattr(
137            getUtility(IExtFileStore).getFileByContext(self.context),
138            'name', DEFAULT_PASSPORT_IMAGE_PATH)
139        data_left = [[creator.getImage(img_path)]]
140        table_left = Table(data_left,style=SLIP_STYLE)
141
142        # append column-two fields to the right
143        fields = [
144            field for field in self.form_fields
145                if field.__name__ in self.column_two_fields]
146        table_right = creator.getWidgetsTable(
147            fields, self.context, None, lang=portal_language,
148            separators=None, colWidths=[5*cm, 6*cm])
149        header_table = Table([[table_left, table_right],],style=SLIP_STYLE)
150        data.append(header_table)
151
152        # append two-column table of widgets of those fields defined in
153        # two_columns_design_fields
154        fields = [
155            field for field in self.form_fields
156                if not field.__name__ in self.column_two_fields and
157                field.__name__ in self.two_columns_design_fields]
158        if fields:
159            data.append(creator.getWidgetsTable(
160                fields, self.context, view, lang=portal_language,
161                domain='waeup.kofa', twoDataCols=True))
162
163        # append widgets except those already added in column two
164        dept, faculty = self._getDeptAndFaculty()
165        fields = [
166            field for field in self.form_fields
167                if not field.__name__ in self.column_two_fields and
168                not field.__name__ in self.two_columns_design_fields]
169        data.append(creator.getWidgetsTable(
170            fields, self.context, view, lang=portal_language,
171            domain='waeup.kofa', separators=separators,
172            course_label='Admitted Course of Study:',
173            course_link=self._getCourseAdmittedLink(view),
174            dept=dept, faculty=faculty))
175
176        # append comments
177        data = self._addComments(data)
178
179        return creator.create_pdf(data, None, doc_title, note=self.note)
Note: See TracBrowser for help on using the repository browser.