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

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

Fix docstrings.

In my old ZODB which I used for testing there were orphaned catalog entries. I don't know why. The tests show clearly that the catalog is updated whenever a hostel is removed or cleared. However, to be 100% that nothing goes wrong I added some extra safety belts.

  • Property svn:keywords set to Id
File size: 18.4 KB
RevLine 
[7191]1## $Id: interfaces.py 9424 2012-10-26 17:17:10Z henrik $
[6621]2##
[7191]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##
[8409]18#from datetime import datetime
[7620]19from zope.component import getUtility
[7256]20from zope.interface import Attribute, Interface
[6621]21from zope import schema
[7620]22from zc.sourcefactory.contextual import BasicContextualSourceFactory
[9217]23from waeup.kofa.browser.interfaces import IStudentNavigationBase
[7811]24from waeup.kofa.interfaces import (
[8409]25    IKofaObject, academic_sessions_vocab, validate_email, ICSVExporter)
[7811]26from waeup.kofa.interfaces import MessageFactory as _
[8176]27from waeup.kofa.schema import TextLineChoice, FormattedDate, PhoneNumber
[7811]28from waeup.kofa.students.vocabularies import (
[7915]29    StudyLevelSource, contextual_reg_num_source, contextual_mat_num_source,
[9420]30    GenderSource, nats_vocab
[7915]31    )
[8160]32from waeup.kofa.payments.interfaces import (
[8174]33    IPaymentsContainer, IOnlinePayment)
[7915]34from waeup.kofa.university.vocabularies import (
[9420]35    CourseSource, StudyModeSource, CertificateSource, SemesterSource)
[6621]36
[7620]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):
[7841]44        verdicts_dict = getUtility(IStudentsUtils).VERDICTS_DICT
[8820]45        return sorted(verdicts_dict.keys())
[7620]46
47    def getToken(self, context, value):
48        return value
49
50    def getTitle(self, context, value):
[7841]51        verdicts_dict = getUtility(IStudentsUtils).VERDICTS_DICT
[8820]52        if value != '0':
53            return verdicts_dict[value] + ' (%s)' % value
[7688]54        return verdicts_dict[value]
[7620]55
[7681]56
[7150]57class IStudentsUtils(Interface):
58    """A collection of methods which are subject to customization.
59
60    """
[7841]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
[9148]69    def setPaymentDetails(category, student, previous_session=None,
70            previous_level=None,):
[8595]71        """Create Payment object and set the payment data of a student for
72        the payment category specified.
[7150]73
74        """
75
[7186]76    def getAccommodation_details(student):
[7150]77        """Determine the accommodation dates of a student.
78
79        """
80
[7186]81    def selectBed(available_beds):
[7150]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
[7186]88    def renderPDF(view, subject='', filename='slip.pdf',):
[7150]89        """Render pdf slips for various pages.
90
91        """
92
[7819]93class IStudentsContainer(IKofaObject):
[7096]94    """A students container contains university students.
[6692]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
[8408]132    unique_student_id = Attribute("""A unique student id.""")
133
[9217]134class IStudentNavigation(IStudentNavigationBase):
[8735]135    """Interface needed for student navigation, logging, etc.
[7150]136
[6642]137    """
[8736]138    student = Attribute('Student object of context.')
[7150]139
[8735]140    def writeLogMessage(view, message):
141        """Write a view specific log message into students.log.
142
143        """
144
[7819]145class IStudentBase(IKofaObject):
[6631]146    """Representation of student base data.
[7150]147
[6621]148    """
[7062]149    history = Attribute('Object history, a list of messages')
[6637]150    state = Attribute('Returns the registration state of a student')
[6699]151    password = Attribute('Encrypted password of a student')
[9334]152    temp_password = Attribute(
153        'Dictionary with user name, timestamp and encrypted password')
[7203]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')
[7062]157    current_session = Attribute('The current session of the student')
[9142]158    current_level = Attribute('The current level of the student')
[7641]159    current_mode = Attribute('The current mode of the student')
[9182]160    current_verdict = Attribute('The current verdict of the student')
[7364]161    fullname = Attribute('All name parts separated by hyphens')
162    display_fullname = Attribute('The fullname of an applicant')
[8969]163    is_postgrad = Attribute('True if postgraduate student')
[6637]164
[8983]165    suspended = schema.Bool(
166        title = _(u'Account suspended'),
167        default = False,
[9035]168        required = False,
[8983]169        )
170
[6665]171    student_id = schema.TextLine(
[7723]172        title = _(u'Student Id'),
[6849]173        required = False,
[6665]174        )
175
[7357]176    firstname = schema.TextLine(
[7723]177        title = _(u'First Name'),
[6621]178        required = True,
179        )
180
[7357]181    middlename = schema.TextLine(
[7723]182        title = _(u'Middle Name'),
[7357]183        required = False,
184        )
185
186    lastname = schema.TextLine(
[7723]187        title = _(u'Last Name (Surname)'),
[7357]188        required = True,
189        )
190
[6996]191    sex = schema.Choice(
[7723]192        title = _(u'Sex'),
[6996]193        source = GenderSource(),
194        required = True,
195        )
196
[6788]197    reg_number = TextLineChoice(
[7723]198        title = _(u'Registration Number'),
[6696]199        required = True,
200        readonly = False,
[6788]201        source = contextual_reg_num_source,
[6696]202        )
203
[6788]204    matric_number = TextLineChoice(
[7723]205        title = _(u'Matriculation Number'),
[6750]206        required = False,
207        readonly = False,
[6788]208        source = contextual_mat_num_source,
[6750]209        )
210
[6769]211    adm_code = schema.TextLine(
[7723]212        title = _(u'PWD Activation Code'),
[6769]213        required = False,
[8977]214        readonly = False,
[6769]215        )
216
[7133]217    email = schema.ASCIILine(
[7723]218        title = _(u'Email'),
[7133]219        required = False,
220        constraint=validate_email,
221        )
[8176]222    phone = PhoneNumber(
[7723]223        title = _(u'Phone'),
[7331]224        description = u'',
[7133]225        required = False,
226        )
227
[9334]228    def setTempPassword(user, password):
229        """Set a temporary password (LDAP-compatible) SSHA encoded for
230        officers.
231
232        """
233
234    def getTempPassword():
235        """Check if a temporary password has been set and if it
236        is not expired.
237
238        Return the temporary password if valid,
239        None otherwise. Unset the temporary password if expired.
240        """
241
[9131]242    def transfer(certificate, current_session,
243        current_level, current_verdict):
244        """ Creates a new studycourse and backups the old one.
245
246        """
247
[7993]248class IUGStudentClearance(IKofaObject):
249    """Representation of undergraduate student clearance data.
[7150]250
[6631]251    """
[8160]252    date_of_birth = FormattedDate(
[7723]253        title = _(u'Date of Birth'),
[6631]254        required = True,
[8160]255        show_year = True,
[6631]256        )
257
[6695]258    clearance_locked = schema.Bool(
[7723]259        title = _(u'Clearance form locked'),
[6695]260        default = False,
[9035]261        required = False,
[6695]262        )
263
[6769]264    clr_code = schema.TextLine(
[7723]265        title = _(u'CLR Activation Code'),
[6769]266        required = False,
[8977]267        readonly = False,
[6769]268        )
269
[7523]270    nationality = schema.Choice(
[8069]271        vocabulary = nats_vocab,
[7723]272        title = _(u'Nationality'),
[7983]273        required = False,
[7523]274        )
275
[7993]276class IPGStudentClearance(IUGStudentClearance):
277    """Representation of postgraduate student clearance data.
278
279    """
280    employer = schema.TextLine(
281        title = _(u'Employer'),
282        required = False,
283        readonly = False,
284        )
285
[7819]286class IStudentPersonal(IKofaObject):
[6631]287    """Representation of student personal data.
[7150]288
[6631]289    """
[6651]290    perm_address = schema.Text(
[7723]291        title = _(u'Permanent Address'),
[6631]292        required = False,
293        )
294
[8008]295class IStudent(IStudentBase,IUGStudentClearance,IPGStudentClearance,
296    IStudentPersonal):
[6631]297    """Representation of a student.
[7150]298
[6631]299    """
300
[6849]301class IStudentUpdateByRegNo(IStudent):
302    """Representation of a student. Skip regular reg_number validation.
[7150]303
[6849]304    """
305    reg_number = schema.TextLine(
[7723]306        title = _(u'Registration Number'),
[6849]307        required = False,
308        )
309
310class IStudentUpdateByMatricNo(IStudent):
311    """Representation of a student. Skip regular matric_number validation.
[7150]312
[6849]313    """
314    matric_number = schema.TextLine(
[7723]315        title = _(u'Matriculation Number'),
[6849]316        required = False,
317        )
318
[8779]319class IStudentRequestPW(IStudent):
320    """Representation of an student for first-time password request.
321
322    This interface is used when students use the requestpw page to
323    login for the the first time.
324    """
[8854]325    number = schema.TextLine(
326        title = _(u'Registr. or Matric. Number'),
[8779]327        required = True,
328        )
329
330    firstname = schema.TextLine(
331        title = _(u'First Name'),
332        required = True,
333        )
334
335    email = schema.ASCIILine(
336        title = _(u'Email Address'),
337        required = True,
338        constraint=validate_email,
339        )
340
[7819]341class IStudentStudyCourse(IKofaObject):
[6633]342    """A container for student study levels.
343
344    """
[6648]345    certificate = schema.Choice(
[7723]346        title = _(u'Certificate'),
[6648]347        source = CertificateSource(),
[7209]348        required = False,
[6633]349        )
[6635]350
[6996]351    entry_mode = schema.Choice(
[7723]352        title = _(u'Entry Mode'),
[7681]353        source = StudyModeSource(),
[6996]354        required = True,
355        readonly = False,
356        )
357
358    entry_session = schema.Choice(
[7723]359        title = _(u'Entry Session'),
[6996]360        source = academic_sessions_vocab,
[7425]361        #default = datetime.now().year,
[6996]362        required = True,
363        readonly = False,
364        )
365
[6724]366    current_session = schema.Choice(
[7723]367        title = _(u'Current Session'),
[6744]368        source = academic_sessions_vocab,
[6724]369        required = True,
[6996]370        readonly = False,
[6724]371        )
372
373    current_level = schema.Choice(
[7723]374        title = _(u'Current Level'),
[6725]375        source = StudyLevelSource(),
376        required = False,
[6996]377        readonly = False,
[6724]378        )
379
380    current_verdict = schema.Choice(
[7723]381        title = _(u'Current Verdict'),
[7619]382        source = VerdictSource(),
[8820]383        default = '0',
[6725]384        required = False,
[6724]385        )
386
387    previous_verdict = schema.Choice(
[7723]388        title = _(u'Previous Verdict'),
[7619]389        source = VerdictSource(),
[8820]390        default = '0',
[6725]391        required = False,
[6724]392        )
393
[9138]394class IStudentStudyCourseTransfer(IStudentStudyCourse):
395    """An student transfers.
396
397    """
398
399    certificate = schema.Choice(
400        title = _(u'Certificate'),
401        source = CertificateSource(),
402        required = True,
403        )
404
405    current_level = schema.Choice(
406        title = _(u'Current Level'),
407        source = StudyLevelSource(),
408        required = True,
409        readonly = False,
410        )
411
412
413IStudentStudyCourseTransfer['certificate'].order = IStudentStudyCourse[
414    'certificate'].order
415IStudentStudyCourseTransfer['current_level'].order = IStudentStudyCourse[
416    'current_level'].order
417
[7951]418class IStudentVerdictUpdate(IKofaObject):
419    """A interface for verdict imports.
420
421    """
422
423    current_verdict = schema.Choice(
424        title = _(u'Current Verdict'),
425        source = VerdictSource(),
426        required = True,
427        )
428
429    current_session = schema.Choice(
430        title = _(u'Current Session'),
431        source = academic_sessions_vocab,
432        required = True,
433        )
434
435    current_level = schema.Choice(
436        title = _(u'Current Level'),
437        source = StudyLevelSource(),
438        required = True,
439        )
440
[9296]441    bypass_validation = schema.Bool(
442        title = _(u'Bypass validation'),
443        required = False,
444        )
445
446    validated_by = schema.TextLine(
447        title = _(u'Validated by'),
448        required = False,
449        )
450
[7819]451class IStudentStudyLevel(IKofaObject):
[6774]452    """A container for course tickets.
453
454    """
455    level = Attribute('The level code')
[9235]456    number_of_tickets = Attribute('Number of tickets contained in this level')
[9253]457    certcode = Attribute('The certificate code of the study course')
[9257]458    is_current_level = Attribute('Is this level the current level of the student?')
[6774]459
[6793]460    level_session = schema.Choice(
[7723]461        title = _(u'Session'),
[6793]462        source = academic_sessions_vocab,
[9167]463        required = False,
[6793]464        )
[6781]465
[6793]466    level_verdict = schema.Choice(
[7723]467        title = _(u'Verdict'),
[7619]468        source = VerdictSource(),
[8820]469        default = '0',
[6793]470        required = False,
471        )
472
[9161]473    validated_by = schema.TextLine(
474        title = _(u'Validated by'),
475        default = None,
476        required = False,
477        )
478
479    validation_date = schema.Datetime(
480        title = _(u'Validation Date'),
481        required = False,
482        readonly = False,
483        )
484
[8920]485    def addCourseTicket(ticket, course):
[8182]486        """Add a course ticket object.
487        """
488
[7819]489class ICourseTicket(IKofaObject):
[9420]490    """An interface for course tickets.
[6781]491
492    """
[6783]493    code = Attribute('code of the original course')
[9253]494    certcode = Attribute('certificate code of the study course')
[6781]495
[9420]496    title = schema.TextLine(
497        title = _(u'Title'),
498        required = False,
499        )
500
501    fcode = schema.TextLine(
502        title = _(u'Faculty Code'),
503        required = False,
504        )
505
506    dcode = schema.TextLine(
507        title = _(u'Department Code'),
508        required = False,
509        )
510
511    semester = schema.Choice(
512        title = _(u'Semester/Term'),
513        source = SemesterSource(),
514        required = False,
515        )
516
517    passmark = schema.Int(
518        title = _(u'Passmark'),
519        required = False,
520        )
521
522    credits = schema.Int(
523        title = _(u'Credits'),
524        required = False,
525        )
526
[7665]527    mandatory = schema.Bool(
[9320]528        title = _(u'Required'),
[6795]529        default = False,
530        required = False,
531        )
532
[6781]533    score = schema.Int(
[7723]534        title = _(u'Score'),
[6781]535        default = 0,
536        required = False,
537        )
538
[7661]539    carry_over = schema.Bool(
[7723]540        title = _(u'Carry-over Course'),
[7661]541        default = False,
542        required = False,
543        )
544
[9420]545    automatic = schema.Bool(
546        title = _(u'Automatical Creation'),
547        default = False,
[9316]548        required = False,
549        )
550
551
[7633]552    def getLevel():
553        """Returns the id of the level the ticket has been added to.
554        """
555
556    def getLevelSession():
557        """Returns the session of the level the ticket has been added to.
558        """
559
[9420]560class ICourseTicketAdd(IKofaObject):
[7150]561    """An interface for adding course tickets.
[6795]562
563    """
564    course = schema.Choice(
[7723]565        title = _(u'Course'),
[6795]566        source = CourseSource(),
567        readonly = False,
568        )
569
[9420]570class ICourseTicketImport(ICourseTicket):
571    """An interface for importing course results and nothing more.
572
573    """
574    score = schema.Int(
575        title = _(u'Score'),
576        required = False,
577        readonly = False,
578        )
579
580    level_session = schema.Choice(
581        title = _(u'Level Session'),
582        source = academic_sessions_vocab,
583        required = False,
584        readonly = False,
585        )
586
[7819]587class IStudentAccommodation(IKofaObject):
[6635]588    """A container for student accommodation objects.
589
590    """
591
[9423]592    def addBedTicket(bedticket):
593        """Add a bed ticket object.
594        """
595
596
[7819]597class IBedTicket(IKofaObject):
[6989]598    """A ticket for accommodation booking.
599
600    """
[6996]601    bed = Attribute('The bed object.')
602
603    bed_coordinates = schema.TextLine(
[9424]604        title = _(u'Allocated Bed'),
[9423]605        required = True,
[7014]606        readonly = False,
[6992]607        )
608
[6996]609    bed_type = schema.TextLine(
[9424]610        title = _(u'Requested Bed Type'),
[9423]611        required = True,
[7014]612        readonly = False,
[6996]613        )
614
[6992]615    booking_session = schema.Choice(
[7723]616        title = _(u'Session'),
[6992]617        source = academic_sessions_vocab,
618        required = True,
[7014]619        readonly = True,
[6992]620        )
621
[8170]622    booking_date = schema.Datetime(
[7723]623        title = _(u'Booking Date'),
[6992]624        required = False,
[7014]625        readonly = True,
[6992]626        )
627
628    booking_code = schema.TextLine(
[7723]629        title = _(u'Booking Activation Code'),
[6992]630        required = False,
[7014]631        readonly = True,
[6992]632        )
633
[6994]634    def getSessionString():
[7633]635        """Returns the title of academic_sessions_vocab term.
[7150]636
[6994]637        """
[6992]638
[6860]639class IStudentPaymentsContainer(IPaymentsContainer):
[6635]640    """A container for student payment objects.
641
642    """
643
[6877]644class IStudentOnlinePayment(IOnlinePayment):
645    """A student payment via payment gateways.
646
647    """
648
[9148]649    p_current = schema.Bool(
650        title = _(u'Current Session Payment'),
651        default = True,
652        required = False,
653        )
654
[8268]655    p_level = schema.Int(
656        title = _(u'Payment Level'),
657        required = False,
658        readonly = True,
659        )
[6877]660
[8422]661    def doAfterStudentPayment():
662        """Process student after payment was made.
663
664        """
665
[8453]666    def doAfterStudentPaymentApproval():
667        """Process student after payment was approved.
668
669        """
670
[8420]671    def approveStudentPayment():
[8422]672        """Approve payment and process student.
[8420]673
674        """
675
[8268]676IStudentOnlinePayment['p_level'].order = IStudentOnlinePayment[
677    'p_session'].order
[8408]678
[9148]679class IStudentPreviousPayment(IOnlinePayment):
680    """An interface for adding previous session payments.
681
682    """
683
684    p_session = schema.Choice(
685        title = _(u'Payment Session'),
686        source = academic_sessions_vocab,
687        required = True,
688        )
689
690    p_level = schema.Choice(
691        title = _(u'Payment Level'),
692        source = StudyLevelSource(),
693        required = True,
694        )
695
[8408]696class ICSVStudentExporter(ICSVExporter):
697    """A regular ICSVExporter that additionally supports exporting
698      data from a given student object.
699    """
700
701    def export_student(student, filepath=None):
702        """Export data for a given student.
703        """
Note: See TracBrowser for help on using the repository browser.