source: main/waeup.kofa/trunk/src/waeup/kofa/students/interfaces.py @ 9723

Last change on this file since 9723 was 9702, checked in by Henrik Bettermann, 12 years ago

Add field 'suspended_comment'. This attribute will be used to render flash messages for deactivated students. The field is only displayed on the student manage page.

  • Property svn:keywords set to Id
File size: 19.7 KB
Line 
1## $Id: interfaces.py 9702 2012-11-21 15:18:31Z 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##
18#from datetime import datetime
19from zope.component import getUtility
20from zope.interface import Attribute, Interface
21from zope import schema
22from zc.sourcefactory.contextual import BasicContextualSourceFactory
23from waeup.kofa.browser.interfaces import IStudentNavigationBase
24from waeup.kofa.interfaces import (
25    IKofaObject, academic_sessions_vocab, validate_email, ICSVExporter)
26from waeup.kofa.interfaces import MessageFactory as _
27from waeup.kofa.schema import TextLineChoice, FormattedDate, PhoneNumber
28from waeup.kofa.students.vocabularies import (
29    StudyLevelSource, contextual_reg_num_source, contextual_mat_num_source,
30    GenderSource, nats_vocab
31    )
32from waeup.kofa.payments.interfaces import (
33    IPaymentsContainer, IOnlinePayment)
34from waeup.kofa.university.vocabularies import (
35    CourseSource, StudyModeSource, CertificateSource, SemesterSource)
36
37# VerdictSource can't be placed into the vocabularies module because it
38# requires importing IStudentsUtils which then leads to circular imports.
39class VerdictSource(BasicContextualSourceFactory):
40    """A verdicts source delivers all verdicts provided
41    in the portal.
42    """
43    def getValues(self, context):
44        verdicts_dict = getUtility(IStudentsUtils).VERDICTS_DICT
45        return sorted(verdicts_dict.keys())
46
47    def getToken(self, context, value):
48        return value
49
50    def getTitle(self, context, value):
51        verdicts_dict = getUtility(IStudentsUtils).VERDICTS_DICT
52        if value != '0':
53            return verdicts_dict[value] + ' (%s)' % value
54        return verdicts_dict[value]
55
56
57class IStudentsUtils(Interface):
58    """A collection of methods which are subject to customization.
59
60    """
61    def setReturningData(student):
62        """ This method defines what happens after school fee payment
63        depending on the student's senate verdict.
64
65        In the base configuration current level is always increased
66        by 100 no matter which verdict has been assigned.
67        """
68
69    def setPaymentDetails(category, student, previous_session=None,
70            previous_level=None,):
71        """Create Payment object and set the payment data of a student for
72        the payment category specified.
73
74        """
75
76    def getAccommodation_details(student):
77        """Determine the accommodation dates of a student.
78
79        """
80
81    def selectBed(available_beds):
82        """Select a bed from a list of available beds.
83
84        In the standard configuration we select the first bed found,
85        but can also randomize the selection if we like.
86        """
87
88    def renderPDF(view, subject='', filename='slip.pdf',):
89        """Render pdf slips for various pages.
90
91        """
92
93class IStudentsContainer(IKofaObject):
94    """A students container contains university students.
95
96    """
97    def addStudent(student):
98        """Add an IStudent object and subcontainers.
99
100        """
101
102    def archive(id=None):
103        """Create on-dist archive of students.
104
105        If id is `None`, all students are archived.
106
107        If id contains a single id string, only the respective
108        students are archived.
109
110        If id contains a list of id strings all of the respective
111        students types are saved to disk.
112        """
113
114    def clear(id=None, archive=True):
115        """Remove students of type given by 'id'.
116
117        Optionally archive the students.
118
119        If id is `None`, all students are archived.
120
121        If id contains a single id string, only the respective
122        students are archived.
123
124        If id contains a list of id strings all of the respective
125        student types are saved to disk.
126
127        If `archive` is ``False`` none of the archive-handling is done
128        and respective students are simply removed from the
129        database.
130        """
131
132    unique_student_id = Attribute("""A unique student id.""")
133
134class IStudentNavigation(IStudentNavigationBase):
135    """Interface needed for student navigation, logging, etc.
136
137    """
138    student = Attribute('Student object of context.')
139
140    def writeLogMessage(view, message):
141        """Write a view specific log message into students.log.
142
143        """
144
145class IStudentBase(IKofaObject):
146    """Representation of student base data.
147
148    """
149    history = Attribute('Object history, a list of messages')
150    state = Attribute('Returns the registration state of a student')
151    password = Attribute('Encrypted password of a student')
152    temp_password = Attribute(
153        'Dictionary with user name, timestamp and encrypted password')
154    certcode = Attribute('The certificate code of any chosen study course')
155    depcode = Attribute('The department code of any chosen study course')
156    faccode = Attribute('The faculty code of any chosen study course')
157    current_session = Attribute('The current session of the student')
158    current_level = Attribute('The current level of the student')
159    current_mode = Attribute('The current mode of the student')
160    current_verdict = Attribute('The current verdict of the student')
161    fullname = Attribute('All name parts separated by hyphens')
162    display_fullname = Attribute('The fullname of an applicant')
163    is_postgrad = Attribute('True if postgraduate student')
164
165    suspended = schema.Bool(
166        title = _(u'Account suspended'),
167        default = False,
168        required = False,
169        )
170
171    suspended_comment = schema.Text(
172        title = _(u"Reasons for Deactivation"),
173        required = False,
174        description = _(
175            u'This message will be shown if and only if deactivated '
176            'students try to login.'),
177        )
178
179    student_id = schema.TextLine(
180        title = _(u'Student Id'),
181        required = False,
182        )
183
184    firstname = schema.TextLine(
185        title = _(u'First Name'),
186        required = True,
187        )
188
189    middlename = schema.TextLine(
190        title = _(u'Middle Name'),
191        required = False,
192        )
193
194    lastname = schema.TextLine(
195        title = _(u'Last Name (Surname)'),
196        required = True,
197        )
198
199    sex = schema.Choice(
200        title = _(u'Sex'),
201        source = GenderSource(),
202        required = True,
203        )
204
205    reg_number = TextLineChoice(
206        title = _(u'Registration Number'),
207        required = True,
208        readonly = False,
209        source = contextual_reg_num_source,
210        )
211
212    matric_number = TextLineChoice(
213        title = _(u'Matriculation Number'),
214        required = False,
215        readonly = False,
216        source = contextual_mat_num_source,
217        )
218
219    adm_code = schema.TextLine(
220        title = _(u'PWD Activation Code'),
221        required = False,
222        readonly = False,
223        )
224
225    email = schema.ASCIILine(
226        title = _(u'Email'),
227        required = False,
228        constraint=validate_email,
229        )
230    phone = PhoneNumber(
231        title = _(u'Phone'),
232        description = u'',
233        required = False,
234        )
235
236    def setTempPassword(user, password):
237        """Set a temporary password (LDAP-compatible) SSHA encoded for
238        officers.
239
240        """
241
242    def getTempPassword():
243        """Check if a temporary password has been set and if it
244        is not expired.
245
246        Return the temporary password if valid,
247        None otherwise. Unset the temporary password if expired.
248        """
249
250    def transfer(certificate, current_session,
251        current_level, current_verdict):
252        """ Creates a new studycourse and backups the old one.
253
254        """
255
256class IUGStudentClearance(IKofaObject):
257    """Representation of undergraduate student clearance data.
258
259    """
260    officer_comment = schema.Text(
261        title = _(u"Officer's Comment"),
262        required = False,
263        )
264
265    clearance_locked = schema.Bool(
266        title = _(u'Clearance form locked'),
267        default = False,
268        required = False,
269        )
270
271    clr_code = schema.TextLine(
272        title = _(u'CLR Activation Code'),
273        required = False,
274        readonly = False,
275        )
276
277    date_of_birth = FormattedDate(
278        title = _(u'Date of Birth'),
279        required = True,
280        show_year = True,
281        )
282
283    nationality = schema.Choice(
284        vocabulary = nats_vocab,
285        title = _(u'Nationality'),
286        required = False,
287        )
288
289class IPGStudentClearance(IUGStudentClearance):
290    """Representation of postgraduate student clearance data.
291
292    """
293    employer = schema.TextLine(
294        title = _(u'Employer'),
295        required = False,
296        readonly = False,
297        )
298
299class IStudentPersonal(IKofaObject):
300    """Representation of student personal data.
301
302    """
303    personal_updated = schema.Datetime(
304        title = _(u'Updated'),
305        required = False,
306        readonly = False,
307        )
308
309    perm_address = schema.Text(
310        title = _(u'Permanent Address'),
311        required = False,
312        )
313
314class IStudent(IStudentBase,IUGStudentClearance,IPGStudentClearance,
315    IStudentPersonal):
316    """Representation of a student.
317
318    """
319
320class IStudentPersonalEdit(IStudentPersonal):
321    """Interface for editing personal data by students.
322
323    Here we can repeat the fields from IStudentPersonal and set the
324    `required` if necessary.
325    """
326
327    perm_address = schema.Text(
328        title = _(u'Permanent Address'),
329        required = True,
330        )
331
332class IStudentUpdateByRegNo(IStudent):
333    """Representation of a student. Skip regular reg_number validation.
334
335    """
336    reg_number = schema.TextLine(
337        title = _(u'Registration Number'),
338        required = False,
339        )
340
341class IStudentUpdateByMatricNo(IStudent):
342    """Representation of a student. Skip regular matric_number validation.
343
344    """
345    matric_number = schema.TextLine(
346        title = _(u'Matriculation Number'),
347        required = False,
348        )
349
350class IStudentRequestPW(IStudent):
351    """Representation of an student for first-time password request.
352
353    This interface is used when students use the requestpw page to
354    login for the the first time.
355    """
356    number = schema.TextLine(
357        title = _(u'Registr. or Matric. Number'),
358        required = True,
359        )
360
361    firstname = schema.TextLine(
362        title = _(u'First Name'),
363        required = True,
364        )
365
366    email = schema.ASCIILine(
367        title = _(u'Email Address'),
368        required = True,
369        constraint=validate_email,
370        )
371
372class IStudentStudyCourse(IKofaObject):
373    """A container for student study levels.
374
375    """
376    certificate = schema.Choice(
377        title = _(u'Certificate'),
378        source = CertificateSource(),
379        required = False,
380        )
381
382    entry_mode = schema.Choice(
383        title = _(u'Entry Mode'),
384        source = StudyModeSource(),
385        required = True,
386        readonly = False,
387        )
388
389    entry_session = schema.Choice(
390        title = _(u'Entry Session'),
391        source = academic_sessions_vocab,
392        #default = datetime.now().year,
393        required = True,
394        readonly = False,
395        )
396
397    current_session = schema.Choice(
398        title = _(u'Current Session'),
399        source = academic_sessions_vocab,
400        required = True,
401        readonly = False,
402        )
403
404    current_level = schema.Choice(
405        title = _(u'Current Level'),
406        source = StudyLevelSource(),
407        required = False,
408        readonly = False,
409        )
410
411    current_verdict = schema.Choice(
412        title = _(u'Current Verdict'),
413        source = VerdictSource(),
414        default = '0',
415        required = False,
416        )
417
418    previous_verdict = schema.Choice(
419        title = _(u'Previous Verdict'),
420        source = VerdictSource(),
421        default = '0',
422        required = False,
423        )
424
425class IStudentStudyCourseTransfer(IStudentStudyCourse):
426    """An student transfers.
427
428    """
429
430    certificate = schema.Choice(
431        title = _(u'Certificate'),
432        source = CertificateSource(),
433        required = True,
434        )
435
436    current_level = schema.Choice(
437        title = _(u'Current Level'),
438        source = StudyLevelSource(),
439        required = True,
440        readonly = False,
441        )
442
443
444IStudentStudyCourseTransfer['certificate'].order = IStudentStudyCourse[
445    'certificate'].order
446IStudentStudyCourseTransfer['current_level'].order = IStudentStudyCourse[
447    'current_level'].order
448
449class IStudentVerdictUpdate(IKofaObject):
450    """A interface for verdict imports.
451
452    """
453
454    current_verdict = schema.Choice(
455        title = _(u'Current Verdict'),
456        source = VerdictSource(),
457        required = True,
458        )
459
460    current_session = schema.Choice(
461        title = _(u'Current Session'),
462        source = academic_sessions_vocab,
463        required = True,
464        )
465
466    current_level = schema.Choice(
467        title = _(u'Current Level'),
468        source = StudyLevelSource(),
469        required = True,
470        )
471
472    bypass_validation = schema.Bool(
473        title = _(u'Bypass validation'),
474        required = False,
475        )
476
477    validated_by = schema.TextLine(
478        title = _(u'Validated by'),
479        required = False,
480        )
481
482class IStudentStudyLevel(IKofaObject):
483    """A container for course tickets.
484
485    """
486    level = Attribute('The level code')
487    number_of_tickets = Attribute('Number of tickets contained in this level')
488    certcode = Attribute('The certificate code of the study course')
489    is_current_level = Attribute('Is this level the current level of the student?')
490
491    level_session = schema.Choice(
492        title = _(u'Session'),
493        source = academic_sessions_vocab,
494        required = True,
495        )
496
497    level_verdict = schema.Choice(
498        title = _(u'Verdict'),
499        source = VerdictSource(),
500        default = '0',
501        required = False,
502        )
503
504    validated_by = schema.TextLine(
505        title = _(u'Validated by'),
506        default = None,
507        required = False,
508        )
509
510    validation_date = schema.Datetime(
511        title = _(u'Validation Date'),
512        required = False,
513        readonly = False,
514        )
515
516    total_credits = schema.Int(
517        title = _(u'Total Credits'),
518        required = False,
519        readonly = True,
520        )
521
522    gpa = schema.Int(
523        title = _(u'GPA'),
524        required = False,
525        readonly = True,
526        )
527
528    def addCourseTicket(ticket, course):
529        """Add a course ticket object.
530        """
531
532    def addCertCourseTickets(cert):
533        """Collect all certificate courses and create course
534        tickets automatically.
535        """
536
537class ICourseTicket(IKofaObject):
538    """An interface for course tickets.
539
540    """
541    code = Attribute('code of the original course')
542    certcode = Attribute('certificate code of the study course')
543    grade = Attribute('grade calculated from score')
544    weight = Attribute('weight calculated from score')
545    removable_by_student = Attribute('Is student allowed to remove the ticket?')
546
547    title = schema.TextLine(
548        title = _(u'Title'),
549        required = False,
550        )
551
552    fcode = schema.TextLine(
553        title = _(u'Faculty Code'),
554        required = False,
555        )
556
557    dcode = schema.TextLine(
558        title = _(u'Department Code'),
559        required = False,
560        )
561
562    semester = schema.Choice(
563        title = _(u'Semester/Term'),
564        source = SemesterSource(),
565        required = False,
566        )
567
568    passmark = schema.Int(
569        title = _(u'Passmark'),
570        required = False,
571        )
572
573    credits = schema.Int(
574        title = _(u'Credits'),
575        required = False,
576        )
577
578    mandatory = schema.Bool(
579        title = _(u'Required'),
580        default = False,
581        required = False,
582        )
583
584    score = schema.Int(
585        title = _(u'Score'),
586        default = None,
587        required = False,
588        )
589
590    carry_over = schema.Bool(
591        title = _(u'Carry-over Course'),
592        default = False,
593        required = False,
594        )
595
596    automatic = schema.Bool(
597        title = _(u'Automatical Creation'),
598        default = False,
599        required = False,
600        )
601
602    def getLevel():
603        """Returns the id of the level the ticket has been added to.
604        """
605
606    def getLevelSession():
607        """Returns the session of the level the ticket has been added to.
608        """
609
610class ICourseTicketAdd(IKofaObject):
611    """An interface for adding course tickets.
612
613    """
614    course = schema.Choice(
615        title = _(u'Course'),
616        source = CourseSource(),
617        readonly = False,
618        )
619
620class ICourseTicketImport(ICourseTicket):
621    """An interface for importing course results and nothing more.
622
623    """
624    score = schema.Int(
625        title = _(u'Score'),
626        required = False,
627        readonly = False,
628        )
629
630    level_session = schema.Choice(
631        title = _(u'Level Session'),
632        source = academic_sessions_vocab,
633        required = False,
634        readonly = False,
635        )
636
637class IStudentAccommodation(IKofaObject):
638    """A container for student accommodation objects.
639
640    """
641
642    def addBedTicket(bedticket):
643        """Add a bed ticket object.
644        """
645
646
647class IBedTicket(IKofaObject):
648    """A ticket for accommodation booking.
649
650    """
651    bed = Attribute('The bed object.')
652
653    bed_coordinates = schema.TextLine(
654        title = _(u'Allocated Bed'),
655        required = True,
656        readonly = False,
657        )
658
659    bed_type = schema.TextLine(
660        title = _(u'Requested Bed Type'),
661        required = True,
662        readonly = False,
663        )
664
665    booking_session = schema.Choice(
666        title = _(u'Session'),
667        source = academic_sessions_vocab,
668        required = True,
669        readonly = True,
670        )
671
672    booking_date = schema.Datetime(
673        title = _(u'Booking Date'),
674        required = False,
675        readonly = True,
676        )
677
678    booking_code = schema.TextLine(
679        title = _(u'Booking Activation Code'),
680        required = False,
681        readonly = True,
682        )
683
684    def getSessionString():
685        """Returns the title of academic_sessions_vocab term.
686
687        """
688
689class IStudentPaymentsContainer(IPaymentsContainer):
690    """A container for student payment objects.
691
692    """
693
694class IStudentOnlinePayment(IOnlinePayment):
695    """A student payment via payment gateways.
696
697    """
698
699    p_current = schema.Bool(
700        title = _(u'Current Session Payment'),
701        default = True,
702        required = False,
703        )
704
705    p_level = schema.Int(
706        title = _(u'Payment Level'),
707        required = False,
708        )
709
710    def doAfterStudentPayment():
711        """Process student after payment was made.
712
713        """
714
715    def doAfterStudentPaymentApproval():
716        """Process student after payment was approved.
717
718        """
719
720    def approveStudentPayment():
721        """Approve payment and process student.
722
723        """
724
725IStudentOnlinePayment['p_level'].order = IStudentOnlinePayment[
726    'p_session'].order
727
728class IStudentPreviousPayment(IOnlinePayment):
729    """An interface for adding previous session payments.
730
731    """
732
733    p_session = schema.Choice(
734        title = _(u'Payment Session'),
735        source = academic_sessions_vocab,
736        required = True,
737        )
738
739    p_level = schema.Choice(
740        title = _(u'Payment Level'),
741        source = StudyLevelSource(),
742        required = True,
743        )
744
745class ICSVStudentExporter(ICSVExporter):
746    """A regular ICSVExporter that additionally supports exporting
747      data from a given student object.
748    """
749
750    def export_student(student, filepath=None):
751        """Export data for a given student.
752        """
Note: See TracBrowser for help on using the repository browser.