source: main/waeup.kofa/trunk/src/waeup/kofa/students/export.py @ 9792

Last change on this file since 9792 was 9787, checked in by uli, 12 years ago

Make use of new students query (replacing the old filter) and simplify level list creation for studylevelsoverview exporter.

  • Property svn:keywords set to Id
File size: 13.7 KB
Line 
1## $Id: export.py 9787 2012-12-07 10:57:21Z uli $
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"""Exporters for student related stuff.
19"""
20import grok
21from datetime import datetime
22from waeup.kofa.interfaces import MessageFactory as _
23from waeup.kofa.students.catalog import StudentsQuery
24from waeup.kofa.students.interfaces import (
25    IStudent, IStudentStudyCourse, IStudentStudyLevel, ICourseTicket,
26    IStudentOnlinePayment, ICSVStudentExporter, IBedTicket)
27from waeup.kofa.students.vocabularies import study_levels
28from waeup.kofa.utils.batching import ExporterBase
29from waeup.kofa.utils.helpers import iface_names
30
31#: A tuple containing all exporter names referring to students or
32#: subobjects thereof.
33EXPORTER_NAMES = ('students', 'studentstudycourses', 'studentstudylevels',
34                  'coursetickets', 'studentpayments')
35
36def get_students(site, stud_filter=StudentsQuery()):
37    """Get all students registered in catalog in `site`.
38    """
39    return stud_filter.query()
40
41def get_studycourses(students):
42    """Get studycourses of `students`.
43    """
44    return [x.get('studycourse', None) for x in students
45            if x is not None]
46
47def get_levels(students):
48    """Get all studylevels of `students`.
49    """
50    levels = []
51    for course in get_studycourses(students):
52        for level in course.values():
53            levels.append(level)
54    return levels
55
56def get_tickets(students):
57    """Get all course tickets of `students`.
58    """
59    tickets = []
60    for level in get_levels(students):
61        for ticket in level.values():
62            tickets.append(ticket)
63    return tickets
64
65def get_payments(students):
66    """Get all payments of `students`.
67    """
68    payments = []
69    for student in students:
70        for payment in student.get('payments', {}).values():
71            payments.append(payment)
72    return payments
73
74def get_bedtickets(students):
75    """Get all bedtickets of `students`.
76    """
77    tickets = []
78    for student in students:
79        for ticket in student.get('accommodation', {}).values():
80            tickets.append(ticket)
81    return tickets
82
83class StudentExporterBase(ExporterBase):
84    """Exporter for students or related objects.
85
86    This is a baseclass.
87    """
88    grok.baseclass()
89    grok.implements(ICSVStudentExporter)
90    grok.provides(ICSVStudentExporter)
91
92    def export(self, values, filepath=None):
93        """Export `values`, an iterable, as CSV file.
94
95        If `filepath` is ``None``, a raw string with CSV data is returned.
96        """
97        writer, outfile = self.get_csv_writer(filepath)
98        for value in values:
99            self.write_item(value, writer)
100        return self.close_outfile(filepath, outfile)
101
102    def export_filtered(self, site, session, level, faccode=None,
103                        depcode=None, filepath=None):
104        """Export all students denoted by the given parameters.
105        """
106        filter_inst = StudentsQuery(
107            current_session=session, current_level=level,
108            faccode=faccode, depcode=depcode)
109        result_set = get_students(site, stud_filter=filter_inst)
110        return self.export(result_set, filepath=filepath)
111
112
113class StudentsExporter(grok.GlobalUtility, StudentExporterBase):
114    """Exporter for Students.
115    """
116    grok.name('students')
117
118    #: Fieldnames considered by this exporter
119    fields = tuple(sorted(iface_names(
120        IStudent, omit=['loggerInfo']))) + (
121        'password', 'state', 'history', 'certcode', 'is_postgrad',
122        'current_level', 'current_session')
123
124    #: The title under which this exporter will be displayed
125    title = _(u'Students')
126
127    def mangle_value(self, value, name, context=None):
128        if name == 'history':
129            value = value.messages
130        if name == 'phone' and value is not None:
131            # Append hash '#' to phone numbers to circumvent
132            # unwanted excel automatic
133            value = str('%s#' % value)
134        return super(
135            StudentsExporter, self).mangle_value(
136            value, name, context=context)
137
138    def export_all(self, site, filepath=None):
139        """Export students into filepath as CSV data.
140
141        If `filepath` is ``None``, a raw string with CSV data is returned.
142        """
143        return self.export(get_students(site), filepath)
144
145    def export_student(self, student, filepath=None):
146        return self.export([student], filepath=filepath)
147
148
149class StudentStudyCourseExporter(grok.GlobalUtility, StudentExporterBase):
150    """Exporter for StudentStudyCourses.
151    """
152    grok.name('studentstudycourses')
153
154    #: Fieldnames considered by this exporter
155    fields = tuple(sorted(iface_names(IStudentStudyCourse))) + ('student_id',)
156
157    #: The title under which this exporter will be displayed
158    title = _(u'Student Study Courses')
159
160    def mangle_value(self, value, name, context=None):
161        """Treat location values special.
162        """
163        if name == 'certificate' and value is not None:
164            # XXX: hopefully cert codes are unique site-wide
165            value = value.code
166        if name == 'student_id' and context is not None:
167            student = context.student
168            value = getattr(student, name, None)
169        return super(
170            StudentStudyCourseExporter, self).mangle_value(
171            value, name, context=context)
172
173    def export_all(self, site, filepath=None):
174        """Export study courses into filepath as CSV data.
175
176        If `filepath` is ``None``, a raw string with CSV data is returned.
177        """
178        return self.export(get_studycourses(get_students(site)), filepath)
179
180    def export_student(self, student, filepath=None):
181        """Export studycourse of a single student object.
182        """
183        return self.export(get_studycourses([student]), filepath)
184
185
186class StudentStudyLevelExporter(grok.GlobalUtility, StudentExporterBase):
187    """Exporter for StudentStudyLevels.
188    """
189    grok.name('studentstudylevels')
190
191    #: Fieldnames considered by this exporter
192    fields = tuple(sorted(iface_names(
193        IStudentStudyLevel) + ['level'])) + (
194        'student_id', 'number_of_tickets','certcode')
195
196    #: The title under which this exporter will be displayed
197    title = _(u'Student Study Levels')
198
199    def mangle_value(self, value, name, context=None):
200        """Treat location values special.
201        """
202        if name == 'student_id' and context is not None:
203            student = context.student
204            value = getattr(student, name, None)
205        return super(
206            StudentStudyLevelExporter, self).mangle_value(
207            value, name, context=context)
208
209    def export_all(self, site, filepath=None):
210        """Export study levels into filepath as CSV data.
211
212        If `filepath` is ``None``, a raw string with CSV data is returned.
213        """
214        return self.export(get_levels(get_students(site)), filepath)
215
216    def export_student(self, student, filepath=None):
217        return self.export(get_levels([student]), filepath)
218
219class CourseTicketExporter(grok.GlobalUtility, StudentExporterBase):
220    """Exporter for CourseTickets.
221    """
222    grok.name('coursetickets')
223
224    #: Fieldnames considered by this exporter
225    fields = tuple(sorted(iface_names(ICourseTicket) +
226        ['level', 'code'])) + ('student_id', 'certcode')
227
228    #: The title under which this exporter will be displayed
229    title = _(u'Course Tickets')
230
231    def mangle_value(self, value, name, context=None):
232        """Treat location values special.
233        """
234        if context is not None:
235            student = context.student
236            if name == 'student_id' and student is not None:
237                value = getattr(student, name, None)
238            if name == 'level':
239                value = getattr(context, 'getLevel', lambda: None)()
240        return super(
241            CourseTicketExporter, self).mangle_value(
242            value, name, context=context)
243
244    def export_all(self, site, filepath=None):
245        """Export course tickets into filepath as CSV data.
246
247        If `filepath` is ``None``, a raw string with CSV data is returned.
248        """
249        return self.export(get_tickets(get_students(site)), filepath)
250
251    def export_student(self, student, filepath=None):
252        return self.export(get_tickets([student]), filepath)
253
254
255class PaymentsExporter(grok.GlobalUtility, StudentExporterBase):
256    """Exporter for OnlinePayment instances.
257    """
258    grok.name('studentpayments')
259
260    #: Fieldnames considered by this exporter
261    fields = tuple(
262        sorted(iface_names(
263            IStudentOnlinePayment, exclude_attribs=False))) + (
264                'student_id','student_state','current_session')
265
266    #: The title under which this exporter will be displayed
267    title = _(u'Student Payments')
268
269    def mangle_value(self, value, name, context=None):
270        """Treat location values special.
271        """
272        if context is not None:
273            student = context.student
274            if name in ['student_id'] and student is not None:
275                value = getattr(student, name, None)
276        return super(
277            PaymentsExporter, self).mangle_value(
278            value, name, context=context)
279
280    def export_all(self, site, filepath=None):
281        """Export payments into filepath as CSV data.
282
283        If `filepath` is ``None``, a raw string with CSV data is returned.
284        """
285        return self.export(get_payments(get_students(site)), filepath)
286
287    def export_student(self, student, filepath=None):
288        return self.export(get_payments([student]), filepath)
289
290class BedTicketsExporter(grok.GlobalUtility, StudentExporterBase):
291    """Exporter for BedTicket instances.
292    """
293    grok.name('bedtickets')
294
295    #: Fieldnames considered by this exporter
296    fields = tuple(
297        sorted(iface_names(
298            IBedTicket, exclude_attribs=False))) + (
299                'student_id', 'actual_bed_type')
300
301    #: The title under which this exporter will be displayed
302    title = _(u'Bed Tickets')
303
304    def mangle_value(self, value, name, context=None):
305        """Treat location values and others special.
306        """
307        if context is not None:
308            student = context.student
309            if name in ['student_id'] and student is not None:
310                value = getattr(student, name, None)
311        if name == 'bed' and value is not None:
312            value = getattr(value, 'bed_id', None)
313        if name == 'actual_bed_type':
314            value = getattr(getattr(context, 'bed', None), 'bed_type')
315        return super(
316            BedTicketsExporter, self).mangle_value(
317            value, name, context=context)
318
319    def export_all(self, site, filepath=None):
320        """Export payments into filepath as CSV data.
321
322        If `filepath` is ``None``, a raw string with CSV data is returned.
323        """
324        return self.export(get_bedtickets(get_students(site)), filepath)
325
326    def export_student(self, student, filepath=None):
327        return self.export(get_bedtickets([student]), filepath)
328
329class StudentPaymentsOverviewExporter(StudentsExporter):
330    """Exporter for students with payment overview.
331    """
332    grok.name('paymentsoverview')
333
334    curr_year = datetime.now().year
335    year_range = range(curr_year - 9, curr_year + 1)
336    year_range_tuple = tuple([str(year) for year in year_range])
337
338    #: Fieldnames considered by this exporter
339    fields = ('student_id', ) + (
340        'state', 'certcode', 'faccode', 'depcode', 'is_postgrad',
341        'current_level', 'current_session',
342        ) + year_range_tuple
343
344    #: The title under which this exporter will be displayed
345    title = _(u'Student Payments Overview')
346
347    def mangle_value(self, value, name, context=None):
348        if name in self.year_range_tuple and context is not None:
349            value = ''
350            for ticket in context['payments'].values():
351                if ticket.p_state == 'paid' and \
352                    ticket.p_category == 'schoolfee' and \
353                    ticket.p_session == int(name):
354                    value = ticket.amount_auth
355                    break
356        return super(
357            StudentsExporter, self).mangle_value(
358            value, name, context=context)
359
360class StudentStudyLevelsOverviewExporter(StudentsExporter):
361    """Exporter for students with study level overview.
362    """
363    grok.name('studylevelsoverview')
364
365    avail_levels = tuple([str(x) for x in study_levels(None)])
366
367    #: Fieldnames considered by this exporter
368    fields = ('student_id', ) + (
369        'state', 'certcode', 'faccode', 'depcode', 'is_postgrad',
370        'entry_session', 'current_level', 'current_session',
371        ) + avail_levels
372
373    #: The title under which this exporter will be displayed
374    title = _(u'Student Study Levels Overview')
375
376    def mangle_value(self, value, name, context=None):
377        if name in self.avail_levels and context is not None:
378            value = ''
379            for level in context['studycourse'].values():
380                if level.level == int(name):
381                    #value = '%s|%s|%s|%s' % (
382                    #    level.level_session,
383                    #    len(level),
384                    #    level.validated_by,
385                    #    level.level_verdict)
386                    value = '%s' % level.level_session
387                    break
388        return super(
389            StudentsExporter, self).mangle_value(
390            value, name, context=context)
Note: See TracBrowser for help on using the repository browser.