source: main/waeup.kofa/trunk/src/waeup/kofa/students/viewlets.py @ 17867

Last change on this file since 17867 was 17867, checked in by Henrik Bettermann, 7 weeks ago

Implement Final Year Clearance Routing Slip upload (not active in base package).

  • Property svn:keywords set to Id
File size: 29.9 KB
Line 
1## $Id: viewlets.py 17867 2024-08-02 19:10:34Z 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
640class StudentFinalClearanceFormActionButton(ManageActionButton):
641    grok.order(5)
642    grok.context(IStudent)
643    grok.view(StudentBaseDisplayFormPage)
644    grok.require('waeup.handleStudent')
645    icon = 'actionicon_signature.png'
646    text = _('Upload final clearance routing slip')
647    target = 'routing_slip_upload'
648
649    @property
650    def target_url(self):
651        final_clearance_enabled = getUtility(
652            IStudentsUtils).final_clearance_enabled(self.context)
653        if not final_clearance_enabled:
654            return ''
655        return self.view.url(self.view.context, self.target)
656
657
658class StudentClearanceStartActionButton(ManageActionButton):
659    grok.order(1)
660    grok.context(IStudent)
661    grok.view(StudentClearanceDisplayFormPage)
662    grok.require('waeup.handleStudent')
663    icon = 'actionicon_start.gif'
664    text = _('Start clearance')
665    target = 'start_clearance'
666
667    @property
668    def target_url(self):
669        if self.context.state != ADMITTED:
670            return ''
671        return self.view.url(self.view.context, self.target)
672
673
674class StudentClearanceEditActionButton(ManageActionButton):
675    grok.order(1)
676    grok.context(IStudent)
677    grok.view(StudentClearanceDisplayFormPage)
678    grok.require('waeup.handleStudent')
679    text = _('Edit')
680    target = 'cedit'
681
682    @property
683    def target_url(self):
684        if self.context.clearance_locked:
685            return ''
686        return self.view.url(self.view.context, self.target)
687
688
689class StartSessionActionButton(ManageActionButton):
690    grok.order(1)
691    grok.context(IStudentStudyCourse)
692    grok.view(StudyCourseDisplayFormPage)
693    grok.require('waeup.handleStudent')
694    icon = 'actionicon_start.gif'
695    text = _('Start new session')
696    target = 'start_session'
697
698    @property
699    def target_url(self):
700        if self.context.next_session_allowed and self.context.is_current:
701            return self.view.url(self.view.context, self.target)
702        return False
703
704
705class AddStudyLevelActionButton(AddActionButton):
706    grok.order(1)
707    grok.context(IStudentStudyCourse)
708    grok.view(StudyCourseDisplayFormPage)
709    grok.require('waeup.handleStudent')
710    text = _('Add course list')
711    target = 'add'
712
713    @property
714    def target_url(self):
715        student = self.view.context.student
716        condition1 = student.state != PAID
717        condition2 = str(student['studycourse'].current_level) in \
718            self.view.context.keys()
719        condition3 = not self.context.is_current
720        if condition1 or condition2 or condition3:
721            return ''
722        return self.view.url(self.view.context, self.target)
723
724
725class StudyLevelEditActionButton(ManageActionButton):
726    grok.order(2)
727    grok.context(IStudentStudyLevel)
728    grok.view(StudyLevelDisplayFormPage)
729    grok.require('waeup.editStudyLevel')
730    text = _('Edit course list')
731    target = 'edit'
732
733    @property
734    def target_url(self):
735        student = self.view.context.student
736        condition1 = student.state == PAID
737        condition2 = self.view.context.is_current_level
738        is_current = self.context.__parent__.is_current
739        if condition1 and condition2 and is_current:
740            return self.view.url(self.view.context, self.target)
741        return ''
742
743
744class AddPaymentActionButton(AddActionButton):
745    grok.order(1)
746    grok.context(IStudentPaymentsContainer)
747    grok.view(PaymentsManageFormPage)
748    grok.require('waeup.payStudent')
749    text = _('Add current session payment ticket')
750    target = 'addop'
751
752
753class AddPreviousPaymentActionButton(AddActionButton):
754    grok.order(2)
755    grok.context(IStudentPaymentsContainer)
756    grok.view(PaymentsManageFormPage)
757    grok.require('waeup.payStudent')
758    grok.name('addpreviouspaymentactionbutton')
759    text = _('Add previous session payment ticket')
760    target = 'addpp'
761
762    @property
763    def target_url(self):
764        student = self.view.context.student
765        if student.before_payment or not self.target:
766            return ''
767        return self.view.url(self.view.context, self.target)
768
769
770class AddBalancePaymentActionButton(AddActionButton):
771    grok.order(3)
772    grok.context(IStudentPaymentsContainer)
773    grok.view(PaymentsManageFormPage)
774    grok.require('waeup.manageStudent')
775    grok.name('addbalancepaymentactionbutton')
776    text = _('Add balance payment ticket')
777    target = 'addbp'
778
779    @property
780    def target_url(self):
781        if not self.target:
782            return ''
783        return self.view.url(self.view.context, self.target)
784
785
786class StudyCourseTranscriptActionButton(ManageActionButton):
787    grok.order(2)
788    grok.name('transcript')
789    grok.context(IStudentStudyCourse)
790    grok.view(StudyCourseDisplayFormPage)
791    grok.require('waeup.viewTranscript')
792    text = _('Transcript')
793    target = 'transcript'
794    icon = 'actionicon_transcript.png'
795
796    @property
797    def target_url(self):
798        final_slip = getUtility(IExtFileStore).getFileByContext(
799            self.context.student, attr='final_transcript')
800        if self.context.student.transcript_enabled and not final_slip:
801            return self.view.url(self.view.context, self.target)
802        return False
803
804
805class RequestTranscriptActionButton(ManageActionButton):
806    grok.order(8)
807    grok.context(IStudent)
808    grok.view(StudentBaseDisplayFormPage)
809    grok.require('waeup.handleStudent')
810    text = _('Request transcript')
811    target = 'request_transcript'
812    icon = 'actionicon_transcript.png'
813
814    @property
815    def target_url(self):
816        if self.context.state != GRADUATED:
817            return ''
818        return self.view.url(self.view.context, self.target)
819
820class TORequestTranscriptActionButton(RequestTranscriptActionButton):
821    grok.require('waeup.processTranscript')
822    text = _('Request transcript for student')
823    target = 'request_transcript_for_student'
824
825
826class ValidateTranscriptActionButton(ManageActionButton):
827    grok.order(8)
828    grok.context(IStudentStudyCourse)
829    grok.view(StudyCourseTranscriptPage)
830    grok.require('waeup.processTranscript')
831    text = _('Validate transcript')
832    target = 'validate_transcript'
833    icon = 'actionicon_transcript.png'
834
835    @property
836    def target_url(self):
837        if self.context.student.state != TRANSREQ:
838            return ''
839        return self.view.url(self.view.context, self.target)
840
841
842class ReleaseTranscriptActionButton(ManageActionButton):
843    grok.order(8)
844    grok.context(IStudentStudyCourse)
845    grok.view(StudyCourseTranscriptPage)
846    grok.require('waeup.processTranscript')
847    text = _('Release transcript')
848    target = 'release_transcript'
849    icon = 'actionicon_transcript.png'
850
851    @property
852    def target_url(self):
853        if self.context.student.state != TRANSVAL:
854            return ''
855        return self.view.url(self.view.context, self.target)
856
857
858class TranscriptSlipActionButton(ManageActionButton):
859    grok.order(1)
860    grok.name('transcript_slip')
861    grok.context(IStudentStudyCourse)
862    grok.view(StudyCourseTranscriptPage)
863    grok.require('waeup.downloadTranscript')
864    text = _('Academic Transcript')
865    target = 'transcript.pdf'
866    icon = 'actionicon_pdf.png'
867
868    @property
869    def target_url(self):
870        final_slip = getUtility(IExtFileStore).getFileByContext(
871            self.context.student, attr='final_transcript')
872        if self.context.student.transcript_enabled \
873            and not final_slip:
874            return self.view.url(self.view.context, self.target)
875        return False
876
877
878class SignTranscriptActionButton(ManageActionButton):
879    grok.order(2)
880    grok.context(IStudentStudyCourse)
881    grok.view(StudyCourseTranscriptPage)
882    grok.require('waeup.signTranscript')
883    text = _('Sign transcript electronically')
884    target = 'sign_transcript'
885    icon = 'actionicon_transcript.png'
886
887    @property
888    def target_url(self):
889        if self.context.student.state != TRANSVAL:
890            return ''
891        return self.view.url(self.view.context, self.target)
892
893    @property
894    def onclick(self):
895        return "return window.confirm(%s);" % _(
896            "'Signing a transcript electronically cannot be revoked. "
897            "The electronic signature replaces your handwritten signature.\\n\\n"
898            "You really want to sign the transcript?'")
899
900
901class StudentsTab(PrimaryNavTab):
902    """Students tab in primary navigation.
903    """
904    grok.context(IKofaObject)
905    grok.order(4)
906    grok.require('waeup.viewStudentsContainer')
907    grok.name('studentstab')
908
909    pnav = 4
910    tab_title = _(u'Students')
911
912    @property
913    def link_target(self):
914        return self.view.application_url('students')
915
916
917class PrimaryStudentNavManager(grok.ViewletManager):
918    """Viewlet manager for the primary navigation tab.
919    """
920    grok.name('primary_nav_student')
921
922
923class PrimaryStudentNavTab(grok.Viewlet):
924    """Base for primary student nav tabs.
925    """
926    grok.baseclass()
927    grok.context(IKofaObject)
928    grok.viewletmanager(PrimaryStudentNavManager)
929    template = default_primary_nav_template
930    grok.order(1)
931    grok.require('waeup.Authenticated')
932    pnav = 0
933    tab_title = u'Some Text'
934
935    @property
936    def link_target(self):
937        return self.view.application_url()
938
939    @property
940    def active(self):
941        view_pnav = getattr(self.view, 'pnav', 0)
942        if view_pnav == self.pnav:
943            return 'active'
944        return ''
945
946
947class MyStudentDataTab(PrimaryStudentNavTab):
948    """MyData dropdown tab in primary navigation.
949    """
950    grok.order(3)
951    grok.require('waeup.viewMyStudentDataTab')
952    grok.template('mydatadropdowntabs')
953    grok.name('mystudentdatatab')
954    pnav = 4
955    tab_title = _(u'My Data')
956
957    @property
958    def active(self):
959        view_pnav = getattr(self.view, 'pnav', 0)
960        if view_pnav == self.pnav:
961            return 'active dropdown'
962        return 'dropdown'
963
964    @property
965    def targets(self):
966        student = grok.getSite()['students'][self.request.principal.id]
967        student_url = self.view.url(student)
968        app_slip = getUtility(IExtFileStore).getFileByContext(
969            student, 'application_slip')
970        targets = []
971        if student.getParentsPassword():
972            targets += [
973                {'url': student_url, 'title': 'Base Data'},
974                {'url': student_url + '/studycourse', 'title': _('Study Course')},
975                {'url': student_url + '/payments', 'title': _('Payments')},
976                ]
977            return targets
978        if app_slip:
979            targets = [{'url': student_url + '/application_slip',
980                        'title': _('Application Slip')}, ]
981        targets += [
982            {'url': student_url, 'title': 'Base Data'},
983            {'url': student_url + '/view_clearance',
984             'title': _('Clearance Data')},
985            {'url': student_url + '/view_personal',
986             'title': _('Personal Data')},
987            {'url': student_url + '/studycourse', 'title': _('Study Course')},
988            {'url': student_url + '/payments', 'title': _('Payments')},
989            {'url': student_url + '/accommodation',
990             'title': _('Accommodation Data')},
991            {'url': student_url + '/history', 'title': _('History')},
992            ]
993        return targets
Note: See TracBrowser for help on using the repository browser.