source: main/waeup.uniben/trunk/src/waeup/uniben/students/browser.py @ 16369

Last change on this file since 16369 was 16364, checked in by Henrik Bettermann, 4 years ago

Rename WAEC Results.

  • Property svn:keywords set to Id
File size: 29.0 KB
Line 
1## $Id: browser.py 16364 2021-01-11 14:48:41Z henrik $
2##
3## Copyright (C) 2012 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
18import grok
19from zope.i18n import translate
20from zope.security import checkPermission
21from zope.schema.interfaces import ConstraintNotSatisfied
22from zope.formlib.textwidgets import BytesDisplayWidget
23from zope.component import getUtility
24from hurry.workflow.interfaces import IWorkflowInfo
25from waeup.kofa.interfaces import (
26    REQUESTED, IExtFileStore, IKofaUtils, IObjectHistory)
27from waeup.kofa.widgets.datewidget import FriendlyDatetimeDisplayWidget
28from waeup.kofa.browser.layout import action, KofaEditFormPage, UtilityView
29from waeup.kofa.students.browser import (
30    StudentBaseEditFormPage,
31    StudyLevelEditFormPage, StudyLevelDisplayFormPage,
32    StudentBasePDFFormPage, ExportPDFCourseRegistrationSlip,
33    CourseTicketDisplayFormPage, StudentTriggerTransitionFormPage,
34    msave, emit_lock_message,
35    StudentActivateView, StudentDeactivateView,
36    ExportPDFTranscriptSlip,
37    PaymentsManageFormPage,
38    StartClearancePage)
39from waeup.kofa.students.workflow import (CREATED, ADMITTED, PAID,
40    CLEARANCE, REQUESTED, RETURNING, CLEARED, REGISTERED, VALIDATED,
41    GRADUATED, TRANSREQ, TRANSVAL, TRANSREL, FORBIDDEN_POSTGRAD_TRANS)
42from waeup.kofa.students.interfaces import IStudentsUtils, ICourseTicket
43from waeup.kofa.students.workflow import FORBIDDEN_POSTGRAD_TRANS
44from kofacustom.nigeria.students.browser import (
45    NigeriaOnlinePaymentDisplayFormPage,
46    NigeriaStudentBaseManageFormPage,
47    NigeriaStudentClearanceEditFormPage,
48    NigeriaOnlinePaymentAddFormPage,
49    NigeriaExportPDFPaymentSlip,
50    NigeriaExportPDFClearanceSlip,
51    NigeriaExportPDFBedTicketSlip,
52    NigeriaStudentPersonalDisplayFormPage,
53    NigeriaStudentPersonalManageFormPage,
54    NigeriaStudentPersonalEditFormPage,
55    NigeriaAccommodationManageFormPage,
56    NigeriaAccommodationDisplayFormPage,
57    NigeriaStudentBaseDisplayFormPage,
58    NigeriaStudentFilesUploadPage,
59    )
60
61from waeup.uniben.students.interfaces import (
62    ICustomStudent,
63    ICustomStudentBase,
64    ICustomStudentOnlinePayment,
65    ICustomStudentStudyCourse,
66    ICustomStudentStudyLevel,
67    ICustomUGStudentClearance,
68    ICustomPGStudentClearance,
69    ICustomStudentPersonal,
70    ICustomStudentPersonalEdit)
71from waeup.uniben.interfaces import MessageFactory as _
72
73class CustomStudentBaseDisplayFormPage(NigeriaStudentBaseDisplayFormPage):
74    """ Page to display student base data
75    """
76    form_fields = grok.AutoFields(ICustomStudentBase).omit(
77        'password', 'suspended', 'suspended_comment',
78        'flash_notice', 'provisionally_cleared', 'parents_email')
79    form_fields[
80        'financial_clearance_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
81
82class CustomStudentBaseManageFormPage(NigeriaStudentBaseManageFormPage):
83    """ View to manage student base data
84    """
85    form_fields = grok.AutoFields(ICustomStudentBase).omit(
86        'student_id', 'adm_code', 'suspended',
87        'financially_cleared_by', 'financial_clearance_date',
88        'parents_email')
89
90class CustomOnlinePaymentDisplayFormPage(NigeriaOnlinePaymentDisplayFormPage):
91    """ Page to view an online payment ticket
92    """
93    grok.context(ICustomStudentOnlinePayment)
94    form_fields = grok.AutoFields(ICustomStudentOnlinePayment).omit(
95        'provider_amt', 'gateway_amt', 'thirdparty_amt', 'p_item')
96    form_fields[
97        'creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
98    form_fields[
99        'payment_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
100
101class CustomStartClearancePage(StartClearancePage):
102
103    @property
104    def with_ac(self):
105        if self.context.faccode == 'DCOEM':
106            return False
107        return True
108
109
110CLEARANCE_FLASH_MESSAGE = """
111If you have not presented for physical clearance, scan your WAEC, NECO
112and other O level results scratch cards on one document and
113attach to the form below (Scans > O Level Results Scratch Card).
114Then come back to check for your successful cleared status as from 3 days
115after successful clearance request.
116If status is cleared, pay your school charges and proceed to the
117Dean's Office to collect the signed eligibility form.
118"""
119
120class CustomStudentClearanceEditFormPage(NigeriaStudentClearanceEditFormPage):
121    """ View to edit student clearance data by student
122    """
123
124    @property
125    def form_fields(self):
126        if self.context.is_postgrad:
127            form_fields = grok.AutoFields(ICustomPGStudentClearance).omit(
128            'clearance_locked', 'nysc_location', 'clr_code', 'officer_comment',
129            'physical_clearance_date')
130        else:
131            form_fields = grok.AutoFields(ICustomUGStudentClearance).omit(
132            'clearance_locked', 'clr_code', 'officer_comment',
133            'physical_clearance_date')
134            form_fields['date_of_birth'].for_display = True
135            form_fields['nationality'].for_display = True
136            form_fields['lga'].for_display = True
137        return form_fields
138
139    def dataNotComplete(self):
140        store = getUtility(IExtFileStore)
141        if not store.getFileByContext(self.context, attr=u'birth_certificate.jpg'):
142            return _('No birth certificate uploaded.')
143        if not store.getFileByContext(self.context, attr=u'ref_let.jpg'):
144            return _('No guarantor/referee letter uploaded.')
145        if not store.getFileByContext(self.context, attr=u'acc_let.jpg'):
146            return _('No acceptance letter uploaded.')
147        if not store.getFileByContext(self.context, attr=u'fst_sit_scan.jpg'):
148            return _('No first sitting result uploaded.')
149        #if not store.getFileByContext(self.context, attr=u'scd_sit_scan.jpg'):
150        #    return _('No second sitting result uploaded.')
151        if not store.getFileByContext(self.context, attr=u'secr_cults.jpg'):
152            return _('No affidavit of non-membership of secret cults uploaded.')
153        return False
154
155    def update(self):
156        self.flash(CLEARANCE_FLASH_MESSAGE, type="warning")
157        return super(CustomStudentClearanceEditFormPage, self).update()
158
159class CustomOnlinePaymentAddFormPage(NigeriaOnlinePaymentAddFormPage):
160    """ Page to add an online payment ticket
161    """
162    form_fields = grok.AutoFields(ICustomStudentOnlinePayment).select(
163        'p_combi')
164
165class CustomExportPDFPaymentSlip(NigeriaExportPDFPaymentSlip):
166    """Deliver a PDF slip of the context.
167    """
168    grok.context(ICustomStudentOnlinePayment)
169    form_fields = grok.AutoFields(ICustomStudentOnlinePayment).omit(
170        'provider_amt', 'gateway_amt', 'thirdparty_amt', 'p_item', 'p_combi')
171    form_fields['creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
172    form_fields['payment_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
173
174
175class CustomExportPDFClearanceSlip(NigeriaExportPDFClearanceSlip):
176    """Deliver a PDF slip of the context.
177    """
178
179    @property
180    def omit_fields(self):
181        omit_fields = ('password', 'suspended', 'suspended_comment',
182                       'phone', 'adm_code', 'email', 'date_of_birth',
183                       'flash_notice')
184        if self.context.is_jupeb:
185            omit_fields += ('faculty', 'department')
186        return omit_fields
187
188    @property
189    def label(self):
190        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
191        line0 = ''
192        if self.context.is_jupeb:
193            line0 = 'Joint Universities Preliminary Examinations Board (JUPEB)\n'
194        line1 = translate(_('Clearance Slip of'),
195            'waeup.kofa', target_language=portal_language) \
196            + ' %s' % self.context.display_fullname
197        return '%s%s' % (line0, line1)
198
199    def _sigsInFooter(self):
200        isStudent = getattr(
201            self.request.principal, 'user_type', None) == 'student'
202        if not isStudent and self.context.state in (CLEARED, RETURNING):
203            return (_('Date, Student Signature'),
204                    _('Date, Clearance Officer Signature'),
205                    )
206        return ()
207
208    def render(self):
209        studentview = StudentBasePDFFormPage(self.context.student,
210            self.request, self.omit_fields)
211        students_utils = getUtility(IStudentsUtils)
212        return students_utils.renderPDF(
213            self, 'clearance_slip.pdf',
214            self.context.student, studentview, signatures=self._signatures(),
215            sigs_in_footer=self._sigsInFooter(), show_scans=False,
216            omit_fields=self.omit_fields)
217
218
219class ExportClearanceInvitationSlip(UtilityView, grok.View):
220    """Deliver an invitation letter to physical clearance.
221
222    This form page is available only in Uniben.
223    """
224    grok.context(ICustomStudent)
225    grok.name('clearance_invitation_slip.pdf')
226    grok.require('waeup.viewStudent')
227    prefix = 'form'
228
229    label = u'Invitation Letter for Physical Clearance'
230
231    omit_fields = (
232        'suspended', 'phone', 'email',
233        'adm_code', 'suspended_comment',
234        'date_of_birth', 'current_level',
235        'department', 'current_mode',
236        'entry_session', 'matric_number', 'sex',
237        'flash_notice')
238
239    form_fields = []
240
241    @property
242    def note(self):
243        if self.context.physical_clearance_date:
244            return """
245<br /><br /><br /><br /><font size='12'>
246Dear %s,
247<br /><br /><br />
248You are invited for your physical clearance on:
249<br /><br />
250<strong>%s</strong>.
251<br /><br />
252Please bring along this letter of invitation to the University Main Auditorium
253<br /><br />
254on your clearance date.
255<br /><br /><br />
256Signed,
257<br /><br />
258The Registrar<br />
259</font>
260
261""" % (self.context.display_fullname, self.context.physical_clearance_date)
262        return
263
264
265    def update(self):
266        if self.context.student.state != REQUESTED \
267            or not  self.context.student.physical_clearance_date:
268            self.flash(_('Forbidden'), type="warning")
269            self.redirect(self.url(self.context))
270
271    def render(self):
272        studentview = StudentBasePDFFormPage(self.context.student,
273            self.request, self.omit_fields)
274        students_utils = getUtility(IStudentsUtils)
275        return students_utils.renderPDF(
276            self, 'clearance_invitation_slip',
277            self.context.student, studentview,
278            omit_fields=self.omit_fields,
279            note=self.note)
280
281class ExportExaminationScheduleSlip(UtilityView, grok.View):
282    """Deliver a examination schedule slip.
283
284    This form page is available only in Uniben and AAUE.
285    """
286    grok.context(ICustomStudent)
287    grok.name('examination_schedule_slip.pdf')
288    grok.require('waeup.viewStudent')
289    prefix = 'form'
290
291    label = u'Examination Schedule Slip'
292
293    omit_fields = (
294        'suspended', 'phone', 'email',
295        'adm_code', 'suspended_comment',
296        'date_of_birth', 'current_level',
297        'current_mode',
298        'entry_session',
299        'flash_notice')
300
301    form_fields = []
302
303    @property
304    def note(self):
305        return """
306<br /><br /><br /><br /><font size='12'>
307Your examination date, time and venue is scheduled as follows:
308<br /><br />
309<strong>%s</strong>
310</font>
311
312""" % self.context.flash_notice
313        return
314
315
316    def update(self):
317        if not self.context.flash_notice \
318            or not 'exam' in self.context.flash_notice.lower():
319            self.flash(_('Forbidden'), type="warning")
320            self.redirect(self.url(self.context))
321
322    def render(self):
323        studentview = StudentBasePDFFormPage(self.context.student,
324            self.request, self.omit_fields)
325        students_utils = getUtility(IStudentsUtils)
326        return students_utils.renderPDF(
327            self, 'examination_schedule_slip',
328            self.context.student, studentview,
329            omit_fields=self.omit_fields,
330            note=self.note)
331
332class SwitchLibraryAccessView(UtilityView, grok.View):
333    """ Switch the library attribute
334    """
335    grok.context(ICustomStudent)
336    grok.name('switch_library_access')
337    grok.require('waeup.switchLibraryAccess')
338
339    def update(self):
340        if self.context.library:
341            self.context.library = False
342            self.context.writeLogMessage(self, 'library access disabled')
343            self.flash(_('Library access disabled'))
344        else:
345            self.context.library = True
346            self.context.writeLogMessage(self, 'library access enabled')
347            self.flash(_('Library access enabled'))
348        self.redirect(self.url(self.context))
349        return
350
351    def render(self):
352        return
353
354class ExportJHLIdCard(UtilityView, grok.View):
355    """Deliver an id card for the John Harris Library.
356    """
357    grok.context(ICustomStudent)
358    grok.name('jhl_idcard.pdf')
359    grok.require('waeup.viewStudent')
360    prefix = 'form'
361
362    label = u"John Harris Library Clearance"
363
364    omit_fields = (
365        'suspended', 'email', 'phone',
366        'adm_code', 'suspended_comment',
367        'date_of_birth',
368        'current_mode', 'certificate',
369        'entry_session',
370        'flash_notice')
371
372    form_fields = []
373
374    def _sigsInFooter(self):
375        isStudent = getattr(
376            self.request.principal, 'user_type', None) == 'student'
377        if isStudent:
378            return ''
379        return (_("Date, Reader's Signature"),
380                _("Date, Circulation Librarian's Signature"),
381                )
382
383    def update(self):
384        if not self.context.library:
385            self.flash(_('Forbidden!'), type="danger")
386            self.redirect(self.url(self.context))
387        return
388
389    @property
390    def note(self):
391        return """
392<br /><br /><br /><br /><font size='12'>
393This is to certify that the bearer whose photograph and other details appear
394 overleaf is a registered user of <b>John Harris Library, University of Benin</b>.
395 The card is not transferable. A replacement fee is charged for a loss,
396 mutilation or otherwise. If found, please, return to John Harris Library,
397 University of Benin, Benin City.
398</font>
399
400"""
401        return
402
403    def render(self):
404        studentview = StudentBasePDFFormPage(self.context.student,
405            self.request, self.omit_fields)
406        students_utils = getUtility(IStudentsUtils)
407        return students_utils.renderPDF(
408            self, 'jhl_idcard',
409            self.context.student, studentview,
410            omit_fields=self.omit_fields,
411            sigs_in_footer=self._sigsInFooter(),
412            note=self.note)
413
414class ExportJUPEBResultSlip(ExportExaminationScheduleSlip):
415    """Deliver a JUPEB result slip.
416
417    This form page is available only in Uniben.
418    """
419
420    grok.name('jupeb_result_slip.pdf')
421    label = u'JUPEB Result Slip'
422
423    @property
424    def note(self):
425        return """
426<br /><br /><br /><br /><font size='12'>
427<strong>%s</strong>
428</font>
429<br /><br /><br /><br />
430<font size='8'>
431Key: A = 5, B = 4, C = 3, D = 2, E = 1, F = 0, X = Absent, Q = Cancelled
432</font>
433
434""" % self.context.flash_notice
435        return
436
437    def update(self):
438        if not self.context.flash_notice or not self.context.is_jupeb \
439            or not 'results' in self.context.flash_notice.lower():
440            self.flash(_('Forbidden'), type="warning")
441            self.redirect(self.url(self.context))
442
443class CustomStudentPersonalDisplayFormPage(
444    NigeriaStudentPersonalDisplayFormPage):
445    """ Page to display student personal data
446    """
447
448    form_fields = grok.AutoFields(ICustomStudentPersonal)
449    form_fields['perm_address'].custom_widget = BytesDisplayWidget
450    form_fields['next_kin_address'].custom_widget = BytesDisplayWidget
451    form_fields[
452        'personal_updated'].custom_widget = FriendlyDatetimeDisplayWidget('le')
453
454class CustomStudentPersonalManageFormPage(
455    NigeriaStudentPersonalManageFormPage):
456    """ Page to manage personal data
457    """
458
459    form_fields = grok.AutoFields(ICustomStudentPersonal)
460    form_fields['personal_updated'].for_display = True
461    form_fields[
462        'personal_updated'].custom_widget = FriendlyDatetimeDisplayWidget('le')
463
464class CstomStudentPersonalEditFormPage(NigeriaStudentPersonalEditFormPage):
465    """ Page to edit personal data
466    """
467    form_fields = grok.AutoFields(
468        ICustomStudentPersonalEdit).omit('personal_updated')
469
470class StudyCourseCOEditFormPage(KofaEditFormPage):
471    """ Page to edit the student study course data by clearance officers.
472
473    This form page is available only in Uniben.
474    """
475    grok.context(ICustomStudentStudyCourse)
476    grok.name('edit_level')
477    grok.require('waeup.clearStudent')
478    label = _('Edit current level')
479    pnav = 4
480    form_fields = grok.AutoFields(
481        ICustomStudentStudyCourse).select('current_level')
482
483    def update(self):
484        if not (self.context.is_current and
485            self.context.student.state == REQUESTED):
486            emit_lock_message(self)
487            return
488        super(StudyCourseCOEditFormPage, self).update()
489        return
490
491    @action(_('Save'), style='primary')
492    def save(self, **data):
493        try:
494            msave(self, **data)
495        except ConstraintNotSatisfied:
496            # The selected level might not exist in certificate
497            self.flash(_('Current level not available for certificate.'))
498            return
499        #notify(grok.ObjectModifiedEvent(self.context.__parent__))
500        return
501
502class CustomStudyLevelEditFormPage(StudyLevelEditFormPage):
503    """ Page to edit the student study level data by students.
504
505    """
506    grok.template('studyleveleditpage')
507
508class CustomStudyLevelDisplayFormPage(StudyLevelDisplayFormPage):
509    """ Page to display student study levels
510    """
511    grok.template('studylevelpage')
512
513class CustomExportPDFCourseRegistrationSlip(
514    ExportPDFCourseRegistrationSlip):
515    """Deliver a PDF slip of the context.
516    """
517
518    form_fields = grok.AutoFields(ICustomStudentStudyLevel).omit(
519        'level_verdict', 'gpa', 'level', 'transcript_remark')
520
521    def update(self):
522        if self.context.student.state != REGISTERED \
523            or self.context.student.current_level != self.context.level:
524            self.flash(_('Forbidden'), type="warning")
525            self.redirect(self.url(self.context))
526
527    @property
528    def tabletitle(self):
529        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
530        tabletitle = []
531        tabletitle.append(translate(_('1st Semester Courses'), 'waeup.kofa',
532            target_language=portal_language))
533        tabletitle.append(translate(_('2nd Semester Courses'), 'waeup.kofa',
534            target_language=portal_language))
535        tabletitle.append(translate(_('Level Courses'), 'waeup.kofa',
536            target_language=portal_language))
537        tabletitle.append(translate(_('1st Trimester Courses'), 'waeup.kofa',
538            target_language=portal_language))
539        tabletitle.append(translate(_('2nd Trimester Courses'), 'waeup.kofa',
540            target_language=portal_language))
541        tabletitle.append(translate(_('3rd Trimester Courses'), 'waeup.kofa',
542            target_language=portal_language))
543        return tabletitle
544
545    def render(self):
546        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
547        Code = translate('Code', 'waeup.kofa', target_language=portal_language)
548        Title = translate('Title', 'waeup.kofa', target_language=portal_language)
549        Dept = translate('Dept.', 'waeup.kofa', target_language=portal_language)
550        Faculty = translate('Faculty', 'waeup.kofa', target_language=portal_language)
551        Cred = translate(_('Credits'), 'waeup.uniben', target_language=portal_language)
552        studentview = StudentBasePDFFormPage(self.context.student,
553            self.request, self.omit_fields)
554        students_utils = getUtility(IStudentsUtils)
555
556        tabledata = []
557        tableheader = []
558        for i in range(1,7):
559            tabledata.append(sorted(
560                [value for value in self.context.values() if value.semester == i],
561                key=lambda value: str(value.semester) + value.code))
562            tableheader.append([(Code,'code', 2.5),
563                             (Title,'title', 5),
564                             (Dept,'dcode', 1.5), (Faculty,'fcode', 1.5),
565                             (Cred, 'credits', 1.5),
566                             ])
567        return students_utils.renderPDF(
568            self, 'course_registration_slip.pdf',
569            self.context.student, studentview,
570            tableheader=tableheader,
571            tabledata=tabledata,
572            omit_fields=self.omit_fields
573            )
574
575class ExportPDFCourseResultSlip(ExportPDFCourseRegistrationSlip):
576    """Deliver a PDF slip of the context.
577    """
578
579    grok.name('course_result_slip.pdf')
580
581    form_fields = grok.AutoFields(ICustomStudentStudyLevel).omit('level')
582
583    @property
584    def tabletitle(self):
585        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
586        tabletitle = []
587        tabletitle.append(translate(_('1st Semester Courses'), 'waeup.kofa',
588            target_language=portal_language))
589        tabletitle.append(translate(_('2nd Semester Courses'), 'waeup.kofa',
590            target_language=portal_language))
591        tabletitle.append(translate(_('Level Courses'), 'waeup.kofa',
592            target_language=portal_language))
593        tabletitle.append(translate(_('1st Trimester Courses'), 'waeup.kofa',
594            target_language=portal_language))
595        tabletitle.append(translate(_('2nd Trimester Courses'), 'waeup.kofa',
596            target_language=portal_language))
597        tabletitle.append(translate(_('3rd Trimester Courses'), 'waeup.kofa',
598            target_language=portal_language))
599        return tabletitle
600
601    @property
602    def label(self):
603        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
604        lang = self.request.cookies.get('kofa.language', portal_language)
605        level_title = translate(self.context.level_title, 'waeup.kofa',
606            target_language=lang)
607        return translate(_('Course Result Slip'),
608            'waeup.uniben', target_language=portal_language) \
609            + ' %s' % level_title
610
611    def render(self):
612        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
613        Code = translate('Code', 'waeup.kofa', target_language=portal_language)
614        Title = translate('Title', 'waeup.kofa', target_language=portal_language)
615        Dept = translate('Dept.', 'waeup.kofa', target_language=portal_language)
616        Faculty = translate('Faculty', 'waeup.kofa', target_language=portal_language)
617        Cred = translate(_('Credits'), 'waeup.uniben', target_language=portal_language)
618        Grade = translate('Grade', 'waeup.kofa', target_language=portal_language)
619        studentview = StudentBasePDFFormPage(self.context.student,
620            self.request, self.omit_fields)
621        students_utils = getUtility(IStudentsUtils)
622
623        tabledata = []
624        tableheader = []
625        for i in range(1,7):
626            tabledata.append(sorted(
627                [value for value in self.context.values() if value.semester == i],
628                key=lambda value: str(value.semester) + value.code))
629            tableheader.append([(Code,'code', 2.5),
630                             (Title,'title', 5),
631                             (Dept,'dcode', 1.5), (Faculty,'fcode', 1.5),
632                             (Cred, 'credits', 1.5),
633                             (Grade, 'grade', 1.5),
634                             ])
635        return students_utils.renderPDF(
636            self, 'course_result_slip.pdf',
637            self.context.student, studentview,
638            tableheader=tableheader,
639            tabledata=tabledata,
640            omit_fields=self.omit_fields
641            )
642
643class CustomCourseTicketDisplayFormPage(CourseTicketDisplayFormPage):
644    """ Page to display course tickets
645    """
646    form_fields = grok.AutoFields(ICourseTicket).omit('score')
647
648class CustomStudentActivateView(StudentActivateView):
649    """ Activate student account
650    """
651
652    def update(self):
653        self.context.suspended = False
654        self.context.writeLogMessage(self, 'account activated')
655        history = IObjectHistory(self.context)
656        history.addMessage('Student account activated', user='undisclosed')
657        self.flash(_('Student account has been activated.'))
658        self.redirect(self.url(self.context))
659        return
660
661class CustomStudentDeactivateView(StudentDeactivateView):
662    """ Deactivate student account
663    """
664    def update(self):
665        self.context.suspended = True
666        self.context.writeLogMessage(self, 'account deactivated')
667        history = IObjectHistory(self.context)
668        history.addMessage('Student account deactivated', user='undisclosed')
669        self.flash(_('Student account has been deactivated.'))
670        self.redirect(self.url(self.context))
671        return
672
673class CustomExportPDFTranscriptSlip(ExportPDFTranscriptSlip):
674    """Deliver a PDF slip of the context.
675    """
676
677    def _sigsInFooter(self):
678        isStudent = getattr(
679            self.request.principal, 'user_type', None) == 'student'
680        if not isStudent and self.context.student.state in (TRANSVAL, TRANSREL):
681            return (_('D. R. (Exams & Records)'),_('Current Dean of Faculty'),)
682        return ()
683
684    #def _signatures(self):
685    #    return ([(
686    #        'Current HD<br /> D. R. (Exams & Records)<br /> '
687    #        'For: Registrar')],)
688
689    def render(self):
690        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
691        Term = translate(_('Term'), 'waeup.kofa', target_language=portal_language)
692        Code = translate(_('Code'), 'waeup.kofa', target_language=portal_language)
693        Title = translate(_('Title'), 'waeup.kofa', target_language=portal_language)
694        Cred = translate(_('Credits'), 'waeup.kofa', target_language=portal_language)
695        #Score = translate(_('Score'), 'waeup.kofa', target_language=portal_language)
696        Grade = translate(_('Grade'), 'waeup.kofa', target_language=portal_language)
697        studentview = StudentBasePDFFormPage(self.context.student,
698            self.request, self.omit_fields)
699        students_utils = getUtility(IStudentsUtils)
700
701        tableheader = [(Code,'code', 2.5),
702                         (Title,'title', 8.5),
703                         (Term, 'semester', 1.5),
704                         (Cred, 'credits', 1.5),
705                         #(Score, 'score', 1.5),
706                         (Grade, 'grade', 1.5),
707                         ]
708
709        pdfstream = students_utils.renderPDFTranscript(
710            self, 'transcript.pdf',
711            self.context.student, studentview,
712            omit_fields=self.omit_fields,
713            tableheader=tableheader,
714            signatures=self._signatures(),
715            sigs_in_footer=self._sigsInFooter(),
716            digital_sigs=self._digital_sigs(),
717            save_file=self._save_file(),
718            )
719        if not pdfstream:
720            self.redirect(self.url(self.context.student))
721            return
722        return pdfstream
723
724class CustomExportPDFBedTicketSlip(NigeriaExportPDFBedTicketSlip):
725    """Deliver a PDF slip of the context.
726    """
727    omit_fields = ('password', 'suspended', 'suspended_comment',
728        'phone', 'adm_code', 'email', 'date_of_birth', 'flash_notice')
729
730class CustomPaymentsManageFormPage(PaymentsManageFormPage):
731    """ Page to manage the student payments. This manage form page is for
732    both students and students officers. Uniben does not allow students
733    to remove any payment ticket.
734    """
735    @property
736    def manage_payments_allowed(self):
737        return checkPermission('waeup.manageStudent', self.context)
738
739class CustomAccommodationDisplayFormPage(NigeriaAccommodationDisplayFormPage):
740    """ Page to view bed tickets.
741    """
742    with_hostel_selection = True
743
744class CustomAccommodationManageFormPage(NigeriaAccommodationManageFormPage):
745    """ Page to manage bed tickets.
746    This manage form page is for both students and students officers.
747    """
748    with_hostel_selection = True
749
750class CustomStudentBaseEditFormPage(StudentBaseEditFormPage):
751    """ View to edit student base data
752    """
753    form_fields = grok.AutoFields(ICustomStudentBase).select(
754        'email', 'phone')
755    form_fields['email'].field.required = True
756
757class CustomStudentFilesUploadPage(NigeriaStudentFilesUploadPage):
758    """ View to upload passport picture.
759
760    Students are not allowed to change the picture if they
761    passed the regular Kofa application.
762    """
763
764    def update(self):
765        # Uniben: Only 2020 session students are allowed to edit the picture.
766        if self.context.entry_session != 2020:
767            emit_lock_message(self)
768            return
769        # Passport pictures must not be editable if application slip
770        # exists.
771        slip = getUtility(IExtFileStore).getFileByContext(
772            self.context, 'application_slip')
773        PORTRAIT_CHANGE_STATES = getUtility(IStudentsUtils).PORTRAIT_CHANGE_STATES
774        if self.context.state not in PORTRAIT_CHANGE_STATES or slip is not None:
775            emit_lock_message(self)
776            return
777        super(StudentFilesUploadPage, self).update()
778        return
Note: See TracBrowser for help on using the repository browser.