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

Last change on this file since 11653 was 11653, checked in by Henrik Bettermann, 10 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
RevLine 
[7419]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##
[7151]18import grok
[8600]19from time import time
20from zope.component import createObject
[10922]21from waeup.kofa.interfaces import (
22    CLEARED, RETURNING, PAID, academic_sessions_vocab)
[8823]23from kofacustom.nigeria.students.utils import NigeriaStudentsUtils
[8247]24from waeup.kofa.accesscodes import create_accesscode
[10922]25from waeup.kofa.students.utils import trans
[8444]26from waeup.aaue.interfaces import MessageFactory as _
[6902]27
[8823]28class CustomStudentsUtils(NigeriaStudentsUtils):
[7151]29    """A collection of customized methods.
30
31    """
32
[10656]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
[10641]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
[11596]73    def constructMatricNumber(self, student):
74        next_integer = grok.getSite()['configuration'].next_matric_integer
75        if next_integer == 0:
76            return None
[11593]77        faccode = student.faccode
78        depcode = student.depcode
79        year = unicode(student.entry_session)[2:]
[11605]80        if student.current_mode in ('ug_pt', 'de_pt') \
81            and student.state in (PAID, ) \
82            and student.is_fresh:
[11620]83            return None, "PTP/%s/%s/%s/%05d" % (faccode, depcode, year, next_integer)
[11596]84        #if student.current_mode in ('pg_ft', 'pg_pt'):
[11620]85        #    return None, "SPS/%s/%s/%s/%05d" % (faccode, depcode, year, next_integer)
[11596]86        #if student.current_mode in ('dp_ft', 'dp_pt'):
[11620]87        #    return None, "DIP/%s/%s/%s/%05d" % (faccode, depcode, year, next_integer)
[11596]88        #if student.current_mode == 'found':
[11620]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
[11593]92
[8270]93    def getReturningData(self, student):
94        """ This method defines what happens after school fee payment
[8319]95        of returning students depending on the student's senate verdict.
[8270]96        """
[8319]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
[8270]109        new_session = student['studycourse'].current_session + 1
110        return new_session, new_level
111
[9154]112    def setPaymentDetails(self, category, student,
113            previous_session=None, previous_level=None):
[8600]114        """Create Payment object and set the payment data of a student for
115        the payment category specified.
116
117        """
[8306]118        details = {}
[8600]119        p_item = u''
120        amount = 0.0
121        error = u''
[9154]122        if previous_session:
123            return _('Previous session payment not yet implemented.'), None
[8600]124        p_session = student['studycourse'].current_session
125        p_level = student['studycourse'].current_level
[9154]126        p_current = True
[9527]127        academic_session = self._getSessionConfiguration(p_session)
128        if academic_session == None:
[8600]129            return _(u'Session configuration object is not available.'), None
[8677]130        # Determine fee.
[7151]131        if category == 'transfer':
[8600]132            amount = academic_session.transfer_fee
[10467]133        elif category == 'transcript':
134            amount = academic_session.transcript_fee
[7151]135        elif category == 'gown':
[8600]136            amount = academic_session.gown_fee
[7151]137        elif category == 'bed_allocation':
[8600]138            amount = academic_session.booking_fee
[7151]139        elif category == 'hostel_maintenance':
[8600]140            amount = academic_session.maint_fee
[7151]141        elif category == 'clearance':
[11653]142            if student.faccode == 'FP':
143                amount = academic_session.clearance_fee_fp
144            else:
145                amount = academic_session.clearance_fee
[8753]146            p_item = student['studycourse'].certificate.code
[11004]147        elif category == 'late_registration':
148            amount = academic_session.late_fee
[9905]149        elif category == 'schoolfee':
[8600]150            try:
[8753]151                certificate = student['studycourse'].certificate
152                p_item = certificate.code
[8600]153            except (AttributeError, TypeError):
154                return _('Study course data are incomplete.'), None
[8753]155            if student.state == CLEARED:
[10922]156                if student.faccode == 'FP':
[11653]157                    amount = academic_session.school_fee_3
[10930]158                else:
[11624]159                    amount = academic_session.school_fee_1
[8961]160            elif student.state == RETURNING or\
161                (student.is_postgrad and student.state == PAID):
[9527]162                academic_session = self._getSessionConfiguration(p_session)
163                if academic_session == None:
164                    return _(u'Session configuration object is not available.'), None
[8961]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
[11624]176                amount = academic_session.school_fee_2
[8600]177            else:
[8753]178                return _('Wrong state.'), None
[8600]179        if amount in (0.0, None):
180            return _(u'Amount could not be determined.'), None
[8677]181        # Add session specific penalty fee.
[9905]182        if category == 'schoolfee' and student.is_postgrad:
[8677]183            amount += academic_session.penalty_pg
[9905]184        elif category == 'schoolfee':
[8677]185            amount += academic_session.penalty_ug
186        # Create ticket.
[8600]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
[11455]194        if self._isPaymentDisabled(p_session, category, student):
195            return _('Payment temporarily disabled.'), None
[8712]196        payment = createObject(u'waeup.StudentOnlinePayment')
[8954]197        timestamp = ("%d" % int(time()*10000))[1:]
[8600]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
[9154]203        payment.p_current = p_current
[8600]204        payment.amount_auth = amount
205        return None, payment
[7621]206
[10922]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(_(
[10953]212            'This is to inform you that you have been offered provisional'
213            ' admission into ${a} for the ${b} academic session as follows:',
[10922]214            mapping = {'a': inst_name, 'b': entry_session}),
215            portal_language)
216        return text
217
[10051]218    def maxCredits(self, studylevel):
219        """Return maximum credits.
220
221        """
222        return 48
223
[8444]224    # AAUE prefix
225    STUDENT_ID_PREFIX = u'E'
Note: See TracBrowser for help on using the repository browser.