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

Last change on this file since 13411 was 13410, checked in by Henrik Bettermann, 9 years ago

Remove duplicate payment category.

  • Property svn:keywords set to Id
File size: 10.8 KB
Line 
1## $Id: utils.py 13410 2015-11-08 06:18:44Z 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 dynamic_gateway_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 == 'gown':
119            amount = academic_session.gown_fee
120        elif category == 'bed_allocation':
121            amount = academic_session.booking_fee
122        elif category == 'hostel_maintenance':
123            amount = academic_session.maint_fee
124        elif category == 'welfare':
125            amount = academic_session.welfare_fee
126        elif category == 'union':
127            amount = academic_session.union_fee
128        elif category == 'lapel':
129            amount = academic_session.lapel_fee
130        elif category == 'matric_gown':
131            amount = academic_session.matric_gown_fee
132        elif category == 'concessional':
133            amount = academic_session.concession_fee
134        elif category.startswith('clearance'):
135            if student.faccode == 'FP':
136                amount = academic_session.clearance_fee_fp
137            elif student.current_mode.endswith('_pt'):
138                amount = academic_session.clearance_fee_pt
139            elif student.faccode in ('FBM', 'FCS'):
140                amount = academic_session.clearance_fee_med
141            else:
142                amount = academic_session.clearance_fee
143            p_item = student['studycourse'].certificate.code
144            # Add Matric Gown Fee and Lapel Fee
145            if category.endswith('_incl'):
146                if amount is None:
147                    # Otherwise we can't add somtehing
148                    amount = 0.0
149                amount += academic_session.matric_gown_fee + \
150                    academic_session.lapel_fee - \
151                    dynamic_gateway_amt(academic_session.matric_gown_fee) -\
152                    dynamic_gateway_amt(academic_session.lapel_fee)
153        elif category == 'late_registration':
154            amount = academic_session.late_registration_fee
155        elif category.startswith('schoolfee'):
156            try:
157                certificate = student['studycourse'].certificate
158                p_item = certificate.code
159            except (AttributeError, TypeError):
160                return _('Study course data are incomplete.'), None
161            if student.state == CLEARED:
162                if student.is_foreigner:
163                    amount = getattr(certificate, 'school_fee_3', 0.0)
164                else:
165                    amount = getattr(certificate, 'school_fee_1', 0.0)
166            elif student.state == RETURNING:
167                # In case of returning school fee payment the payment session
168                # and level contain the values of the session the student
169                # has paid for.
170                p_session, p_level = self.getReturningData(student)
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                if student.is_foreigner:
177                    amount = getattr(certificate, 'school_fee_4', 0.0)
178                else:
179                    amount = getattr(certificate, 'school_fee_2', 0.0)
180            else:
181                return _('Wrong state.'), None
182            # Add Student Union Fee and Welfare Assurance
183            if category == 'schoolfee_incl':
184                if amount is None:
185                    # Otherwise we can't add somtehing
186                    amount = 0.0
187                amount += academic_session.welfare_fee + \
188                    academic_session.union_fee - \
189                    dynamic_gateway_amt(academic_session.welfare_fee) -\
190                    dynamic_gateway_amt(academic_session.union_fee)
191        if amount in (0.0, None):
192            return _(u'Amount could not be determined.'), None
193        # Add session specific penalty fee.
194        if category.startswith('schoolfee') and student.is_postgrad:
195            amount += academic_session.penalty_pg
196        elif category.startswith('schoolfee'):
197            amount += academic_session.penalty_ug
198        # Create ticket.
199        for key in student['payments'].keys():
200            ticket = student['payments'][key]
201            if ticket.p_state == 'paid' and\
202               ticket.p_category == category and \
203               ticket.p_item == p_item and \
204               ticket.p_session == p_session:
205                  return _('This type of payment has already been made.'), None
206        if self._isPaymentDisabled(p_session, category, student):
207            return _('Payment temporarily disabled.'), None
208        payment = createObject(u'waeup.StudentOnlinePayment')
209        timestamp = ("%d" % int(time()*10000))[1:]
210        payment.p_id = "p%s" % timestamp
211        payment.p_category = category
212        payment.p_item = p_item
213        payment.p_session = p_session
214        payment.p_level = p_level
215        payment.p_current = p_current
216        payment.amount_auth = amount
217        return None, payment
218
219    def _admissionText(self, student, portal_language):
220        inst_name = grok.getSite()['configuration'].name
221        entry_session = student['studycourse'].entry_session
222        entry_session = academic_sessions_vocab.getTerm(entry_session).title
223        text = trans(_(
224            'This is to inform you that you have been offered provisional'
225            ' admission into ${a} for the ${b} academic session as follows:',
226            mapping = {'a': inst_name, 'b': entry_session}),
227            portal_language)
228        return text
229
230    def maxCredits(self, studylevel):
231        """Return maximum credits.
232
233        """
234        return 48
235
236    def getBedCoordinates(self, bedticket):
237        """Return descriptive bed coordinates.
238        This method can be used to customize the `display_coordinates`
239        property method in order to  display a
240        customary description of the bed space.
241        """
242        bc = bedticket.bed_coordinates.split(',')
243        if len(bc) == 4:
244            return bc[0]
245        return bedticket.bed_coordinates
246
247    # AAUE prefix
248    STUDENT_ID_PREFIX = u'E'
Note: See TracBrowser for help on using the repository browser.