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

Last change on this file since 12970 was 11653, checked in by Henrik Bettermann, 11 years ago

Configure all types school fees and clearance (acceptance) fees in session configuration objects.

  • Property svn:keywords set to Id
File size: 9.5 KB
Line 
1## $Id: utils.py 11653 2014-05-15 07:08:46Z 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    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.interfaces import MessageFactory as _
27
28class CustomStudentsUtils(NigeriaStudentsUtils):
29    """A collection of customized methods.
30
31    """
32
33    VERDICTS_DICT = {
34        '0': 'not yet',
35        'A': 'Successful student',
36        'B': 'Student with carryover courses',
37        'C': 'Student on probation',
38        #'D': 'Withdrawn from the faculty',
39        #'E': 'Student who were previously on probation',
40        #'F': 'Medical case',
41        #'G': 'Absent from examination',
42        #'H': 'Withheld results',
43        #'I': 'Expelled/rusticated/suspended student',
44        #'J': 'Temporary withdrawn from the university',
45        #'K': 'Unregistered student',
46        #'L': 'Referred student',
47        #'M': 'Reinstatement',
48        #'N': 'Student on transfer',
49        #'O': 'NCE-III repeater',
50        #'Y': 'No previous verdict',
51        #'X': 'New 300 level student',
52        'Z': 'Successful student (provisional)',
53        #'A1': 'First Class',
54        #'A2': 'Second Class Upper',
55        #'A3': 'Second Class Lower',
56        #'A4': 'Third Class',
57        #'A5': 'Pass',
58        #'A6': 'Distinction',
59        #'A7': 'Credit',
60        #'A8': 'Merit',
61        'NEOR': 'No evidence of registration',
62        'NEOV': 'No evidence of verification',
63        'FRNS': 'Faculty requirements not satisfied',
64        }
65
66    gpa_boundaries = ((1, 'FRNS'),
67                      (1.5, 'Pass'),
68                      (2.4, '3rd Class Honours'),
69                      (3.5, '2nd Class Honours Lower Division'),
70                      (4.5, '2nd Class Honours Upper Division'),
71                      (5, '1st Class Honours'))
72
73    def constructMatricNumber(self, student):
74        next_integer = grok.getSite()['configuration'].next_matric_integer
75        if next_integer == 0:
76            return None
77        faccode = student.faccode
78        depcode = student.depcode
79        year = unicode(student.entry_session)[2:]
80        if student.current_mode in ('ug_pt', 'de_pt') \
81            and student.state in (PAID, ) \
82            and student.is_fresh:
83            return None, "PTP/%s/%s/%s/%05d" % (faccode, depcode, year, next_integer)
84        #if student.current_mode in ('pg_ft', 'pg_pt'):
85        #    return None, "SPS/%s/%s/%s/%05d" % (faccode, depcode, year, next_integer)
86        #if student.current_mode in ('dp_ft', 'dp_pt'):
87        #    return None, "DIP/%s/%s/%s/%05d" % (faccode, depcode, year, next_integer)
88        #if student.current_mode == 'found':
89        #    return _('Foundation programme students don\'t have matric number.'), None
90        #return None, "%s/%s/%s/%05d" % (faccode, depcode, year, next_integer)
91        return _('Matriculation number cannot be set.'), None
92
93    def getReturningData(self, student):
94        """ This method defines what happens after school fee payment
95        of returning students depending on the student's senate verdict.
96        """
97        prev_level = student['studycourse'].current_level
98        cur_verdict = student['studycourse'].current_verdict
99        if cur_verdict in ('A','B','L','M','N','Z',):
100            # Successful student
101            new_level = divmod(int(prev_level),100)[0]*100 + 100
102        elif cur_verdict == 'C':
103            # Student on probation
104            new_level = int(prev_level) + 10
105        else:
106            # Student is somehow in an undefined state.
107            # Level has to be set manually.
108            new_level = prev_level
109        new_session = student['studycourse'].current_session + 1
110        return new_session, new_level
111
112    def setPaymentDetails(self, category, student,
113            previous_session=None, previous_level=None):
114        """Create Payment object and set the payment data of a student for
115        the payment category specified.
116
117        """
118        details = {}
119        p_item = u''
120        amount = 0.0
121        error = u''
122        if previous_session:
123            return _('Previous session payment not yet implemented.'), None
124        p_session = student['studycourse'].current_session
125        p_level = student['studycourse'].current_level
126        p_current = True
127        academic_session = self._getSessionConfiguration(p_session)
128        if academic_session == None:
129            return _(u'Session configuration object is not available.'), None
130        # Determine fee.
131        if category == 'transfer':
132            amount = academic_session.transfer_fee
133        elif category == 'transcript':
134            amount = academic_session.transcript_fee
135        elif category == 'gown':
136            amount = academic_session.gown_fee
137        elif category == 'bed_allocation':
138            amount = academic_session.booking_fee
139        elif category == 'hostel_maintenance':
140            amount = academic_session.maint_fee
141        elif category == 'clearance':
142            if student.faccode == 'FP':
143                amount = academic_session.clearance_fee_fp
144            else:
145                amount = academic_session.clearance_fee
146            p_item = student['studycourse'].certificate.code
147        elif category == 'late_registration':
148            amount = academic_session.late_fee
149        elif category == 'schoolfee':
150            try:
151                certificate = student['studycourse'].certificate
152                p_item = certificate.code
153            except (AttributeError, TypeError):
154                return _('Study course data are incomplete.'), None
155            if student.state == CLEARED:
156                if student.faccode == 'FP':
157                    amount = academic_session.school_fee_3
158                else:
159                    amount = academic_session.school_fee_1
160            elif student.state == RETURNING or\
161                (student.is_postgrad and student.state == PAID):
162                academic_session = self._getSessionConfiguration(p_session)
163                if academic_session == None:
164                    return _(u'Session configuration object is not available.'), None
165                if student.state == RETURNING:
166                    p_session, p_level = self.getReturningData(student)
167                else:
168                    # Returning postgraduate students also pay for the
169                    # next session but their level always remains the same.
170                    p_session += 1
171                try:
172                    academic_session = grok.getSite()[
173                        'configuration'][str(p_session)]
174                except KeyError:
175                    return _(u'Session configuration object is not available.'), None
176                amount = academic_session.school_fee_2
177            else:
178                return _('Wrong state.'), None
179        if amount in (0.0, None):
180            return _(u'Amount could not be determined.'), None
181        # Add session specific penalty fee.
182        if category == 'schoolfee' and student.is_postgrad:
183            amount += academic_session.penalty_pg
184        elif category == 'schoolfee':
185            amount += academic_session.penalty_ug
186        # Create ticket.
187        for key in student['payments'].keys():
188            ticket = student['payments'][key]
189            if ticket.p_state == 'paid' and\
190               ticket.p_category == category and \
191               ticket.p_item == p_item and \
192               ticket.p_session == p_session:
193                  return _('This type of payment has already been made.'), None
194        if self._isPaymentDisabled(p_session, category, student):
195            return _('Payment temporarily disabled.'), None
196        payment = createObject(u'waeup.StudentOnlinePayment')
197        timestamp = ("%d" % int(time()*10000))[1:]
198        payment.p_id = "p%s" % timestamp
199        payment.p_category = category
200        payment.p_item = p_item
201        payment.p_session = p_session
202        payment.p_level = p_level
203        payment.p_current = p_current
204        payment.amount_auth = amount
205        return None, payment
206
207    def _admissionText(self, student, portal_language):
208        inst_name = grok.getSite()['configuration'].name
209        entry_session = student['studycourse'].entry_session
210        entry_session = academic_sessions_vocab.getTerm(entry_session).title
211        text = trans(_(
212            'This is to inform you that you have been offered provisional'
213            ' admission into ${a} for the ${b} academic session as follows:',
214            mapping = {'a': inst_name, 'b': entry_session}),
215            portal_language)
216        return text
217
218    def maxCredits(self, studylevel):
219        """Return maximum credits.
220
221        """
222        return 48
223
224    # AAUE prefix
225    STUDENT_ID_PREFIX = u'E'
Note: See TracBrowser for help on using the repository browser.