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

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

We need a special interface for the StudentPersonalEditFormPage?. Some fields on this form are required.

  • Property svn:keywords set to Id
File size: 19.1 KB
Line 
1## $Id: interfaces.py 9563 2012-11-06 20:29:35Z 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    student_id = schema.TextLine(
172        title = _(u'Student Id'),
173        required = False,
174        )
175
176    firstname = schema.TextLine(
177        title = _(u'First Name'),
178        required = True,
179        )
180
181    middlename = schema.TextLine(
182        title = _(u'Middle Name'),
183        required = False,
184        )
185
186    lastname = schema.TextLine(
187        title = _(u'Last Name (Surname)'),
188        required = True,
189        )
190
191    sex = schema.Choice(
192        title = _(u'Sex'),
193        source = GenderSource(),
194        required = True,
195        )
196
197    reg_number = TextLineChoice(
198        title = _(u'Registration Number'),
199        required = True,
200        readonly = False,
201        source = contextual_reg_num_source,
202        )
203
204    matric_number = TextLineChoice(
205        title = _(u'Matriculation Number'),
206        required = False,
207        readonly = False,
208        source = contextual_mat_num_source,
209        )
210
211    adm_code = schema.TextLine(
212        title = _(u'PWD Activation Code'),
213        required = False,
214        readonly = False,
215        )
216
217    email = schema.ASCIILine(
218        title = _(u'Email'),
219        required = False,
220        constraint=validate_email,
221        )
222    phone = PhoneNumber(
223        title = _(u'Phone'),
224        description = u'',
225        required = False,
226        )
227
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
242    def transfer(certificate, current_session,
243        current_level, current_verdict):
244        """ Creates a new studycourse and backups the old one.
245
246        """
247
248class IUGStudentClearance(IKofaObject):
249    """Representation of undergraduate student clearance data.
250
251    """
252    officer_comment = schema.Text(
253        title = _(u"Officer's Comment"),
254        required = False,
255        )
256
257    clearance_locked = schema.Bool(
258        title = _(u'Clearance form locked'),
259        default = False,
260        required = False,
261        )
262
263    clr_code = schema.TextLine(
264        title = _(u'CLR Activation Code'),
265        required = False,
266        readonly = False,
267        )
268
269    date_of_birth = FormattedDate(
270        title = _(u'Date of Birth'),
271        required = True,
272        show_year = True,
273        )
274
275    nationality = schema.Choice(
276        vocabulary = nats_vocab,
277        title = _(u'Nationality'),
278        required = False,
279        )
280
281class IPGStudentClearance(IUGStudentClearance):
282    """Representation of postgraduate student clearance data.
283
284    """
285    employer = schema.TextLine(
286        title = _(u'Employer'),
287        required = False,
288        readonly = False,
289        )
290
291class IStudentPersonal(IKofaObject):
292    """Representation of student personal data.
293
294    """
295    personal_updated = schema.Datetime(
296        title = _(u'Updated'),
297        required = False,
298        readonly = False,
299        )
300
301    perm_address = schema.Text(
302        title = _(u'Permanent Address'),
303        required = False,
304        )
305
306class IStudent(IStudentBase,IUGStudentClearance,IPGStudentClearance,
307    IStudentPersonal):
308    """Representation of a student.
309
310    """
311
312class IStudentPersonalEdit(IStudentPersonal):
313    """Interface for editing personal data by students.
314
315    Here we can repeat the fields from IStudentPersonal and set the
316    `required` if necessary.
317    """
318
319    perm_address = schema.Text(
320        title = _(u'Permanent Address'),
321        required = True,
322        )
323
324class IStudentUpdateByRegNo(IStudent):
325    """Representation of a student. Skip regular reg_number validation.
326
327    """
328    reg_number = schema.TextLine(
329        title = _(u'Registration Number'),
330        required = False,
331        )
332
333class IStudentUpdateByMatricNo(IStudent):
334    """Representation of a student. Skip regular matric_number validation.
335
336    """
337    matric_number = schema.TextLine(
338        title = _(u'Matriculation Number'),
339        required = False,
340        )
341
342class IStudentRequestPW(IStudent):
343    """Representation of an student for first-time password request.
344
345    This interface is used when students use the requestpw page to
346    login for the the first time.
347    """
348    number = schema.TextLine(
349        title = _(u'Registr. or Matric. Number'),
350        required = True,
351        )
352
353    firstname = schema.TextLine(
354        title = _(u'First Name'),
355        required = True,
356        )
357
358    email = schema.ASCIILine(
359        title = _(u'Email Address'),
360        required = True,
361        constraint=validate_email,
362        )
363
364class IStudentStudyCourse(IKofaObject):
365    """A container for student study levels.
366
367    """
368    certificate = schema.Choice(
369        title = _(u'Certificate'),
370        source = CertificateSource(),
371        required = False,
372        )
373
374    entry_mode = schema.Choice(
375        title = _(u'Entry Mode'),
376        source = StudyModeSource(),
377        required = True,
378        readonly = False,
379        )
380
381    entry_session = schema.Choice(
382        title = _(u'Entry Session'),
383        source = academic_sessions_vocab,
384        #default = datetime.now().year,
385        required = True,
386        readonly = False,
387        )
388
389    current_session = schema.Choice(
390        title = _(u'Current Session'),
391        source = academic_sessions_vocab,
392        required = True,
393        readonly = False,
394        )
395
396    current_level = schema.Choice(
397        title = _(u'Current Level'),
398        source = StudyLevelSource(),
399        required = False,
400        readonly = False,
401        )
402
403    current_verdict = schema.Choice(
404        title = _(u'Current Verdict'),
405        source = VerdictSource(),
406        default = '0',
407        required = False,
408        )
409
410    previous_verdict = schema.Choice(
411        title = _(u'Previous Verdict'),
412        source = VerdictSource(),
413        default = '0',
414        required = False,
415        )
416
417class IStudentStudyCourseTransfer(IStudentStudyCourse):
418    """An student transfers.
419
420    """
421
422    certificate = schema.Choice(
423        title = _(u'Certificate'),
424        source = CertificateSource(),
425        required = True,
426        )
427
428    current_level = schema.Choice(
429        title = _(u'Current Level'),
430        source = StudyLevelSource(),
431        required = True,
432        readonly = False,
433        )
434
435
436IStudentStudyCourseTransfer['certificate'].order = IStudentStudyCourse[
437    'certificate'].order
438IStudentStudyCourseTransfer['current_level'].order = IStudentStudyCourse[
439    'current_level'].order
440
441class IStudentVerdictUpdate(IKofaObject):
442    """A interface for verdict imports.
443
444    """
445
446    current_verdict = schema.Choice(
447        title = _(u'Current Verdict'),
448        source = VerdictSource(),
449        required = True,
450        )
451
452    current_session = schema.Choice(
453        title = _(u'Current Session'),
454        source = academic_sessions_vocab,
455        required = True,
456        )
457
458    current_level = schema.Choice(
459        title = _(u'Current Level'),
460        source = StudyLevelSource(),
461        required = True,
462        )
463
464    bypass_validation = schema.Bool(
465        title = _(u'Bypass validation'),
466        required = False,
467        )
468
469    validated_by = schema.TextLine(
470        title = _(u'Validated by'),
471        required = False,
472        )
473
474class IStudentStudyLevel(IKofaObject):
475    """A container for course tickets.
476
477    """
478    level = Attribute('The level code')
479    number_of_tickets = Attribute('Number of tickets contained in this level')
480    certcode = Attribute('The certificate code of the study course')
481    is_current_level = Attribute('Is this level the current level of the student?')
482    total_credits = Attribute('Total of all ticket credits in this study level.')
483
484    level_session = schema.Choice(
485        title = _(u'Session'),
486        source = academic_sessions_vocab,
487        required = True,
488        )
489
490    level_verdict = schema.Choice(
491        title = _(u'Verdict'),
492        source = VerdictSource(),
493        default = '0',
494        required = False,
495        )
496
497    validated_by = schema.TextLine(
498        title = _(u'Validated by'),
499        default = None,
500        required = False,
501        )
502
503    validation_date = schema.Datetime(
504        title = _(u'Validation Date'),
505        required = False,
506        readonly = False,
507        )
508
509    def addCourseTicket(ticket, course):
510        """Add a course ticket object.
511        """
512
513    def addCertCourseTickets(cert):
514        """Collect all certificate courses and create course
515        tickets automatically.
516        """
517
518class ICourseTicket(IKofaObject):
519    """An interface for course tickets.
520
521    """
522    code = Attribute('code of the original course')
523    certcode = Attribute('certificate code of the study course')
524
525    title = schema.TextLine(
526        title = _(u'Title'),
527        required = False,
528        )
529
530    fcode = schema.TextLine(
531        title = _(u'Faculty Code'),
532        required = False,
533        )
534
535    dcode = schema.TextLine(
536        title = _(u'Department Code'),
537        required = False,
538        )
539
540    semester = schema.Choice(
541        title = _(u'Semester/Term'),
542        source = SemesterSource(),
543        required = False,
544        )
545
546    passmark = schema.Int(
547        title = _(u'Passmark'),
548        required = False,
549        )
550
551    credits = schema.Int(
552        title = _(u'Credits'),
553        required = False,
554        )
555
556    mandatory = schema.Bool(
557        title = _(u'Required'),
558        default = False,
559        required = False,
560        )
561
562    score = schema.Int(
563        title = _(u'Score'),
564        default = 0,
565        required = False,
566        )
567
568    carry_over = schema.Bool(
569        title = _(u'Carry-over Course'),
570        default = False,
571        required = False,
572        )
573
574    automatic = schema.Bool(
575        title = _(u'Automatical Creation'),
576        default = False,
577        required = False,
578        )
579
580
581    def getLevel():
582        """Returns the id of the level the ticket has been added to.
583        """
584
585    def getLevelSession():
586        """Returns the session of the level the ticket has been added to.
587        """
588
589class ICourseTicketAdd(IKofaObject):
590    """An interface for adding course tickets.
591
592    """
593    course = schema.Choice(
594        title = _(u'Course'),
595        source = CourseSource(),
596        readonly = False,
597        )
598
599class ICourseTicketImport(ICourseTicket):
600    """An interface for importing course results and nothing more.
601
602    """
603    score = schema.Int(
604        title = _(u'Score'),
605        required = False,
606        readonly = False,
607        )
608
609    level_session = schema.Choice(
610        title = _(u'Level Session'),
611        source = academic_sessions_vocab,
612        required = False,
613        readonly = False,
614        )
615
616class IStudentAccommodation(IKofaObject):
617    """A container for student accommodation objects.
618
619    """
620
621    def addBedTicket(bedticket):
622        """Add a bed ticket object.
623        """
624
625
626class IBedTicket(IKofaObject):
627    """A ticket for accommodation booking.
628
629    """
630    bed = Attribute('The bed object.')
631
632    bed_coordinates = schema.TextLine(
633        title = _(u'Allocated Bed'),
634        required = True,
635        readonly = False,
636        )
637
638    bed_type = schema.TextLine(
639        title = _(u'Requested Bed Type'),
640        required = True,
641        readonly = False,
642        )
643
644    booking_session = schema.Choice(
645        title = _(u'Session'),
646        source = academic_sessions_vocab,
647        required = True,
648        readonly = True,
649        )
650
651    booking_date = schema.Datetime(
652        title = _(u'Booking Date'),
653        required = False,
654        readonly = True,
655        )
656
657    booking_code = schema.TextLine(
658        title = _(u'Booking Activation Code'),
659        required = False,
660        readonly = True,
661        )
662
663    def getSessionString():
664        """Returns the title of academic_sessions_vocab term.
665
666        """
667
668class IStudentPaymentsContainer(IPaymentsContainer):
669    """A container for student payment objects.
670
671    """
672
673class IStudentOnlinePayment(IOnlinePayment):
674    """A student payment via payment gateways.
675
676    """
677
678    p_current = schema.Bool(
679        title = _(u'Current Session Payment'),
680        default = True,
681        required = False,
682        )
683
684    p_level = schema.Int(
685        title = _(u'Payment Level'),
686        required = False,
687        )
688
689    def doAfterStudentPayment():
690        """Process student after payment was made.
691
692        """
693
694    def doAfterStudentPaymentApproval():
695        """Process student after payment was approved.
696
697        """
698
699    def approveStudentPayment():
700        """Approve payment and process student.
701
702        """
703
704IStudentOnlinePayment['p_level'].order = IStudentOnlinePayment[
705    'p_session'].order
706
707class IStudentPreviousPayment(IOnlinePayment):
708    """An interface for adding previous session payments.
709
710    """
711
712    p_session = schema.Choice(
713        title = _(u'Payment Session'),
714        source = academic_sessions_vocab,
715        required = True,
716        )
717
718    p_level = schema.Choice(
719        title = _(u'Payment Level'),
720        source = StudyLevelSource(),
721        required = True,
722        )
723
724class ICSVStudentExporter(ICSVExporter):
725    """A regular ICSVExporter that additionally supports exporting
726      data from a given student object.
727    """
728
729    def export_student(student, filepath=None):
730        """Export data for a given student.
731        """
Note: See TracBrowser for help on using the repository browser.