## $Id: browser.py 17750 2024-05-06 07:53:03Z 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 import os import csv from datetime import datetime from zope.i18n import translate from zope.security import checkPermission from zope.schema.interfaces import ConstraintNotSatisfied from zope.formlib.textwidgets import BytesDisplayWidget from zope.component import getUtility from hurry.workflow.interfaces import IWorkflowInfo from waeup.kofa.interfaces import ( REQUESTED, IExtFileStore, IKofaUtils, IObjectHistory) from waeup.kofa.widgets.datewidget import FriendlyDatetimeDisplayWidget from waeup.kofa.browser.layout import action, KofaEditFormPage, UtilityView, KofaPage from waeup.kofa.students.browser import ( StudentBaseEditFormPage, StudyLevelEditFormPage, StudyLevelDisplayFormPage, StudentBasePDFFormPage, ExportPDFCourseRegistrationSlip, CourseTicketDisplayFormPage, CourseTicketManageFormPage, StudentTriggerTransitionFormPage, msave, emit_lock_message, StudentActivateView, StudentDeactivateView, ExportPDFTranscriptSlip, PaymentsManageFormPage, StartClearancePage, StudentFilesUploadPage, StudyCourseTranscriptPage, ExportPDFAdmissionSlip) from waeup.kofa.students.workflow import (CREATED, ADMITTED, PAID, CLEARANCE, REQUESTED, RETURNING, CLEARED, REGISTERED, VALIDATED, GRADUATED, TRANSREQ, TRANSVAL, TRANSREL, FORBIDDEN_POSTGRAD_TRANS) from waeup.kofa.students.interfaces import IStudentsUtils, ICourseTicket from waeup.kofa.students.workflow import FORBIDDEN_POSTGRAD_TRANS from kofacustom.nigeria.students.browser import ( NigeriaOnlinePaymentDisplayFormPage, NigeriaStudentBaseManageFormPage, NigeriaStudentClearanceEditFormPage, NigeriaOnlinePaymentAddFormPage, NigeriaExportPDFPaymentSlip, NigeriaExportPDFClearanceSlip, NigeriaExportPDFBedTicketSlip, NigeriaStudentPersonalDisplayFormPage, NigeriaStudentPersonalManageFormPage, NigeriaStudentPersonalEditFormPage, NigeriaAccommodationManageFormPage, NigeriaAccommodationDisplayFormPage, NigeriaStudentBaseDisplayFormPage, NigeriaStudentFilesUploadPage, ) from waeup.uniben.students.interfaces import ( ICustomStudent, ICustomStudentBase, ICustomStudentOnlinePayment, ICustomStudentStudyCourse, ICustomStudentStudyLevel, ICustomUGStudentClearance, ICustomPGStudentClearance, ICustomStudentPersonal, ICustomStudentPersonalEdit, IMedicalHistory, ITiship, ICustomCourseTicket) from waeup.uniben.interfaces import MessageFactory as _ deplinks_path = os.path.join( os.path.dirname(__file__), 'deplinks.csv') reader = csv.DictReader(open(deplinks_path, 'rb')) DEPLINKS = {line['code']:line['url'] for line in reader} class CustomStudentBaseDisplayFormPage(NigeriaStudentBaseDisplayFormPage): """ Page to display student base data """ form_fields = grok.AutoFields(ICustomStudentBase).omit( 'password', 'suspended', 'suspended_comment', 'flash_notice', 'provisionally_cleared', 'parents_email') form_fields[ 'financial_clearance_date'].custom_widget = FriendlyDatetimeDisplayWidget('le') class CustomStudentBaseManageFormPage(NigeriaStudentBaseManageFormPage): """ View to manage student base data """ form_fields = grok.AutoFields(ICustomStudentBase).omit( 'student_id', 'adm_code', 'suspended', 'financially_cleared_by', 'financial_clearance_date', 'parents_email') class CustomOnlinePaymentDisplayFormPage(NigeriaOnlinePaymentDisplayFormPage): """ Page to view an online payment ticket """ grok.context(ICustomStudentOnlinePayment) form_fields = grok.AutoFields(ICustomStudentOnlinePayment).omit( 'provider_amt', 'gateway_amt', 'thirdparty_amt', 'p_item') form_fields[ 'creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le') form_fields[ 'payment_date'].custom_widget = FriendlyDatetimeDisplayWidget('le') class CustomStartClearancePage(StartClearancePage): @property def with_ac(self): if self.context.faccode == 'DCOEM': return False return True @property def portrait_uploaded(self): return True CLEARANCE_FLASH_MESSAGE = """ If you have not presented for physical clearance, scan your WAEC, NECO and other O level results scratch cards on one document and attach to the form below (Scans > O Level Results Scratch Card). Then come back to check for your successful cleared status as from 3 days after successful clearance request. If status is cleared, pay your school charges and proceed to the Dean's Office to collect the signed eligibility form. """ class CustomStudentClearanceEditFormPage(NigeriaStudentClearanceEditFormPage): """ View to edit student clearance data by student """ @property def form_fields(self): if self.context.is_postgrad: form_fields = grok.AutoFields(ICustomPGStudentClearance).omit( 'clearance_locked', 'nysc_location', 'clr_code', 'officer_comment', 'physical_clearance_date') else: form_fields = grok.AutoFields(ICustomUGStudentClearance).omit( 'clearance_locked', 'clr_code', 'officer_comment', 'physical_clearance_date') form_fields['date_of_birth'].for_display = True form_fields['nationality'].for_display = True form_fields['lga'].for_display = True return form_fields def dataNotComplete(self): store = getUtility(IExtFileStore) if self.context.entry_mode in ('ug_ft', 'de_ft') and \ not store.getFileByContext(self.context, attr=u'passport.jpg'): return _('No red background passport picture uploaded.') if not store.getFileByContext(self.context, attr=u'birth_certificate.jpg'): return _('No birth certificate uploaded.') if not store.getFileByContext(self.context, attr=u'ref_let.jpg'): return _('No guarantor/referee letter uploaded.') if not store.getFileByContext(self.context, attr=u'acc_let.jpg'): return _('No acceptance letter uploaded.') if not store.getFileByContext(self.context, attr=u'fst_sit_scan.jpg'): return _('No first sitting result uploaded.') if not store.getFileByContext(self.context, attr=u'secr_cults.jpg'): return _('No affidavit of non-membership of secret cults uploaded.') if not store.getFileByContext(self.context, attr=u'olevel_sc.jpg'): return _('No O level results scratch card uploaded.') return False #def update(self): # self.flash(CLEARANCE_FLASH_MESSAGE, type="warning") # return super(CustomStudentClearanceEditFormPage, self).update() class CustomOnlinePaymentAddFormPage(NigeriaOnlinePaymentAddFormPage): """ Page to add an online payment ticket """ form_fields = grok.AutoFields(ICustomStudentOnlinePayment).select( 'p_combi') class CustomExportPDFPaymentSlip(NigeriaExportPDFPaymentSlip): """Deliver a PDF slip of the context. """ grok.context(ICustomStudentOnlinePayment) form_fields = grok.AutoFields(ICustomStudentOnlinePayment).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 CustomExportPDFClearanceSlip(NigeriaExportPDFClearanceSlip): """Deliver a PDF slip of the context. """ @property def omit_fields(self): omit_fields = ('password', 'suspended', 'suspended_comment', 'phone', 'adm_code', 'email', 'date_of_birth', 'flash_notice') if self.context.is_jupeb: omit_fields += ('faculty', 'department') return omit_fields @property def label(self): portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE line0 = '' if self.context.is_jupeb: line0 = 'Joint Universities Preliminary Examinations Board (JUPEB)\n' line1 = translate(_('Clearance Slip of'), 'waeup.kofa', target_language=portal_language) \ + ' %s' % self.context.display_fullname return '%s%s' % (line0, line1) def _sigsInFooter(self): isStudent = getattr( self.request.principal, 'user_type', None) == 'student' if not isStudent and self.context.state in (CLEARED, RETURNING): return (_('Date, Student Signature'), _('Date, Clearance Officer Signature'), ) return () def render(self): studentview = StudentBasePDFFormPage(self.context.student, self.request, self.omit_fields) students_utils = getUtility(IStudentsUtils) return students_utils.renderPDF( self, 'clearance_slip.pdf', self.context.student, studentview, signatures=self._signatures(), sigs_in_footer=self._sigsInFooter(), show_scans=False, omit_fields=self.omit_fields) class ExportClearanceInvitationSlip(UtilityView, grok.View): """Deliver an invitation letter to physical clearance. This form page is available only in Uniben. """ grok.context(ICustomStudent) grok.name('clearance_invitation_slip.pdf') grok.require('waeup.viewStudent') prefix = 'form' label = u'Invitation Letter for Physical Clearance' omit_fields = ( 'suspended', 'phone', 'email', 'adm_code', 'suspended_comment', 'date_of_birth', 'current_level', 'department', 'current_mode', 'entry_session', 'matric_number', 'sex', 'flash_notice') form_fields = [] @property def note(self): if self.context.physical_clearance_date: return """



