source: main/waeup.aaue/trunk/src/waeup/aaue/students/browser.py @ 13907

Last change on this file since 13907 was 13907, checked in by Henrik Bettermann, 8 years ago

Sort table.

  • Property svn:keywords set to Id
File size: 25.9 KB
RevLine 
[8911]1## $Id: browser.py 13907 2016-06-10 07:59:13Z henrik $
2##
3## Copyright (C) 2012 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
18import grok
19from zope.i18n import translate
[13900]20from zope.component import getUtility, queryUtility
[13523]21from zope.security import checkPermission
[13900]22from zope.catalog.interfaces import ICatalog
[13351]23from zope.formlib.textwidgets import BytesDisplayWidget
[11597]24from waeup.kofa.browser.layout import UtilityView
[8911]25from waeup.kofa.widgets.datewidget import FriendlyDatetimeDisplayWidget
[9914]26from waeup.kofa.interfaces import IKofaUtils
[11597]27from waeup.kofa.students.interfaces import IStudentsUtils, IStudent
[13038]28from waeup.kofa.students.workflow import PAID, REGISTERED
[9914]29from waeup.kofa.students.browser import (
[11846]30    StartClearancePage,
[9914]31    StudentBasePDFFormPage,
32    CourseTicketAddFormPage,
33    StudyLevelDisplayFormPage,
[13834]34    StudyLevelManageFormPage,
35    StudyLevelEditFormPage,
[13059]36    ExportPDFTranscriptSlip,
37    ExportPDFAdmissionSlip,
[13353]38    BedTicketAddPage,
[13380]39    StudentFilesUploadPage,
[13523]40    PaymentsManageFormPage,
[13770]41    CourseTicketDisplayFormPage,
42    CourseTicketManageFormPage,
[13900]43    EditScoresPage,
44    ExportPDFScoresSlip
[10269]45    )
[8911]46from kofacustom.nigeria.students.browser import (
47    NigeriaOnlinePaymentDisplayFormPage,
48    NigeriaOnlinePaymentAddFormPage,
[13059]49    NigeriaExportPDFPaymentSlip,
50    NigeriaExportPDFCourseRegistrationSlip,
51    NigeriaExportPDFClearanceSlip,
[13351]52    NigeriaStudentPersonalDisplayFormPage,
53    NigeriaStudentPersonalEditFormPage,
54    NigeriaStudentPersonalManageFormPage,
[13362]55    NigeriaStudentClearanceEditFormPage,
[13462]56    NigeriaAccommodationManageFormPage,
[13795]57    NigeriaStudentBaseDisplayFormPage,
58    NigeriaStudentBaseManageFormPage
[10269]59    )
[9496]60from waeup.aaue.students.interfaces import (
[9914]61    ICustomStudentOnlinePayment,
[11607]62    ICustomStudentStudyLevel,
[13351]63    ICustomStudent,
64    ICustomStudentPersonal,
[13362]65    ICustomStudentPersonalEdit,
[13770]66    ICustomUGStudentClearance,
[13795]67    ICustomCourseTicket,
68    ICustomStudentBase)
[13414]69from waeup.aaue.interswitch.browser import gateway_net_amt
[9914]70from waeup.aaue.interfaces import MessageFactory as _
[8911]71
[13795]72class CustomStudentBaseDisplayFormPage(NigeriaStudentBaseDisplayFormPage):
73    """ Page to display student base data
74    """
75    form_fields = grok.AutoFields(ICustomStudentBase).omit(
76        'password', 'suspended', 'suspended_comment', 'flash_notice')
77    form_fields[
78        'financial_clearance_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
79
80class CustomStudentBaseManageFormPage(NigeriaStudentBaseManageFormPage):
81    """ View to manage student base data
82    """
83    form_fields = grok.AutoFields(ICustomStudentBase).omit(
84        'student_id', 'adm_code', 'suspended',
85        'financially_cleared_by', 'financial_clearance_date')
86
[13351]87class CustomStudentPersonalDisplayFormPage(NigeriaStudentPersonalDisplayFormPage):
88    """ Page to display student personal data
89    """
90    form_fields = grok.AutoFields(ICustomStudentPersonal)
91    form_fields['perm_address'].custom_widget = BytesDisplayWidget
92    form_fields['father_address'].custom_widget = BytesDisplayWidget
93    form_fields['mother_address'].custom_widget = BytesDisplayWidget
94    form_fields['next_kin_address'].custom_widget = BytesDisplayWidget
95    form_fields[
96        'personal_updated'].custom_widget = FriendlyDatetimeDisplayWidget('le')
97
98class CustomStudentPersonalEditFormPage(NigeriaStudentPersonalEditFormPage):
99    """ Page to edit personal data
100    """
101    form_fields = grok.AutoFields(ICustomStudentPersonalEdit).omit('personal_updated')
102
103class CustomStudentPersonalManageFormPage(NigeriaStudentPersonalManageFormPage):
104    """ Page to edit personal data
105    """
106    form_fields = grok.AutoFields(ICustomStudentPersonal)
107    form_fields['personal_updated'].for_display = True
108    form_fields[
109        'personal_updated'].custom_widget = FriendlyDatetimeDisplayWidget('le')
110
[13362]111class CustomStudentClearanceEditFormPage(NigeriaStudentClearanceEditFormPage):
112    """ View to edit student clearance data by student
113    """
114
115    @property
116    def form_fields(self):
117        if self.context.is_postgrad:
118            form_fields = grok.AutoFields(ICustomPGStudentClearance).omit(
119            'clearance_locked', 'nysc_location', 'clr_code', 'officer_comment',
120            'physical_clearance_date')
121        else:
122            form_fields = grok.AutoFields(ICustomUGStudentClearance).omit(
123            'clearance_locked', 'clr_code', 'officer_comment',
124            'physical_clearance_date')
125        return form_fields
126
[11846]127class CustomStartClearancePage(StartClearancePage):
[13360]128    with_ac = False
[11846]129
[13351]130    @property
131    def all_required_fields_filled(self):
132        if not self.context.email:
133            return _("Email address is missing."), 'edit_base'
134        if not self.context.phone:
135            return _("Phone number is missing."), 'edit_base'
136        if not self.context.father_name:
137            return _("Personal data form is not properly filled."), 'edit_personal'
138        return
139
[8911]140class CustomOnlinePaymentDisplayFormPage(NigeriaOnlinePaymentDisplayFormPage):
141    """ Page to view an online payment ticket
142    """
143    grok.context(ICustomStudentOnlinePayment)
[9853]144    form_fields = grok.AutoFields(ICustomStudentOnlinePayment).omit(
[9990]145        'provider_amt', 'gateway_amt', 'thirdparty_amt', 'p_item')
[8911]146    form_fields[
147        'creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
148    form_fields[
149        'payment_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
150
151class CustomOnlinePaymentAddFormPage(NigeriaOnlinePaymentAddFormPage):
152    """ Page to add an online payment ticket
153    """
154    form_fields = grok.AutoFields(ICustomStudentOnlinePayment).select(
155        'p_category')
156
[13523]157class CustomPaymentsManageFormPage(PaymentsManageFormPage):
158    """ Page to manage the student payments.
159
160    This manage form page is for both students and students officers.
161    """
162    @property
163    def manage_payments_allowed(self):
164        return checkPermission('waeup.manageStudent', self.context)
165
[13059]166class CustomExportPDFPaymentSlip(NigeriaExportPDFPaymentSlip):
[8911]167    """Deliver a PDF slip of the context.
168    """
169    grok.context(ICustomStudentOnlinePayment)
[9853]170    form_fields = grok.AutoFields(ICustomStudentOnlinePayment).omit(
[9990]171        'provider_amt', 'gateway_amt', 'thirdparty_amt', 'p_item')
[8911]172    form_fields['creation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
[9496]173    form_fields['payment_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
[9914]174
[11625]175    @property
176    def note(self):
[13408]177        p_session = self.context.p_session
[13405]178        try:
[13408]179            academic_session = grok.getSite()['configuration'][str(p_session)]
[13405]180        except KeyError:
181            academic_session = None
[13425]182        text =  '\n\n The Amount Authorized is inclusive of: '
[13512]183        if self.context.p_category in ('schoolfee_incl', 'schoolfee_1') \
184            and academic_session:
[13414]185            welfare_fee = gateway_net_amt(academic_session.welfare_fee)
186            union_fee = gateway_net_amt(academic_session.union_fee)
[13437]187            text += ('School Fee, '
[13463]188                     '%s Naira Student Union Dues, '
[13437]189                     '%s Naira Student Welfare Assurance Fee and '
[13425]190                     % (union_fee, welfare_fee))
[13410]191        elif self.context.p_category in (
192            'clearance_incl', 'clearance_medical_incl') and academic_session:
[13414]193            matric_gown_fee = gateway_net_amt(academic_session.matric_gown_fee)
194            lapel_fee = gateway_net_amt(academic_session.lapel_fee)
[13437]195            text += ('Acceptance Fee, '
196                     '%s Naira Matriculation Gown Fee, '
197                     '%s Naira Lapel/File Fee and '
[13408]198                     % (matric_gown_fee, lapel_fee))
[13437]199        return text + '250.0 Naira Transaction Charge.'
[11625]200
[9914]201class CustomStudyLevelDisplayFormPage(StudyLevelDisplayFormPage):
202    """ Page to display student study levels
203    """
204    grok.context(ICustomStudentStudyLevel)
[10480]205    form_fields = grok.AutoFields(ICustomStudentStudyLevel).omit(
[12876]206        'total_credits', 'gpa', 'level')
[9914]207    form_fields[
208        'validation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
209
[13834]210class CustomStudyLevelManageFormPage(StudyLevelManageFormPage):
211    """ Page to edit the student study level data
212    """
213    grok.context(ICustomStudentStudyLevel)
214
215class CustomStudyLevelEditFormPage(StudyLevelEditFormPage):
216    """ Page to edit the student study level data by students
217    """
218    grok.context(ICustomStudentStudyLevel)
219
[13059]220class CustomExportPDFCourseRegistrationSlip(
221    NigeriaExportPDFCourseRegistrationSlip):
[9914]222    """Deliver a PDF slip of the context.
223    """
224    grok.context(ICustomStudentStudyLevel)
225    form_fields = grok.AutoFields(ICustomStudentStudyLevel).omit(
[10102]226        'level_session', 'level_verdict',
[12876]227        'validated_by', 'validation_date', 'gpa', 'level')
[9914]228
[10269]229    omit_fields = ('password', 'suspended', 'suspended_comment',
[10689]230        'phone', 'adm_code', 'sex', 'email', 'date_of_birth',
[13713]231        'department', 'current_mode', 'current_level', 'flash_notice')
[10269]232
[13038]233    def update(self):
234        if self.context.student.state != REGISTERED \
[13051]235            and self.context.student.current_level == self.context.level:
[13038]236            self.flash(_('Forbidden'), type="warning")
237            self.redirect(self.url(self.context))
238
[9914]239    @property
240    def label(self):
241        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
242        lang = self.request.cookies.get('kofa.language', portal_language)
243        level_title = translate(self.context.level_title, 'waeup.kofa',
244            target_language=lang)
245        line0 = ''
[13788]246        if self.context.student.is_postgrad:
247            line0 = 'SCHOOL OF POSTGRADUATE STUDIES\n'
248        elif self.context.student.current_mode.endswith('_pt'):
[9914]249            line0 = 'DIRECTORATE OF PART-TIME DEGREE PROGRAMMES\n'
[13866]250        line1 = translate(_('Course Registration Slip'),
251            target_language=portal_language) \
[9914]252            + ' %s' % level_title
[13866]253        line2 = translate(_('Session'),
254            target_language=portal_language) \
[9914]255            + ' %s' % self.context.getSessionString
256        return '%s%s\n%s' % (line0, line1, line2)
257
258    @property
259    def title(self):
260        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
[13866]261        return translate(_('Units Registered'), target_language=portal_language)
[9914]262
263    def _signatures(self):
[13647]264        if self.context.student.current_mode.endswith('_pt') \
265            or self.context.student.current_mode == 'found':
266            return (
267                [('I have selected the course on the advise of my Head of '
268                 'Department. <br>', _('Student\'s Signature'), '<br>')],
269                [('This student has satisfied the department\'s requirements. '
270                 'I recommend to approve the course registration. <br>',
271                 _('Head of Department\'s Signature'), '<br>')],
272                [('' , _('Principal Assistant Registrar\'s Signature'), '<br>')],
273                [('', _('Director\'s Signature'))]
274                )
275        if self.context.student.current_mode in (
276            'de_ft', 'ug_ft', 'dp_ft', 'transfer'):
[13649]277            return ([_('Academic Adviser\'s Signature'),
278                _('Faculty Officer\'s Signature'),
279                _('Student\'s Signature')],)
280
[13647]281        if self.context.student.current_mode in ('special_pg_ft', 'special_pg_pt'):
282            return (
[13676]283                [('I declare that all items of information supplied above are correct:' ,
[13680]284                    _('Student\'s Signature'), '<br>')],
[13676]285                [('We approved the above registration:',
[13680]286                    _('Major Supervisor (Name / Signature)'), '')],
287                [('', _('Co-Supervisor (Name / Signature)'), '')],
[13676]288                [('', _('Head of Department'), '<br>')],
289                [('The student has satisfied the conditions for renewal of '
290                  'registration for graduate school programme in this university:',
[13680]291                  _('Secretary <br /> (School of Postgraduate Studies)'), '')],
292                [('', _('Dean <br /> (School of Postgraduate Studies)'), '')],
[13647]293                )
294        return None
[9914]295
[13647]296
[9914]297    def render(self):
298        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
[13866]299        Sem = translate(_('Sem.'), target_language=portal_language)
300        Code = translate(_('Code'), target_language=portal_language)
301        Title = translate(_('Title'), target_language=portal_language)
302        Cred = translate(_('Cred.'), target_language=portal_language)
303        Score = translate(_('Score'), target_language=portal_language)
[13880]304        #CA = translate(_('CA'), target_language=portal_language)
[13866]305        Grade = translate(_('Grade'), target_language=portal_language)
306        Signature = translate(_('Lecturer\'s Signature'), 'waeup.aaue',
[9914]307            target_language=portal_language)
308        studentview = StudentBasePDFFormPage(self.context.student,
309            self.request, self.omit_fields)
310        students_utils = getUtility(IStudentsUtils)
[10442]311
312        tabledata = []
313        tableheader = []
314        contenttitle = []
315        for i in range(1,7):
316            tabledata.append(sorted(
317                [value for value in self.context.values() if value.semester == i],
318                key=lambda value: str(value.semester) + value.code))
319            tableheader.append([(Code,'code', 2.0),
320                               (Title,'title', 7),
321                               (Cred, 'credits', 1.5),
322                               (Score, 'score', 1.4),
[13880]323                               #(CA, 'ca', 1.4),
[10442]324                               (Grade, 'grade', 1.4),
325                               (Signature, 'dummy', 3),
326                               ])
[9914]327        if len(self.label.split('\n')) == 3:
328            topMargin = 1.9
329        elif len(self.label.split('\n')) == 2:
330            topMargin = 1.7
331        else:
332            topMargin = 1.5
333        return students_utils.renderPDF(
334            self, 'course_registration_slip.pdf',
335            self.context.student, studentview,
[10442]336            tableheader=tableheader,
337            tabledata=tabledata,
[9914]338            signatures=self._signatures(),
[10269]339            topMargin=topMargin,
340            omit_fields=self.omit_fields
[9914]341            )
[10566]342
[13059]343class CustomExportPDFTranscriptSlip(ExportPDFTranscriptSlip):
[10566]344    """Deliver a PDF slip of the context.
345    """
346
347    def _sigsInFooter(self):
348        return []
349
350    def _signatures(self):
351        return ([(
[11555]352            'Akhimien Felicia O. (MANUPA) <br /> Principal Assistant Registrar  <br /> '
353            'Exams, Records and Data Processing Division <br /> For: Registrar')],)
[10922]354
[13834]355    def render(self):
356        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
[13866]357        Term = translate(_('Sem.'), target_language=portal_language)
358        Code = translate(_('Code'), target_language=portal_language)
359        Title = translate(_('Title'), target_language=portal_language)
360        Cred = translate(_('Credits'), target_language=portal_language)
361        Score = translate(_('Score'), target_language=portal_language)
362        #CA = translate(_('CA'), target_language=portal_language)
363        Grade = translate(_('Grade'), target_language=portal_language)
[13834]364        studentview = StudentBasePDFFormPage(self.context.student,
365            self.request, self.omit_fields)
366        students_utils = getUtility(IStudentsUtils)
367
368        tableheader = [(Code,'code', 2.5),
369                         (Title,'title', 7),
370                         (Term, 'semester', 1.5),
371                         (Cred, 'credits', 1.5),
372                         (Score, 'score', 1.5),
[13863]373                         #(CA, 'ca', 1.5),
[13834]374                         (Grade, 'grade', 1.5),
375                         ]
376
377        return students_utils.renderPDFTranscript(
378            self, 'transcript.pdf',
379            self.context.student, studentview,
380            omit_fields=self.omit_fields,
381            tableheader=tableheader,
382            signatures=self._signatures(),
383            sigs_in_footer=self._sigsInFooter(),
384            )
385
[13059]386class CustomExportPDFAdmissionSlip(ExportPDFAdmissionSlip):
[10922]387    """Deliver a PDF Admission slip.
388    """
389
390    @property
391    def label(self):
392        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
[13866]393        return translate(_('e-Admission Slip \n'),
394            target_language=portal_language) \
[10922]395            + ' %s' % self.context.display_fullname
[11597]396
[13059]397class CustomExportPDFClearanceSlip(NigeriaExportPDFClearanceSlip):
[11606]398    """Deliver a PDF slip of the context.
399    """
400
401    @property
402    def label(self):
403        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
[13866]404        return translate(_('Clearance Slip\n'),
405            target_language=portal_language) \
[11606]406            + ' %s' % self.context.display_fullname
407
[11597]408class StudentGetMatricNumberPage(UtilityView, grok.View):
409    """ Construct and set the matriculation number.
410    """
411    grok.context(IStudent)
412    grok.name('get_matric_number')
413    grok.require('waeup.viewStudent')
414
415    def update(self):
416        students_utils = getUtility(IStudentsUtils)
417        msg, mnumber = students_utils.setMatricNumber(self.context)
418        if msg:
419            self.flash(msg, type="danger")
420        else:
421            self.flash(_('Matriculation number %s assigned.' % mnumber))
[11602]422            self.context.writeLogMessage(self, '%s assigned' % mnumber)
[11597]423        self.redirect(self.url(self.context))
424        return
425
426    def render(self):
[11607]427        return
428
[13059]429class ExportPDFMatricNumberSlip(UtilityView, grok.View):
[11607]430    """Deliver a PDF notification slip.
431    """
432    grok.context(ICustomStudent)
433    grok.name('matric_number_slip.pdf')
434    grok.require('waeup.viewStudent')
435    prefix = 'form'
436
437    form_fields = grok.AutoFields(ICustomStudent).select(
438        'student_id', 'matric_number')
[13713]439    omit_fields = ('date_of_birth', 'current_level', 'flash_notice')
[11607]440
441    @property
[13489]442    def title(self):
443        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
[13866]444        return translate(_('Matriculation Number'), 'waeup.kofa',
[13489]445            target_language=portal_language)
446
447    @property
[11607]448    def label(self):
449        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
[13866]450        return translate(_('Matriculation Number Slip\n'),
451            target_language=portal_language) \
[11607]452            + ' %s' % self.context.display_fullname
453
454    def render(self):
455        if self.context.state not in (PAID,) or not self.context.is_fresh \
456            or not self.context.matric_number:
457            self.flash('Not allowed.', type="danger")
458            self.redirect(self.url(self.context))
459            return
460        students_utils = getUtility(IStudentsUtils)
[11609]461        pre_text = _('Congratulations! Your acceptance fee and school fees ' +
462                     'payments have been received and your matriculation ' +
463                     'number generated with details as follows.')
[11607]464        return students_utils.renderPDFAdmissionLetter(self,
465            self.context.student, omit_fields=self.omit_fields,
[13353]466            pre_text=pre_text, post_text='')
467
[13489]468class ExportPersonalDataSlip(UtilityView, grok.View):
469    """Deliver a PDF notification slip.
470    """
471    grok.context(ICustomStudent)
472    grok.name('personal_data_slip.pdf')
473    grok.require('waeup.viewStudent')
474    prefix = 'form'
475    note = None
476
477    form_fields = grok.AutoFields(ICustomStudentPersonal).omit('personal_updated')
[13713]478    omit_fields = ('suspended', 'suspended_comment', 'adm_code',
479                   'certificate', 'flash_notice')
[13489]480
481    @property
482    def title(self):
483        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
[13866]484        return translate(_('Personal Data'), 'waeup.kofa',
[13489]485            target_language=portal_language)
486
487    @property
488    def label(self):
489        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
[13866]490        return translate(_('Personal Data Slip\n'),
491            target_language=portal_language) \
[13489]492            + ' %s' % self.context.display_fullname
493
494    def render(self):
495        studentview = StudentBasePDFFormPage(self.context.student,
496            self.request, self.omit_fields)
497        students_utils = getUtility(IStudentsUtils)
498        return students_utils.renderPDF(self, 'personal_data_slip.pdf',
499            self.context.student, studentview, note=self.note,
500            omit_fields=self.omit_fields)
501
[13462]502class CustomAccommodationManageFormPage(NigeriaAccommodationManageFormPage):
503    """ Page to manage bed tickets.
504    This manage form page is for both students and students officers.
505    """
506    with_hostel_selection = True
507
[13353]508class CustomBedTicketAddPage(BedTicketAddPage):
[13360]509    with_ac = False
[13380]510
511class CustomStudentFilesUploadPage(StudentFilesUploadPage):
512    """ View to upload files by student. Inherit from same class in
513    base package, not from kofacustom.nigeria which
514    requires that no application slip exists.
[13770]515    """
516
517class CustomCourseTicketDisplayFormPage(CourseTicketDisplayFormPage):
518    """ Page to display course tickets
519    """
520    form_fields = grok.AutoFields(ICustomCourseTicket)
521
522class CustomCourseTicketManageFormPage(CourseTicketManageFormPage):
523    """ Page to manage course tickets
524    """
525    form_fields = grok.AutoFields(ICustomCourseTicket)
526    form_fields['title'].for_display = True
527    form_fields['fcode'].for_display = True
528    form_fields['dcode'].for_display = True
529    form_fields['semester'].for_display = True
530    form_fields['passmark'].for_display = True
531    form_fields['credits'].for_display = True
532    form_fields['mandatory'].for_display = False
533    form_fields['automatic'].for_display = True
534    form_fields['carry_over'].for_display = True
535
536class CustomEditScoresPage(EditScoresPage):
537    """Page that filters and lists students.
538    """
539    grok.template('editscorespage')
540
541    def update(self,  *args, **kw):
542        form = self.request.form
543        ob_class = self.__implemented__.__name__.replace('waeup.kofa.','')
544        self.current_academic_session = grok.getSite()[
545            'configuration'].current_academic_session
546        if self.context.__parent__.__parent__.score_editing_disabled:
547            self.flash(_('Score editing disabled.'), type="warning")
548            self.redirect(self.url(self.context))
549            return
550        if not self.current_academic_session:
551            self.flash(_('Current academic session not set.'), type="warning")
552            self.redirect(self.url(self.context))
553            return
554        self.tickets = self._searchCatalog(self.current_academic_session)
555        editable_tickets = [
556            ticket for ticket in self.tickets if ticket.editable_by_lecturer]
557        if not self.tickets:
558            self.flash(_('No student found.'), type="warning")
559            self.redirect(self.url(self.context))
560            return
561        if 'UPDATE' in form:
562            error = ''
563            if not editable_tickets:
564                return
565            scores = form['scores']
566            cas = form['cas']
[13875]567            sids = form['sids']
[13770]568            if isinstance(scores, basestring):
569                scores = [scores]
570            if isinstance(cas, basestring):
571                cas = [cas]
[13875]572            if isinstance(sids, basestring):
573                sids = [sids]
574            formvals = dict([(sids[i], (scores[i], cas[i]))
575                             for i in range(len(sids))])
[13770]576            for ticket in editable_tickets:
577                ticket_error = False
578                score = ticket.score
579                ca = ticket.ca
[13875]580                sid = ticket.student.student_id
581                if formvals[sid][0] == '':
[13770]582                    score = None
[13875]583                if formvals[sid][1] == '':
[13770]584                    ca = None
585                try:
[13875]586                    if formvals[sid][0]:
587                        score = int(formvals[sid][0])
588                    if formvals[sid][1]:
589                        ca = int(formvals[sid][1])
[13770]590                except ValueError:
591                    error += '%s, ' % ticket.student.display_fullname
592                    ticket_error = True
593                if not ticket_error and ticket.score != score:
594                    ticket.score = score
595                    ticket.student.__parent__.logger.info(
596                        '%s - %s %s/%s score updated (%s)' %
597                        (ob_class, ticket.student.student_id,
598                         ticket.level, ticket.code, score))
599                if not ticket_error and ticket.ca != ca:
600                    ticket.ca = ca
601                    ticket.student.__parent__.logger.info(
602                        '%s - %s %s/%s ca updated (%s)' %
603                        (ob_class, ticket.student.student_id,
604                         ticket.level, ticket.code, ca))
605            if error:
606                self.flash(_('Error: Score(s) and CA(s) of %s have not be updated. '
607                  'Only integers are allowed.' % error.strip(', ')),
608                  type="danger")
[13900]609        return
610
611class CustomExportPDFScoresSlip(ExportPDFScoresSlip):
612    """Deliver a PDF slip of course tickets for a lecturer.
613    """
614
615    def table_data(self, session):
616        cat = queryUtility(ICatalog, name='coursetickets_catalog')
617        coursetickets = cat.searchResults(
618            session=(session, session),
619            code=(self.context.code, self.context.code)
620            )
[13907]621        header = [[_('Matric No.'),
[13900]622                   _('Reg. No.'),
623                   _('Fullname'),
624                   _('Status'),
625                   _('Course of Studies'),
626                   _('Level'),
627                   _('Score'),
628                   _('CA') ],]
[13907]629        tickets = []
[13900]630        for ticket in list(coursetickets):
631            row = [ticket.student.matric_number,
632                  ticket.student.reg_number,
633                  ticket.student.display_fullname,
634                  ticket.student.translated_state,
635                  ticket.student.certcode,
636                  ticket.level,
637                  ticket.score,
638                  ticket.ca]
[13907]639            tickets.append(row)
640        return header + sorted(tickets, key=lambda value: value[0])
641
Note: See TracBrowser for help on using the repository browser.