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

Last change on this file since 13414 was 13414, checked in by Henrik Bettermann, 10 years ago

Determine net amount instead of gateway reduction. This is much easier to handle.

  • Property svn:keywords set to Id
File size: 10.5 KB
Line 
1## $Id: utils.py 13414 2015-11-09 07:08:21Z 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.current_mode in ('ug_pt', 'de_pt'):
63            next_integer = grok.getSite()['configuration'].next_matric_integer
64            if next_integer == 0:
65                return _('Matriculation number cannot be set.'), None
66            return None, "PTP/%s/%s/%s/%05d" % (
67                faccode, depcode, year, next_integer)
68        next_integer = grok.getSite()['configuration'].next_matric_integer_2
69        if next_integer == 0:
70            return _('Matriculation number cannot be set.'), None
71        if student.faccode in ('FBM', 'FCS'):
72            return None, "CMS/%s/%s/%s/%05d" % (
73                faccode, depcode, year, next_integer)
74        return None, "%s/%s/%s/%05d" % (faccode, depcode, year, next_integer)
75
76    def getReturningData(self, student):
77        """ This method defines what happens after school fee payment
78        of returning students depending on the student's senate verdict.
79        """
80        prev_level = student['studycourse'].current_level
81        cur_verdict = student['studycourse'].current_verdict
82        if cur_verdict in ('A','B','L','M','N','Z',):
83            # Successful student
84            new_level = divmod(int(prev_level),100)[0]*100 + 100
85        elif cur_verdict == 'C':
86            # Student on probation
87            new_level = int(prev_level) + 10
88        else:
89            # Student is somehow in an undefined state.
90            # Level has to be set manually.
91            new_level = prev_level
92        new_session = student['studycourse'].current_session + 1
93        return new_session, new_level
94
95    def setPaymentDetails(self, category, student,
96            previous_session=None, previous_level=None):
97        """Create Payment object and set the payment data of a student for
98        the payment category specified.
99
100        """
101        details = {}
102        p_item = u''
103        amount = 0.0
104        error = u''
105        if previous_session:
106            return _('Previous session payment not yet implemented.'), None
107        p_session = student['studycourse'].current_session
108        p_level = student['studycourse'].current_level
109        p_current = True
110        academic_session = self._getSessionConfiguration(p_session)
111        if academic_session == None:
112            return _(u'Session configuration object is not available.'), None
113        # Determine fee.
114        if category == 'transfer':
115            amount = academic_session.transfer_fee
116        elif category == 'transcript':
117            amount = academic_session.transcript_fee
118        elif category == 'bed_allocation':
119            amount = academic_session.booking_fee
120        elif category == 'hostel_maintenance':
121            amount = academic_session.maint_fee
122        elif category == 'welfare':
123            amount = academic_session.welfare_fee
124        elif category == 'union':
125            amount = academic_session.union_fee
126        elif category == 'lapel':
127            amount = academic_session.lapel_fee
128        elif category == 'matric_gown':
129            amount = academic_session.matric_gown_fee
130        elif category == 'concessional':
131            amount = academic_session.concession_fee
132        elif category.startswith('clearance'):
133            if student.faccode == 'FP':
134                amount = academic_session.clearance_fee_fp
135            elif student.current_mode.endswith('_pt'):
136                amount = academic_session.clearance_fee_pt
137            elif student.faccode in ('FBM', 'FCS'):
138                amount = academic_session.clearance_fee_med
139            else:
140                amount = academic_session.clearance_fee
141            p_item = student['studycourse'].certificate.code
142            # Add Matric Gown Fee and Lapel Fee
143            if category.endswith('_incl'):
144                if amount is None:
145                    # Otherwise we can't add somtehing
146                    amount = 0.0
147                amount += gateway_net_amt(academic_session.matric_gown_fee) + \
148                    gateway_net_amt(academic_session.lapel_fee)
149        elif category == 'late_registration':
150            amount = academic_session.late_registration_fee
151        elif category.startswith('schoolfee'):
152            try:
153                certificate = student['studycourse'].certificate
154                p_item = certificate.code
155            except (AttributeError, TypeError):
156                return _('Study course data are incomplete.'), None
157            if student.state == CLEARED:
158                if student.is_foreigner:
159                    amount = getattr(certificate, 'school_fee_3', 0.0)
160                else:
161                    amount = getattr(certificate, 'school_fee_1', 0.0)
162            elif student.state == RETURNING:
163                # In case of returning school fee payment the payment session
164                # and level contain the values of the session the student
165                # has paid for.
166                p_session, p_level = self.getReturningData(student)
167                try:
168                    academic_session = grok.getSite()[
169                        'configuration'][str(p_session)]
170                except KeyError:
171                    return _(u'Session configuration object is not available.'), None
172                if student.is_foreigner:
173                    amount = getattr(certificate, 'school_fee_4', 0.0)
174                else:
175                    amount = getattr(certificate, 'school_fee_2', 0.0)
176            else:
177                return _('Wrong state.'), None
178            # Add Student Union Fee and Welfare Assurance
179            if category == 'schoolfee_incl':
180                if amount is None:
181                    # Otherwise we can't add somtehing
182                    amount = 0.0
183                amount += gateway_net_amt(academic_session.welfare_fee) + \
184                    gateway_net_amt(academic_session.union_fee)
185        if amount in (0.0, None):
186            return _(u'Amount could not be determined.'), None
187        # Add session specific penalty fee.
188        if category.startswith('schoolfee') and student.is_postgrad:
189            amount += academic_session.penalty_pg
190        elif category.startswith('schoolfee'):
191            amount += academic_session.penalty_ug
192        # Create ticket.
193        for key in student['payments'].keys():
194            ticket = student['payments'][key]
195            if ticket.p_state == 'paid' and\
196               ticket.p_category == category and \
197               ticket.p_item == p_item and \
198               ticket.p_session == p_session:
199                  return _('This type of payment has already been made.'), None
200        if self._isPaymentDisabled(p_session, category, student):
201            return _('Payment temporarily disabled.'), None
202        payment = createObject(u'waeup.StudentOnlinePayment')
203        timestamp = ("%d" % int(time()*10000))[1:]
204        payment.p_id = "p%s" % timestamp
205        payment.p_category = category
206        payment.p_item = p_item
207        payment.p_session = p_session
208        payment.p_level = p_level
209        payment.p_current = p_current
210        payment.amount_auth = amount
211        return None, payment
212
213    def _admissionText(self, student, portal_language):
214        inst_name = grok.getSite()['configuration'].name
215        entry_session = student['studycourse'].entry_session
216        entry_session = academic_sessions_vocab.getTerm(entry_session).title
217        text = trans(_(
218            'This is to inform you that you have been offered provisional'
219            ' admission into ${a} for the ${b} academic session as follows:',
220            mapping = {'a': inst_name, 'b': entry_session}),
221            portal_language)
222        return text
223
224    def maxCredits(self, studylevel):
225        """Return maximum credits.
226
227        """
228        return 48
229
230    def getBedCoordinates(self, bedticket):
231        """Return descriptive bed coordinates.
232        This method can be used to customize the `display_coordinates`
233        property method in order to  display a
234        customary description of the bed space.
235        """
236        bc = bedticket.bed_coordinates.split(',')
237        if len(bc) == 4:
238            return bc[0]
239        return bedticket.bed_coordinates
240
241    # AAUE prefix
242    STUDENT_ID_PREFIX = u'E'
Note: See TracBrowser for help on using the repository browser.