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

Last change on this file since 18023 was 18023, checked in by Henrik Bettermann, 6 days ago

Fix conditions.

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