Dear %s,


You are invited for your Health Centre clearance on:

%s.

Please bring along your downloaded Health Centre Form to the University Health Centre on your Health Centre clearance date.


Signed,

The Registrar
""" % (self.context.display_fullname, self.context.physical_clearance_date) return def update(self): if self.context.student.state != REQUESTED \ or not self.context.student.physical_clearance_date: self.flash(_('Forbidden'), type="warning") self.redirect(self.url(self.context)) def render(self): studentview = StudentBasePDFFormPage(self.context.student, self.request, self.omit_fields) students_utils = getUtility(IStudentsUtils) return students_utils.renderPDF( self, 'clearance_invitation_slip', self.context.student, studentview, omit_fields=self.omit_fields, note=self.note) class ExportMedicalExaminationSlip(UtilityView, grok.View): """Deliver an . This form page is available only in Uniben. """ grok.context(ICustomStudent) grok.name('medical_examination_slip.pdf') grok.require('waeup.viewStudent') prefix = 'form' label = u'Uniben Medical Examination Form' omit_fields = ( 'suspended', 'adm_code', 'suspended_comment', 'current_level', 'department', 'current_mode', 'entry_session', 'matric_number', 'flash_notice', 'parents_email', 'faculty', 'department') form_fields = grok.AutoFields(ICustomStudentPersonal).select( 'marit_stat', 'perm_address', 'next_kin_phone') form_fields['perm_address'].custom_widget = BytesDisplayWidget def _medicalClearancePaymentMade(self, student, session): if len(student['payments']): for ticket in student['payments'].values(): if ticket.p_state == 'paid' and \ ticket.p_category == 'medical_clearance' and \ ticket.p_session == session: return True return False def update(self): if self.context.student.state != CLEARED \ or not self.context.student.physical_clearance_date: self.flash(_('Forbidden'), type="warning") self.redirect(self.url(self.context)) if not self._medicalClearancePaymentMade( self.context, self.context.current_session): self.flash('Please pay medical clearance fee first.', type="warning") self.redirect(self.url(self.context)) return def render(self): studentview = StudentBasePDFFormPage(self.context.student, self.request, self.omit_fields) students_utils = getUtility(IStudentsUtils) file_path = os.path.join( os.path.dirname(__file__), 'static', 'medical_examination_form.pdf') file = open(file_path, 'rb') mergefiles = [file,] return students_utils.renderPDF( self, 'medical_examination_slip', self.context.student, studentview, omit_fields=self.omit_fields, mergefiles=mergefiles, ) class ExportExaminationScheduleSlip(UtilityView, grok.View): """Deliver a examination schedule slip. This form page is available only in Uniben and AAUE. """ grok.context(ICustomStudent) grok.name('examination_schedule_slip.pdf') grok.require('waeup.viewStudent') prefix = 'form' label = u'Examination Schedule Slip' omit_fields = ( 'suspended', 'phone', 'email', 'adm_code', 'suspended_comment', 'date_of_birth', 'current_level', 'current_mode', 'entry_session', 'flash_notice') form_fields = [] @property def note(self): return """



