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

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

Show correct buttons if payment state in ('paid', 'waived', 'scholarship').

  • Property svn:keywords set to Id
File size: 15.9 KB
Line 
1## $Id: browser.py 15842 2019-11-25 11:02:44Z 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    BedTicketAddPage)
43from waeup.kofa.students.interfaces import IStudentsUtils
44from kofacustom.nigeria.students.interfaces import (
45    INigeriaStudentBase, INigeriaStudent, INigeriaStudentPersonal,
46    INigeriaStudentPersonalEdit,
47    INigeriaUGStudentClearance,INigeriaPGStudentClearance,
48    INigeriaStudentOnlinePayment
49    )
50from waeup.kofa.students.workflow import ADMITTED
51from kofacustom.nigeria.interfaces import MessageFactory as _
52
53class NigeriaOnlinePaymentBreadcrumb(OnlinePaymentBreadcrumb):
54    """A breadcrumb for payments.
55    """
56    grok.context(INigeriaStudentOnlinePayment)
57
58class NigeriaStudentBaseDisplayFormPage(StudentBaseDisplayFormPage):
59    """ Page to display student base data
60    """
61    form_fields = grok.AutoFields(INigeriaStudentBase).omit(
62        'password', 'suspended', 'suspended_comment',
63        'flash_notice', 'provisionally_cleared')
64    form_fields[
65        'financial_clearance_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
66
67class NigeriaStudentBaseManageFormPage(StudentBaseManageFormPage):
68    """ View to manage student base data
69    """
70    form_fields = grok.AutoFields(INigeriaStudentBase).omit(
71        'student_id', 'adm_code', 'suspended',
72        'financially_cleared_by', 'financial_clearance_date')
73
74class NigeriaStudentBaseEditFormPage(StudentBaseEditFormPage):
75    """ View to edit student base data
76    """
77    form_fields = grok.AutoFields(INigeriaStudentBase).select(
78        'email', 'phone')
79
80class NigeriaStudentPersonalDisplayFormPage(StudentPersonalDisplayFormPage):
81    """ Page to display student personal data
82    """
83    form_fields = grok.AutoFields(INigeriaStudentPersonal)
84    form_fields['perm_address'].custom_widget = BytesDisplayWidget
85    form_fields['next_kin_address'].custom_widget = BytesDisplayWidget
86    form_fields[
87        'personal_updated'].custom_widget = FriendlyDatetimeDisplayWidget('le')
88
89class NigeriaStudentPersonalEditFormPage(StudentPersonalEditFormPage):
90    """ Page to edit personal data
91    """
92    form_fields = grok.AutoFields(INigeriaStudentPersonalEdit).omit('personal_updated')
93
94class NigeriaStudentPersonalManageFormPage(StudentPersonalManageFormPage):
95    """ Page to edit personal data
96    """
97    form_fields = grok.AutoFields(INigeriaStudentPersonal)
98    form_fields['personal_updated'].for_display = True
99    form_fields[
100        'personal_updated'].custom_widget = FriendlyDatetimeDisplayWidget('le')
101
102class NigeriaStudentClearanceDisplayFormPage(StudentClearanceDisplayFormPage):
103    """ Page to display student clearance data
104    """
105
106    @property
107    def form_fields(self):
108        if self.context.is_postgrad:
109            form_fields = grok.AutoFields(
110                INigeriaPGStudentClearance).omit('clearance_locked')
111        else:
112            form_fields = grok.AutoFields(
113                INigeriaUGStudentClearance).omit('clearance_locked')
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
118        return form_fields
119
120class NigeriaExportPDFClearanceSlip(ExportPDFClearanceSlip):
121    """Deliver a PDF slip of the context.
122    """
123    omit_fields = ('password', 'suspended', 'suspended_comment',
124        'phone', 'adm_code', 'email', 'date_of_birth', 'current_level',
125        'flash_notice')
126
127    @property
128    def form_fields(self):
129        if self.context.is_postgrad:
130            form_fields = grok.AutoFields(
131                INigeriaPGStudentClearance).omit('clearance_locked')
132        else:
133            form_fields = grok.AutoFields(
134                INigeriaUGStudentClearance).omit('clearance_locked')
135        if not getattr(self.context, 'officer_comment'):
136            form_fields = form_fields.omit('officer_comment')
137        return form_fields
138
139class NigeriaStudentClearanceManageFormPage(StudentClearanceManageFormPage):
140    """ Page to edit student clearance data
141    """
142
143    @property
144    def form_fields(self):
145        if self.context.is_postgrad:
146            form_fields = grok.AutoFields(
147                INigeriaPGStudentClearance).omit('clr_code')
148        else:
149            form_fields = grok.AutoFields(
150                INigeriaUGStudentClearance).omit('clr_code')
151        return form_fields
152
153class NigeriaStudentClearanceEditFormPage(StudentClearanceEditFormPage):
154    """ View to edit student clearance data by student
155    """
156
157    @property
158    def form_fields(self):
159        if self.context.is_postgrad:
160            form_fields = grok.AutoFields(INigeriaPGStudentClearance).omit(
161            'clearance_locked', 'nysc_location', 'clr_code', 'officer_comment',
162            'physical_clearance_date')
163        else:
164            form_fields = grok.AutoFields(INigeriaUGStudentClearance).omit(
165            'clearance_locked', 'clr_code', 'officer_comment',
166            'physical_clearance_date')
167        return form_fields
168
169class NigeriaExportPDFCourseRegistrationSlip(ExportPDFCourseRegistrationSlip):
170    """Deliver a PDF slip of the context.
171    """
172    omit_fields = ('password', 'suspended', 'suspended_comment',
173        'phone', 'adm_code', 'sex', 'email', 'date_of_birth', 'current_level',
174        'flash_notice')
175
176class NigeriaOnlinePaymentDisplayFormPage(OnlinePaymentDisplayFormPage):
177    """ Page to view an online payment ticket
178    """
179    grok.context(INigeriaStudentOnlinePayment)
180    form_fields = grok.AutoFields(INigeriaStudentOnlinePayment).omit(
181        'provider_amt', 'gateway_amt', 'thirdparty_amt', 'p_item','p_combi')
182    form_fields[
183        'creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
184    form_fields[
185        'payment_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
186
187class NigeriaOnlinePaymentAddFormPage(OnlinePaymentAddFormPage):
188    """ Page to add an online payment ticket
189    """
190    form_fields = grok.AutoFields(INigeriaStudentOnlinePayment).select(
191        'p_combi')
192
193class NigeriaOnlinePaymentFakeApproveView(OnlinePaymentFakeApproveView):
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
205class NigeriaExportPDFPaymentSlip(ExportPDFPaymentSlip):
206    """Deliver a PDF slip of the context.
207    """
208    grok.context(INigeriaStudentOnlinePayment)
209    form_fields = grok.AutoFields(INigeriaStudentOnlinePayment).omit(
210        'provider_amt', 'gateway_amt', 'thirdparty_amt', 'p_item',
211        'p_split_data','p_combi')
212    form_fields['creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
213    form_fields['payment_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
214    omit_fields = ('password', 'suspended', 'suspended_comment', 'phone',
215        'adm_code', 'sex', 'email', 'date_of_birth', 'current_level',
216        'flash_notice')
217
218    def update(self):
219        if not self.context.r_company:
220            self.redirect(self.url(self.context))
221            return
222        return
223
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
230class NigeriaBedTicketAddPage(BedTicketAddPage):
231    """ Page to add a bed ticket
232    """
233    with_ac = True
234    with_bedselection = False
235
236class NigeriaExportPDFBedTicketSlip(ExportPDFBedTicketSlip):
237    """Deliver a PDF slip of the context.
238    """
239    omit_fields = ('password', 'suspended', 'suspended_comment',
240        'phone', 'adm_code', 'email', 'date_of_birth', 'current_level',
241        'flash_notice')
242
243class NigeriaStudentFilesUploadPage(StudentFilesUploadPage):
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):
251        # Passport pictures must not be editable if application slip
252        # exists.
253        slip = getUtility(IExtFileStore).getFileByContext(
254            self.context, 'application_slip')
255        PORTRAIT_CHANGE_STATES = getUtility(IStudentsUtils).PORTRAIT_CHANGE_STATES
256        if self.context.state not in PORTRAIT_CHANGE_STATES or slip is not None:
257            emit_lock_message(self)
258            return
259        super(StudentFilesUploadPage, self).update()
260        return
261
262class ClearStudentFinancially(UtilityView, grok.View):
263    """ Clear student financially by financial clearance officer
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):
295    """ Withdraw financial clearance by financial clearance officer
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):
317        return
318
319cleared_note = """
320<br /><br /><br />
321<strong>Financially cleared on %s by %s.</strong>
322
323"""
324
325class NigeriaExportPDFFinancialClearancePage(UtilityView, grok.View):
326    """Deliver a PDF financial clearance slip.
327    """
328    grok.context(INigeriaStudent)
329    grok.name('fee_payment_history.pdf')
330    grok.require('waeup.viewStudent')
331    prefix = 'form'
332
333    omit_fields = (
334        'suspended', 'phone',
335        'adm_code', 'suspended_comment',
336        'date_of_birth', 'current_level',
337        'flash_notice')
338
339    form_fields = None
340
341    @property
342    def label(self):
343        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
344        return translate(_('Fee Payment History for'),
345            'waeup.kofa', target_language=portal_language) \
346            + ' %s' % self.context.display_fullname
347
348    def _sigsInFooter(self):
349        if not checkPermission('waeup.clearStudentFinancially', self.context):
350            return ()
351        return (_('Date, Checking Officer Signature'),
352                _('Date, Approving Officer Signature'),
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:
364                return
365            return cleared_note % (
366                timestamp, self.context.financially_cleared_by)
367        return
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()
394             if value.p_state in ('paid', 'waived', 'scholarship')],
395             key=lambda value: value.p_session))
396        tableheader.append([(P_ID,'p_id', 4.2),
397                         #(CD,'creation_date', 3),
398                         (PD,'formatted_p_date', 3),
399                         (CAT,'category', 3),
400                         (ITEM, 'p_item', 3),
401                         (AMT, 'amount_auth', 2),
402                         (SSS, 'p_session', 2),
403                         ])
404        return students_utils.renderPDF(
405            self, 'financial_clearance_slip.pdf',
406            self.context.student, studentview,
407            tableheader=tableheader,
408            tabledata=tabledata,
409            signatures=None,
410            sigs_in_footer=self._sigsInFooter(),
411            omit_fields=self.omit_fields,
412            note=self.note
413            )
Note: See TracBrowser for help on using the repository browser.