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

Last change on this file since 17238 was 16671, checked in by Henrik Bettermann, 3 years ago

Ease customization of portrait upload conditions.

  • Property svn:keywords set to Id
File size: 28.3 KB
RevLine 
[7191]1## $Id: interfaces.py 16671 2021-10-07 11:06:40Z henrik $
[6621]2##
[7191]3## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
[8409]18#from datetime import datetime
[7620]19from zope.component import getUtility
[15203]20from zope.interface import Attribute, Interface, invariant, Invalid
[6621]21from zope import schema
[7620]22from zc.sourcefactory.contextual import BasicContextualSourceFactory
[9217]23from waeup.kofa.browser.interfaces import IStudentNavigationBase
[7811]24from waeup.kofa.interfaces import (
[11450]25    IKofaObject, academic_sessions_vocab, validate_email, ICSVExporter,
[13125]26    ContextualDictSourceFactoryBase, IKofaUtils)
[7811]27from waeup.kofa.interfaces import MessageFactory as _
[8176]28from waeup.kofa.schema import TextLineChoice, FormattedDate, PhoneNumber
[7811]29from waeup.kofa.students.vocabularies import (
[7915]30    StudyLevelSource, contextual_reg_num_source, contextual_mat_num_source,
[9420]31    GenderSource, nats_vocab
[7915]32    )
[8160]33from waeup.kofa.payments.interfaces import (
[8174]34    IPaymentsContainer, IOnlinePayment)
[7915]35from waeup.kofa.university.vocabularies import (
[14642]36    CourseSource, StudyModeSource, CertificateSource,
37    SemesterSource, CourseCategorySource
[11450]38    )
[6621]39
[9864]40class PreviousPaymentCategorySource(ContextualDictSourceFactoryBase):
41    """A source that delivers all selectable categories of previous session
42    payments.
43    """
44    #: name of dict to deliver from kofa utils.
45    DICT_NAME = 'PREVIOUS_PAYMENT_CATEGORIES'
46
[9868]47class BalancePaymentCategorySource(ContextualDictSourceFactoryBase):
[9864]48    """A source that delivers all selectable items of balance payments.
49    """
50    #: name of dict to deliver from kofa utils.
[9868]51    DICT_NAME = 'BALANCE_PAYMENT_CATEGORIES'
[9864]52
[7620]53# VerdictSource can't be placed into the vocabularies module because it
54# requires importing IStudentsUtils which then leads to circular imports.
55class VerdictSource(BasicContextualSourceFactory):
56    """A verdicts source delivers all verdicts provided
57    in the portal.
58    """
59    def getValues(self, context):
[13125]60        verdicts_dict = getUtility(IKofaUtils).VERDICTS_DICT
[8820]61        return sorted(verdicts_dict.keys())
[7620]62
63    def getToken(self, context, value):
64        return value
65
66    def getTitle(self, context, value):
[13125]67        verdicts_dict = getUtility(IKofaUtils).VERDICTS_DICT
[8820]68        if value != '0':
69            return verdicts_dict[value] + ' (%s)' % value
[7688]70        return verdicts_dict[value]
[7620]71
[7681]72
[7150]73class IStudentsUtils(Interface):
74    """A collection of methods which are subject to customization.
75    """
[7841]76    def setReturningData(student):
77        """ This method defines what happens after school fee payment
78        depending on the student's senate verdict.
79
80        In the base configuration current level is always increased
81        by 100 no matter which verdict has been assigned.
82        """
83
[9148]84    def setPaymentDetails(category, student, previous_session=None,
[15664]85            previous_level=None, combi=None):
[8595]86        """Create Payment object and set the payment data of a student for
87        the payment category specified.
[12902]88        """
[7150]89
[12902]90    def increaseMatricInteger(student):
91        """Increase counter for matric numbers.
92
93        This counter can be a centrally stored attribute or an attribute of
94        faculties, departments or certificates. In the base package the counter
95        is as an attribute of the site configuration object.
[7150]96        """
97
[12902]98    def constructMatricNumber(student):
99        """Fetch the matric number counter which fits the student and
100        construct the new matric number of the student.
101
102        In the base package the counter is returned which is as an attribute
103        of the site configuration object.
104        """
105
[16671]106    def allowPortraitChange(student):
107        """Check if student is allowed to change the portrait file.
108        """
109
[11589]110    def setMatricNumber(student):
111        """Set matriculation number of student.
112
113        If the student's matric number is unset a new matric number is
[12902]114        constructed according to the matriculation number construction rules
115        defined in the constructMatricNumber method. The new matric number is
116        set, the students catalog updated. The corresponding matric number
117        counter is increased by one.
[11589]118
119        This method is tested but not used in the base package. It can
120        be used in custom packages by adding respective views
[12902]121        and by customizing increaseMatricInteger and constructMatricNumber
122        according to the university's matriculation number construction rules.
[11589]123
[12902]124        The method can be disabled by setting the counter to zero.
[11589]125        """
126
[7186]127    def getAccommodation_details(student):
[7150]128        """Determine the accommodation dates of a student.
129        """
130
[7186]131    def selectBed(available_beds):
[7150]132        """Select a bed from a list of available beds.
133        In the standard configuration we select the first bed found,
134        but can also randomize the selection if we like.
135        """
136
[14655]137    def getDegreeClassNumber(level_obj):
138        """Get degree class number (used for SessionResultsPresentation
139        reports).
140        """
141
[9949]142    def getPDFCreator(context):
143        """Get some IPDFCreator instance suitable for use with `context`.
144        """
145
[7186]146    def renderPDF(view, subject='', filename='slip.pdf',):
[7150]147        """Render pdf slips for various pages.
148        """
149
[14655]150    def renderPDFAdmissionLetter(view, student=None, omit_fields=(),
[15880]151                                 pre_text=None, post_text=None,
[15889]152                                 topMargin = None,
[15880]153                                 letterhead_path=None):
[14655]154        """Render pdf admission letter.
[14157]155        """
156
[14583]157    def renderPDFTranscript(view, filename, student,
158                  studentview, note, signatures, sigs_in_footer,
159                  show_scans, topMargin, omit_fields,
160                  tableheader, no_passport):
161        """Render pdf slip of a transcripts.
162        """
163
[14702]164    def renderPDFCourseticketsOverview(
[15423]165                  view, name, session, data, lecturers, orientation,
[15246]166                  title_length, note):
[14583]167        """Render pdf slip of course tickets for a lecturer.
168        """
169
[14584]170    def warnCreditsOOR(studylevel, course=None):
171        """Return message if credits are out of range. In the base
172        package only maximum credits is set.
[14583]173        """
174
175    def getBedCoordinates(bedticket):
176        """Return descriptive bed coordinates.
177        This method can be used to customize the `display_coordinates`
178        property method in order to  display a
179        customary description of the bed space.
180        """
181
182    def clearance_disabled_message(student):
183        """Render message if clearance is disabled.
184        """
185
[15998]186    def updateCourseTickets(course):
187        """Udate registered course tickets if course
188        attributes were changed.
189        """
190
[7819]191class IStudentsContainer(IKofaObject):
[7096]192    """A students container contains university students.
[6692]193    """
194    def addStudent(student):
195        """Add an IStudent object and subcontainers.
196        """
197
[13736]198    unique_student_id = Attribute('A unique student id')
[8408]199
[9217]200class IStudentNavigation(IStudentNavigationBase):
[13003]201    """Interface needed for navigation and logging. This interface is
[13076]202    implemented by all content classes in the students section.
[6642]203    """
[13003]204    student = Attribute('Student object of context')
[7150]205
[8735]206    def writeLogMessage(view, message):
[13167]207        """Add an INFO message to students.log.
[8735]208        """
209
[7819]210class IStudentBase(IKofaObject):
[6631]211    """Representation of student base data.
[6621]212    """
[12997]213    history = Attribute('Object history, a list of messages')
214    state = Attribute('Registration state')
[13080]215    translated_state = Attribute('Real name of the registration state')
[12997]216    certcode = Attribute('Certificate code of any chosen study course')
217    depcode = Attribute('Department code of any chosen study course')
218    faccode = Attribute('Faculty code of any chosen study course')
219    entry_session = Attribute('Entry session')
220    current_session = Attribute('Current session')
221    current_level = Attribute('Current level')
222    current_mode = Attribute('Current mode')
223    current_verdict = Attribute('Current verdict')
[7364]224    fullname = Attribute('All name parts separated by hyphens')
[12997]225    display_fullname = Attribute('Fullname as displayed on pages')
[8969]226    is_postgrad = Attribute('True if postgraduate student')
[12997]227    is_special_postgrad = Attribute('True if special postgraduate student')
228    is_fresh = Attribute('True if fresh student')
229    before_payment = Attribute('True if no previous payment has to be made')
230    personal_data_expired = Attribute('True if personal data expired')
231    transcript_enabled = Attribute('True if transcript processing is enabled')
[13103]232    clearance_locked = Attribute('True if clearance form is locked')
[15163]233    studycourse_locked = Attribute(
234        'True if nobody is allowed to change studycourse, studylecel or '
235        'course ticket data, neither through the UI nor via import')
[6637]236
[13003]237    password = Attribute('Encrypted password')
238    temp_password = Attribute('Dictionary with user name, timestamp and encrypted password')
[15606]239    parents_password = Attribute('Dictionary with student_id, timestamp and encrypted password')
[13003]240
[8983]241    suspended = schema.Bool(
242        title = _(u'Account suspended'),
243        default = False,
[9035]244        required = False,
[8983]245        )
246
[9702]247    suspended_comment = schema.Text(
248        title = _(u"Reasons for Deactivation"),
249        required = False,
250        description = _(
251            u'This message will be shown if and only if deactivated '
252            'students try to login.'),
253        )
254
[13711]255    flash_notice = schema.TextLine(
256        title = _(u'Flash Notice'),
257        required = False,
258        readonly = False,
259        description = _(
260            u'This single-line message will be shown in a flash box.'),
261        )
262
[6665]263    student_id = schema.TextLine(
[7723]264        title = _(u'Student Id'),
[6849]265        required = False,
[6665]266        )
267
[7357]268    firstname = schema.TextLine(
[7723]269        title = _(u'First Name'),
[6621]270        required = True,
271        )
272
[7357]273    middlename = schema.TextLine(
[7723]274        title = _(u'Middle Name'),
[7357]275        required = False,
276        )
277
278    lastname = schema.TextLine(
[7723]279        title = _(u'Last Name (Surname)'),
[7357]280        required = True,
281        )
282
[6996]283    sex = schema.Choice(
[15790]284        title = _(u'Gender'),
[6996]285        source = GenderSource(),
286        required = True,
287        )
288
[6788]289    reg_number = TextLineChoice(
[7723]290        title = _(u'Registration Number'),
[6696]291        required = True,
292        readonly = False,
[6788]293        source = contextual_reg_num_source,
[6696]294        )
295
[6788]296    matric_number = TextLineChoice(
[7723]297        title = _(u'Matriculation Number'),
[6750]298        required = False,
299        readonly = False,
[6788]300        source = contextual_mat_num_source,
[6750]301        )
302
[6769]303    adm_code = schema.TextLine(
[7723]304        title = _(u'PWD Activation Code'),
[6769]305        required = False,
[8977]306        readonly = False,
[6769]307        )
308
[7133]309    email = schema.ASCIILine(
[7723]310        title = _(u'Email'),
[13345]311        required = False,
[7133]312        constraint=validate_email,
313        )
[15705]314
[8176]315    phone = PhoneNumber(
[7723]316        title = _(u'Phone'),
[7133]317        required = False,
318        )
319
[15609]320    parents_email = schema.ASCIILine(
321        title = _(u"Parents' Email"),
322        required = False,
323        constraint=validate_email,
324        )
325
[9334]326    def setTempPassword(user, password):
327        """Set a temporary password (LDAP-compatible) SSHA encoded for
328        officers.
329        """
330
331    def getTempPassword():
332        """Check if a temporary password has been set and if it
[12997]333        is not expired. Return the temporary password if valid,
[9334]334        None otherwise. Unset the temporary password if expired.
335        """
336
[15606]337    def setParentsPassword(password):
338        """Set a parents password (LDAP-compatible) SSHA encoded for
339        parents.
340        """
341
342    def getParentsPassword():
343        """Check if a parents password has been set and if it
344        is not expired.
345
346        Return the parents password if valid,
347        None otherwise. Unset the parents password if expired.
348        """
349
[9131]350    def transfer(certificate, current_session,
351        current_level, current_verdict):
352        """ Creates a new studycourse and backups the old one.
[12997]353        """
[9131]354
[12997]355    def revert_transfer():
356        """ Revert previous transfer.
[9131]357        """
358
[7993]359class IUGStudentClearance(IKofaObject):
360    """Representation of undergraduate student clearance data.
[6631]361    """
[9543]362    officer_comment = schema.Text(
363        title = _(u"Officer's Comment"),
364        required = False,
[6631]365        )
366
[6769]367    clr_code = schema.TextLine(
[7723]368        title = _(u'CLR Activation Code'),
[6769]369        required = False,
[8977]370        readonly = False,
[6769]371        )
372
[9543]373    date_of_birth = FormattedDate(
374        title = _(u'Date of Birth'),
375        required = True,
376        show_year = True,
377        )
378
[7523]379    nationality = schema.Choice(
[8069]380        vocabulary = nats_vocab,
[7723]381        title = _(u'Nationality'),
[7983]382        required = False,
[7523]383        )
384
[7993]385class IPGStudentClearance(IUGStudentClearance):
386    """Representation of postgraduate student clearance data.
387    """
388    employer = schema.TextLine(
389        title = _(u'Employer'),
390        required = False,
391        readonly = False,
392        )
393
[7819]394class IStudentPersonal(IKofaObject):
[6631]395    """Representation of student personal data.
396    """
[9543]397    personal_updated = schema.Datetime(
398        title = _(u'Updated'),
399        required = False,
400        readonly = False,
401        )
402
[6651]403    perm_address = schema.Text(
[7723]404        title = _(u'Permanent Address'),
[6631]405        required = False,
406        )
407
[8008]408class IStudent(IStudentBase,IUGStudentClearance,IPGStudentClearance,
[15163]409    IStudentPersonal):
[6631]410    """Representation of a student.
411    """
412
[9563]413class IStudentPersonalEdit(IStudentPersonal):
414    """Interface for editing personal data by students.
415    Here we can repeat the fields from IStudentPersonal and set the
416    `required` if necessary.
417    """
418
419    perm_address = schema.Text(
420        title = _(u'Permanent Address'),
421        required = True,
422        )
423
[6849]424class IStudentUpdateByRegNo(IStudent):
425    """Representation of a student. Skip regular reg_number validation.
426    """
427    reg_number = schema.TextLine(
[7723]428        title = _(u'Registration Number'),
[6849]429        required = False,
430        )
431
432class IStudentUpdateByMatricNo(IStudent):
433    """Representation of a student. Skip regular matric_number validation.
434    """
435    matric_number = schema.TextLine(
[7723]436        title = _(u'Matriculation Number'),
[6849]437        required = False,
438        )
439
[8779]440class IStudentRequestPW(IStudent):
[12999]441    """Representation of a student for first-time password request.
[8779]442    This interface is used when students use the requestpw page to
443    login for the the first time.
444    """
[8854]445    number = schema.TextLine(
446        title = _(u'Registr. or Matric. Number'),
[8779]447        required = True,
448        )
449
450    email = schema.ASCIILine(
451        title = _(u'Email Address'),
452        required = True,
453        constraint=validate_email,
454        )
455
[7819]456class IStudentStudyCourse(IKofaObject):
[12999]457    """Representation of student study course data.
[6633]458    """
[13002]459    next_session_allowed = Attribute('True if the student can proceed to next session')
460    is_postgrad = Attribute('True if student is postgraduate student')
461    is_current = Attribute('True if the study course is the current course of studies')
462    is_previous = Attribute('True if the study course is the previous course of studies')
463
[6648]464    certificate = schema.Choice(
[7723]465        title = _(u'Certificate'),
[6648]466        source = CertificateSource(),
[7209]467        required = False,
[6633]468        )
[6635]469
[6996]470    entry_mode = schema.Choice(
[7723]471        title = _(u'Entry Mode'),
[7681]472        source = StudyModeSource(),
[6996]473        required = True,
474        readonly = False,
475        )
476
477    entry_session = schema.Choice(
[7723]478        title = _(u'Entry Session'),
[6996]479        source = academic_sessions_vocab,
[7425]480        #default = datetime.now().year,
[6996]481        required = True,
482        readonly = False,
483        )
484
[6724]485    current_session = schema.Choice(
[7723]486        title = _(u'Current Session'),
[6744]487        source = academic_sessions_vocab,
[6724]488        required = True,
[6996]489        readonly = False,
[6724]490        )
491
492    current_level = schema.Choice(
[7723]493        title = _(u'Current Level'),
[6725]494        source = StudyLevelSource(),
495        required = False,
[6996]496        readonly = False,
[6724]497        )
498
499    current_verdict = schema.Choice(
[7723]500        title = _(u'Current Verdict'),
[7619]501        source = VerdictSource(),
[8820]502        default = '0',
[6725]503        required = False,
[6724]504        )
505
506    previous_verdict = schema.Choice(
[7723]507        title = _(u'Previous Verdict'),
[7619]508        source = VerdictSource(),
[8820]509        default = '0',
[6725]510        required = False,
[6724]511        )
512
[13002]513    def addStudentStudyLevel(cert, studylevel):
514        """Add a study level object.
515        """
516
517    def getTranscriptData():
518        """Get a sorted list of dicts with level and course ticket data.
519        This method is used for transcripts.
520        """
521
[9138]522class IStudentStudyCourseTransfer(IStudentStudyCourse):
[12999]523    """An interface used for student transfers.
[9138]524    """
525    certificate = schema.Choice(
526        title = _(u'Certificate'),
527        source = CertificateSource(),
528        required = True,
529        )
530
531    current_level = schema.Choice(
532        title = _(u'Current Level'),
533        source = StudyLevelSource(),
534        required = True,
535        readonly = False,
536        )
537
[9960]538    entry_session = schema.Choice(
539        title = _(u'Entry Session'),
540        source = academic_sessions_vocab,
541        #default = datetime.now().year,
542        required = False,
543        readonly = False,
544        )
545
546
[9138]547IStudentStudyCourseTransfer['certificate'].order = IStudentStudyCourse[
548    'certificate'].order
549IStudentStudyCourseTransfer['current_level'].order = IStudentStudyCourse[
550    'current_level'].order
551
[7951]552class IStudentVerdictUpdate(IKofaObject):
553    """A interface for verdict imports.
554    """
555    current_verdict = schema.Choice(
556        title = _(u'Current Verdict'),
557        source = VerdictSource(),
558        required = True,
559        )
560
561    current_session = schema.Choice(
562        title = _(u'Current Session'),
563        source = academic_sessions_vocab,
564        required = True,
565        )
566
567    current_level = schema.Choice(
568        title = _(u'Current Level'),
569        source = StudyLevelSource(),
570        required = True,
571        )
572
[9296]573    bypass_validation = schema.Bool(
574        title = _(u'Bypass validation'),
575        required = False,
576        )
577
578    validated_by = schema.TextLine(
579        title = _(u'Validated by'),
580        required = False,
581        )
582
[7819]583class IStudentStudyLevel(IKofaObject):
[12999]584    """A representation of student study level data.
[6774]585    """
[13002]586    certcode = Attribute('The certificate code of the study course')
587    is_current_level = Attribute('True if level is current level of the student')
588    level_title = Attribute('Level title from source')
589    getSessionString = Attribute('Session title from source')
[9235]590    number_of_tickets = Attribute('Number of tickets contained in this level')
[10553]591    passed_params = Attribute('Information about passed and failed courses')
[13002]592    gpa_params_rectified = Attribute('Corrected sessional GPA parameters')
593    gpa_params = Attribute('GPA parameters for this level.')
[14247]594    cumulative_params = Attribute(
595        'Cumulative GPA and other cumulative parameters for this level')
596    course_registration_forbidden = Attribute(
597        'Return error message if course registration is forbidden')
[6774]598
[12873]599    level = schema.Choice(
600        title = _(u'Level'),
601        source = StudyLevelSource(),
602        required = True,
603        readonly = False,
604        )
605
[6793]606    level_session = schema.Choice(
[7723]607        title = _(u'Session'),
[6793]608        source = academic_sessions_vocab,
[9437]609        required = True,
[6793]610        )
[6781]611
[6793]612    level_verdict = schema.Choice(
[7723]613        title = _(u'Verdict'),
[7619]614        source = VerdictSource(),
[8820]615        default = '0',
[6793]616        required = False,
617        )
618
[9161]619    validated_by = schema.TextLine(
620        title = _(u'Validated by'),
621        default = None,
622        required = False,
623        )
624
625    validation_date = schema.Datetime(
626        title = _(u'Validation Date'),
627        required = False,
628        readonly = False,
629        )
630
[9690]631    total_credits = schema.Int(
632        title = _(u'Total Credits'),
633        required = False,
634        readonly = True,
635        )
636
[14574]637    gpa = schema.TextLine(
[10479]638        title = _(u'Unrectified GPA'),
639        required = False,
640        readonly = True,
641        )
[9690]642
[16120]643    transcript_remark = schema.Text(
[15333]644        title = _(u'Transcript Remark'),
645        required = False,
646        readonly = False,
647        )
648
[8920]649    def addCourseTicket(ticket, course):
[8182]650        """Add a course ticket object.
651        """
652
[9501]653    def addCertCourseTickets(cert):
654        """Collect all certificate courses and create course
655        tickets automatically.
656        """
657
[14684]658    def updateCourseTicket(ticket, course):
659        """Updates a course ticket object and return code
660        if ticket has been invalidated.
661        """
662
[7819]663class ICourseTicket(IKofaObject):
[12999]664    """A representation of course ticket data.
[6781]665    """
[13003]666    certcode = Attribute('Certificate code of the study course')
667    level_session = Attribute('Session of the study level the ticket has been added to')
668    level = Attribute('Level value of the study level the ticket has been added to')
[14133]669    total_score = Attribute('Score')
670    grade = Attribute('Grade calculated from total score')
671    weight = Attribute('Weight calculated from total score')
[13003]672    removable_by_student = Attribute('True if student is allowed to remove the ticket')
673    editable_by_lecturer = Attribute('True if lecturer is allowed to edit the ticket')
[6781]674
[13003]675    code = Attribute('Code of the original course')
676
[9420]677    title = schema.TextLine(
678        title = _(u'Title'),
679        required = False,
680        )
681
682    fcode = schema.TextLine(
683        title = _(u'Faculty Code'),
684        required = False,
685        )
686
687    dcode = schema.TextLine(
688        title = _(u'Department Code'),
689        required = False,
690        )
691
692    semester = schema.Choice(
693        title = _(u'Semester/Term'),
694        source = SemesterSource(),
695        required = False,
696        )
697
[15203]698    ticket_session = schema.Choice(
699        title = _(u'Imported Session'),
700        source = academic_sessions_vocab,
701        required = False,
702        )
703
[9420]704    passmark = schema.Int(
705        title = _(u'Passmark'),
706        required = False,
707        )
708
709    credits = schema.Int(
710        title = _(u'Credits'),
711        required = False,
712        )
713
[7665]714    mandatory = schema.Bool(
[9320]715        title = _(u'Required'),
[6795]716        default = False,
717        required = False,
718        )
719
[14574]720    outstanding = schema.Bool(
721        title = _(u'Outstanding Course'),
722        default = False,
723        required = False,
724        )
725
[14642]726    course_category = schema.Choice(
727        title = _(u'Course Category'),
728        source = CourseCategorySource(),
729        required = False,
730        )
731
[6781]732    score = schema.Int(
[7723]733        title = _(u'Score'),
[9684]734        default = None,
[6781]735        required = False,
[10637]736        missing_value = None,
[6781]737        )
738
[7661]739    carry_over = schema.Bool(
[7723]740        title = _(u'Carry-over Course'),
[7661]741        default = False,
742        required = False,
743        )
744
[9420]745    automatic = schema.Bool(
746        title = _(u'Automatical Creation'),
747        default = False,
[9316]748        required = False,
749        )
750
[9420]751class ICourseTicketAdd(IKofaObject):
[7150]752    """An interface for adding course tickets.
[6795]753    """
754    course = schema.Choice(
[7723]755        title = _(u'Course'),
[6795]756        source = CourseSource(),
757        readonly = False,
758        )
759
[9420]760class ICourseTicketImport(ICourseTicket):
761    """An interface for importing course results and nothing more.
762    """
763    score = schema.Int(
764        title = _(u'Score'),
765        required = False,
766        readonly = False,
767        )
768
769    level_session = schema.Choice(
770        title = _(u'Level Session'),
771        source = academic_sessions_vocab,
772        required = False,
773        readonly = False,
774        )
775
[7819]776class IStudentAccommodation(IKofaObject):
[6635]777    """A container for student accommodation objects.
778    """
779
[13457]780    desired_hostel = schema.TextLine(
781        title = _(u'Desired Hostel'),
782        required = False,
783        )
784
[9423]785    def addBedTicket(bedticket):
786        """Add a bed ticket object.
787        """
788
789
[7819]790class IBedTicket(IKofaObject):
[12999]791    """A representation of accommodation booking data.
[6989]792    """
[13314]793    bed = Attribute('The bed object')
794    maint_payment_made = Attribute('True if maintenance payment is made')
[6996]795
[13012]796    display_coordinates = schema.TextLine(
797        title = _(u'Allocated Bed'),
798        required = False,
799        readonly = True,
800        )
801
[6996]802    bed_coordinates = schema.TextLine(
[9984]803        title = u'',
[9423]804        required = True,
[7014]805        readonly = False,
[6992]806        )
807
[6996]808    bed_type = schema.TextLine(
[9424]809        title = _(u'Requested Bed Type'),
[9423]810        required = True,
[7014]811        readonly = False,
[6996]812        )
813
[6992]814    booking_session = schema.Choice(
[7723]815        title = _(u'Session'),
[6992]816        source = academic_sessions_vocab,
817        required = True,
[13316]818        readonly = False
[6992]819        )
820
[8170]821    booking_date = schema.Datetime(
[7723]822        title = _(u'Booking Date'),
[6992]823        required = False,
[13316]824        readonly = False,
[6992]825        )
826
827    booking_code = schema.TextLine(
[7723]828        title = _(u'Booking Activation Code'),
[6992]829        required = False,
[13316]830        readonly = False,
[6992]831        )
832
[6994]833    def getSessionString():
[13012]834        """Returns the title of academic_sessions_vocab term of the session
835        when the bed was booked.
[6994]836        """
[6992]837
[6860]838class IStudentPaymentsContainer(IPaymentsContainer):
[6635]839    """A container for student payment objects.
840    """
841
[13736]842    certificate = Attribute('Certificate to determine the correct p_level value')
843
[6877]844class IStudentOnlinePayment(IOnlinePayment):
845    """A student payment via payment gateways.
846    """
847
[13736]848    certificate = Attribute('Certificate to determine the correct p_level value')
[13871]849    student = Attribute('Student')
[13736]850
[9148]851    p_current = schema.Bool(
852        title = _(u'Current Session Payment'),
853        default = True,
854        required = False,
855        )
856
[13733]857    p_level = schema.Choice(
[8268]858        title = _(u'Payment Level'),
[13733]859        source = StudyLevelSource(),
[8268]860        required = False,
861        )
[6877]862
[13871]863    def redeemTicket():
864        """Either create an appropriate access code or trigger an action
865        directly.
866        """
867
[8422]868    def doAfterStudentPayment():
869        """Process student after payment was made.
870        """
871
[8453]872    def doAfterStudentPaymentApproval():
873        """Process student after payment was approved.
874        """
875
[8420]876    def approveStudentPayment():
[8422]877        """Approve payment and process student.
[8420]878        """
879
[8268]880IStudentOnlinePayment['p_level'].order = IStudentOnlinePayment[
881    'p_session'].order
[8408]882
[9864]883class IStudentPreviousPayment(IKofaObject):
[9148]884    """An interface for adding previous session payments.
885    """
886
[9864]887    p_category = schema.Choice(
888        title = _(u'Payment Category'),
889        default = u'schoolfee',
890        source = PreviousPaymentCategorySource(),
891        required = True,
892        )
893
[9148]894    p_session = schema.Choice(
895        title = _(u'Payment Session'),
896        source = academic_sessions_vocab,
897        required = True,
898        )
899
900    p_level = schema.Choice(
901        title = _(u'Payment Level'),
902        source = StudyLevelSource(),
903        required = True,
904        )
905
[9864]906class IStudentBalancePayment(IKofaObject):
907    """An interface for adding balances.
908    """
909
[9868]910    p_category = schema.Choice(
[9864]911        title = _(u'Payment Category'),
912        default = u'schoolfee',
913        required = True,
[9868]914        source = BalancePaymentCategorySource(),
[9864]915        )
916
917    balance_session = schema.Choice(
918        title = _(u'Payment Session'),
919        source = academic_sessions_vocab,
920        required = True,
921        )
922
923    balance_level = schema.Choice(
924        title = _(u'Payment Level'),
925        source = StudyLevelSource(),
926        required = True,
927        )
928
929    balance_amount = schema.Float(
930        title = _(u'Balance Amount'),
[9874]931        default = None,
[9864]932        required = True,
933        readonly = False,
934        description = _(
935            u'Balance in Naira '),
936        )
937
[8408]938class ICSVStudentExporter(ICSVExporter):
939    """A regular ICSVExporter that additionally supports exporting
940      data from a given student object.
941    """
[9801]942    def get_filtered(site, **kw):
[9797]943        """Get a filtered set of students.
944        """
[8408]945
[12518]946    def get_selected(site, selected):
947        """Get set of selected students.
948        """
949
[8408]950    def export_student(student, filepath=None):
951        """Export data for a given student.
952        """
[9734]953
[9797]954    def export_filtered(site, filepath=None, **kw):
[12518]955        """Export data for filtered set of students.
[9734]956        """
[12518]957
958    def export_selected(site, filepath=None, **kw):
959        """Export data for selected set of students.
960        """
Note: See TracBrowser for help on using the repository browser.