Changeset 15859


Ignore:
Timestamp:
28 Nov 2019, 08:21:23 (5 years ago)
Author:
Henrik Bettermann
Message:

Implement library clearance facilities.

Location:
main/kofacustom.iuokada/trunk/src/kofacustom/iuokada
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/permissions.py

    r10765 r15859  
    1919from waeup.kofa.permissions import CCOfficer
    2020
     21class ClearLibrary(grok.Permission):
     22    grok.name('waeup.switchLibraryAccess')
     23
     24class LibraryClearanceOfficer(grok.Role):
     25    """Library Clearance Officers can enable library id card slips.
     26    """
     27    grok.name('waeup.LibraryClearanceOfficer')
     28    grok.title(u'Library Clearance Officer')
     29    grok.permissions('waeup.showStudents',
     30                     'waeup.viewAcademics',
     31                     'waeup.switchLibraryAccess')
    2132
    2233class CRPUOfficer(CCOfficer):
  • main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/students/browser.py

    r15805 r15859  
    4949from kofacustom.iuokada.students.interfaces import (
    5050    ICustomStudentOnlinePayment, ICustomStudentStudyCourse,
    51     ICustomStudentStudyLevel, ICustomStudentBase)
     51    ICustomStudentStudyLevel, ICustomStudentBase, ICustomStudent)
    5252from kofacustom.iuokada.interfaces import MessageFactory as _
    5353
     
    123123    def render(self):
    124124        return
     125
     126class SwitchLibraryAccessView(UtilityView, grok.View):
     127    """ Switch the library attribute
     128    """
     129    grok.context(ICustomStudent)
     130    grok.name('switch_library_access')
     131    grok.require('waeup.switchLibraryAccess')
     132
     133    def update(self):
     134        if self.context.library:
     135            self.context.library = False
     136            self.context.writeLogMessage(self, 'library access disabled')
     137            self.flash(_('Library access disabled'))
     138        else:
     139            self.context.library = True
     140            self.context.writeLogMessage(self, 'library access enabled')
     141            self.flash(_('Library access enabled'))
     142        self.redirect(self.url(self.context))
     143        return
     144
     145    def render(self):
     146        return
     147
     148class ExportLibIdCard(UtilityView, grok.View):
     149    """Deliver an id card for the library.
     150    """
     151    grok.context(ICustomStudent)
     152    grok.name('lib_idcard.pdf')
     153    grok.require('waeup.viewStudent')
     154    prefix = 'form'
     155
     156    label = u"Library Clearance"
     157
     158    omit_fields = (
     159        'suspended', 'email', 'phone',
     160        'adm_code', 'suspended_comment',
     161        'date_of_birth',
     162        'current_mode', 'certificate',
     163        'entry_session',
     164        'flash_notice')
     165
     166    form_fields = []
     167
     168    def _sigsInFooter(self):
     169        isStudent = getattr(
     170            self.request.principal, 'user_type', None) == 'student'
     171        if isStudent:
     172            return ''
     173        return (_("Date, Reader's Signature"),
     174                _("Date, Circulation Librarian's Signature"),
     175                )
     176
     177    def update(self):
     178        if not self.context.library:
     179            self.flash(_('Forbidden!'), type="danger")
     180            self.redirect(self.url(self.context))
     181        return
     182
     183    @property
     184    def note(self):
     185        return """
     186<br /><br /><br /><br /><font size='12'>
     187This is to certify that the bearer whose photograph and other details appear
     188 overleaf is a registered user of the <b>University Library</b>.
     189 The card is not transferable. A replacement fee is charged for a loss,
     190 mutilation or otherwise. If found, please, return to the University Library,
     191 Igbinedion University, Okada.
     192</font>
     193
     194"""
     195        return
     196
     197    def render(self):
     198        studentview = StudentBasePDFFormPage(self.context.student,
     199            self.request, self.omit_fields)
     200        students_utils = getUtility(IStudentsUtils)
     201        return students_utils.renderPDF(
     202            self, 'lib_idcard',
     203            self.context.student, studentview,
     204            omit_fields=self.omit_fields,
     205            sigs_in_footer=self._sigsInFooter(),
     206            note=self.note)
  • main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/students/interfaces.py

    r15704 r15859  
    3838        required = False,
    3939        constraint=validate_email,
     40        )
     41
     42    library = schema.Bool(
     43        title = _(u'Library Id Card'),
     44        default = False,
     45        required = False,
    4046        )
    4147
  • main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/students/tests/test_browser.py

    r15696 r15859  
    3535    IExtFileStore, IFileStoreNameChooser)
    3636from waeup.kofa.students.interfaces import IStudentsUtils
     37from waeup.kofa.tests.test_authentication import SECRET
    3738from kofacustom.iuokada.testing import FunctionalLayer
    3839
     
    4647        return
    4748
     49class OfficerUITests(StudentsFullSetup):
     50    # Tests for Student class views and pages
     51
     52    layer = FunctionalLayer
     53
     54    def test_lib_idcard_officer(self):
     55        # Create library officer
     56        self.app['users'].addUser('mrlibrary', SECRET)
     57        self.app['users']['mrlibrary'].email = 'library@foo.ng'
     58        self.app['users']['mrlibrary'].title = 'Carlo Pitter'
     59        prmglobal = IPrincipalRoleManager(self.app)
     60        prmglobal.assignRoleToPrincipal(
     61            'waeup.LibraryClearanceOfficer', 'mrlibrary')
     62        prmglobal.assignRoleToPrincipal(
     63            'waeup.StudentsOfficer', 'mrlibrary')
     64        self.browser.open(self.login_path)
     65        self.browser.getControl(name="form.login").value = 'mrlibrary'
     66        self.browser.getControl(name="form.password").value = SECRET
     67        self.browser.getControl("Login").click()
     68        self.assertMatches('...You logged in...', self.browser.contents)
     69        self.browser.open(self.student_path)
     70        self.assertFalse('Download Library Id Card' in self.browser.contents)
     71        self.browser.getLink("Switch library access").click()
     72        self.assertTrue('Library access enabled' in self.browser.contents)
     73        self.browser.getLink("Download Library Id Card").click()
     74        self.assertEqual(self.browser.headers['Status'], '200 Ok')
     75        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
     76        path = os.path.join(samples_dir(), 'lib_idcard_officer.pdf')
     77        open(path, 'wb').write(self.browser.contents)
     78        print "Sample PDF lib_idcard_officer.pdf written to %s" % path
    4879
    4980class StudentUITests(StudentsFullSetup):
     
    72103        open(path, 'wb').write(self.browser.contents)
    73104        print "Sample PDF course_registration_slip.pdf written to %s" % path
     105
     106    def test_library_idcard(self):
     107        IWorkflowState(self.student).setState('returning')
     108        self.browser.open(self.login_path)
     109        self.browser.getControl(name="form.login").value = self.student_id
     110        self.browser.getControl(name="form.password").value = 'spwd'
     111        self.browser.getControl("Login").click()
     112        self.assertFalse('Library' in self.browser.contents)
     113        self.student.library = True
     114        self.browser.open(self.student_path)
     115        self.browser.getLink("Download Library Id Card").click()
     116        self.assertEqual(self.browser.headers['Status'], '200 Ok')
     117        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
     118        path = os.path.join(samples_dir(), 'lib_idcard_student.pdf')
     119        open(path, 'wb').write(self.browser.contents)
     120        print "Sample PDF lib_idcard_student.pdf written to %s" % path
     121        self.assertTrue(self.student.library)
     122        IWorkflowInfo(self.student).fireTransition('pay_school_fee')
     123        self.assertFalse(self.student.library)
  • main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/students/tests/test_export.py

    r15733 r15859  
    5656            'fst_sit_type,hq2_degree,hq2_disc,hq2_matric_no,hq2_school,'
    5757            'hq2_session,hq2_type,hq_degree,hq_disc,hq_fname,hq_matric_no,'
    58             'hq_school,hq_session,hq_type,is_staff,lastname,lga,'
     58            'hq_school,hq_session,hq_type,is_staff,lastname,lga,library,'
    5959            'marit_stat,matric_number,middlename,nationality,'
    6060            'next_kin_address,next_kin_name,next_kin_phone,next_kin_relation,'
     
    6868            '"[(\'printing_craft_practice\', \'A1\')]",my clr code,1981-02-04#,,,'
    6969            'anna@sample.com,,,,,,,,,,,,,,Anna,,,,,,"[(\'printing_craft_practice\', \'A1\')]"'
    70             ',,,,,,,,,,,,,,,,Tester,,,234,M.,NG,,,,,,,,,,'
     70            ',,,,,,,,,,,,,,,,Tester,,,,234,M.,NG,,,,,,,,,,'
    7171            '"Studentroad 21\nLagos 123456\n",,+234-123-12345#,,,123,,,,,'
    7272            '"[(\'printing_craft_practice\', \'A1\')]",,f,A111111,0,,,created,'
  • main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/students/viewlets.py

    r15849 r15859  
    2323from waeup.kofa.students.interfaces import IStudent, IStudentsUtils
    2424from kofacustom.iuokada.students.interfaces import (
    25     ICustomStudentStudyCourse, ICustomStudentStudyLevel)
     25    ICustomStudentStudyCourse, ICustomStudentStudyLevel, ICustomStudent)
    2626from waeup.kofa.students.fileviewlets import (
    2727    StudentFileDisplay, StudentFileUpload, StudentImage)
     
    3131
    3232from kofacustom.nigeria.interfaces import MessageFactory as _
     33
     34class SwitchLibraryAccessActionButton(ManageActionButton):
     35    grok.order(7)
     36    grok.context(ICustomStudent)
     37    grok.view(StudentBaseDisplayFormPage)
     38    grok.require('waeup.switchLibraryAccess')
     39    text = _('Switch library access')
     40    target = 'switch_library_access'
     41    icon = 'actionicon_book.png'
     42
    3343
    3444class GetMatricNumberActionButton(ManageActionButton):
     
    5060            return ''
    5161        return self.view.url(self.view.context, 'get_matric_number')
     62
     63# Library
     64
     65class LibraryIdCardActionButton(ManageActionButton):
     66    grok.order(10)
     67    grok.context(ICustomStudent)
     68    grok.view(StudentBaseDisplayFormPage)
     69    grok.require('waeup.viewStudent')
     70    icon = 'actionicon_pdf.png'
     71    text = _('Download Library Id Card')
     72    target = 'lib_idcard.pdf'
     73
     74    @property
     75    def target_url(self):
     76        if self.context.library:
     77            return self.view.url(self.view.context, self.target)
     78        return
    5279
    5380# Signature
Note: See TracChangeset for help on using the changeset viewer.