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

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

Implement school fee payments by instalment.

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