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

Last change on this file since 11636 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
RevLine 
[7419]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##
[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':
[8753]142            amount = academic_session.clearance_fee
143            p_item = student['studycourse'].certificate.code
[11004]144        elif category == 'late_registration':
145            amount = academic_session.late_fee
[9905]146        elif category == 'schoolfee':
[8600]147            try:
[8753]148                certificate = student['studycourse'].certificate
149                p_item = certificate.code
[8600]150            except (AttributeError, TypeError):
151                return _('Study course data are incomplete.'), None
[8753]152            if student.state == CLEARED:
[10922]153                if student.faccode == 'FP':
[10931]154                    amount = 84000.0
[10930]155                else:
[11624]156                    amount = academic_session.school_fee_1
[8961]157            elif student.state == RETURNING or\
158                (student.is_postgrad and student.state == PAID):
[9527]159                academic_session = self._getSessionConfiguration(p_session)
160                if academic_session == None:
161                    return _(u'Session configuration object is not available.'), None
[8961]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
[11624]173                amount = academic_session.school_fee_2
[8600]174            else:
[8753]175                return _('Wrong state.'), None
[8600]176        if amount in (0.0, None):
177            return _(u'Amount could not be determined.'), None
[8677]178        # Add session specific penalty fee.
[9905]179        if category == 'schoolfee' and student.is_postgrad:
[8677]180            amount += academic_session.penalty_pg
[9905]181        elif category == 'schoolfee':
[8677]182            amount += academic_session.penalty_ug
183        # Create ticket.
[8600]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
[11455]191        if self._isPaymentDisabled(p_session, category, student):
192            return _('Payment temporarily disabled.'), None
[8712]193        payment = createObject(u'waeup.StudentOnlinePayment')
[8954]194        timestamp = ("%d" % int(time()*10000))[1:]
[8600]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
[9154]200        payment.p_current = p_current
[8600]201        payment.amount_auth = amount
202        return None, payment
[7621]203
[10922]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(_(
[10953]209            'This is to inform you that you have been offered provisional'
210            ' admission into ${a} for the ${b} academic session as follows:',
[10922]211            mapping = {'a': inst_name, 'b': entry_session}),
212            portal_language)
213        return text
214
[10051]215    def maxCredits(self, studylevel):
216        """Return maximum credits.
217
218        """
219        return 48
220
[8444]221    # AAUE prefix
222    STUDENT_ID_PREFIX = u'E'
Note: See TracBrowser for help on using the repository browser.