Ignore:
Timestamp:
20 Nov 2011, 07:35:35 (13 years ago)
Author:
Henrik Bettermann
Message:

Turn all functions subject to customization into methods of a global utility component called StudentsUtils?. This is really an incredible improvement and eases customization a lot.

Location:
main/waeup.sirp/trunk/src/waeup/sirp/students
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • main/waeup.sirp/trunk/src/waeup/sirp/students/browser.py

    r7147 r7150  
    4545    IStudentAccommodation, IStudentClearanceEdit, IStudentStudyLevel,
    4646    ICourseTicket, ICourseTicketAdd, IStudentPaymentsContainer,
    47     IStudentOnlinePayment, IBedTicket
     47    IStudentOnlinePayment, IBedTicket, IStudentsUtils
    4848    )
    4949from waeup.sirp.students.catalog import search
     
    5252from waeup.sirp.students.studylevel import StudentStudyLevel, CourseTicket
    5353from waeup.sirp.students.vocabularies import StudyLevelSource
    54 from waeup.sirp.students.utils import (
    55     get_payment_details, get_accommodation_details, select_bed,
    56     render_pdf)
    5754from waeup.sirp.browser.resources import toggleall
    5855from waeup.sirp.authentication import get_principal_role_manager
     
    667664        studentview = StudentBaseDisplayFormPage(self.context.getStudent(),
    668665            self.request)
    669         return render_pdf(self,'Course Registration', 'course_registration.pdf',
     666        students_utils = getUtility(IStudentsUtils)
     667        return students_utils.render_pdf(
     668            self,'Course Registration', 'course_registration.pdf',
    670669            self.context.getStudent, studentview)
    671670
     
    939938    pnav = 4
    940939   
    941     # To be sepezified in customization packages
    942     def get_payment_details(self, category, student):
    943         return get_payment_details(category, student)
    944 
    945940    @grok.action('Create ticket')
    946941    def createTicket(self, **data):
     
    954949                self.redirect(self.url(self.context))
    955950                return
    956         pay_details  = self.get_payment_details(
     951        students_utils = getUtility(IStudentsUtils)
     952        pay_details  = students_utils.get_payment_details(
    957953            p_category,student)
    958954        if pay_details['error']:
     
    11081104        studentview = StudentBaseDisplayFormPage(self.context.getStudent(),
    11091105            self.request)
    1110         return render_pdf(self,'Payment', 'payment_receipt.pdf',
     1106        students_utils = getUtility(IStudentsUtils)
     1107        return students_utils.render_pdf(self,'Payment', 'payment_receipt.pdf',
    11111108            self.context.getStudent, studentview)
    11121109
     
    12171214    notice = ''
    12181215
    1219     # To be sepezified in customization packages
    1220     def get_accommodation_details(self, student):
    1221         return get_accommodation_details(student)
    1222 
    1223     # To be sepezified in customization packages
    1224     def select_bed(self, available_beds):
    1225         return select_bed(available_beds)
    1226 
    12271216    def update(self, SUBMIT=None):
    12281217        student = self.context.getStudent()
    1229         acc_details  = self.get_accommodation_details(student)
     1218        students_utils = getUtility(IStudentsUtils)
     1219        acc_details  = students_utils.get_accommodation_details(student)
    12301220        if not student.state in acc_details['allowed_states']:
    12311221            self.flash("You are in the wrong registration state.")
     
    12641254                entry for entry in entries if entry.owner == NOT_OCCUPIED]
    12651255            if available_beds:
    1266                 bed = self.select_bed(available_beds)
     1256                students_utils = getUtility(IStudentsUtils)
     1257                bed = students_utils.select_bed(available_beds)
    12671258                bed.bookBed(student.student_id)
    12681259            else:
     
    13451336        studentview = StudentBaseDisplayFormPage(self.context.getStudent(),
    13461337            self.request)
    1347         return render_pdf(self,'Bed Allocation', 'bed_allocation.pdf',
     1338        students_utils = getUtility(IStudentsUtils)
     1339        return students_utils.render_pdf(
     1340            self,'Bed Allocation', 'bed_allocation.pdf',
    13481341            self.context.getStudent, studentview)
    13491342
     
    13641357    grok.require('waeup.manageHostels')
    13651358
    1366     # To be sepezified in customization packages
    1367     def get_accommodation_details(self, student):
    1368         return get_accommodation_details(student)
    1369 
    1370     # To be sepezified in customization packages
    1371     def select_bed(self, available_beds):
    1372         return select_bed(available_beds)
    1373 
    13741359    # Relocate student if student parameters have changed or the bed_type
    13751360    # of the bed has changed
    13761361    def update(self):
    13771362        student = self.context.getStudent()
    1378         acc_details  = self.get_accommodation_details(student)
     1363        students_utils = getUtility(IStudentsUtils)
     1364        acc_details  = students_utils.get_accommodation_details(student)
    13791365        if self.context.bed != None and \
    13801366              'reserved' in self.context.bed.bed_type:
     
    14031389                entry for entry in entries if entry.owner == NOT_OCCUPIED]
    14041390            if available_beds:
    1405                 new_bed = self.select_bed(available_beds)
     1391                students_utils = getUtility(IStudentsUtils)
     1392                new_bed = students_utils.select_bed(available_beds)
    14061393                new_bed.bookBed(student.student_id)
    14071394            else:
  • main/waeup.sirp/trunk/src/waeup/sirp/students/interfaces.py

    r7144 r7150  
    33import re
    44from datetime import datetime
    5 from zope.interface import Attribute, invariant
     5from zope.interface import Attribute, invariant, Interface
    66from zope.interface.exceptions import Invalid
    77from zope import schema
     
    2626    return True
    2727
     28class IStudentsUtils(Interface):
     29    """A collection of methods which are subject to customization.
     30
     31    """
     32    def get_payment_details(category, student):
     33        """Get the payment dates of a student for the payment category
     34        specified.
     35
     36        """
     37
     38    def get_accommodation_details(student):
     39        """Determine the accommodation dates of a student.
     40
     41        """
     42
     43    def select_bed(available_beds):
     44        """Select a bed from a list of available beds.
     45
     46        In the standard configuration we select the first bed found,
     47        but can also randomize the selection if we like.
     48        """
     49
     50    def render_pdf(view, subject='', filename='slip.pdf',):
     51        """Render pdf slips for various pages.
     52
     53        """
     54
    2855class IStudentsContainer(IWAeUPObject):
    2956    """A students container contains university students.
    3057
    3158    """
    32 
    3359    def addStudent(student):
    3460        """Add an IStudent object and subcontainers.
     
    6894class IStudentNavigation(IWAeUPObject):
    6995    """Interface needed for student navigation.
    70     """
    71 
     96
     97    """
    7298    def getStudent():
    7399        """Return student object.
     100
    74101        """
    75102
    76103class IStudentBase(IWAeUPObject):
    77104    """Representation of student base data.
     105
    78106    """
    79107    history = Attribute('Object history, a list of messages')
     
    84112
    85113    def loggerInfo(ob_class, comment):
    86         """Adds an INFO message to the log file
     114        """Adds an INFO message to the log file.
     115
    87116        """
    88117
     
    141170class IStudentClearance(IWAeUPObject):
    142171    """Representation of student clearance data.
    143     """
    144 
     172
     173    """
    145174    date_of_birth = schema.Date(
    146175        title = u'Date of Birth',
     
    162191class IStudentPersonal(IWAeUPObject):
    163192    """Representation of student personal data.
    164     """
    165 
     193
     194    """
    166195    perm_address = schema.Text(
    167196        title = u'Permanent Address',
     
    171200class IStudent(IStudentBase,IStudentClearance,IStudentPersonal):
    172201    """Representation of a student.
     202
    173203    """
    174204
    175205class IStudentUpdateByRegNo(IStudent):
    176206    """Representation of a student. Skip regular reg_number validation.
    177     """
    178 
     207
     208    """
    179209    reg_number = schema.TextLine(
    180210        title = u'Registration Number',
     
    185215class IStudentUpdateByMatricNo(IStudent):
    186216    """Representation of a student. Skip regular matric_number validation.
    187     """
    188 
     217
     218    """
    189219    matric_number = schema.TextLine(
    190220        title = u'Matriculation Number',
     
    197227
    198228    """
    199 
    200229    certificate = schema.Choice(
    201230        title = u'Certificate',
     
    256285
    257286    """
    258 
    259287    current_level = schema.Int(
    260288        title = u'Current Level',
     
    318346
    319347class ICourseTicketAdd(ICourseTicket):
    320     """An interface for adding course tickets
     348    """An interface for adding course tickets.
    321349
    322350    """
     
    336364
    337365    """
    338 
    339366    bed = Attribute('The bed object.')
    340367
     
    375402
    376403    def getSessionString():
    377         """Returns the the title of academic_sessions_vocab term
     404        """Returns the the title of academic_sessions_vocab term.
     405
    378406        """
    379407
     
    387415
    388416    """
    389 
    390417    p_session = schema.Choice(
    391418        title = u'Payment Session',
     
    401428class IStudentClearanceEdit(IStudentClearance):
    402429    """Interface needed for restricted editing of student clearance data.
     430
    403431    """
    404432
    405433class IStudentPersonalEdit(IStudentPersonal):
    406434    """Interface needed for restricted editing of student personal data.
    407     """
     435
     436    """
  • main/waeup.sirp/trunk/src/waeup/sirp/students/utils.py

    r7147 r7150  
    11"""General helper functions for the student section.
    22"""
    3 from grok import getSite
     3import grok
    44from random import SystemRandom as r
    55from datetime import date, datetime
     
    1313from zope.formlib.form import setUpEditWidgets
    1414from waeup.sirp.interfaces import academic_sessions_vocab
     15from waeup.sirp.students.interfaces import IStudentsUtils
    1516
    1617SLIP_STYLE = TableStyle(
     
    3334    student['studycourse'].previous_verdict = verdict
    3435    return
    35 
    36 # To be specified in customization packages, see also the view which
    37 # calls the function.
    38 def get_payment_details(category, student):
    39     d = {}
    40     d['p_item'] = u''
    41     d['amount'] = 0
    42     d['error'] = u''
    43     d['p_session'] = student['studycourse'].current_session
    44     session = str(d['p_session'])
    45     try:
    46         academic_session = getSite()['configuration'][session]
    47     except KeyError:
    48         d['error'] = u'Session configuration object is not available.'
    49         return d
    50     d['surcharge_1'] = academic_session.surcharge_1
    51     d['surcharge_2'] = academic_session.surcharge_2
    52     d['surcharge_3'] = academic_session.surcharge_3
    53     if category == 'schoolfee':
    54         d['amount'] = academic_session.school_fee_base
    55         d['p_item'] = student['studycourse'].certificate.code
    56     elif category == 'clearance':
    57         d['p_item'] = student['studycourse'].certificate.code
    58         d['amount'] = academic_session.clearance_fee
    59     elif category == 'bed_allocation':
    60         d['p_item'] = get_accommodation_details(student)['bt']
    61         d['amount'] = academic_session.booking_fee
    62     return d
    63 
    64 # To be specified in customization packages, see also the view which
    65 # calls the function.
    66 def get_accommodation_details(student):
    67     d = {}
    68     d['error'] = u''
    69     site_confoguration = getSite()['configuration']
    70     d['booking_session'] = site_confoguration.accommodation_session
    71     d['allowed_states'] = site_confoguration.accommodation_states
    72     session = str(d['booking_session'])
    73     # Determine bed type
    74     studycourse = student['studycourse']
    75     entry_session = studycourse.entry_session
    76     current_level = studycourse.current_level
    77     end_level = studycourse.certificate.end_level
    78     if entry_session == getSite()['configuration'].accommodation_session:
    79         bt = 'fr'
    80     elif current_level >= end_level:
    81         bt = 'fi'
    82     else:
    83         bt = 're'
    84     if student.sex == 'f':
    85         sex = 'female'
    86     else:
    87         sex = 'male'
    88     special_handling = 'regular'
    89     d['bt'] = u'%s_%s_%s' % (special_handling,sex,bt)
    90     return d
    91 
    92 # To be specified in customization packages, see also view which
    93 # calls the function.
    94 # I the standard configuration we select the first bed found,
    95 # but can also randomize the selection if we like.
    96 def select_bed(available_beds):
    97     return available_beds[0]
    9836
    9937def setUpWidgets(view, ignore_request=False):
     
    12058    return table
    12159
    122 # To be specified in customization packages, see also view which
    123 # calls the function.
    124 def render_pdf(view, subject='', filename='slip.pdf', student=None, studentview=None):
    125     # (0,0),(-1,-1) = whole table
    126     # (0,0),(0,-1) = first column
    127     # (-1,0),(-1,-1) = last column
    128     # (0,0),(-1,0) = first row
    129     # (0,-1),(-1,-1) = last row
     60class StudentsUtils(grok.GlobalUtility):
     61    """A collection of methods subject to customization.
     62    """
     63    grok.implements(IStudentsUtils)
    13064
    131     pdf = canvas.Canvas(filename,pagesize=A4)
    132     pdf.setTitle(view.label)
    133     pdf.setSubject(subject)
    134     pdf.setAuthor('%s (%s)' % (view.request.principal.title,
    135         view.request.principal.id))
    136     pdf.setCreator('WAeUP SIRP')
    137     width, height = A4
    138     style = getSampleStyleSheet()
    139     pdf.line(1*cm,height-(1.8*cm),width-(1*cm),height-(1.8*cm))
     65    def get_payment_details(self,category, student):
     66        d = {}
     67        d['p_item'] = u''
     68        d['amount'] = 0
     69        d['error'] = u''
     70        d['p_session'] = student['studycourse'].current_session
     71        session = str(d['p_session'])
     72        try:
     73            academic_session = grok.getSite()['configuration'][session]
     74        except KeyError:
     75            d['error'] = u'Session configuration object is not available.'
     76            return d
     77        d['surcharge_1'] = academic_session.surcharge_1
     78        d['surcharge_2'] = academic_session.surcharge_2
     79        d['surcharge_3'] = academic_session.surcharge_3
     80        if category == 'schoolfee':
     81            d['amount'] = academic_session.school_fee_base
     82            d['p_item'] = student['studycourse'].certificate.code
     83        elif category == 'clearance':
     84            d['p_item'] = student['studycourse'].certificate.code
     85            d['amount'] = academic_session.clearance_fee
     86        elif category == 'bed_allocation':
     87            d['p_item'] = self.get_accommodation_details(student)['bt']
     88            d['amount'] = academic_session.booking_fee
     89        return d
    14090
    141     story = []
    142     frame_header = Frame(1*cm,1*cm,width-(1.7*cm),height-(1.7*cm))
    143     header_title = getattr(getSite(), 'name', u'Sample University')
    144     story.append(Paragraph(header_title, style["Heading1"]))
    145     frame_header.addFromList(story,pdf)
     91    def get_accommodation_details(self, student):
     92        d = {}
     93        d['error'] = u''
     94        site_confoguration = grok.getSite()['configuration']
     95        d['booking_session'] = site_confoguration.accommodation_session
     96        d['allowed_states'] = site_confoguration.accommodation_states
     97        session = str(d['booking_session'])
     98        # Determine bed type
     99        studycourse = student['studycourse']
     100        entry_session = studycourse.entry_session
     101        current_level = studycourse.current_level
     102        end_level = studycourse.certificate.end_level
     103        if entry_session == grok.getSite()['configuration'].accommodation_session:
     104            bt = 'fr'
     105        elif current_level >= end_level:
     106            bt = 'fi'
     107        else:
     108            bt = 're'
     109        if student.sex == 'f':
     110            sex = 'female'
     111        else:
     112            sex = 'male'
     113        special_handling = 'regular'
     114        d['bt'] = u'%s_%s_%s' % (special_handling,sex,bt)
     115        return d
    146116
    147     story = []
    148     frame_body = Frame(1*cm,1*cm,width-(2*cm),height-(3.5*cm))
    149     story.append(Paragraph(view.label, style["Heading2"]))
    150     #story.append(HRFlowable())
    151     if student:
     117    # In the standard configuration we select the first bed found,
     118    # but can also randomize the selection if we like.
     119    def select_bed(self, available_beds):
     120        return available_beds[0]
     121
     122    def render_pdf(self, view, subject='', filename='slip.pdf',
     123        student=None, studentview=None):
     124        # (0,0),(-1,-1) = whole table
     125        # (0,0),(0,-1) = first column
     126        # (-1,0),(-1,-1) = last column
     127        # (0,0),(-1,0) = first row
     128        # (0,-1),(-1,-1) = last row
     129
     130        pdf = canvas.Canvas(filename,pagesize=A4)
     131        pdf.setTitle(view.label)
     132        pdf.setSubject(subject)
     133        pdf.setAuthor('%s (%s)' % (view.request.principal.title,
     134            view.request.principal.id))
     135        pdf.setCreator('WAeUP SIRP')
     136        width, height = A4
     137        style = getSampleStyleSheet()
     138        pdf.line(1*cm,height-(1.8*cm),width-(1*cm),height-(1.8*cm))
     139
     140        story = []
     141        frame_header = Frame(1*cm,1*cm,width-(1.7*cm),height-(1.7*cm))
     142        header_title = getattr(grok.getSite(), 'name', u'Sample University')
     143        story.append(Paragraph(header_title, style["Heading1"]))
     144        frame_header.addFromList(story,pdf)
     145
     146        story = []
     147        frame_body = Frame(1*cm,1*cm,width-(2*cm),height-(3.5*cm))
     148        story.append(Paragraph(view.label, style["Heading2"]))
     149        #story.append(HRFlowable())
     150        if student:
     151            story.append(Spacer(1, 18))
     152            studenttable = render_student_data(student, studentview)
     153            story.append(studenttable)
    152154        story.append(Spacer(1, 18))
    153         studenttable = render_student_data(student, studentview)
    154         story.append(studenttable)
    155     story.append(Spacer(1, 18))
    156     setUpWidgets(view)
    157     data = []
    158     for widget in view.widgets:
    159         f_label = '<font size=12>%s</font>:' % widget.label.strip()
    160         f_label = Paragraph(f_label, style["Normal"])
    161         f_text = '<font size=12>%s</font>' % widget()
    162         f_text = Paragraph(f_text, style["Normal"])
    163         data.append([f_label,f_text])
    164     table = Table(data,style=SLIP_STYLE)
    165     story.append(table)
    166     frame_body.addFromList(story,pdf)
     155        setUpWidgets(view)
     156        data = []
     157        for widget in view.widgets:
     158            f_label = '<font size=12>%s</font>:' % widget.label.strip()
     159            f_label = Paragraph(f_label, style["Normal"])
     160            f_text = '<font size=12>%s</font>' % widget()
     161            f_text = Paragraph(f_text, style["Normal"])
     162            data.append([f_label,f_text])
     163        table = Table(data,style=SLIP_STYLE)
     164        story.append(table)
     165        frame_body.addFromList(story,pdf)
    167166
    168     story = []
    169     frame_footer = Frame(1*cm,0,width-(2*cm),1*cm)
    170     timestamp = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
    171     f_text = '<font size=10>%s</font>' % timestamp
    172     story.append(Paragraph(f_text, style["Normal"]))
    173     frame_footer.addFromList(story,pdf)
     167        story = []
     168        frame_footer = Frame(1*cm,0,width-(2*cm),1*cm)
     169        timestamp = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
     170        f_text = '<font size=10>%s</font>' % timestamp
     171        story.append(Paragraph(f_text, style["Normal"]))
     172        frame_footer.addFromList(story,pdf)
    174173
    175     view.response.setHeader(
    176         'Content-Type', 'application/pdf')
    177     return pdf.getpdfdata()
     174        view.response.setHeader(
     175            'Content-Type', 'application/pdf')
     176        return pdf.getpdfdata()
Note: See TracChangeset for help on using the changeset viewer.