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

Last change on this file since 17984 was 17984, checked in by Henrik Bettermann, 2 weeks ago

Increase upper limit.

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