source: main/kofacustom.nigeria/trunk/src/kofacustom/nigeria/students/browser.py @ 15844

Last change on this file since 15844 was 15844, checked in by Henrik Bettermann, 5 years ago

Render payment slip in states waived and scholarship.

  • Property svn:keywords set to Id
File size: 15.9 KB
RevLine 
[8862]1## $Id: browser.py 15844 2019-11-25 11:09:43Z 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.formlib.textwidgets import BytesDisplayWidget
20from zope.component import getUtility
[13856]21from zope.security import checkPermission
[8862]22from zope.i18n import translate
[13620]23from datetime import datetime
[8862]24from waeup.kofa.widgets.datewidget import FriendlyDatetimeDisplayWidget
[13623]25from waeup.kofa.interfaces import IExtFileStore, IObjectHistory, IKofaUtils
[13620]26from waeup.kofa.browser.layout import action, UtilityView
[13623]27from waeup.kofa.utils.helpers import get_current_principal, to_timezone
[8862]28from waeup.kofa.students.browser import (
[8904]29    StudentPersonalDisplayFormPage, StudentPersonalManageFormPage,
[8862]30    StudentClearanceManageFormPage, StudentClearanceEditFormPage,
[13058]31    StudentClearanceDisplayFormPage, OnlinePaymentFakeApproveView,
32    ExportPDFClearanceSlip, StudentBaseManageFormPage,
[8966]33    StudentBaseDisplayFormPage,
[13623]34    StudentBasePDFFormPage,
[8862]35    StudentBaseEditFormPage, StudentPersonalEditFormPage,
36    OnlinePaymentDisplayFormPage, OnlinePaymentAddFormPage,
[13058]37    OnlinePaymentBreadcrumb, ExportPDFPaymentSlip,
38    ExportPDFCourseRegistrationSlip,
39    ExportPDFBedTicketSlip,
[13458]40    StudentFilesUploadPage, emit_lock_message,
[15711]41    AccommodationManageFormPage,
42    BedTicketAddPage)
[10707]43from waeup.kofa.students.interfaces import IStudentsUtils
[8862]44from kofacustom.nigeria.students.interfaces import (
[8863]45    INigeriaStudentBase, INigeriaStudent, INigeriaStudentPersonal,
[9564]46    INigeriaStudentPersonalEdit,
[8863]47    INigeriaUGStudentClearance,INigeriaPGStudentClearance,
[8904]48    INigeriaStudentOnlinePayment
[8862]49    )
50from waeup.kofa.students.workflow import ADMITTED
51from kofacustom.nigeria.interfaces import MessageFactory as _
52
[8863]53class NigeriaOnlinePaymentBreadcrumb(OnlinePaymentBreadcrumb):
[8862]54    """A breadcrumb for payments.
55    """
[8863]56    grok.context(INigeriaStudentOnlinePayment)
[8862]57
[8966]58class NigeriaStudentBaseDisplayFormPage(StudentBaseDisplayFormPage):
59    """ Page to display student base data
60    """
[9704]61    form_fields = grok.AutoFields(INigeriaStudentBase).omit(
[14274]62        'password', 'suspended', 'suspended_comment',
63        'flash_notice', 'provisionally_cleared')
[13620]64    form_fields[
65        'financial_clearance_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
[8966]66
[8863]67class NigeriaStudentBaseManageFormPage(StudentBaseManageFormPage):
[8862]68    """ View to manage student base data
69    """
[9144]70    form_fields = grok.AutoFields(INigeriaStudentBase).omit(
[13620]71        'student_id', 'adm_code', 'suspended',
72        'financially_cleared_by', 'financial_clearance_date')
[8862]73
[8863]74class NigeriaStudentBaseEditFormPage(StudentBaseEditFormPage):
[8862]75    """ View to edit student base data
76    """
[8863]77    form_fields = grok.AutoFields(INigeriaStudentBase).select(
[8862]78        'email', 'phone')
79
[8863]80class NigeriaStudentPersonalDisplayFormPage(StudentPersonalDisplayFormPage):
[8862]81    """ Page to display student personal data
82    """
[9562]83    form_fields = grok.AutoFields(INigeriaStudentPersonal)
[8862]84    form_fields['perm_address'].custom_widget = BytesDisplayWidget
[9053]85    form_fields['next_kin_address'].custom_widget = BytesDisplayWidget
[9562]86    form_fields[
87        'personal_updated'].custom_widget = FriendlyDatetimeDisplayWidget('le')
[8862]88
[8863]89class NigeriaStudentPersonalEditFormPage(StudentPersonalEditFormPage):
[8862]90    """ Page to edit personal data
91    """
[9564]92    form_fields = grok.AutoFields(INigeriaStudentPersonalEdit).omit('personal_updated')
[8862]93
[8904]94class NigeriaStudentPersonalManageFormPage(StudentPersonalManageFormPage):
95    """ Page to edit personal data
96    """
97    form_fields = grok.AutoFields(INigeriaStudentPersonal)
[9554]98    form_fields['personal_updated'].for_display = True
[9572]99    form_fields[
100        'personal_updated'].custom_widget = FriendlyDatetimeDisplayWidget('le')
[8904]101
[8863]102class NigeriaStudentClearanceDisplayFormPage(StudentClearanceDisplayFormPage):
[8862]103    """ Page to display student clearance data
104    """
105
106    @property
107    def form_fields(self):
[9248]108        if self.context.is_postgrad:
[8862]109            form_fields = grok.AutoFields(
[8863]110                INigeriaPGStudentClearance).omit('clearance_locked')
[8862]111        else:
112            form_fields = grok.AutoFields(
[8863]113                INigeriaUGStudentClearance).omit('clearance_locked')
[9535]114        if not getattr(self.context, 'officer_comment'):
115            form_fields = form_fields.omit('officer_comment')
116        else:
117            form_fields['officer_comment'].custom_widget = BytesDisplayWidget
[8862]118        return form_fields
119
[13058]120class NigeriaExportPDFClearanceSlip(ExportPDFClearanceSlip):
[8862]121    """Deliver a PDF slip of the context.
122    """
[9704]123    omit_fields = ('password', 'suspended', 'suspended_comment',
[13712]124        'phone', 'adm_code', 'email', 'date_of_birth', 'current_level',
125        'flash_notice')
[8862]126
127    @property
128    def form_fields(self):
[9248]129        if self.context.is_postgrad:
[8862]130            form_fields = grok.AutoFields(
[8863]131                INigeriaPGStudentClearance).omit('clearance_locked')
[8862]132        else:
133            form_fields = grok.AutoFields(
[8863]134                INigeriaUGStudentClearance).omit('clearance_locked')
[9535]135        if not getattr(self.context, 'officer_comment'):
136            form_fields = form_fields.omit('officer_comment')
[8862]137        return form_fields
138
[8863]139class NigeriaStudentClearanceManageFormPage(StudentClearanceManageFormPage):
[8862]140    """ Page to edit student clearance data
141    """
142
143    @property
144    def form_fields(self):
[9248]145        if self.context.is_postgrad:
[9249]146            form_fields = grok.AutoFields(
147                INigeriaPGStudentClearance).omit('clr_code')
[8862]148        else:
[9249]149            form_fields = grok.AutoFields(
150                INigeriaUGStudentClearance).omit('clr_code')
[8862]151        return form_fields
152
[8863]153class NigeriaStudentClearanceEditFormPage(StudentClearanceEditFormPage):
[8862]154    """ View to edit student clearance data by student
155    """
156
157    @property
158    def form_fields(self):
[9248]159        if self.context.is_postgrad:
[8946]160            form_fields = grok.AutoFields(INigeriaPGStudentClearance).omit(
[12107]161            'clearance_locked', 'nysc_location', 'clr_code', 'officer_comment',
[12120]162            'physical_clearance_date')
[8862]163        else:
[8946]164            form_fields = grok.AutoFields(INigeriaUGStudentClearance).omit(
[12107]165            'clearance_locked', 'clr_code', 'officer_comment',
[12120]166            'physical_clearance_date')
[8862]167        return form_fields
168
[13058]169class NigeriaExportPDFCourseRegistrationSlip(ExportPDFCourseRegistrationSlip):
[9376]170    """Deliver a PDF slip of the context.
171    """
[9704]172    omit_fields = ('password', 'suspended', 'suspended_comment',
[13712]173        'phone', 'adm_code', 'sex', 'email', 'date_of_birth', 'current_level',
174        'flash_notice')
[9376]175
[8863]176class NigeriaOnlinePaymentDisplayFormPage(OnlinePaymentDisplayFormPage):
[8862]177    """ Page to view an online payment ticket
178    """
[8863]179    grok.context(INigeriaStudentOnlinePayment)
[9774]180    form_fields = grok.AutoFields(INigeriaStudentOnlinePayment).omit(
[15687]181        'provider_amt', 'gateway_amt', 'thirdparty_amt', 'p_item','p_combi')
[8862]182    form_fields[
183        'creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
184    form_fields[
185        'payment_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
186
[8863]187class NigeriaOnlinePaymentAddFormPage(OnlinePaymentAddFormPage):
[8862]188    """ Page to add an online payment ticket
189    """
[8863]190    form_fields = grok.AutoFields(INigeriaStudentOnlinePayment).select(
[15665]191        'p_combi')
[8862]192
[13058]193class NigeriaOnlinePaymentFakeApproveView(OnlinePaymentFakeApproveView):
[8862]194    """ Disable payment approval view for students.
195
196    This view is used for browser tests only and
197    has to be neutralized here!
198    """
199    grok.name('fake_approve')
200    grok.require('waeup.managePortal')
201
202    def update(self):
203        return
204
[13058]205class NigeriaExportPDFPaymentSlip(ExportPDFPaymentSlip):
[8862]206    """Deliver a PDF slip of the context.
207    """
[8863]208    grok.context(INigeriaStudentOnlinePayment)
[9774]209    form_fields = grok.AutoFields(INigeriaStudentOnlinePayment).omit(
[15470]210        'provider_amt', 'gateway_amt', 'thirdparty_amt', 'p_item',
[15687]211        'p_split_data','p_combi')
[8862]212    form_fields['creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
213    form_fields['payment_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
[9704]214    omit_fields = ('password', 'suspended', 'suspended_comment', 'phone',
[13712]215        'adm_code', 'sex', 'email', 'date_of_birth', 'current_level',
216        'flash_notice')
[8862]217
[15796]218    def update(self):
[15844]219        if not self.context.p_state in ('waived', 'scholarship') \
220            and not self.context.r_company:
[15796]221            self.redirect(self.url(self.context))
222            return
223        return
224
[13458]225class NigeriaAccommodationManageFormPage(AccommodationManageFormPage):
226    """ Page to manage bed tickets.
227    This manage form page is for both students and students officers.
228    """
229    with_hostel_selection = False
230
[15711]231class NigeriaBedTicketAddPage(BedTicketAddPage):
232    """ Page to add a bed ticket
233    """
234    with_ac = True
235    with_bedselection = False
236
[13058]237class NigeriaExportPDFBedTicketSlip(ExportPDFBedTicketSlip):
[9376]238    """Deliver a PDF slip of the context.
239    """
[9704]240    omit_fields = ('password', 'suspended', 'suspended_comment',
[13712]241        'phone', 'adm_code', 'email', 'date_of_birth', 'current_level',
242        'flash_notice')
[9376]243
[8863]244class NigeriaStudentFilesUploadPage(StudentFilesUploadPage):
[8862]245    """ View to upload passport picture.
246
247    Students are not allowed to change the picture if they
248    passed the regular Kofa application.
249    """
250
251    def update(self):
[10707]252        # Passport pictures must not be editable if application slip
253        # exists.
[8862]254        slip = getUtility(IExtFileStore).getFileByContext(
255            self.context, 'application_slip')
[13130]256        PORTRAIT_CHANGE_STATES = getUtility(IStudentsUtils).PORTRAIT_CHANGE_STATES
257        if self.context.state not in PORTRAIT_CHANGE_STATES or slip is not None:
[8862]258            emit_lock_message(self)
259            return
260        super(StudentFilesUploadPage, self).update()
[13620]261        return
262
263class ClearStudentFinancially(UtilityView, grok.View):
[13634]264    """ Clear student financially by financial clearance officer
[13620]265    """
266    grok.context(INigeriaStudent)
267    grok.name('clear_financially')
268    grok.require('waeup.clearStudentFinancially')
269
270    def update(self):
271        if self.context.financially_cleared_by:
272            self.flash(_('This student has already been financially cleared.'),
273                       type="danger")
274            self.redirect(self.url(self.context))
275            return
276        user = get_current_principal()
277        if user is None:
278            usertitle = 'system'
279        else:
280            usertitle = getattr(user, 'public_name', None)
281            if not usertitle:
282                usertitle = user.title
283        self.context.financially_cleared_by = usertitle
284        self.context.financial_clearance_date = datetime.utcnow()
285        self.context.writeLogMessage(self,'financially cleared')
286        history = IObjectHistory(self.context)
287        history.addMessage('Financially cleared')
288        self.flash(_('Student has been financially cleared.'))
289        self.redirect(self.url(self.context))
290        return
291
292    def render(self):
293        return
294
295class WithdrawFinancialClearance(UtilityView, grok.View):
[13634]296    """ Withdraw financial clearance by financial clearance officer
[13620]297    """
298    grok.context(INigeriaStudent)
299    grok.name('withdraw_financial_clearance')
300    grok.require('waeup.clearStudentFinancially')
301
302    def update(self):
303        if not self.context.financially_cleared_by:
304            self.flash(_('This student has not yet been financially cleared.'),
305                       type="danger")
306            self.redirect(self.url(self.context))
307            return
308        self.context.financially_cleared_by = None
309        self.context.financial_clearance_date = None
310        self.context.writeLogMessage(self,'financial clearance withdrawn')
311        history = IObjectHistory(self.context)
312        history.addMessage('Financial clearance withdrawn')
313        self.flash(_('Financial clearance withdrawn.'))
314        self.redirect(self.url(self.context))
315        return
316
317    def render(self):
[13623]318        return
319
320cleared_note = """
321<br /><br /><br />
322<strong>Financially cleared on %s by %s.</strong>
323
324"""
325
[13634]326class NigeriaExportPDFFinancialClearancePage(UtilityView, grok.View):
327    """Deliver a PDF financial clearance slip.
[13623]328    """
329    grok.context(INigeriaStudent)
[13781]330    grok.name('fee_payment_history.pdf')
[13623]331    grok.require('waeup.viewStudent')
332    prefix = 'form'
333
334    omit_fields = (
335        'suspended', 'phone',
336        'adm_code', 'suspended_comment',
[13712]337        'date_of_birth', 'current_level',
338        'flash_notice')
[13623]339
340    form_fields = None
341
342    @property
343    def label(self):
344        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
[13787]345        return translate(_('Fee Payment History for'),
[13623]346            'waeup.kofa', target_language=portal_language) \
347            + ' %s' % self.context.display_fullname
348
349    def _sigsInFooter(self):
[14163]350        if not checkPermission('waeup.clearStudentFinancially', self.context):
351            return ()
[13642]352        return (_('Date, Checking Officer Signature'),
353                _('Date, Approving Officer Signature'),
[13623]354                )
355
356    @property
357    def note(self):
358        if self.context.financially_cleared_by:
359            tz = getUtility(IKofaUtils).tzinfo
360            try:
361                timestamp = to_timezone(
362                    self.context.financial_clearance_date, tz).strftime(
363                        "%Y-%m-%d %H:%M:%S")
364            except ValueError:
[13760]365                return
[13623]366            return cleared_note % (
367                timestamp, self.context.financially_cleared_by)
[13760]368        return
[13623]369
370    @property
371    def tabletitle(self):
372        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
373        tabletitle = []
374        tabletitle.append(translate(_('Successful Payments'), 'waeup.kofa',
375            target_language=portal_language))
376        return tabletitle
377
378    def render(self):
379        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
380        P_ID = translate(_('Payment Id'), 'waeup.kofa', target_language=portal_language)
381        #CD = translate(_('Creation Date'), 'waeup.kofa', target_language=portal_language)
382        PD = translate(_('Payment Date'), 'waeup.kofa', target_language=portal_language)
383        CAT = translate(_('Payment Category'), 'waeup.kofa', target_language=portal_language)
384        ITEM = translate(_('Payment Item'), 'waeup.kofa', target_language=portal_language)
385        AMT = translate(_('Amount (Naira)'), 'waeup.kofa', target_language=portal_language)
386        SSS = translate(_('Payment Session'), 'waeup.kofa', target_language=portal_language)
387        studentview = StudentBasePDFFormPage(self.context.student,
388            self.request, self.omit_fields)
389        students_utils = getUtility(IStudentsUtils)
390
391        tabledata = []
392        tableheader = []
393        tabledata.append(sorted(
394            [value for value in self.context['payments'].values()
[15842]395             if value.p_state in ('paid', 'waived', 'scholarship')],
396             key=lambda value: value.p_session))
[13634]397        tableheader.append([(P_ID,'p_id', 4.2),
[13623]398                         #(CD,'creation_date', 3),
399                         (PD,'formatted_p_date', 3),
400                         (CAT,'category', 3),
401                         (ITEM, 'p_item', 3),
402                         (AMT, 'amount_auth', 2),
403                         (SSS, 'p_session', 2),
404                         ])
405        return students_utils.renderPDF(
[13634]406            self, 'financial_clearance_slip.pdf',
[13623]407            self.context.student, studentview,
408            tableheader=tableheader,
409            tabledata=tabledata,
410            signatures=None,
411            sigs_in_footer=self._sigsInFooter(),
412            omit_fields=self.omit_fields,
413            note=self.note
414            )
Note: See TracBrowser for help on using the repository browser.