source: main/waeup.kofa/branches/0.2/src/waeup/kofa/students/reports/session_results_presentation.py

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

Convert longtitle() into property attribute.

  • Property svn:keywords set to Id
File size: 9.2 KB
Line 
1## $Id: session_results_presentation.py 10650 2013-09-25 06:46:53Z henrik $
2##
3## Copyright (C) 2013 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##
18import grok
19from zope.catalog.interfaces import ICatalog
20from zope.component import queryUtility, getUtility
21from zope.interface import implementer, Interface, Attribute
22from waeup.kofa.interfaces import (
23    IKofaUtils,
24    academic_sessions_vocab, registration_states_vocab)
25from waeup.kofa.students.interfaces import IStudentsUtils
26from waeup.kofa.interfaces import MessageFactory as _
27from waeup.kofa.browser.pdf import get_signature_tables
28from waeup.kofa.reports import IReport
29from waeup.kofa.students.reports.level_report import (
30    ILevelReport, LevelReportGeneratorPage)
31from waeup.kofa.students.reports.student_statistics import (
32    StudentStatisticsReportPDFView)
33
34
35class ISessionResultsPresentation(ILevelReport):
36
37    """ Same interface as for level reports.
38    """
39
40def get_students(faccode, depcode, session, level=None):
41    """Get students in a certain department who registered courses
42    in a certain session at a certain level.
43
44    Returns a list of lists of student data tuples.
45    """
46    site = grok.getSite()
47    cat = queryUtility(ICatalog, name="students_catalog")
48    result = cat.searchResults(
49        depcode = (depcode, depcode), faccode = (faccode, faccode)
50        )
51    students_utils = getUtility(IStudentsUtils)
52    table = []
53    for i in range(len(students_utils.gpa_boundaries)+1):
54        # The last list is reserved for students with more than one
55        # level in the same session.
56        table.append([])
57    for stud in result:
58        line = (stud.student_id,
59                stud.matric_number,
60                stud.display_fullname,
61                )
62        if level is not None:
63            if not stud['studycourse'].has_key(str(level)):
64                continue
65            level_obj = stud['studycourse'][str(level)]
66            if level_obj.level_session != session:
67                continue
68        else:
69            itemcount = 0
70            for item in stud['studycourse'].values():
71                if item.level_session == session:
72                    level_obj = item
73                    itemcount += 1
74            if itemcount == 0:
75                # No level registered in this session
76                continue
77            if itemcount > 1:
78                # Error: more than one session registered in this session
79                table[len(students_utils.gpa_boundaries)].append(line)
80                continue
81        if level_obj.gpa_params[1] == 0:
82            # Error: no credits weighted
83            table[len(students_utils.gpa_boundaries)].append(line)
84            continue
85        # Session GPA can be determined
86        table[students_utils.getClassFromCGPA(level_obj.gpa)[0]].append(line)
87    return table
88
89from reportlab.lib import colors
90from reportlab.lib.styles import getSampleStyleSheet
91from reportlab.lib.units import cm
92from reportlab.platypus import Paragraph, Table, Spacer
93from reportlab.platypus.flowables import Flowable
94from waeup.kofa.reports import IReport, IReportGenerator
95from waeup.kofa.reports import Report
96from waeup.kofa.browser.interfaces import IPDFCreator
97from waeup.kofa.university.vocabularies import course_levels
98
99STYLE = getSampleStyleSheet()
100
101TABLE_STYLE = [
102    ('FONT', (0,0), (-1,-1), 'Helvetica', 8),
103    ('FONT', (0,0), (-1,0), 'Helvetica-Bold', 8), # 1st row
104    ('ALIGN', (3,1), (-1,-1), 'RIGHT'),
105    #('ALIGN', (1,0), (1,-1), 'LEFT'),
106    #('ALIGN', (2,0), (2,-1), 'LEFT'),
107    #('INNERGRID', (0,1), (-1,-1), 0.25, colors.black),
108    #('BOX', (0,1), (-1,-1), 1, colors.black),
109    ]
110
111@implementer(ISessionResultsPresentation)
112class SessionResultsPresentation(Report):
113    data = None
114    session = None
115    level = None
116    faccode = None
117    depcode = None
118
119    def __init__(self, faccode, depcode, session, level, author='System'):
120        super(SessionResultsPresentation, self).__init__(
121            args=[faccode, depcode, session, level], kwargs={'author':author})
122        site = grok.getSite()
123        self.session = academic_sessions_vocab.getTerm(session).title
124        if level == None:
125            self.level = 'All levels'
126        else:
127            self.level = course_levels.getTerm(level).title
128        self.levelcode = level
129        self.sessioncode = session
130        self.faccode = faccode
131        self.depcode = depcode
132        self.factitle = site['faculties'][faccode].longtitle
133        self.deptitle = site['faculties'][faccode][depcode].longtitle
134        self.author = author
135        self.creation_dt_string = self.creation_dt.astimezone(
136            getUtility(IKofaUtils).tzinfo).strftime("%Y-%m-%d %H:%M:%S %Z")
137        self.data = get_students(faccode, depcode, session, level)
138
139    def create_pdf(self):
140        creator = getUtility(IPDFCreator)
141        #col_widths = [2*cm, 4*cm, 5*cm, 0.8*cm, 0.8*cm, 0.8*cm, 6*cm, ]
142        pdf_data = [Paragraph('<b>%s</b>' % self.creation_dt_string,
143                              STYLE["Normal"]),
144                    Spacer(1, 12),]
145        pdf_data += [Paragraph('%s<br />%s<br />Level: %s<br />Session: %s' % (
146                    self.factitle, self.deptitle, self.level, self.session),
147                    STYLE["Normal"]),
148                    Spacer(1, 12),]
149        students_utils = getUtility(IStudentsUtils)
150        # Print classes in reverse order
151        for gpa_class in range(len(students_utils.gpa_boundaries)-1,-1,-1):
152            pdf_data.append(Spacer(1, 20))
153            gpa_class_name = students_utils.gpa_boundaries[gpa_class][1]
154            pdf_data += [Paragraph('<strong>%s</strong>' % gpa_class_name,
155                         STYLE["Normal"])]
156            table_data = [('Student Id', 'Matric No.', 'Name')] + self.data[gpa_class]
157            pdf_data += [Table(table_data, style=TABLE_STYLE)]    #, colWidths=col_widths)]
158            gpa_class += 1
159        if self.data[-1]:
160            pdf_data.append(Spacer(1, 20))
161            pdf_data += [
162                Paragraph('<strong>Erroneous Data</strong>', STYLE["Normal"])]
163            table_data = [('Student Id', 'Matric No.', 'Name')] + self.data[-1]
164            pdf_data += [Table(table_data, style=TABLE_STYLE)]
165
166        doc_title = 'Presentation of Session Results'
167        pdf_data.append(Spacer(1, 40))
168        signatures = ['Ag. Head of Department',
169                      'External Examiner', 'Dean of Faculty']
170        signaturetables = get_signature_tables(signatures)
171        pdf_data.append(signaturetables[0])
172
173        pdf = creator.create_pdf(
174            pdf_data, None, doc_title, self.author,
175            'Session Results Presentation %s/%s/%s/%s' % (
176            self.faccode, self.depcode, self.levelcode, self.sessioncode)
177            )
178        return pdf
179
180@implementer(IReportGenerator)
181class SessionResultsPresentationGenerator(grok.GlobalUtility):
182
183    title = _('Session Results Presentation')
184    grok.name('session_results_presentation')
185
186    def generate(self, site, faccode=None, depcode=None,
187                 session=None, level=None, author=None):
188        result = SessionResultsPresentation(faccode=faccode, depcode=depcode,
189                             session=session, level=level, author=author)
190        return result
191
192###############################################################
193## Browser related stuff
194##
195## XXX: move to local browser module
196###############################################################
197from waeup.kofa.browser.layout import KofaPage
198from waeup.kofa.interfaces import academic_sessions_vocab
199from waeup.kofa.reports import get_generators
200grok.templatedir('browser_templates')
201class SessionResultsPresentationGeneratorPage(LevelReportGeneratorPage):
202
203    grok.context(SessionResultsPresentationGenerator)
204    grok.template('levelreportgeneratorpage')
205    label = _('Create session results presentation')
206
207    def update(self, CREATE=None, faccode_depcode=None,
208               session=None, level=None):
209        if level == 'all':
210            level = None
211        super(SessionResultsPresentationGeneratorPage, self).update(
212            CREATE, faccode_depcode ,session, level)
213
214    def _set_level_values(self):
215        vocab_terms = course_levels.by_value.values()
216        self.levels = [('All levels', 'all')] + sorted(
217            [(x.title, x.token) for x in vocab_terms])
218        return
219
220class SessionResultsPresentationPDFView(StudentStatisticsReportPDFView):
221
222    grok.context(ISessionResultsPresentation)
223    grok.name('pdf')
224    grok.require('waeup.Public')
225    prefix = 'SessionResultsPresentation'
226
227    def _filename(self):
228        return 'SessionResultsPresentation_%s_%s_%s_%s_%s.pdf' % (
229            self.context.faccode, self.context.depcode,
230            self.context.sessioncode, self.context.levelcode,
231            self.context.creation_dt_string)
Note: See TracBrowser for help on using the repository browser.