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

Last change on this file since 15333 was 15333, checked in by Henrik Bettermann, 6 years ago

Add transcript_remark field to study levels. Add page to allow
transcript officers editing the field during transcript processing.

Tests will follow!

  • Property svn:keywords set to Id
File size: 27.4 KB
Line 
1## $Id: interfaces.py 15333 2019-02-17 10:51:02Z 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, invariant, Invalid
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 getDegreeClassNumber(level_obj):
134        """Get degree class number (used for SessionResultsPresentation
135        reports).
136        """
137
138    def getPDFCreator(context):
139        """Get some IPDFCreator instance suitable for use with `context`.
140        """
141
142    def renderPDF(view, subject='', filename='slip.pdf',):
143        """Render pdf slips for various pages.
144        """
145
146    def renderPDFAdmissionLetter(view, student=None, omit_fields=(),
147                                 pre_text=None, post_text=None,):
148        """Render pdf admission letter.
149        """
150
151    def renderPDFTranscript(view, filename, student,
152                  studentview, note, signatures, sigs_in_footer,
153                  show_scans, topMargin, omit_fields,
154                  tableheader, no_passport):
155        """Render pdf slip of a transcripts.
156        """
157
158    def renderPDFCourseticketsOverview(
159                  view, session, data, lecturers, orientation,
160                  title_length, note):
161        """Render pdf slip of course tickets for a lecturer.
162        """
163
164    def warnCreditsOOR(studylevel, course=None):
165        """Return message if credits are out of range. In the base
166        package only maximum credits is set.
167        """
168
169    def getBedCoordinates(bedticket):
170        """Return descriptive bed coordinates.
171        This method can be used to customize the `display_coordinates`
172        property method in order to  display a
173        customary description of the bed space.
174        """
175
176    def clearance_disabled_message(student):
177        """Render message if clearance is disabled.
178        """
179
180class IStudentsContainer(IKofaObject):
181    """A students container contains university students.
182    """
183    def addStudent(student):
184        """Add an IStudent object and subcontainers.
185        """
186
187    unique_student_id = Attribute('A unique student id')
188
189class IStudentNavigation(IStudentNavigationBase):
190    """Interface needed for navigation and logging. This interface is
191    implemented by all content classes in the students section.
192    """
193    student = Attribute('Student object of context')
194
195    def writeLogMessage(view, message):
196        """Add an INFO message to students.log.
197        """
198
199class IStudentBase(IKofaObject):
200    """Representation of student base data.
201    """
202    history = Attribute('Object history, a list of messages')
203    state = Attribute('Registration state')
204    translated_state = Attribute('Real name of the registration state')
205    certcode = Attribute('Certificate code of any chosen study course')
206    depcode = Attribute('Department code of any chosen study course')
207    faccode = Attribute('Faculty code of any chosen study course')
208    entry_session = Attribute('Entry session')
209    current_session = Attribute('Current session')
210    current_level = Attribute('Current level')
211    current_mode = Attribute('Current mode')
212    current_verdict = Attribute('Current verdict')
213    fullname = Attribute('All name parts separated by hyphens')
214    display_fullname = Attribute('Fullname as displayed on pages')
215    is_postgrad = Attribute('True if postgraduate student')
216    is_special_postgrad = Attribute('True if special postgraduate student')
217    is_fresh = Attribute('True if fresh student')
218    before_payment = Attribute('True if no previous payment has to be made')
219    personal_data_expired = Attribute('True if personal data expired')
220    transcript_enabled = Attribute('True if transcript processing is enabled')
221    clearance_locked = Attribute('True if clearance form is locked')
222    studycourse_locked = Attribute(
223        'True if nobody is allowed to change studycourse, studylecel or '
224        'course ticket data, neither through the UI nor via import')
225
226    password = Attribute('Encrypted password')
227    temp_password = Attribute('Dictionary with user name, timestamp and encrypted password')
228
229    suspended = schema.Bool(
230        title = _(u'Account suspended'),
231        default = False,
232        required = False,
233        )
234
235    suspended_comment = schema.Text(
236        title = _(u"Reasons for Deactivation"),
237        required = False,
238        description = _(
239            u'This message will be shown if and only if deactivated '
240            'students try to login.'),
241        )
242
243    flash_notice = schema.TextLine(
244        title = _(u'Flash Notice'),
245        required = False,
246        readonly = False,
247        description = _(
248            u'This single-line message will be shown in a flash box.'),
249        )
250
251    student_id = schema.TextLine(
252        title = _(u'Student Id'),
253        required = False,
254        )
255
256    firstname = schema.TextLine(
257        title = _(u'First Name'),
258        required = True,
259        )
260
261    middlename = schema.TextLine(
262        title = _(u'Middle Name'),
263        required = False,
264        )
265
266    lastname = schema.TextLine(
267        title = _(u'Last Name (Surname)'),
268        required = True,
269        )
270
271    sex = schema.Choice(
272        title = _(u'Sex'),
273        source = GenderSource(),
274        required = True,
275        )
276
277    reg_number = TextLineChoice(
278        title = _(u'Registration Number'),
279        required = True,
280        readonly = False,
281        source = contextual_reg_num_source,
282        )
283
284    matric_number = TextLineChoice(
285        title = _(u'Matriculation Number'),
286        required = False,
287        readonly = False,
288        source = contextual_mat_num_source,
289        )
290
291    adm_code = schema.TextLine(
292        title = _(u'PWD Activation Code'),
293        required = False,
294        readonly = False,
295        )
296
297    email = schema.ASCIILine(
298        title = _(u'Email'),
299        required = False,
300        constraint=validate_email,
301        )
302    phone = PhoneNumber(
303        title = _(u'Phone'),
304        required = False,
305        )
306
307    def setTempPassword(user, password):
308        """Set a temporary password (LDAP-compatible) SSHA encoded for
309        officers.
310        """
311
312    def getTempPassword():
313        """Check if a temporary password has been set and if it
314        is not expired. Return the temporary password if valid,
315        None otherwise. Unset the temporary password if expired.
316        """
317
318    def transfer(certificate, current_session,
319        current_level, current_verdict):
320        """ Creates a new studycourse and backups the old one.
321        """
322
323    def revert_transfer():
324        """ Revert previous transfer.
325        """
326
327class IUGStudentClearance(IKofaObject):
328    """Representation of undergraduate student clearance data.
329    """
330    officer_comment = schema.Text(
331        title = _(u"Officer's Comment"),
332        required = False,
333        )
334
335    clr_code = schema.TextLine(
336        title = _(u'CLR Activation Code'),
337        required = False,
338        readonly = False,
339        )
340
341    date_of_birth = FormattedDate(
342        title = _(u'Date of Birth'),
343        required = True,
344        show_year = True,
345        )
346
347    nationality = schema.Choice(
348        vocabulary = nats_vocab,
349        title = _(u'Nationality'),
350        required = False,
351        )
352
353class IPGStudentClearance(IUGStudentClearance):
354    """Representation of postgraduate student clearance data.
355    """
356    employer = schema.TextLine(
357        title = _(u'Employer'),
358        required = False,
359        readonly = False,
360        )
361
362class IStudentPersonal(IKofaObject):
363    """Representation of student personal data.
364    """
365    personal_updated = schema.Datetime(
366        title = _(u'Updated'),
367        required = False,
368        readonly = False,
369        )
370
371    perm_address = schema.Text(
372        title = _(u'Permanent Address'),
373        required = False,
374        )
375
376class IStudent(IStudentBase,IUGStudentClearance,IPGStudentClearance,
377    IStudentPersonal):
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 IStudentVerdictUpdate(IKofaObject):
526    """A interface for verdict imports.
527    """
528    current_verdict = schema.Choice(
529        title = _(u'Current Verdict'),
530        source = VerdictSource(),
531        required = True,
532        )
533
534    current_session = schema.Choice(
535        title = _(u'Current Session'),
536        source = academic_sessions_vocab,
537        required = True,
538        )
539
540    current_level = schema.Choice(
541        title = _(u'Current Level'),
542        source = StudyLevelSource(),
543        required = True,
544        )
545
546    bypass_validation = schema.Bool(
547        title = _(u'Bypass validation'),
548        required = False,
549        )
550
551    validated_by = schema.TextLine(
552        title = _(u'Validated by'),
553        required = False,
554        )
555
556class IStudentStudyLevel(IKofaObject):
557    """A representation of student study level data.
558    """
559    certcode = Attribute('The certificate code of the study course')
560    is_current_level = Attribute('True if level is current level of the student')
561    level_title = Attribute('Level title from source')
562    getSessionString = Attribute('Session title from source')
563    number_of_tickets = Attribute('Number of tickets contained in this level')
564    passed_params = Attribute('Information about passed and failed courses')
565    gpa_params_rectified = Attribute('Corrected sessional GPA parameters')
566    gpa_params = Attribute('GPA parameters for this level.')
567    cumulative_params = Attribute(
568        'Cumulative GPA and other cumulative parameters for this level')
569    course_registration_forbidden = Attribute(
570        'Return error message if course registration is forbidden')
571
572    level = schema.Choice(
573        title = _(u'Level'),
574        source = StudyLevelSource(),
575        required = True,
576        readonly = False,
577        )
578
579    level_session = schema.Choice(
580        title = _(u'Session'),
581        source = academic_sessions_vocab,
582        required = True,
583        )
584
585    level_verdict = schema.Choice(
586        title = _(u'Verdict'),
587        source = VerdictSource(),
588        default = '0',
589        required = False,
590        )
591
592    validated_by = schema.TextLine(
593        title = _(u'Validated by'),
594        default = None,
595        required = False,
596        )
597
598    validation_date = schema.Datetime(
599        title = _(u'Validation Date'),
600        required = False,
601        readonly = False,
602        )
603
604    total_credits = schema.Int(
605        title = _(u'Total Credits'),
606        required = False,
607        readonly = True,
608        )
609
610    gpa = schema.TextLine(
611        title = _(u'Unrectified GPA'),
612        required = False,
613        readonly = True,
614        )
615
616    transcript_remark = schema.TextLine(
617        title = _(u'Transcript Remark'),
618        required = False,
619        readonly = False,
620        )
621
622    def addCourseTicket(ticket, course):
623        """Add a course ticket object.
624        """
625
626    def addCertCourseTickets(cert):
627        """Collect all certificate courses and create course
628        tickets automatically.
629        """
630
631    def updateCourseTicket(ticket, course):
632        """Updates a course ticket object and return code
633        if ticket has been invalidated.
634        """
635
636class ICourseTicket(IKofaObject):
637    """A representation of course ticket data.
638    """
639    certcode = Attribute('Certificate code of the study course')
640    level_session = Attribute('Session of the study level the ticket has been added to')
641    level = Attribute('Level value of the study level the ticket has been added to')
642    total_score = Attribute('Score')
643    grade = Attribute('Grade calculated from total score')
644    weight = Attribute('Weight calculated from total score')
645    removable_by_student = Attribute('True if student is allowed to remove the ticket')
646    editable_by_lecturer = Attribute('True if lecturer is allowed to edit the ticket')
647
648    code = Attribute('Code of the original course')
649
650    title = schema.TextLine(
651        title = _(u'Title'),
652        required = False,
653        )
654
655    fcode = schema.TextLine(
656        title = _(u'Faculty Code'),
657        required = False,
658        )
659
660    dcode = schema.TextLine(
661        title = _(u'Department Code'),
662        required = False,
663        )
664
665    semester = schema.Choice(
666        title = _(u'Semester/Term'),
667        source = SemesterSource(),
668        required = False,
669        )
670
671    ticket_session = schema.Choice(
672        title = _(u'Imported Session'),
673        source = academic_sessions_vocab,
674        required = False,
675        )
676
677    passmark = schema.Int(
678        title = _(u'Passmark'),
679        required = False,
680        )
681
682    credits = schema.Int(
683        title = _(u'Credits'),
684        required = False,
685        )
686
687    mandatory = schema.Bool(
688        title = _(u'Required'),
689        default = False,
690        required = False,
691        )
692
693    outstanding = schema.Bool(
694        title = _(u'Outstanding Course'),
695        default = False,
696        required = False,
697        )
698
699    course_category = schema.Choice(
700        title = _(u'Course Category'),
701        source = CourseCategorySource(),
702        required = False,
703        )
704
705    score = schema.Int(
706        title = _(u'Score'),
707        default = None,
708        required = False,
709        missing_value = None,
710        )
711
712    carry_over = schema.Bool(
713        title = _(u'Carry-over Course'),
714        default = False,
715        required = False,
716        )
717
718    automatic = schema.Bool(
719        title = _(u'Automatical Creation'),
720        default = False,
721        required = False,
722        )
723
724class ICourseTicketAdd(IKofaObject):
725    """An interface for adding course tickets.
726    """
727    course = schema.Choice(
728        title = _(u'Course'),
729        source = CourseSource(),
730        readonly = False,
731        )
732
733class ICourseTicketImport(ICourseTicket):
734    """An interface for importing course results and nothing more.
735    """
736    score = schema.Int(
737        title = _(u'Score'),
738        required = False,
739        readonly = False,
740        )
741
742    level_session = schema.Choice(
743        title = _(u'Level Session'),
744        source = academic_sessions_vocab,
745        required = False,
746        readonly = False,
747        )
748
749class IStudentAccommodation(IKofaObject):
750    """A container for student accommodation objects.
751    """
752
753    desired_hostel = schema.TextLine(
754        title = _(u'Desired Hostel'),
755        required = False,
756        )
757
758    def addBedTicket(bedticket):
759        """Add a bed ticket object.
760        """
761
762
763class IBedTicket(IKofaObject):
764    """A representation of accommodation booking data.
765    """
766    bed = Attribute('The bed object')
767    maint_payment_made = Attribute('True if maintenance payment is made')
768
769    display_coordinates = schema.TextLine(
770        title = _(u'Allocated Bed'),
771        required = False,
772        readonly = True,
773        )
774
775    bed_coordinates = schema.TextLine(
776        title = u'',
777        required = True,
778        readonly = False,
779        )
780
781    bed_type = schema.TextLine(
782        title = _(u'Requested Bed Type'),
783        required = True,
784        readonly = False,
785        )
786
787    booking_session = schema.Choice(
788        title = _(u'Session'),
789        source = academic_sessions_vocab,
790        required = True,
791        readonly = False
792        )
793
794    booking_date = schema.Datetime(
795        title = _(u'Booking Date'),
796        required = False,
797        readonly = False,
798        )
799
800    booking_code = schema.TextLine(
801        title = _(u'Booking Activation Code'),
802        required = False,
803        readonly = False,
804        )
805
806    def getSessionString():
807        """Returns the title of academic_sessions_vocab term of the session
808        when the bed was booked.
809        """
810
811class IStudentPaymentsContainer(IPaymentsContainer):
812    """A container for student payment objects.
813    """
814
815    certificate = Attribute('Certificate to determine the correct p_level value')
816
817class IStudentOnlinePayment(IOnlinePayment):
818    """A student payment via payment gateways.
819    """
820
821    certificate = Attribute('Certificate to determine the correct p_level value')
822    student = Attribute('Student')
823
824    p_current = schema.Bool(
825        title = _(u'Current Session Payment'),
826        default = True,
827        required = False,
828        )
829
830    p_level = schema.Choice(
831        title = _(u'Payment Level'),
832        source = StudyLevelSource(),
833        required = False,
834        )
835
836    def redeemTicket():
837        """Either create an appropriate access code or trigger an action
838        directly.
839        """
840
841    def doAfterStudentPayment():
842        """Process student after payment was made.
843        """
844
845    def doAfterStudentPaymentApproval():
846        """Process student after payment was approved.
847        """
848
849    def approveStudentPayment():
850        """Approve payment and process student.
851        """
852
853IStudentOnlinePayment['p_level'].order = IStudentOnlinePayment[
854    'p_session'].order
855
856class IStudentPreviousPayment(IKofaObject):
857    """An interface for adding previous session payments.
858    """
859
860    p_category = schema.Choice(
861        title = _(u'Payment Category'),
862        default = u'schoolfee',
863        source = PreviousPaymentCategorySource(),
864        required = True,
865        )
866
867    p_session = schema.Choice(
868        title = _(u'Payment Session'),
869        source = academic_sessions_vocab,
870        required = True,
871        )
872
873    p_level = schema.Choice(
874        title = _(u'Payment Level'),
875        source = StudyLevelSource(),
876        required = True,
877        )
878
879class IStudentBalancePayment(IKofaObject):
880    """An interface for adding balances.
881    """
882
883    p_category = schema.Choice(
884        title = _(u'Payment Category'),
885        default = u'schoolfee',
886        required = True,
887        source = BalancePaymentCategorySource(),
888        )
889
890    balance_session = schema.Choice(
891        title = _(u'Payment Session'),
892        source = academic_sessions_vocab,
893        required = True,
894        )
895
896    balance_level = schema.Choice(
897        title = _(u'Payment Level'),
898        source = StudyLevelSource(),
899        required = True,
900        )
901
902    balance_amount = schema.Float(
903        title = _(u'Balance Amount'),
904        default = None,
905        required = True,
906        readonly = False,
907        description = _(
908            u'Balance in Naira '),
909        )
910
911class ICSVStudentExporter(ICSVExporter):
912    """A regular ICSVExporter that additionally supports exporting
913      data from a given student object.
914    """
915    def get_filtered(site, **kw):
916        """Get a filtered set of students.
917        """
918
919    def get_selected(site, selected):
920        """Get set of selected students.
921        """
922
923    def export_student(student, filepath=None):
924        """Export data for a given student.
925        """
926
927    def export_filtered(site, filepath=None, **kw):
928        """Export data for filtered set of students.
929        """
930
931    def export_selected(site, filepath=None, **kw):
932        """Export data for selected set of students.
933        """
Note: See TracBrowser for help on using the repository browser.