source: main/waeup.kofa/branches/uli-fix-zc-async/src/waeup/kofa/students/viewlets.py @ 17731

Last change on this file since 17731 was 17217, checked in by Henrik Bettermann, 2 years ago

‚Approve payment‘ should always be the last button.

  • Property svn:keywords set to Id
File size: 29.3 KB
Line 
1## $Id: viewlets.py 17217 2022-12-13 11:52:26Z henrik $
2##
3## Copyright (C) 2011 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.component import getUtility
20from zope.i18n import translate
21from zope.interface import Interface
22from waeup.kofa.browser.layout import default_primary_nav_template
23from waeup.kofa.browser.viewlets import (
24    PrimaryNavTab, ManageActionButton, AddActionButton)
25from waeup.kofa.interfaces import MessageFactory as _
26from waeup.kofa.interfaces import IExtFileStore, IKofaObject
27from waeup.kofa.students.browser import (
28    StudentsContainerPage, StudentsContainerManagePage,
29    StudentBaseDisplayFormPage, StudentClearanceDisplayFormPage,
30    StudentPersonalDisplayFormPage, StudyCourseDisplayFormPage,
31    StudyLevelDisplayFormPage, CourseTicketDisplayFormPage,
32    OnlinePaymentDisplayFormPage, BedTicketDisplayFormPage,
33    StudentClearanceEditFormPage, StudentPersonalEditFormPage,
34    PaymentsManageFormPage, StudyCourseTranscriptPage)
35from waeup.kofa.students.interfaces import (
36    IStudentsContainer, IStudent, IStudentStudyCourse, IStudentStudyLevel,
37    ICourseTicket, IStudentOnlinePayment, IBedTicket,
38    IStudentPaymentsContainer, IStudentsUtils,
39    )
40from waeup.kofa.students.workflow import (
41    ADMITTED, PAID, REQUESTED, CLEARED, REGISTERED, VALIDATED, GRADUATED,
42    TRANSREQ, TRANSVAL, TRANSREL)
43
44
45grok.context(IKofaObject)  # Make IKofaObject the default context
46grok.templatedir('browser_templates')
47
48
49class StudentManageSidebar(grok.ViewletManager):
50    grok.name('left_studentmanage')
51
52
53class StudentManageLink(grok.Viewlet):
54    """A link displayed in the student box which shows up for StudentNavigation
55    objects.
56
57    """
58    grok.baseclass()
59    grok.viewletmanager(StudentManageSidebar)
60    grok.context(IKofaObject)
61    grok.view(Interface)
62    grok.order(5)
63    grok.require('waeup.viewStudent')
64
65    link = 'index'
66    text = _(u'Base Data')
67
68    def render(self):
69        url = self.view.url(self.context.student, self.link)
70        # Here we know that the cookie has been set
71        lang = self.request.cookies.get('kofa.language')
72        text = translate(
73            self.text, 'waeup.kofa', target_language=lang)
74        if not self.link:
75            return ''
76        return u'<li><a href="%s">%s</a></li>' % (
77            url, text)
78
79
80class StudentManageApplicationLink(StudentManageLink):
81    grok.order(1)
82    link = 'application_slip'
83    text = _(u'Application Slip')
84
85    def render(self):
86        slip = getUtility(IExtFileStore).getFileByContext(
87            self.context.student, attr=self.link)
88        if slip:
89            lang = self.request.cookies.get('kofa.language')
90            text = translate(
91                self.text, 'waeup.kofa', target_language=lang)
92            url = self.view.url(self.context.student, self.link)
93            return u'<li><a href="%s">%s</a></li>' % (
94                url, text)
95        return ''
96
97class StudentManageBaseLink(StudentManageLink):
98    grok.order(2)
99    link = 'index'
100    text = _(u'Base Data')
101
102
103class StudentManageClearanceLink(StudentManageLink):
104    grok.order(3)
105    grok.name('studentmanageclearancelink')
106    link = 'view_clearance'
107    text = _(u'Clearance Data')
108
109
110class StudentManagePersonalLink(StudentManageLink):
111    grok.order(4)
112    grok.name('studentmanagepersonallink')
113    link = 'view_personal'
114    text = _(u'Personal Data')
115
116
117class StudentManageStudyCourseLink(StudentManageLink):
118    grok.order(5)
119    link = 'studycourse'
120    text = _(u'Study Course')
121
122
123class StudentManagePaymentsLink(StudentManageLink):
124    grok.order(6)
125    grok.require('waeup.viewStudent')
126    link = 'payments'
127    text = _(u'Payments')
128
129
130class StudentManageAccommodationLink(StudentManageLink):
131    grok.order(7)
132    grok.name('studentmanageaccommodationlink')
133    grok.require('waeup.viewStudent')
134    link = 'accommodation'
135    text = _(u'Accommodation')
136
137
138class StudentManageHistoryLink(StudentManageLink):
139    grok.order(8)
140    link = 'history'
141    text = _(u'History')
142
143
144class StudentManageTranscriptLink(StudentManageLink):
145    grok.order(9)
146    link = 'final_transcript'
147    text = _(u'Final Transcript')
148
149    def render(self):
150        slip = getUtility(IExtFileStore).getFileByContext(
151            self.context.student, attr=self.link)
152        if slip:
153            lang = self.request.cookies.get('kofa.language')
154            text = translate(
155                self.text, 'waeup.kofa', target_language=lang)
156            url = self.view.url(self.context.student, self.link)
157            return u'<li><a href="%s">%s</a></li>' % (
158                url, text)
159        return ''
160
161
162class StudentsContainerManageActionButton(ManageActionButton):
163    grok.order(1)
164    grok.context(IStudentsContainer)
165    grok.view(StudentsContainerPage)
166    grok.require('waeup.manageStudent')
167    text = _('Manage students section')
168
169
170class StudentsContainerAddActionButton(AddActionButton):
171    grok.order(1)
172    grok.context(IStudentsContainer)
173    grok.view(StudentsContainerManagePage)
174    grok.require('waeup.manageStudent')
175    text = _('Add student')
176    target = 'addstudent'
177
178
179class ContactActionButton(ManageActionButton):
180    grok.order(5)
181    grok.context(IStudent)
182    grok.view(StudentBaseDisplayFormPage)
183    grok.require('waeup.viewStudent')
184    icon = 'actionicon_mail.png'
185    text = _('Send email')
186    target = 'contactstudent'
187
188
189class StudentBaseManageActionButton(ManageActionButton):
190    grok.order(1)
191    grok.context(IStudent)
192    grok.view(StudentBaseDisplayFormPage)
193    grok.require('waeup.manageStudent')
194    text = _('Manage')
195    target = 'manage_base'
196
197
198class StudentTrigTransActionButton(ManageActionButton):
199    grok.order(2)
200    grok.context(IStudent)
201    grok.view(StudentBaseDisplayFormPage)
202    grok.require('waeup.triggerTransition')
203    icon = 'actionicon_trigtrans.png'
204    text = _(u'Trigger transition')
205    target = 'trigtrans'
206
207
208class StudentLoginAsActionButton(ManageActionButton):
209    grok.order(3)
210    grok.context(IStudent)
211    grok.view(StudentBaseDisplayFormPage)
212    grok.require('waeup.loginAsStudent')
213    icon = 'actionicon_mask.png'
214    text = _(u'Login as student')
215    target = 'loginasstep1'
216
217
218class AdmissionSlipActionButton(ManageActionButton):
219    grok.order(4)
220    grok.context(IStudent)
221    grok.view(StudentBaseDisplayFormPage)
222    grok.require('waeup.viewStudent')
223    icon = 'actionicon_pdf.png'
224    text = _('Download admission letter')
225    target = 'admission_slip.pdf'
226
227
228class StudentTransferButton(ManageActionButton):
229    grok.order(6)
230    grok.context(IStudent)
231    grok.view(StudentBaseDisplayFormPage)
232    grok.require('waeup.manageStudent')
233    text = _('Transfer student')
234    target = 'transfer'
235    icon = 'actionicon_redo.png'
236
237
238class StudentDeactivateActionButton(ManageActionButton):
239    grok.order(7)
240    grok.context(IStudent)
241    grok.view(StudentBaseDisplayFormPage)
242    grok.require('waeup.manageStudent')
243    text = _('Deactivate account')
244    target = 'deactivate'
245    icon = 'actionicon_traffic_lights_red.png'
246
247    @property
248    def target_url(self):
249        if self.context.suspended:
250            return ''
251        return self.view.url(self.view.context, self.target)
252
253    @property
254    def onclick(self):
255        return "return window.confirm(%s);" % _(
256            "'A history message will be added. Are you sure?'")
257
258
259class StudentActivateActionButton(ManageActionButton):
260    grok.order(7)
261    grok.context(IStudent)
262    grok.view(StudentBaseDisplayFormPage)
263    grok.require('waeup.manageStudent')
264    text = _('Activate account')
265    target = 'activate'
266    icon = 'actionicon_traffic_lights_green.png'
267
268    @property
269    def target_url(self):
270        if not self.context.suspended:
271            return ''
272        return self.view.url(self.view.context, self.target)
273
274    @property
275    def onclick(self):
276        return "return window.confirm(%s);" % _(
277            "'A history message will be added. Are you sure?'")
278
279
280class StudentClearanceManageActionButton(ManageActionButton):
281    grok.order(1)
282    grok.context(IStudent)
283    grok.view(StudentClearanceDisplayFormPage)
284    grok.require('waeup.manageStudent')
285    text = _('Manage')
286    target = 'manage_clearance'
287
288
289class StudentClearActionButton(ManageActionButton):
290    grok.order(2)
291    grok.context(IStudent)
292    grok.view(StudentClearanceDisplayFormPage)
293    grok.require('waeup.clearStudent')
294    text = _('Clear student')
295    target = 'clear'
296    icon = 'actionicon_accept.png'
297
298    @property
299    def target_url(self):
300        cdm = getUtility(
301            IStudentsUtils).clearance_disabled_message(self.context)
302        if cdm:
303            return ''
304        if self.context.state != REQUESTED:
305            return ''
306        return self.view.url(self.view.context, self.target)
307
308class StudentTemporarilyClearActionButton(ManageActionButton):
309    grok.order(3)
310    grok.context(IStudent)
311    grok.view(StudentClearanceDisplayFormPage)
312    grok.require('waeup.clearStudent')
313    text = _('Clear student temporarily')
314    target = 'temp_clearance'
315    icon = 'actionicon_accept.png'
316
317    @property
318    def target_url(self):
319        cdm = getUtility(
320            IStudentsUtils).clearance_disabled_message(self.context)
321        if cdm:
322            return ''
323        if self.context.officer_comment \
324            and self.context.officer_comment.startswith('Temporarily cleared'):
325            return ''
326        if self.context.state != REQUESTED:
327            return ''
328        return self.view.url(self.view.context, self.target)
329
330
331class StudentRejectClearanceActionButton(ManageActionButton):
332    grok.order(4)
333    grok.context(IStudent)
334    grok.view(StudentClearanceDisplayFormPage)
335    grok.require('waeup.clearStudent')
336    text = _('Reject clearance')
337    target = 'reject_clearance'
338    icon = 'actionicon_reject.png'
339
340    @property
341    def target_url(self):
342        cdm = getUtility(
343            IStudentsUtils).clearance_disabled_message(self.context)
344        if cdm:
345            return ''
346        if self.context.state not in (REQUESTED, CLEARED):
347            return ''
348        return self.view.url(self.view.context, self.target)
349
350
351class ClearanceSlipActionButton(ManageActionButton):
352    grok.order(5)
353    grok.context(IStudent)
354    grok.view(StudentClearanceDisplayFormPage)
355    grok.require('waeup.viewStudent')
356    icon = 'actionicon_pdf.png'
357    text = _('Download clearance slip')
358    target = 'clearance_slip.pdf'
359
360
361class ClearanceViewActionButton(ManageActionButton):
362    grok.order(1)
363    grok.context(IStudent)
364    grok.view(StudentClearanceEditFormPage)
365    grok.require('waeup.viewStudent')
366    icon = 'actionicon_view.png'
367    text = _('View')
368    target = 'view_clearance'
369
370
371class PersonalViewActionButton(ManageActionButton):
372    grok.order(1)
373    grok.context(IStudent)
374    grok.view(StudentPersonalEditFormPage)
375    grok.require('waeup.viewStudent')
376    icon = 'actionicon_view.png'
377    text = _('View')
378    target = 'view_personal'
379
380
381class StudentPersonalManageActionButton(ManageActionButton):
382    grok.order(1)
383    grok.context(IStudent)
384    grok.view(StudentPersonalDisplayFormPage)
385    grok.require('waeup.manageStudent')
386    text = _('Manage')
387    target = 'manage_personal'
388
389
390class StudentPersonalEditActionButton(ManageActionButton):
391    grok.order(2)
392    grok.context(IStudent)
393    grok.view(StudentPersonalDisplayFormPage)
394    grok.require('waeup.handleStudent')
395    text = _('Edit')
396    target = 'edit_personal'
397
398
399class StudyCourseManageActionButton(ManageActionButton):
400    grok.order(1)
401    grok.context(IStudentStudyCourse)
402    grok.view(StudyCourseDisplayFormPage)
403    grok.require('waeup.manageStudent')
404    text = _('Manage')
405    target = 'manage'
406
407    @property
408    def target_url(self):
409        if self.context.is_current:
410            return self.view.url(self.view.context, self.target)
411        return False
412
413
414class RevertTransferActionButton(ManageActionButton):
415    grok.order(1)
416    grok.context(IStudentStudyCourse)
417    grok.view(StudyCourseDisplayFormPage)
418    grok.require('waeup.manageStudent')
419    icon = 'actionicon_undo.png'
420    text = _('Reactivate this study course (revert previous transfer)')
421    target = 'revert_transfer'
422
423    @property
424    def target_url(self):
425        if self.context.is_previous:
426            return self.view.url(self.view.context.__parent__, self.target)
427        return False
428
429
430class StudyLevelManageActionButton(ManageActionButton):
431    grok.order(1)
432    grok.context(IStudentStudyLevel)
433    grok.view(StudyLevelDisplayFormPage)
434    grok.require('waeup.manageStudent')
435    text = _('Manage')
436    target = 'manage'
437
438    @property
439    def target_url(self):
440        is_current = self.context.__parent__.is_current
441        if not is_current:
442            return ''
443        return self.view.url(self.view.context, self.target)
444
445
446class StudentValidateCoursesActionButton(ManageActionButton):
447    grok.order(3)
448    grok.context(IStudentStudyLevel)
449    grok.view(StudyLevelDisplayFormPage)
450    grok.require('waeup.validateStudent')
451    text = _('Validate courses')
452    target = 'validate_courses'
453    icon = 'actionicon_accept.png'
454
455    @property
456    def target_url(self):
457        if not self.context.__parent__.is_current:
458            return ''
459        if self.context.student.state != REGISTERED:
460            return ''
461        if str(self.context.__parent__.current_level) != self.context.__name__:
462            return ''
463        return self.view.url(self.view.context, self.target)
464
465
466class StudentRejectCoursesActionButton(ManageActionButton):
467    grok.order(4)
468    grok.context(IStudentStudyLevel)
469    grok.view(StudyLevelDisplayFormPage)
470    grok.require('waeup.validateStudent')
471    text = _('Reject courses')
472    target = 'reject_courses'
473    icon = 'actionicon_reject.png'
474
475    @property
476    def target_url(self):
477        if not self.context.__parent__.is_current:
478            return ''
479        if self.context.student.state not in (VALIDATED, REGISTERED):
480            return ''
481        if str(self.context.__parent__.current_level) != self.context.__name__:
482            return ''
483        return self.view.url(self.view.context, self.target)
484
485
486class StudentUnregisterCoursesActionButton(ManageActionButton):
487    grok.order(5)
488    grok.context(IStudentStudyLevel)
489    grok.view(StudyLevelDisplayFormPage)
490    grok.require('waeup.handleStudent')
491    text = _('Unregister courses')
492    target = 'unregister_courses'
493    icon = 'actionicon_reject.png'
494
495    @property
496    def onclick(self):
497        return "return window.confirm(%s);" % _(
498            "'You really want to unregister your course list?'")
499
500    @property
501    def target_url(self):
502        if not self.context.__parent__.is_current:
503            return ''
504        if self.context.student.state != REGISTERED:
505            return ''
506        if str(self.context.__parent__.current_level) != self.context.__name__:
507            return ''
508        return self.view.url(self.view.context, self.target)
509
510
511class CourseRegistrationSlipActionButton(ManageActionButton):
512    grok.order(6)
513    grok.context(IStudentStudyLevel)
514    grok.view(StudyLevelDisplayFormPage)
515    grok.require('waeup.viewStudent')
516    icon = 'actionicon_pdf.png'
517    text = _('Download course registration slip')
518    target = 'course_registration_slip.pdf'
519
520    @property
521    def target_url(self):
522        is_current = self.context.__parent__.is_current
523        if not is_current:
524            return ''
525        return self.view.url(self.view.context, self.target)
526
527
528class CourseTicketManageActionButton(ManageActionButton):
529    grok.order(1)
530    grok.context(ICourseTicket)
531    grok.view(CourseTicketDisplayFormPage)
532    grok.require('waeup.manageStudent')
533    text = _('Manage')
534    target = 'manage'
535
536
537class PaymentReceiptActionButton(ManageActionButton):
538    grok.order(9)  # This button should always be the last one.
539    grok.context(IStudentOnlinePayment)
540    grok.view(OnlinePaymentDisplayFormPage)
541    grok.require('waeup.viewStudent')
542    icon = 'actionicon_pdf.png'
543    text = _('Download payment slip')
544    target = 'payment_slip.pdf'
545
546    @property
547    def target_url(self):
548        #if self.context.p_state != 'paid':
549        #    return ''
550        return self.view.url(self.view.context, self.target)
551
552
553class ApprovePaymentActionButton(ManageActionButton):
554    grok.order(20)
555    grok.context(IStudentOnlinePayment)
556    grok.view(OnlinePaymentDisplayFormPage)
557    grok.require('waeup.managePortal')
558    icon = 'actionicon_accept.png'
559    text = _('Approve payment')
560    target = 'approve'
561
562    @property
563    def target_url(self):
564        if self.context.p_state in ('paid', 'waived', 'scholarship'):
565            return ''
566        return self.view.url(self.view.context, self.target)
567
568
569class BedTicketSlipActionButton(ManageActionButton):
570    grok.order(1)
571    grok.context(IBedTicket)
572    grok.view(BedTicketDisplayFormPage)
573    grok.require('waeup.viewStudent')
574    icon = 'actionicon_pdf.png'
575    text = _('Download bed allocation slip')
576    target = 'bed_allocation_slip.pdf'
577
578
579class RelocateStudentActionButton(ManageActionButton):
580    grok.order(2)
581    grok.context(IBedTicket)
582    grok.view(BedTicketDisplayFormPage)
583    grok.require('waeup.manageHostels')
584    icon = 'actionicon_reload.png'
585    text = _('Relocate student')
586    target = 'relocate'
587
588
589class StudentBaseActionButton(ManageActionButton):
590    grok.order(1)
591    grok.context(IStudent)
592    grok.view(StudentBaseDisplayFormPage)
593    grok.require('waeup.handleStudent')
594    text = _('Edit')
595    target = 'edit_base'
596
597
598class StudentPasswordActionButton(ManageActionButton):
599    grok.order(2)
600    grok.context(IStudent)
601    grok.view(StudentBaseDisplayFormPage)
602    grok.require('waeup.handleStudent')
603    icon = 'actionicon_key.png'
604    text = _('Change password')
605    target = 'change_password'
606
607
608class StudentPassportActionButton(ManageActionButton):
609    grok.order(3)
610    grok.context(IStudent)
611    grok.view(StudentBaseDisplayFormPage)
612    grok.require('waeup.handleStudent')
613    icon = 'actionicon_portrait.png'
614    text = _('Change portrait')
615    target = 'change_portrait'
616
617    @property
618    def target_url(self):
619        if not getUtility(IStudentsUtils).allowPortraitChange(self.context):
620            return ''
621        return self.view.url(self.view.context, self.target)
622
623class StudentSignatureActionButton(ManageActionButton):
624    grok.order(4)
625    grok.context(IStudent)
626    grok.view(StudentBaseDisplayFormPage)
627    grok.require('waeup.handleStudent')
628    icon = 'actionicon_signature.png'
629    text = _('Upload signature')
630    target = 'change_signature'
631
632    @property
633    def target_url(self):
634        SIGNATURE_CHANGE_STATES = getUtility(
635            IStudentsUtils).SIGNATURE_CHANGE_STATES
636        if self.context.state not in SIGNATURE_CHANGE_STATES:
637            return ''
638        return self.view.url(self.view.context, self.target)
639
640
641class StudentClearanceStartActionButton(ManageActionButton):
642    grok.order(1)
643    grok.context(IStudent)
644    grok.view(StudentClearanceDisplayFormPage)
645    grok.require('waeup.handleStudent')
646    icon = 'actionicon_start.gif'
647    text = _('Start clearance')
648    target = 'start_clearance'
649
650    @property
651    def target_url(self):
652        if self.context.state != ADMITTED:
653            return ''
654        return self.view.url(self.view.context, self.target)
655
656
657class StudentClearanceEditActionButton(ManageActionButton):
658    grok.order(1)
659    grok.context(IStudent)
660    grok.view(StudentClearanceDisplayFormPage)
661    grok.require('waeup.handleStudent')
662    text = _('Edit')
663    target = 'cedit'
664
665    @property
666    def target_url(self):
667        if self.context.clearance_locked:
668            return ''
669        return self.view.url(self.view.context, self.target)
670
671
672class StartSessionActionButton(ManageActionButton):
673    grok.order(1)
674    grok.context(IStudentStudyCourse)
675    grok.view(StudyCourseDisplayFormPage)
676    grok.require('waeup.handleStudent')
677    icon = 'actionicon_start.gif'
678    text = _('Start new session')
679    target = 'start_session'
680
681    @property
682    def target_url(self):
683        if self.context.next_session_allowed and self.context.is_current:
684            return self.view.url(self.view.context, self.target)
685        return False
686
687
688class AddStudyLevelActionButton(AddActionButton):
689    grok.order(1)
690    grok.context(IStudentStudyCourse)
691    grok.view(StudyCourseDisplayFormPage)
692    grok.require('waeup.handleStudent')
693    text = _('Add course list')
694    target = 'add'
695
696    @property
697    def target_url(self):
698        student = self.view.context.student
699        condition1 = student.state != PAID
700        condition2 = str(student['studycourse'].current_level) in \
701            self.view.context.keys()
702        condition3 = not self.context.is_current
703        if condition1 or condition2 or condition3:
704            return ''
705        return self.view.url(self.view.context, self.target)
706
707
708class StudyLevelEditActionButton(ManageActionButton):
709    grok.order(2)
710    grok.context(IStudentStudyLevel)
711    grok.view(StudyLevelDisplayFormPage)
712    grok.require('waeup.editStudyLevel')
713    text = _('Edit course list')
714    target = 'edit'
715
716    @property
717    def target_url(self):
718        student = self.view.context.student
719        condition1 = student.state == PAID
720        condition2 = self.view.context.is_current_level
721        is_current = self.context.__parent__.is_current
722        if condition1 and condition2 and is_current:
723            return self.view.url(self.view.context, self.target)
724        return ''
725
726
727class AddPaymentActionButton(AddActionButton):
728    grok.order(1)
729    grok.context(IStudentPaymentsContainer)
730    grok.view(PaymentsManageFormPage)
731    grok.require('waeup.payStudent')
732    text = _('Add current session payment ticket')
733    target = 'addop'
734
735
736class AddPreviousPaymentActionButton(AddActionButton):
737    grok.order(2)
738    grok.context(IStudentPaymentsContainer)
739    grok.view(PaymentsManageFormPage)
740    grok.require('waeup.payStudent')
741    grok.name('addpreviouspaymentactionbutton')
742    text = _('Add previous session payment ticket')
743    target = 'addpp'
744
745    @property
746    def target_url(self):
747        student = self.view.context.student
748        if student.before_payment or not self.target:
749            return ''
750        return self.view.url(self.view.context, self.target)
751
752
753class AddBalancePaymentActionButton(AddActionButton):
754    grok.order(3)
755    grok.context(IStudentPaymentsContainer)
756    grok.view(PaymentsManageFormPage)
757    grok.require('waeup.manageStudent')
758    grok.name('addbalancepaymentactionbutton')
759    text = _('Add balance payment ticket')
760    target = 'addbp'
761
762    @property
763    def target_url(self):
764        if not self.target:
765            return ''
766        return self.view.url(self.view.context, self.target)
767
768
769class StudyCourseTranscriptActionButton(ManageActionButton):
770    grok.order(2)
771    grok.name('transcript')
772    grok.context(IStudentStudyCourse)
773    grok.view(StudyCourseDisplayFormPage)
774    grok.require('waeup.viewTranscript')
775    text = _('Transcript')
776    target = 'transcript'
777    icon = 'actionicon_transcript.png'
778
779    @property
780    def target_url(self):
781        final_slip = getUtility(IExtFileStore).getFileByContext(
782            self.context.student, attr='final_transcript')
783        if self.context.student.transcript_enabled and not final_slip:
784            return self.view.url(self.view.context, self.target)
785        return False
786
787
788class RequestTranscriptActionButton(ManageActionButton):
789    grok.order(8)
790    grok.context(IStudent)
791    grok.view(StudentBaseDisplayFormPage)
792    grok.require('waeup.handleStudent')
793    text = _('Request transcript')
794    target = 'request_transcript'
795    icon = 'actionicon_transcript.png'
796
797    @property
798    def target_url(self):
799        if self.context.state != GRADUATED:
800            return ''
801        return self.view.url(self.view.context, self.target)
802
803class TORequestTranscriptActionButton(RequestTranscriptActionButton):
804    grok.require('waeup.processTranscript')
805    text = _('Request transcript for student')
806    target = 'request_transcript_for_student'
807
808
809class ValidateTranscriptActionButton(ManageActionButton):
810    grok.order(8)
811    grok.context(IStudentStudyCourse)
812    grok.view(StudyCourseTranscriptPage)
813    grok.require('waeup.processTranscript')
814    text = _('Validate transcript')
815    target = 'validate_transcript'
816    icon = 'actionicon_transcript.png'
817
818    @property
819    def target_url(self):
820        if self.context.student.state != TRANSREQ:
821            return ''
822        return self.view.url(self.view.context, self.target)
823
824
825class ReleaseTranscriptActionButton(ManageActionButton):
826    grok.order(8)
827    grok.context(IStudentStudyCourse)
828    grok.view(StudyCourseTranscriptPage)
829    grok.require('waeup.processTranscript')
830    text = _('Release transcript')
831    target = 'release_transcript'
832    icon = 'actionicon_transcript.png'
833
834    @property
835    def target_url(self):
836        if self.context.student.state != TRANSVAL:
837            return ''
838        return self.view.url(self.view.context, self.target)
839
840
841class TranscriptSlipActionButton(ManageActionButton):
842    grok.order(1)
843    grok.name('transcript_slip')
844    grok.context(IStudentStudyCourse)
845    grok.view(StudyCourseTranscriptPage)
846    grok.require('waeup.downloadTranscript')
847    text = _('Academic Transcript')
848    target = 'transcript.pdf'
849    icon = 'actionicon_pdf.png'
850
851    @property
852    def target_url(self):
853        final_slip = getUtility(IExtFileStore).getFileByContext(
854            self.context.student, attr='final_transcript')
855        if self.context.student.transcript_enabled \
856            and not final_slip:
857            return self.view.url(self.view.context, self.target)
858        return False
859
860
861class SignTranscriptActionButton(ManageActionButton):
862    grok.order(2)
863    grok.context(IStudentStudyCourse)
864    grok.view(StudyCourseTranscriptPage)
865    grok.require('waeup.signTranscript')
866    text = _('Sign transcript electronically')
867    target = 'sign_transcript'
868    icon = 'actionicon_transcript.png'
869
870    @property
871    def target_url(self):
872        if self.context.student.state != TRANSVAL:
873            return ''
874        return self.view.url(self.view.context, self.target)
875
876    @property
877    def onclick(self):
878        return "return window.confirm(%s);" % _(
879            "'Signing a transcript electronically cannot be revoked. "
880            "The electronic signature replaces your handwritten signature.\\n\\n"
881            "You really want to sign the transcript?'")
882
883
884class StudentsTab(PrimaryNavTab):
885    """Students tab in primary navigation.
886    """
887    grok.context(IKofaObject)
888    grok.order(4)
889    grok.require('waeup.viewStudentsContainer')
890    grok.name('studentstab')
891
892    pnav = 4
893    tab_title = _(u'Students')
894
895    @property
896    def link_target(self):
897        return self.view.application_url('students')
898
899
900class PrimaryStudentNavManager(grok.ViewletManager):
901    """Viewlet manager for the primary navigation tab.
902    """
903    grok.name('primary_nav_student')
904
905
906class PrimaryStudentNavTab(grok.Viewlet):
907    """Base for primary student nav tabs.
908    """
909    grok.baseclass()
910    grok.context(IKofaObject)
911    grok.viewletmanager(PrimaryStudentNavManager)
912    template = default_primary_nav_template
913    grok.order(1)
914    grok.require('waeup.Authenticated')
915    pnav = 0
916    tab_title = u'Some Text'
917
918    @property
919    def link_target(self):
920        return self.view.application_url()
921
922    @property
923    def active(self):
924        view_pnav = getattr(self.view, 'pnav', 0)
925        if view_pnav == self.pnav:
926            return 'active'
927        return ''
928
929
930class MyStudentDataTab(PrimaryStudentNavTab):
931    """MyData dropdown tab in primary navigation.
932    """
933    grok.order(3)
934    grok.require('waeup.viewMyStudentDataTab')
935    grok.template('mydatadropdowntabs')
936    grok.name('mystudentdatatab')
937    pnav = 4
938    tab_title = _(u'My Data')
939
940    @property
941    def active(self):
942        view_pnav = getattr(self.view, 'pnav', 0)
943        if view_pnav == self.pnav:
944            return 'active dropdown'
945        return 'dropdown'
946
947    @property
948    def targets(self):
949        student = grok.getSite()['students'][self.request.principal.id]
950        student_url = self.view.url(student)
951        app_slip = getUtility(IExtFileStore).getFileByContext(
952            student, 'application_slip')
953        targets = []
954        if student.getParentsPassword():
955            targets += [
956                {'url': student_url, 'title': 'Base Data'},
957                {'url': student_url + '/studycourse', 'title': _('Study Course')},
958                {'url': student_url + '/payments', 'title': _('Payments')},
959                ]
960            return targets
961        if app_slip:
962            targets = [{'url': student_url + '/application_slip',
963                        'title': _('Application Slip')}, ]
964        targets += [
965            {'url': student_url, 'title': 'Base Data'},
966            {'url': student_url + '/view_clearance',
967             'title': _('Clearance Data')},
968            {'url': student_url + '/view_personal',
969             'title': _('Personal Data')},
970            {'url': student_url + '/studycourse', 'title': _('Study Course')},
971            {'url': student_url + '/payments', 'title': _('Payments')},
972            {'url': student_url + '/accommodation',
973             'title': _('Accommodation Data')},
974            {'url': student_url + '/history', 'title': _('History')},
975            ]
976        return targets
Note: See TracBrowser for help on using the repository browser.