## $Id: browser.py 17942 2024-10-12 11:41:29Z 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
import pytz
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, queryUtility
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,
NigeriaExportPDFFinancialClearancePage,
)
from waeup.uniben.students.interfaces import (
ICustomStudent,
ICustomStudentBase,
ICustomStudentOnlinePayment,
ICustomStudentStudyCourse,
ICustomStudentStudyLevel,
ICustomUGStudentClearance,
ICustomPGStudentClearance,
ICustomStudentPersonal,
ICustomStudentPersonalEdit,
IMedicalHistory,
ITiship,
INYSC,
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')
form_fields[
'final_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',
'finally_cleared_by', 'final_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)
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(_('Sem.'), 'waeup.kofa', target_language=portal_language)
Code = translate(_('Course'), 'waeup.kofa', target_language=portal_language)
Title = translate(_('Subject/Course (Title)'), 'waeup.kofa', target_language=portal_language)
Cred = translate(_('Credit'), '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
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)
class StudentNYSCEditFormPage(KofaEditFormPage):
""" Page to edit NYSC data
"""
grok.context(ICustomStudent)
grok.name('edit_nysc')
grok.require('waeup.handleStudent')
label = _('NYSC Request')
pnav = 4
def update(self):
if not self.context.eligible_for_nysc:
self.flash('You are not allowed to apply for NYSC.',
type="warning")
self.redirect(self.url(self.context))
return
return super(StudentNYSCEditFormPage, self).update()
@property
def form_fields(self):
form_fields = grok.AutoFields(INYSC)
form_fields['nysc_updated'].for_display = True
#form_fields['nysc_senate_info'].for_display = True
form_fields['nysc'].field.description = u'Ensure that all your school charges are paid up to date to your graduating session before making this nysc application.'
form_fields['nysc'].field.title = u'Do you want to apply for NYSC?'
form_fields[
'nysc_updated'].custom_widget = FriendlyDatetimeDisplayWidget('le')
form_fields['nysc'].custom_widget = CustomBooleanRadioWidget
form_fields['nysc_processed'].for_display = True
#form_fields['nysc_senate_info'].field.description = u''
return form_fields
@action(_('Save'), style='primary')
def save(self, **data):
msave(self, **data)
self.context.nysc_updated = datetime.utcnow()
self.context.nysc_processed = False
return
class StudentNYSCManageFormPage(KofaEditFormPage):
""" Page to manage NYSC data
"""
grok.context(ICustomStudent)
grok.name('manage_nysc')
grok.require('waeup.manageStudent')
label = _('Manage NYSC request data')
@property
def form_fields(self):
form_fields = grok.AutoFields(INYSC)
form_fields['nysc_updated'].for_display = True
form_fields['nysc'].field.description = u''
form_fields['nysc'].field.title = u'NYSC requested'
form_fields[
'nysc_updated'].custom_widget = FriendlyDatetimeDisplayWidget('le')
return form_fields
@action(_('Save'), style='primary')
def save(self, **data):
msave(self, **data)
return
class CustomNigeriaExportPDFFinancialClearancePage(NigeriaExportPDFFinancialClearancePage):
"""Deliver a PDF financial clearance slip.
"""
grok.context(ICustomStudent)
@property
def note(self):
if self.context.nysc and self.context.nysc_updated:
nysc_updated = self.context.nysc_updated.strftime('%d/%m/%Y')
return """
NYSC requested on %s.
Senate Info: %s
""" % (nysc_updated, self.context.nysc_senate_info)
else:
return
form_fields = grok.AutoFields(ICustomStudent).select('email2')
omit_fields = (
'suspended', 'phone', 'email', 'parents_email',
'adm_code', 'suspended_comment',
'date_of_birth', 'entry_session', 'current_mode',
'flash_notice')
class StudentAffidavitUploadPage(KofaPage):
"""View to upload scanned affidavit of good behavior by student.
"""
grok.context(ICustomStudent)
grok.name('affidavit_upload')
grok.require('waeup.uploadStudentFile')
grok.template('affidavituploadpage')
label = _('Upload affidavit of good conduct')
deletion_warning = _('Are you sure?')
pnav = 4
class ExportPDFAffidavitSlip(UtilityView, grok.View):
"""Deliver a affidavit PDF template.
"""
grok.context(ICustomStudent)
grok.name('affidavit_good_conduct.pdf')
grok.require('waeup.viewStudent')
prefix = 'form'
omit_fields = ('date_of_birth', 'current_level', 'certificate',
'current_mode', 'entry_session')
form_fields = grok.AutoFields(ICustomStudentBase).select('student_id', 'matric_number', 'reg_number', 'sex')
pre_text = ' '
post_text = '''To undertake as follows:
(i) to abide by the arrangement(s) put in place by the University Management for the
supply, distribution and utilization of electricity on the campuses of the
University of Benin;
(ii) to pay outstanding school charges upon resumption as eligibility for examinations
will henceforth be strictly based on presentation of evidence of payment of approved
school charges;
(iii) not to bring any prohibited appliances, such as hot plate, ring boiler,
gas cooker etc into the Halls of Residence, as violation of this rule shall attract
rustication of such a Student;
(iv) not to be involved in any unruly conduct that is against the Rules and
Regulations of the University; and
(v) to be of good conduct, and not to sponsor or participate in any unauthorized
assembly or demonstration within the campuses and their precincts.
________________________________
(Deponent)
Sworn at ________________________________
This Day ________________________________
Before Me _______________________________
Commissioner of Oaths
'''
@property
def label(self):
portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
return 'Affidavit of Undertaking to be of Good Conduct'
def render(self):
students_utils = getUtility(IStudentsUtils)
letterhead_path = os.path.join(
os.path.dirname(__file__), 'static', 'letterhead.jpg')
if not os.path.exists(letterhead_path):
letterhead_path = None
return students_utils.renderPDFAdmissionLetter(self,
self.context.student, omit_fields=self.omit_fields,
letterhead_path=letterhead_path,
pre_text=self.pre_text, post_text=self.post_text)