source: main/kofacustom.coewarri/trunk/src/kofacustom/coewarri/students/utils.py @ 15424

Last change on this file since 15424 was 15381, checked in by Henrik Bettermann, 6 years ago

Customize warnCreditsOOR.

  • Property svn:keywords set to Id
File size: 9.0 KB
Line 
1## $Id: utils.py 15381 2019-04-02 07:06:56Z 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##
18from time import time
19from zope.component import createObject, getUtility
20from waeup.kofa.fees import FeeTable
21from waeup.kofa.interfaces import (IKofaUtils,
22    ADMITTED, CLEARED, RETURNING, PAID, REGISTERED, VALIDATED)
23from kofacustom.nigeria.students.utils import NigeriaStudentsUtils
24from kofacustom.coewarri.interfaces import MessageFactory as _
25from kofacustom.coewarri.interswitch.browser import GATEWAY_AMT
26
27
28def local_nonlocal(student):
29    lga = getattr(student, 'lga')
30    if lga and lga.startswith('delta'):
31        return 'local'
32    else:
33        return 'non-local'
34
35PAYMENT_LEVELS = (100, 110, 200, 210, 300, 310, 400, 410, 500, 999)
36
37FEES_PARAMS = (
38        ('local', 'non-local'),
39        ('nce_ft', 'nce_pt', 'ug_ft', 'nce_we_pt'),
40        PAYMENT_LEVELS
41    )
42
43FEES_VALUES = (
44      ( # 100      110      200      210      300      310      400      410     500  999
45        (42200.0, 42200.0, 39700.0, 39700.0, 37200.0, 37200.0, 0.0, 0.0, 0.0, 0.0), # nce_ft
46        (55200.0, 55200.0, 49200.0, 49200.0, 52200.0, 52200.0, 42200.0, 42200.0, 0.0, 0.0), # nce_pt
47        (69200.0, 69200.0, 64700.0, 64700.0, 67700.0, 67700.0, 62100.0, 62100.0, 0.0, 0.0), # ug_ft
48        (33000.0, 33000.0, 28000.0, 28000.0, 28000.0, 28000.0, 20000.0, 20000.0, 0.0, 0.0), # nce_we_pt
49      ), # local
50      ( #
51        (54800.0, 54800.0, 52300.0, 52300.0, 49800.0, 49800.0, 0.0, 0.0, 0.0, 0.0), # nce_ft
52        (55200.0, 55200.0, 49200.0, 49200.0, 52200.0, 52200.0, 42200.0, 42200.0, 0.0, 0.0), # nce_pt
53        (79200.0, 79200.0, 74700.0, 74700.0, 77700.0, 77700.0, 62100.0, 62100.0, 0.0, 0.0), # ug_ft
54        (33000.0, 33000.0, 28000.0, 28000.0, 28000.0, 28000.0, 20000.0, 20000.0, 0.0, 0.0), # nce_we_pt
55      ), # non-local
56    )
57
58SCHOOL_FEES = FeeTable(FEES_PARAMS, FEES_VALUES)
59
60class CustomStudentsUtils(NigeriaStudentsUtils):
61    """A collection of customized methods.
62
63    """
64
65    def warnCreditsOOR(self, studylevel, course=None):
66        """Return message if credits are out of range. In the base
67        package only maximum credits is set.
68        """
69        if studylevel.student.current_mode == 'nce_ft':
70            limit = 56
71        elif studylevel.student.current_mode == 'ug_ft':
72            limit = 48
73        else:
74            limit = 50
75        if course and studylevel.total_credits + course.credits > limit:
76            return _('Maximum credits exceeded.')
77        elif studylevel.total_credits > limit:
78            return _('Maximum credits exceeded.')
79        return
80
81    def _isPaymentDisabled(self, p_session, category, student):
82        academic_session = self._getSessionConfiguration(p_session)
83        if category.startswith('schoolfee'):
84            if 'sf_all' in academic_session.payment_disabled:
85                return True
86            if student.current_mode == 'ug_ft' and \
87                'degree' in academic_session.payment_disabled:
88                return True
89        return False
90
91    def setPaymentDetails(self, category, student,
92            previous_session=None, previous_level=None):
93        """Create a payment ticket and set the payment data of a
94        student for the payment category specified.
95        """
96        p_item = u''
97        amount = 0.0
98        if previous_session:
99            if previous_session < student['studycourse'].entry_session:
100                return _('The previous session must not fall below '
101                         'your entry session.'), None
102            if category == 'schoolfee':
103                # School fee is always paid for the following session
104                if previous_session > student['studycourse'].current_session:
105                    return _('This is not a previous session.'), None
106            else:
107                if previous_session > student['studycourse'].current_session - 1:
108                    return _('This is not a previous session.'), None
109            p_session = previous_session
110            p_level = previous_level
111            p_current = False
112        else:
113            p_session = student['studycourse'].current_session
114            p_level = student['studycourse'].current_level
115            p_current = True
116        academic_session = self._getSessionConfiguration(p_session)
117        if academic_session == None:
118            return _(u'Session configuration object is not available.'), None
119        # Determine fee.
120        if category.startswith('schoolfee'):
121            try:
122                certificate = student['studycourse'].certificate
123                p_item = certificate.code
124            except (AttributeError, TypeError):
125                return _('Study course data are incomplete.'), None
126            if student.state == RETURNING:
127                # Override p_session and p_level
128                p_session, p_level = self.getReturningData(student)
129                academic_session = self._getSessionConfiguration(p_session)
130                if academic_session == None:
131                    return _(u'Session configuration object '
132                              'is not available.'), None
133            if p_level in PAYMENT_LEVELS:
134                if student.entry_mode == 'de_ft' and p_level == 200:
135                    amount = SCHOOL_FEES.get_fee(
136                        (
137                         local_nonlocal(student),
138                         student.current_mode,
139                         100)
140                        )
141                else:
142                    amount = SCHOOL_FEES.get_fee(
143                        (
144                         local_nonlocal(student),
145                         student.current_mode,
146                         p_level)
147                        )
148            if amount and category in ('schoolfee_1', 'schoolfee_2'):
149                amount /= 2
150            if amount:
151                amount += GATEWAY_AMT
152        elif category == 'clearance':
153            try:
154                p_item = student['studycourse'].certificate.code
155            except (AttributeError, TypeError):
156                return _('Study course data are incomplete.'), None
157            if student.entry_mode == 'nce_we_pt':
158                amount = academic_session.clearance_fee_3
159            elif student.entry_mode in ('ug_ft', 'de_ft'):
160                amount = academic_session.clearance_fee_2
161            else:
162                amount = academic_session.clearance_fee_1
163            if local_nonlocal(student) == 'non-local'  \
164                and student.entry_mode != 'nce_we_pt':
165                amount += 5000.0
166        elif category == 'bed_allocation':
167            p_item = self.getAccommodationDetails(student)['bt']
168            amount = academic_session.booking_fee
169        elif category == 'hostel_maintenance':
170            amount = 0.0
171            bedticket = student['accommodation'].get(
172                str(student.current_session), None)
173            if bedticket is not None and bedticket.bed is not None:
174                p_item = bedticket.bed_coordinates
175                if bedticket.bed.__parent__.maint_fee > 0:
176                    amount = bedticket.bed.__parent__.maint_fee
177                else:
178                    # fallback
179                    amount = academic_session.maint_fee
180            else:
181                return _(u'No bed allocated.'), None
182        elif category == 'transcript':
183            amount = academic_session.transcript_fee
184        elif category == 'transfer':
185            amount = academic_session.transfer_fee
186        elif category == 'late_registration':
187            amount = academic_session.late_registration_fee
188        if amount in (0.0, None):
189            return _('Amount could not be determined.'), None
190        if self.samePaymentMade(student, category, p_item, p_session):
191            return _('This type of payment has already been made.'), None
192        if self._isPaymentDisabled(p_session, category, student):
193            return _('This category of payments has been disabled.'), None
194        payment = createObject(u'waeup.StudentOnlinePayment')
195        timestamp = ("%d" % int(time()*10000))[1:]
196        payment.p_id = "p%s" % timestamp
197        payment.p_category = category
198        payment.p_item = p_item
199        payment.p_session = p_session
200        payment.p_level = p_level
201        payment.p_current = p_current
202        payment.amount_auth = amount
203        return None, payment
204
205    # prefix
206    STUDENT_ID_PREFIX = u'R'
207
208    PORTRAIT_CHANGE_STATES = (
209        ADMITTED, CLEARED, RETURNING, PAID, REGISTERED, VALIDATED)
Note: See TracBrowser for help on using the repository browser.