## $Id: interfaces.py 8920 2012-07-05 14:48:51Z henrik $ ## ## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## #from datetime import datetime from zope.component import getUtility from zope.interface import Attribute, Interface from zope import schema from zc.sourcefactory.contextual import BasicContextualSourceFactory from waeup.kofa.interfaces import ( IKofaObject, academic_sessions_vocab, validate_email, ICSVExporter) from waeup.kofa.interfaces import MessageFactory as _ from waeup.kofa.schema import TextLineChoice, FormattedDate, PhoneNumber from waeup.kofa.students.vocabularies import ( StudyLevelSource, contextual_reg_num_source, contextual_mat_num_source, GenderSource, nats_vocab, ) from waeup.kofa.payments.interfaces import ( IPaymentsContainer, IOnlinePayment) from waeup.kofa.university.vocabularies import ( CourseSource, StudyModeSource, CertificateSource) # VerdictSource can't be placed into the vocabularies module because it # requires importing IStudentsUtils which then leads to circular imports. class VerdictSource(BasicContextualSourceFactory): """A verdicts source delivers all verdicts provided in the portal. """ def getValues(self, context): verdicts_dict = getUtility(IStudentsUtils).VERDICTS_DICT return sorted(verdicts_dict.keys()) def getToken(self, context, value): return value def getTitle(self, context, value): verdicts_dict = getUtility(IStudentsUtils).VERDICTS_DICT if value != '0': return verdicts_dict[value] + ' (%s)' % value return verdicts_dict[value] class IStudentsUtils(Interface): """A collection of methods which are subject to customization. """ def setReturningData(student): """ This method defines what happens after school fee payment depending on the student's senate verdict. In the base configuration current level is always increased by 100 no matter which verdict has been assigned. """ def setPaymentDetails(category, student): """Create Payment object and set the payment data of a student for the payment category specified. """ def getAccommodation_details(student): """Determine the accommodation dates of a student. """ def selectBed(available_beds): """Select a bed from a list of available beds. In the standard configuration we select the first bed found, but can also randomize the selection if we like. """ def renderPDF(view, subject='', filename='slip.pdf',): """Render pdf slips for various pages. """ class IStudentsContainer(IKofaObject): """A students container contains university students. """ def addStudent(student): """Add an IStudent object and subcontainers. """ def archive(id=None): """Create on-dist archive of students. If id is `None`, all students are archived. If id contains a single id string, only the respective students are archived. If id contains a list of id strings all of the respective students types are saved to disk. """ def clear(id=None, archive=True): """Remove students of type given by 'id'. Optionally archive the students. If id is `None`, all students are archived. If id contains a single id string, only the respective students are archived. If id contains a list of id strings all of the respective student types are saved to disk. If `archive` is ``False`` none of the archive-handling is done and respective students are simply removed from the database. """ unique_student_id = Attribute("""A unique student id.""") class IStudentNavigation(IKofaObject): """Interface needed for student navigation, logging, etc. """ student = Attribute('Student object of context.') def writeLogMessage(view, message): """Write a view specific log message into students.log. """ class IStudentBase(IKofaObject): """Representation of student base data. """ history = Attribute('Object history, a list of messages') state = Attribute('Returns the registration state of a student') password = Attribute('Encrypted password of a student') certcode = Attribute('The certificate code of any chosen study course') depcode = Attribute('The department code of any chosen study course') faccode = Attribute('The faculty code of any chosen study course') current_session = Attribute('The current session of the student') current_mode = Attribute('The current mode of the student') fullname = Attribute('All name parts separated by hyphens') display_fullname = Attribute('The fullname of an applicant') student_id = schema.TextLine( title = _(u'Student Id'), required = False, ) firstname = schema.TextLine( title = _(u'First Name'), required = True, ) middlename = schema.TextLine( title = _(u'Middle Name'), required = False, ) lastname = schema.TextLine( title = _(u'Last Name (Surname)'), required = True, ) sex = schema.Choice( title = _(u'Sex'), source = GenderSource(), required = True, ) reg_number = TextLineChoice( title = _(u'Registration Number'), required = True, readonly = False, source = contextual_reg_num_source, ) matric_number = TextLineChoice( title = _(u'Matriculation Number'), required = False, readonly = False, source = contextual_mat_num_source, ) adm_code = schema.TextLine( title = _(u'PWD Activation Code'), required = False, readonly = True, ) email = schema.ASCIILine( title = _(u'Email'), required = False, constraint=validate_email, ) phone = PhoneNumber( title = _(u'Phone'), description = u'', required = False, ) class IUGStudentClearance(IKofaObject): """Representation of undergraduate student clearance data. """ date_of_birth = FormattedDate( title = _(u'Date of Birth'), required = True, show_year = True, ) clearance_locked = schema.Bool( title = _(u'Clearance form locked'), default = False, ) clr_code = schema.TextLine( title = _(u'CLR Activation Code'), required = False, readonly = True, ) nationality = schema.Choice( vocabulary = nats_vocab, title = _(u'Nationality'), required = False, ) class IPGStudentClearance(IUGStudentClearance): """Representation of postgraduate student clearance data. """ employer = schema.TextLine( title = _(u'Employer'), required = False, readonly = False, ) class IStudentPersonal(IKofaObject): """Representation of student personal data. """ perm_address = schema.Text( title = _(u'Permanent Address'), required = False, ) class IStudent(IStudentBase,IUGStudentClearance,IPGStudentClearance, IStudentPersonal): """Representation of a student. """ class IStudentUpdateByRegNo(IStudent): """Representation of a student. Skip regular reg_number validation. """ reg_number = schema.TextLine( title = _(u'Registration Number'), required = False, ) class IStudentUpdateByMatricNo(IStudent): """Representation of a student. Skip regular matric_number validation. """ matric_number = schema.TextLine( title = _(u'Matriculation Number'), required = False, ) class IStudentRequestPW(IStudent): """Representation of an student for first-time password request. This interface is used when students use the requestpw page to login for the the first time. """ number = schema.TextLine( title = _(u'Registr. or Matric. Number'), required = True, ) firstname = schema.TextLine( title = _(u'First Name'), required = True, ) email = schema.ASCIILine( title = _(u'Email Address'), required = True, constraint=validate_email, ) class IStudentStudyCourse(IKofaObject): """A container for student study levels. """ certificate = schema.Choice( title = _(u'Certificate'), source = CertificateSource(), required = False, ) entry_mode = schema.Choice( title = _(u'Entry Mode'), source = StudyModeSource(), required = True, readonly = False, ) entry_session = schema.Choice( title = _(u'Entry Session'), source = academic_sessions_vocab, #default = datetime.now().year, required = True, readonly = False, ) current_session = schema.Choice( title = _(u'Current Session'), source = academic_sessions_vocab, required = True, readonly = False, ) current_level = schema.Choice( title = _(u'Current Level'), source = StudyLevelSource(), required = False, readonly = False, ) current_verdict = schema.Choice( title = _(u'Current Verdict'), source = VerdictSource(), default = '0', required = False, ) previous_verdict = schema.Choice( title = _(u'Previous Verdict'), source = VerdictSource(), default = '0', required = False, ) class IStudentVerdictUpdate(IKofaObject): """A interface for verdict imports. """ current_verdict = schema.Choice( title = _(u'Current Verdict'), source = VerdictSource(), required = True, ) current_session = schema.Choice( title = _(u'Current Session'), source = academic_sessions_vocab, required = True, ) current_level = schema.Choice( title = _(u'Current Level'), source = StudyLevelSource(), required = True, ) class IStudentStudyLevel(IKofaObject): """A container for course tickets. """ level = Attribute('The level code') validation_date = Attribute('The date of validation') validated_by = Attribute('User Id of course adviser') level_session = schema.Choice( title = _(u'Session'), source = academic_sessions_vocab, required = True, ) level_verdict = schema.Choice( title = _(u'Verdict'), source = VerdictSource(), default = '0', required = False, ) def addCourseTicket(ticket, course): """Add a course ticket object. """ class ICourseTicket(IKofaObject): """A course ticket. """ code = Attribute('code of the original course') title = Attribute('title of the original course') credits = Attribute('credits of the original course') passmark = Attribute('passmark of the original course') semester = Attribute('semester of the original course') fcode = Attribute('faculty code of the original course') dcode = Attribute('department code of the original course') mandatory = schema.Bool( title = _(u'Mandatory'), default = False, required = False, readonly = False, ) score = schema.Int( title = _(u'Score'), default = 0, required = False, readonly = False, ) automatic = schema.Bool( title = _(u'Automatical Creation'), default = False, required = False, readonly = True, ) carry_over = schema.Bool( title = _(u'Carry-over Course'), default = False, required = False, readonly = False, ) def getLevel(): """Returns the id of the level the ticket has been added to. """ def getLevelSession(): """Returns the session of the level the ticket has been added to. """ class ICourseTicketAdd(ICourseTicket): """An interface for adding course tickets. """ course = schema.Choice( title = _(u'Course'), source = CourseSource(), readonly = False, ) class IStudentAccommodation(IKofaObject): """A container for student accommodation objects. """ class IBedTicket(IKofaObject): """A ticket for accommodation booking. """ bed = Attribute('The bed object.') bed_coordinates = schema.TextLine( title = _(u'Bed Coordinates'), required = False, readonly = False, ) bed_type = schema.TextLine( title = _(u'Bed Type'), required = False, readonly = False, ) booking_session = schema.Choice( title = _(u'Session'), source = academic_sessions_vocab, required = True, readonly = True, ) booking_date = schema.Datetime( title = _(u'Booking Date'), required = False, readonly = True, ) booking_code = schema.TextLine( title = _(u'Booking Activation Code'), required = False, readonly = True, ) def getSessionString(): """Returns the title of academic_sessions_vocab term. """ class IStudentPaymentsContainer(IPaymentsContainer): """A container for student payment objects. """ class IStudentOnlinePayment(IOnlinePayment): """A student payment via payment gateways. """ p_level = schema.Int( title = _(u'Payment Level'), required = False, readonly = True, ) def doAfterStudentPayment(): """Process student after payment was made. """ def doAfterStudentPaymentApproval(): """Process student after payment was approved. """ def approveStudentPayment(): """Approve payment and process student. """ IStudentOnlinePayment['p_level'].order = IStudentOnlinePayment[ 'p_session'].order class ICSVStudentExporter(ICSVExporter): """A regular ICSVExporter that additionally supports exporting data from a given student object. """ def export_student(student, filepath=None): """Export data for a given student. """