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

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

Use second matriculation number counter and configure constructMatricNumber method.

  • Property svn:keywords set to Id
File size: 9.3 KB
RevLine 
[7419]1## $Id: utils.py 13359 2015-10-28 20:54:47Z 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 (
[13348]22    ADMITTED, 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
[13348]33    PORTRAIT_CHANGE_STATES = (ADMITTED, RETURNING)
34
[10641]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
[13359]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
[11596]54    def constructMatricNumber(self, student):
[11593]55        faccode = student.faccode
56        depcode = student.depcode
57        year = unicode(student.entry_session)[2:]
[13359]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
[12975]65            return None, "PTP/%s/%s/%s/%05d" % (
66                faccode, depcode, year, next_integer)
[13359]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)
[12975]74
[8270]75    def getReturningData(self, student):
76        """ This method defines what happens after school fee payment
[8319]77        of returning students depending on the student's senate verdict.
[8270]78        """
[8319]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
[8270]91        new_session = student['studycourse'].current_session + 1
92        return new_session, new_level
93
[9154]94    def setPaymentDetails(self, category, student,
95            previous_session=None, previous_level=None):
[8600]96        """Create Payment object and set the payment data of a student for
97        the payment category specified.
98
99        """
[8306]100        details = {}
[8600]101        p_item = u''
102        amount = 0.0
103        error = u''
[9154]104        if previous_session:
105            return _('Previous session payment not yet implemented.'), None
[8600]106        p_session = student['studycourse'].current_session
107        p_level = student['studycourse'].current_level
[9154]108        p_current = True
[9527]109        academic_session = self._getSessionConfiguration(p_session)
110        if academic_session == None:
[8600]111            return _(u'Session configuration object is not available.'), None
[8677]112        # Determine fee.
[7151]113        if category == 'transfer':
[8600]114            amount = academic_session.transfer_fee
[10467]115        elif category == 'transcript':
116            amount = academic_session.transcript_fee
[7151]117        elif category == 'gown':
[8600]118            amount = academic_session.gown_fee
[7151]119        elif category == 'bed_allocation':
[8600]120            amount = academic_session.booking_fee
[7151]121        elif category == 'hostel_maintenance':
[8600]122            amount = academic_session.maint_fee
[7151]123        elif category == 'clearance':
[11653]124            if student.faccode == 'FP':
125                amount = academic_session.clearance_fee_fp
126            else:
127                amount = academic_session.clearance_fee
[8753]128            p_item = student['studycourse'].certificate.code
[11004]129        elif category == 'late_registration':
[13035]130            amount = academic_session.late_registration_fee
[9905]131        elif category == 'schoolfee':
[8600]132            try:
[8753]133                certificate = student['studycourse'].certificate
134                p_item = certificate.code
[8600]135            except (AttributeError, TypeError):
136                return _('Study course data are incomplete.'), None
[8753]137            if student.state == CLEARED:
[10922]138                if student.faccode == 'FP':
[11653]139                    amount = academic_session.school_fee_3
[10930]140                else:
[11624]141                    amount = academic_session.school_fee_1
[8961]142            elif student.state == RETURNING or\
143                (student.is_postgrad and student.state == PAID):
[9527]144                academic_session = self._getSessionConfiguration(p_session)
145                if academic_session == None:
146                    return _(u'Session configuration object is not available.'), None
[8961]147                if student.state == RETURNING:
148                    p_session, p_level = self.getReturningData(student)
149                else:
150                    # Returning postgraduate students also pay for the
151                    # next session but their level always remains the same.
152                    p_session += 1
153                try:
154                    academic_session = grok.getSite()[
155                        'configuration'][str(p_session)]
156                except KeyError:
157                    return _(u'Session configuration object is not available.'), None
[11624]158                amount = academic_session.school_fee_2
[8600]159            else:
[8753]160                return _('Wrong state.'), None
[8600]161        if amount in (0.0, None):
162            return _(u'Amount could not be determined.'), None
[8677]163        # Add session specific penalty fee.
[9905]164        if category == 'schoolfee' and student.is_postgrad:
[8677]165            amount += academic_session.penalty_pg
[9905]166        elif category == 'schoolfee':
[8677]167            amount += academic_session.penalty_ug
168        # Create ticket.
[8600]169        for key in student['payments'].keys():
170            ticket = student['payments'][key]
171            if ticket.p_state == 'paid' and\
172               ticket.p_category == category and \
173               ticket.p_item == p_item and \
174               ticket.p_session == p_session:
175                  return _('This type of payment has already been made.'), None
[11455]176        if self._isPaymentDisabled(p_session, category, student):
177            return _('Payment temporarily disabled.'), None
[8712]178        payment = createObject(u'waeup.StudentOnlinePayment')
[8954]179        timestamp = ("%d" % int(time()*10000))[1:]
[8600]180        payment.p_id = "p%s" % timestamp
181        payment.p_category = category
182        payment.p_item = p_item
183        payment.p_session = p_session
184        payment.p_level = p_level
[9154]185        payment.p_current = p_current
[8600]186        payment.amount_auth = amount
187        return None, payment
[7621]188
[10922]189    def _admissionText(self, student, portal_language):
190        inst_name = grok.getSite()['configuration'].name
191        entry_session = student['studycourse'].entry_session
192        entry_session = academic_sessions_vocab.getTerm(entry_session).title
193        text = trans(_(
[10953]194            'This is to inform you that you have been offered provisional'
195            ' admission into ${a} for the ${b} academic session as follows:',
[10922]196            mapping = {'a': inst_name, 'b': entry_session}),
197            portal_language)
198        return text
199
[10051]200    def maxCredits(self, studylevel):
201        """Return maximum credits.
202
203        """
204        return 48
205
[13353]206    def getBedCoordinates(self, bedticket):
207        """Return descriptive bed coordinates.
208        This method can be used to customize the `display_coordinates`
209        property method in order to  display a
210        customary description of the bed space.
211        """
212        bc = bedticket.bed_coordinates.split(',')
213        if len(bc) == 4:
214            return bc[0]
215        return bedticket.bed_coordinates
216
[8444]217    # AAUE prefix
218    STUDENT_ID_PREFIX = u'E'
Note: See TracBrowser for help on using the repository browser.