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

Last change on this file since 13297 was 13297, checked in by Henrik Bettermann, 9 years ago

Print notice on bed allocation slip.

  • Property svn:keywords set to Id
File size: 20.0 KB
RevLine 
[8911]1## $Id: browser.py 13297 2015-10-07 20:25:33Z 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
[9210]20from zope.schema.interfaces import ConstraintNotSatisfied
[12856]21from zope.formlib.textwidgets import BytesDisplayWidget
[9380]22from zope.component import getUtility
[9281]23from hurry.workflow.interfaces import IWorkflowInfo
[11069]24from waeup.kofa.interfaces import (
25    REQUESTED, IExtFileStore, IKofaUtils, IObjectHistory)
[8911]26from waeup.kofa.widgets.datewidget import FriendlyDatetimeDisplayWidget
[12121]27from waeup.kofa.browser.layout import action, KofaEditFormPage, UtilityView
[9205]28from waeup.kofa.students.browser import (
[9686]29    StudyLevelEditFormPage, StudyLevelDisplayFormPage,
[13063]30    StudentBasePDFFormPage, ExportPDFCourseRegistrationSlip,
[10025]31    CourseTicketDisplayFormPage, StudentTriggerTransitionFormPage,
[11069]32    msave, emit_lock_message,
[13063]33    StudentActivateView, StudentDeactivateView,
34    ExportPDFTranscriptSlip)
[12845]35from waeup.kofa.students.workflow import (CREATED, ADMITTED, PAID,
36    CLEARANCE, REQUESTED, RETURNING, CLEARED, REGISTERED, VALIDATED,
37    GRADUATED, TRANSCRIPT, FORBIDDEN_POSTGRAD_TRANS)
[9686]38from waeup.kofa.students.interfaces import IStudentsUtils, ICourseTicket
[9251]39from waeup.kofa.students.workflow import FORBIDDEN_POSTGRAD_TRANS
[8911]40from kofacustom.nigeria.students.browser import (
41    NigeriaOnlinePaymentDisplayFormPage,
[9251]42    NigeriaStudentBaseManageFormPage,
[9380]43    NigeriaStudentClearanceEditFormPage,
[8911]44    NigeriaOnlinePaymentAddFormPage,
[13063]45    NigeriaExportPDFPaymentSlip,
46    NigeriaExportPDFClearanceSlip,
[13297]47    NigeriaExportPDFBedTicketSlip,
[12856]48    NigeriaStudentPersonalDisplayFormPage,
[13085]49    NigeriaStudentPersonalManageFormPage,
50    NigeriaStudentPersonalEditFormPage
[9281]51    )
[8911]52
[9210]53from waeup.uniben.students.interfaces import (
[12121]54    ICustomStudent,
[12856]55    ICustomStudentOnlinePayment,
56    ICustomStudentStudyCourse,
[11552]57    ICustomStudentStudyLevel,
58    ICustomUGStudentClearance,
[12856]59    ICustomPGStudentClearance,
[13085]60    ICustomStudentPersonal,
61    ICustomStudentPersonalEdit)
[9210]62from waeup.uniben.interfaces import MessageFactory as _
[8911]63
64class CustomOnlinePaymentDisplayFormPage(NigeriaOnlinePaymentDisplayFormPage):
65    """ Page to view an online payment ticket
66    """
67    grok.context(ICustomStudentOnlinePayment)
[9775]68    form_fields = grok.AutoFields(ICustomStudentOnlinePayment).omit(
[9993]69        'provider_amt', 'gateway_amt', 'thirdparty_amt', 'p_item')
[8911]70    form_fields[
71        'creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
72    form_fields[
73        'payment_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
74
[9380]75class CustomStudentClearanceEditFormPage(NigeriaStudentClearanceEditFormPage):
76    """ View to edit student clearance data by student
77    """
78
[11552]79    @property
80    def form_fields(self):
81        if self.context.is_postgrad:
82            form_fields = grok.AutoFields(ICustomPGStudentClearance).omit(
[12391]83            'clearance_locked', 'nysc_location', 'clr_code', 'officer_comment',
84            'physical_clearance_date')
[11552]85        else:
86            form_fields = grok.AutoFields(ICustomUGStudentClearance).omit(
[12391]87            'clearance_locked', 'clr_code', 'officer_comment',
88            'physical_clearance_date')
[11552]89            form_fields['date_of_birth'].for_display = True
90            form_fields['nationality'].for_display = True
91            form_fields['lga'].for_display = True
92        return form_fields
93
[9380]94    def dataNotComplete(self):
95        store = getUtility(IExtFileStore)
96        if not store.getFileByContext(self.context, attr=u'birth_certificate.jpg'):
97            return _('No birth certificate uploaded.')
98        if not store.getFileByContext(self.context, attr=u'ref_let.jpg'):
99            return _('No guarantor/referee letter uploaded.')
100        if not store.getFileByContext(self.context, attr=u'acc_let.jpg'):
101            return _('No acceptance letter uploaded.')
102        if not store.getFileByContext(self.context, attr=u'fst_sit_scan.jpg'):
103            return _('No first sitting result uploaded.')
[9395]104        #if not store.getFileByContext(self.context, attr=u'scd_sit_scan.jpg'):
105        #    return _('No second sitting result uploaded.')
[9380]106        if not store.getFileByContext(self.context, attr=u'secr_cults.jpg'):
[9848]107            return _('No affidavit of non-membership of secret cults uploaded.')
[9380]108        return False
109
[8911]110class CustomOnlinePaymentAddFormPage(NigeriaOnlinePaymentAddFormPage):
111    """ Page to add an online payment ticket
112    """
113    form_fields = grok.AutoFields(ICustomStudentOnlinePayment).select(
114        'p_category')
115
[13063]116class CustomExportPDFPaymentSlip(NigeriaExportPDFPaymentSlip):
[8911]117    """Deliver a PDF slip of the context.
118    """
119    grok.context(ICustomStudentOnlinePayment)
[9775]120    form_fields = grok.AutoFields(ICustomStudentOnlinePayment).omit(
[9993]121        'provider_amt', 'gateway_amt', 'thirdparty_amt', 'p_item')
[8911]122    form_fields['creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
[9205]123    form_fields['payment_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
124
125
[13063]126class CustomExportPDFClearanceSlip(NigeriaExportPDFClearanceSlip):
[9551]127    """Deliver a PDF slip of the context.
128    """
129
[11537]130    omit_fields = ('password', 'suspended', 'suspended_comment',
131        'phone', 'adm_code', 'email', 'date_of_birth')
132
[12846]133    def _sigsInFooter(self):
[12845]134        isStudent = getattr(
135            self.request.principal, 'user_type', None) == 'student'
[12852]136        if not isStudent and self.context.state in (CLEARED, RETURNING):
[12846]137            return (_('Date, Student Signature'),
138                    _('Date, Clearance Officer Signature'),
139                    )
140        return ()
[12845]141
[9551]142    def render(self):
143        studentview = StudentBasePDFFormPage(self.context.student,
144            self.request, self.omit_fields)
145        students_utils = getUtility(IStudentsUtils)
146        return students_utils.renderPDF(
147            self, 'clearance_slip.pdf',
148            self.context.student, studentview, signatures=self._signatures(),
[10271]149            sigs_in_footer=self._sigsInFooter(), show_scans=False,
150            omit_fields=self.omit_fields)
[9551]151
[12121]152
[13063]153class ExportClearanceInvitationSlip(UtilityView, grok.View):
[12121]154    """Deliver an invitation letter to physical clearance.
155
156    This form page is available only in Uniben.
157    """
158    grok.context(ICustomStudent)
159    grok.name('clearance_invitation_slip.pdf')
160    grok.require('waeup.viewStudent')
161    prefix = 'form'
162
[12263]163    label = u'Invitation Letter for Physical Clearance'
[12121]164
165    omit_fields = (
166        'suspended', 'phone', 'email',
167        'adm_code', 'suspended_comment',
168        'date_of_birth', 'current_level',
[12150]169        'department', 'current_mode',
[12121]170        'entry_session', 'matric_number', 'sex')
171
172    form_fields = []
173
174    @property
175    def note(self):
176        if self.context.physical_clearance_date:
177            return """
[12147]178<br /><br /><br /><br /><font size='12'>
179Dear %s,
180<br /><br /><br />
[12264]181You are invited for your physical clearance on:
[12121]182<br /><br />
[12264]183<strong>%s</strong>.
184<br /><br />
[12265]185Please bring along this letter of invitation to the University Main Auditorium
[12147]186<br /><br />
[12263]187on your clearance date.
[12147]188<br /><br /><br />
[12263]189Signed,
[12147]190<br /><br />
191The Registrar<br />
[12121]192</font>
193
[12147]194""" % (self.context.display_fullname, self.context.physical_clearance_date)
[12121]195        return
196
[12122]197
198    def update(self):
199        if self.context.student.state != REQUESTED \
200            or not  self.context.student.physical_clearance_date:
201            self.flash(_('Forbidden'), type="warning")
202            self.redirect(self.url(self.context))
203
[12121]204    def render(self):
205        studentview = StudentBasePDFFormPage(self.context.student,
206            self.request, self.omit_fields)
207        students_utils = getUtility(IStudentsUtils)
208        return students_utils.renderPDF(
209            self, 'clearance_invitation_slip',
210            self.context.student, studentview,
211            omit_fields=self.omit_fields,
212            note=self.note)
213
[12856]214class CustomStudentPersonalDisplayFormPage(
215    NigeriaStudentPersonalDisplayFormPage):
216    """ Page to display student personal data
217    """
218
219    form_fields = grok.AutoFields(ICustomStudentPersonal)
220    form_fields['perm_address'].custom_widget = BytesDisplayWidget
221    form_fields['next_kin_address'].custom_widget = BytesDisplayWidget
222    form_fields[
223        'personal_updated'].custom_widget = FriendlyDatetimeDisplayWidget('le')
224
225class CustomStudentPersonalManageFormPage(
226    NigeriaStudentPersonalManageFormPage):
227    """ Page to manage personal data
228    """
229
230    form_fields = grok.AutoFields(ICustomStudentPersonal)
231    form_fields['personal_updated'].for_display = True
232    form_fields[
233        'personal_updated'].custom_widget = FriendlyDatetimeDisplayWidget('le')
234
[13085]235class CstomStudentPersonalEditFormPage(NigeriaStudentPersonalEditFormPage):
236    """ Page to edit personal data
237    """
238    form_fields = grok.AutoFields(
239        ICustomStudentPersonalEdit).omit('personal_updated')
240
[9210]241class StudyCourseCOEditFormPage(KofaEditFormPage):
[9281]242    """ Page to edit the student study course data by clearance officers.
[9210]243
244    This form page is available only in Uniben.
245    """
246    grok.context(ICustomStudentStudyCourse)
247    grok.name('edit_level')
248    grok.require('waeup.clearStudent')
249    label = _('Edit current level')
250    pnav = 4
251    form_fields = grok.AutoFields(
252        ICustomStudentStudyCourse).select('current_level')
253
254    def update(self):
255        if not (self.context.is_current and
256            self.context.student.state == REQUESTED):
257            emit_lock_message(self)
258            return
259        super(StudyCourseCOEditFormPage, self).update()
260        return
261
262    @action(_('Save'), style='primary')
263    def save(self, **data):
264        try:
265            msave(self, **data)
266        except ConstraintNotSatisfied:
267            # The selected level might not exist in certificate
268            self.flash(_('Current level not available for certificate.'))
269            return
270        #notify(grok.ObjectModifiedEvent(self.context.__parent__))
[9281]271        return
272
273class CustomStudyLevelEditFormPage(StudyLevelEditFormPage):
274    """ Page to edit the student study level data by students.
275
276    """
[9686]277    grok.template('studyleveleditpage')
[9281]278
[9686]279class CustomStudyLevelDisplayFormPage(StudyLevelDisplayFormPage):
280    """ Page to display student study levels
281    """
282    grok.template('studylevelpage')
283
[13063]284class CustomExportPDFCourseRegistrationSlip(
285    ExportPDFCourseRegistrationSlip):
[9686]286    """Deliver a PDF slip of the context.
287    """
288
[9921]289    form_fields = grok.AutoFields(ICustomStudentStudyLevel).omit(
[12879]290        'level_verdict', 'gpa', 'level')
[9921]291
[12855]292    def update(self):
293        if self.context.student.state != REGISTERED \
294            or self.context.student.current_level != self.context.level:
295            self.flash(_('Forbidden'), type="warning")
296            self.redirect(self.url(self.context))
297
[10441]298    @property
299    def tabletitle(self):
300        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
301        tabletitle = []
302        tabletitle.append(translate(_('1st Semester Courses'), 'waeup.kofa',
303            target_language=portal_language))
304        tabletitle.append(translate(_('2nd Semester Courses'), 'waeup.kofa',
305            target_language=portal_language))
306        tabletitle.append(translate(_('Level Courses'), 'waeup.kofa',
307            target_language=portal_language))
308        tabletitle.append(translate(_('1st Trimester Courses'), 'waeup.kofa',
309            target_language=portal_language))
310        tabletitle.append(translate(_('2nd Trimester Courses'), 'waeup.kofa',
311            target_language=portal_language))
312        tabletitle.append(translate(_('3rd Trimester Courses'), 'waeup.kofa',
313            target_language=portal_language))
314        return tabletitle
315
[9686]316    def render(self):
317        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
[9909]318        Code = translate('Code', 'waeup.kofa', target_language=portal_language)
319        Title = translate('Title', 'waeup.kofa', target_language=portal_language)
320        Dept = translate('Dept.', 'waeup.kofa', target_language=portal_language)
321        Faculty = translate('Faculty', 'waeup.kofa', target_language=portal_language)
322        Cred = translate(_('Credits'), 'waeup.uniben', target_language=portal_language)
[9686]323        studentview = StudentBasePDFFormPage(self.context.student,
324            self.request, self.omit_fields)
325        students_utils = getUtility(IStudentsUtils)
[10441]326
327        tabledata = []
328        tableheader = []
329        contenttitle = []
330        for i in range(1,7):
331            tabledata.append(sorted(
332                [value for value in self.context.values() if value.semester == i],
333                key=lambda value: str(value.semester) + value.code))
334            tableheader.append([(Code,'code', 2.5),
335                             (Title,'title', 5),
336                             (Dept,'dcode', 1.5), (Faculty,'fcode', 1.5),
337                             (Cred, 'credits', 1.5),
338                             ])
[9686]339        return students_utils.renderPDF(
340            self, 'course_registration_slip.pdf',
341            self.context.student, studentview,
[10441]342            tableheader=tableheader,
343            tabledata=tabledata,
[10271]344            omit_fields=self.omit_fields
[9908]345            )
[9848]346
[13063]347class UnibenExportPDFCourseResultSlip(ExportPDFCourseRegistrationSlip):
[9848]348    """Deliver a PDF slip of the context.
349    """
350
351    grok.name('course_result_slip.pdf')
352
353    @property
[10441]354    def tabletitle(self):
355        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
356        tabletitle = []
357        tabletitle.append(translate(_('1st Semester Courses'), 'waeup.kofa',
358            target_language=portal_language))
359        tabletitle.append(translate(_('2nd Semester Courses'), 'waeup.kofa',
360            target_language=portal_language))
361        tabletitle.append(translate(_('Level Courses'), 'waeup.kofa',
362            target_language=portal_language))
363        tabletitle.append(translate(_('1st Trimester Courses'), 'waeup.kofa',
364            target_language=portal_language))
365        tabletitle.append(translate(_('2nd Trimester Courses'), 'waeup.kofa',
366            target_language=portal_language))
367        tabletitle.append(translate(_('3rd Trimester Courses'), 'waeup.kofa',
368            target_language=portal_language))
369        return tabletitle
370
371    @property
[9848]372    def label(self):
373        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
374        lang = self.request.cookies.get('kofa.language', portal_language)
375        level_title = translate(self.context.level_title, 'waeup.kofa',
376            target_language=lang)
377        return translate(_('Course Result Slip'),
378            'waeup.uniben', target_language=portal_language) \
379            + ' %s' % level_title
380
381    def render(self):
382        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
[9909]383        Code = translate('Code', 'waeup.kofa', target_language=portal_language)
384        Title = translate('Title', 'waeup.kofa', target_language=portal_language)
385        Dept = translate('Dept.', 'waeup.kofa', target_language=portal_language)
386        Faculty = translate('Faculty', 'waeup.kofa', target_language=portal_language)
387        Cred = translate(_('Credits'), 'waeup.uniben', target_language=portal_language)
388        Grade = translate('Grade', 'waeup.kofa', target_language=portal_language)
[9848]389        studentview = StudentBasePDFFormPage(self.context.student,
390            self.request, self.omit_fields)
391        students_utils = getUtility(IStudentsUtils)
[10441]392
393        tabledata = []
394        tableheader = []
395        contenttitle = []
396        for i in range(1,7):
397            tabledata.append(sorted(
398                [value for value in self.context.values() if value.semester == i],
399                key=lambda value: str(value.semester) + value.code))
400            tableheader.append([(Code,'code', 2.5),
401                             (Title,'title', 5),
402                             (Dept,'dcode', 1.5), (Faculty,'fcode', 1.5),
403                             (Cred, 'credits', 1.5),
404                             (Grade, 'grade', 1.5),
405                             ])
[9908]406        return students_utils.renderPDF(
407            self, 'course_registration_slip.pdf',
408            self.context.student, studentview,
[10441]409            tableheader=tableheader,
410            tabledata=tabledata,
[10271]411            omit_fields=self.omit_fields
[9908]412            )
[9686]413
414class CustomCourseTicketDisplayFormPage(CourseTicketDisplayFormPage):
415    """ Page to display course tickets
416    """
417    form_fields = grok.AutoFields(ICourseTicket).omit('score')
[11069]418
[13063]419class CustomStudentActivateView(StudentActivateView):
[11069]420    """ Activate student account
421    """
422
423    def update(self):
424        self.context.suspended = False
425        self.context.writeLogMessage(self, 'account activated')
426        history = IObjectHistory(self.context)
427        history.addMessage('Student account activated', user='undisclosed')
428        self.flash(_('Student account has been activated.'))
429        self.redirect(self.url(self.context))
430        return
431
[13063]432class CustomStudentDeactivateView(StudentDeactivateView):
[11069]433    """ Deactivate student account
434    """
435    def update(self):
436        self.context.suspended = True
437        self.context.writeLogMessage(self, 'account deactivated')
438        history = IObjectHistory(self.context)
439        history.addMessage('Student account deactivated', user='undisclosed')
440        self.flash(_('Student account has been deactivated.'))
441        self.redirect(self.url(self.context))
442        return
[12845]443
[13063]444class CustomExportPDFTranscriptSlip(ExportPDFTranscriptSlip):
[12845]445    """Deliver a PDF slip of the context.
446    """
447
448    def _sigsInFooter(self):
449        return []
450        #return (_('CERTIFIED TRUE COPY'),)
451
452    def _signatures(self):
453        return ([(
454            'Current HD<br /> D. R. (Exams & Records)<br /> '
455            'For: Registrar')],)
456
457    def render(self):
458        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
459        Term = translate(_('Term'), 'waeup.kofa', target_language=portal_language)
460        Code = translate(_('Code'), 'waeup.kofa', target_language=portal_language)
461        Title = translate(_('Title'), 'waeup.kofa', target_language=portal_language)
462        Cred = translate(_('Credits'), 'waeup.kofa', target_language=portal_language)
463        #Score = translate(_('Score'), 'waeup.kofa', target_language=portal_language)
464        Grade = translate(_('Grade'), 'waeup.kofa', target_language=portal_language)
465        studentview = StudentBasePDFFormPage(self.context.student,
466            self.request, self.omit_fields)
467        students_utils = getUtility(IStudentsUtils)
468
469        tableheader = [(Code,'code', 2.5),
470                         (Title,'title', 8.5),
471                         (Term, 'semester', 1.5),
472                         (Cred, 'credits', 1.5),
473                         #(Score, 'score', 1.5),
474                         (Grade, 'grade', 1.5),
475                         ]
476
477        return students_utils.renderPDFTranscript(
478            self, 'transcript.pdf',
479            self.context.student, studentview,
480            omit_fields=self.omit_fields,
481            tableheader=tableheader,
482            signatures=self._signatures(),
483            sigs_in_footer=self._sigsInFooter(),
[13297]484            )
485
486class CustomExportPDFBedTicketSlip(NigeriaExportPDFBedTicketSlip):
487    """Deliver a PDF slip of the context.
488    """
489
490
491    def render(self):
492        studentview = StudentBasePDFFormPage(self.context.student,
493            self.request, self.omit_fields)
494        students_utils = getUtility(IStudentsUtils)
495
496        note = """
497<br /><br />
498PLEASE ENDEAVOUR TO PAY YOUR HOSTEL MAINTENANCE  CHARGE WITHIN 7 DAYS OF
499BEING ALLOCATED A SPACE OR ELSE YOU ARE DEEMED TO HAVE VOLUNTARILY
500FORFEITED IT AND IT GOES BACK INTO CIRCULATION TO BE AVAILABLE FOR BOOKING
501AFRESH!"""
502
503        return students_utils.renderPDF(
504            self, 'bed_allocation_slip.pdf',
505            self.context.student, studentview,
506            omit_fields=self.omit_fields,
507            note=note)
Note: See TracBrowser for help on using the repository browser.