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

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

Change signature fields again.

  • Property svn:keywords set to Id
File size: 18.0 KB
Line 
1## $Id: browser.py 13676 2016-02-11 08:40:36Z 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.component import getUtility
21from zope.security import checkPermission
22from zope.formlib.textwidgets import BytesDisplayWidget
23from waeup.kofa.browser.layout import UtilityView
24from waeup.kofa.widgets.datewidget import FriendlyDatetimeDisplayWidget
25from waeup.kofa.interfaces import IKofaUtils
26from waeup.kofa.students.interfaces import IStudentsUtils, IStudent
27from waeup.kofa.students.workflow import PAID, REGISTERED
28from waeup.kofa.students.browser import (
29    StartClearancePage,
30    StudentBasePDFFormPage,
31    CourseTicketAddFormPage,
32    StudyLevelDisplayFormPage,
33    ExportPDFTranscriptSlip,
34    ExportPDFAdmissionSlip,
35    BedTicketAddPage,
36    StudentFilesUploadPage,
37    PaymentsManageFormPage,
38    )
39from kofacustom.nigeria.students.browser import (
40    NigeriaOnlinePaymentDisplayFormPage,
41    NigeriaOnlinePaymentAddFormPage,
42    NigeriaExportPDFPaymentSlip,
43    NigeriaExportPDFCourseRegistrationSlip,
44    NigeriaExportPDFClearanceSlip,
45    NigeriaStudentPersonalDisplayFormPage,
46    NigeriaStudentPersonalEditFormPage,
47    NigeriaStudentPersonalManageFormPage,
48    NigeriaStudentClearanceEditFormPage,
49    NigeriaAccommodationManageFormPage,
50    )
51from waeup.aaue.students.interfaces import (
52    ICustomStudentOnlinePayment,
53    ICustomStudentStudyLevel,
54    ICustomStudent,
55    ICustomStudentPersonal,
56    ICustomStudentPersonalEdit,
57    ICustomUGStudentClearance)
58from waeup.aaue.interswitch.browser import gateway_net_amt
59from waeup.aaue.interfaces import MessageFactory as _
60
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
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
101class CustomStartClearancePage(StartClearancePage):
102    with_ac = False
103
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
114class CustomOnlinePaymentDisplayFormPage(NigeriaOnlinePaymentDisplayFormPage):
115    """ Page to view an online payment ticket
116    """
117    grok.context(ICustomStudentOnlinePayment)
118    form_fields = grok.AutoFields(ICustomStudentOnlinePayment).omit(
119        'provider_amt', 'gateway_amt', 'thirdparty_amt', 'p_item')
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
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
140class CustomExportPDFPaymentSlip(NigeriaExportPDFPaymentSlip):
141    """Deliver a PDF slip of the context.
142    """
143    grok.context(ICustomStudentOnlinePayment)
144    form_fields = grok.AutoFields(ICustomStudentOnlinePayment).omit(
145        'provider_amt', 'gateway_amt', 'thirdparty_amt', 'p_item')
146    form_fields['creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
147    form_fields['payment_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
148
149    @property
150    def note(self):
151        p_session = self.context.p_session
152        try:
153            academic_session = grok.getSite()['configuration'][str(p_session)]
154        except KeyError:
155            academic_session = None
156        text =  '\n\n The Amount Authorized is inclusive of: '
157        if self.context.p_category in ('schoolfee_incl', 'schoolfee_1') \
158            and academic_session:
159            welfare_fee = gateway_net_amt(academic_session.welfare_fee)
160            union_fee = gateway_net_amt(academic_session.union_fee)
161            text += ('School Fee, '
162                     '%s Naira Student Union Dues, '
163                     '%s Naira Student Welfare Assurance Fee and '
164                     % (union_fee, welfare_fee))
165        elif self.context.p_category in (
166            'clearance_incl', 'clearance_medical_incl') and academic_session:
167            matric_gown_fee = gateway_net_amt(academic_session.matric_gown_fee)
168            lapel_fee = gateway_net_amt(academic_session.lapel_fee)
169            text += ('Acceptance Fee, '
170                     '%s Naira Matriculation Gown Fee, '
171                     '%s Naira Lapel/File Fee and '
172                     % (matric_gown_fee, lapel_fee))
173        return text + '250.0 Naira Transaction Charge.'
174
175class CustomStudyLevelDisplayFormPage(StudyLevelDisplayFormPage):
176    """ Page to display student study levels
177    """
178    grok.context(ICustomStudentStudyLevel)
179    form_fields = grok.AutoFields(ICustomStudentStudyLevel).omit(
180        'total_credits', 'gpa', 'level')
181    form_fields[
182        'validation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
183
184class CustomExportPDFCourseRegistrationSlip(
185    NigeriaExportPDFCourseRegistrationSlip):
186    """Deliver a PDF slip of the context.
187    """
188    grok.context(ICustomStudentStudyLevel)
189    form_fields = grok.AutoFields(ICustomStudentStudyLevel).omit(
190        'level_session', 'level_verdict',
191        'validated_by', 'validation_date', 'gpa', 'level')
192
193    omit_fields = ('password', 'suspended', 'suspended_comment',
194        'phone', 'adm_code', 'sex', 'email', 'date_of_birth',
195        'department', 'current_mode', 'current_level')
196
197    def update(self):
198        if self.context.student.state != REGISTERED \
199            and self.context.student.current_level == self.context.level:
200            self.flash(_('Forbidden'), type="warning")
201            self.redirect(self.url(self.context))
202
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):
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'):
240            return ([_('Academic Adviser\'s Signature'),
241                _('Faculty Officer\'s Signature'),
242                _('Student\'s Signature')],)
243
244        if self.context.student.current_mode in ('special_pg_ft', 'special_pg_pt'):
245            return (
246                [('I declare that all items of information supplied above are correct:' ,
247                    _('Student'), '<br>')],
248                [('We approved the above registration:',
249                    _('Major Supervisor'), '<br>')],
250                [('', _('Co-Supervisor'), '<br>')],
251                [('', _('Head of Department'), '<br>')],
252                [('The student has satisfied the conditions for renewal of '
253                  'registration for graduate school programme in this university:',
254                  _('Secretary <br /> (School of Postgraduate Studies)'), '<br>')],
255                [('', _('Dean <br /> (School of Postgraduate Studies)'), '<br>')],
256                )
257        return None
258
259
260    def render(self):
261        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
262        Sem = translate('Sem.', 'waeup.kofa', target_language=portal_language)
263        Code = translate('Code', 'waeup.kofa', target_language=portal_language)
264        Title = translate('Title', 'waeup.kofa', target_language=portal_language)
265        Cred = translate('Cred.', 'waeup.kofa', target_language=portal_language)
266        Score = translate('Score', 'waeup.kofa', target_language=portal_language)
267        Grade = translate('Grade', 'waeup.kofa', target_language=portal_language)
268        Signature = translate(_('Lecturer\'s Signature'), 'waeup.aaue',
269            target_language=portal_language)
270        studentview = StudentBasePDFFormPage(self.context.student,
271            self.request, self.omit_fields)
272        students_utils = getUtility(IStudentsUtils)
273
274        tabledata = []
275        tableheader = []
276        contenttitle = []
277        for i in range(1,7):
278            tabledata.append(sorted(
279                [value for value in self.context.values() if value.semester == i],
280                key=lambda value: str(value.semester) + value.code))
281            tableheader.append([(Code,'code', 2.0),
282                               (Title,'title', 7),
283                               (Cred, 'credits', 1.5),
284                               (Score, 'score', 1.4),
285                               (Grade, 'grade', 1.4),
286                               (Signature, 'dummy', 3),
287                               ])
288        if len(self.label.split('\n')) == 3:
289            topMargin = 1.9
290        elif len(self.label.split('\n')) == 2:
291            topMargin = 1.7
292        else:
293            topMargin = 1.5
294        return students_utils.renderPDF(
295            self, 'course_registration_slip.pdf',
296            self.context.student, studentview,
297            tableheader=tableheader,
298            tabledata=tabledata,
299            signatures=self._signatures(),
300            topMargin=topMargin,
301            omit_fields=self.omit_fields
302            )
303
304class CustomExportPDFTranscriptSlip(ExportPDFTranscriptSlip):
305    """Deliver a PDF slip of the context.
306    """
307
308    def _sigsInFooter(self):
309        return []
310
311    def _signatures(self):
312        return ([(
313            'Akhimien Felicia O. (MANUPA) <br /> Principal Assistant Registrar  <br /> '
314            'Exams, Records and Data Processing Division <br /> For: Registrar')],)
315
316class CustomExportPDFAdmissionSlip(ExportPDFAdmissionSlip):
317    """Deliver a PDF Admission slip.
318    """
319
320    @property
321    def label(self):
322        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
323        return translate(_('e-Admission Slip \n'),
324            'waeup.kofa', target_language=portal_language) \
325            + ' %s' % self.context.display_fullname
326
327class CustomExportPDFClearanceSlip(NigeriaExportPDFClearanceSlip):
328    """Deliver a PDF slip of the context.
329    """
330
331    @property
332    def label(self):
333        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
334        return translate(_('Clearance Slip\n'),
335            'waeup.kofa', target_language=portal_language) \
336            + ' %s' % self.context.display_fullname
337
338class StudentGetMatricNumberPage(UtilityView, grok.View):
339    """ Construct and set the matriculation number.
340    """
341    grok.context(IStudent)
342    grok.name('get_matric_number')
343    grok.require('waeup.viewStudent')
344
345    def update(self):
346        students_utils = getUtility(IStudentsUtils)
347        msg, mnumber = students_utils.setMatricNumber(self.context)
348        if msg:
349            self.flash(msg, type="danger")
350        else:
351            self.flash(_('Matriculation number %s assigned.' % mnumber))
352            self.context.writeLogMessage(self, '%s assigned' % mnumber)
353        self.redirect(self.url(self.context))
354        return
355
356    def render(self):
357        return
358
359class ExportPDFMatricNumberSlip(UtilityView, grok.View):
360    """Deliver a PDF notification slip.
361    """
362    grok.context(ICustomStudent)
363    grok.name('matric_number_slip.pdf')
364    grok.require('waeup.viewStudent')
365    prefix = 'form'
366
367    form_fields = grok.AutoFields(ICustomStudent).select(
368        'student_id', 'matric_number')
369    omit_fields = ('date_of_birth', 'current_level')
370
371    @property
372    def title(self):
373        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
374        return translate(_('Matriculation Number'), 'waeup.kofa',
375            target_language=portal_language)
376
377    @property
378    def label(self):
379        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
380        return translate(_('Matriculation Number Slip\n'),
381            'waeup.kofa', target_language=portal_language) \
382            + ' %s' % self.context.display_fullname
383
384    def render(self):
385        if self.context.state not in (PAID,) or not self.context.is_fresh \
386            or not self.context.matric_number:
387            self.flash('Not allowed.', type="danger")
388            self.redirect(self.url(self.context))
389            return
390        students_utils = getUtility(IStudentsUtils)
391        pre_text = _('Congratulations! Your acceptance fee and school fees ' +
392                     'payments have been received and your matriculation ' +
393                     'number generated with details as follows.')
394        return students_utils.renderPDFAdmissionLetter(self,
395            self.context.student, omit_fields=self.omit_fields,
396            pre_text=pre_text, post_text='')
397
398class ExportPersonalDataSlip(UtilityView, grok.View):
399    """Deliver a PDF notification slip.
400    """
401    grok.context(ICustomStudent)
402    grok.name('personal_data_slip.pdf')
403    grok.require('waeup.viewStudent')
404    prefix = 'form'
405    note = None
406
407    form_fields = grok.AutoFields(ICustomStudentPersonal).omit('personal_updated')
408    omit_fields = ('suspended', 'suspended_comment', 'adm_code', 'certificate')
409
410    @property
411    def title(self):
412        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
413        return translate(_('Personal Data'), 'waeup.kofa',
414            target_language=portal_language)
415
416    @property
417    def label(self):
418        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
419        return translate(_('Personal Data Slip\n'),
420            'waeup.kofa', target_language=portal_language) \
421            + ' %s' % self.context.display_fullname
422
423    def render(self):
424        studentview = StudentBasePDFFormPage(self.context.student,
425            self.request, self.omit_fields)
426        students_utils = getUtility(IStudentsUtils)
427        return students_utils.renderPDF(self, 'personal_data_slip.pdf',
428            self.context.student, studentview, note=self.note,
429            omit_fields=self.omit_fields)
430
431class CustomAccommodationManageFormPage(NigeriaAccommodationManageFormPage):
432    """ Page to manage bed tickets.
433    This manage form page is for both students and students officers.
434    """
435    with_hostel_selection = True
436
437class CustomBedTicketAddPage(BedTicketAddPage):
438    with_ac = False
439
440class CustomStudentFilesUploadPage(StudentFilesUploadPage):
441    """ View to upload files by student. Inherit from same class in
442    base package, not from kofacustom.nigeria which
443    requires that no application slip exists.
444    """
Note: See TracBrowser for help on using the repository browser.