Ignore:
Timestamp:
16 Jan 2016, 15:01:09 (9 years ago)
Author:
Henrik Bettermann
Message:

Add fields, permissions, browser views and buttons to enable financial clearance by bursory officers.

Location:
main/kofacustom.nigeria/trunk/src/kofacustom/nigeria/students
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • main/kofacustom.nigeria/trunk/src/kofacustom/nigeria/students/browser.py

    r13458 r13620  
    2020from zope.component import getUtility
    2121from zope.i18n import translate
     22from datetime import datetime
    2223from waeup.kofa.widgets.datewidget import FriendlyDatetimeDisplayWidget
    23 from waeup.kofa.interfaces import IExtFileStore
    24 from waeup.kofa.browser.layout import action
     24from waeup.kofa.interfaces import IExtFileStore, IObjectHistory
     25from waeup.kofa.browser.layout import action, UtilityView
     26from waeup.kofa.utils.helpers import get_current_principal
    2527from waeup.kofa.students.browser import (
    2628    StudentPersonalDisplayFormPage, StudentPersonalManageFormPage,
     
    6264    form_fields = grok.AutoFields(INigeriaStudentBase).omit(
    6365        'password', 'suspended', 'suspended_comment')
     66    form_fields[
     67        'financial_clearance_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
    6468
    6569class NigeriaStudentBaseManageFormPage(StudentBaseManageFormPage):
     
    6771    """
    6872    form_fields = grok.AutoFields(INigeriaStudentBase).omit(
    69         'student_id', 'adm_code', 'suspended')
     73        'student_id', 'adm_code', 'suspended',
     74        'financially_cleared_by', 'financial_clearance_date')
    7075
    7176class NigeriaStudentBaseEditFormPage(StudentBaseEditFormPage):
     
    252257        super(StudentFilesUploadPage, self).update()
    253258        return
     259
     260class ClearStudentFinancially(UtilityView, grok.View):
     261    """ Clear student financially by bursary officer
     262    """
     263    grok.context(INigeriaStudent)
     264    grok.name('clear_financially')
     265    grok.require('waeup.clearStudentFinancially')
     266
     267    def update(self):
     268        if self.context.financially_cleared_by:
     269            self.flash(_('This student has already been financially cleared.'),
     270                       type="danger")
     271            self.redirect(self.url(self.context))
     272            return
     273        user = get_current_principal()
     274        if user is None:
     275            usertitle = 'system'
     276        else:
     277            usertitle = getattr(user, 'public_name', None)
     278            if not usertitle:
     279                usertitle = user.title
     280        self.context.financially_cleared_by = usertitle
     281        self.context.financial_clearance_date = datetime.utcnow()
     282        self.context.writeLogMessage(self,'financially cleared')
     283        history = IObjectHistory(self.context)
     284        history.addMessage('Financially cleared')
     285        self.flash(_('Student has been financially cleared.'))
     286        self.redirect(self.url(self.context))
     287        return
     288
     289    def render(self):
     290        return
     291
     292class WithdrawFinancialClearance(UtilityView, grok.View):
     293    """ Withdraw financial clearance by bursary officer
     294    """
     295    grok.context(INigeriaStudent)
     296    grok.name('withdraw_financial_clearance')
     297    grok.require('waeup.clearStudentFinancially')
     298
     299    def update(self):
     300        if not self.context.financially_cleared_by:
     301            self.flash(_('This student has not yet been financially cleared.'),
     302                       type="danger")
     303            self.redirect(self.url(self.context))
     304            return
     305        self.context.financially_cleared_by = None
     306        self.context.financial_clearance_date = None
     307        self.context.writeLogMessage(self,'financial clearance withdrawn')
     308        history = IObjectHistory(self.context)
     309        history.addMessage('Financial clearance withdrawn')
     310        self.flash(_('Financial clearance withdrawn.'))
     311        self.redirect(self.url(self.context))
     312        return
     313
     314    def render(self):
     315        return
  • main/kofacustom.nigeria/trunk/src/kofacustom/nigeria/students/interfaces.py

    r13109 r13620  
    5555        )
    5656
     57    financially_cleared_by = schema.TextLine(
     58        title = _(u'Financially Cleared by'),
     59        default = None,
     60        required = False,
     61        )
     62
     63    financial_clearance_date = schema.Datetime(
     64        title = _(u'Financial Clearance Date'),
     65        required = False,
     66        readonly = False,
     67        )
     68
    5769INigeriaStudentBase['reg_number'].order = IStudentBase[
    5870    'reg_number'].order
  • main/kofacustom.nigeria/trunk/src/kofacustom/nigeria/students/tests/test_browser.py

    r12985 r13620  
    2525from zope.component import getUtility, createObject
    2626from zope.interface import verify
     27from zope.securitypolicy.interfaces import IPrincipalRoleManager
    2728from waeup.kofa.app import University
    2829from waeup.kofa.students.tests.test_browser import (
     
    347348        self.assertTrue(
    348349            'Form has been saved' in self.browser.contents)
     350
     351    def test_financial_clearance(self):
     352        self.app['users'].addUser('mrbursary', 'mrbursarysecret')
     353        self.app['users']['mrbursary'].email = 'mrbursary@foo.ng'
     354        self.app['users']['mrbursary'].title = u'Carlo Pitter'
     355        # Clearance officers needs to get
     356        # the StudentsOfficer site role
     357        prmglobal = IPrincipalRoleManager(self.app)
     358        prmglobal.assignRoleToPrincipal('waeup.StudentsOfficer', 'mrbursary')
     359        # Assign BursaryOfficer role
     360        prmglobal.assignRoleToPrincipal('waeup.BursaryOfficer', 'mrbursary')
     361        # Login
     362        self.browser.open(self.login_path)
     363        self.browser.getControl(name="form.login").value = 'mrbursary'
     364        self.browser.getControl(name="form.password").value = 'mrbursarysecret'
     365        self.browser.getControl("Login").click()
     366        # BO can see his roles
     367        self.browser.getLink("My Roles").click()
     368        self.assertMatches(
     369            '...<div>Bursary Officer</div>...',
     370            self.browser.contents)
     371        # BO can view student record
     372        self.browser.open(self.student_path)
     373        prmglobal.assignRoleToPrincipal('waeup.BursaryOfficer', 'mrbursary')
     374        self.browser.open(self.student_path)
     375        # BO can see clearance button ...
     376        self.assertTrue(
     377            'Clear student financially' in self.browser.contents)
     378        # ... but not withdraw button
     379        self.assertFalse(
     380            'Withdraw financial clearance' in self.browser.contents)
     381        # BO can clear student
     382        self.browser.getLink("Clear student financially").click()
     383        self.assertTrue(
     384            'Student has been financially cleared' in self.browser.contents)
     385        # Name of BO and date have been stored
     386        self.assertEqual(self.student.financially_cleared_by, 'Carlo Pitter')
     387        self.assertMatches(
     388            '<YYYY-MM-DD hh:mm:ss>',
     389            self.student.financial_clearance_date.strftime(
     390                "%Y-%m-%d %H:%M:%S"))
     391        # BO can't see clearance button ...
     392        self.assertFalse(
     393            'Clear student financially' in self.browser.contents)
     394        # ... but withdraw button and can withdraw clearance
     395        self.browser.getLink("Withdraw financial clearance").click()
     396        self.assertTrue(
     397            'Financial clearance withdrawn' in self.browser.contents)
     398        # Name of BO and date have been deleted
     399        self.assertEqual(self.student.financially_cleared_by, None)
     400        self.assertEqual(self.student.financial_clearance_date, None)
     401        # Clearance is logged
     402        logfile = os.path.join(
     403            self.app['datacenter'].storage, 'logs', 'students.log')
     404        logcontent = open(logfile).read()
     405        self.assertTrue(
     406            'mrbursary - kofacustom.nigeria.students.browser.ClearStudentFinancially'
     407            ' - K1000000 - financially cleared' in logcontent)
     408        self.assertTrue(
     409            'mrbursary - kofacustom.nigeria.students.browser.WithdrawFinancialClearance'
     410            ' - K1000000 - financial clearance withdrawn' in logcontent)
     411        # Clearance is also stored in the history
     412        self.browser.open(self.history_path)
     413        self.assertMatches(
     414            '...2016-01-16 15:50:48 WAT - Financially cleared by Carlo Pitter...',
     415            self.browser.contents)
     416        self.assertMatches(
     417            '...2016-01-16 15:50:48 WAT - Financial clearance withdrawn by Carlo Pitter...',
     418            self.browser.contents)
  • main/kofacustom.nigeria/trunk/src/kofacustom/nigeria/students/tests/test_export.py

    r13109 r13620  
    6868            'clr_code,date_of_birth,def_adm,disabled,email,emp2_end,'
    6969            'emp2_position,emp2_reason,emp2_start,emp_end,emp_position,'
    70             'emp_reason,emp_start,employer,employer2,firstname,former_matric,'
     70            'emp_reason,emp_start,employer,employer2,'
     71            'financial_clearance_date,financially_cleared_by,'
     72            'firstname,former_matric,'
    7173            'fst_sit_date,fst_sit_fname,fst_sit_no,fst_sit_results,'
    7274            'fst_sit_type,hq2_degree,hq2_disc,hq2_matric_no,hq2_school,'
     
    8284            'current_level,current_session\r\nmy adm code,,,,'
    8385            '"[(\'accounts\', \'A\')]",my clr code,1981-02-04#,,,'
    84             'anna@sample.com,,,,,,,,,,,Anna,,,,,"[(\'accounts\', \'A\')]"'
     86            'anna@sample.com,,,,,,,,,,,,,Anna,,,,,"[(\'accounts\', \'A\')]"'
    8587            ',,,,,,,,,,,,,,,,Tester,,,234,M.,NG,,,,,,,,,'
    8688            '"Studentroad 21\nLagos 123456\n",,+234-123-12345#,,123,,,,,'
  • main/kofacustom.nigeria/trunk/src/kofacustom/nigeria/students/viewlets.py

    r13058 r13620  
    1919import grok
    2020from zope.component import getUtility
     21from waeup.kofa.browser.viewlets import ManageActionButton
    2122from waeup.kofa.students.interfaces import IStudentsUtils
    2223from waeup.kofa.students.fileviewlets import (
     
    2425from waeup.kofa.students.browser import ExportPDFClearanceSlip
    2526
     27from kofacustom.nigeria.students.interfaces import INigeriaStudent
     28from kofacustom.nigeria.students.browser import NigeriaStudentBaseDisplayFormPage
    2629from kofacustom.nigeria.interfaces import MessageFactory as _
    2730
     
    3538    return False
    3639
     40# Bursery officer buttons
     41
     42class StudentClearActionButton(ManageActionButton):
     43    grok.order(10)
     44    grok.context(INigeriaStudent)
     45    grok.view(NigeriaStudentBaseDisplayFormPage)
     46    grok.require('waeup.clearStudentFinancially')
     47    text = _('Clear student financially')
     48    target = 'clear_financially'
     49    icon = 'actionicon_accept.png'
     50
     51    @property
     52    def target_url(self):
     53        if self.context.financially_cleared_by:
     54            return ''
     55        return self.view.url(self.view.context, self.target)
     56
     57class StudentWithdrawClearanceActionButton(ManageActionButton):
     58    grok.order(11)
     59    grok.context(INigeriaStudent)
     60    grok.view(NigeriaStudentBaseDisplayFormPage)
     61    grok.require('waeup.clearStudentFinancially')
     62    text = _('Withdraw financial clearance')
     63    target = 'withdraw_financial_clearance'
     64    icon = 'actionicon_reject.png'
     65
     66    @property
     67    def target_url(self):
     68        if not self.context.financially_cleared_by:
     69            return ''
     70        return self.view.url(self.view.context, self.target)
     71
     72
    3773# Acceptance Letter
    3874
Note: See TracChangeset for help on using the changeset viewer.