source: main/waeup.aaue/trunk/src/waeup/aaue/students/utils.py @ 13563

Last change on this file since 13563 was 13534, checked in by Henrik Bettermann, 9 years ago

Add non-indigenous fee.

  • Property svn:keywords set to Id
File size: 13.0 KB
Line 
1## $Id: utils.py 13534 2015-12-04 18:10: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
19from time import time
20from zope.component import createObject
21from waeup.kofa.interfaces import (
22    ADMITTED, CLEARED, RETURNING, PAID, academic_sessions_vocab)
23from kofacustom.nigeria.students.utils import NigeriaStudentsUtils
24from waeup.kofa.accesscodes import create_accesscode
25from waeup.kofa.students.utils import trans
26from waeup.aaue.interswitch.browser import gateway_net_amt
27from waeup.aaue.interfaces import MessageFactory as _
28
29class CustomStudentsUtils(NigeriaStudentsUtils):
30    """A collection of customized methods.
31
32    """
33
34    PORTRAIT_CHANGE_STATES = (ADMITTED, RETURNING)
35
36    gpa_boundaries = ((1, 'FRNS'),
37                      (1.5, 'Pass'),
38                      (2.4, '3rd Class Honours'),
39                      (3.5, '2nd Class Honours Lower Division'),
40                      (4.5, '2nd Class Honours Upper Division'),
41                      (5, '1st Class Honours'))
42
43    def increaseMatricInteger(self, student):
44        """Increase counter for matric numbers.
45        This counter can be a centrally stored attribute or an attribute of
46        faculties, departments or certificates. In the base package the counter
47        is as an attribute of the site configuration container.
48        """
49        if student.current_mode in ('ug_pt', 'de_pt'):
50            grok.getSite()['configuration'].next_matric_integer += 1
51            return
52        grok.getSite()['configuration'].next_matric_integer_2 += 1
53        return
54
55    def constructMatricNumber(self, student):
56        faccode = student.faccode
57        depcode = student.depcode
58        year = unicode(student.entry_session)[2:]
59        if not student.state in (PAID, ) or not student.is_fresh or \
60            student.current_mode == 'found':
61            return _('Matriculation number cannot be set.'), None
62        if student.current_mode in ('ug_pt', 'de_pt'):
63            next_integer = grok.getSite()['configuration'].next_matric_integer
64            if next_integer == 0:
65                return _('Matriculation number cannot be set.'), None
66            return None, "PTP/%s/%s/%s/%05d" % (
67                faccode, depcode, year, next_integer)
68        next_integer = grok.getSite()['configuration'].next_matric_integer_2
69        if next_integer == 0:
70            return _('Matriculation number cannot be set.'), None
71        if student.faccode in ('FBM', 'FCS'):
72            return None, "CMS/%s/%s/%s/%05d" % (
73                faccode, depcode, year, next_integer)
74        return None, "%s/%s/%s/%05d" % (faccode, depcode, year, next_integer)
75
76    def getReturningData(self, student):
77        """ This method defines what happens after school fee payment
78        of returning students depending on the student's senate verdict.
79        """
80        prev_level = student['studycourse'].current_level
81        cur_verdict = student['studycourse'].current_verdict
82        if cur_verdict in ('A','B','L','M','N','Z',):
83            # Successful student
84            new_level = divmod(int(prev_level),100)[0]*100 + 100
85        elif cur_verdict == 'C':
86            # Student on probation
87            new_level = int(prev_level) + 10
88        else:
89            # Student is somehow in an undefined state.
90            # Level has to be set manually.
91            new_level = prev_level
92        new_session = student['studycourse'].current_session + 1
93        return new_session, new_level
94
95    def _isPaymentDisabled(self, p_session, category, student):
96        academic_session = self._getSessionConfiguration(p_session)
97        if category == 'schoolfee' and \
98            'sf_all' in academic_session.payment_disabled:
99            return True
100        if category == 'hostel_maintenance' and \
101            'maint_all' in academic_session.payment_disabled:
102            return True
103        return False
104
105    def setPaymentDetails(self, category, student,
106            previous_session=None, previous_level=None):
107        """Create Payment object and set the payment data of a student for
108        the payment category specified.
109
110        """
111        details = {}
112        p_item = u''
113        amount = 0.0
114        error = u''
115        if previous_session:
116            return _('Previous session payment not yet implemented.'), None
117        p_session = student['studycourse'].current_session
118        p_level = student['studycourse'].current_level
119        p_current = True
120        academic_session = self._getSessionConfiguration(p_session)
121        if academic_session == None:
122            return _(u'Session configuration object is not available.'), None
123        # Determine fee.
124        if category == 'transfer':
125            amount = academic_session.transfer_fee
126        elif category == 'transcript':
127            amount = academic_session.transcript_fee
128        elif category == 'bed_allocation':
129            amount = academic_session.booking_fee
130        elif category == 'hostel_maintenance':
131            amount = 0.0
132            bedticket = student['accommodation'].get(
133                str(student.current_session), None)
134            if bedticket is not None and bedticket.bed is not None:
135                p_item = bedticket.display_coordinates
136                if bedticket.bed.__parent__.maint_fee > 0:
137                    amount = bedticket.bed.__parent__.maint_fee
138                else:
139                    # fallback
140                    amount = academic_session.maint_fee
141            else:
142                return _(u'No bed allocated.'), None
143        elif category == 'welfare':
144            amount = academic_session.welfare_fee
145        elif category == 'union':
146            amount = academic_session.union_fee
147        elif category == 'lapel':
148            amount = academic_session.lapel_fee
149        elif category == 'matric_gown':
150            amount = academic_session.matric_gown_fee
151        elif category == 'concessional':
152            amount = academic_session.concessional_fee
153        elif category.startswith('clearance'):
154            if student.faccode == 'FP':
155                amount = academic_session.clearance_fee_fp
156            elif student.current_mode.endswith('_pt'):
157                amount = academic_session.clearance_fee_pt
158            elif student.faccode == 'FCS':
159                # Students in clinical medical sciences pay the medical
160                # acceptance fee
161                amount = academic_session.clearance_fee_med
162            elif student.is_postgrad:
163                amount = academic_session.clearance_fee_pg
164            else:
165                amount = academic_session.clearance_fee
166            p_item = student['studycourse'].certificate.code
167            # Add Matric Gown Fee and Lapel Fee
168            if category.endswith('_incl'):
169                if amount is None:
170                    # Otherwise we can't add somtehing
171                    amount = 0.0
172                amount += gateway_net_amt(academic_session.matric_gown_fee) + \
173                    gateway_net_amt(academic_session.lapel_fee)
174        elif category == 'late_registration':
175            amount = academic_session.late_registration_fee
176        elif category.startswith('schoolfee'):
177            try:
178                certificate = student['studycourse'].certificate
179                p_item = certificate.code
180            except (AttributeError, TypeError):
181                return _('Study course data are incomplete.'), None
182            if student.state == CLEARED or category == 'schoolfee_2':
183                if student.is_foreigner:
184                    amount = getattr(certificate, 'school_fee_3', 0.0)
185                else:
186                    amount = getattr(certificate, 'school_fee_1', 0.0)
187                # Cut school fee by 50%
188                if category in ('schoolfee_1', 'schoolfee_2'):
189                    amount = amount / 2
190            elif category == 'schoolfee_1':
191                return _("Wrong state. Only students in state 'cleared' "
192                         "are allowed to pay by instalments."), None
193            elif student.state == RETURNING:
194                if student.is_postgrad and category == 'schoolfee_incl':
195                    return _("No additional fees required."), None
196                if not student.father_name:
197                    return _("Personal data form is not properly filled."), None
198                # In case of returning school fee payment the payment session
199                # and level contain the values of the session the student
200                # has paid for.
201                p_session, p_level = self.getReturningData(student)
202                try:
203                    academic_session = grok.getSite()[
204                        'configuration'][str(p_session)]
205                except KeyError:
206                    return _(u'Session configuration object is not available.'), None
207                if student.is_foreigner:
208                    amount = getattr(certificate, 'school_fee_4', 0.0)
209                else:
210                    amount = getattr(certificate, 'school_fee_2', 0.0)
211            else:
212                return _('Wrong state.'), None
213            if amount in (0.0, None):
214                return _(u'Amount could not be determined.'), None
215            # Add Student Union Fee and Welfare Assurance
216            if category in ('schoolfee_incl', 'schoolfee_1'):
217                amount += gateway_net_amt(academic_session.welfare_fee) + \
218                    gateway_net_amt(academic_session.union_fee)
219            # Add non-indigenous fee and session specific penalty fees
220            if student.is_postgrad:
221                amount += academic_session.penalty_pg
222                if not student.lga.startswith('edo'):
223                    amount += 20000.0
224            else:
225                amount += academic_session.penalty_ug
226        if amount in (0.0, None):
227            return _(u'Amount could not be determined.'), None
228
229        # Create ticket.
230        for key in student['payments'].keys():
231            ticket = student['payments'][key]
232            if ticket.p_state == 'paid' and\
233               ticket.p_category == category and \
234               ticket.p_item == p_item and \
235               ticket.p_session == p_session:
236                  return _('This type of payment has already been made.'), None
237        if self._isPaymentDisabled(p_session, category, student):
238            return _('Payment temporarily disabled.'), None
239        payment = createObject(u'waeup.StudentOnlinePayment')
240        timestamp = ("%d" % int(time()*10000))[1:]
241        payment.p_id = "p%s" % timestamp
242        payment.p_category = category
243        payment.p_item = p_item
244        payment.p_session = p_session
245        payment.p_level = p_level
246        payment.p_current = p_current
247        payment.amount_auth = amount
248        return None, payment
249
250    def _admissionText(self, student, portal_language):
251        inst_name = grok.getSite()['configuration'].name
252        entry_session = student['studycourse'].entry_session
253        entry_session = academic_sessions_vocab.getTerm(entry_session).title
254        text = trans(_(
255            'This is to inform you that you have been offered provisional'
256            ' admission into ${a} for the ${b} academic session as follows:',
257            mapping = {'a': inst_name, 'b': entry_session}),
258            portal_language)
259        return text
260
261    def maxCredits(self, studylevel):
262        """Return maximum credits.
263
264        """
265        return 48
266
267    def getBedCoordinates(self, bedticket):
268        """Return descriptive bed coordinates.
269        This method can be used to customize the `display_coordinates`
270        property method in order to  display a
271        customary description of the bed space.
272        """
273        bc = bedticket.bed_coordinates.split(',')
274        if len(bc) == 4:
275            return bc[0]
276        return bedticket.bed_coordinates
277
278    def getAccommodationDetails(self, student):
279        """Determine the accommodation data of a student.
280        """
281        d = {}
282        d['error'] = u''
283        hostels = grok.getSite()['hostels']
284        d['booking_session'] = hostels.accommodation_session
285        d['allowed_states'] = hostels.accommodation_states
286        d['startdate'] = hostels.startdate
287        d['enddate'] = hostels.enddate
288        d['expired'] = hostels.expired
289        # Determine bed type
290        bt = 'all'
291        if student.sex == 'f':
292            sex = 'female'
293        else:
294            sex = 'male'
295        special_handling = 'regular'
296        d['bt'] = u'%s_%s_%s' % (special_handling,sex,bt)
297        return d
298
299    # AAUE prefix
300    STUDENT_ID_PREFIX = u'E'
Note: See TracBrowser for help on using the repository browser.