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

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

Move viewlet classes.

  • Property svn:keywords set to Id
File size: 15.8 KB
RevLine 
[8862]1## $Id: browser.py 15826 2019-11-19 13:07:22Z 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):
219        if not self.context.r_company:
220            self.redirect(self.url(self.context))
221            return
222        return
223
[13458]224class NigeriaAccommodationManageFormPage(AccommodationManageFormPage):
225    """ Page to manage bed tickets.
226    This manage form page is for both students and students officers.
227    """
228    with_hostel_selection = False
229
[15711]230class NigeriaBedTicketAddPage(BedTicketAddPage):
231    """ Page to add a bed ticket
232    """
233    with_ac = True
234    with_bedselection = False
235
[13058]236class NigeriaExportPDFBedTicketSlip(ExportPDFBedTicketSlip):
[9376]237    """Deliver a PDF slip of the context.
238    """
[9704]239    omit_fields = ('password', 'suspended', 'suspended_comment',
[13712]240        'phone', 'adm_code', 'email', 'date_of_birth', 'current_level',
241        'flash_notice')
[9376]242
[8863]243class NigeriaStudentFilesUploadPage(StudentFilesUploadPage):
[8862]244    """ View to upload passport picture.
245
246    Students are not allowed to change the picture if they
247    passed the regular Kofa application.
248    """
249
250    def update(self):
[10707]251        # Passport pictures must not be editable if application slip
252        # exists.
[8862]253        slip = getUtility(IExtFileStore).getFileByContext(
254            self.context, 'application_slip')
[13130]255        PORTRAIT_CHANGE_STATES = getUtility(IStudentsUtils).PORTRAIT_CHANGE_STATES
256        if self.context.state not in PORTRAIT_CHANGE_STATES or slip is not None:
[8862]257            emit_lock_message(self)
258            return
259        super(StudentFilesUploadPage, self).update()
[13620]260        return
261
262class ClearStudentFinancially(UtilityView, grok.View):
[13634]263    """ Clear student financially by financial clearance officer
[13620]264    """
265    grok.context(INigeriaStudent)
266    grok.name('clear_financially')
267    grok.require('waeup.clearStudentFinancially')
268
269    def update(self):
270        if self.context.financially_cleared_by:
271            self.flash(_('This student has already been financially cleared.'),
272                       type="danger")
273            self.redirect(self.url(self.context))
274            return
275        user = get_current_principal()
276        if user is None:
277            usertitle = 'system'
278        else:
279            usertitle = getattr(user, 'public_name', None)
280            if not usertitle:
281                usertitle = user.title
282        self.context.financially_cleared_by = usertitle
283        self.context.financial_clearance_date = datetime.utcnow()
284        self.context.writeLogMessage(self,'financially cleared')
285        history = IObjectHistory(self.context)
286        history.addMessage('Financially cleared')
287        self.flash(_('Student has been financially cleared.'))
288        self.redirect(self.url(self.context))
289        return
290
291    def render(self):
292        return
293
294class WithdrawFinancialClearance(UtilityView, grok.View):
[13634]295    """ Withdraw financial clearance by financial clearance officer
[13620]296    """
297    grok.context(INigeriaStudent)
298    grok.name('withdraw_financial_clearance')
299    grok.require('waeup.clearStudentFinancially')
300
301    def update(self):
302        if not self.context.financially_cleared_by:
303            self.flash(_('This student has not yet been financially cleared.'),
304                       type="danger")
305            self.redirect(self.url(self.context))
306            return
307        self.context.financially_cleared_by = None
308        self.context.financial_clearance_date = None
309        self.context.writeLogMessage(self,'financial clearance withdrawn')
310        history = IObjectHistory(self.context)
311        history.addMessage('Financial clearance withdrawn')
312        self.flash(_('Financial clearance withdrawn.'))
313        self.redirect(self.url(self.context))
314        return
315
316    def render(self):
[13623]317        return
318
319cleared_note = """
320<br /><br /><br />
321<strong>Financially cleared on %s by %s.</strong>
322
323"""
324
[13634]325class NigeriaExportPDFFinancialClearancePage(UtilityView, grok.View):
326    """Deliver a PDF financial clearance slip.
[13623]327    """
328    grok.context(INigeriaStudent)
[13781]329    grok.name('fee_payment_history.pdf')
[13623]330    grok.require('waeup.viewStudent')
331    prefix = 'form'
332
333    omit_fields = (
334        'suspended', 'phone',
335        'adm_code', 'suspended_comment',
[13712]336        'date_of_birth', 'current_level',
337        'flash_notice')
[13623]338
339    form_fields = None
340
341    @property
342    def label(self):
343        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
[13787]344        return translate(_('Fee Payment History for'),
[13623]345            'waeup.kofa', target_language=portal_language) \
346            + ' %s' % self.context.display_fullname
347
348    def _sigsInFooter(self):
[14163]349        if not checkPermission('waeup.clearStudentFinancially', self.context):
350            return ()
[13642]351        return (_('Date, Checking Officer Signature'),
352                _('Date, Approving Officer Signature'),
[13623]353                )
354
355    @property
356    def note(self):
357        if self.context.financially_cleared_by:
358            tz = getUtility(IKofaUtils).tzinfo
359            try:
360                timestamp = to_timezone(
361                    self.context.financial_clearance_date, tz).strftime(
362                        "%Y-%m-%d %H:%M:%S")
363            except ValueError:
[13760]364                return
[13623]365            return cleared_note % (
366                timestamp, self.context.financially_cleared_by)
[13760]367        return
[13623]368
369    @property
370    def tabletitle(self):
371        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
372        tabletitle = []
373        tabletitle.append(translate(_('Successful Payments'), 'waeup.kofa',
374            target_language=portal_language))
375        return tabletitle
376
377    def render(self):
378        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
379        P_ID = translate(_('Payment Id'), 'waeup.kofa', target_language=portal_language)
380        #CD = translate(_('Creation Date'), 'waeup.kofa', target_language=portal_language)
381        PD = translate(_('Payment Date'), 'waeup.kofa', target_language=portal_language)
382        CAT = translate(_('Payment Category'), 'waeup.kofa', target_language=portal_language)
383        ITEM = translate(_('Payment Item'), 'waeup.kofa', target_language=portal_language)
384        AMT = translate(_('Amount (Naira)'), 'waeup.kofa', target_language=portal_language)
385        SSS = translate(_('Payment Session'), 'waeup.kofa', target_language=portal_language)
386        studentview = StudentBasePDFFormPage(self.context.student,
387            self.request, self.omit_fields)
388        students_utils = getUtility(IStudentsUtils)
389
390        tabledata = []
391        tableheader = []
392        tabledata.append(sorted(
393            [value for value in self.context['payments'].values()
[14279]394             if value.p_state in ('paid', 'waived')], key=lambda value: value.p_session))
[13634]395        tableheader.append([(P_ID,'p_id', 4.2),
[13623]396                         #(CD,'creation_date', 3),
397                         (PD,'formatted_p_date', 3),
398                         (CAT,'category', 3),
399                         (ITEM, 'p_item', 3),
400                         (AMT, 'amount_auth', 2),
401                         (SSS, 'p_session', 2),
402                         ])
403        return students_utils.renderPDF(
[13634]404            self, 'financial_clearance_slip.pdf',
[13623]405            self.context.student, studentview,
406            tableheader=tableheader,
407            tabledata=tabledata,
408            signatures=None,
409            sigs_in_footer=self._sigsInFooter(),
410            omit_fields=self.omit_fields,
411            note=self.note
412            )
Note: See TracBrowser for help on using the repository browser.