source: main/waeup.kofa/branches/henrik-transcript-workflow/src/waeup/kofa/students/interfaces.py @ 15127

Last change on this file since 15127 was 14702, checked in by Henrik Bettermann, 7 years ago

Make pdf page orientation customizable.

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