source: main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/students/browser.py @ 16270

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

Remove email2 field.

  • Property svn:keywords set to Id
File size: 20.6 KB
Line 
1## $Id: browser.py 16265 2020-10-05 06:32: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
19import os
20from zope.i18n import translate
21from zope.schema.interfaces import ConstraintNotSatisfied
22from zope.component import getUtility
23from zope.formlib.textwidgets import BytesDisplayWidget
24from hurry.workflow.interfaces import IWorkflowInfo
25from waeup.kofa.interfaces import (REQUESTED, ADMITTED, CLEARANCE,
26    IExtFileStore, IKofaUtils, academic_sessions_vocab)
27from waeup.kofa.widgets.datewidget import FriendlyDatetimeDisplayWidget
28from waeup.kofa.browser.layout import (
29    action, jsaction, UtilityView, KofaEditFormPage)
30from waeup.kofa.students.browser import (
31    StudyLevelEditFormPage, StudyLevelDisplayFormPage,
32    StudentBasePDFFormPage, ExportPDFCourseRegistrationSlip,
33    CourseTicketDisplayFormPage, StudentTriggerTransitionFormPage,
34    StartClearancePage, BalancePaymentAddFormPage,
35    ExportPDFAdmissionSlip, ExportPDFPersonalDataSlip,
36    msave, emit_lock_message)
37from waeup.kofa.students.interfaces import (
38    IStudentsUtils, ICourseTicket, IStudent)
39from waeup.kofa.students.vocabularies import StudyLevelSource
40from waeup.kofa.students.workflow import FORBIDDEN_POSTGRAD_TRANS
41from kofacustom.nigeria.students.browser import (
42    NigeriaOnlinePaymentDisplayFormPage,
43    NigeriaStudentBaseDisplayFormPage,
44    NigeriaStudentBaseManageFormPage,
45    NigeriaStudentClearanceEditFormPage,
46    NigeriaOnlinePaymentAddFormPage,
47    NigeriaExportPDFPaymentSlip,
48    NigeriaExportPDFClearanceSlip,
49    NigeriaExportPDFCourseRegistrationSlip,
50    NigeriaStudentBaseEditFormPage,
51    NigeriaBedTicketAddPage,
52    NigeriaAccommodationManageFormPage,
53    NigeriaAccommodationDisplayFormPage,
54    NigeriaStudentPersonalManageFormPage,
55    NigeriaStudentPersonalEditFormPage,
56    NigeriaStudentPersonalDisplayFormPage
57    )
58from kofacustom.iuokada.students.interfaces import (
59    ICustomStudentOnlinePayment, ICustomStudentStudyCourse,
60    ICustomStudentStudyLevel, ICustomStudentBase, ICustomStudent,
61    ICustomStudentPersonal, ICustomStudentPersonalEdit)
62from kofacustom.iuokada.interfaces import MessageFactory as _
63
64class CustomStudentBaseDisplayFormPage(NigeriaStudentBaseDisplayFormPage):
65    """ Page to display student base data
66    """
67    form_fields = grok.AutoFields(ICustomStudentBase).omit(
68        'password', 'suspended', 'suspended_comment', 'flash_notice')
69
70class CustomStudentBaseManageFormPage(NigeriaStudentBaseManageFormPage):
71    """ View to manage student base data
72    """
73    form_fields = grok.AutoFields(ICustomStudentBase).omit(
74        'student_id', 'adm_code', 'suspended',
75        'financially_cleared_by', 'financial_clearance_date')
76
77class StudentBaseEditFormPage(NigeriaStudentBaseEditFormPage):
78    """ View to edit student base data
79    """
80    @property
81    def form_fields(self):
82        form_fields = grok.AutoFields(ICustomStudentBase).select(
83            'email', 'parents_email', 'phone',)
84        if not self.context.state in (ADMITTED, CLEARANCE):
85            form_fields['parents_email'].for_display = True
86        return form_fields
87
88class CustomExportPDFCourseRegistrationSlip(
89    NigeriaExportPDFCourseRegistrationSlip):
90    """Deliver a PDF slip of the context.
91    """
92
93    def _signatures(self):
94        return (
95                ['Student Signature'],
96                ['HoD / Course Adviser Signature'],
97                ['College Officer Signature'],
98                ['Dean Signature']
99                )
100
101    #def _sigsInFooter(self):
102    #    return (_('Student'),
103    #            _('HoD / Course Adviser'),
104    #            _('College Officer'),
105    #            _('Dean'),
106    #            )
107    #    return ()
108
109class CustomStudentPersonalDisplayFormPage(NigeriaStudentPersonalDisplayFormPage):
110    """ Page to display student personal data
111    """
112    form_fields = grok.AutoFields(ICustomStudentPersonal)
113    form_fields['perm_address'].custom_widget = BytesDisplayWidget
114    form_fields['postal_address'].custom_widget = BytesDisplayWidget
115    form_fields['hostel_address'].custom_widget = BytesDisplayWidget
116    form_fields['father_address'].custom_widget = BytesDisplayWidget
117    form_fields['mother_address'].custom_widget = BytesDisplayWidget
118    form_fields['guardian_address'].custom_widget = BytesDisplayWidget
119    form_fields[
120        'personal_updated'].custom_widget = FriendlyDatetimeDisplayWidget('le')
121
122
123class CustomStudentPersonalEditFormPage(NigeriaStudentPersonalEditFormPage):
124    """ Page to edit personal data
125    """
126    form_fields = grok.AutoFields(ICustomStudentPersonalEdit).omit(
127        'personal_updated')
128
129    def update(self):
130        if not self.context.is_fresh:
131            self.flash('Not allowed.', type="danger")
132            self.redirect(self.url(self.context))
133            return
134        minamount = 200000
135        if not self.context.minimumFreshStudentPayments(minamount):
136            self.flash('Please make required payments first '
137                       '(at least in the amount of %s Naira).' % minamount,
138                       type="warning")
139            self.redirect(self.url(self.context, 'view_personal'))
140            return
141        super(CustomStudentPersonalEditFormPage, self).update()
142        return
143
144
145class CustomStudentPersonalManageFormPage(NigeriaStudentPersonalManageFormPage):
146    """ Page to edit personal data
147    """
148    form_fields = grok.AutoFields(ICustomStudentPersonal)
149    form_fields['personal_updated'].for_display = True
150    form_fields[
151        'personal_updated'].custom_widget = FriendlyDatetimeDisplayWidget('le')
152
153class CustomExportPDFPersonalDataSlip(ExportPDFPersonalDataSlip):
154    """Deliver a PDF base and personal data slip.
155    """
156    omit_fields = (
157        'phone', 'email',
158        'suspended',
159        'adm_code', 'suspended_comment',
160        'current_level',
161        'flash_notice', 'entry_session',
162        'parents_email')
163
164    form_fields = grok.AutoFields(ICustomStudentPersonal)
165
166    def render(self):
167        studentview = StudentBasePDFFormPage(self.context.student,
168            self.request, self.omit_fields)
169        students_utils = getUtility(IStudentsUtils)
170
171        watermark_path = os.path.join(
172            os.path.dirname(__file__), 'static', 'watermark.pdf')
173        watermark = open(watermark_path, 'rb')
174        file_path = os.path.join(
175            os.path.dirname(__file__), 'static', 'biodataPage2.pdf')
176        file = open(file_path, 'rb')
177        mergefiles = [file,]
178        return students_utils.renderPDF(
179            self, 'personal_slip.pdf',
180            self.context.student, studentview,
181            omit_fields=self.omit_fields,
182            mergefiles=mergefiles,
183            watermark=watermark)
184
185class CustomAccommodationDisplayFormPage(NigeriaAccommodationDisplayFormPage):
186    """ Page to view bed tickets.
187    """
188    with_hostel_selection = True
189
190class CustomAccommodationManageFormPage(NigeriaAccommodationManageFormPage):
191    """ Page to manage bed tickets.
192    This manage form page is for both students and students officers.
193    """
194    with_hostel_selection = True
195
196class CustomBedTicketAddPage(NigeriaBedTicketAddPage):
197    """ Page to add a bed ticket
198    """
199    with_ac = False
200    with_bedselection = True
201
202class StudentGetMatricNumberPage(UtilityView, grok.View):
203    """ Construct and set the matriculation number.
204    """
205    grok.context(IStudent)
206    grok.name('get_matric_number')
207    grok.require('waeup.manageStudent')
208
209    def update(self):
210        students_utils = getUtility(IStudentsUtils)
211        msg, mnumber = students_utils.setMatricNumber(self.context)
212        if msg:
213            self.flash(msg, type="danger")
214        else:
215            self.flash(_('Matriculation number %s assigned.' % mnumber))
216            self.context.writeLogMessage(self, '%s assigned' % mnumber)
217        self.redirect(self.url(self.context))
218        return
219
220    def render(self):
221        return
222
223class SwitchLibraryAccessView(UtilityView, grok.View):
224    """ Switch the library attribute
225    """
226    grok.context(ICustomStudent)
227    grok.name('switch_library_access')
228    grok.require('waeup.switchLibraryAccess')
229
230    def update(self):
231        if self.context.library:
232            self.context.library = False
233            self.context.writeLogMessage(self, 'library access disabled')
234            self.flash(_('Library access disabled'))
235        else:
236            self.context.library = True
237            self.context.writeLogMessage(self, 'library access enabled')
238            self.flash(_('Library access enabled'))
239        self.redirect(self.url(self.context))
240        return
241
242    def render(self):
243        return
244
245class ExportLibIdCard(UtilityView, grok.View):
246    """Deliver an id card for the library.
247    """
248    grok.context(ICustomStudent)
249    grok.name('lib_idcard.pdf')
250    grok.require('waeup.viewStudent')
251    prefix = 'form'
252
253    label = u"Library Clearance"
254
255    omit_fields = (
256        'suspended', 'email', 'phone',
257        'adm_code', 'suspended_comment',
258        'date_of_birth',
259        'current_mode', 'certificate',
260        'entry_session',
261        'flash_notice')
262
263    form_fields = []
264
265    def _sigsInFooter(self):
266        isStudent = getattr(
267            self.request.principal, 'user_type', None) == 'student'
268        if isStudent:
269            return ''
270        return (_("Date, Reader's Signature"),
271                _("Date, Circulation Librarian's Signature"),
272                )
273
274    def update(self):
275        if not self.context.library:
276            self.flash(_('Forbidden!'), type="danger")
277            self.redirect(self.url(self.context))
278        return
279
280    @property
281    def note(self):
282        return """
283<br /><br /><br /><br /><font size='12'>
284This is to certify that the bearer whose photograph and other details appear
285 overleaf is a registered user of the <b>University Library</b>.
286 The card is not transferable. A replacement fee is charged for a loss,
287 mutilation or otherwise. If found, please, return to the University Library,
288 Igbinedion University, Okada.
289</font>
290
291"""
292        return
293
294    def render(self):
295        studentview = StudentBasePDFFormPage(self.context.student,
296            self.request, self.omit_fields)
297        students_utils = getUtility(IStudentsUtils)
298        return students_utils.renderPDF(
299            self, 'lib_idcard',
300            self.context.student, studentview,
301            omit_fields=self.omit_fields,
302            sigs_in_footer=self._sigsInFooter(),
303            note=self.note)
304
305class CustomStartClearancePage(StartClearancePage):
306    with_ac = False
307
308class CustomBalancePaymentAddFormPage(BalancePaymentAddFormPage):
309    grok.require('waeup.payStudent')
310
311class CustomExportPDFAdmissionSlip(ExportPDFAdmissionSlip):
312    """Deliver a PDF Admission slip.
313    """
314
315    omit_fields = ('date_of_birth',
316                   #'current_level',
317                   'current_mode',
318                   #'entry_session'
319                   )
320
321    @property
322    def session(self):
323        return academic_sessions_vocab.getTerm(
324            self.context.entry_session).title
325
326    @property
327    def level(self):
328        studylevelsource = StudyLevelSource()
329        return studylevelsource.factory.getTitle(
330            self.context['studycourse'].certificate, self.context.current_level)
331
332    @property
333    def label(self):
334        return 'OFFER OF PROVISIONAL ADMISSION \nFOR %s SESSION' % self.session
335
336    @property
337    def pre_text_ug(self):
338        return (
339            'Following your performance in the screening exercise '
340            'for the %s academic session, I am pleased to inform '
341            'you that you have been offered provisional admission into the '
342            'Igbinedion University, Okada as follows:' % self.session)
343
344    @property
345    def pre_text_pg(self):
346        return (
347            'I am pleased to inform you that your application for admission'
348            ' into the Igbinedion University, Okada was successful. You have'
349            ' been admitted as follows:')
350
351    @property
352    def post_text_ug(self):
353        return """
354Please note that at the point of registration for your programme of study (course), you will be required to present the following documents: Current UTME result slip, WAEC/NECO (0' Level) result, Birth certificate or sworn affidavit of age, and health certificate from a recognized Medical Centre.
355
356All credentials (original) will be checked during registration. This admission will be cancelled at any point in time it is found that your claims in the application form are false.
357
358You are required to show evidence of the result / credentials you presented on application for admission.
359
360Fees can be paid using any of the following options:
361
362Fees can be paid through your portal page. INSTRUCTIONS can be found below "FEES PAYMENT PROCEDURE" for the options you have to make your payment, as well as instructions on how to use your preferred payment option. If you choose to use the bank payment option, you can pay at any branch of the following banks through Etranzact platform only: Access Bank, First Bank, Zenith Bank
363
364Kindly note the following:
365
366Fees indicated on the Fee Structure page are valid for the current session only.
367Your Student Id (indicated above) Is your logln to the University portal.
368As an indication of your acceptance of this offer of admission, you should pay a non-refundable Acceptance deposit of 200,000. Further note that the 200,000 deposit is part of the tuition fee for the session. Failure to pay after the expiration of two weeks may lead to forfeiture of admission.
369All fees must be paid in full at the beginning of the session, as basis for accommodation, registration and attendance of lectures. This is the rule for all students at all levels. Install mental payments of not more than two installments, may be allowed under exceptional circumstances.
370Fees once paid are not refundable.
371It is advisable that you keep the original receipts of fees paid and present them on demand.
372
373Accommodation: Accommodation in University hostels is compulsory for every student. No student Is allowed to live outside the hostels. Any student who does so will be expelled from the University.
374
375Food: Food is available in cafeteria on "pay-as-you-eat" basis.
376
377Resumption Date: The University opens for fresh students with online registration starting from Monday 28th September, 2020. The date for physical resumption is 7th November, 2020.
378
379Registration/Orientation Programme: Orientation programme/registration for fresh students will start on Monday, 9th November 2020. Registration ends on 2020-10-30. A late registration fee of N50,000 will be charged after this date. All credentials, O'Level Results, Birth Certificate/Age Declaration, UTME Result Slip (Original) will be checked during registration. This admission will be cancelled at any point in time it is found that any of your claims in the application form is false.
380
381Transport Facility: The University provides a compulsory shuttle bus service to all students at a fee already included in the other charges.
382
383Kindly note that fresh students are not allowed the use of private vehicles.
384
385Conduct: All students are expected to conduct themselves properly and dress decently on campus, as well as obey all rules and regulations as failure to comply will attract appropriate sanctions.
386
387We wish you a successful academic career in Igbinedion University.
388
389Congratulations!
390
391
392
393<img src="${signature_benji_img_path}" valign="-20" height="38" width="86" />
394
395Friday Benji Bakare Esq.
396Registrar
397registrar@iuokada.edu.ng
39808035902949
399"""
400
401    @property
402    def post_text_pg(self):
403        return """
4041. Details of your programme will be made available to you by the Head of your Department on your arrival at the Igbinedion University.
405
4062. This offer is conditional upon the confirmation of your qualifications as listed by you in your application form. You will be required to produce the ORIGINAL COPIES of all your certificates for verification during registration. If at any time after admission, it is discovered that you do not possess any of the qualifications upon which this offer of admission was made, you will be required to withdraw from the University.
407
4083. If you accept this offer of admission upon the conditions above, you should please:
409
410(a) Complete the enclosed Acceptance Form of Provisional Offer of Admission in duplicate and send  by registered mail or by hand to the
411
412Secretary
413School of Postgraduate Studies and Research
414Igbinedion University,
415P.M.B. 0006,
416Benin City, Edo State,
417Nigeria
418
419(b)     Forward the following along with the Acceptance Form of Provisional Offer of Admission.
420
421(i) A non-refundable deposit of N100,000.00 (One Hundred Thousand Naira Only) which is part of the School fees: Payable Online.
422
423(ii) Four recent passport-size photograph of yourself with your full-names (surname first in BLOCK LETTERS) written on the reverse side of the photograph and pinned to the Acceptance Form.
424
4254. The following will be required for Registration:
426
427(a) A medical examination to be conducted by an approved medical practitioner. On your arrival at the Igbinedion University, you should submit the enclosed Igbinedion University Medical Examination Form duly completed and signed by an approved medical practitioner together with your chest X-ray film to Director of Health Service at the Igbinedion University, Okada.
428
429(b) The original copies of all credentials listed in your application form (including NYSC discharge/exemption certificate) should be brought for sighting.
430
4315. You are required to pay the necessary fees and register for your degree programme not later than three weeks from the beginning of the Academic Session. Late registration may be allowed during an additional period of five weeks on payment of a late registration fees. Please note that you will be allowed to register after two months have elapsed from the beginning of the sessions.
432
4336. Please find attached:
434
435(a) A copy of School fees Regime
436(b) A copy of Acceptance Forms
437
4387. Note:
439
440(a) All Tuition fees are to be paid online
441(b) Post-graduate dues and other charges are to be paid into ABC Microfinance Bank Okada, Account No: 30125
442
4438.  CONGRATULATIONS!!!
444
445Yours faithfully,
446
447Mr. Olaoke, Olasoji Oluwole
448Secretary, School of Postgraduate Studies & Research
449"""
450
451    def render(self):
452        students_utils = getUtility(IStudentsUtils)
453        watermark_path = os.path.join(
454            os.path.dirname(__file__), 'static', 'watermark.pdf')
455        watermark = open(watermark_path, 'rb')
456        if self.context.is_postgrad:
457            file_path = os.path.join(
458                os.path.dirname(__file__), 'static', 'admission_letter_pg.pdf')
459            file = open(file_path, 'rb')
460            mergefiles = [file,]
461            return students_utils.renderPDFAdmissionLetter(self,
462                self.context.student, omit_fields=self.omit_fields,
463                pre_text=self.pre_text_pg, post_text=self.post_text_pg,
464                mergefiles=mergefiles,
465                watermark=watermark)
466        file_path = os.path.join(
467            os.path.dirname(__file__), 'static', 'admission_letter_ug.pdf')
468        file = open(file_path, 'rb')
469        mergefiles = [file,]
470        return students_utils.renderPDFAdmissionLetter(self,
471            self.context.student, omit_fields=self.omit_fields,
472            pre_text=self.pre_text_ug, post_text=self.post_text_ug,
473            mergefiles=mergefiles,
474            watermark=watermark)
475
476class CustomOnlinePaymentDisplayFormPage(NigeriaOnlinePaymentDisplayFormPage):
477    """ Page to view an online payment ticket. We do not omit provider_amt.
478    """
479    form_fields = grok.AutoFields(ICustomStudentOnlinePayment).omit(
480        'gateway_amt', 'thirdparty_amt', 'p_item','p_combi')
481    form_fields[
482        'creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
483    form_fields[
484        'payment_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
485
486class CustomExportPDFPaymentSlip(NigeriaExportPDFPaymentSlip):
487    """Deliver a PDF slip of the context. We do not omit provider_amt.
488    """
489    form_fields = grok.AutoFields(ICustomStudentOnlinePayment).omit(
490        'gateway_amt', 'thirdparty_amt', 'p_item',
491        'p_split_data','p_combi')
492    form_fields['creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
493    form_fields['payment_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
Note: See TracBrowser for help on using the repository browser.