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

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

Implement course result validation workflow for lecturers.

  • Property svn:keywords set to Id
File size: 27.4 KB
Line 
1## $Id: viewlets.py 15422 2019-05-24 09:11:40Z 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.handleAccommodation')
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.manageStudent')
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
308
309class StudentRejectClearanceActionButton(ManageActionButton):
310    grok.order(3)
311    grok.context(IStudent)
312    grok.view(StudentClearanceDisplayFormPage)
313    grok.require('waeup.clearStudent')
314    text = _('Reject clearance')
315    target = 'reject_clearance'
316    icon = 'actionicon_reject.png'
317
318    @property
319    def target_url(self):
320        cdm = getUtility(
321            IStudentsUtils).clearance_disabled_message(self.context)
322        if cdm:
323            return ''
324        if self.context.state not in (REQUESTED, CLEARED):
325            return ''
326        return self.view.url(self.view.context, self.target)
327
328
329class ClearanceSlipActionButton(ManageActionButton):
330    grok.order(4)
331    grok.context(IStudent)
332    grok.view(StudentClearanceDisplayFormPage)
333    grok.require('waeup.viewStudent')
334    icon = 'actionicon_pdf.png'
335    text = _('Download clearance slip')
336    target = 'clearance_slip.pdf'
337
338
339class ClearanceViewActionButton(ManageActionButton):
340    grok.order(1)
341    grok.context(IStudent)
342    grok.view(StudentClearanceEditFormPage)
343    grok.require('waeup.viewStudent')
344    icon = 'actionicon_view.png'
345    text = _('View')
346    target = 'view_clearance'
347
348
349class PersonalViewActionButton(ManageActionButton):
350    grok.order(1)
351    grok.context(IStudent)
352    grok.view(StudentPersonalEditFormPage)
353    grok.require('waeup.viewStudent')
354    icon = 'actionicon_view.png'
355    text = _('View')
356    target = 'view_personal'
357
358
359class StudentPersonalManageActionButton(ManageActionButton):
360    grok.order(1)
361    grok.context(IStudent)
362    grok.view(StudentPersonalDisplayFormPage)
363    grok.require('waeup.manageStudent')
364    text = _('Manage')
365    target = 'manage_personal'
366
367
368class StudentPersonalEditActionButton(ManageActionButton):
369    grok.order(2)
370    grok.context(IStudent)
371    grok.view(StudentPersonalDisplayFormPage)
372    grok.require('waeup.handleStudent')
373    text = _('Edit')
374    target = 'edit_personal'
375
376
377class StudyCourseManageActionButton(ManageActionButton):
378    grok.order(1)
379    grok.context(IStudentStudyCourse)
380    grok.view(StudyCourseDisplayFormPage)
381    grok.require('waeup.manageStudent')
382    text = _('Manage')
383    target = 'manage'
384
385    @property
386    def target_url(self):
387        if self.context.is_current:
388            return self.view.url(self.view.context, self.target)
389        return False
390
391
392class RevertTransferActionButton(ManageActionButton):
393    grok.order(1)
394    grok.context(IStudentStudyCourse)
395    grok.view(StudyCourseDisplayFormPage)
396    grok.require('waeup.manageStudent')
397    icon = 'actionicon_undo.png'
398    text = _('Reactivate this study course (revert previous transfer)')
399    target = 'revert_transfer'
400
401    @property
402    def target_url(self):
403        if self.context.is_previous:
404            return self.view.url(self.view.context.__parent__, self.target)
405        return False
406
407
408class StudyLevelManageActionButton(ManageActionButton):
409    grok.order(1)
410    grok.context(IStudentStudyLevel)
411    grok.view(StudyLevelDisplayFormPage)
412    grok.require('waeup.manageStudent')
413    text = _('Manage')
414    target = 'manage'
415
416    @property
417    def target_url(self):
418        is_current = self.context.__parent__.is_current
419        if not is_current:
420            return ''
421        return self.view.url(self.view.context, self.target)
422
423
424class StudentValidateCoursesActionButton(ManageActionButton):
425    grok.order(3)
426    grok.context(IStudentStudyLevel)
427    grok.view(StudyLevelDisplayFormPage)
428    grok.require('waeup.validateStudent')
429    text = _('Validate courses')
430    target = 'validate_courses'
431    icon = 'actionicon_accept.png'
432
433    @property
434    def target_url(self):
435        if not self.context.__parent__.is_current:
436            return ''
437        if self.context.student.state != REGISTERED:
438            return ''
439        if str(self.context.__parent__.current_level) != self.context.__name__:
440            return ''
441        return self.view.url(self.view.context, self.target)
442
443
444class StudentRejectCoursesActionButton(ManageActionButton):
445    grok.order(4)
446    grok.context(IStudentStudyLevel)
447    grok.view(StudyLevelDisplayFormPage)
448    grok.require('waeup.validateStudent')
449    text = _('Reject courses')
450    target = 'reject_courses'
451    icon = 'actionicon_reject.png'
452
453    @property
454    def target_url(self):
455        if not self.context.__parent__.is_current:
456            return ''
457        if self.context.student.state not in (VALIDATED, REGISTERED):
458            return ''
459        if str(self.context.__parent__.current_level) != self.context.__name__:
460            return ''
461        return self.view.url(self.view.context, self.target)
462
463
464class StudentUnregisterCoursesActionButton(ManageActionButton):
465    grok.order(5)
466    grok.context(IStudentStudyLevel)
467    grok.view(StudyLevelDisplayFormPage)
468    grok.require('waeup.handleStudent')
469    text = _('Unregister courses')
470    target = 'unregister_courses'
471    icon = 'actionicon_reject.png'
472
473    @property
474    def target_url(self):
475        if not self.context.__parent__.is_current:
476            return ''
477        if self.context.student.state != REGISTERED:
478            return ''
479        if str(self.context.__parent__.current_level) != self.context.__name__:
480            return ''
481        return self.view.url(self.view.context, self.target)
482
483
484class CourseRegistrationSlipActionButton(ManageActionButton):
485    grok.order(6)
486    grok.context(IStudentStudyLevel)
487    grok.view(StudyLevelDisplayFormPage)
488    grok.require('waeup.viewStudent')
489    icon = 'actionicon_pdf.png'
490    text = _('Download course registration slip')
491    target = 'course_registration_slip.pdf'
492
493    @property
494    def target_url(self):
495        is_current = self.context.__parent__.is_current
496        if not is_current:
497            return ''
498        return self.view.url(self.view.context, self.target)
499
500
501class CourseTicketManageActionButton(ManageActionButton):
502    grok.order(1)
503    grok.context(ICourseTicket)
504    grok.view(CourseTicketDisplayFormPage)
505    grok.require('waeup.manageStudent')
506    text = _('Manage')
507    target = 'manage'
508
509
510class PaymentReceiptActionButton(ManageActionButton):
511    grok.order(9)  # This button should always be the last one.
512    grok.context(IStudentOnlinePayment)
513    grok.view(OnlinePaymentDisplayFormPage)
514    grok.require('waeup.viewStudent')
515    icon = 'actionicon_pdf.png'
516    text = _('Download payment slip')
517    target = 'payment_slip.pdf'
518
519    @property
520    def target_url(self):
521        #if self.context.p_state != 'paid':
522        #    return ''
523        return self.view.url(self.view.context, self.target)
524
525
526class ApprovePaymentActionButton(ManageActionButton):
527    grok.order(8)
528    grok.context(IStudentOnlinePayment)
529    grok.view(OnlinePaymentDisplayFormPage)
530    grok.require('waeup.managePortal')
531    icon = 'actionicon_accept.png'
532    text = _('Approve payment')
533    target = 'approve'
534
535    @property
536    def target_url(self):
537        if self.context.p_state == 'paid':
538            return ''
539        return self.view.url(self.view.context, self.target)
540
541
542class BedTicketSlipActionButton(ManageActionButton):
543    grok.order(1)
544    grok.context(IBedTicket)
545    grok.view(BedTicketDisplayFormPage)
546    grok.require('waeup.handleAccommodation')
547    icon = 'actionicon_pdf.png'
548    text = _('Download bed allocation slip')
549    target = 'bed_allocation_slip.pdf'
550
551
552class RelocateStudentActionButton(ManageActionButton):
553    grok.order(2)
554    grok.context(IBedTicket)
555    grok.view(BedTicketDisplayFormPage)
556    grok.require('waeup.manageHostels')
557    icon = 'actionicon_reload.png'
558    text = _('Relocate student')
559    target = 'relocate'
560
561
562class StudentBaseActionButton(ManageActionButton):
563    grok.order(1)
564    grok.context(IStudent)
565    grok.view(StudentBaseDisplayFormPage)
566    grok.require('waeup.handleStudent')
567    text = _('Edit')
568    target = 'edit_base'
569
570
571class StudentPasswordActionButton(ManageActionButton):
572    grok.order(2)
573    grok.context(IStudent)
574    grok.view(StudentBaseDisplayFormPage)
575    grok.require('waeup.handleStudent')
576    icon = 'actionicon_key.png'
577    text = _('Change password')
578    target = 'change_password'
579
580
581class StudentPassportActionButton(ManageActionButton):
582    grok.order(3)
583    grok.context(IStudent)
584    grok.view(StudentBaseDisplayFormPage)
585    grok.require('waeup.handleStudent')
586    icon = 'actionicon_portrait.png'
587    text = _('Change portrait')
588    target = 'change_portrait'
589
590    @property
591    def target_url(self):
592        PORTRAIT_CHANGE_STATES = getUtility(
593            IStudentsUtils).PORTRAIT_CHANGE_STATES
594        if self.context.state not in PORTRAIT_CHANGE_STATES:
595            return ''
596        return self.view.url(self.view.context, self.target)
597
598
599class StudentClearanceStartActionButton(ManageActionButton):
600    grok.order(1)
601    grok.context(IStudent)
602    grok.view(StudentClearanceDisplayFormPage)
603    grok.require('waeup.handleStudent')
604    icon = 'actionicon_start.gif'
605    text = _('Start clearance')
606    target = 'start_clearance'
607
608    @property
609    def target_url(self):
610        if self.context.state != ADMITTED:
611            return ''
612        return self.view.url(self.view.context, self.target)
613
614
615class StudentClearanceEditActionButton(ManageActionButton):
616    grok.order(1)
617    grok.context(IStudent)
618    grok.view(StudentClearanceDisplayFormPage)
619    grok.require('waeup.handleStudent')
620    text = _('Edit')
621    target = 'cedit'
622
623    @property
624    def target_url(self):
625        if self.context.clearance_locked:
626            return ''
627        return self.view.url(self.view.context, self.target)
628
629
630class StartSessionActionButton(ManageActionButton):
631    grok.order(1)
632    grok.context(IStudentStudyCourse)
633    grok.view(StudyCourseDisplayFormPage)
634    grok.require('waeup.handleStudent')
635    icon = 'actionicon_start.gif'
636    text = _('Start new session')
637    target = 'start_session'
638
639    @property
640    def target_url(self):
641        if self.context.next_session_allowed and self.context.is_current:
642            return self.view.url(self.view.context, self.target)
643        return False
644
645
646class AddStudyLevelActionButton(AddActionButton):
647    grok.order(1)
648    grok.context(IStudentStudyCourse)
649    grok.view(StudyCourseDisplayFormPage)
650    grok.require('waeup.handleStudent')
651    text = _('Add course list')
652    target = 'add'
653
654    @property
655    def target_url(self):
656        student = self.view.context.student
657        condition1 = student.state != PAID
658        condition2 = str(student['studycourse'].current_level) in \
659            self.view.context.keys()
660        condition3 = not self.context.is_current
661        if condition1 or condition2 or condition3:
662            return ''
663        return self.view.url(self.view.context, self.target)
664
665
666class StudyLevelEditActionButton(ManageActionButton):
667    grok.order(2)
668    grok.context(IStudentStudyLevel)
669    grok.view(StudyLevelDisplayFormPage)
670    grok.require('waeup.editStudyLevel')
671    text = _('Edit course list')
672    target = 'edit'
673
674    @property
675    def target_url(self):
676        student = self.view.context.student
677        condition1 = student.state == PAID
678        condition2 = self.view.context.is_current_level
679        is_current = self.context.__parent__.is_current
680        if condition1 and condition2 and is_current:
681            return self.view.url(self.view.context, self.target)
682        return ''
683
684
685class AddPaymentActionButton(AddActionButton):
686    grok.order(1)
687    grok.context(IStudentPaymentsContainer)
688    grok.view(PaymentsManageFormPage)
689    grok.require('waeup.payStudent')
690    text = _('Add current session payment ticket')
691    target = 'addop'
692
693
694class AddPreviousPaymentActionButton(AddActionButton):
695    grok.order(2)
696    grok.context(IStudentPaymentsContainer)
697    grok.view(PaymentsManageFormPage)
698    grok.require('waeup.payStudent')
699    grok.name('addpreviouspaymentactionbutton')
700    text = _('Add previous session payment ticket')
701    target = 'addpp'
702
703    @property
704    def target_url(self):
705        student = self.view.context.student
706        if student.before_payment or not self.target:
707            return ''
708        return self.view.url(self.view.context, self.target)
709
710
711class AddBalancePaymentActionButton(AddActionButton):
712    grok.order(3)
713    grok.context(IStudentPaymentsContainer)
714    grok.view(PaymentsManageFormPage)
715    grok.require('waeup.manageStudent')
716    grok.name('addbalancepaymentactionbutton')
717    text = _('Add balance payment ticket')
718    target = 'addbp'
719
720    @property
721    def target_url(self):
722        if not self.target:
723            return ''
724        return self.view.url(self.view.context, self.target)
725
726
727class StudyCourseTranscriptActionButton(ManageActionButton):
728    grok.order(2)
729    grok.name('transcript')
730    grok.context(IStudentStudyCourse)
731    grok.view(StudyCourseDisplayFormPage)
732    grok.require('waeup.viewTranscript')
733    text = _('Transcript')
734    target = 'transcript'
735    icon = 'actionicon_transcript.png'
736
737    @property
738    def target_url(self):
739        final_slip = getUtility(IExtFileStore).getFileByContext(
740            self.context.student, attr='final_transcript')
741        if self.context.student.transcript_enabled and not final_slip:
742            return self.view.url(self.view.context, self.target)
743        return False
744
745
746class RequestTranscriptActionButton(ManageActionButton):
747    grok.order(8)
748    grok.context(IStudent)
749    grok.view(StudentBaseDisplayFormPage)
750    grok.require('waeup.handleStudent')
751    text = _('Request transcript')
752    target = 'request_transcript'
753    icon = 'actionicon_transcript.png'
754
755    @property
756    def target_url(self):
757        if self.context.state != GRADUATED:
758            return ''
759        return self.view.url(self.view.context, self.target)
760
761
762class ValidateTranscriptActionButton(ManageActionButton):
763    grok.order(8)
764    grok.context(IStudentStudyCourse)
765    grok.view(StudyCourseTranscriptPage)
766    grok.require('waeup.processTranscript')
767    text = _('Validate transcript')
768    target = 'validate_transcript'
769    icon = 'actionicon_transcript.png'
770
771    @property
772    def target_url(self):
773        if self.context.student.state != TRANSREQ:
774            return ''
775        return self.view.url(self.view.context, self.target)
776
777
778class ReleaseTranscriptActionButton(ManageActionButton):
779    grok.order(8)
780    grok.context(IStudentStudyCourse)
781    grok.view(StudyCourseTranscriptPage)
782    grok.require('waeup.processTranscript')
783    text = _('Release transcript')
784    target = 'release_transcript'
785    icon = 'actionicon_transcript.png'
786
787    @property
788    def target_url(self):
789        if self.context.student.state != TRANSVAL:
790            return ''
791        return self.view.url(self.view.context, self.target)
792
793
794class TranscriptSlipActionButton(ManageActionButton):
795    grok.order(1)
796    grok.name('transcript_slip')
797    grok.context(IStudentStudyCourse)
798    grok.view(StudyCourseTranscriptPage)
799    grok.require('waeup.viewTranscript')
800    text = _('Academic Transcript')
801    target = 'transcript.pdf'
802    icon = 'actionicon_pdf.png'
803
804    @property
805    def target_url(self):
806        final_slip = getUtility(IExtFileStore).getFileByContext(
807            self.context.student, attr='final_transcript')
808        if self.context.student.transcript_enabled \
809            and not final_slip:
810            return self.view.url(self.view.context, self.target)
811        return False
812
813
814class SignTranscriptActionButton(ManageActionButton):
815    grok.order(2)
816    grok.context(IStudentStudyCourse)
817    grok.view(StudyCourseTranscriptPage)
818    grok.require('waeup.signTranscript')
819    text = _('Sign transcript electronically')
820    target = 'sign_transcript'
821    icon = 'actionicon_transcript.png'
822
823    @property
824    def target_url(self):
825        if self.context.student.state != TRANSVAL:
826            return ''
827        return self.view.url(self.view.context, self.target)
828
829    @property
830    def onclick(self):
831        return "return window.confirm(%s);" % _(
832            "'Signing a transcript electronically cannot be revoked. "
833            "The electronic signature replaces your handwritten signature.\\n\\n"
834            "You really want to sign the transcript?'")
835
836
837class StudentsTab(PrimaryNavTab):
838    """Students tab in primary navigation.
839    """
840    grok.context(IKofaObject)
841    grok.order(4)
842    grok.require('waeup.viewStudentsContainer')
843    grok.name('studentstab')
844
845    pnav = 4
846    tab_title = _(u'Students')
847
848    @property
849    def link_target(self):
850        return self.view.application_url('students')
851
852
853class PrimaryStudentNavManager(grok.ViewletManager):
854    """Viewlet manager for the primary navigation tab.
855    """
856    grok.name('primary_nav_student')
857
858
859class PrimaryStudentNavTab(grok.Viewlet):
860    """Base for primary student nav tabs.
861    """
862    grok.baseclass()
863    grok.context(IKofaObject)
864    grok.viewletmanager(PrimaryStudentNavManager)
865    template = default_primary_nav_template
866    grok.order(1)
867    grok.require('waeup.Authenticated')
868    pnav = 0
869    tab_title = u'Some Text'
870
871    @property
872    def link_target(self):
873        return self.view.application_url()
874
875    @property
876    def active(self):
877        view_pnav = getattr(self.view, 'pnav', 0)
878        if view_pnav == self.pnav:
879            return 'active'
880        return ''
881
882
883class MyStudentDataTab(PrimaryStudentNavTab):
884    """MyData dropdown tab in primary navigation.
885    """
886    grok.order(3)
887    grok.require('waeup.viewMyStudentDataTab')
888    grok.template('mydatadropdowntabs')
889    grok.name('mystudentdatatab')
890    pnav = 4
891    tab_title = _(u'My Data')
892
893    @property
894    def active(self):
895        view_pnav = getattr(self.view, 'pnav', 0)
896        if view_pnav == self.pnav:
897            return 'active dropdown'
898        return 'dropdown'
899
900    @property
901    def targets(self):
902        student = grok.getSite()['students'][self.request.principal.id]
903        student_url = self.view.url(student)
904        app_slip = getUtility(IExtFileStore).getFileByContext(
905            student, 'application_slip')
906        targets = []
907        if app_slip:
908            targets = [{'url': student_url + '/application_slip',
909                        'title': _('Application Slip')}, ]
910        targets += [
911            {'url': student_url, 'title': 'Base Data'},
912            {'url': student_url + '/view_clearance',
913             'title': _('Clearance Data')},
914            {'url': student_url + '/view_personal',
915             'title': _('Personal Data')},
916            {'url': student_url + '/studycourse', 'title': _('Study Course')},
917            {'url': student_url + '/payments', 'title': _('Payments')},
918            {'url': student_url + '/accommodation',
919             'title': _('Accommodation Data')},
920            {'url': student_url + '/history', 'title': _('History')},
921            ]
922        return targets
Note: See TracBrowser for help on using the repository browser.