Changeset 13894 for main/waeup.kofa


Ignore:
Timestamp:
8 Jun 2016, 15:48:51 (8 years ago)
Author:
Henrik Bettermann
Message:

Add DownloadScoresView which is for lecturers only. Remove
waeup.showStudents from Lecturer role. Adjust
DataForLecturerExporter. Only editable course tickets are being
exported.

Location:
main/waeup.kofa/trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • main/waeup.kofa/trunk/CHANGES.txt

    r13886 r13894  
    441.4.2.dev0 (unreleased)
    55=======================
     6
     7* Add `DownloadScoresView` which is for lecturers only. Remove
     8  `waeup.showStudents` from `Lecturer` role. Adjust
     9  `DataForLecturerExporter`. Only editable course tickets are being
     10  exported.
    611
    712* Remove application fee fallback option. Application fees can only
  • main/waeup.kofa/trunk/src/waeup/kofa/browser/viewlets.py

    r13813 r13894  
    2727    DepartmentPage, CoursePage, CertificatePage, CertificateCoursePage,
    2828    UsersContainerPage, UserManageFormPage, DatacenterImportStep1)
     29from waeup.kofa.students.browser import EditScoresPage
    2930from waeup.kofa.browser.interfaces import (
    3031    IFacultiesContainer, IFaculty, IDepartment, ICourse, ICertificate,
     
    537538    target = 'edit_scores'
    538539    grok.order(4)
     540
     541class DownloadCSVFileActionButton(ManageActionButton):
     542    """ 'Download csv file' button for courses.
     543    """
     544    grok.context(ICourse)
     545    grok.view(EditScoresPage)
     546    grok.name('downloadcsv')
     547    grok.require('waeup.editScores')
     548    icon = 'actionicon_down.png'
     549    text = _('Download editable tickets')
     550    target = 'download_scores'
     551    grok.order(1)
    539552
    540553class ManageCertificateActionButton(ManageActionButton):
  • main/waeup.kofa/trunk/src/waeup/kofa/permissions.py

    r13763 r13894  
    362362class Lecturer(grok.Role):
    363363    """The local Lecturer role can be assigned at course level.
    364     The role allows to export student
     364    The role allows to export some student
    365365    data within the course the local role is assigned. Lecturers can't access
    366366    student data directly but they can edit the scores in course tickets.
     
    368368    grok.name('waeup.local.Lecturer')
    369369    grok.title(u'Lecturer')
    370     grok.permissions('waeup.showStudents',
    371                      'waeup.editScores',
     370    grok.permissions('waeup.editScores',
    372371                     'waeup.viewAcademics',
    373372                     'waeup.exportData')
  • main/waeup.kofa/trunk/src/waeup/kofa/students/browser.py

    r13874 r13894  
    30813081
    30823082class EditScoresPage(KofaPage):
    3083     """Page that filters and lists students.
     3083    """Page that allows to edit batches of scores.
    30843084    """
    30853085    grok.context(ICourse)
     
    31563156                  type="danger")
    31573157        return
     3158
     3159class DownloadScoresView(UtilityView, grok.View):
     3160    """View that exports scores.
     3161    """
     3162    grok.context(ICourse)
     3163    grok.require('waeup.editScores')
     3164    grok.name('download_scores')
     3165    redirect_target = '@@export'
     3166
     3167    def update(self):
     3168        ob_class = self.__implemented__.__name__.replace('waeup.kofa.','')
     3169        self.current_academic_session = grok.getSite()[
     3170            'configuration'].current_academic_session
     3171        if self.context.__parent__.__parent__.score_editing_disabled:
     3172            self.flash(_('Score editing disabled.'), type="warning")
     3173            self.redirect(self.url(self.context))
     3174            return
     3175        if not self.current_academic_session:
     3176            self.flash(_('Current academic session not set.'), type="warning")
     3177            self.redirect(self.url(self.context))
     3178            return
     3179        site = grok.getSite()
     3180        exporter = getUtility(ICSVExporter, name='lecturer')
     3181        self.csv = exporter.export_filtered(site, filepath=None,
     3182                                 catalog='coursetickets',
     3183                                 session=self.current_academic_session,
     3184                                 level=None,
     3185                                 code=self.context.code)
     3186        return
     3187
     3188    def render(self):
     3189        filename = 'results_%s_%s.csv' % (
     3190            self.context.code, self.current_academic_session)
     3191        self.response.setHeader(
     3192            'Content-Type', 'text/csv; charset=UTF-8')
     3193        self.response.setHeader(
     3194            'Content-Disposition:', 'attachment; filename="%s' % filename)
     3195        return self.csv
    31583196
    31593197class ExportJobContainerOverview(KofaPage):
     
    34303468
    34313469    def _set_exporter_values(self):
    3432         # We provide only the 'lecturer' exporter but can add more.
     3470        # We provide only the 'coursetickets' and 'lecturer' exporter
     3471        # but can add more.
    34333472        exporters = []
    3434         for name in ('lecturer',):
     3473        for name in ('coursetickets', 'lecturer'):
    34353474            util = getUtility(ICSVExporter, name=name)
    34363475            exporters.append((util.title, name),)
  • main/waeup.kofa/trunk/src/waeup/kofa/students/export.py

    r13885 r13894  
    8484                    continue
    8585                tickets.append(ticket)
     86    return tickets
     87
     88def get_tickets_for_lecturer(students, **kw):
     89    """Get course tickets of `students`.
     90    Filter course tickets which belong to this course code and
     91    which are editable by lecturers.
     92    """
     93    tickets = []
     94    code = kw.get('code', None)
     95    level_session = kw.get('session', None)
     96    level = kw.get('level', None)
     97    for level_obj in get_levels(students):
     98        for ticket in level_obj.values():
     99            if ticket.code != code:
     100                continue
     101            if not ticket.editable_by_lecturer:
     102                continue
     103            if level is not None:
     104                level = int(level)
     105                if level_obj.level in (10, 999, None)  \
     106                    and int(level) != level_obj.level:
     107                    continue
     108                if level_obj.level not in range(level, level+100, 10):
     109                    continue
     110            if level_session is not None and \
     111                int(level_session) != level_obj.level_session:
     112                continue
     113            tickets.append(ticket)
    86114    return tickets
    87115
     
    349377            value, name, context=context)
    350378
    351 class DataForLecturerExporter(CourseTicketExporter):
     379class DataForLecturerExporter(grok.GlobalUtility, StudentExporterBase):
    352380    """
    353381    """
    354382    grok.name('lecturer')
    355383
    356     fields = ('matric_number', 'reg_number', 'student_id', 'display_fullname',
     384    fields = ('matric_number', 'student_id', 'display_fullname',
    357385              'level', 'code', 'level_session', 'score')
    358386
    359387    title = _(u'Data for Lecturer')
     388
     389    def filter_func(self, x, **kw):
     390        return get_tickets_for_lecturer(x, **kw)
    360391
    361392    def mangle_value(self, value, name, context=None):
     
    370401                value = getattr(student, name, None)
    371402        return super(
    372             CourseTicketExporter, self).mangle_value(
     403            DataForLecturerExporter, self).mangle_value(
    373404            value, name, context=context)
    374405
  • main/waeup.kofa/trunk/src/waeup/kofa/students/reports/level_report.py

    r13879 r13894  
    190190        pdf_data.append(Spacer(1, 40))
    191191        signatures = [
    192             translate(_('Ag. Head of Department')),
     192            translate(_('Head of Department')),
    193193            translate(_('Dean of Faculty'))]
    194194        signaturetables = get_signature_tables(signatures, landscape=True)
  • main/waeup.kofa/trunk/src/waeup/kofa/students/tests/test_browser.py

    r13885 r13894  
    38063806        studylevel.level = 100
    38073807        studylevel.level_session = 2004
     3808        IWorkflowState(self.student).setState('courses validated')
    38083809        self.student['studycourse'].addStudentStudyLevel(
    38093810            self.certificate,studylevel)
     
    38343835        # ... and contains the course ticket COURSE1
    38353836        self.assertEqual(self.browser.contents,
    3836             'matric_number,reg_number,student_id,display_fullname,level,code,'
    3837             'level_session,score\r\n234,123,K1000000,Anna Tester,'
     3837            'matric_number,student_id,display_fullname,level,code,'
     3838            'level_session,score\r\n234,K1000000,Anna Tester,'
    38383839            '100,COURSE1,2004,\r\n')
    38393840        self.assertEqual(len(self.app['datacenter'].running_exports), 1)
     
    38613862            '- discarded: job_id=%s' % job_id in logcontent
    38623863            )
     3864
     3865    def test_course_download_lecturer(self):
     3866        # We add study level 100 to the student's studycourse
     3867        studylevel = StudentStudyLevel()
     3868        studylevel.level = 100
     3869        studylevel.level_session = 2004
     3870        IWorkflowState(self.student).setState('courses validated')
     3871        self.student['studycourse'].addStudentStudyLevel(
     3872            self.certificate,studylevel)
     3873        course1_path = 'http://localhost/app/faculties/fac1/dep1/courses/COURSE1'
     3874        # Create lecturer
     3875        self.app['users'].addUser('mrlecturer', 'mrlecturersecret')
     3876        self.app['users']['mrlecturer'].email = 'mrlecturer@foo.ng'
     3877        self.app['users']['mrlecturer'].title = 'Carlo Intelligent'
     3878        prmglobal = IPrincipalRoleManager(self.course)
     3879        prmglobal.assignRoleToPrincipal('waeup.local.Lecturer', 'mrlecturer')
     3880        # Login as lecturer
     3881        self.browser.open(self.login_path)
     3882        self.browser.getControl(name="form.login").value = 'mrlecturer'
     3883        self.browser.getControl(name="form.password").value = 'mrlecturersecret'
     3884        self.browser.getControl("Login").click()
     3885        self.assertMatches('...You logged in...', self.browser.contents)
     3886        self.browser.open(course1_path)
     3887        self.assertFalse('Export' in self.browser.contents)
     3888        self.browser.getLink("Update scores").click()
     3889        self.assertTrue('Current academic session not set' in self.browser.contents)
     3890        self.app['configuration'].current_academic_session = 2004
     3891        self.browser.getLink("Update scores").click()
     3892        self.browser.getLink("Download editable tickets").click()
     3893        self.assertEqual(self.browser.headers['Status'], '200 Ok')
     3894        self.assertEqual(self.browser.headers['Content-Type'],
     3895                         'text/csv; charset=UTF-8')
     3896        self.assertEqual(self.browser.contents, 'matric_number,student_id,'
     3897            'display_fullname,level,code,level_session,score\r\n234,'
     3898            'K1000000,Anna Tester,100,COURSE1,2004,\r\n')
    38633899
    38643900    def test_export_departmet_officers(self):
Note: See TracChangeset for help on using the changeset viewer.