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

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

Add addCertCourseTickets method to StudentStudyLevel?.

  • Property svn:keywords set to Id
File size: 18.7 KB
RevLine 
[7191]1## $Id: interfaces.py 9501 2012-11-02 05:39:40Z 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
[9486]276    officer_comment = schema.Text(
[9484]277        title = _(u"Officer's Comment"),
278        required = False,
279        #description = _(
280        #    u'This comment will be deleted when student is cleared.'),
281        )
282
[7993]283class IPGStudentClearance(IUGStudentClearance):
284    """Representation of postgraduate student clearance data.
285
286    """
287    employer = schema.TextLine(
288        title = _(u'Employer'),
289        required = False,
290        readonly = False,
291        )
292
[7819]293class IStudentPersonal(IKofaObject):
[6631]294    """Representation of student personal data.
[7150]295
[6631]296    """
[6651]297    perm_address = schema.Text(
[7723]298        title = _(u'Permanent Address'),
[6631]299        required = False,
300        )
301
[8008]302class IStudent(IStudentBase,IUGStudentClearance,IPGStudentClearance,
303    IStudentPersonal):
[6631]304    """Representation of a student.
[7150]305
[6631]306    """
307
[6849]308class IStudentUpdateByRegNo(IStudent):
309    """Representation of a student. Skip regular reg_number validation.
[7150]310
[6849]311    """
312    reg_number = schema.TextLine(
[7723]313        title = _(u'Registration Number'),
[6849]314        required = False,
315        )
316
317class IStudentUpdateByMatricNo(IStudent):
318    """Representation of a student. Skip regular matric_number validation.
[7150]319
[6849]320    """
321    matric_number = schema.TextLine(
[7723]322        title = _(u'Matriculation Number'),
[6849]323        required = False,
324        )
325
[8779]326class IStudentRequestPW(IStudent):
327    """Representation of an student for first-time password request.
328
329    This interface is used when students use the requestpw page to
330    login for the the first time.
331    """
[8854]332    number = schema.TextLine(
333        title = _(u'Registr. or Matric. Number'),
[8779]334        required = True,
335        )
336
337    firstname = schema.TextLine(
338        title = _(u'First Name'),
339        required = True,
340        )
341
342    email = schema.ASCIILine(
343        title = _(u'Email Address'),
344        required = True,
345        constraint=validate_email,
346        )
347
[7819]348class IStudentStudyCourse(IKofaObject):
[6633]349    """A container for student study levels.
350
351    """
[6648]352    certificate = schema.Choice(
[7723]353        title = _(u'Certificate'),
[6648]354        source = CertificateSource(),
[7209]355        required = False,
[6633]356        )
[6635]357
[6996]358    entry_mode = schema.Choice(
[7723]359        title = _(u'Entry Mode'),
[7681]360        source = StudyModeSource(),
[6996]361        required = True,
362        readonly = False,
363        )
364
365    entry_session = schema.Choice(
[7723]366        title = _(u'Entry Session'),
[6996]367        source = academic_sessions_vocab,
[7425]368        #default = datetime.now().year,
[6996]369        required = True,
370        readonly = False,
371        )
372
[6724]373    current_session = schema.Choice(
[7723]374        title = _(u'Current Session'),
[6744]375        source = academic_sessions_vocab,
[6724]376        required = True,
[6996]377        readonly = False,
[6724]378        )
379
380    current_level = schema.Choice(
[7723]381        title = _(u'Current Level'),
[6725]382        source = StudyLevelSource(),
383        required = False,
[6996]384        readonly = False,
[6724]385        )
386
387    current_verdict = schema.Choice(
[7723]388        title = _(u'Current Verdict'),
[7619]389        source = VerdictSource(),
[8820]390        default = '0',
[6725]391        required = False,
[6724]392        )
393
394    previous_verdict = schema.Choice(
[7723]395        title = _(u'Previous Verdict'),
[7619]396        source = VerdictSource(),
[8820]397        default = '0',
[6725]398        required = False,
[6724]399        )
400
[9138]401class IStudentStudyCourseTransfer(IStudentStudyCourse):
402    """An student transfers.
403
404    """
405
406    certificate = schema.Choice(
407        title = _(u'Certificate'),
408        source = CertificateSource(),
409        required = True,
410        )
411
412    current_level = schema.Choice(
413        title = _(u'Current Level'),
414        source = StudyLevelSource(),
415        required = True,
416        readonly = False,
417        )
418
419
420IStudentStudyCourseTransfer['certificate'].order = IStudentStudyCourse[
421    'certificate'].order
422IStudentStudyCourseTransfer['current_level'].order = IStudentStudyCourse[
423    'current_level'].order
424
[7951]425class IStudentVerdictUpdate(IKofaObject):
426    """A interface for verdict imports.
427
428    """
429
430    current_verdict = schema.Choice(
431        title = _(u'Current Verdict'),
432        source = VerdictSource(),
433        required = True,
434        )
435
436    current_session = schema.Choice(
437        title = _(u'Current Session'),
438        source = academic_sessions_vocab,
439        required = True,
440        )
441
442    current_level = schema.Choice(
443        title = _(u'Current Level'),
444        source = StudyLevelSource(),
445        required = True,
446        )
447
[9296]448    bypass_validation = schema.Bool(
449        title = _(u'Bypass validation'),
450        required = False,
451        )
452
453    validated_by = schema.TextLine(
454        title = _(u'Validated by'),
455        required = False,
456        )
457
[7819]458class IStudentStudyLevel(IKofaObject):
[6774]459    """A container for course tickets.
460
461    """
462    level = Attribute('The level code')
[9235]463    number_of_tickets = Attribute('Number of tickets contained in this level')
[9253]464    certcode = Attribute('The certificate code of the study course')
[9257]465    is_current_level = Attribute('Is this level the current level of the student?')
[6774]466
[6793]467    level_session = schema.Choice(
[7723]468        title = _(u'Session'),
[6793]469        source = academic_sessions_vocab,
[9437]470        required = True,
[6793]471        )
[6781]472
[6793]473    level_verdict = schema.Choice(
[7723]474        title = _(u'Verdict'),
[7619]475        source = VerdictSource(),
[8820]476        default = '0',
[6793]477        required = False,
478        )
479
[9161]480    validated_by = schema.TextLine(
481        title = _(u'Validated by'),
482        default = None,
483        required = False,
484        )
485
486    validation_date = schema.Datetime(
487        title = _(u'Validation Date'),
488        required = False,
489        readonly = False,
490        )
491
[8920]492    def addCourseTicket(ticket, course):
[8182]493        """Add a course ticket object.
494        """
495
[9501]496    def addCertCourseTickets(cert):
497        """Collect all certificate courses and create course
498        tickets automatically.
499        """
500
[7819]501class ICourseTicket(IKofaObject):
[9420]502    """An interface for course tickets.
[6781]503
504    """
[6783]505    code = Attribute('code of the original course')
[9253]506    certcode = Attribute('certificate code of the study course')
[6781]507
[9420]508    title = schema.TextLine(
509        title = _(u'Title'),
510        required = False,
511        )
512
513    fcode = schema.TextLine(
514        title = _(u'Faculty Code'),
515        required = False,
516        )
517
518    dcode = schema.TextLine(
519        title = _(u'Department Code'),
520        required = False,
521        )
522
523    semester = schema.Choice(
524        title = _(u'Semester/Term'),
525        source = SemesterSource(),
526        required = False,
527        )
528
529    passmark = schema.Int(
530        title = _(u'Passmark'),
531        required = False,
532        )
533
534    credits = schema.Int(
535        title = _(u'Credits'),
536        required = False,
537        )
538
[7665]539    mandatory = schema.Bool(
[9320]540        title = _(u'Required'),
[6795]541        default = False,
542        required = False,
543        )
544
[6781]545    score = schema.Int(
[7723]546        title = _(u'Score'),
[6781]547        default = 0,
548        required = False,
549        )
550
[7661]551    carry_over = schema.Bool(
[7723]552        title = _(u'Carry-over Course'),
[7661]553        default = False,
554        required = False,
555        )
556
[9420]557    automatic = schema.Bool(
558        title = _(u'Automatical Creation'),
559        default = False,
[9316]560        required = False,
561        )
562
563
[7633]564    def getLevel():
565        """Returns the id of the level the ticket has been added to.
566        """
567
568    def getLevelSession():
569        """Returns the session of the level the ticket has been added to.
570        """
571
[9420]572class ICourseTicketAdd(IKofaObject):
[7150]573    """An interface for adding course tickets.
[6795]574
575    """
576    course = schema.Choice(
[7723]577        title = _(u'Course'),
[6795]578        source = CourseSource(),
579        readonly = False,
580        )
581
[9420]582class ICourseTicketImport(ICourseTicket):
583    """An interface for importing course results and nothing more.
584
585    """
586    score = schema.Int(
587        title = _(u'Score'),
588        required = False,
589        readonly = False,
590        )
591
592    level_session = schema.Choice(
593        title = _(u'Level Session'),
594        source = academic_sessions_vocab,
595        required = False,
596        readonly = False,
597        )
598
[7819]599class IStudentAccommodation(IKofaObject):
[6635]600    """A container for student accommodation objects.
601
602    """
603
[9423]604    def addBedTicket(bedticket):
605        """Add a bed ticket object.
606        """
607
608
[7819]609class IBedTicket(IKofaObject):
[6989]610    """A ticket for accommodation booking.
611
612    """
[6996]613    bed = Attribute('The bed object.')
614
615    bed_coordinates = schema.TextLine(
[9424]616        title = _(u'Allocated Bed'),
[9423]617        required = True,
[7014]618        readonly = False,
[6992]619        )
620
[6996]621    bed_type = schema.TextLine(
[9424]622        title = _(u'Requested Bed Type'),
[9423]623        required = True,
[7014]624        readonly = False,
[6996]625        )
626
[6992]627    booking_session = schema.Choice(
[7723]628        title = _(u'Session'),
[6992]629        source = academic_sessions_vocab,
630        required = True,
[7014]631        readonly = True,
[6992]632        )
633
[8170]634    booking_date = schema.Datetime(
[7723]635        title = _(u'Booking Date'),
[6992]636        required = False,
[7014]637        readonly = True,
[6992]638        )
639
640    booking_code = schema.TextLine(
[7723]641        title = _(u'Booking Activation Code'),
[6992]642        required = False,
[7014]643        readonly = True,
[6992]644        )
645
[6994]646    def getSessionString():
[7633]647        """Returns the title of academic_sessions_vocab term.
[7150]648
[6994]649        """
[6992]650
[6860]651class IStudentPaymentsContainer(IPaymentsContainer):
[6635]652    """A container for student payment objects.
653
654    """
655
[6877]656class IStudentOnlinePayment(IOnlinePayment):
657    """A student payment via payment gateways.
658
659    """
660
[9148]661    p_current = schema.Bool(
662        title = _(u'Current Session Payment'),
663        default = True,
664        required = False,
665        )
666
[8268]667    p_level = schema.Int(
668        title = _(u'Payment Level'),
669        required = False,
670        readonly = True,
671        )
[6877]672
[8422]673    def doAfterStudentPayment():
674        """Process student after payment was made.
675
676        """
677
[8453]678    def doAfterStudentPaymentApproval():
679        """Process student after payment was approved.
680
681        """
682
[8420]683    def approveStudentPayment():
[8422]684        """Approve payment and process student.
[8420]685
686        """
687
[8268]688IStudentOnlinePayment['p_level'].order = IStudentOnlinePayment[
689    'p_session'].order
[8408]690
[9148]691class IStudentPreviousPayment(IOnlinePayment):
692    """An interface for adding previous session payments.
693
694    """
695
696    p_session = schema.Choice(
697        title = _(u'Payment Session'),
698        source = academic_sessions_vocab,
699        required = True,
700        )
701
702    p_level = schema.Choice(
703        title = _(u'Payment Level'),
704        source = StudyLevelSource(),
705        required = True,
706        )
707
[8408]708class ICSVStudentExporter(ICSVExporter):
709    """A regular ICSVExporter that additionally supports exporting
710      data from a given student object.
711    """
712
713    def export_student(student, filepath=None):
714        """Export data for a given student.
715        """
Note: See TracBrowser for help on using the repository browser.