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

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

Adjust to changes in base package.

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