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

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

Editing parents_email is only allowed in states 'admitted' and 'clearance started'.

  • Property svn:keywords set to Id
File size: 20.2 KB
Line 
1## $Id: browser.py 16259 2020-09-30 06:53:05Z 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', 'email2', '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        super(CustomStudentPersonalEditFormPage, self).update()
135        return
136
137
138class CustomStudentPersonalManageFormPage(NigeriaStudentPersonalManageFormPage):
139    """ Page to edit personal data
140    """
141    form_fields = grok.AutoFields(ICustomStudentPersonal)
142    form_fields['personal_updated'].for_display = True
143    form_fields[
144        'personal_updated'].custom_widget = FriendlyDatetimeDisplayWidget('le')
145
146class CustomExportPDFPersonalDataSlip(ExportPDFPersonalDataSlip):
147    """Deliver a PDF base and personal data slip.
148    """
149    omit_fields = (
150        'phone', 'email',
151        'suspended',
152        'adm_code', 'suspended_comment',
153        'current_level',
154        'flash_notice', 'entry_session',
155        'parents_email')
156
157    form_fields = grok.AutoFields(ICustomStudentPersonal)
158
159    def render(self):
160        studentview = StudentBasePDFFormPage(self.context.student,
161            self.request, self.omit_fields)
162        students_utils = getUtility(IStudentsUtils)
163
164        watermark_path = os.path.join(
165            os.path.dirname(__file__), 'static', 'watermark.pdf')
166        watermark = open(watermark_path, 'rb')
167        file_path = os.path.join(
168            os.path.dirname(__file__), 'static', 'biodataPage2.pdf')
169        file = open(file_path, 'rb')
170        mergefiles = [file,]
171        return students_utils.renderPDF(
172            self, 'personal_slip.pdf',
173            self.context.student, studentview,
174            omit_fields=self.omit_fields,
175            mergefiles=mergefiles,
176            watermark=watermark)
177
178class CustomAccommodationDisplayFormPage(NigeriaAccommodationDisplayFormPage):
179    """ Page to view bed tickets.
180    """
181    with_hostel_selection = True
182
183class CustomAccommodationManageFormPage(NigeriaAccommodationManageFormPage):
184    """ Page to manage bed tickets.
185    This manage form page is for both students and students officers.
186    """
187    with_hostel_selection = True
188
189class CustomBedTicketAddPage(NigeriaBedTicketAddPage):
190    """ Page to add a bed ticket
191    """
192    with_ac = False
193    with_bedselection = True
194
195class StudentGetMatricNumberPage(UtilityView, grok.View):
196    """ Construct and set the matriculation number.
197    """
198    grok.context(IStudent)
199    grok.name('get_matric_number')
200    grok.require('waeup.manageStudent')
201
202    def update(self):
203        students_utils = getUtility(IStudentsUtils)
204        msg, mnumber = students_utils.setMatricNumber(self.context)
205        if msg:
206            self.flash(msg, type="danger")
207        else:
208            self.flash(_('Matriculation number %s assigned.' % mnumber))
209            self.context.writeLogMessage(self, '%s assigned' % mnumber)
210        self.redirect(self.url(self.context))
211        return
212
213    def render(self):
214        return
215
216class SwitchLibraryAccessView(UtilityView, grok.View):
217    """ Switch the library attribute
218    """
219    grok.context(ICustomStudent)
220    grok.name('switch_library_access')
221    grok.require('waeup.switchLibraryAccess')
222
223    def update(self):
224        if self.context.library:
225            self.context.library = False
226            self.context.writeLogMessage(self, 'library access disabled')
227            self.flash(_('Library access disabled'))
228        else:
229            self.context.library = True
230            self.context.writeLogMessage(self, 'library access enabled')
231            self.flash(_('Library access enabled'))
232        self.redirect(self.url(self.context))
233        return
234
235    def render(self):
236        return
237
238class ExportLibIdCard(UtilityView, grok.View):
239    """Deliver an id card for the library.
240    """
241    grok.context(ICustomStudent)
242    grok.name('lib_idcard.pdf')
243    grok.require('waeup.viewStudent')
244    prefix = 'form'
245
246    label = u"Library Clearance"
247
248    omit_fields = (
249        'suspended', 'email', 'phone',
250        'adm_code', 'suspended_comment',
251        'date_of_birth',
252        'current_mode', 'certificate',
253        'entry_session',
254        'flash_notice')
255
256    form_fields = []
257
258    def _sigsInFooter(self):
259        isStudent = getattr(
260            self.request.principal, 'user_type', None) == 'student'
261        if isStudent:
262            return ''
263        return (_("Date, Reader's Signature"),
264                _("Date, Circulation Librarian's Signature"),
265                )
266
267    def update(self):
268        if not self.context.library:
269            self.flash(_('Forbidden!'), type="danger")
270            self.redirect(self.url(self.context))
271        return
272
273    @property
274    def note(self):
275        return """
276<br /><br /><br /><br /><font size='12'>
277This is to certify that the bearer whose photograph and other details appear
278 overleaf is a registered user of the <b>University Library</b>.
279 The card is not transferable. A replacement fee is charged for a loss,
280 mutilation or otherwise. If found, please, return to the University Library,
281 Igbinedion University, Okada.
282</font>
283
284"""
285        return
286
287    def render(self):
288        studentview = StudentBasePDFFormPage(self.context.student,
289            self.request, self.omit_fields)
290        students_utils = getUtility(IStudentsUtils)
291        return students_utils.renderPDF(
292            self, 'lib_idcard',
293            self.context.student, studentview,
294            omit_fields=self.omit_fields,
295            sigs_in_footer=self._sigsInFooter(),
296            note=self.note)
297
298class CustomStartClearancePage(StartClearancePage):
299    with_ac = False
300
301class CustomBalancePaymentAddFormPage(BalancePaymentAddFormPage):
302    grok.require('waeup.payStudent')
303
304class CustomExportPDFAdmissionSlip(ExportPDFAdmissionSlip):
305    """Deliver a PDF Admission slip.
306    """
307
308    omit_fields = ('date_of_birth',
309                   #'current_level',
310                   'current_mode',
311                   #'entry_session'
312                   )
313
314    @property
315    def session(self):
316        return academic_sessions_vocab.getTerm(
317            self.context.entry_session).title
318
319    @property
320    def level(self):
321        studylevelsource = StudyLevelSource()
322        return studylevelsource.factory.getTitle(
323            self.context['studycourse'].certificate, self.context.current_level)
324
325    @property
326    def label(self):
327        return 'OFFER OF PROVISIONAL ADMISSION \nFOR %s SESSION' % self.session
328
329    @property
330    def pre_text_ug(self):
331        return (
332            'Following your performance in the screening exercise '
333            'for the %s academic session, I am pleased to inform '
334            'you that you have been offered provisional admission into the '
335            'Igbinedion University, Okada as follows:' % self.session)
336
337    @property
338    def pre_text_pg(self):
339        return (
340            'I am pleased to inform you that your application for admission'
341            ' into the Igbinedion University, Okada was successful. You have'
342            ' been admitted as follows:')
343
344    @property
345    def post_text_ug(self):
346        return """
347Please 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.
348
349All 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.
350
351You are required to show evidence of the result / credentials you presented on application for admission.
352
353Fees can be paid using any of the following options:
354
355Fees 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
356
357Kindly note the following:
358
359Fees indicated on the Fee Structure page are valid for the current session only.
360Your Student Id (indicated above) Is your logln to the University portal.
361As 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.
362All 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.
363Fees once paid are not refundable.
364It is advisable that you keep the original receipts of fees paid and present them on demand.
365
366Accommodation: 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.
367
368Food: Food is available in cafeteria on "pay-as-you-eat" basis.
369
370Resumption Date: The University opens for fresh students with online registration starting from Monday 28th September, 2020. The date for physical resumption will be communicated soon.
371
372Registration/Orientation Programme: Orientation programme/registration for fresh students will start on Monday, 30th September 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.
373
374Transport Facility: The University provides a compulsory shuttle bus service to all students at a fee already included in the other charges.
375
376Kindly note that fresh students are not allowed the use of private vehicles.
377
378Conduct: 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.
379
380We wish you a successful academic career in Igbinedion University.
381
382Congratulations!
383
384Friday Benji Bakare Esq.
385Registrar
386registrar@iuokada.edu.ng
38708035902949
388"""
389
390    @property
391    def post_text_pg(self):
392        return """
3931. Details of your programme will be made available to you by the Head of your Department on your arrival at the Igbinedion University.
394
3952. 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.
396
3973. If you accept this offer of admission upon the conditions above, you should please:
398
399(a) Complete the enclosed Acceptance Form of Provisional Offer of Admission in duplicate and send  by registered mail or by hand to the
400
401Secretary
402School of Postgraduate Studies and Research
403Igbinedion University,
404P.M.B. 0006,
405Benin City, Edo State,
406Nigeria
407
408(b)     Forward the following along with the Acceptance Form of Provisional Offer of Admission.
409
410(i) A non-refundable deposit of N100,000.00 (One Hundred Thousand Naira Only) which is part of the School fees: Payable Online.
411
412(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.
413
4144. The following will be required for Registration:
415
416(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.
417
418(b) The original copies of all credentials listed in your application form (including NYSC discharge/exemption certificate) should be brought for sighting.
419
4205. 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.
421
4226. Please find attached:
423
424(a) A copy of School fees Regime
425(b) A copy of Acceptance Forms
426
4277. Note:
428
429(a) All Tuition fees are to be paid online
430(b) Post-graduate dues and other charges are to be paid into ABC Microfinance Bank Okada, Account No: 30125
431
4328.  CONGRATULATIONS!!!
433
434Yours faithfully,
435
436Mr. Olaoke, Olasoji Oluwole
437Secretary, School of Postgraduate Studies & Research
438"""
439
440    def render(self):
441        students_utils = getUtility(IStudentsUtils)
442        watermark_path = os.path.join(
443            os.path.dirname(__file__), 'static', 'watermark.pdf')
444        watermark = open(watermark_path, 'rb')
445        if self.context.is_postgrad:
446            file_path = os.path.join(
447                os.path.dirname(__file__), 'static', 'admission_letter_pg.pdf')
448            file = open(file_path, 'rb')
449            mergefiles = [file,]
450            return students_utils.renderPDFAdmissionLetter(self,
451                self.context.student, omit_fields=self.omit_fields,
452                pre_text=self.pre_text_pg, post_text=self.post_text_pg,
453                mergefiles=mergefiles,
454                watermark=watermark)
455        file_path = os.path.join(
456            os.path.dirname(__file__), 'static', 'admission_letter_ug.pdf')
457        file = open(file_path, 'rb')
458        mergefiles = [file,]
459        return students_utils.renderPDFAdmissionLetter(self,
460            self.context.student, omit_fields=self.omit_fields,
461            pre_text=self.pre_text_ug, post_text=self.post_text_ug,
462            mergefiles=mergefiles,
463            watermark=watermark)
464
465class CustomOnlinePaymentDisplayFormPage(NigeriaOnlinePaymentDisplayFormPage):
466    """ Page to view an online payment ticket. We do not omit provider_amt.
467    """
468    form_fields = grok.AutoFields(ICustomStudentOnlinePayment).omit(
469        'gateway_amt', 'thirdparty_amt', 'p_item','p_combi')
470    form_fields[
471        'creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
472    form_fields[
473        'payment_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
474
475class CustomExportPDFPaymentSlip(NigeriaExportPDFPaymentSlip):
476    """Deliver a PDF slip of the context. We do not omit provider_amt.
477    """
478    form_fields = grok.AutoFields(ICustomStudentOnlinePayment).omit(
479        'gateway_amt', 'thirdparty_amt', 'p_item',
480        'p_split_data','p_combi')
481    form_fields['creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
482    form_fields['payment_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
Note: See TracBrowser for help on using the repository browser.