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

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

Customize BedTicketAddPage?

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