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

Last change on this file since 8483 was 8453, checked in by Henrik Bettermann, 13 years ago

Applicants must not trigger the the approve transition which lead to wrong history message.

Distinguish between payment approval and regular payment in log files too.

  • Property svn:keywords set to Id
File size: 14.2 KB
RevLine 
[7191]1## $Id: interfaces.py 8453 2012-05-15 20:29:34Z 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
[7811]23from waeup.kofa.interfaces import (
[8409]24    IKofaObject, academic_sessions_vocab, validate_email, ICSVExporter)
[7811]25from waeup.kofa.interfaces import MessageFactory as _
[8176]26from waeup.kofa.schema import TextLineChoice, FormattedDate, PhoneNumber
[7811]27from waeup.kofa.students.vocabularies import (
[7915]28    StudyLevelSource, contextual_reg_num_source, contextual_mat_num_source,
29    GenderSource, nats_vocab,
30    )
[8160]31from waeup.kofa.payments.interfaces import (
[8174]32    IPaymentsContainer, IOnlinePayment)
[7915]33from waeup.kofa.university.vocabularies import (
34    CourseSource, StudyModeSource, CertificateSource)
[6621]35
[7620]36# VerdictSource can't be placed into the vocabularies module because it
37# requires importing IStudentsUtils which then leads to circular imports.
38class VerdictSource(BasicContextualSourceFactory):
39    """A verdicts source delivers all verdicts provided
40    in the portal.
41    """
42    def getValues(self, context):
[7841]43        verdicts_dict = getUtility(IStudentsUtils).VERDICTS_DICT
[7688]44        return verdicts_dict.keys()
[7620]45
46    def getToken(self, context, value):
47        return value
48
49    def getTitle(self, context, value):
[7841]50        verdicts_dict = getUtility(IStudentsUtils).VERDICTS_DICT
[7688]51        return verdicts_dict[value]
[7620]52
[7681]53
[7150]54class IStudentsUtils(Interface):
55    """A collection of methods which are subject to customization.
56
57    """
[7841]58    def setReturningData(student):
59        """ This method defines what happens after school fee payment
60        depending on the student's senate verdict.
61
62        In the base configuration current level is always increased
63        by 100 no matter which verdict has been assigned.
64        """
65
[7186]66    def getPaymentDetails(category, student):
[7150]67        """Get the payment dates of a student for the payment category
68        specified.
69
70        """
71
[7186]72    def getAccommodation_details(student):
[7150]73        """Determine the accommodation dates of a student.
74
75        """
76
[7186]77    def selectBed(available_beds):
[7150]78        """Select a bed from a list of available beds.
79
80        In the standard configuration we select the first bed found,
81        but can also randomize the selection if we like.
82        """
83
[7186]84    def renderPDF(view, subject='', filename='slip.pdf',):
[7150]85        """Render pdf slips for various pages.
86
87        """
88
[7819]89class IStudentsContainer(IKofaObject):
[7096]90    """A students container contains university students.
[6692]91
92    """
93    def addStudent(student):
94        """Add an IStudent object and subcontainers.
95
96        """
97
98    def archive(id=None):
99        """Create on-dist archive of students.
100
101        If id is `None`, all students are archived.
102
103        If id contains a single id string, only the respective
104        students are archived.
105
106        If id contains a list of id strings all of the respective
107        students types are saved to disk.
108        """
109
110    def clear(id=None, archive=True):
111        """Remove students of type given by 'id'.
112
113        Optionally archive the students.
114
115        If id is `None`, all students are archived.
116
117        If id contains a single id string, only the respective
118        students are archived.
119
120        If id contains a list of id strings all of the respective
121        student types are saved to disk.
122
123        If `archive` is ``False`` none of the archive-handling is done
124        and respective students are simply removed from the
125        database.
126        """
127
[8408]128    unique_student_id = Attribute("""A unique student id.""")
129
[7819]130class IStudentNavigation(IKofaObject):
[6642]131    """Interface needed for student navigation.
[7150]132
[6642]133    """
134    def getStudent():
135        """Return student object.
[7150]136
[6642]137        """
138
[7819]139class IStudentBase(IKofaObject):
[6631]140    """Representation of student base data.
[7150]141
[6621]142    """
[7062]143    history = Attribute('Object history, a list of messages')
[6637]144    state = Attribute('Returns the registration state of a student')
[6699]145    password = Attribute('Encrypted password of a student')
[7203]146    certcode = Attribute('The certificate code of any chosen study course')
147    depcode = Attribute('The department code of any chosen study course')
148    faccode = Attribute('The faculty code of any chosen study course')
[7062]149    current_session = Attribute('The current session of the student')
[7641]150    current_mode = Attribute('The current mode of the student')
[7364]151    fullname = Attribute('All name parts separated by hyphens')
152    display_fullname = Attribute('The fullname of an applicant')
[6637]153
154    def loggerInfo(ob_class, comment):
[7150]155        """Adds an INFO message to the log file.
156
[6637]157        """
158
[6665]159    student_id = schema.TextLine(
[7723]160        title = _(u'Student Id'),
[6849]161        required = False,
[6665]162        )
163
[7357]164    firstname = schema.TextLine(
[7723]165        title = _(u'First Name'),
[6621]166        required = True,
167        )
168
[7357]169    middlename = schema.TextLine(
[7723]170        title = _(u'Middle Name'),
[7357]171        required = False,
172        )
173
174    lastname = schema.TextLine(
[7723]175        title = _(u'Last Name (Surname)'),
[7357]176        required = True,
177        )
178
[6996]179    sex = schema.Choice(
[7723]180        title = _(u'Sex'),
[6996]181        source = GenderSource(),
182        required = True,
183        )
184
[6788]185    reg_number = TextLineChoice(
[7723]186        title = _(u'Registration Number'),
[6696]187        required = True,
188        readonly = False,
[6788]189        source = contextual_reg_num_source,
[6696]190        )
191
[6788]192    matric_number = TextLineChoice(
[7723]193        title = _(u'Matriculation Number'),
[6750]194        required = False,
195        readonly = False,
[6788]196        source = contextual_mat_num_source,
[6750]197        )
198
[6769]199    adm_code = schema.TextLine(
[7723]200        title = _(u'PWD Activation Code'),
[6769]201        required = False,
202        readonly = True,
203        )
204
[7133]205    email = schema.ASCIILine(
[7723]206        title = _(u'Email'),
[7133]207        required = False,
208        constraint=validate_email,
209        )
[8176]210    phone = PhoneNumber(
[7723]211        title = _(u'Phone'),
[7331]212        description = u'',
[7133]213        required = False,
214        )
215
[7993]216class IUGStudentClearance(IKofaObject):
217    """Representation of undergraduate student clearance data.
[7150]218
[6631]219    """
[8160]220    date_of_birth = FormattedDate(
[7723]221        title = _(u'Date of Birth'),
[6631]222        required = True,
[8160]223        show_year = True,
[6631]224        )
225
[6695]226    clearance_locked = schema.Bool(
[7723]227        title = _(u'Clearance form locked'),
[6695]228        default = False,
229        )
230
[6769]231    clr_code = schema.TextLine(
[7723]232        title = _(u'CLR Activation Code'),
[6769]233        required = False,
234        readonly = True,
235        )
236
[7523]237    nationality = schema.Choice(
[8069]238        vocabulary = nats_vocab,
[7723]239        title = _(u'Nationality'),
[7983]240        required = False,
[7523]241        )
242
[7993]243class IPGStudentClearance(IUGStudentClearance):
244    """Representation of postgraduate student clearance data.
245
246    """
247    employer = schema.TextLine(
248        title = _(u'Employer'),
249        required = False,
250        readonly = False,
251        )
252
[7819]253class IStudentPersonal(IKofaObject):
[6631]254    """Representation of student personal data.
[7150]255
[6631]256    """
[6651]257    perm_address = schema.Text(
[7723]258        title = _(u'Permanent Address'),
[6631]259        required = False,
260        )
261
[8008]262class IStudent(IStudentBase,IUGStudentClearance,IPGStudentClearance,
263    IStudentPersonal):
[6631]264    """Representation of a student.
[7150]265
[6631]266    """
267
[6849]268class IStudentUpdateByRegNo(IStudent):
269    """Representation of a student. Skip regular reg_number validation.
[7150]270
[6849]271    """
272    reg_number = schema.TextLine(
[7723]273        title = _(u'Registration Number'),
[6849]274        required = False,
275        )
276
277class IStudentUpdateByMatricNo(IStudent):
278    """Representation of a student. Skip regular matric_number validation.
[7150]279
[6849]280    """
281    matric_number = schema.TextLine(
[7723]282        title = _(u'Matriculation Number'),
[6849]283        required = False,
284        )
285
[7819]286class IStudentStudyCourse(IKofaObject):
[6633]287    """A container for student study levels.
288
289    """
[6648]290    certificate = schema.Choice(
[7723]291        title = _(u'Certificate'),
[6648]292        source = CertificateSource(),
[7209]293        required = False,
[6633]294        )
[6635]295
[6996]296    entry_mode = schema.Choice(
[7723]297        title = _(u'Entry Mode'),
[7681]298        source = StudyModeSource(),
[6996]299        required = True,
300        readonly = False,
301        )
302
303    entry_session = schema.Choice(
[7723]304        title = _(u'Entry Session'),
[6996]305        source = academic_sessions_vocab,
[7425]306        #default = datetime.now().year,
[6996]307        required = True,
308        readonly = False,
309        )
310
[6724]311    current_session = schema.Choice(
[7723]312        title = _(u'Current Session'),
[6744]313        source = academic_sessions_vocab,
[6724]314        required = True,
[6996]315        readonly = False,
[6724]316        )
317
318    current_level = schema.Choice(
[7723]319        title = _(u'Current Level'),
[6725]320        source = StudyLevelSource(),
321        required = False,
[6996]322        readonly = False,
[6724]323        )
324
325    current_verdict = schema.Choice(
[7723]326        title = _(u'Current Verdict'),
[7619]327        source = VerdictSource(),
[6804]328        default = '0',
[6725]329        required = False,
[6724]330        )
331
332    previous_verdict = schema.Choice(
[7723]333        title = _(u'Previous Verdict'),
[7619]334        source = VerdictSource(),
[6805]335        default = '0',
[6725]336        required = False,
[6724]337        )
338
[7951]339class IStudentVerdictUpdate(IKofaObject):
340    """A interface for verdict imports.
341
342    """
343
344    current_verdict = schema.Choice(
345        title = _(u'Current Verdict'),
346        source = VerdictSource(),
347        required = True,
348        )
349
350    current_session = schema.Choice(
351        title = _(u'Current Session'),
352        source = academic_sessions_vocab,
353        required = True,
354        )
355
356    current_level = schema.Choice(
357        title = _(u'Current Level'),
358        source = StudyLevelSource(),
359        required = True,
360        )
361
[7819]362class IStudentStudyLevel(IKofaObject):
[6774]363    """A container for course tickets.
364
365    """
366    level = Attribute('The level code')
[6793]367    validation_date = Attribute('The date of validation')
368    validated_by = Attribute('User Id of course adviser')
[6774]369
[6793]370    level_session = schema.Choice(
[7723]371        title = _(u'Session'),
[6793]372        source = academic_sessions_vocab,
373        required = True,
374        )
[6781]375
[6793]376    level_verdict = schema.Choice(
[7723]377        title = _(u'Verdict'),
[7619]378        source = VerdictSource(),
[6805]379        default = '0',
[6793]380        required = False,
381        )
382
[8182]383    def addCourseTicket(courseticket):
384        """Add a course ticket object.
385        """
386
387    def getStudent():
388        """Return student
389        """
390
[7819]391class ICourseTicket(IKofaObject):
[6781]392    """A course ticket.
393
394    """
[6783]395    code = Attribute('code of the original course')
396    title = Attribute('title of the original course')
397    credits = Attribute('credits of the original course')
398    passmark = Attribute('passmark of the original course')
399    semester = Attribute('semester of the original course')
[7304]400    fcode = Attribute('faculty code of the original course')
401    dcode = Attribute('department code of the original course')
[6781]402
[7665]403    mandatory = schema.Bool(
[7723]404        title = _(u'Mandatory'),
[6795]405        default = False,
406        required = False,
407        readonly = False,
408        )
409
[6781]410    score = schema.Int(
[7723]411        title = _(u'Score'),
[6781]412        default = 0,
413        required = False,
414        readonly = False,
415        )
416
[6806]417    automatic = schema.Bool(
[7723]418        title = _(u'Automatical Creation'),
[6806]419        default = False,
420        required = False,
421        readonly = True,
422        )
423
[7661]424    carry_over = schema.Bool(
[7723]425        title = _(u'Carry-over Course'),
[7661]426        default = False,
427        required = False,
428        readonly = False,
429        )
430
[7633]431    def getLevel():
432        """Returns the id of the level the ticket has been added to.
433        """
434
435    def getLevelSession():
436        """Returns the session of the level the ticket has been added to.
437        """
438
[6795]439class ICourseTicketAdd(ICourseTicket):
[7150]440    """An interface for adding course tickets.
[6795]441
442    """
443    course = schema.Choice(
[7723]444        title = _(u'Course'),
[6795]445        source = CourseSource(),
446        readonly = False,
447        )
448
[7819]449class IStudentAccommodation(IKofaObject):
[6635]450    """A container for student accommodation objects.
451
452    """
453
[7819]454class IBedTicket(IKofaObject):
[6989]455    """A ticket for accommodation booking.
456
457    """
[6996]458    bed = Attribute('The bed object.')
459
460    bed_coordinates = schema.TextLine(
[7723]461        title = _(u'Bed Coordinates'),
[6992]462        required = False,
[7014]463        readonly = False,
[6992]464        )
465
[6996]466    bed_type = schema.TextLine(
[7723]467        title = _(u'Bed Type'),
[6996]468        required = False,
[7014]469        readonly = False,
[6996]470        )
471
[6992]472    booking_session = schema.Choice(
[7723]473        title = _(u'Session'),
[6992]474        source = academic_sessions_vocab,
475        required = True,
[7014]476        readonly = True,
[6992]477        )
478
[8170]479    booking_date = schema.Datetime(
[7723]480        title = _(u'Booking Date'),
[6992]481        required = False,
[7014]482        readonly = True,
[6992]483        )
484
485    booking_code = schema.TextLine(
[7723]486        title = _(u'Booking Activation Code'),
[6992]487        required = False,
[7014]488        readonly = True,
[6992]489        )
490
[6994]491    def getSessionString():
[7633]492        """Returns the title of academic_sessions_vocab term.
[7150]493
[6994]494        """
[6992]495
[6860]496class IStudentPaymentsContainer(IPaymentsContainer):
[6635]497    """A container for student payment objects.
498
499    """
500
[6877]501class IStudentOnlinePayment(IOnlinePayment):
502    """A student payment via payment gateways.
503
504    """
505
[8268]506    p_level = schema.Int(
507        title = _(u'Payment Level'),
508        required = False,
509        readonly = True,
510        )
[6877]511
[8422]512    def doAfterStudentPayment():
513        """Process student after payment was made.
514
515        """
516
[8453]517    def doAfterStudentPaymentApproval():
518        """Process student after payment was approved.
519
520        """
521
[8420]522    def approveStudentPayment():
[8422]523        """Approve payment and process student.
[8420]524
525        """
526
[8268]527IStudentOnlinePayment['p_level'].order = IStudentOnlinePayment[
528    'p_session'].order
[8408]529
530class ICSVStudentExporter(ICSVExporter):
531    """A regular ICSVExporter that additionally supports exporting
532      data from a given student object.
533    """
534
535    def export_student(student, filepath=None):
536        """Export data for a given student.
537        """
Note: See TracBrowser for help on using the repository browser.