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

Last change on this file since 13519 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
Line 
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
20from zope.component import getUtility
21from zope.formlib.textwidgets import BytesDisplayWidget
22from waeup.kofa.browser.layout import UtilityView
23from waeup.kofa.widgets.datewidget import FriendlyDatetimeDisplayWidget
24from waeup.kofa.interfaces import IKofaUtils
25from waeup.kofa.students.interfaces import IStudentsUtils, IStudent
26from waeup.kofa.students.workflow import PAID, REGISTERED
27from waeup.kofa.students.browser import (
28    StartClearancePage,
29    StudentBasePDFFormPage,
30    CourseTicketAddFormPage,
31    StudyLevelDisplayFormPage,
32    ExportPDFTranscriptSlip,
33    ExportPDFAdmissionSlip,
34    BedTicketAddPage,
35    StudentFilesUploadPage,
36    )
37from kofacustom.nigeria.students.browser import (
38    NigeriaOnlinePaymentDisplayFormPage,
39    NigeriaOnlinePaymentAddFormPage,
40    NigeriaExportPDFPaymentSlip,
41    NigeriaExportPDFCourseRegistrationSlip,
42    NigeriaExportPDFClearanceSlip,
43    NigeriaStudentPersonalDisplayFormPage,
44    NigeriaStudentPersonalEditFormPage,
45    NigeriaStudentPersonalManageFormPage,
46    NigeriaStudentClearanceEditFormPage,
47    NigeriaAccommodationManageFormPage,
48    )
49from waeup.aaue.students.interfaces import (
50    ICustomStudentOnlinePayment,
51    ICustomStudentStudyLevel,
52    ICustomStudent,
53    ICustomStudentPersonal,
54    ICustomStudentPersonalEdit,
55    ICustomUGStudentClearance)
56from waeup.aaue.interswitch.browser import gateway_net_amt
57from waeup.aaue.interfaces import MessageFactory as _
58
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
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
99class CustomStartClearancePage(StartClearancePage):
100    with_ac = False
101
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
112class CustomOnlinePaymentDisplayFormPage(NigeriaOnlinePaymentDisplayFormPage):
113    """ Page to view an online payment ticket
114    """
115    grok.context(ICustomStudentOnlinePayment)
116    form_fields = grok.AutoFields(ICustomStudentOnlinePayment).omit(
117        'provider_amt', 'gateway_amt', 'thirdparty_amt', 'p_item')
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
129class CustomExportPDFPaymentSlip(NigeriaExportPDFPaymentSlip):
130    """Deliver a PDF slip of the context.
131    """
132    grok.context(ICustomStudentOnlinePayment)
133    form_fields = grok.AutoFields(ICustomStudentOnlinePayment).omit(
134        'provider_amt', 'gateway_amt', 'thirdparty_amt', 'p_item')
135    form_fields['creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
136    form_fields['payment_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
137
138    @property
139    def note(self):
140        p_session = self.context.p_session
141        try:
142            academic_session = grok.getSite()['configuration'][str(p_session)]
143        except KeyError:
144            academic_session = None
145        text =  '\n\n The Amount Authorized is inclusive of: '
146        if self.context.p_category in ('schoolfee_incl', 'schoolfee_1') \
147            and academic_session:
148            welfare_fee = gateway_net_amt(academic_session.welfare_fee)
149            union_fee = gateway_net_amt(academic_session.union_fee)
150            text += ('School Fee, '
151                     '%s Naira Student Union Dues, '
152                     '%s Naira Student Welfare Assurance Fee and '
153                     % (union_fee, welfare_fee))
154        elif self.context.p_category in (
155            'clearance_incl', 'clearance_medical_incl') and academic_session:
156            matric_gown_fee = gateway_net_amt(academic_session.matric_gown_fee)
157            lapel_fee = gateway_net_amt(academic_session.lapel_fee)
158            text += ('Acceptance Fee, '
159                     '%s Naira Matriculation Gown Fee, '
160                     '%s Naira Lapel/File Fee and '
161                     % (matric_gown_fee, lapel_fee))
162        return text + '250.0 Naira Transaction Charge.'
163
164class CustomStudyLevelDisplayFormPage(StudyLevelDisplayFormPage):
165    """ Page to display student study levels
166    """
167    grok.context(ICustomStudentStudyLevel)
168    form_fields = grok.AutoFields(ICustomStudentStudyLevel).omit(
169        'total_credits', 'gpa', 'level')
170    form_fields[
171        'validation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
172
173class CustomExportPDFCourseRegistrationSlip(
174    NigeriaExportPDFCourseRegistrationSlip):
175    """Deliver a PDF slip of the context.
176    """
177    grok.context(ICustomStudentStudyLevel)
178    form_fields = grok.AutoFields(ICustomStudentStudyLevel).omit(
179        'level_session', 'level_verdict',
180        'validated_by', 'validation_date', 'gpa', 'level')
181
182    omit_fields = ('password', 'suspended', 'suspended_comment',
183        'phone', 'adm_code', 'sex', 'email', 'date_of_birth',
184        'department', 'current_mode', 'current_level')
185
186    def update(self):
187        if self.context.student.state != REGISTERED \
188            and self.context.student.current_level == self.context.level:
189            self.flash(_('Forbidden'), type="warning")
190            self.redirect(self.url(self.context))
191
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):
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            )
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)
234        Signature = translate(_('Lecturer\'s Signature'), 'waeup.aaue',
235            target_language=portal_language)
236        studentview = StudentBasePDFFormPage(self.context.student,
237            self.request, self.omit_fields)
238        students_utils = getUtility(IStudentsUtils)
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                               ])
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,
263            tableheader=tableheader,
264            tabledata=tabledata,
265            signatures=self._signatures(),
266            topMargin=topMargin,
267            omit_fields=self.omit_fields
268            )
269
270class CustomExportPDFTranscriptSlip(ExportPDFTranscriptSlip):
271    """Deliver a PDF slip of the context.
272    """
273
274    def _sigsInFooter(self):
275        return []
276
277    def _signatures(self):
278        return ([(
279            'Akhimien Felicia O. (MANUPA) <br /> Principal Assistant Registrar  <br /> '
280            'Exams, Records and Data Processing Division <br /> For: Registrar')],)
281
282class CustomExportPDFAdmissionSlip(ExportPDFAdmissionSlip):
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
292
293class CustomExportPDFClearanceSlip(NigeriaExportPDFClearanceSlip):
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
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))
318            self.context.writeLogMessage(self, '%s assigned' % mnumber)
319        self.redirect(self.url(self.context))
320        return
321
322    def render(self):
323        return
324
325class ExportPDFMatricNumberSlip(UtilityView, grok.View):
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
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
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)
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.')
360        return students_utils.renderPDFAdmissionLetter(self,
361            self.context.student, omit_fields=self.omit_fields,
362            pre_text=pre_text, post_text='')
363
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
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
403class CustomBedTicketAddPage(BedTicketAddPage):
404    with_ac = False
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.