## $Id: utils.py 16478 2021-05-08 16:11:45Z henrik $ ## ## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## from time import time from zope.component import createObject, getUtility from waeup.kofa.fees import FeeTable from waeup.kofa.interfaces import (IKofaUtils, ADMITTED, CLEARED, RETURNING, PAID, REGISTERED, VALIDATED) from kofacustom.nigeria.students.utils import NigeriaStudentsUtils from kofacustom.coewarri.interfaces import MessageFactory as _ from kofacustom.coewarri.interswitch.browser import GATEWAY_AMT def local_nonlocal(student): lga = getattr(student, 'lga') if lga and lga.startswith('delta'): return 'local' else: return 'non-local' PAYMENT_LEVELS = (100, 110, 200, 210, 300, 310, 400, 410, 500, 999) FEES_PARAMS = ( ('local', 'non-local'), ('nce_ft', 'nce_pt', 'ug_ft', 'nce_we_pt'), PAYMENT_LEVELS ) FEES_VALUES = ( ( # 100 110 200 210 300 310 400 410 500 999 (43200.0, 43200.0, 43200.0, 43200.0, 37200.0, 37200.0, 0.0, 0.0, 0.0, 0.0), # nce_ft (55200.0, 55200.0, 49200.0, 49200.0, 53200.0, 53200.0, 49200.0, 49200.0, 0.0, 0.0), # nce_pt (75700.0, 75700.0, 64700.0, 64700.0, 68700.0, 68700.0, 62700.0, 62700.0, 0.0, 0.0), # ug_ft (33200.0, 33200.0, 28000.0, 28000.0, 32000.0, 32000.0, 28000.0, 28000.0, 0.0, 0.0), # nce_we_pt ), # local ( # (55800.0, 55800.0, 55700.0, 55700.0, 49700.0, 49700.0, 0.0, 0.0, 0.0, 0.0), # nce_ft (55200.0, 55200.0, 49200.0, 49200.0, 53200.0, 53200.0, 49200.0, 49200.0, 0.0, 0.0), # nce_pt (85700.0, 85700.0, 74700.0, 74700.0, 78700.0, 78700.0, 72700.0, 72700.0, 0.0, 0.0), # ug_ft (33200.0, 33200.0, 28000.0, 28000.0, 32000.0, 32000.0, 28000.0, 28000.0, 0.0, 0.0), # nce_we_pt ), # non-local ) SCHOOL_FEES = FeeTable(FEES_PARAMS, FEES_VALUES) class CustomStudentsUtils(NigeriaStudentsUtils): """A collection of customized methods. """ def warnCreditsOOR(self, studylevel, course=None): """Return message if credits are out of range. """ if studylevel.student.current_mode == 'nce_ft': limit = 56 elif studylevel.student.current_mode == 'ug_ft': limit = 48 if studylevel.level == 400: limit = 51 else: limit = 50 if course and studylevel.total_credits + course.credits > limit: return _('Maximum credits exceeded.') elif studylevel.total_credits > limit: return _('Maximum credits exceeded.') return def _isPaymentDisabled(self, p_session, category, student): academic_session = self._getSessionConfiguration(p_session) if category.startswith('schoolfee'): if 'sf_all' in academic_session.payment_disabled: return True if student.current_mode == 'ug_ft' and \ 'degree' in academic_session.payment_disabled: return True return False def _lsfp_penalty_paymentMade(self, student, session): if student.current_mode not in ('ug_ft','de_ft', 'nce_ft', 'nce_pt'): return True if len(student['payments']): for ticket in student['payments'].values(): if ticket.p_state == 'paid' and \ ticket.p_category == 'lsfp_penalty' and \ ticket.p_session == session: return True return False def setPaymentDetails(self, category, student, previous_session=None, previous_level=None, combi=[]): """Create a payment ticket and set the payment data of a student for the payment category specified. """ p_item = u'' amount = 0.0 if previous_session: if previous_session < student['studycourse'].entry_session: return _('The previous session must not fall below ' 'your entry session.'), None if category == 'schoolfee': # School fee is always paid for the following session if previous_session > student['studycourse'].current_session: return _('This is not a previous session.'), None else: if previous_session > student['studycourse'].current_session - 1: return _('This is not a previous session.'), None p_session = previous_session p_level = previous_level p_current = False else: p_session = student['studycourse'].current_session p_level = student['studycourse'].current_level p_current = True academic_session = self._getSessionConfiguration(p_session) if academic_session == None: return _(u'Session configuration object is not available.'), None # Determine fee. if category.startswith('schoolfee'): try: certificate = student['studycourse'].certificate p_item = certificate.code except (AttributeError, TypeError): return _('Study course data are incomplete.'), None if student.state == RETURNING: # Override p_session and p_level p_session, p_level = self.getReturningData(student) academic_session = self._getSessionConfiguration(p_session) if academic_session == None: return _(u'Session configuration object ' 'is not available.'), None penalty = getattr(academic_session, 'lsfp_penalty_fee') if p_session < 2020 and penalty and \ not self._lsfp_penalty_paymentMade( student, student.current_session): return _('You have to pay late school fee payment penalty first.'), None if p_level in PAYMENT_LEVELS: amount = SCHOOL_FEES.get_fee( ( local_nonlocal(student), student.current_mode, p_level) ) if student.entry_mode == 'de_ft' and p_level == 200: if student['studycourse'].entry_session >= 2020: amount += 15000 elif student['studycourse'].entry_session >= 2019: amount += 10500 if amount and category in ('schoolfee_1', 'schoolfee_2'): amount /= 2 if amount: amount += GATEWAY_AMT elif category == 'clearance': try: p_item = student['studycourse'].certificate.code except (AttributeError, TypeError): return _('Study course data are incomplete.'), None if student.entry_mode in ('nce_we_pt', 'nce_pt'): amount = academic_session.clearance_fee_3 elif student.entry_mode in ('ug_ft', 'de_ft'): amount = academic_session.clearance_fee_2 else: amount = academic_session.clearance_fee_1 if local_nonlocal(student) == 'non-local' \ and student.entry_mode not in ('nce_we_pt', 'nce_pt'): amount += 5000.0 elif category == 'bed_allocation': p_item = self.getAccommodationDetails(student)['bt'] amount = academic_session.booking_fee elif category == 'hostel_maintenance': amount = 0.0 bedticket = student['accommodation'].get( str(student.current_session), None) if bedticket is not None and bedticket.bed is not None: p_item = bedticket.bed_coordinates if bedticket.bed.__parent__.maint_fee > 0: amount = bedticket.bed.__parent__.maint_fee else: # fallback amount = academic_session.maint_fee else: return _(u'No bed allocated.'), None else: fee_name = category + '_fee' amount = getattr(academic_session, fee_name, 0.0) if amount in (0.0, None): return _('Amount could not be determined.'), None if self.samePaymentMade(student, category, p_item, p_session): return _('This type of payment has already been made.'), None if self._isPaymentDisabled(p_session, category, student): return _('This category of payments has been disabled.'), None payment = createObject(u'waeup.StudentOnlinePayment') timestamp = ("%d" % int(time()*10000))[1:] payment.p_id = "p%s" % timestamp payment.p_category = category payment.p_item = p_item payment.p_session = p_session payment.p_level = p_level payment.p_current = p_current payment.amount_auth = amount return None, payment # prefix STUDENT_ID_PREFIX = u'R' PORTRAIT_CHANGE_STATES = ()