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

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

Hide flash_notice on slips and adjust tests.

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