source: main/waeup.aaue/trunk/src/waeup/aaue/students/browser.py @ 13674

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

Signatures in onle line.

  • Property svn:keywords set to Id
File size: 17.7 KB
RevLine 
[8911]1## $Id: browser.py 13649 2016-02-02 17:12:14Z 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
[9914]20from zope.component import getUtility
[13523]21from zope.security import checkPermission
[13351]22from zope.formlib.textwidgets import BytesDisplayWidget
[11597]23from waeup.kofa.browser.layout import UtilityView
[8911]24from waeup.kofa.widgets.datewidget import FriendlyDatetimeDisplayWidget
[9914]25from waeup.kofa.interfaces import IKofaUtils
[11597]26from waeup.kofa.students.interfaces import IStudentsUtils, IStudent
[13038]27from waeup.kofa.students.workflow import PAID, REGISTERED
[9914]28from waeup.kofa.students.browser import (
[11846]29    StartClearancePage,
[9914]30    StudentBasePDFFormPage,
31    CourseTicketAddFormPage,
32    StudyLevelDisplayFormPage,
[13059]33    ExportPDFTranscriptSlip,
34    ExportPDFAdmissionSlip,
[13353]35    BedTicketAddPage,
[13380]36    StudentFilesUploadPage,
[13523]37    PaymentsManageFormPage,
[10269]38    )
[8911]39from kofacustom.nigeria.students.browser import (
40    NigeriaOnlinePaymentDisplayFormPage,
41    NigeriaOnlinePaymentAddFormPage,
[13059]42    NigeriaExportPDFPaymentSlip,
43    NigeriaExportPDFCourseRegistrationSlip,
44    NigeriaExportPDFClearanceSlip,
[13351]45    NigeriaStudentPersonalDisplayFormPage,
46    NigeriaStudentPersonalEditFormPage,
47    NigeriaStudentPersonalManageFormPage,
[13362]48    NigeriaStudentClearanceEditFormPage,
[13462]49    NigeriaAccommodationManageFormPage,
[10269]50    )
[9496]51from waeup.aaue.students.interfaces import (
[9914]52    ICustomStudentOnlinePayment,
[11607]53    ICustomStudentStudyLevel,
[13351]54    ICustomStudent,
55    ICustomStudentPersonal,
[13362]56    ICustomStudentPersonalEdit,
57    ICustomUGStudentClearance)
[13414]58from waeup.aaue.interswitch.browser import gateway_net_amt
[9914]59from waeup.aaue.interfaces import MessageFactory as _
[8911]60
[13351]61class CustomStudentPersonalDisplayFormPage(NigeriaStudentPersonalDisplayFormPage):
62    """ Page to display student personal data
63    """
64    form_fields = grok.AutoFields(ICustomStudentPersonal)
65    form_fields['perm_address'].custom_widget = BytesDisplayWidget
66    form_fields['father_address'].custom_widget = BytesDisplayWidget
67    form_fields['mother_address'].custom_widget = BytesDisplayWidget
68    form_fields['next_kin_address'].custom_widget = BytesDisplayWidget
69    form_fields[
70        'personal_updated'].custom_widget = FriendlyDatetimeDisplayWidget('le')
71
72class CustomStudentPersonalEditFormPage(NigeriaStudentPersonalEditFormPage):
73    """ Page to edit personal data
74    """
75    form_fields = grok.AutoFields(ICustomStudentPersonalEdit).omit('personal_updated')
76
77class CustomStudentPersonalManageFormPage(NigeriaStudentPersonalManageFormPage):
78    """ Page to edit personal data
79    """
80    form_fields = grok.AutoFields(ICustomStudentPersonal)
81    form_fields['personal_updated'].for_display = True
82    form_fields[
83        'personal_updated'].custom_widget = FriendlyDatetimeDisplayWidget('le')
84
[13362]85class CustomStudentClearanceEditFormPage(NigeriaStudentClearanceEditFormPage):
86    """ View to edit student clearance data by student
87    """
88
89    @property
90    def form_fields(self):
91        if self.context.is_postgrad:
92            form_fields = grok.AutoFields(ICustomPGStudentClearance).omit(
93            'clearance_locked', 'nysc_location', 'clr_code', 'officer_comment',
94            'physical_clearance_date')
95        else:
96            form_fields = grok.AutoFields(ICustomUGStudentClearance).omit(
97            'clearance_locked', 'clr_code', 'officer_comment',
98            'physical_clearance_date')
99        return form_fields
100
[11846]101class CustomStartClearancePage(StartClearancePage):
[13360]102    with_ac = False
[11846]103
[13351]104    @property
105    def all_required_fields_filled(self):
106        if not self.context.email:
107            return _("Email address is missing."), 'edit_base'
108        if not self.context.phone:
109            return _("Phone number is missing."), 'edit_base'
110        if not self.context.father_name:
111            return _("Personal data form is not properly filled."), 'edit_personal'
112        return
113
[8911]114class CustomOnlinePaymentDisplayFormPage(NigeriaOnlinePaymentDisplayFormPage):
115    """ Page to view an online payment ticket
116    """
117    grok.context(ICustomStudentOnlinePayment)
[9853]118    form_fields = grok.AutoFields(ICustomStudentOnlinePayment).omit(
[9990]119        'provider_amt', 'gateway_amt', 'thirdparty_amt', 'p_item')
[8911]120    form_fields[
121        'creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
122    form_fields[
123        'payment_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
124
125class CustomOnlinePaymentAddFormPage(NigeriaOnlinePaymentAddFormPage):
126    """ Page to add an online payment ticket
127    """
128    form_fields = grok.AutoFields(ICustomStudentOnlinePayment).select(
129        'p_category')
130
[13523]131class CustomPaymentsManageFormPage(PaymentsManageFormPage):
132    """ Page to manage the student payments.
133
134    This manage form page is for both students and students officers.
135    """
136    @property
137    def manage_payments_allowed(self):
138        return checkPermission('waeup.manageStudent', self.context)
139
[13059]140class CustomExportPDFPaymentSlip(NigeriaExportPDFPaymentSlip):
[8911]141    """Deliver a PDF slip of the context.
142    """
143    grok.context(ICustomStudentOnlinePayment)
[9853]144    form_fields = grok.AutoFields(ICustomStudentOnlinePayment).omit(
[9990]145        'provider_amt', 'gateway_amt', 'thirdparty_amt', 'p_item')
[8911]146    form_fields['creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
[9496]147    form_fields['payment_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
[9914]148
[11625]149    @property
150    def note(self):
[13408]151        p_session = self.context.p_session
[13405]152        try:
[13408]153            academic_session = grok.getSite()['configuration'][str(p_session)]
[13405]154        except KeyError:
155            academic_session = None
[13425]156        text =  '\n\n The Amount Authorized is inclusive of: '
[13512]157        if self.context.p_category in ('schoolfee_incl', 'schoolfee_1') \
158            and academic_session:
[13414]159            welfare_fee = gateway_net_amt(academic_session.welfare_fee)
160            union_fee = gateway_net_amt(academic_session.union_fee)
[13437]161            text += ('School Fee, '
[13463]162                     '%s Naira Student Union Dues, '
[13437]163                     '%s Naira Student Welfare Assurance Fee and '
[13425]164                     % (union_fee, welfare_fee))
[13410]165        elif self.context.p_category in (
166            'clearance_incl', 'clearance_medical_incl') and academic_session:
[13414]167            matric_gown_fee = gateway_net_amt(academic_session.matric_gown_fee)
168            lapel_fee = gateway_net_amt(academic_session.lapel_fee)
[13437]169            text += ('Acceptance Fee, '
170                     '%s Naira Matriculation Gown Fee, '
171                     '%s Naira Lapel/File Fee and '
[13408]172                     % (matric_gown_fee, lapel_fee))
[13437]173        return text + '250.0 Naira Transaction Charge.'
[11625]174
[9914]175class CustomStudyLevelDisplayFormPage(StudyLevelDisplayFormPage):
176    """ Page to display student study levels
177    """
178    grok.context(ICustomStudentStudyLevel)
[10480]179    form_fields = grok.AutoFields(ICustomStudentStudyLevel).omit(
[12876]180        'total_credits', 'gpa', 'level')
[9914]181    form_fields[
182        'validation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
183
[13059]184class CustomExportPDFCourseRegistrationSlip(
185    NigeriaExportPDFCourseRegistrationSlip):
[9914]186    """Deliver a PDF slip of the context.
187    """
188    grok.context(ICustomStudentStudyLevel)
189    form_fields = grok.AutoFields(ICustomStudentStudyLevel).omit(
[10102]190        'level_session', 'level_verdict',
[12876]191        'validated_by', 'validation_date', 'gpa', 'level')
[9914]192
[10269]193    omit_fields = ('password', 'suspended', 'suspended_comment',
[10689]194        'phone', 'adm_code', 'sex', 'email', 'date_of_birth',
[11538]195        'department', 'current_mode', 'current_level')
[10269]196
[13038]197    def update(self):
198        if self.context.student.state != REGISTERED \
[13051]199            and self.context.student.current_level == self.context.level:
[13038]200            self.flash(_('Forbidden'), type="warning")
201            self.redirect(self.url(self.context))
202
[9914]203    @property
204    def label(self):
205        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
206        lang = self.request.cookies.get('kofa.language', portal_language)
207        level_title = translate(self.context.level_title, 'waeup.kofa',
208            target_language=lang)
209        line0 = ''
210        if self.context.student.current_mode.endswith('_pt'):
211            line0 = 'DIRECTORATE OF PART-TIME DEGREE PROGRAMMES\n'
212        line1 = translate(_('Course Registration Slip'),
213            'waeup.kofa', target_language=portal_language) \
214            + ' %s' % level_title
215        line2 = translate(_('Session'),
216            'waeup.kofa', target_language=portal_language) \
217            + ' %s' % self.context.getSessionString
218        return '%s%s\n%s' % (line0, line1, line2)
219
220    @property
221    def title(self):
222        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
223        return translate(_('Units Registered'), 'waeup.kofa',
224            target_language=portal_language)
225
226    def _signatures(self):
[13647]227        if self.context.student.current_mode.endswith('_pt') \
228            or self.context.student.current_mode == 'found':
229            return (
230                [('I have selected the course on the advise of my Head of '
231                 'Department. <br>', _('Student\'s Signature'), '<br>')],
232                [('This student has satisfied the department\'s requirements. '
233                 'I recommend to approve the course registration. <br>',
234                 _('Head of Department\'s Signature'), '<br>')],
235                [('' , _('Principal Assistant Registrar\'s Signature'), '<br>')],
236                [('', _('Director\'s Signature'))]
237                )
238        if self.context.student.current_mode in (
239            'de_ft', 'ug_ft', 'dp_ft', 'transfer'):
[13649]240            return ([_('Academic Adviser\'s Signature'),
241                _('Faculty Officer\'s Signature'),
242                _('Student\'s Signature')],)
243
[13647]244        if self.context.student.current_mode in ('special_pg_ft', 'special_pg_pt'):
245            return (
246                [('' , _('Student\'s Signature'), '<br>')],
247                [('', _('Major Supervisor\'s Signature'), '<br>')],
248                [('', _('Co-Supervisor\'s Signature'), '<br>')],
249                [('', _('Head of Department\'s Signature'), '<br>')],
250                [('', _('Secretary\'s Signature'), '<br>')],
251                )
252        return None
[9914]253
[13647]254
[9914]255    def render(self):
256        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
257        Sem = translate('Sem.', 'waeup.kofa', target_language=portal_language)
258        Code = translate('Code', 'waeup.kofa', target_language=portal_language)
259        Title = translate('Title', 'waeup.kofa', target_language=portal_language)
260        Cred = translate('Cred.', 'waeup.kofa', target_language=portal_language)
261        Score = translate('Score', 'waeup.kofa', target_language=portal_language)
262        Grade = translate('Grade', 'waeup.kofa', target_language=portal_language)
[10269]263        Signature = translate(_('Lecturer\'s Signature'), 'waeup.aaue',
[9914]264            target_language=portal_language)
265        studentview = StudentBasePDFFormPage(self.context.student,
266            self.request, self.omit_fields)
267        students_utils = getUtility(IStudentsUtils)
[10442]268
269        tabledata = []
270        tableheader = []
271        contenttitle = []
272        for i in range(1,7):
273            tabledata.append(sorted(
274                [value for value in self.context.values() if value.semester == i],
275                key=lambda value: str(value.semester) + value.code))
276            tableheader.append([(Code,'code', 2.0),
277                               (Title,'title', 7),
278                               (Cred, 'credits', 1.5),
279                               (Score, 'score', 1.4),
280                               (Grade, 'grade', 1.4),
281                               (Signature, 'dummy', 3),
282                               ])
[9914]283        if len(self.label.split('\n')) == 3:
284            topMargin = 1.9
285        elif len(self.label.split('\n')) == 2:
286            topMargin = 1.7
287        else:
288            topMargin = 1.5
289        return students_utils.renderPDF(
290            self, 'course_registration_slip.pdf',
291            self.context.student, studentview,
[10442]292            tableheader=tableheader,
293            tabledata=tabledata,
[9914]294            signatures=self._signatures(),
[10269]295            topMargin=topMargin,
296            omit_fields=self.omit_fields
[9914]297            )
[10566]298
[13059]299class CustomExportPDFTranscriptSlip(ExportPDFTranscriptSlip):
[10566]300    """Deliver a PDF slip of the context.
301    """
302
303    def _sigsInFooter(self):
304        return []
305
306    def _signatures(self):
307        return ([(
[11555]308            'Akhimien Felicia O. (MANUPA) <br /> Principal Assistant Registrar  <br /> '
309            'Exams, Records and Data Processing Division <br /> For: Registrar')],)
[10922]310
[13059]311class CustomExportPDFAdmissionSlip(ExportPDFAdmissionSlip):
[10922]312    """Deliver a PDF Admission slip.
313    """
314
315    @property
316    def label(self):
317        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
318        return translate(_('e-Admission Slip \n'),
319            'waeup.kofa', target_language=portal_language) \
320            + ' %s' % self.context.display_fullname
[11597]321
[13059]322class CustomExportPDFClearanceSlip(NigeriaExportPDFClearanceSlip):
[11606]323    """Deliver a PDF slip of the context.
324    """
325
326    @property
327    def label(self):
328        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
329        return translate(_('Clearance Slip\n'),
330            'waeup.kofa', target_language=portal_language) \
331            + ' %s' % self.context.display_fullname
332
[11597]333class StudentGetMatricNumberPage(UtilityView, grok.View):
334    """ Construct and set the matriculation number.
335    """
336    grok.context(IStudent)
337    grok.name('get_matric_number')
338    grok.require('waeup.viewStudent')
339
340    def update(self):
341        students_utils = getUtility(IStudentsUtils)
342        msg, mnumber = students_utils.setMatricNumber(self.context)
343        if msg:
344            self.flash(msg, type="danger")
345        else:
346            self.flash(_('Matriculation number %s assigned.' % mnumber))
[11602]347            self.context.writeLogMessage(self, '%s assigned' % mnumber)
[11597]348        self.redirect(self.url(self.context))
349        return
350
351    def render(self):
[11607]352        return
353
[13059]354class ExportPDFMatricNumberSlip(UtilityView, grok.View):
[11607]355    """Deliver a PDF notification slip.
356    """
357    grok.context(ICustomStudent)
358    grok.name('matric_number_slip.pdf')
359    grok.require('waeup.viewStudent')
360    prefix = 'form'
361
362    form_fields = grok.AutoFields(ICustomStudent).select(
363        'student_id', 'matric_number')
364    omit_fields = ('date_of_birth', 'current_level')
365
366    @property
[13489]367    def title(self):
368        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
369        return translate(_('Matriculation Number'), 'waeup.kofa',
370            target_language=portal_language)
371
372    @property
[11607]373    def label(self):
374        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
375        return translate(_('Matriculation Number Slip\n'),
376            'waeup.kofa', target_language=portal_language) \
377            + ' %s' % self.context.display_fullname
378
379    def render(self):
380        if self.context.state not in (PAID,) or not self.context.is_fresh \
381            or not self.context.matric_number:
382            self.flash('Not allowed.', type="danger")
383            self.redirect(self.url(self.context))
384            return
385        students_utils = getUtility(IStudentsUtils)
[11609]386        pre_text = _('Congratulations! Your acceptance fee and school fees ' +
387                     'payments have been received and your matriculation ' +
388                     'number generated with details as follows.')
[11607]389        return students_utils.renderPDFAdmissionLetter(self,
390            self.context.student, omit_fields=self.omit_fields,
[13353]391            pre_text=pre_text, post_text='')
392
[13489]393class ExportPersonalDataSlip(UtilityView, grok.View):
394    """Deliver a PDF notification slip.
395    """
396    grok.context(ICustomStudent)
397    grok.name('personal_data_slip.pdf')
398    grok.require('waeup.viewStudent')
399    prefix = 'form'
400    note = None
401
402    form_fields = grok.AutoFields(ICustomStudentPersonal).omit('personal_updated')
403    omit_fields = ('suspended', 'suspended_comment', 'adm_code', 'certificate')
404
405    @property
406    def title(self):
407        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
408        return translate(_('Personal Data'), 'waeup.kofa',
409            target_language=portal_language)
410
411    @property
412    def label(self):
413        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
414        return translate(_('Personal Data Slip\n'),
415            'waeup.kofa', target_language=portal_language) \
416            + ' %s' % self.context.display_fullname
417
418    def render(self):
419        studentview = StudentBasePDFFormPage(self.context.student,
420            self.request, self.omit_fields)
421        students_utils = getUtility(IStudentsUtils)
422        return students_utils.renderPDF(self, 'personal_data_slip.pdf',
423            self.context.student, studentview, note=self.note,
424            omit_fields=self.omit_fields)
425
[13462]426class CustomAccommodationManageFormPage(NigeriaAccommodationManageFormPage):
427    """ Page to manage bed tickets.
428    This manage form page is for both students and students officers.
429    """
430    with_hostel_selection = True
431
[13353]432class CustomBedTicketAddPage(BedTicketAddPage):
[13360]433    with_ac = False
[13380]434
435class CustomStudentFilesUploadPage(StudentFilesUploadPage):
436    """ View to upload files by student. Inherit from same class in
437    base package, not from kofacustom.nigeria which
438    requires that no application slip exists.
439    """
Note: See TracBrowser for help on using the repository browser.