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

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

Enable previous session payments.

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