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

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

Convert longtitle() into property attribute.

  • Property svn:keywords set to Id
File size: 7.8 KB
Line 
1## $Id: pdf.py 10650 2013-09-25 06:46: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 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, get_qrcode
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 _addLoginInformation(self):
98        if self.context.state == 'created':
99            comment = translate(_(
100                '\n 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            return comment
109        return
110
111    def _getPDFCreator(self):
112        return getUtility(IPDFCreator)
113
114    def __call__(self, view=None, note=None):
115        """Return a PDF representation of the context applicant.
116
117        If no `view` is given, the course admitted field will be an
118        empty string and author will be set as ``'unknown'``.
119
120        If a `view` is given, author will be set as the calling
121        principal.
122        """
123        doc_title = '\n'.join([x.strip() for x in self.title.split(' - ')])
124        data = []
125        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
126        separators = getUtility(IApplicantsUtils).SEPARATORS_DICT
127        creator = self._getPDFCreator()
128
129        # append history
130        data.extend(creator.fromStringList(self.context.history.messages))
131        data.append(Spacer(1, 5))
132
133        # create three-column header table
134        # append photograph to the left
135        img_path = getattr(
136            getUtility(IExtFileStore).getFileByContext(self.context),
137            'name', DEFAULT_PASSPORT_IMAGE_PATH)
138        data_left = [[creator.getImage(img_path)]]
139        table_left = Table(data_left,style=SLIP_STYLE)
140
141        # append base data table to the middle
142        fields = [
143            field for field in self.form_fields
144                if field.__name__ in self.column_two_fields]
145        table_middle = creator.getWidgetsTable(
146            fields, self.context, None, lang=portal_language,
147            separators=None, colWidths=[5*cm, 4.5*cm])
148
149        # append QR code to the right
150        if view is not None:
151            url = view.url(self.context, 'application_slip.pdf')
152            data_right = [[get_qrcode(url, width=70.0)]]
153            table_right = Table(data_right,style=SLIP_STYLE)
154        else:
155            table_right = None
156
157        header_table = Table(
158            [[table_left, table_middle, table_right],],style=SLIP_STYLE)
159        data.append(header_table)
160
161        # append widgets except those already added in column two
162        # and those in two_columns_design_fields
163        dept, faculty = self._getDeptAndFaculty()
164        fields = [
165            field for field in self.form_fields
166                if not field.__name__ in self.column_two_fields and
167                not field.__name__ in self.two_columns_design_fields]
168        data.append(creator.getWidgetsTable(
169            fields, self.context, view, lang=portal_language,
170            domain='waeup.kofa', separators=separators,
171            course_label='Admitted Course of Study:',
172            course_link=self._getCourseAdmittedLink(view),
173            dept=dept, faculty=faculty))
174
175        # append two-column table of widgets of those fields defined in
176        # two_columns_design_fields
177        if len(self.two_columns_design_fields):
178            fields = [
179                field for field in self.form_fields
180                    if not field.__name__ in self.column_two_fields and
181                    field.__name__ in self.two_columns_design_fields]
182            if fields:
183                data.append(creator.getWidgetsTable(
184                    fields, self.context, view, lang=portal_language,
185                    domain='waeup.kofa', separators=separators,
186                    twoDataCols=True))
187
188        # append login information
189        note = None
190        login_information = self._addLoginInformation()
191        if not None in (self.note, login_information):
192            note = self.note + login_information
193        elif self.note:
194            note = self.note
195        elif login_information:
196            note = login_information
197
198        return creator.create_pdf(data, None, doc_title, note=note)
Note: See TracBrowser for help on using the repository browser.