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

Last change on this file since 14642 was 14642, checked in by Henrik Bettermann, 8 years ago

Add course_category attribute to course tickets. In the base package,
this attribute is omitted from display and manage pages.

  • Property svn:keywords set to Id
File size: 27.2 KB
Line 
1## $Id: interfaces.py 14642 2017-03-22 10:24:10Z 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,
26    ContextualDictSourceFactoryBase, IKofaUtils)
27from waeup.kofa.interfaces import MessageFactory as _
28from waeup.kofa.schema import TextLineChoice, FormattedDate, PhoneNumber
29from waeup.kofa.students.vocabularies import (
30    StudyLevelSource, contextual_reg_num_source, contextual_mat_num_source,
31    GenderSource, nats_vocab
32    )
33from waeup.kofa.payments.interfaces import (
34    IPaymentsContainer, IOnlinePayment)
35from waeup.kofa.university.vocabularies import (
36    CourseSource, StudyModeSource, CertificateSource,
37    SemesterSource, CourseCategorySource
38    )
39
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
47class BalancePaymentCategorySource(ContextualDictSourceFactoryBase):
48    """A source that delivers all selectable items of balance payments.
49    """
50    #: name of dict to deliver from kofa utils.
51    DICT_NAME = 'BALANCE_PAYMENT_CATEGORIES'
52
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):
60        verdicts_dict = getUtility(IKofaUtils).VERDICTS_DICT
61        return sorted(verdicts_dict.keys())
62
63    def getToken(self, context, value):
64        return value
65
66    def getTitle(self, context, value):
67        verdicts_dict = getUtility(IKofaUtils).VERDICTS_DICT
68        if value != '0':
69            return verdicts_dict[value] + ' (%s)' % value
70        return verdicts_dict[value]
71
72
73class IStudentsUtils(Interface):
74    """A collection of methods which are subject to customization.
75    """
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
84    def setPaymentDetails(category, student, previous_session=None,
85            previous_level=None,):
86        """Create Payment object and set the payment data of a student for
87        the payment category specified.
88        """
89
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.
96        """
97
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
106    def setMatricNumber(student):
107        """Set matriculation number of student.
108
109        If the student's matric number is unset a new matric number is
110        constructed according to the matriculation number construction rules
111        defined in the constructMatricNumber method. The new matric number is
112        set, the students catalog updated. The corresponding matric number
113        counter is increased by one.
114
115        This method is tested but not used in the base package. It can
116        be used in custom packages by adding respective views
117        and by customizing increaseMatricInteger and constructMatricNumber
118        according to the university's matriculation number construction rules.
119
120        The method can be disabled by setting the counter to zero.
121        """
122
123    def getAccommodation_details(student):
124        """Determine the accommodation dates of a student.
125        """
126
127    def selectBed(available_beds):
128        """Select a bed from a list of available beds.
129        In the standard configuration we select the first bed found,
130        but can also randomize the selection if we like.
131        """
132
133    def getPDFCreator(context):
134        """Get some IPDFCreator instance suitable for use with `context`.
135        """
136
137    def renderPDF(view, subject='', filename='slip.pdf',):
138        """Render pdf slips for various pages.
139        """
140
141    def getDegreeClassNumber(level_obj):
142        """Get degree class number (used for SessionResultsPresentation
143        reports).
144        """
145
146    def renderPDFTranscript(view, filename, student,
147                  studentview, note, signatures, sigs_in_footer,
148                  show_scans, topMargin, omit_fields,
149                  tableheader, no_passport):
150        """Render pdf slip of a transcripts.
151        """
152
153    def renderPDFCourseticketsOverview(view, session, data, lecturers):
154        """Render pdf slip of course tickets for a lecturer.
155        """
156
157    def warnCreditsOOR(studylevel, course=None):
158        """Return message if credits are out of range. In the base
159        package only maximum credits is set.
160        """
161
162    def getBedCoordinates(bedticket):
163        """Return descriptive bed coordinates.
164        This method can be used to customize the `display_coordinates`
165        property method in order to  display a
166        customary description of the bed space.
167        """
168
169    def clearance_disabled_message(student):
170        """Render message if clearance is disabled.
171        """
172
173class IStudentsContainer(IKofaObject):
174    """A students container contains university students.
175    """
176    def addStudent(student):
177        """Add an IStudent object and subcontainers.
178        """
179
180    unique_student_id = Attribute('A unique student id')
181
182class IStudentNavigation(IStudentNavigationBase):
183    """Interface needed for navigation and logging. This interface is
184    implemented by all content classes in the students section.
185    """
186    student = Attribute('Student object of context')
187
188    def writeLogMessage(view, message):
189        """Add an INFO message to students.log.
190        """
191
192class IStudentBase(IKofaObject):
193    """Representation of student base data.
194    """
195    history = Attribute('Object history, a list of messages')
196    state = Attribute('Registration state')
197    translated_state = Attribute('Real name of the registration state')
198    certcode = Attribute('Certificate code of any chosen study course')
199    depcode = Attribute('Department code of any chosen study course')
200    faccode = Attribute('Faculty code of any chosen study course')
201    entry_session = Attribute('Entry session')
202    current_session = Attribute('Current session')
203    current_level = Attribute('Current level')
204    current_mode = Attribute('Current mode')
205    current_verdict = Attribute('Current verdict')
206    fullname = Attribute('All name parts separated by hyphens')
207    display_fullname = Attribute('Fullname as displayed on pages')
208    is_postgrad = Attribute('True if postgraduate student')
209    is_special_postgrad = Attribute('True if special postgraduate student')
210    is_fresh = Attribute('True if fresh student')
211    before_payment = Attribute('True if no previous payment has to be made')
212    personal_data_expired = Attribute('True if personal data expired')
213    transcript_enabled = Attribute('True if transcript processing is enabled')
214    clearance_locked = Attribute('True if clearance form is locked')
215
216    password = Attribute('Encrypted password')
217    temp_password = Attribute('Dictionary with user name, timestamp and encrypted password')
218
219    suspended = schema.Bool(
220        title = _(u'Account suspended'),
221        default = False,
222        required = False,
223        )
224
225    suspended_comment = schema.Text(
226        title = _(u"Reasons for Deactivation"),
227        required = False,
228        description = _(
229            u'This message will be shown if and only if deactivated '
230            'students try to login.'),
231        )
232
233    flash_notice = schema.TextLine(
234        title = _(u'Flash Notice'),
235        required = False,
236        readonly = False,
237        description = _(
238            u'This single-line message will be shown in a flash box.'),
239        )
240
241    student_id = schema.TextLine(
242        title = _(u'Student Id'),
243        required = False,
244        )
245
246    firstname = schema.TextLine(
247        title = _(u'First Name'),
248        required = True,
249        )
250
251    middlename = schema.TextLine(
252        title = _(u'Middle Name'),
253        required = False,
254        )
255
256    lastname = schema.TextLine(
257        title = _(u'Last Name (Surname)'),
258        required = True,
259        )
260
261    sex = schema.Choice(
262        title = _(u'Sex'),
263        source = GenderSource(),
264        required = True,
265        )
266
267    reg_number = TextLineChoice(
268        title = _(u'Registration Number'),
269        required = True,
270        readonly = False,
271        source = contextual_reg_num_source,
272        )
273
274    matric_number = TextLineChoice(
275        title = _(u'Matriculation Number'),
276        required = False,
277        readonly = False,
278        source = contextual_mat_num_source,
279        )
280
281    adm_code = schema.TextLine(
282        title = _(u'PWD Activation Code'),
283        required = False,
284        readonly = False,
285        )
286
287    email = schema.ASCIILine(
288        title = _(u'Email'),
289        required = False,
290        constraint=validate_email,
291        )
292    phone = PhoneNumber(
293        title = _(u'Phone'),
294        required = False,
295        )
296
297    def setTempPassword(user, password):
298        """Set a temporary password (LDAP-compatible) SSHA encoded for
299        officers.
300        """
301
302    def getTempPassword():
303        """Check if a temporary password has been set and if it
304        is not expired. Return the temporary password if valid,
305        None otherwise. Unset the temporary password if expired.
306        """
307
308    def transfer(certificate, current_session,
309        current_level, current_verdict):
310        """ Creates a new studycourse and backups the old one.
311        """
312
313    def revert_transfer():
314        """ Revert previous transfer.
315        """
316
317class IUGStudentClearance(IKofaObject):
318    """Representation of undergraduate student clearance data.
319    """
320    officer_comment = schema.Text(
321        title = _(u"Officer's Comment"),
322        required = False,
323        )
324
325    clr_code = schema.TextLine(
326        title = _(u'CLR Activation Code'),
327        required = False,
328        readonly = False,
329        )
330
331    date_of_birth = FormattedDate(
332        title = _(u'Date of Birth'),
333        required = True,
334        show_year = True,
335        )
336
337    nationality = schema.Choice(
338        vocabulary = nats_vocab,
339        title = _(u'Nationality'),
340        required = False,
341        )
342
343class IPGStudentClearance(IUGStudentClearance):
344    """Representation of postgraduate student clearance data.
345    """
346    employer = schema.TextLine(
347        title = _(u'Employer'),
348        required = False,
349        readonly = False,
350        )
351
352class IStudentPersonal(IKofaObject):
353    """Representation of student personal data.
354    """
355    personal_updated = schema.Datetime(
356        title = _(u'Updated'),
357        required = False,
358        readonly = False,
359        )
360
361    perm_address = schema.Text(
362        title = _(u'Permanent Address'),
363        required = False,
364        )
365
366class IStudentTranscript(IKofaObject):
367    """Representation of student transcript data.
368    """
369
370    transcript_comment = schema.Text(
371        title = _(u'Comment'),
372        required = False,
373        )
374
375
376class IStudent(IStudentBase,IUGStudentClearance,IPGStudentClearance,
377    IStudentPersonal, IStudentTranscript):
378    """Representation of a student.
379    """
380
381class IStudentPersonalEdit(IStudentPersonal):
382    """Interface for editing personal data by students.
383    Here we can repeat the fields from IStudentPersonal and set the
384    `required` if necessary.
385    """
386
387    perm_address = schema.Text(
388        title = _(u'Permanent Address'),
389        required = True,
390        )
391
392class IStudentUpdateByRegNo(IStudent):
393    """Representation of a student. Skip regular reg_number validation.
394    """
395    reg_number = schema.TextLine(
396        title = _(u'Registration Number'),
397        required = False,
398        )
399
400class IStudentUpdateByMatricNo(IStudent):
401    """Representation of a student. Skip regular matric_number validation.
402    """
403    matric_number = schema.TextLine(
404        title = _(u'Matriculation Number'),
405        required = False,
406        )
407
408class IStudentRequestPW(IStudent):
409    """Representation of a student for first-time password request.
410    This interface is used when students use the requestpw page to
411    login for the the first time.
412    """
413    number = schema.TextLine(
414        title = _(u'Registr. or Matric. Number'),
415        required = True,
416        )
417
418    firstname = schema.TextLine(
419        title = _(u'First Name'),
420        required = True,
421        )
422
423    email = schema.ASCIILine(
424        title = _(u'Email Address'),
425        required = True,
426        constraint=validate_email,
427        )
428
429class IStudentStudyCourse(IKofaObject):
430    """Representation of student study course data.
431    """
432    next_session_allowed = Attribute('True if the student can proceed to next session')
433    is_postgrad = Attribute('True if student is postgraduate student')
434    is_current = Attribute('True if the study course is the current course of studies')
435    is_previous = Attribute('True if the study course is the previous course of studies')
436
437    certificate = schema.Choice(
438        title = _(u'Certificate'),
439        source = CertificateSource(),
440        required = False,
441        )
442
443    entry_mode = schema.Choice(
444        title = _(u'Entry Mode'),
445        source = StudyModeSource(),
446        required = True,
447        readonly = False,
448        )
449
450    entry_session = schema.Choice(
451        title = _(u'Entry Session'),
452        source = academic_sessions_vocab,
453        #default = datetime.now().year,
454        required = True,
455        readonly = False,
456        )
457
458    current_session = schema.Choice(
459        title = _(u'Current Session'),
460        source = academic_sessions_vocab,
461        required = True,
462        readonly = False,
463        )
464
465    current_level = schema.Choice(
466        title = _(u'Current Level'),
467        source = StudyLevelSource(),
468        required = False,
469        readonly = False,
470        )
471
472    current_verdict = schema.Choice(
473        title = _(u'Current Verdict'),
474        source = VerdictSource(),
475        default = '0',
476        required = False,
477        )
478
479    previous_verdict = schema.Choice(
480        title = _(u'Previous Verdict'),
481        source = VerdictSource(),
482        default = '0',
483        required = False,
484        )
485
486    def addStudentStudyLevel(cert, studylevel):
487        """Add a study level object.
488        """
489
490    def getTranscriptData():
491        """Get a sorted list of dicts with level and course ticket data.
492        This method is used for transcripts.
493        """
494
495class IStudentStudyCourseTransfer(IStudentStudyCourse):
496    """An interface used for student transfers.
497    """
498    certificate = schema.Choice(
499        title = _(u'Certificate'),
500        source = CertificateSource(),
501        required = True,
502        )
503
504    current_level = schema.Choice(
505        title = _(u'Current Level'),
506        source = StudyLevelSource(),
507        required = True,
508        readonly = False,
509        )
510
511    entry_session = schema.Choice(
512        title = _(u'Entry Session'),
513        source = academic_sessions_vocab,
514        #default = datetime.now().year,
515        required = False,
516        readonly = False,
517        )
518
519
520IStudentStudyCourseTransfer['certificate'].order = IStudentStudyCourse[
521    'certificate'].order
522IStudentStudyCourseTransfer['current_level'].order = IStudentStudyCourse[
523    'current_level'].order
524
525class IStudentStudyCourseTranscript(IKofaObject):
526    """An interface for student transcripts.
527    """
528    entry_mode = schema.Choice(
529        title = _(u'Entry Mode'),
530        source = StudyModeSource(),
531        required = True,
532        readonly = False,
533        )
534
535    entry_session = schema.Choice(
536        title = _(u'Entry Session'),
537        source = academic_sessions_vocab,
538        #default = datetime.now().year,
539        required = True,
540        readonly = False,
541        )
542
543class IStudentVerdictUpdate(IKofaObject):
544    """A interface for verdict imports.
545    """
546    current_verdict = schema.Choice(
547        title = _(u'Current Verdict'),
548        source = VerdictSource(),
549        required = True,
550        )
551
552    current_session = schema.Choice(
553        title = _(u'Current Session'),
554        source = academic_sessions_vocab,
555        required = True,
556        )
557
558    current_level = schema.Choice(
559        title = _(u'Current Level'),
560        source = StudyLevelSource(),
561        required = True,
562        )
563
564    bypass_validation = schema.Bool(
565        title = _(u'Bypass validation'),
566        required = False,
567        )
568
569    validated_by = schema.TextLine(
570        title = _(u'Validated by'),
571        required = False,
572        )
573
574class IStudentStudyLevel(IKofaObject):
575    """A representation of student study level data.
576    """
577    certcode = Attribute('The certificate code of the study course')
578    is_current_level = Attribute('True if level is current level of the student')
579    level_title = Attribute('Level title from source')
580    getSessionString = Attribute('Session title from source')
581    number_of_tickets = Attribute('Number of tickets contained in this level')
582    passed_params = Attribute('Information about passed and failed courses')
583    gpa_params_rectified = Attribute('Corrected sessional GPA parameters')
584    gpa_params = Attribute('GPA parameters for this level.')
585    cumulative_params = Attribute(
586        'Cumulative GPA and other cumulative parameters for this level')
587    course_registration_forbidden = Attribute(
588        'Return error message if course registration is forbidden')
589
590    level = schema.Choice(
591        title = _(u'Level'),
592        source = StudyLevelSource(),
593        required = True,
594        readonly = False,
595        )
596
597    level_session = schema.Choice(
598        title = _(u'Session'),
599        source = academic_sessions_vocab,
600        required = True,
601        )
602
603    level_verdict = schema.Choice(
604        title = _(u'Verdict'),
605        source = VerdictSource(),
606        default = '0',
607        required = False,
608        )
609
610    validated_by = schema.TextLine(
611        title = _(u'Validated by'),
612        default = None,
613        required = False,
614        )
615
616    validation_date = schema.Datetime(
617        title = _(u'Validation Date'),
618        required = False,
619        readonly = False,
620        )
621
622    total_credits = schema.Int(
623        title = _(u'Total Credits'),
624        required = False,
625        readonly = True,
626        )
627
628    gpa = schema.TextLine(
629        title = _(u'Unrectified GPA'),
630        required = False,
631        readonly = True,
632        )
633
634    def addCourseTicket(ticket, course):
635        """Add a course ticket object.
636        """
637
638    def addCertCourseTickets(cert):
639        """Collect all certificate courses and create course
640        tickets automatically.
641        """
642
643class ICourseTicket(IKofaObject):
644    """A representation of course ticket data.
645    """
646    certcode = Attribute('Certificate code of the study course')
647    level_session = Attribute('Session of the study level the ticket has been added to')
648    level = Attribute('Level value of the study level the ticket has been added to')
649    total_score = Attribute('Score')
650    grade = Attribute('Grade calculated from total score')
651    weight = Attribute('Weight calculated from total score')
652    removable_by_student = Attribute('True if student is allowed to remove the ticket')
653    editable_by_lecturer = Attribute('True if lecturer is allowed to edit the ticket')
654
655    code = Attribute('Code of the original course')
656
657    title = schema.TextLine(
658        title = _(u'Title'),
659        required = False,
660        )
661
662    fcode = schema.TextLine(
663        title = _(u'Faculty Code'),
664        required = False,
665        )
666
667    dcode = schema.TextLine(
668        title = _(u'Department Code'),
669        required = False,
670        )
671
672    semester = schema.Choice(
673        title = _(u'Semester/Term'),
674        source = SemesterSource(),
675        required = False,
676        )
677
678    passmark = schema.Int(
679        title = _(u'Passmark'),
680        required = False,
681        )
682
683    credits = schema.Int(
684        title = _(u'Credits'),
685        required = False,
686        )
687
688    mandatory = schema.Bool(
689        title = _(u'Required'),
690        default = False,
691        required = False,
692        )
693
694    outstanding = schema.Bool(
695        title = _(u'Outstanding Course'),
696        default = False,
697        required = False,
698        )
699
700    course_category = schema.Choice(
701        title = _(u'Course Category'),
702        source = CourseCategorySource(),
703        required = False,
704        )
705
706    score = schema.Int(
707        title = _(u'Score'),
708        default = None,
709        required = False,
710        missing_value = None,
711        )
712
713    carry_over = schema.Bool(
714        title = _(u'Carry-over Course'),
715        default = False,
716        required = False,
717        )
718
719    automatic = schema.Bool(
720        title = _(u'Automatical Creation'),
721        default = False,
722        required = False,
723        )
724
725class ICourseTicketAdd(IKofaObject):
726    """An interface for adding course tickets.
727    """
728    course = schema.Choice(
729        title = _(u'Course'),
730        source = CourseSource(),
731        readonly = False,
732        )
733
734class ICourseTicketImport(ICourseTicket):
735    """An interface for importing course results and nothing more.
736    """
737    score = schema.Int(
738        title = _(u'Score'),
739        required = False,
740        readonly = False,
741        )
742
743    level_session = schema.Choice(
744        title = _(u'Level Session'),
745        source = academic_sessions_vocab,
746        required = False,
747        readonly = False,
748        )
749
750class IStudentAccommodation(IKofaObject):
751    """A container for student accommodation objects.
752    """
753
754    desired_hostel = schema.TextLine(
755        title = _(u'Desired Hostel'),
756        required = False,
757        )
758
759    def addBedTicket(bedticket):
760        """Add a bed ticket object.
761        """
762
763
764class IBedTicket(IKofaObject):
765    """A representation of accommodation booking data.
766    """
767    bed = Attribute('The bed object')
768    maint_payment_made = Attribute('True if maintenance payment is made')
769
770    display_coordinates = schema.TextLine(
771        title = _(u'Allocated Bed'),
772        required = False,
773        readonly = True,
774        )
775
776    bed_coordinates = schema.TextLine(
777        title = u'',
778        required = True,
779        readonly = False,
780        )
781
782    bed_type = schema.TextLine(
783        title = _(u'Requested Bed Type'),
784        required = True,
785        readonly = False,
786        )
787
788    booking_session = schema.Choice(
789        title = _(u'Session'),
790        source = academic_sessions_vocab,
791        required = True,
792        readonly = False
793        )
794
795    booking_date = schema.Datetime(
796        title = _(u'Booking Date'),
797        required = False,
798        readonly = False,
799        )
800
801    booking_code = schema.TextLine(
802        title = _(u'Booking Activation Code'),
803        required = False,
804        readonly = False,
805        )
806
807    def getSessionString():
808        """Returns the title of academic_sessions_vocab term of the session
809        when the bed was booked.
810        """
811
812class IStudentPaymentsContainer(IPaymentsContainer):
813    """A container for student payment objects.
814    """
815
816    certificate = Attribute('Certificate to determine the correct p_level value')
817
818class IStudentOnlinePayment(IOnlinePayment):
819    """A student payment via payment gateways.
820    """
821
822    certificate = Attribute('Certificate to determine the correct p_level value')
823    student = Attribute('Student')
824
825    p_current = schema.Bool(
826        title = _(u'Current Session Payment'),
827        default = True,
828        required = False,
829        )
830
831    p_level = schema.Choice(
832        title = _(u'Payment Level'),
833        source = StudyLevelSource(),
834        required = False,
835        )
836
837    def redeemTicket():
838        """Either create an appropriate access code or trigger an action
839        directly.
840        """
841
842    def doAfterStudentPayment():
843        """Process student after payment was made.
844        """
845
846    def doAfterStudentPaymentApproval():
847        """Process student after payment was approved.
848        """
849
850    def approveStudentPayment():
851        """Approve payment and process student.
852        """
853
854IStudentOnlinePayment['p_level'].order = IStudentOnlinePayment[
855    'p_session'].order
856
857class IStudentPreviousPayment(IKofaObject):
858    """An interface for adding previous session payments.
859    """
860
861    p_category = schema.Choice(
862        title = _(u'Payment Category'),
863        default = u'schoolfee',
864        source = PreviousPaymentCategorySource(),
865        required = True,
866        )
867
868    p_session = schema.Choice(
869        title = _(u'Payment Session'),
870        source = academic_sessions_vocab,
871        required = True,
872        )
873
874    p_level = schema.Choice(
875        title = _(u'Payment Level'),
876        source = StudyLevelSource(),
877        required = True,
878        )
879
880class IStudentBalancePayment(IKofaObject):
881    """An interface for adding balances.
882    """
883
884    p_category = schema.Choice(
885        title = _(u'Payment Category'),
886        default = u'schoolfee',
887        required = True,
888        source = BalancePaymentCategorySource(),
889        )
890
891    balance_session = schema.Choice(
892        title = _(u'Payment Session'),
893        source = academic_sessions_vocab,
894        required = True,
895        )
896
897    balance_level = schema.Choice(
898        title = _(u'Payment Level'),
899        source = StudyLevelSource(),
900        required = True,
901        )
902
903    balance_amount = schema.Float(
904        title = _(u'Balance Amount'),
905        default = None,
906        required = True,
907        readonly = False,
908        description = _(
909            u'Balance in Naira '),
910        )
911
912class ICSVStudentExporter(ICSVExporter):
913    """A regular ICSVExporter that additionally supports exporting
914      data from a given student object.
915    """
916    def get_filtered(site, **kw):
917        """Get a filtered set of students.
918        """
919
920    def get_selected(site, selected):
921        """Get set of selected students.
922        """
923
924    def export_student(student, filepath=None):
925        """Export data for a given student.
926        """
927
928    def export_filtered(site, filepath=None, **kw):
929        """Export data for filtered set of students.
930        """
931
932    def export_selected(site, filepath=None, **kw):
933        """Export data for selected set of students.
934        """
Note: See TracBrowser for help on using the repository browser.