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

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

Configure acceptance/clearance fee computation.

  • Property svn:keywords set to Id
File size: 9.9 KB
Line 
1## $Id: utils.py 13377 2015-11-02 05:54:08Z 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.interfaces import MessageFactory as _
27
28class CustomStudentsUtils(NigeriaStudentsUtils):
29    """A collection of customized methods.
30
31    """
32
33    PORTRAIT_CHANGE_STATES = (ADMITTED, RETURNING)
34
35    gpa_boundaries = ((1, 'FRNS'),
36                      (1.5, 'Pass'),
37                      (2.4, '3rd Class Honours'),
38                      (3.5, '2nd Class Honours Lower Division'),
39                      (4.5, '2nd Class Honours Upper Division'),
40                      (5, '1st Class Honours'))
41
42    def increaseMatricInteger(self, student):
43        """Increase counter for matric numbers.
44        This counter can be a centrally stored attribute or an attribute of
45        faculties, departments or certificates. In the base package the counter
46        is as an attribute of the site configuration container.
47        """
48        if student.current_mode in ('ug_pt', 'de_pt'):
49            grok.getSite()['configuration'].next_matric_integer += 1
50            return
51        grok.getSite()['configuration'].next_matric_integer_2 += 1
52        return
53
54    def constructMatricNumber(self, student):
55        faccode = student.faccode
56        depcode = student.depcode
57        year = unicode(student.entry_session)[2:]
58        if not student.state in (PAID, ) or not student.is_fresh or \
59            student.current_mode == 'found':
60            return _('Matriculation number cannot be set.'), None
61        if student.current_mode in ('ug_pt', 'de_pt'):
62            next_integer = grok.getSite()['configuration'].next_matric_integer
63            if next_integer == 0:
64                return _('Matriculation number cannot be set.'), None
65            return None, "PTP/%s/%s/%s/%05d" % (
66                faccode, depcode, year, next_integer)
67        next_integer = grok.getSite()['configuration'].next_matric_integer_2
68        if next_integer == 0:
69            return _('Matriculation number cannot be set.'), None
70        if student.faccode in ('FBM', 'FCS'):
71            return None, "CMS/%s/%s/%s/%05d" % (
72                faccode, depcode, year, next_integer)
73        return None, "%s/%s/%s/%05d" % (faccode, depcode, year, next_integer)
74
75    def getReturningData(self, student):
76        """ This method defines what happens after school fee payment
77        of returning students depending on the student's senate verdict.
78        """
79        prev_level = student['studycourse'].current_level
80        cur_verdict = student['studycourse'].current_verdict
81        if cur_verdict in ('A','B','L','M','N','Z',):
82            # Successful student
83            new_level = divmod(int(prev_level),100)[0]*100 + 100
84        elif cur_verdict == 'C':
85            # Student on probation
86            new_level = int(prev_level) + 10
87        else:
88            # Student is somehow in an undefined state.
89            # Level has to be set manually.
90            new_level = prev_level
91        new_session = student['studycourse'].current_session + 1
92        return new_session, new_level
93
94    def setPaymentDetails(self, category, student,
95            previous_session=None, previous_level=None):
96        """Create Payment object and set the payment data of a student for
97        the payment category specified.
98
99        """
100        details = {}
101        p_item = u''
102        amount = 0.0
103        error = u''
104        if previous_session:
105            return _('Previous session payment not yet implemented.'), None
106        p_session = student['studycourse'].current_session
107        p_level = student['studycourse'].current_level
108        p_current = True
109        academic_session = self._getSessionConfiguration(p_session)
110        if academic_session == None:
111            return _(u'Session configuration object is not available.'), None
112        # Determine fee.
113        if category == 'transfer':
114            amount = academic_session.transfer_fee
115        elif category == 'transcript':
116            amount = academic_session.transcript_fee
117        elif category == 'gown':
118            amount = academic_session.gown_fee
119        elif category == 'bed_allocation':
120            amount = academic_session.booking_fee
121        elif category == 'hostel_maintenance':
122            amount = academic_session.maint_fee
123        elif category == 'welfare':
124            amount = academic_session.welfare_fee
125        elif category == 'union':
126            amount = academic_session.union_fee
127        elif category == 'lapel':
128            amount = academic_session.lapel_fee
129        elif category == 'matric_gown':
130            amount = academic_session.matric_gown_fee
131        elif category == 'concessional':
132            amount = academic_session.concession_fee
133        elif category == 'medical':
134            amount = academic_session.medical_fee
135        elif category == 'clearance':
136            if student.faccode == 'FP':
137                amount = academic_session.clearance_fee_fp
138            elif student.current_mode.endswith('_pt'):
139                amount = academic_session.clearance_fee_pt
140            elif student.faccode in ('FBM', 'FCS'):
141                amount = academic_session.clearance_fee_med
142            else:
143                amount = academic_session.clearance_fee
144            p_item = student['studycourse'].certificate.code
145        elif category == 'late_registration':
146            amount = academic_session.late_registration_fee
147        elif category == 'schoolfee':
148            try:
149                certificate = student['studycourse'].certificate
150                p_item = certificate.code
151            except (AttributeError, TypeError):
152                return _('Study course data are incomplete.'), None
153            if student.state == CLEARED:
154                if student.is_foreigner:
155                    amount = getattr(certificate, 'school_fee_3', 0.0)
156                else:
157                    amount = getattr(certificate, 'school_fee_1', 0.0)
158            elif student.state == RETURNING:
159                # In case of returning school fee payment the payment session
160                # and level contain the values of the session the student
161                # has paid for.
162                p_session, p_level = self.getReturningData(student)
163                try:
164                    academic_session = grok.getSite()[
165                        'configuration'][str(p_session)]
166                except KeyError:
167                    return _(u'Session configuration object is not available.'), None
168                if student.is_foreigner:
169                    amount = getattr(certificate, 'school_fee_4', 0.0)
170                else:
171                    amount = getattr(certificate, 'school_fee_2', 0.0)
172            else:
173                return _('Wrong state.'), None
174        if amount in (0.0, None):
175            return _(u'Amount could not be determined.'), None
176        # Add session specific penalty fee.
177        if category == 'schoolfee' and student.is_postgrad:
178            amount += academic_session.penalty_pg
179        elif category == 'schoolfee':
180            amount += academic_session.penalty_ug
181        # Create ticket.
182        for key in student['payments'].keys():
183            ticket = student['payments'][key]
184            if ticket.p_state == 'paid' and\
185               ticket.p_category == category and \
186               ticket.p_item == p_item and \
187               ticket.p_session == p_session:
188                  return _('This type of payment has already been made.'), None
189        if self._isPaymentDisabled(p_session, category, student):
190            return _('Payment temporarily disabled.'), None
191        payment = createObject(u'waeup.StudentOnlinePayment')
192        timestamp = ("%d" % int(time()*10000))[1:]
193        payment.p_id = "p%s" % timestamp
194        payment.p_category = category
195        payment.p_item = p_item
196        payment.p_session = p_session
197        payment.p_level = p_level
198        payment.p_current = p_current
199        payment.amount_auth = amount
200        return None, payment
201
202    def _admissionText(self, student, portal_language):
203        inst_name = grok.getSite()['configuration'].name
204        entry_session = student['studycourse'].entry_session
205        entry_session = academic_sessions_vocab.getTerm(entry_session).title
206        text = trans(_(
207            'This is to inform you that you have been offered provisional'
208            ' admission into ${a} for the ${b} academic session as follows:',
209            mapping = {'a': inst_name, 'b': entry_session}),
210            portal_language)
211        return text
212
213    def maxCredits(self, studylevel):
214        """Return maximum credits.
215
216        """
217        return 48
218
219    def getBedCoordinates(self, bedticket):
220        """Return descriptive bed coordinates.
221        This method can be used to customize the `display_coordinates`
222        property method in order to  display a
223        customary description of the bed space.
224        """
225        bc = bedticket.bed_coordinates.split(',')
226        if len(bc) == 4:
227            return bc[0]
228        return bedticket.bed_coordinates
229
230    # AAUE prefix
231    STUDENT_ID_PREFIX = u'E'
Note: See TracBrowser for help on using the repository browser.