Your examination date, time and venue is scheduled as follows:

%s
""" % self.context.flash_notice return def update(self): if not self.context.flash_notice \ or not 'exam' in self.context.flash_notice.lower(): self.flash(_('Forbidden'), type="warning") self.redirect(self.url(self.context)) def render(self): studentview = StudentBasePDFFormPage(self.context.student, self.request, self.omit_fields) students_utils = getUtility(IStudentsUtils) return students_utils.renderPDF( self, 'examination_schedule_slip', self.context.student, studentview, omit_fields=self.omit_fields, note=self.note) class SwitchLibraryAccessView(UtilityView, grok.View): """ Switch the library attribute """ grok.context(ICustomStudent) grok.name('switch_library_access') grok.require('waeup.switchLibraryAccess') def update(self): if self.context.library: self.context.library = False self.context.writeLogMessage(self, 'library access disabled') self.flash(_('Library access disabled')) else: self.context.library = True self.context.writeLogMessage(self, 'library access enabled') self.flash(_('Library access enabled')) self.redirect(self.url(self.context)) return def render(self): return class ExportJHLIdCard(UtilityView, grok.View): """Deliver an id card for the John Harris Library. """ grok.context(ICustomStudent) grok.name('jhl_idcard.pdf') grok.require('waeup.viewStudent') prefix = 'form' label = u"John Harris Library Clearance" omit_fields = ( 'suspended', 'email', 'phone', 'adm_code', 'suspended_comment', 'date_of_birth', 'current_mode', 'certificate', 'entry_session', 'flash_notice') form_fields = [] def _sigsInFooter(self): isStudent = getattr( self.request.principal, 'user_type', None) == 'student' if isStudent: return '' return (_("Date, Reader's Signature"), _("Date, Circulation Librarian's Signature"), ) def update(self): if not self.context.library: self.flash(_('Forbidden!'), type="danger") self.redirect(self.url(self.context)) return @property def note(self): return """



