source: main/waeup.fceokene/trunk/src/waeup/fceokene/students/utils.py @ 10018

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

Restrict school fee payment to cleared and returning students.

Add school fee for ug_ft.

  • Property svn:keywords set to Id
File size: 13.5 KB
Line 
1## $Id: utils.py 10012 2013-03-05 21:39:26Z 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##
18import grok
19import random
20from time import time
21from zope.component import createObject, getUtility
22from waeup.kofa.interfaces import CLEARED, RETURNING, PAID
23from kofacustom.nigeria.students.utils import NigeriaStudentsUtils
24from waeup.kofa.accesscodes import create_accesscode
25from waeup.kofa.interfaces import CLEARED, RETURNING
26from waeup.fceokene.interfaces import MessageFactory as _
27from waeup.kofa.browser.interfaces import IPDFCreator
28from waeup.kofa.students.utils import trans
29
30class CustomStudentsUtils(NigeriaStudentsUtils):
31    """A collection of customized methods.
32
33    """
34
35    def selectBed(self, available_beds):
36        """Randomly select a bed from a list of available beds.
37
38        """
39        return random.choice(available_beds)
40
41    def getReturningData(self, student):
42        """ This method defines what happens after school fee payment
43        of returning students depending on the student's senate verdict.
44        """
45        prev_level = student['studycourse'].current_level
46        cur_verdict = student['studycourse'].current_verdict
47        if cur_verdict in ('A','B','L','M','N','Z',):
48            # Successful student
49            new_level = divmod(int(prev_level),100)[0]*100 + 100
50        elif cur_verdict in ('C','O'):
51            # Student on probation
52            new_level = int(prev_level) + 10
53        else:
54            # Student is somehow in an undefined state.
55            # Level has to be set manually.
56            new_level = prev_level
57        if cur_verdict == 'O':
58            new_session = student['studycourse'].current_session
59        else:
60            new_session = student['studycourse'].current_session + 1
61        return new_session, new_level
62
63    def setPaymentDetails(self, category, student,
64            previous_session=None, previous_level=None):
65        """Create Payment object and set the payment data of a student for
66        the payment category specified.
67
68        """
69        details = {}
70        p_item = u''
71        amount = 0.0
72        error = u''
73        if previous_session:
74            return _('Previous session payment not yet implemented.'), None
75        p_session = student['studycourse'].current_session
76        p_level = student['studycourse'].current_level
77        p_current = True
78        academic_session = self._getSessionConfiguration(p_session)
79        if academic_session == None:
80            return _(u'Session configuration object is not available.'), None
81        # Determine fee.
82        if category == 'transfer':
83            amount = academic_session.transfer_fee
84        elif category == 'gown':
85            amount = academic_session.gown_fee
86        elif category == 'bed_allocation':
87            amount = academic_session.booking_fee
88        elif category == 'hostel_maintenance':
89            current_session = student['studycourse'].current_session
90            bedticket = student['accommodation'].get(str(current_session), None)
91            if bedticket is not None and bedticket.bed is not None:
92                p_item = bedticket.bed_coordinates
93            else:
94                return _(u'You have not yet booked accommodation.'), None
95            acc_details = self.getAccommodationDetails(student)
96            if current_session != acc_details['booking_session']:
97                return _(u'Current session does not match accommodation session.'), None
98            if student.current_mode.endswith('_sw') or student.current_mode == 'pd_ft':
99                amount = 2650.0
100            else:
101                amount = 4150.0
102        elif category == 'clearance':
103            amount = academic_session.clearance_fee
104            try:
105                p_item = student['studycourse'].certificate.code
106            except (AttributeError, TypeError):
107                return _('Study course data are incomplete.'), None
108        elif category == 'schoolfee':
109            try:
110                certificate = student['studycourse'].certificate
111                p_item = certificate.code
112            except (AttributeError, TypeError):
113                return _('Study course data are incomplete.'), None
114
115            # Very special school fee configuration, should be moved to
116            # a seperate file.
117
118            ARTS = ('CRS','ISS','HIS','MUS','ECO','GEO','POL','SOS','CCA','ECU',
119                    'THA','GED','GSE','PES','SPC','ENG','FRE','ARB','HAU','IGB',
120                    'YOR','NCRS','NISS','NHIS','NMUS','NECO','NGEO','NPOL',
121                    'NCCA','NECU','NTHA','NGED','NGSE','NPES','NSPC','NENG',
122                    'NFRE','NARB','NHAU','NIGB','NYOR','NSOS')
123
124            if student.state not in (CLEARED, RETURNING):
125                return _('Wrong state.'), None
126
127            #PDE
128            if student.current_mode == 'pd_ft':
129                amount = 35000
130            # UG
131            elif student.current_mode == 'ug_ft':
132                amount = 65150
133            # NCE
134            elif not student.current_mode.endswith('_sw'):
135                # PRENCE
136                if student.current_level == 10 and student.state == CLEARED:
137                    if student.depcode in ARTS:
138                        amount = 14900
139                    else:
140                        amount = 15400
141                # NCE I fresh
142                elif student.current_level == 100 and student.state == CLEARED:
143                    if student.depcode in ARTS:
144                        amount = 12020
145                    else:
146                        amount = 12495
147                # NCE II
148                elif student.current_level in (100, 110, 120) and \
149                    student.state == RETURNING:
150                    if student.depcode in ARTS:
151                        amount = 11070
152                    else:
153                        amount = 11545
154                # NCE III
155                elif student.current_level in (200, 210, 220):
156                    if student.depcode in ARTS:
157                        amount = 11070
158                    else:
159                        amount = 11545
160                # NCE III repeater
161                elif student.current_level in (300, 310, 320) and \
162                    student.current_verdict == 'O':
163                    if student.depcode in ARTS:
164                        amount = 6535
165                    else:
166                        amount = 6773
167                # NCE III spillover
168                elif student.current_level in (300, 310, 320) and \
169                    student.current_verdict == 'B':
170                    if student.depcode in ARTS:
171                        amount = 9170
172                    else:
173                        amount = 9645
174                # NCE III second spillover
175                elif student.current_level in (400, 410, 420) and \
176                    student.current_verdict == 'B':
177                    if student.depcode in ARTS:
178                        amount = 9170
179                    else:
180                        amount = 9645
181            else:
182                if student.current_level == 100 and student.state == CLEARED:
183                    if student.depcode in ARTS:
184                        amount = 21900
185                    else:
186                        amount = 22400
187                # NCE II sw
188                elif student.current_level in (100, 110, 120) and \
189                    student.state == RETURNING:
190                    if student.depcode in ARTS:
191                        amount = 18400
192                    else:
193                        amount = 18900
194                # NCE III sw
195                elif student.current_level in (200, 210, 220):
196                    if student.depcode in ARTS:
197                        amount = 20400
198                    else:
199                        amount = 20900
200                # NCE IV sw
201                elif student.current_level in (300, 310, 320):
202                    if student.depcode in ARTS:
203                        amount = 18400
204                    else:
205                        amount = 18900
206                # NCE V sw
207                elif student.current_level in (400, 410, 420):
208                    if student.depcode in ARTS:
209                        amount = 18400
210                    else:
211                        amount = 18900
212                # NCE V spillover sw
213                elif student.current_level in (500, 510, 520) and \
214                    student.current_verdict == 'B':
215                    if student.depcode in ARTS:
216                        amount = 16900
217                    else:
218                        amount = 17400
219                # NCE V second spillover sw
220                elif student.current_level in (600, 610, 620) and \
221                    student.current_verdict == 'B':
222                    if student.depcode in ARTS:
223                        amount = 16900
224                    else:
225                        amount = 17400
226            # NCE student payment can be disabled by
227            # setting the base school fee to -1
228            if academic_session.school_fee_base == -1 and \
229                student.current_mode.startswith('nce'):
230                return _(u'School fee payment is disabled.'), None
231            if student.state == RETURNING:
232                # Override p_session and p_level
233                p_session, p_level = self.getReturningData(student)
234                academic_session = self._getSessionConfiguration(p_session)
235                if academic_session == None:
236                    return _(u'Session configuration object is not available.'), None
237
238        if amount in (0.0, None):
239            return _(u'Amount could not be determined.'), None
240        for key in student['payments'].keys():
241            ticket = student['payments'][key]
242            if ticket.p_state == 'paid' and\
243               ticket.p_category == category and \
244               ticket.p_item == p_item and \
245               ticket.p_session == p_session:
246                  return _('This type of payment has already been made.'), None
247        payment = createObject(u'waeup.StudentOnlinePayment')
248        timestamp = ("%d" % int(time()*10000))[1:]
249        payment.p_id = "p%s" % timestamp
250        payment.p_category = category
251        payment.p_item = p_item
252        payment.p_session = p_session
253        payment.p_level = p_level
254        payment.p_current = p_current
255        payment.amount_auth = float(amount)
256        return None, payment
257
258    def getAccommodationDetails(self, student):
259        """Determine the accommodation data of a student.
260        """
261        d = {}
262        d['error'] = u''
263        hostels = grok.getSite()['hostels']
264        d['booking_session'] = hostels.accommodation_session
265        d['allowed_states'] = hostels.accommodation_states
266        d['startdate'] = hostels.startdate
267        d['enddate'] = hostels.enddate
268        d['expired'] = hostels.expired
269        # Determine bed type
270        studycourse = student['studycourse']
271        certificate = getattr(studycourse,'certificate',None)
272        current_level = studycourse.current_level
273        if None in (current_level, certificate):
274            return d
275        end_level = certificate.end_level
276        if current_level == 10:
277            bt = 'pr'
278        elif current_level == 100:
279            bt = 'fr'
280        elif current_level >= 300:
281            bt = 'fi'
282        else:
283            bt = 're'
284        if student.sex == 'f':
285            sex = 'female'
286        else:
287            sex = 'male'
288        special_handling = 'regular'
289        d['bt'] = u'%s_%s_%s' % (special_handling,sex,bt)
290        return d
291
292    def maxCredits(self, studylevel):
293        """Return maximum credits.
294
295        """
296        return 58
297
298    def getPDFCreator(self, context):
299        """Get a pdf creator suitable for `context`.
300
301        The default implementation always returns the default creator.
302        """
303        mode = getattr(context, 'current_mode', None)
304        if mode and mode.startswith('ug'):
305            return getUtility(IPDFCreator, name='ibadan_pdfcreator')
306        return getUtility(IPDFCreator)
307
308    def _admissionText(self, student, portal_language):
309        mode = getattr(student, 'current_mode', None)
310        if mode and mode.startswith('ug'):
311            text = trans(_(
312                'With reference to your application for admission into Bachelor Degree '
313                'Programme of the University of Ibadan, this is to inform you that you have '
314                'been provisionally admitted to pursue a full-time Bachelor of Arts in '
315                'Education Degree Programme as follows:'),
316                portal_language)
317        else:
318            inst_name = grok.getSite()['configuration'].name
319            text = trans(_(
320                'This is to inform you that you have been provisionally'
321                ' admitted into ${a} as follows:', mapping = {'a': inst_name}),
322                portal_language)
323        return text
324
325    def getBedCoordinates(self, bedticket):
326        """Return bed coordinates.
327
328        Bed coordinates are invisible in FCEOkene.
329        """
330        return _('(see payment slip)')
331
332    # FCEOkene prefix
333    STUDENT_ID_PREFIX = u'K'
Note: See TracBrowser for help on using the repository browser.