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

Last change on this file since 9840 was 9801, checked in by uli, 12 years ago

get_filtered() now accepts any keyword parameters and can handle catalog queries more properly.

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