This is to certify that the bearer whose photograph and other details appear overleaf is a registered user of John Harris Library, University of Benin. The card is not transferable. A replacement fee is charged for a loss, mutilation or otherwise. If found, please, return to John Harris Library, University of Benin, Benin City. """ return def render(self): studentview = StudentBasePDFFormPage(self.context.student, self.request, self.omit_fields) students_utils = getUtility(IStudentsUtils) return students_utils.renderPDF( self, 'jhl_idcard', self.context.student, studentview, omit_fields=self.omit_fields, sigs_in_footer=self._sigsInFooter(), note=self.note) class ExportJUPEBResultSlip(ExportExaminationScheduleSlip): """Deliver a JUPEB result slip. This form page is available only in Uniben. """ grok.name('jupeb_result_slip.pdf') label = u'JUPEB Result Slip' @property def note(self): return """



%s



Key: A = 5, B = 4, C = 3, D = 2, E = 1, F = 0, X = Absent, Q = Cancelled """ % self.context.flash_notice return def update(self): if not self.context.flash_notice or not self.context.is_jupeb \ or not 'results' in self.context.flash_notice.lower(): self.flash(_('Forbidden'), type="warning") self.redirect(self.url(self.context)) class CustomStudentPersonalDisplayFormPage( NigeriaStudentPersonalDisplayFormPage): """ Page to display student personal data """ form_fields = grok.AutoFields(ICustomStudentPersonal) + grok.AutoFields(ITiship) form_fields['perm_address'].custom_widget = BytesDisplayWidget form_fields['next_kin_address'].custom_widget = BytesDisplayWidget form_fields[ 'personal_updated'].custom_widget = FriendlyDatetimeDisplayWidget('le') class CustomStudentPersonalManageFormPage( NigeriaStudentPersonalManageFormPage): """ Page to manage personal data """ form_fields = grok.AutoFields(ICustomStudentPersonal) + grok.AutoFields(ITiship) form_fields['personal_updated'].for_display = True form_fields[ 'personal_updated'].custom_widget = FriendlyDatetimeDisplayWidget('le') class CstomStudentPersonalEditFormPage(NigeriaStudentPersonalEditFormPage): """ Page to edit personal data """ @property def form_fields(self): form_fields = grok.AutoFields( ICustomStudentPersonalEdit).omit('personal_updated') + grok.AutoFields(ITiship) studycourse = self.context['studycourse'] certificate = getattr(studycourse,'certificate',None) current_level = studycourse.current_level end_level = certificate.end_level if not self.context.current_level >= end_level: form_fields = form_fields.omit('nysc') return form_fields class StudyCourseCOEditFormPage(KofaEditFormPage): """ Page to edit the student study course data by clearance officers. This form page is available only in Uniben. """ grok.context(ICustomStudentStudyCourse) grok.name('edit_level') grok.require('waeup.clearStudent') label = _('Edit current level') pnav = 4 form_fields = grok.AutoFields( ICustomStudentStudyCourse).select('current_level') def update(self): if not (self.context.is_current and self.context.student.state == REQUESTED): emit_lock_message(self) return super(StudyCourseCOEditFormPage, self).update() return @action(_('Save'), style='primary') def save(self, **data): try: msave(self, **data) except ConstraintNotSatisfied: # The selected level might not exist in certificate self.flash(_('Current level not available for certificate.')) return #notify(grok.ObjectModifiedEvent(self.context.__parent__)) return class CustomStudyLevelEditFormPage(StudyLevelEditFormPage): """ Page to edit the student study level data by students. """ grok.template('studyleveleditpage') class CustomStudyLevelDisplayFormPage(StudyLevelDisplayFormPage): """ Page to display student study levels """ grok.template('studylevelpage') @property def view_scores_allowed(self): return checkPermission('waeup.manageStudent', self.context) class CustomExportPDFCourseRegistrationSlip( ExportPDFCourseRegistrationSlip): """Deliver a PDF slip of the context. """ form_fields = grok.AutoFields(ICustomStudentStudyLevel).omit( 'level_verdict', 'gpa', 'level', 'transcript_remark') def update(self): if self.context.student.state != REGISTERED \ or self.context.student.current_level != self.context.level: self.flash(_('Forbidden'), type="warning") self.redirect(self.url(self.context)) @property def tabletitle(self): portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE tabletitle = [] tabletitle.append(translate(_('1st Semester Courses'), 'waeup.kofa', target_language=portal_language)) tabletitle.append(translate(_('2nd Semester Courses'), 'waeup.kofa', target_language=portal_language)) tabletitle.append(translate(_('Level Courses'), 'waeup.kofa', target_language=portal_language)) tabletitle.append(translate(_('1st Trimester Courses'), 'waeup.kofa', target_language=portal_language)) tabletitle.append(translate(_('2nd Trimester Courses'), 'waeup.kofa', target_language=portal_language)) tabletitle.append(translate(_('3rd Trimester Courses'), 'waeup.kofa', target_language=portal_language)) return tabletitle def render(self): portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE Code = translate('Code', 'waeup.kofa', target_language=portal_language) Title = translate('Title', 'waeup.kofa', target_language=portal_language) Dept = translate('Dept.', 'waeup.kofa', target_language=portal_language) Faculty = translate('Faculty', 'waeup.kofa', target_language=portal_language) Cred = translate(_('Credits'), 'waeup.uniben', target_language=portal_language) studentview = StudentBasePDFFormPage(self.context.student, self.request, self.omit_fields) students_utils = getUtility(IStudentsUtils) tabledata = [] tableheader = [] for i in range(1,7): tabledata.append(sorted( [value for value in self.context.values() if value.semester == i], key=lambda value: str(value.semester) + value.code)) tableheader.append([(Code,'code', 2.5), (Title,'title', 5), (Dept,'dcode', 1.5), (Faculty,'fcode', 1.5), (Cred, 'credits', 1.5), ]) return students_utils.renderPDF( self, 'course_registration_slip.pdf', self.context.student, studentview, tableheader=tableheader, tabledata=tabledata, omit_fields=self.omit_fields ) class ExportPDFCourseResultSlip(ExportPDFCourseRegistrationSlip): """Deliver a PDF slip of the context. """ grok.name('course_result_slip.pdf') form_fields = grok.AutoFields(ICustomStudentStudyLevel).omit('level') @property def tabletitle(self): portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE tabletitle = [] tabletitle.append(translate(_('1st Semester Courses'), 'waeup.kofa', target_language=portal_language)) tabletitle.append(translate(_('2nd Semester Courses'), 'waeup.kofa', target_language=portal_language)) tabletitle.append(translate(_('Level Courses'), 'waeup.kofa', target_language=portal_language)) tabletitle.append(translate(_('1st Trimester Courses'), 'waeup.kofa', target_language=portal_language)) tabletitle.append(translate(_('2nd Trimester Courses'), 'waeup.kofa', target_language=portal_language)) tabletitle.append(translate(_('3rd Trimester Courses'), 'waeup.kofa', target_language=portal_language)) return tabletitle @property def label(self): portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE lang = self.request.cookies.get('kofa.language', portal_language) level_title = translate(self.context.level_title, 'waeup.kofa', target_language=lang) return translate(_('Course Result Slip'), 'waeup.uniben', target_language=portal_language) \ + ' %s' % level_title def render(self): portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE Code = translate('Code', 'waeup.kofa', target_language=portal_language) Title = translate('Title', 'waeup.kofa', target_language=portal_language) Dept = translate('Dept.', 'waeup.kofa', target_language=portal_language) Faculty = translate('Faculty', 'waeup.kofa', target_language=portal_language) Cred = translate(_('Credits'), 'waeup.uniben', target_language=portal_language) Grade = translate('Grade', 'waeup.kofa', target_language=portal_language) studentview = StudentBasePDFFormPage(self.context.student, self.request, self.omit_fields) students_utils = getUtility(IStudentsUtils) tabledata = [] tableheader = [] for i in range(1,7): tabledata.append(sorted( [value for value in self.context.values() if value.semester == i], key=lambda value: str(value.semester) + value.code)) tableheader.append([(Code,'code', 2.5), (Title,'title', 5), (Dept,'dcode', 1.5), (Faculty,'fcode', 1.5), (Cred, 'credits', 1.5), (Grade, 'grade', 1.5), ]) return students_utils.renderPDF( self, 'course_result_slip.pdf', self.context.student, studentview, tableheader=tableheader, tabledata=tabledata, omit_fields=self.omit_fields ) class CustomCourseTicketDisplayFormPage(CourseTicketDisplayFormPage): """ Page to display course tickets """ form_fields = grok.AutoFields(ICustomCourseTicket).omit('score') class CustomCourseTicketManageFormPage(CourseTicketManageFormPage): """ Page to manage course tickets """ form_fields = grok.AutoFields(ICustomCourseTicket).omit('course_category') form_fields['title'].for_display = True form_fields['fcode'].for_display = True form_fields['dcode'].for_display = True form_fields['semester'].for_display = True form_fields['passmark'].for_display = True form_fields['credits'].for_display = True form_fields['mandatory'].for_display = False form_fields['automatic'].for_display = True form_fields['carry_over'].for_display = True form_fields['ticket_session'].for_display = True class CustomStudentActivateView(StudentActivateView): """ Activate student account """ def update(self): self.context.suspended = False self.context.writeLogMessage(self, 'account activated') history = IObjectHistory(self.context) history.addMessage('Student account activated', user='undisclosed') self.flash(_('Student account has been activated.')) self.redirect(self.url(self.context)) return class CustomStudentDeactivateView(StudentDeactivateView): """ Deactivate student account """ def update(self): self.context.suspended = True self.context.writeLogMessage(self, 'account deactivated') history = IObjectHistory(self.context) history.addMessage('Student account deactivated', user='undisclosed') self.flash(_('Student account has been deactivated.')) self.redirect(self.url(self.context)) return class CustomStudyCourseTranscriptPage(StudyCourseTranscriptPage): """ Page to display the student's transcript. """ # grok.require('waeup.viewStudent') class CustomExportPDFTranscriptSlip(ExportPDFTranscriptSlip): """Deliver a PDF slip of the context. """ # grok.require('waeup.viewStudent') def _sigsInFooter(self): isStudent = getattr( self.request.principal, 'user_type', None) == 'student' if not isStudent and self.context.student.state in (TRANSVAL, TRANSREL): return (_('D. R. (Exams & Records)'),_('Current Dean of Faculty'),) return () #def _signatures(self): # return ([( # 'Current HD
D. R. (Exams & Records)
' # 'For: Registrar')],) def render(self): portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE Term = translate(_('Term'), 'waeup.kofa', target_language=portal_language) Code = translate(_('Code'), 'waeup.kofa', target_language=portal_language) Title = translate(_('Title'), 'waeup.kofa', target_language=portal_language) Cred = translate(_('Credits'), 'waeup.kofa', target_language=portal_language) #Score = translate(_('Score'), 'waeup.kofa', target_language=portal_language) Grade = translate(_('Grade'), 'waeup.kofa', target_language=portal_language) studentview = StudentBasePDFFormPage(self.context.student, self.request, self.omit_fields) students_utils = getUtility(IStudentsUtils) tableheader = [(Code,'code', 2.5), (Title,'title', 8.5), (Term, 'semester', 1.5), (Cred, 'credits', 1.5), #(Score, 'score', 1.5), (Grade, 'grade', 1.5), ] pdfstream = students_utils.renderPDFTranscript( self, 'transcript.pdf', self.context.student, studentview, omit_fields=self.omit_fields, tableheader=tableheader, signatures=self._signatures(), sigs_in_footer=self._sigsInFooter(), digital_sigs=self._digital_sigs(), save_file=self._save_file(), ) if not pdfstream: self.redirect(self.url(self.context.student)) return return pdfstream class CustomExportPDFBedTicketSlip(NigeriaExportPDFBedTicketSlip): """Deliver a PDF slip of the context. """ omit_fields = ('password', 'suspended', 'suspended_comment', 'phone', 'adm_code', 'email', 'date_of_birth', 'flash_notice') class CustomPaymentsManageFormPage(PaymentsManageFormPage): """ Page to manage the student payments. This manage form page is for both students and students officers. Uniben does not allow students to remove any payment ticket. """ @property def manage_payments_allowed(self): return checkPermission('waeup.manageStudent', self.context) class CustomAccommodationDisplayFormPage(NigeriaAccommodationDisplayFormPage): """ Page to view bed tickets. """ with_hostel_selection = True class CustomAccommodationManageFormPage(NigeriaAccommodationManageFormPage): """ Page to manage bed tickets. This manage form page is for both students and students officers. """ with_hostel_selection = True class CustomStudentBaseEditFormPage(StudentBaseEditFormPage): """ View to edit student base data """ form_fields = grok.AutoFields(ICustomStudentBase).select( 'email', 'phone') form_fields['email'].field.required = True class CustomStudentFilesUploadPage(NigeriaStudentFilesUploadPage): """ View to upload passport picture. """ def update(self): # Postgrad students should allowed to change their picture whenever they want. if self.context.is_postgrad: return if self.context.is_jupeb: emit_lock_message(self) return super(StudentFilesUploadPage, self).update() return from zope.schema.vocabulary import SimpleVocabulary from zope.formlib.itemswidgets import RadioWidget from zope.formlib.itemswidgets import SelectWidget, DropdownWidget def CustomBooleanRadioWidget(field, request, true=_('yes'), false=_('no')): vocabulary = SimpleVocabulary.fromItems( ((true, True), (false, False)) ) widget = RadioWidget(field, vocabulary, request) widget.required = False return widget class StudentMedicalHistoryEditFormPage(KofaEditFormPage): """ Page to edit medical data """ grok.context(ICustomStudent) grok.name('edit_medical') grok.require('waeup.handleStudent') label = _('Medical Questionnaire') pnav = 4 def _medicalQuestPaymentMade(self, student, session): if len(student['payments']): for ticket in student['payments'].values(): if ticket.p_state == 'paid' and \ ticket.p_category == 'medical_quest' and \ ticket.p_session == session: return True return False def update(self): if not self._medicalQuestPaymentMade( self.context, self.context.current_session): self.flash('Please pay medical questionnaire payment first.', type="warning") self.redirect(self.url(self.context)) return return super(StudentMedicalHistoryEditFormPage, self).update() @property def form_fields(self): form_fields = grok.AutoFields(IMedicalHistory) + grok.AutoFields(ITiship) form_fields['medical_updated'].for_display = True for field in ('fever', 'headaches', 'catarrh', 'cough', 'sore_throat', 'breathing', 'sneezing', 'weakness', 'body_pains', 'smell', 'taste', 'asthma', 'hypertension', 'diabetes', 'obesity', 'lagos_abuja', 'outside', 'company_suspected', 'company_confirmed', 'positive', 'negative', 'vaccination'): form_fields[field].custom_widget = CustomBooleanRadioWidget return form_fields @property def separators(self): return getUtility(IStudentsUtils).SEPARATORS_DICT @action(_('Save/Confirm'), style='primary') def save(self, **data): msave(self, **data) self.context.medical_updated = datetime.utcnow() return class StudentMedicalHistoryManageFormPage(StudentMedicalHistoryEditFormPage): """ Page to manage medical data """ grok.name('manage_medical') grok.require('waeup.manageStudent') label = _('Manage medical questionnaire data') def update(self): return super(StudentMedicalHistoryEditFormPage, self).update() class ExportPDFMedicalHistorySlip(grok.View): """Deliver a PDF slip of the context. """ grok.context(ICustomStudent) grok.name('medical_questionnaire_slip.pdf') grok.require('waeup.viewStudent') prefix = 'form' form_fields = grok.AutoFields(IMedicalHistory) omit_fields = ('password', 'suspended', 'suspended_comment', 'adm_code', 'date_of_birth', 'flash_notice', 'current_mode', 'entry_mode', 'entry_session', 'parents_email', 'current_level', 'reg_number', 'sex', 'certificate') @property def title(self): portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE return translate(_('Medical Questionnaire'), 'waeup.kofa', target_language=portal_language) @property def label(self): portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE return translate(_('Medical Questionnaire Slip of'), 'waeup.kofa', target_language=portal_language) \ + ' %s' % self.context.display_fullname def render(self): studentview = StudentBasePDFFormPage(self.context.student, self.request, self.omit_fields) students_utils = getUtility(IStudentsUtils) return students_utils.renderPDF( self, 'medical_questionnaire_slip.pdf', self.context.student, studentview, omit_fields=self.omit_fields,) class ExportPDFTishipSlip(grok.View): """Deliver a PDF slip of the context. """ grok.context(ICustomStudent) grok.name('tiship_slip.pdf') grok.require('waeup.viewStudent') prefix = 'form' form_fields = grok.AutoFields(ITiship) title = '' omit_fields = ('password', 'suspended', 'suspended_comment', 'adm_code', 'flash_notice', 'current_mode', 'entry_mode', 'parents_email', ) @property def label(self): portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE return translate(_('TISHIP Registration Slip of'), 'waeup.kofa', target_language=portal_language) \ + ' %s' % self.context.display_fullname def _sigsInFooter(self): return (_('Year of Graduation'), _('Signature'), _('Date'), ) def render(self): studentview = StudentBasePDFFormPage(self.context.student, self.request, self.omit_fields) students_utils = getUtility(IStudentsUtils) return students_utils.renderPDF( self, 'tiship_slip.pdf', self.context.student, studentview, sigs_in_footer=self._sigsInFooter(), omit_fields=self.omit_fields,) class PlagTestInfoPage(KofaPage): "Landing page after plagiation test payment" grok.context(ICustomStudentOnlinePayment) grok.name('plagtestinfo') grok.require('waeup.viewStudent') def update(self): if self.context.p_state != 'paid' \ or self.context.p_category != 'plag_test': self.flash(_('Forbidden'), type="danger") self.redirect(self.url(self.context)) return super(PlagTestInfoPage, self).update() @property def facdep(self): facdepkey = "%s-%s" % (self.context.student.faccode, self.context.student.depcode) return DEPLINKS[facdepkey] class CustomExportPDFAdmissionSlip(ExportPDFAdmissionSlip): """Deliver a PDF Admission slip. """ @property def post_text_pt(self): datelist = self.context.history.messages[0].split()[0].split('-') creation_date = u'%s/%s/%s' % (datelist[2], datelist[1], datelist[0]) return ( 'Your Kofa student record was created on %s.

' 'Please Note: This admission for ' 'Undergraduate Part-Time and Undergraduate Sandwich is incomplete ' 'until you have successfully applied on the JAMB CAPS PORTAL. ' 'Ignore this if you have completed your own pre-admission ' 'activities on the JAMB website.' % creation_date) def render(self): students_utils = getUtility(IStudentsUtils) letterhead_path = os.path.join( os.path.dirname(__file__), 'static', 'letterhead_admission.jpg') if not os.path.exists(letterhead_path): letterhead_path = None if self.context.current_mode in ('ug_pt', 'ug_sw'): return students_utils.renderPDFAdmissionLetter(self, self.context.student, omit_fields=self.omit_fields, letterhead_path=letterhead_path, post_text=self.post_text_pt) return students_utils.renderPDFAdmissionLetter(self, self.context.student, omit_fields=self.omit_fields, letterhead_path=letterhead_path, post_text=None)