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

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

Configure new payment categories. School fee amounts are now set via certificates not session configuration objects.

  • Property svn:keywords set to Id
File size: 9.7 KB
Line 
1## $Id: utils.py 13374 2015-11-01 14:11:52Z 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            else:
139                amount = academic_session.clearance_fee
140            p_item = student['studycourse'].certificate.code
141        elif category == 'late_registration':
142            amount = academic_session.late_registration_fee
143        elif category == 'schoolfee':
144            try:
145                certificate = student['studycourse'].certificate
146                p_item = certificate.code
147            except (AttributeError, TypeError):
148                return _('Study course data are incomplete.'), None
149            if student.state == CLEARED:
150                if student.is_foreigner:
151                    amount = getattr(certificate, 'school_fee_3', 0.0)
152                else:
153                    amount = getattr(certificate, 'school_fee_1', 0.0)
154            elif student.state == RETURNING:
155                # In case of returning school fee payment the payment session
156                # and level contain the values of the session the student
157                # has paid for.
158                p_session, p_level = self.getReturningData(student)
159                try:
160                    academic_session = grok.getSite()[
161                        'configuration'][str(p_session)]
162                except KeyError:
163                    return _(u'Session configuration object is not available.'), None
164                if student.is_foreigner:
165                    amount = getattr(certificate, 'school_fee_4', 0.0)
166                else:
167                    amount = getattr(certificate, 'school_fee_2', 0.0)
168            else:
169                return _('Wrong state.'), None
170        if amount in (0.0, None):
171            return _(u'Amount could not be determined.'), None
172        # Add session specific penalty fee.
173        if category == 'schoolfee' and student.is_postgrad:
174            amount += academic_session.penalty_pg
175        elif category == 'schoolfee':
176            amount += academic_session.penalty_ug
177        # Create ticket.
178        for key in student['payments'].keys():
179            ticket = student['payments'][key]
180            if ticket.p_state == 'paid' and\
181               ticket.p_category == category and \
182               ticket.p_item == p_item and \
183               ticket.p_session == p_session:
184                  return _('This type of payment has already been made.'), None
185        if self._isPaymentDisabled(p_session, category, student):
186            return _('Payment temporarily disabled.'), None
187        payment = createObject(u'waeup.StudentOnlinePayment')
188        timestamp = ("%d" % int(time()*10000))[1:]
189        payment.p_id = "p%s" % timestamp
190        payment.p_category = category
191        payment.p_item = p_item
192        payment.p_session = p_session
193        payment.p_level = p_level
194        payment.p_current = p_current
195        payment.amount_auth = amount
196        return None, payment
197
198    def _admissionText(self, student, portal_language):
199        inst_name = grok.getSite()['configuration'].name
200        entry_session = student['studycourse'].entry_session
201        entry_session = academic_sessions_vocab.getTerm(entry_session).title
202        text = trans(_(
203            'This is to inform you that you have been offered provisional'
204            ' admission into ${a} for the ${b} academic session as follows:',
205            mapping = {'a': inst_name, 'b': entry_session}),
206            portal_language)
207        return text
208
209    def maxCredits(self, studylevel):
210        """Return maximum credits.
211
212        """
213        return 48
214
215    def getBedCoordinates(self, bedticket):
216        """Return descriptive bed coordinates.
217        This method can be used to customize the `display_coordinates`
218        property method in order to  display a
219        customary description of the bed space.
220        """
221        bc = bedticket.bed_coordinates.split(',')
222        if len(bc) == 4:
223            return bc[0]
224        return bedticket.bed_coordinates
225
226    # AAUE prefix
227    STUDENT_ID_PREFIX = u'E'
Note: See TracBrowser for help on using the repository browser.