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

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

Condense application slip a bit more.

  • Property svn:keywords set to Id
File size: 7.5 KB
Line 
1## $Id: pdf.py 10333 2013-06-21 15:42:30Z 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 _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 two-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 column-two fields to the right
142        fields = [
143            field for field in self.form_fields
144                if field.__name__ in self.column_two_fields]
145        table_right = creator.getWidgetsTable(
146            fields, self.context, None, lang=portal_language,
147            separators=None, colWidths=[5*cm, 6*cm])
148        header_table = Table([[table_left, table_right],],style=SLIP_STYLE)
149        data.append(header_table)
150
151        # append widgets except those already added in column two
152        # and those in two_columns_design_fields
153        dept, faculty = self._getDeptAndFaculty()
154        fields = [
155            field for field in self.form_fields
156                if not field.__name__ in self.column_two_fields and
157                not field.__name__ in self.two_columns_design_fields]
158        data.append(creator.getWidgetsTable(
159            fields, self.context, view, lang=portal_language,
160            domain='waeup.kofa', separators=separators,
161            course_label='Admitted Course of Study:',
162            course_link=self._getCourseAdmittedLink(view),
163            dept=dept, faculty=faculty))
164
165        # append two-column table of widgets of those fields defined in
166        # two_columns_design_fields
167        if len(self.two_columns_design_fields):
168            fields = [
169                field for field in self.form_fields
170                    if not field.__name__ in self.column_two_fields and
171                    field.__name__ in self.two_columns_design_fields]
172            if fields:
173                data.append(creator.getWidgetsTable(
174                    fields, self.context, view, lang=portal_language,
175                    domain='waeup.kofa', separators=separators,
176                    twoDataCols=True))
177
178        # append login information
179        note = None
180        login_information = self._addLoginInformation()
181        if not None in (self.note, login_information):
182            note = self.note + login_information
183        elif self.note:
184            note = self.note
185        elif login_information:
186            note = login_information
187
188        return creator.create_pdf(data, None, doc_title, note=note)
Note: See TracBrowser for help on using the repository browser.