## $Id: browser.py 15711 2019-10-29 06:06:52Z henrik $ ## ## Copyright (C) 2012 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 ## import grok from zope.formlib.textwidgets import BytesDisplayWidget from zope.component import getUtility from zope.security import checkPermission from zope.i18n import translate from datetime import datetime from waeup.kofa.widgets.datewidget import FriendlyDatetimeDisplayWidget from waeup.kofa.interfaces import IExtFileStore, IObjectHistory, IKofaUtils from waeup.kofa.browser.layout import action, UtilityView from waeup.kofa.utils.helpers import get_current_principal, to_timezone from waeup.kofa.students.browser import ( StudentPersonalDisplayFormPage, StudentPersonalManageFormPage, StudentClearanceManageFormPage, StudentClearanceEditFormPage, StudentClearanceDisplayFormPage, OnlinePaymentFakeApproveView, ExportPDFClearanceSlip, StudentBaseManageFormPage, StudentBaseDisplayFormPage, StudentBasePDFFormPage, StudentBaseEditFormPage, StudentPersonalEditFormPage, OnlinePaymentDisplayFormPage, OnlinePaymentAddFormPage, OnlinePaymentBreadcrumb, ExportPDFPaymentSlip, ExportPDFCourseRegistrationSlip, ExportPDFBedTicketSlip, StudentFilesUploadPage, emit_lock_message, AccommodationManageFormPage, BedTicketAddPage) from waeup.kofa.students.interfaces import IStudentsUtils from waeup.kofa.students.viewlets import ( PaymentReceiptActionButton, StudentPassportActionButton) from kofacustom.nigeria.students.interfaces import ( INigeriaStudentBase, INigeriaStudent, INigeriaStudentPersonal, INigeriaStudentPersonalEdit, INigeriaUGStudentClearance,INigeriaPGStudentClearance, INigeriaStudentOnlinePayment ) from waeup.kofa.students.workflow import ADMITTED from kofacustom.nigeria.interfaces import MessageFactory as _ class NigeriaOnlinePaymentBreadcrumb(OnlinePaymentBreadcrumb): """A breadcrumb for payments. """ grok.context(INigeriaStudentOnlinePayment) class PaymentReceiptActionButton(PaymentReceiptActionButton): grok.order(4) grok.context(INigeriaStudentOnlinePayment) class NigeriaStudentBaseDisplayFormPage(StudentBaseDisplayFormPage): """ Page to display student base data """ form_fields = grok.AutoFields(INigeriaStudentBase).omit( 'password', 'suspended', 'suspended_comment', 'flash_notice', 'provisionally_cleared') form_fields[ 'financial_clearance_date'].custom_widget = FriendlyDatetimeDisplayWidget('le') class NigeriaStudentBaseManageFormPage(StudentBaseManageFormPage): """ View to manage student base data """ form_fields = grok.AutoFields(INigeriaStudentBase).omit( 'student_id', 'adm_code', 'suspended', 'financially_cleared_by', 'financial_clearance_date') class NigeriaStudentBaseEditFormPage(StudentBaseEditFormPage): """ View to edit student base data """ form_fields = grok.AutoFields(INigeriaStudentBase).select( 'email', 'phone') class NigeriaStudentPersonalDisplayFormPage(StudentPersonalDisplayFormPage): """ Page to display student personal data """ form_fields = grok.AutoFields(INigeriaStudentPersonal) form_fields['perm_address'].custom_widget = BytesDisplayWidget form_fields['next_kin_address'].custom_widget = BytesDisplayWidget form_fields[ 'personal_updated'].custom_widget = FriendlyDatetimeDisplayWidget('le') class NigeriaStudentPersonalEditFormPage(StudentPersonalEditFormPage): """ Page to edit personal data """ form_fields = grok.AutoFields(INigeriaStudentPersonalEdit).omit('personal_updated') class NigeriaStudentPersonalManageFormPage(StudentPersonalManageFormPage): """ Page to edit personal data """ form_fields = grok.AutoFields(INigeriaStudentPersonal) form_fields['personal_updated'].for_display = True form_fields[ 'personal_updated'].custom_widget = FriendlyDatetimeDisplayWidget('le') class NigeriaStudentClearanceDisplayFormPage(StudentClearanceDisplayFormPage): """ Page to display student clearance data """ @property def form_fields(self): if self.context.is_postgrad: form_fields = grok.AutoFields( INigeriaPGStudentClearance).omit('clearance_locked') else: form_fields = grok.AutoFields( INigeriaUGStudentClearance).omit('clearance_locked') if not getattr(self.context, 'officer_comment'): form_fields = form_fields.omit('officer_comment') else: form_fields['officer_comment'].custom_widget = BytesDisplayWidget return form_fields class NigeriaExportPDFClearanceSlip(ExportPDFClearanceSlip): """Deliver a PDF slip of the context. """ omit_fields = ('password', 'suspended', 'suspended_comment', 'phone', 'adm_code', 'email', 'date_of_birth', 'current_level', 'flash_notice') @property def form_fields(self): if self.context.is_postgrad: form_fields = grok.AutoFields( INigeriaPGStudentClearance).omit('clearance_locked') else: form_fields = grok.AutoFields( INigeriaUGStudentClearance).omit('clearance_locked') if not getattr(self.context, 'officer_comment'): form_fields = form_fields.omit('officer_comment') return form_fields class NigeriaStudentClearanceManageFormPage(StudentClearanceManageFormPage): """ Page to edit student clearance data """ @property def form_fields(self): if self.context.is_postgrad: form_fields = grok.AutoFields( INigeriaPGStudentClearance).omit('clr_code') else: form_fields = grok.AutoFields( INigeriaUGStudentClearance).omit('clr_code') return form_fields class NigeriaStudentClearanceEditFormPage(StudentClearanceEditFormPage): """ View to edit student clearance data by student """ @property def form_fields(self): if self.context.is_postgrad: form_fields = grok.AutoFields(INigeriaPGStudentClearance).omit( 'clearance_locked', 'nysc_location', 'clr_code', 'officer_comment', 'physical_clearance_date') else: form_fields = grok.AutoFields(INigeriaUGStudentClearance).omit( 'clearance_locked', 'clr_code', 'officer_comment', 'physical_clearance_date') return form_fields class NigeriaExportPDFCourseRegistrationSlip(ExportPDFCourseRegistrationSlip): """Deliver a PDF slip of the context. """ omit_fields = ('password', 'suspended', 'suspended_comment', 'phone', 'adm_code', 'sex', 'email', 'date_of_birth', 'current_level', 'flash_notice') class NigeriaOnlinePaymentDisplayFormPage(OnlinePaymentDisplayFormPage): """ Page to view an online payment ticket """ grok.context(INigeriaStudentOnlinePayment) form_fields = grok.AutoFields(INigeriaStudentOnlinePayment).omit( 'provider_amt', 'gateway_amt', 'thirdparty_amt', 'p_item','p_combi') form_fields[ 'creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le') form_fields[ 'payment_date'].custom_widget = FriendlyDatetimeDisplayWidget('le') class NigeriaOnlinePaymentAddFormPage(OnlinePaymentAddFormPage): """ Page to add an online payment ticket """ form_fields = grok.AutoFields(INigeriaStudentOnlinePayment).select( 'p_combi') class NigeriaOnlinePaymentFakeApproveView(OnlinePaymentFakeApproveView): """ Disable payment approval view for students. This view is used for browser tests only and has to be neutralized here! """ grok.name('fake_approve') grok.require('waeup.managePortal') def update(self): return class NigeriaExportPDFPaymentSlip(ExportPDFPaymentSlip): """Deliver a PDF slip of the context. """ grok.context(INigeriaStudentOnlinePayment) form_fields = grok.AutoFields(INigeriaStudentOnlinePayment).omit( 'provider_amt', 'gateway_amt', 'thirdparty_amt', 'p_item', 'p_split_data','p_combi') form_fields['creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le') form_fields['payment_date'].custom_widget = FriendlyDatetimeDisplayWidget('le') omit_fields = ('password', 'suspended', 'suspended_comment', 'phone', 'adm_code', 'sex', 'email', 'date_of_birth', 'current_level', 'flash_notice') class NigeriaAccommodationManageFormPage(AccommodationManageFormPage): """ Page to manage bed tickets. This manage form page is for both students and students officers. """ with_hostel_selection = False class NigeriaBedTicketAddPage(BedTicketAddPage): """ Page to add a bed ticket """ with_ac = True with_bedselection = False class NigeriaExportPDFBedTicketSlip(ExportPDFBedTicketSlip): """Deliver a PDF slip of the context. """ omit_fields = ('password', 'suspended', 'suspended_comment', 'phone', 'adm_code', 'email', 'date_of_birth', 'current_level', 'flash_notice') class StudentPassportActionButton(StudentPassportActionButton): @property def target_url(self): # Passport pictures must not be editable if application slip # exists. slip = getUtility(IExtFileStore).getFileByContext( self.context, 'application_slip') PORTRAIT_CHANGE_STATES = getUtility(IStudentsUtils).PORTRAIT_CHANGE_STATES if self.context.state not in PORTRAIT_CHANGE_STATES or slip is not None: return '' return self.view.url(self.view.context, self.target) class NigeriaStudentFilesUploadPage(StudentFilesUploadPage): """ View to upload passport picture. Students are not allowed to change the picture if they passed the regular Kofa application. """ def update(self): # Passport pictures must not be editable if application slip # exists. slip = getUtility(IExtFileStore).getFileByContext( self.context, 'application_slip') PORTRAIT_CHANGE_STATES = getUtility(IStudentsUtils).PORTRAIT_CHANGE_STATES if self.context.state not in PORTRAIT_CHANGE_STATES or slip is not None: emit_lock_message(self) return super(StudentFilesUploadPage, self).update() return class ClearStudentFinancially(UtilityView, grok.View): """ Clear student financially by financial clearance officer """ grok.context(INigeriaStudent) grok.name('clear_financially') grok.require('waeup.clearStudentFinancially') def update(self): if self.context.financially_cleared_by: self.flash(_('This student has already been financially cleared.'), type="danger") self.redirect(self.url(self.context)) return user = get_current_principal() if user is None: usertitle = 'system' else: usertitle = getattr(user, 'public_name', None) if not usertitle: usertitle = user.title self.context.financially_cleared_by = usertitle self.context.financial_clearance_date = datetime.utcnow() self.context.writeLogMessage(self,'financially cleared') history = IObjectHistory(self.context) history.addMessage('Financially cleared') self.flash(_('Student has been financially cleared.')) self.redirect(self.url(self.context)) return def render(self): return class WithdrawFinancialClearance(UtilityView, grok.View): """ Withdraw financial clearance by financial clearance officer """ grok.context(INigeriaStudent) grok.name('withdraw_financial_clearance') grok.require('waeup.clearStudentFinancially') def update(self): if not self.context.financially_cleared_by: self.flash(_('This student has not yet been financially cleared.'), type="danger") self.redirect(self.url(self.context)) return self.context.financially_cleared_by = None self.context.financial_clearance_date = None self.context.writeLogMessage(self,'financial clearance withdrawn') history = IObjectHistory(self.context) history.addMessage('Financial clearance withdrawn') self.flash(_('Financial clearance withdrawn.')) self.redirect(self.url(self.context)) return def render(self): return cleared_note = """


