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

Last change on this file since 15485 was 15485, checked in by Henrik Bettermann, 5 years ago

Allow change of portrait only in state admitted.

  • Property svn:keywords set to Id
File size: 9.0 KB
Line 
1## $Id: utils.py 15485 2019-07-05 06:13:13Z 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.
67        """
68        if studylevel.student.current_mode == 'nce_ft':
69            limit = 56
70        elif studylevel.student.current_mode == 'ug_ft':
71            limit = 48
72            if studylevel.level == 400:
73                limit = 51
74        else:
75            limit = 50
76        if course and studylevel.total_credits + course.credits > limit:
77            return _('Maximum credits exceeded.')
78        elif studylevel.total_credits > limit:
79            return _('Maximum credits exceeded.')
80        return
81
82    def _isPaymentDisabled(self, p_session, category, student):
83        academic_session = self._getSessionConfiguration(p_session)
84        if category.startswith('schoolfee'):
85            if 'sf_all' in academic_session.payment_disabled:
86                return True
87            if student.current_mode == 'ug_ft' and \
88                'degree' in academic_session.payment_disabled:
89                return True
90        return False
91
92    def setPaymentDetails(self, category, student,
93            previous_session=None, previous_level=None):
94        """Create a payment ticket and set the payment data of a
95        student for the payment category specified.
96        """
97        p_item = u''
98        amount = 0.0
99        if previous_session:
100            if previous_session < student['studycourse'].entry_session:
101                return _('The previous session must not fall below '
102                         'your entry session.'), None
103            if category == 'schoolfee':
104                # School fee is always paid for the following session
105                if previous_session > student['studycourse'].current_session:
106                    return _('This is not a previous session.'), None
107            else:
108                if previous_session > student['studycourse'].current_session - 1:
109                    return _('This is not a previous session.'), None
110            p_session = previous_session
111            p_level = previous_level
112            p_current = False
113        else:
114            p_session = student['studycourse'].current_session
115            p_level = student['studycourse'].current_level
116            p_current = True
117        academic_session = self._getSessionConfiguration(p_session)
118        if academic_session == None:
119            return _(u'Session configuration object is not available.'), None
120        # Determine fee.
121        if category.startswith('schoolfee'):
122            try:
123                certificate = student['studycourse'].certificate
124                p_item = certificate.code
125            except (AttributeError, TypeError):
126                return _('Study course data are incomplete.'), None
127            if student.state == RETURNING:
128                # Override p_session and p_level
129                p_session, p_level = self.getReturningData(student)
130                academic_session = self._getSessionConfiguration(p_session)
131                if academic_session == None:
132                    return _(u'Session configuration object '
133                              'is not available.'), None
134            if p_level in PAYMENT_LEVELS:
135                if student.entry_mode == 'de_ft' and p_level == 200:
136                    amount = SCHOOL_FEES.get_fee(
137                        (
138                         local_nonlocal(student),
139                         student.current_mode,
140                         100)
141                        )
142                else:
143                    amount = SCHOOL_FEES.get_fee(
144                        (
145                         local_nonlocal(student),
146                         student.current_mode,
147                         p_level)
148                        )
149            if amount and category in ('schoolfee_1', 'schoolfee_2'):
150                amount /= 2
151            if amount:
152                amount += GATEWAY_AMT
153        elif category == 'clearance':
154            try:
155                p_item = student['studycourse'].certificate.code
156            except (AttributeError, TypeError):
157                return _('Study course data are incomplete.'), None
158            if student.entry_mode == 'nce_we_pt':
159                amount = academic_session.clearance_fee_3
160            elif student.entry_mode in ('ug_ft', 'de_ft'):
161                amount = academic_session.clearance_fee_2
162            else:
163                amount = academic_session.clearance_fee_1
164            if local_nonlocal(student) == 'non-local'  \
165                and student.entry_mode != 'nce_we_pt':
166                amount += 5000.0
167        elif category == 'bed_allocation':
168            p_item = self.getAccommodationDetails(student)['bt']
169            amount = academic_session.booking_fee
170        elif category == 'hostel_maintenance':
171            amount = 0.0
172            bedticket = student['accommodation'].get(
173                str(student.current_session), None)
174            if bedticket is not None and bedticket.bed is not None:
175                p_item = bedticket.bed_coordinates
176                if bedticket.bed.__parent__.maint_fee > 0:
177                    amount = bedticket.bed.__parent__.maint_fee
178                else:
179                    # fallback
180                    amount = academic_session.maint_fee
181            else:
182                return _(u'No bed allocated.'), None
183        elif category == 'transcript':
184            amount = academic_session.transcript_fee
185        elif category == 'transfer':
186            amount = academic_session.transfer_fee
187        elif category == 'late_registration':
188            amount = academic_session.late_registration_fee
189        if amount in (0.0, None):
190            return _('Amount could not be determined.'), None
191        if self.samePaymentMade(student, category, p_item, p_session):
192            return _('This type of payment has already been made.'), None
193        if self._isPaymentDisabled(p_session, category, student):
194            return _('This category of payments has been disabled.'), None
195        payment = createObject(u'waeup.StudentOnlinePayment')
196        timestamp = ("%d" % int(time()*10000))[1:]
197        payment.p_id = "p%s" % timestamp
198        payment.p_category = category
199        payment.p_item = p_item
200        payment.p_session = p_session
201        payment.p_level = p_level
202        payment.p_current = p_current
203        payment.amount_auth = amount
204        return None, payment
205
206    # prefix
207    STUDENT_ID_PREFIX = u'R'
208
209    PORTRAIT_CHANGE_STATES = (ADMITTED, )
Note: See TracBrowser for help on using the repository browser.