source: main/kofacustom.unidel/trunk/src/kofacustom/unidel/students/utils.py @ 18017

Last change on this file since 18017 was 18017, checked in by Henrik Bettermann, 3 days ago

Change minimum credits.

  • Property svn:keywords set to Id
File size: 13.6 KB
Line 
1## $Id: utils.py 18017 2025-02-12 12:57:53Z 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
19from time import time
20from zope.component import createObject, getUtility
21from waeup.kofa.interfaces import (IKofaUtils,
22    CLEARED, RETURNING, PAID, REGISTERED, VALIDATED)
23from kofacustom.nigeria.students.utils import NigeriaStudentsUtils
24from kofacustom.unidel.interfaces import MessageFactory as _
25
26def local(student):
27    lga = getattr(student, 'lga')
28    if lga and lga.startswith('delta'):
29        return True
30    return False
31
32class CustomStudentsUtils(NigeriaStudentsUtils):
33    """A collection of customized methods.
34
35    """
36
37    STUDENT_ID_PREFIX = u'D'
38
39    def warnCreditsOOR(self, studylevel, course=None):
40        """
41        """
42        upper_limit = 53
43        #if studylevel.certcode == 'BSCEDBIO' and current_level >= end_level:
44        #    studycourse = studylevel.__parent__
45        #    certificate = getattr(studycourse,'certificate', None)
46        #    current_level = studycourse.current_level
47        #    if None in (current_level, certificate):
48        #        return
49        #    upper_limit = 53
50        if course and studylevel.total_credits + course.credits > upper_limit:
51            return _('Maximum credits exceeded.')
52        if studylevel.total_credits > upper_limit:
53            return _('Maximum credits exceeded.')
54        if not course:
55            #if studylevel.student.faccode in ('FET', 'FES'):
56            #    if studylevel.level == 400 and studylevel.total_credits < 29:
57            #        return _('Minimum credits not reached.')
58            if studylevel.level in (300, 400) and studylevel.total_credits < 27:
59                return _('Minimum credits not reached.')
60            elif studylevel.total_credits < 30:
61                    return _('Minimum credits not reached.')
62        return
63
64    def _clearancePaymentMade(self, student):
65        if len(student['payments']):
66            for ticket in student['payments'].values():
67                if ticket.p_state == 'paid' and \
68                    ticket.p_category == 'clearance':
69                    return True
70        return False
71
72    def _isPaymentDisabled(self, p_session, category, student):
73        academic_session = self._getSessionConfiguration(p_session)
74        if category == 'schoolfee':
75            if 'sf_all' in academic_session.payment_disabled:
76                return True
77            if student.current_mode == 'ug_ft' and \
78                'sf_ugft' in academic_session.payment_disabled:
79                return True
80        return False
81
82    def setPaymentDetails(self, category, student,
83            previous_session=None, previous_level=None, combi=[]):
84        """Create a payment ticket and set the payment data of a
85        student for the payment category specified.
86        """
87        p_item = u''
88        amount = 0.0
89        if previous_session:
90            if previous_session < student['studycourse'].entry_session:
91                return _('The previous session must not fall below '
92                         'your entry session.'), None
93            if category == 'schoolfee':
94                # School fee is always paid for the following session
95                if previous_session > student['studycourse'].current_session:
96                    return _('This is not a previous session.'), None
97            else:
98                if previous_session > student['studycourse'].current_session - 1:
99                    return _('This is not a previous session.'), None
100            p_session = previous_session
101            p_level = previous_level
102            p_current = False
103        else:
104            p_session = student['studycourse'].current_session
105            p_level = student['studycourse'].current_level
106            p_current = True
107        academic_session = self._getSessionConfiguration(p_session)
108        if academic_session == None:
109            return _(u'Session configuration object is not available.'), None
110        # Determine fee.
111        if category == 'schoolfee':
112            try:
113                certificate = student['studycourse'].certificate
114                p_item = certificate.code
115            except (AttributeError, TypeError):
116                return _('Study course data are incomplete.'), None
117            if previous_session:
118                # Students can pay for previous sessions in all
119                # workflow states.  Fresh students are excluded by the
120                # update method of the PreviousPaymentAddFormPage.
121                if previous_level == 100:
122                    amount = getattr(certificate, 'school_fee_1', 0.0)
123                else:
124                    amount = getattr(certificate, 'school_fee_2', 0.0)
125            else:
126                if student.faccode == 'JUPEB':
127                    if not self._clearancePaymentMade(student):
128                        return _(u'Acceptance fee must be paid first.'), None
129                if student.state == CLEARED:
130                    amount = getattr(certificate, 'school_fee_1', 0.0)
131                elif student.state == RETURNING:
132                    # In case of returning school fee payment the
133                    # payment session and level contain the values of
134                    # the session the student has paid for. Payment
135                    # session is always next session.
136                    p_session, p_level = self.getReturningData(student)
137                    academic_session = self._getSessionConfiguration(p_session)
138                    if academic_session == None:
139                        return _(
140                            u'Session configuration object is not available.'
141                            ), None
142                    amount = getattr(certificate, 'school_fee_2', 0.0)
143                elif student.is_postgrad and student.state == PAID:
144                    # Returning postgraduate students also pay for the
145                    # next session but their level always remains the
146                    # same.
147                    p_session += 1
148                    academic_session = self._getSessionConfiguration(p_session)
149                    if academic_session == None:
150                        return _(
151                            u'Session configuration object is not available.'
152                            ), None
153                    amount = getattr(certificate, 'school_fee_2', 0.0)
154            # Add surcharges for students in FMED and FBM
155            if student.faccode == 'FMED':
156                fmed_surcharge = 0.0
157                if divmod(p_level,100)[0] == 3:
158                    fmed_surcharge = 296000.0
159                elif divmod(p_level,100)[0] == 4:
160                    fmed_surcharge = 224700.0
161                elif divmod(p_level,100)[0] == 5:
162                    fmed_surcharge = 220700.0
163                elif divmod(p_level,100)[0] == 6:
164                    fmed_surcharge = 244950.0
165                amount += fmed_surcharge
166            if student.faccode == 'FBM':
167                fbm_surcharge = 0.0
168                if divmod(p_level,100)[0] == 3:
169                    fbm_surcharge = 146000.0
170                elif divmod(p_level,100)[0] == 4:
171                    fbm_surcharge = 204700.0
172                elif divmod(p_level,100)[0] == 5:
173                    fbm_surcharge = 229950.0
174                if student.depcode == 'NSG' and divmod(p_level,100)[0] == 3:
175                    fbm_surcharge -= 50000.0
176                amount += fbm_surcharge
177            # Add non-local surcharges
178            if amount and not local(student):
179                non_local_surcharge = 0
180                if student.faccode not in ('IJMB', 'PRE', 'JUPEB', 'PDED'):
181                    non_local_surcharge = 40000
182                #if student.faccode in ('FAG', 'FCP', 'FES',
183                #                       'FSS', 'FMS', 'FSC',
184                #                       'FAT', 'FED'):
185                #    if p_level == 200:
186                #        non_local_surcharge = 47000
187                #    if p_level == 500:
188                #        non_local_surcharge = 50000
189                #if student.faccode == 'FET':
190                #    if p_level == 500:
191                #        non_local_surcharge = 31000
192                amount += non_local_surcharge
193        elif category == 'clearance':
194            try:
195                p_item = student['studycourse'].certificate.code
196            except (AttributeError, TypeError):
197                return _('Study course data are incomplete.'), None
198            amount = academic_session.clearance_fee
199            if student.current_mode in ('ug_ft', 'de_ft'):
200                if local(student):
201                    amount = academic_session.ugftlocal_clearance_fee
202                else:
203                    amount = academic_session.ugft_clearance_fee
204            elif student.faccode == 'PRE':
205                amount = 20000.0
206            elif student.faccode == 'JUPEB':
207                amount = 25000.0
208            elif student.current_mode.startswith('dp'):
209                amount = 20000.0
210        elif category == 'bed_allocation':
211            acco_details = self.getAccommodationDetails(student)
212            p_session = acco_details['booking_session']
213            p_item = acco_details['bt']
214            amount = academic_session.booking_fee
215        elif category == 'hostel_maintenance':
216            amount = 0.0
217            booking_session = grok.getSite()['hostels'].accommodation_session
218            bedticket = student['accommodation'].get(str(booking_session), None)
219            if bedticket is not None and bedticket.bed is not None:
220                p_session = booking_session
221                p_item = bedticket.bed_coordinates
222                if bedticket.bed.__parent__.maint_fee > 0:
223                    amount = bedticket.bed.__parent__.maint_fee
224                else:
225                    # fallback
226                    amount = academic_session.maint_fee
227            else:
228                return _(u'No bed allocated.'), None
229        elif category == 'combi' and combi:
230            categories = getUtility(IKofaUtils).COMBI_PAYMENT_CATEGORIES
231            for cat in combi:
232                fee_name = cat + '_fee'
233                cat_amount = getattr(academic_session, fee_name, 0.0)
234                if not cat_amount:
235                    return _('%s undefined.' % categories[cat]), None
236                amount += cat_amount
237                p_item += u'%s + ' % categories[cat]
238            p_item = p_item.strip(' + ')
239        else:
240            fee_name = category + '_fee'
241            amount = getattr(academic_session, fee_name, 0.0)
242        if category != 'bed_allocation' and amount in (0.0, None):
243            return _('Amount could not be determined.'), None
244        if self.samePaymentMade(student, category, p_item, p_session):
245            return _('This type of payment has already been made.'), None
246        if self._isPaymentDisabled(p_session, category, student):
247            return _('This category of payments has been disabled.'), None
248        payment = createObject(u'waeup.StudentOnlinePayment')
249        timestamp = ("%d" % int(time()*10000))[1:]
250        payment.p_id = "p%s" % timestamp
251        payment.p_category = category
252        payment.p_item = p_item
253        payment.p_session = p_session
254        payment.p_level = p_level
255        payment.p_current = p_current
256        payment.amount_auth = amount
257        payment.p_combi = combi
258        return None, payment
259
260    #def checkAccommodationRequirements(self, student, acc_details):
261    #    msg = super(CustomStudentsUtils, self).checkAccommodationRequirements(
262    #        student, acc_details)
263    #    if msg:
264    #        return msg
265    #    if student.faccode not in ('FLW', 'FMED',):
266    #        return _('You are not eligible to book accommodation.')
267    #    return
268
269    def getAccommodationDetails(self, student):
270        """Determine the accommodation data of a student.
271        """
272        d = {}
273        d['error'] = u''
274        hostels = grok.getSite()['hostels']
275        d['booking_session'] = hostels.accommodation_session
276        d['allowed_states'] = hostels.accommodation_states
277        d['startdate'] = hostels.startdate
278        d['enddate'] = hostels.enddate
279        d['expired'] = hostels.expired
280        studycourse = student['studycourse']
281        certificate = getattr(studycourse,'certificate',None)
282        entry_session = studycourse.entry_session
283        current_level = studycourse.current_level
284        if None in (entry_session, current_level, certificate):
285            return d
286        end_level = certificate.end_level
287        # Determine bed type
288        if entry_session == grok.getSite()['hostels'].accommodation_session:
289            bt = 'fr'
290        elif current_level >= end_level:
291            bt = 'fi'
292        else:
293            bt = 're'
294        #if student.current_level >= 300:
295        #    bt = 'na'
296        if student.sex == 'f':
297            sex = 'female'
298        else:
299            sex = 'male'
300        special_handling = 'regular'
301        if student.faccode in ('FLW',):
302            special_handling = 'oyibu'
303        elif student.faccode in ('FMED',):
304            special_handling = 'alero'
305        d['bt'] = u'%s_%s_%s' % (special_handling,sex,bt)
306        return d
307
Note: See TracBrowser for help on using the repository browser.