Financially cleared on %s by %s. """ class NigeriaExportPDFFinancialClearancePage(UtilityView, grok.View): """Deliver a PDF financial clearance slip. """ grok.context(INigeriaStudent) grok.name('fee_payment_history.pdf') grok.require('waeup.viewStudent') prefix = 'form' omit_fields = ( 'suspended', 'phone', 'adm_code', 'suspended_comment', 'date_of_birth', 'current_level', 'flash_notice') form_fields = None @property def label(self): portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE return translate(_('Fee Payment History for'), 'waeup.kofa', target_language=portal_language) \ + ' %s' % self.context.display_fullname def _sigsInFooter(self): if not checkPermission('waeup.clearStudentFinancially', self.context): return () return (_('Date, Checking Officer Signature'), _('Date, Approving Officer Signature'), ) @property def note(self): if self.context.financially_cleared_by: tz = getUtility(IKofaUtils).tzinfo try: timestamp = to_timezone( self.context.financial_clearance_date, tz).strftime( "%Y-%m-%d %H:%M:%S") except ValueError: return return cleared_note % ( timestamp, self.context.financially_cleared_by) return @property def tabletitle(self): portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE tabletitle = [] tabletitle.append(translate(_('Successful Payments'), 'waeup.kofa', target_language=portal_language)) return tabletitle def render(self): portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE P_ID = translate(_('Payment Id'), 'waeup.kofa', target_language=portal_language) #CD = translate(_('Creation Date'), 'waeup.kofa', target_language=portal_language) PD = translate(_('Payment Date'), 'waeup.kofa', target_language=portal_language) CAT = translate(_('Payment Category'), 'waeup.kofa', target_language=portal_language) ITEM = translate(_('Payment Item'), 'waeup.kofa', target_language=portal_language) AMT = translate(_('Amount (Naira)'), 'waeup.kofa', target_language=portal_language) SSS = translate(_('Payment Session'), 'waeup.kofa', target_language=portal_language) studentview = StudentBasePDFFormPage(self.context.student, self.request, self.omit_fields) students_utils = getUtility(IStudentsUtils) tabledata = [] tableheader = [] tabledata.append(sorted( [value for value in self.context['payments'].values() if value.p_state in ('paid', 'waived')], key=lambda value: value.p_session)) tableheader.append([(P_ID,'p_id', 4.2), #(CD,'creation_date', 3), (PD,'formatted_p_date', 3), (CAT,'category', 3), (ITEM, 'p_item', 3), (AMT, 'amount_auth', 2), (SSS, 'p_session', 2), ]) return students_utils.renderPDF( self, 'financial_clearance_slip.pdf', self.context.student, studentview, tableheader=tableheader, tabledata=tabledata, signatures=None, sigs_in_footer=self._sigsInFooter(), omit_fields=self.omit_fields, note=self.note )