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

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

We need to customize if students are allowed to remove mandatory course tickets. Therefore I added a property attribute removable_by_student.

Allow manager to edit the mandatory attribute.

  • Property svn:keywords set to Id
File size: 19.5 KB
Line 
1## $Id: interfaces.py 9698 2012-11-20 09:08:13Z 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
483    level_session = schema.Choice(
484        title = _(u'Session'),
485        source = academic_sessions_vocab,
486        required = True,
487        )
488
489    level_verdict = schema.Choice(
490        title = _(u'Verdict'),
491        source = VerdictSource(),
492        default = '0',
493        required = False,
494        )
495
496    validated_by = schema.TextLine(
497        title = _(u'Validated by'),
498        default = None,
499        required = False,
500        )
501
502    validation_date = schema.Datetime(
503        title = _(u'Validation Date'),
504        required = False,
505        readonly = False,
506        )
507
508    total_credits = schema.Int(
509        title = _(u'Total Credits'),
510        required = False,
511        readonly = True,
512        )
513
514    gpa = schema.Int(
515        title = _(u'GPA'),
516        required = False,
517        readonly = True,
518        )
519
520    def addCourseTicket(ticket, course):
521        """Add a course ticket object.
522        """
523
524    def addCertCourseTickets(cert):
525        """Collect all certificate courses and create course
526        tickets automatically.
527        """
528
529class ICourseTicket(IKofaObject):
530    """An interface for course tickets.
531
532    """
533    code = Attribute('code of the original course')
534    certcode = Attribute('certificate code of the study course')
535    grade = Attribute('grade calculated from score')
536    weight = Attribute('weight calculated from score')
537    removable_by_student = Attribute('Is student allowed to remove the ticket?')
538
539    title = schema.TextLine(
540        title = _(u'Title'),
541        required = False,
542        )
543
544    fcode = schema.TextLine(
545        title = _(u'Faculty Code'),
546        required = False,
547        )
548
549    dcode = schema.TextLine(
550        title = _(u'Department Code'),
551        required = False,
552        )
553
554    semester = schema.Choice(
555        title = _(u'Semester/Term'),
556        source = SemesterSource(),
557        required = False,
558        )
559
560    passmark = schema.Int(
561        title = _(u'Passmark'),
562        required = False,
563        )
564
565    credits = schema.Int(
566        title = _(u'Credits'),
567        required = False,
568        )
569
570    mandatory = schema.Bool(
571        title = _(u'Required'),
572        default = False,
573        required = False,
574        )
575
576    score = schema.Int(
577        title = _(u'Score'),
578        default = None,
579        required = False,
580        )
581
582    carry_over = schema.Bool(
583        title = _(u'Carry-over Course'),
584        default = False,
585        required = False,
586        )
587
588    automatic = schema.Bool(
589        title = _(u'Automatical Creation'),
590        default = False,
591        required = False,
592        )
593
594    def getLevel():
595        """Returns the id of the level the ticket has been added to.
596        """
597
598    def getLevelSession():
599        """Returns the session of the level the ticket has been added to.
600        """
601
602class ICourseTicketAdd(IKofaObject):
603    """An interface for adding course tickets.
604
605    """
606    course = schema.Choice(
607        title = _(u'Course'),
608        source = CourseSource(),
609        readonly = False,
610        )
611
612class ICourseTicketImport(ICourseTicket):
613    """An interface for importing course results and nothing more.
614
615    """
616    score = schema.Int(
617        title = _(u'Score'),
618        required = False,
619        readonly = False,
620        )
621
622    level_session = schema.Choice(
623        title = _(u'Level Session'),
624        source = academic_sessions_vocab,
625        required = False,
626        readonly = False,
627        )
628
629class IStudentAccommodation(IKofaObject):
630    """A container for student accommodation objects.
631
632    """
633
634    def addBedTicket(bedticket):
635        """Add a bed ticket object.
636        """
637
638
639class IBedTicket(IKofaObject):
640    """A ticket for accommodation booking.
641
642    """
643    bed = Attribute('The bed object.')
644
645    bed_coordinates = schema.TextLine(
646        title = _(u'Allocated Bed'),
647        required = True,
648        readonly = False,
649        )
650
651    bed_type = schema.TextLine(
652        title = _(u'Requested Bed Type'),
653        required = True,
654        readonly = False,
655        )
656
657    booking_session = schema.Choice(
658        title = _(u'Session'),
659        source = academic_sessions_vocab,
660        required = True,
661        readonly = True,
662        )
663
664    booking_date = schema.Datetime(
665        title = _(u'Booking Date'),
666        required = False,
667        readonly = True,
668        )
669
670    booking_code = schema.TextLine(
671        title = _(u'Booking Activation Code'),
672        required = False,
673        readonly = True,
674        )
675
676    def getSessionString():
677        """Returns the title of academic_sessions_vocab term.
678
679        """
680
681class IStudentPaymentsContainer(IPaymentsContainer):
682    """A container for student payment objects.
683
684    """
685
686class IStudentOnlinePayment(IOnlinePayment):
687    """A student payment via payment gateways.
688
689    """
690
691    p_current = schema.Bool(
692        title = _(u'Current Session Payment'),
693        default = True,
694        required = False,
695        )
696
697    p_level = schema.Int(
698        title = _(u'Payment Level'),
699        required = False,
700        )
701
702    def doAfterStudentPayment():
703        """Process student after payment was made.
704
705        """
706
707    def doAfterStudentPaymentApproval():
708        """Process student after payment was approved.
709
710        """
711
712    def approveStudentPayment():
713        """Approve payment and process student.
714
715        """
716
717IStudentOnlinePayment['p_level'].order = IStudentOnlinePayment[
718    'p_session'].order
719
720class IStudentPreviousPayment(IOnlinePayment):
721    """An interface for adding previous session payments.
722
723    """
724
725    p_session = schema.Choice(
726        title = _(u'Payment Session'),
727        source = academic_sessions_vocab,
728        required = True,
729        )
730
731    p_level = schema.Choice(
732        title = _(u'Payment Level'),
733        source = StudyLevelSource(),
734        required = True,
735        )
736
737class ICSVStudentExporter(ICSVExporter):
738    """A regular ICSVExporter that additionally supports exporting
739      data from a given student object.
740    """
741
742    def export_student(student, filepath=None):
743        """Export data for a given student.
744        """
Note: See TracBrowser for help on using the repository browser.