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

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

Disable postgrad matric number generation.

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