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

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

To guarantee that cleared students pay both acceptance fee and school fees,
the eTranzact History can only be queried for school fee payments if
acceptance/clearance fee has been successfully queried/paid beforehand.

  • Property svn:keywords set to Id
File size: 9.3 KB
Line 
1## $Id: utils.py 11627 2014-05-07 18:21:58Z 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            amount = academic_session.clearance_fee
143            p_item = student['studycourse'].certificate.code
144        elif category == 'late_registration':
145            amount = academic_session.late_fee
146        elif category == 'schoolfee':
147            try:
148                certificate = student['studycourse'].certificate
149                p_item = certificate.code
150            except (AttributeError, TypeError):
151                return _('Study course data are incomplete.'), None
152            if student.state == CLEARED:
153                if student.faccode == 'FP':
154                    amount = 84000.0
155                else:
156                    amount = academic_session.school_fee_1
157            elif student.state == RETURNING or\
158                (student.is_postgrad and student.state == PAID):
159                academic_session = self._getSessionConfiguration(p_session)
160                if academic_session == None:
161                    return _(u'Session configuration object is not available.'), None
162                if student.state == RETURNING:
163                    p_session, p_level = self.getReturningData(student)
164                else:
165                    # Returning postgraduate students also pay for the
166                    # next session but their level always remains the same.
167                    p_session += 1
168                try:
169                    academic_session = grok.getSite()[
170                        'configuration'][str(p_session)]
171                except KeyError:
172                    return _(u'Session configuration object is not available.'), None
173                amount = academic_session.school_fee_2
174            else:
175                return _('Wrong state.'), None
176        if amount in (0.0, None):
177            return _(u'Amount could not be determined.'), None
178        # Add session specific penalty fee.
179        if category == 'schoolfee' and student.is_postgrad:
180            amount += academic_session.penalty_pg
181        elif category == 'schoolfee':
182            amount += academic_session.penalty_ug
183        # Create ticket.
184        for key in student['payments'].keys():
185            ticket = student['payments'][key]
186            if ticket.p_state == 'paid' and\
187               ticket.p_category == category and \
188               ticket.p_item == p_item and \
189               ticket.p_session == p_session:
190                  return _('This type of payment has already been made.'), None
191        if self._isPaymentDisabled(p_session, category, student):
192            return _('Payment temporarily disabled.'), None
193        payment = createObject(u'waeup.StudentOnlinePayment')
194        timestamp = ("%d" % int(time()*10000))[1:]
195        payment.p_id = "p%s" % timestamp
196        payment.p_category = category
197        payment.p_item = p_item
198        payment.p_session = p_session
199        payment.p_level = p_level
200        payment.p_current = p_current
201        payment.amount_auth = amount
202        return None, payment
203
204    def _admissionText(self, student, portal_language):
205        inst_name = grok.getSite()['configuration'].name
206        entry_session = student['studycourse'].entry_session
207        entry_session = academic_sessions_vocab.getTerm(entry_session).title
208        text = trans(_(
209            'This is to inform you that you have been offered provisional'
210            ' admission into ${a} for the ${b} academic session as follows:',
211            mapping = {'a': inst_name, 'b': entry_session}),
212            portal_language)
213        return text
214
215    def maxCredits(self, studylevel):
216        """Return maximum credits.
217
218        """
219        return 48
220
221    # AAUE prefix
222    STUDENT_ID_PREFIX = u'E'
Note: See TracBrowser for help on using the repository browser.