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

Last change on this file since 9733 was 9574, checked in by Henrik Bettermann, 12 years ago

Add StudentPaymentsOverviewExporter?.

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