source: main/waeup.aaue/trunk/src/waeup/aaue/students/export.py @ 16859

Last change on this file since 16859 was 16859, checked in by Henrik Bettermann, 3 years ago

Implement OutstandingCourses2Exporter (ticket 699)

  • Property svn:keywords set to Id
File size: 11.5 KB
Line 
1## $Id: export.py 16859 2022-03-04 21:27:24Z 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 zope.component import getUtility, createObject
22from waeup.kofa.utils.batching import ExporterBase
23from waeup.kofa.utils.helpers import iface_names
24from waeup.kofa.interfaces import IKofaUtils
25from waeup.kofa.students.export import (get_levels,
26    DataForLecturerExporter, StudentExporterBase,
27    SchoolFeePaymentsOverviewExporter, StudentExporter)
28from waeup.aaue.students.interfaces import (
29    ICustomStudent, ICustomStudentStudyCourse,
30    ICustomStudentStudyLevel,
31    ICustomCourseTicket,
32    ICustomStudentOnlinePayment)
33from kofacustom.nigeria.students.export import (
34    NigeriaStudentExporter, NigeriaStudentStudyCourseExporter,
35    NigeriaStudentStudyLevelExporter,
36    NigeriaCourseTicketExporter, NigeriaStudentPaymentExporter)
37
38
39def get_tickets_for_ict(students, previous=0, **kw):
40    """
41    """
42    tickets = []
43    #code = kw.get('code', None)
44    level = kw.get('level', None)
45    session = kw.get('session', None)
46    ct_level = kw.get('ct_level', None)
47    ct_session = kw.get('ct_session', None)
48    ct_semester = kw.get('ct_semester', None)
49    allticketcodes = list()
50    for level_obj in get_levels(students, previous, **kw):
51
52
53        for ticket in level_obj.values():
54            if ct_level not in ('all', None):
55                if level_obj.level in (10, 999, 1000, None)  \
56                    and int(ct_level) != level_obj.level:
57                    continue
58                if level_obj.level not in range(
59                    int(ct_level), int(ct_level)+100, 10):
60                    continue
61            if ct_session not in ('all', None) and \
62                int(ct_session) != level_obj.level_session:
63                continue
64            if ct_semester not in ('all', None) and \
65                int(ct_semester) != ticket.semester:
66                continue
67            if ticket.total_score is not None:
68                if ticket.total_score < ticket.passmark:
69                    remark = 'failed'
70                else:
71                    remark = 'passed'
72            else:
73                remark = 'nottaken'
74            ticket.remark = remark
75            tickets.append(ticket)
76            allticketcodes.append(ticket.code)
77        # collect missed tickets for each study level
78        certificate = getattr(
79            level_obj.student.get('studycourse', None), 'certificate', None)
80        if certificate:
81            for certcourse in certificate.values():
82                if certcourse.level != level_obj.level:
83                    continue
84                if certcourse.getCourseCode() not in allticketcodes:
85                    ticket = createObject(u'waeup.CourseTicket')
86                    ticket.code = certcourse.getCourseCode()
87                    ticket.remark = 'missed'
88                    ticket.course_category = certcourse.course_category
89                    ticket.stdnt = level_obj.student
90                    tickets.append(ticket)
91    return tickets
92
93class CustomStudentExporter(NigeriaStudentExporter):
94    """Exporter for Students.
95    """
96
97    fields = tuple(sorted(iface_names(
98        ICustomStudent, omit=['loggerInfo']))) + (
99        'password', 'state', 'history', 'certcode', 'is_postgrad',
100        'current_level', 'current_session')
101
102class CustomStudentStudyCourseExporter(NigeriaStudentStudyCourseExporter):
103    """Exporter for StudentStudyCourses.
104    """
105
106    fields = tuple(
107        sorted(iface_names(ICustomStudentStudyCourse))) + (
108            'matric_number', 'state', 'student_id',)
109
110    def mangle_value(self, value, name, context=None):
111        if name == 'certificate' and value is not None:
112            # XXX: hopefully cert codes are unique site-wide
113            value = value.code
114        if name in ('student_id', 'matric_number', 'state') and context is not None:
115            student = context.student
116            value = getattr(student, name, None)
117        return ExporterBase().mangle_value(value, name, context=context)
118
119class CustomCourseTicketExporter(NigeriaCourseTicketExporter):
120    """Exporter for CourseTickets.
121    """
122
123    fields = tuple(sorted(iface_names(ICustomCourseTicket) +
124        ['level', 'code', 'level_session'])) + ('student_id',
125        'certcode', 'display_fullname', 'matric_number', 'state', 'grade',
126        'total_score', 'total_credits', 'previous')
127
128    def mangle_value(self, value, name, context=None):
129        """The mangler determines the student's id and fullname.
130        """
131        if name == 'previous':
132            return self.previous
133        if context is not None:
134            student = context.student
135            if name in ('student_id', 'display_fullname', 'matric_number', 'state') \
136                and student is not None:
137                value = getattr(student, name, None)
138            if name == 'total_credits':
139                value = context.__parent__.total_credits
140        return ExporterBase().mangle_value(value, name, context=context)
141
142class CustomStudentStudyLevelExporter(NigeriaStudentStudyLevelExporter):
143    """Exporter for StudentStudyLevels.
144    """
145    #: Fieldnames considered by this exporter
146    fields = tuple(sorted(iface_names(
147        ICustomStudentStudyLevel))) + (
148        'student_id', 'matric_number', 'number_of_tickets','certcode', 'cgpa')
149
150    def mangle_value(self, value, name, context=None):
151        """The mangler determines the student id, nothing else.
152        """
153        if name in ('student_id', 'matric_number') and context is not None:
154            student = context.student
155            value = getattr(student, name, None)
156        elif name == 'cgpa':
157            value = context.cumulative_params[0]
158        return super(
159            CustomStudentStudyLevelExporter, self).mangle_value(
160            value, name, context=context)
161
162class CustomStudentPaymentExporter(NigeriaStudentPaymentExporter):
163    """Exporter for OnlinePayment instances.
164    """
165
166    fields = tuple(
167        sorted(iface_names(
168            ICustomStudentOnlinePayment, exclude_attribs=False,
169            omit=['display_item','formatted_p_date']))) + (
170            'student_id','state','current_session')
171
172class CustomDataForLecturerExporter(DataForLecturerExporter):
173    """
174    """
175
176    fields = ('matric_number', 'student_id','display_fullname',
177              'depcode', 'faccode',
178              'level', 'code', 'level_session', 'ca', 'score',
179              'total_score', 'grade', 'imported_ts')
180
181    def mangle_value(self, value, name, context=None):
182        """The mangler determines the student's id and fullname.
183        """
184        if context is not None:
185            student = context.student
186            if name in ('matric_number',
187                        'reg_number',
188                        'student_id',
189                        'display_fullname',
190                        'depcode',
191                        'faccode') and student is not None:
192                value = getattr(student, name, None)
193        return super(
194            DataForLecturerExporter, self).mangle_value(
195            value, name, context=context)
196
197class LevelReportDataExporter(grok.GlobalUtility, StudentExporterBase):
198    """
199    """
200    grok.name('levelreportdata')
201
202    fields = ('matric_number', 'display_fullname','level','level_session',
203        'credits_counted', 'credits_passed','level_gpa',
204        'failed_courses','not_taken_courses','cum_credits_taken',
205        'cum_credits_passed','cgpa','remark')
206    title = u'Summary of Result Data'
207
208    def filter_func(self, x, **kw):
209        return get_levels(x, **kw)
210
211    def mangle_value(self, value, name, context=None):
212        """The mangler determines the student id, nothing else.
213        """
214        if context is not None:
215            student = context.student
216            format_float = getUtility(IKofaUtils).format_float
217            if name in ('matric_number',
218                        'display_fullname',) and student is not None:
219                value = getattr(student, name, None)
220            elif name == 'credits_counted':
221                value = context.gpa_params[1]
222            elif name == 'credits_passed':
223                value = context.passed_params[2]
224            elif name == 'level_gpa':
225                value = format_float(context.gpa_params[0], 3)
226            elif name == 'failed_courses':
227                value = context.passed_params[4]
228            elif name == 'not_taken_courses':
229                value = context.passed_params[5]
230            elif name == 'cum_credits_taken':
231                value = context.cumulative_params[1]
232            elif name == 'cum_credits_passed':
233                value = context.cumulative_params[4]
234            elif name == 'cgpa':
235                value = format_float(context.cumulative_params[0], 3)
236            elif name == 'remark':
237                value = getattr(context, 'remark', '')
238        return super(
239            LevelReportDataExporter, self).mangle_value(
240            value, name, context=context)
241
242class CustomSchoolFeePaymentsOverviewExporter(SchoolFeePaymentsOverviewExporter):
243    """
244    """
245
246    def mangle_value(self, value, name, context=None):
247        """
248        """
249        if name in self.year_range_tuple and context is not None:
250            value = 0
251            for ticket in context['payments'].values():
252                if ticket.p_category in (
253                    'schoolfee',
254                    'schoolfee_1',
255                    'schoolfee_2',
256                    'schoolfee_incl',) and \
257                    ticket.p_session == int(name):
258                    if ticket.p_state == 'waived':
259                        value = 'waived'
260                        break
261                    if ticket.p_state == 'paid':
262                        try:
263                            value += ticket.amount_auth
264                        except TypeError:
265                            pass
266            if value == 0:
267                value = ''
268            elif isinstance(value, float):
269                value = round(value, 2)
270        return super(
271            StudentExporter, self).mangle_value(
272            value, name, context=context)
273
274class OutstandingCourses2Exporter(grok.GlobalUtility, StudentExporterBase):
275    """
276    """
277    grok.name('outstandingcourses_2')
278
279    title = u'Outstanding Courses V2'
280
281    fields = ('student_id', 'matric_number', 'certcode', 'display_fullname',
282              'code', 'course_category', 'remark')
283
284    def filter_func(self, x, **kw):
285        return get_tickets_for_ict(x, **kw)
286
287    def mangle_value(self, value, name, context=None):
288        """The mangler determines the student's id and fullname.
289        """
290        if context is not None:
291            student = context.student
292            if not student:
293                student = getattr(context, 'stdnt', None)
294            if name in ('student_id', 'display_fullname', 'matric_number',
295                'certcode') and student is not None:
296                value = getattr(student, name, None)
297        return ExporterBase().mangle_value(value, name, context=context)
Note: See TracBrowser for help on using the repository browser.