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

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

Convert getLevel and getLevelSession into property attributes.

  • Property svn:keywords set to Id
File size: 21.4 KB
Line 
1## $Id: interfaces.py 9925 2013-01-30 09:08:39Z 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    ContextualDictSourceFactoryBase)
37
38class PreviousPaymentCategorySource(ContextualDictSourceFactoryBase):
39    """A source that delivers all selectable categories of previous session
40    payments.
41    """
42    #: name of dict to deliver from kofa utils.
43    DICT_NAME = 'PREVIOUS_PAYMENT_CATEGORIES'
44
45class BalancePaymentCategorySource(ContextualDictSourceFactoryBase):
46    """A source that delivers all selectable items of balance payments.
47    """
48    #: name of dict to deliver from kofa utils.
49    DICT_NAME = 'BALANCE_PAYMENT_CATEGORIES'
50
51# VerdictSource can't be placed into the vocabularies module because it
52# requires importing IStudentsUtils which then leads to circular imports.
53class VerdictSource(BasicContextualSourceFactory):
54    """A verdicts source delivers all verdicts provided
55    in the portal.
56    """
57    def getValues(self, context):
58        verdicts_dict = getUtility(IStudentsUtils).VERDICTS_DICT
59        return sorted(verdicts_dict.keys())
60
61    def getToken(self, context, value):
62        return value
63
64    def getTitle(self, context, value):
65        verdicts_dict = getUtility(IStudentsUtils).VERDICTS_DICT
66        if value != '0':
67            return verdicts_dict[value] + ' (%s)' % value
68        return verdicts_dict[value]
69
70
71class IStudentsUtils(Interface):
72    """A collection of methods which are subject to customization.
73
74    """
75    def setReturningData(student):
76        """ This method defines what happens after school fee payment
77        depending on the student's senate verdict.
78
79        In the base configuration current level is always increased
80        by 100 no matter which verdict has been assigned.
81        """
82
83    def setPaymentDetails(category, student, previous_session=None,
84            previous_level=None,):
85        """Create Payment object and set the payment data of a student for
86        the payment category specified.
87
88        """
89
90    def getAccommodation_details(student):
91        """Determine the accommodation dates of a student.
92
93        """
94
95    def selectBed(available_beds):
96        """Select a bed from a list of available beds.
97
98        In the standard configuration we select the first bed found,
99        but can also randomize the selection if we like.
100        """
101
102    def renderPDF(view, subject='', filename='slip.pdf',):
103        """Render pdf slips for various pages.
104
105        """
106
107class IStudentsContainer(IKofaObject):
108    """A students container contains university students.
109
110    """
111    def addStudent(student):
112        """Add an IStudent object and subcontainers.
113
114        """
115
116    def archive(id=None):
117        """Create on-dist archive of 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        students types are saved to disk.
126        """
127
128    def clear(id=None, archive=True):
129        """Remove students of type given by 'id'.
130
131        Optionally archive the students.
132
133        If id is `None`, all students are archived.
134
135        If id contains a single id string, only the respective
136        students are archived.
137
138        If id contains a list of id strings all of the respective
139        student types are saved to disk.
140
141        If `archive` is ``False`` none of the archive-handling is done
142        and respective students are simply removed from the
143        database.
144        """
145
146    unique_student_id = Attribute("""A unique student id.""")
147
148class IStudentNavigation(IStudentNavigationBase):
149    """Interface needed for student navigation, logging, etc.
150
151    """
152    student = Attribute('Student object of context.')
153
154    def writeLogMessage(view, message):
155        """Write a view specific log message into students.log.
156
157        """
158
159class IStudentBase(IKofaObject):
160    """Representation of student base data.
161
162    """
163    history = Attribute('Object history, a list of messages')
164    state = Attribute('Returns the registration state of a student')
165    password = Attribute('Encrypted password of a student')
166    temp_password = Attribute(
167        'Dictionary with user name, timestamp and encrypted password')
168    certcode = Attribute('The certificate code of any chosen study course')
169    depcode = Attribute('The department code of any chosen study course')
170    faccode = Attribute('The faculty code of any chosen study course')
171    entry_session = Attribute('The entry session of the student')
172    current_session = Attribute('The current session of the student')
173    current_level = Attribute('The current level of the student')
174    current_mode = Attribute('The current mode of the student')
175    current_verdict = Attribute('The current verdict of the student')
176    fullname = Attribute('All name parts separated by hyphens')
177    display_fullname = Attribute('The fullname of an applicant')
178    is_postgrad = Attribute('True if postgraduate student')
179
180    suspended = schema.Bool(
181        title = _(u'Account suspended'),
182        default = False,
183        required = False,
184        )
185
186    suspended_comment = schema.Text(
187        title = _(u"Reasons for Deactivation"),
188        required = False,
189        description = _(
190            u'This message will be shown if and only if deactivated '
191            'students try to login.'),
192        )
193
194    student_id = schema.TextLine(
195        title = _(u'Student Id'),
196        required = False,
197        )
198
199    firstname = schema.TextLine(
200        title = _(u'First Name'),
201        required = True,
202        )
203
204    middlename = schema.TextLine(
205        title = _(u'Middle Name'),
206        required = False,
207        )
208
209    lastname = schema.TextLine(
210        title = _(u'Last Name (Surname)'),
211        required = True,
212        )
213
214    sex = schema.Choice(
215        title = _(u'Sex'),
216        source = GenderSource(),
217        required = True,
218        )
219
220    reg_number = TextLineChoice(
221        title = _(u'Registration Number'),
222        required = True,
223        readonly = False,
224        source = contextual_reg_num_source,
225        )
226
227    matric_number = TextLineChoice(
228        title = _(u'Matriculation Number'),
229        required = False,
230        readonly = False,
231        source = contextual_mat_num_source,
232        )
233
234    adm_code = schema.TextLine(
235        title = _(u'PWD Activation Code'),
236        required = False,
237        readonly = False,
238        )
239
240    email = schema.ASCIILine(
241        title = _(u'Email'),
242        required = False,
243        constraint=validate_email,
244        )
245    phone = PhoneNumber(
246        title = _(u'Phone'),
247        description = u'',
248        required = False,
249        )
250
251    def setTempPassword(user, password):
252        """Set a temporary password (LDAP-compatible) SSHA encoded for
253        officers.
254
255        """
256
257    def getTempPassword():
258        """Check if a temporary password has been set and if it
259        is not expired.
260
261        Return the temporary password if valid,
262        None otherwise. Unset the temporary password if expired.
263        """
264
265    def transfer(certificate, current_session,
266        current_level, current_verdict):
267        """ Creates a new studycourse and backups the old one.
268
269        """
270
271class IUGStudentClearance(IKofaObject):
272    """Representation of undergraduate student clearance data.
273
274    """
275    officer_comment = schema.Text(
276        title = _(u"Officer's Comment"),
277        required = False,
278        )
279
280    clearance_locked = schema.Bool(
281        title = _(u'Clearance form locked'),
282        default = False,
283        required = False,
284        )
285
286    clr_code = schema.TextLine(
287        title = _(u'CLR Activation Code'),
288        required = False,
289        readonly = False,
290        )
291
292    date_of_birth = FormattedDate(
293        title = _(u'Date of Birth'),
294        required = True,
295        show_year = True,
296        )
297
298    nationality = schema.Choice(
299        vocabulary = nats_vocab,
300        title = _(u'Nationality'),
301        required = False,
302        )
303
304class IPGStudentClearance(IUGStudentClearance):
305    """Representation of postgraduate student clearance data.
306
307    """
308    employer = schema.TextLine(
309        title = _(u'Employer'),
310        required = False,
311        readonly = False,
312        )
313
314class IStudentPersonal(IKofaObject):
315    """Representation of student personal data.
316
317    """
318    personal_updated = schema.Datetime(
319        title = _(u'Updated'),
320        required = False,
321        readonly = False,
322        )
323
324    perm_address = schema.Text(
325        title = _(u'Permanent Address'),
326        required = False,
327        )
328
329class IStudent(IStudentBase,IUGStudentClearance,IPGStudentClearance,
330    IStudentPersonal):
331    """Representation of a student.
332
333    """
334
335class IStudentPersonalEdit(IStudentPersonal):
336    """Interface for editing personal data by students.
337
338    Here we can repeat the fields from IStudentPersonal and set the
339    `required` if necessary.
340    """
341
342    perm_address = schema.Text(
343        title = _(u'Permanent Address'),
344        required = True,
345        )
346
347class IStudentUpdateByRegNo(IStudent):
348    """Representation of a student. Skip regular reg_number validation.
349
350    """
351    reg_number = schema.TextLine(
352        title = _(u'Registration Number'),
353        required = False,
354        )
355
356class IStudentUpdateByMatricNo(IStudent):
357    """Representation of a student. Skip regular matric_number validation.
358
359    """
360    matric_number = schema.TextLine(
361        title = _(u'Matriculation Number'),
362        required = False,
363        )
364
365class IStudentRequestPW(IStudent):
366    """Representation of an student for first-time password request.
367
368    This interface is used when students use the requestpw page to
369    login for the the first time.
370    """
371    number = schema.TextLine(
372        title = _(u'Registr. or Matric. Number'),
373        required = True,
374        )
375
376    firstname = schema.TextLine(
377        title = _(u'First Name'),
378        required = True,
379        )
380
381    email = schema.ASCIILine(
382        title = _(u'Email Address'),
383        required = True,
384        constraint=validate_email,
385        )
386
387class IStudentStudyCourse(IKofaObject):
388    """A container for student study levels.
389
390    """
391    certificate = schema.Choice(
392        title = _(u'Certificate'),
393        source = CertificateSource(),
394        required = False,
395        )
396
397    entry_mode = schema.Choice(
398        title = _(u'Entry Mode'),
399        source = StudyModeSource(),
400        required = True,
401        readonly = False,
402        )
403
404    entry_session = schema.Choice(
405        title = _(u'Entry Session'),
406        source = academic_sessions_vocab,
407        #default = datetime.now().year,
408        required = True,
409        readonly = False,
410        )
411
412    current_session = schema.Choice(
413        title = _(u'Current Session'),
414        source = academic_sessions_vocab,
415        required = True,
416        readonly = False,
417        )
418
419    current_level = schema.Choice(
420        title = _(u'Current Level'),
421        source = StudyLevelSource(),
422        required = False,
423        readonly = False,
424        )
425
426    current_verdict = schema.Choice(
427        title = _(u'Current Verdict'),
428        source = VerdictSource(),
429        default = '0',
430        required = False,
431        )
432
433    previous_verdict = schema.Choice(
434        title = _(u'Previous Verdict'),
435        source = VerdictSource(),
436        default = '0',
437        required = False,
438        )
439
440class IStudentStudyCourseTransfer(IStudentStudyCourse):
441    """An student transfers.
442
443    """
444
445    certificate = schema.Choice(
446        title = _(u'Certificate'),
447        source = CertificateSource(),
448        required = True,
449        )
450
451    current_level = schema.Choice(
452        title = _(u'Current Level'),
453        source = StudyLevelSource(),
454        required = True,
455        readonly = False,
456        )
457
458
459IStudentStudyCourseTransfer['certificate'].order = IStudentStudyCourse[
460    'certificate'].order
461IStudentStudyCourseTransfer['current_level'].order = IStudentStudyCourse[
462    'current_level'].order
463
464class IStudentVerdictUpdate(IKofaObject):
465    """A interface for verdict imports.
466
467    """
468
469    current_verdict = schema.Choice(
470        title = _(u'Current Verdict'),
471        source = VerdictSource(),
472        required = True,
473        )
474
475    current_session = schema.Choice(
476        title = _(u'Current Session'),
477        source = academic_sessions_vocab,
478        required = True,
479        )
480
481    current_level = schema.Choice(
482        title = _(u'Current Level'),
483        source = StudyLevelSource(),
484        required = True,
485        )
486
487    bypass_validation = schema.Bool(
488        title = _(u'Bypass validation'),
489        required = False,
490        )
491
492    validated_by = schema.TextLine(
493        title = _(u'Validated by'),
494        required = False,
495        )
496
497class IStudentStudyLevel(IKofaObject):
498    """A container for course tickets.
499
500    """
501    level = Attribute('The level code')
502    number_of_tickets = Attribute('Number of tickets contained in this level')
503    certcode = Attribute('The certificate code of the study course')
504    is_current_level = Attribute('Is this level the current level of the student?')
505
506    level_session = schema.Choice(
507        title = _(u'Session'),
508        source = academic_sessions_vocab,
509        required = True,
510        )
511
512    level_verdict = schema.Choice(
513        title = _(u'Verdict'),
514        source = VerdictSource(),
515        default = '0',
516        required = False,
517        )
518
519    validated_by = schema.TextLine(
520        title = _(u'Validated by'),
521        default = None,
522        required = False,
523        )
524
525    validation_date = schema.Datetime(
526        title = _(u'Validation Date'),
527        required = False,
528        readonly = False,
529        )
530
531    total_credits = schema.Int(
532        title = _(u'Total Credits'),
533        required = False,
534        readonly = True,
535        )
536
537    gpa = schema.Int(
538        title = _(u'GPA'),
539        required = False,
540        readonly = True,
541        )
542
543    def addCourseTicket(ticket, course):
544        """Add a course ticket object.
545        """
546
547    def addCertCourseTickets(cert):
548        """Collect all certificate courses and create course
549        tickets automatically.
550        """
551
552class ICourseTicket(IKofaObject):
553    """An interface for course tickets.
554
555    """
556    code = Attribute('code of the original course')
557    certcode = Attribute('certificate code of the study course')
558    grade = Attribute('grade calculated from score')
559    weight = Attribute('weight calculated from score')
560    removable_by_student = Attribute('Is student allowed to remove the ticket?')
561    level_session = Attribute('session of the level the ticket has been added to')
562    level = Attribute('id of the level the ticket has been added to')
563
564    title = schema.TextLine(
565        title = _(u'Title'),
566        required = False,
567        )
568
569    fcode = schema.TextLine(
570        title = _(u'Faculty Code'),
571        required = False,
572        )
573
574    dcode = schema.TextLine(
575        title = _(u'Department Code'),
576        required = False,
577        )
578
579    semester = schema.Choice(
580        title = _(u'Semester/Term'),
581        source = SemesterSource(),
582        required = False,
583        )
584
585    passmark = schema.Int(
586        title = _(u'Passmark'),
587        required = False,
588        )
589
590    credits = schema.Int(
591        title = _(u'Credits'),
592        required = False,
593        )
594
595    mandatory = schema.Bool(
596        title = _(u'Required'),
597        default = False,
598        required = False,
599        )
600
601    score = schema.Int(
602        title = _(u'Score'),
603        default = None,
604        required = False,
605        )
606
607    carry_over = schema.Bool(
608        title = _(u'Carry-over Course'),
609        default = False,
610        required = False,
611        )
612
613    automatic = schema.Bool(
614        title = _(u'Automatical Creation'),
615        default = False,
616        required = False,
617        )
618
619
620class ICourseTicketAdd(IKofaObject):
621    """An interface for adding course tickets.
622
623    """
624    course = schema.Choice(
625        title = _(u'Course'),
626        source = CourseSource(),
627        readonly = False,
628        )
629
630class ICourseTicketImport(ICourseTicket):
631    """An interface for importing course results and nothing more.
632
633    """
634    score = schema.Int(
635        title = _(u'Score'),
636        required = False,
637        readonly = False,
638        )
639
640    level_session = schema.Choice(
641        title = _(u'Level Session'),
642        source = academic_sessions_vocab,
643        required = False,
644        readonly = False,
645        )
646
647class IStudentAccommodation(IKofaObject):
648    """A container for student accommodation objects.
649
650    """
651
652    def addBedTicket(bedticket):
653        """Add a bed ticket object.
654        """
655
656
657class IBedTicket(IKofaObject):
658    """A ticket for accommodation booking.
659
660    """
661    bed = Attribute('The bed object.')
662
663    bed_coordinates = schema.TextLine(
664        title = _(u'Allocated Bed'),
665        required = True,
666        readonly = False,
667        )
668
669    bed_type = schema.TextLine(
670        title = _(u'Requested Bed Type'),
671        required = True,
672        readonly = False,
673        )
674
675    booking_session = schema.Choice(
676        title = _(u'Session'),
677        source = academic_sessions_vocab,
678        required = True,
679        readonly = True,
680        )
681
682    booking_date = schema.Datetime(
683        title = _(u'Booking Date'),
684        required = False,
685        readonly = True,
686        )
687
688    booking_code = schema.TextLine(
689        title = _(u'Booking Activation Code'),
690        required = False,
691        readonly = True,
692        )
693
694    def getSessionString():
695        """Returns the title of academic_sessions_vocab term.
696
697        """
698
699class IStudentPaymentsContainer(IPaymentsContainer):
700    """A container for student payment objects.
701
702    """
703
704class IStudentOnlinePayment(IOnlinePayment):
705    """A student payment via payment gateways.
706
707    """
708
709    p_current = schema.Bool(
710        title = _(u'Current Session Payment'),
711        default = True,
712        required = False,
713        )
714
715    p_level = schema.Int(
716        title = _(u'Payment Level'),
717        required = False,
718        )
719
720    def doAfterStudentPayment():
721        """Process student after payment was made.
722
723        """
724
725    def doAfterStudentPaymentApproval():
726        """Process student after payment was approved.
727
728        """
729
730    def approveStudentPayment():
731        """Approve payment and process student.
732
733        """
734
735IStudentOnlinePayment['p_level'].order = IStudentOnlinePayment[
736    'p_session'].order
737
738class IStudentPreviousPayment(IKofaObject):
739    """An interface for adding previous session payments.
740
741    """
742
743    p_category = schema.Choice(
744        title = _(u'Payment Category'),
745        default = u'schoolfee',
746        source = PreviousPaymentCategorySource(),
747        required = True,
748        )
749
750    p_session = schema.Choice(
751        title = _(u'Payment Session'),
752        source = academic_sessions_vocab,
753        required = True,
754        )
755
756    p_level = schema.Choice(
757        title = _(u'Payment Level'),
758        source = StudyLevelSource(),
759        required = True,
760        )
761
762class IStudentBalancePayment(IKofaObject):
763    """An interface for adding balances.
764
765    """
766
767    p_category = schema.Choice(
768        title = _(u'Payment Category'),
769        default = u'schoolfee',
770        required = True,
771        source = BalancePaymentCategorySource(),
772        )
773
774    balance_session = schema.Choice(
775        title = _(u'Payment Session'),
776        source = academic_sessions_vocab,
777        required = True,
778        )
779
780    balance_level = schema.Choice(
781        title = _(u'Payment Level'),
782        source = StudyLevelSource(),
783        required = True,
784        )
785
786    balance_amount = schema.Float(
787        title = _(u'Balance Amount'),
788        default = None,
789        required = True,
790        readonly = False,
791        description = _(
792            u'Balance in Naira '),
793        )
794
795class ICSVStudentExporter(ICSVExporter):
796    """A regular ICSVExporter that additionally supports exporting
797      data from a given student object.
798    """
799    def get_filtered(site, **kw):
800        """Get a filtered set of students.
801        """
802
803    def export_student(student, filepath=None):
804        """Export data for a given student.
805        """
806
807    def export_filtered(site, filepath=None, **kw):
808        """Export filtered set of students.
809        """
Note: See TracBrowser for help on using the repository browser.