Ignore:
Timestamp:
20 Sep 2012, 08:49:37 (12 years ago)
Author:
uli
Message:

Merge changes from update branch (includes trunk changes until r9107).

Location:
main/waeup.kofa/branches/uli-zc-async
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • main/waeup.kofa/branches/uli-zc-async

  • main/waeup.kofa/branches/uli-zc-async/src/waeup/kofa/students/browser.py

    r9166 r9209  
    4343from waeup.kofa.interfaces import (
    4444    IKofaObject, IUserAccount, IExtFileStore, IPasswordValidator, IContactForm,
    45     IKofaUtils, IUniversity)
     45    IKofaUtils, IUniversity, IObjectHistory)
    4646from waeup.kofa.interfaces import MessageFactory as _
    4747from waeup.kofa.widgets.datewidget import (
     
    5353    IUGStudentClearance,IPGStudentClearance,
    5454    IStudentPersonal, IStudentBase, IStudentStudyCourse,
     55    IStudentStudyCourseTransfer,
    5556    IStudentAccommodation, IStudentStudyLevel,
    5657    ICourseTicket, ICourseTicketAdd, IStudentPaymentsContainer,
    57     IStudentOnlinePayment, IBedTicket, IStudentsUtils, IStudentRequestPW
     58    IStudentOnlinePayment, IStudentPreviousPayment,
     59    IBedTicket, IStudentsUtils, IStudentRequestPW
    5860    )
    5961from waeup.kofa.students.catalog import search
    6062from waeup.kofa.students.workflow import (CREATED, ADMITTED, PAID,
    61     CLEARANCE, REQUESTED, RETURNING, CLEARED, REGISTERED, VALIDATED)
     63    CLEARANCE, REQUESTED, RETURNING, CLEARED, REGISTERED, VALIDATED,
     64    FORBIDDEN_POSTGRAD_TRANS)
    6265from waeup.kofa.students.studylevel import StudentStudyLevel, CourseTicket
    6366from waeup.kofa.students.vocabularies import StudyLevelSource
     
    6568from waeup.kofa.hostels.hostel import NOT_OCCUPIED
    6669from waeup.kofa.utils.helpers import get_current_principal, to_timezone
     70from waeup.kofa.mandates.mandate import PasswordMandate
    6771
    6872grok.context(IKofaObject) # Make IKofaObject the default context
     
    9195    return
    9296
     97def translated_values(view):
     98    lang = view.request.cookies.get('kofa.language')
     99    for value in view.context.values():
     100        value_dict = dict([i for i in value.__dict__.items()])
     101        value_dict['mandatory_bool'] = value.mandatory
     102        value_dict['mandatory'] = translate(str(value.mandatory), 'zope',
     103            target_language=lang)
     104        value_dict['carry_over'] = translate(str(value.carry_over), 'zope',
     105            target_language=lang)
     106        value_dict['automatic'] = translate(str(value.automatic), 'zope',
     107            target_language=lang)
     108        yield value_dict
     109
    93110class StudentsBreadcrumb(Breadcrumb):
    94111    """A breadcrumb for the students container.
     
    116133    """
    117134    grok.context(IStudentStudyCourse)
    118     title = _('Study Course')
     135
     136    def title(self):
     137        if self.context.is_current:
     138            return _('Study Course')
     139        else:
     140            return _('Previous Study Course')
    119141
    120142class PaymentsBreadcrumb(Breadcrumb):
     
    279301    grok.require('waeup.viewStudent')
    280302    grok.template('basepage')
    281     form_fields = grok.AutoFields(IStudentBase).omit('password')
     303    form_fields = grok.AutoFields(IStudentBase).omit('password', 'suspended')
    282304    pnav = 4
    283305
    284306    @property
    285307    def label(self):
    286         return _('${a}: Base Data',
     308        if self.context.suspended:
     309            return _('${a}: Base Data (account deactivated)',
     310                mapping = {'a':self.context.display_fullname})
     311        return  _('${a}: Base Data',
    287312            mapping = {'a':self.context.display_fullname})
    288313
     
    292317            return _('set')
    293318        return _('unset')
     319
     320class StudentBasePDFFormPage(KofaDisplayFormPage):
     321    """ Page to display student base data in pdf files.
     322    """
     323    form_fields = grok.AutoFields(IStudentBase).omit(
     324        'password', 'suspended', 'phone', 'adm_code', 'sex')
    294325
    295326class ContactStudentForm(ContactAdminForm):
     
    330361        return
    331362
     363class ExportPDFAdmissionSlipPage(UtilityView, grok.View):
     364    """Deliver a PDF Admission slip.
     365    """
     366    grok.context(IStudent)
     367    grok.name('admission_slip.pdf')
     368    grok.require('waeup.viewStudent')
     369    prefix = 'form'
     370
     371    form_fields = grok.AutoFields(IStudentBase).select('student_id', 'reg_number')
     372
     373    @property
     374    def label(self):
     375        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
     376        return translate(_('Admission Letter of'),
     377            'waeup.kofa', target_language=portal_language) \
     378            + ' %s' % self.context.display_fullname
     379
     380    def render(self):
     381        students_utils = getUtility(IStudentsUtils)
     382        return students_utils.renderPDFAdmissionLetter(self,
     383            self.context.student)
     384
    332385class StudentBaseManageFormPage(KofaEditFormPage):
    333386    """ View to manage student base data
     
    336389    grok.name('manage_base')
    337390    grok.require('waeup.manageStudent')
    338     form_fields = grok.AutoFields(IStudentBase).omit('student_id')
     391    form_fields = grok.AutoFields(IStudentBase).omit(
     392        'student_id', 'adm_code', 'suspended')
    339393    grok.template('basemanagepage')
    340394    label = _('Manage base data')
     
    362416        allowed_transitions = [t for t in self.wf_info.getManualTransitions()
    363417            if not t[0].startswith('pay')]
     418        if self.context.is_postgrad:
     419            allowed_transitions = [t for t in allowed_transitions
     420                if not t[0] in FORBIDDEN_POSTGRAD_TRANS]
    364421        return [dict(name='', title=_('No transition'))] +[
    365422            dict(name=x, title=y) for x, y in allowed_transitions]
     
    396453        return
    397454
     455class StudentActivatePage(UtilityView, grok.View):
     456    """ Activate student account
     457    """
     458    grok.context(IStudent)
     459    grok.name('activate')
     460    grok.require('waeup.manageStudent')
     461
     462    def update(self):
     463        self.context.suspended = False
     464        self.context.writeLogMessage(self, 'account activated')
     465        history = IObjectHistory(self.context)
     466        history.addMessage('Student account activated')
     467        self.flash(_('Student account has been activated.'))
     468        self.redirect(self.url(self.context))
     469        return
     470
     471    def render(self):
     472        return
     473
     474class StudentDeactivatePage(UtilityView, grok.View):
     475    """ Deactivate student account
     476    """
     477    grok.context(IStudent)
     478    grok.name('deactivate')
     479    grok.require('waeup.manageStudent')
     480
     481    def update(self):
     482        self.context.suspended = True
     483        self.context.writeLogMessage(self, 'account deactivated')
     484        history = IObjectHistory(self.context)
     485        history.addMessage('Student account deactivated')
     486        self.flash(_('Student account has been deactivated.'))
     487        self.redirect(self.url(self.context))
     488        return
     489
     490    def render(self):
     491        return
     492
    398493class StudentClearanceDisplayFormPage(KofaDisplayFormPage):
    399494    """ Page to display student clearance data
     
    411506    def form_fields(self):
    412507        if self.context.is_postgrad:
    413             form_fields = grok.AutoFields(IPGStudentClearance).omit('clearance_locked')
    414         else:
    415             form_fields = grok.AutoFields(IUGStudentClearance).omit('clearance_locked')
     508            form_fields = grok.AutoFields(
     509                IPGStudentClearance).omit('clearance_locked')
     510        else:
     511            form_fields = grok.AutoFields(
     512                IUGStudentClearance).omit('clearance_locked')
    416513        return form_fields
    417514
     
    432529    def form_fields(self):
    433530        if self.context.is_postgrad:
    434             form_fields = grok.AutoFields(IPGStudentClearance).omit('clearance_locked')
    435         else:
    436             form_fields = grok.AutoFields(IUGStudentClearance).omit('clearance_locked')
     531            form_fields = grok.AutoFields(
     532                IPGStudentClearance).omit('clearance_locked')
     533        else:
     534            form_fields = grok.AutoFields(
     535                IUGStudentClearance).omit('clearance_locked')
    437536        return form_fields
    438537
     
    446545    def label(self):
    447546        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
    448         return translate(_('Clearance Slip of '),
     547        return translate(_('Clearance Slip of'),
    449548            'waeup.kofa', target_language=portal_language) \
    450549            + ' %s' % self.context.display_fullname
    451550
     551    def _signatures(self):
     552        if self.context.state == CLEARED:
     553            return (_('Student Signature'), _('Clearance Officer Signature'))
     554        return
     555
    452556    def render(self):
    453         studentview = StudentBaseDisplayFormPage(self.context.student,
     557        studentview = StudentBasePDFFormPage(self.context.student,
    454558            self.request)
    455559        students_utils = getUtility(IStudentsUtils)
    456560        return students_utils.renderPDF(
    457561            self, 'clearance.pdf',
    458             self.context.student, studentview)
     562            self.context.student, studentview, signatures=self._signatures())
    459563
    460564class StudentClearanceManageFormPage(KofaEditFormPage):
     
    475579    def form_fields(self):
    476580        if self.context.is_postgrad:
    477             form_fields = grok.AutoFields(IPGStudentClearance)
    478         else:
    479             form_fields = grok.AutoFields(IUGStudentClearance)
     581            form_fields = grok.AutoFields(IPGStudentClearance).omit('clr_code')
     582        else:
     583            form_fields = grok.AutoFields(IUGStudentClearance).omit('clr_code')
    480584        return form_fields
    481585
     
    557661            mapping = {'a':self.context.display_fullname})
    558662
    559 class StudentPersonalEditFormPage(KofaEditFormPage):
    560     """ Page to edit personal data
     663class StudentPersonalManageFormPage(KofaEditFormPage):
     664    """ Page to manage personal data
    561665    """
    562666    grok.context(IStudent)
    563     grok.name('edit_personal')
    564     grok.require('waeup.handleStudent')
     667    grok.name('manage_personal')
     668    grok.require('waeup.manageStudent')
    565669    form_fields = grok.AutoFields(IStudentPersonal)
    566     label = _('Edit personal data')
     670    label = _('Manage personal data')
    567671    pnav = 4
    568672
     
    572676        return
    573677
     678class StudentPersonalEditFormPage(StudentPersonalManageFormPage):
     679    """ Page to edit personal data
     680    """
     681    grok.name('edit_personal')
     682    grok.require('waeup.handleStudent')
     683    label = _('Edit personal data')
     684    pnav = 4
     685
    574686class StudyCourseDisplayFormPage(KofaDisplayFormPage):
    575687    """ Page to display the student study course data
     
    578690    grok.name('index')
    579691    grok.require('waeup.viewStudent')
    580     form_fields = grok.AutoFields(IStudentStudyCourse)
    581692    grok.template('studycoursepage')
    582693    pnav = 4
    583694
    584695    @property
     696    def form_fields(self):
     697        if self.context.is_postgrad:
     698            form_fields = grok.AutoFields(IStudentStudyCourse).omit(
     699                'current_verdict', 'previous_verdict')
     700        else:
     701            form_fields = grok.AutoFields(IStudentStudyCourse)
     702        return form_fields
     703
     704    @property
    585705    def label(self):
    586         return _('${a}: Study Course',
    587             mapping = {'a':self.context.__parent__.display_fullname})
     706        if self.context.is_current:
     707            return _('${a}: Study Course',
     708                mapping = {'a':self.context.__parent__.display_fullname})
     709        else:
     710            return _('${a}: Previous Study Course',
     711                mapping = {'a':self.context.__parent__.display_fullname})
    588712
    589713    @property
     
    606730        return
    607731
     732    @property
     733    def prev_studycourses(self):
     734        if self.context.is_current:
     735            if self.context.__parent__.get('studycourse_2', None) is not None:
     736                return (
     737                        {'href':self.url(self.context.student) + '/studycourse_1',
     738                        'title':_('First Study Course, ')},
     739                        {'href':self.url(self.context.student) + '/studycourse_2',
     740                        'title':_('Second Study Course')}
     741                        )
     742            if self.context.__parent__.get('studycourse_1', None) is not None:
     743                return (
     744                        {'href':self.url(self.context.student) + '/studycourse_1',
     745                        'title':_('First Study Course')},
     746                        )
     747        return
     748
    608749class StudyCourseManageFormPage(KofaEditFormPage):
    609750    """ Page to edit the student study course data
     
    613754    grok.require('waeup.manageStudent')
    614755    grok.template('studycoursemanagepage')
    615     form_fields = grok.AutoFields(IStudentStudyCourse)
    616756    label = _('Manage study course')
    617757    pnav = 4
     
    620760    tabthreeactions = [_('Add study level')]
    621761
     762    @property
     763    def form_fields(self):
     764        if self.context.is_postgrad:
     765            form_fields = grok.AutoFields(IStudentStudyCourse).omit(
     766                'current_verdict', 'previous_verdict')
     767        else:
     768            form_fields = grok.AutoFields(IStudentStudyCourse)
     769        return form_fields
     770
    622771    def update(self):
     772        if not self.context.is_current:
     773            emit_lock_message(self)
     774            return
    623775        super(StudyCourseManageFormPage, self).update()
    624776        tabs.need()
     
    685837        return
    686838
     839class StudentTransferFormPage(KofaAddFormPage):
     840    """Page to transfer the student.
     841    """
     842    grok.context(IStudent)
     843    grok.name('transfer')
     844    grok.require('waeup.manageStudent')
     845    label = _('Transfer student')
     846    form_fields = grok.AutoFields(IStudentStudyCourseTransfer).omit(
     847        'entry_mode', 'entry_session')
     848    pnav = 4
     849
     850    def update(self):
     851        super(StudentTransferFormPage, self).update()
     852        warning.need()
     853        return
     854
     855    @jsaction(_('Transfer'))
     856    def transferStudent(self, **data):
     857        error = self.context.transfer(**data)
     858        if error == -1:
     859            self.flash(_('Current level does not match certificate levels.'))
     860        elif error == -2:
     861            self.flash(_('Former study course record incomplete.'))
     862        elif error == -3:
     863            self.flash(_('Maximum number of transfers exceeded.'))
     864        else:
     865            self.flash(_('Successfully transferred.'))
     866        return
     867
    687868class StudyLevelDisplayFormPage(KofaDisplayFormPage):
    688869    """ Page to display student study levels
     
    692873    grok.require('waeup.viewStudent')
    693874    form_fields = grok.AutoFields(IStudentStudyLevel)
     875    form_fields[
     876        'validation_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
    694877    grok.template('studylevelpage')
    695878    pnav = 4
     
    702885    @property
    703886    def translated_values(self):
    704         lang = self.request.cookies.get('kofa.language')
    705         for value in self.context.values():
    706             value_dict = dict([i for i in value.__dict__.items()])
    707             value_dict['mandatory'] = translate(str(value.mandatory), 'zope',
    708                 target_language=lang)
    709             value_dict['carry_over'] = translate(str(value.carry_over), 'zope',
    710                 target_language=lang)
    711             value_dict['automatic'] = translate(str(value.automatic), 'zope',
    712                 target_language=lang)
    713             yield value_dict
     887        return translated_values(self)
    714888
    715889    @property
     
    771945        Mand = translate(_('Mand.'), 'waeup.kofa', target_language=portal_language)
    772946        Score = translate(_('Score'), 'waeup.kofa', target_language=portal_language)
    773         studentview = StudentBaseDisplayFormPage(self.context.student,
     947        studentview = StudentBasePDFFormPage(self.context.student,
    774948            self.request)
    775949        students_utils = getUtility(IStudentsUtils)
     
    796970    grok.require('waeup.manageStudent')
    797971    grok.template('studylevelmanagepage')
    798     form_fields = grok.AutoFields(IStudentStudyLevel)
     972    form_fields = grok.AutoFields(IStudentStudyLevel).omit(
     973        'validation_date', 'validated_by')
    799974    pnav = 4
    800975    taboneactions = [_('Save'),_('Cancel')]
     
    803978
    804979    def update(self):
     980        if not self.context.__parent__.is_current:
     981            emit_lock_message(self)
     982            return
    805983        super(StudyLevelManageFormPage, self).update()
    806984        tabs.need()
     
    813991        datatable.need()
    814992        return
     993
     994    @property
     995    def translated_values(self):
     996        return translated_values(self)
    815997
    816998    @property
     
    8611043
    8621044    def update(self):
     1045        if not self.context.__parent__.is_current:
     1046            emit_lock_message(self)
     1047            return
    8631048        if str(self.context.__parent__.current_level) != self.context.__name__:
    8641049            self.flash(_('This level does not correspond current level.'))
     
    8831068
    8841069    def update(self):
     1070        if not self.context.__parent__.is_current:
     1071            emit_lock_message(self)
     1072            return
    8851073        if str(self.context.__parent__.current_level) != self.context.__name__:
    8861074            self.flash(_('This level does not correspond current level.'))
     
    9181106    pnav = 4
    9191107
     1108    def update(self):
     1109        if not self.context.__parent__.is_current:
     1110            emit_lock_message(self)
     1111            return
     1112        super(CourseTicketAddFormPage, self).update()
     1113        return
     1114
    9201115    @action(_('Add course ticket'))
    9211116    def addCourseTicket(self, **data):
     
    9241119        ticket.automatic = False
    9251120        ticket.carry_over = False
    926         ticket.code = course.code
    927         ticket.title = course.title
    928         ticket.fcode = course.__parent__.__parent__.__parent__.code
    929         ticket.dcode = course.__parent__.__parent__.code
    930         ticket.credits = course.credits
    931         ticket.passmark = course.passmark
    932         ticket.semester = course.semester
    9331121        try:
    934             self.context.addCourseTicket(ticket)
     1122            self.context.addCourseTicket(ticket, course)
    9351123        except KeyError:
    9361124            self.flash(_('The ticket exists.'))
     
    10301218                mapping = {'a': ', '.join(deleted)}))
    10311219            self.context.writeLogMessage(
    1032                 self,'removed: % s' % ', '.join(deleted))
     1220                self,'removed: %s' % ', '.join(deleted))
    10331221        self.redirect(self.url(self.context))
    10341222        return
     
    10521240    def createTicket(self, **data):
    10531241        p_category = data['p_category']
     1242        previous_session = data.get('p_session', None)
     1243        previous_level = data.get('p_level', None)
    10541244        student = self.context.__parent__
    10551245        if p_category == 'bed_allocation' and student[
     
    10621252                return
    10631253        students_utils = getUtility(IStudentsUtils)
    1064         error, payment = students_utils.setPaymentDetails(p_category, student)
     1254        error, payment = students_utils.setPaymentDetails(
     1255            p_category, student, previous_session, previous_level)
    10651256        if error is not None:
    10661257            self.flash(error)
     1258            if 'previous session' in error:
     1259                self.redirect(self.url(self.context) + '/@@addpp')
     1260                return
    10671261            self.redirect(self.url(self.context))
    10681262            return
     
    10711265        self.redirect(self.url(self.context))
    10721266        return
     1267
     1268class PreviousPaymentAddFormPage(OnlinePaymentAddFormPage):
     1269    """ Page to add an online payment ticket for previous sessions
     1270    """
     1271    grok.context(IStudentPaymentsContainer)
     1272    grok.name('addpp')
     1273    grok.require('waeup.payStudent')
     1274    form_fields = grok.AutoFields(IStudentPreviousPayment).select(
     1275        'p_category', 'p_session', 'p_level')
     1276    label = _('Add previous session online payment')
     1277    pnav = 4
    10731278
    10741279class OnlinePaymentDisplayFormPage(KofaDisplayFormPage):
     
    11491354        #    self.redirect(self.url(self.context))
    11501355        #    return
    1151         studentview = StudentBaseDisplayFormPage(self.context.student,
     1356        studentview = StudentBasePDFFormPage(self.context.student,
    11521357            self.request)
    11531358        students_utils = getUtility(IStudentsUtils)
     
    12261431    buttonname = _('Create bed ticket')
    12271432    notice = ''
     1433    with_ac = True
    12281434
    12291435    def update(self, SUBMIT=None):
     
    12661472            self.redirect(self.url(self.context))
    12671473            return
    1268         self.ac_series = self.request.form.get('ac_series', None)
    1269         self.ac_number = self.request.form.get('ac_number', None)
     1474        if self.with_ac:
     1475            self.ac_series = self.request.form.get('ac_series', None)
     1476            self.ac_number = self.request.form.get('ac_number', None)
    12701477        if SUBMIT is None:
    12711478            return
    1272         pin = '%s-%s-%s' % (self.ac_prefix, self.ac_series, self.ac_number)
    1273         code = get_access_code(pin)
    1274         if not code:
    1275             self.flash(_('Activation code is invalid.'))
    1276             return
     1479        if self.with_ac:
     1480            pin = '%s-%s-%s' % (self.ac_prefix, self.ac_series, self.ac_number)
     1481            code = get_access_code(pin)
     1482            if not code:
     1483                self.flash(_('Activation code is invalid.'))
     1484                return
    12771485        # Search and book bed
    12781486        cat = queryUtility(ICatalog, name='beds_catalog', default=None)
     
    12801488            owner=(student.student_id,student.student_id))
    12811489        if len(entries):
    1282             # If bed space has bee manually allocated use this bed
     1490            # If bed space has been manually allocated use this bed
    12831491            bed = [entry for entry in entries][0]
    12841492        else:
     
    12961504                    mapping = {'a':acc_details['bt']}))
    12971505                return
    1298         # Mark pin as used (this also fires a pin related transition)
    1299         if code.state == USED:
    1300             self.flash(_('Activation code has already been used.'))
    1301             return
    1302         else:
    1303             comment = _(u'invalidated')
    1304             # Here we know that the ac is in state initialized so we do not
    1305             # expect an exception, but the owner might be different
    1306             if not invalidate_accesscode(
    1307                 pin,comment,self.context.student.student_id):
    1308                 self.flash(_('You are not the owner of this access code.'))
     1506        if self.with_ac:
     1507            # Mark pin as used (this also fires a pin related transition)
     1508            if code.state == USED:
     1509                self.flash(_('Activation code has already been used.'))
    13091510                return
     1511            else:
     1512                comment = _(u'invalidated')
     1513                # Here we know that the ac is in state initialized so we do not
     1514                # expect an exception, but the owner might be different
     1515                if not invalidate_accesscode(
     1516                    pin,comment,self.context.student.student_id):
     1517                    self.flash(_('You are not the owner of this access code.'))
     1518                    return
    13101519        # Create bed ticket
    13111520        bedticket = createObject(u'waeup.BedTicket')
    1312         bedticket.booking_code = pin
     1521        if self.with_ac:
     1522            bedticket.booking_code = pin
    13131523        bedticket.booking_session = acc_details['booking_session']
    13141524        bedticket.bed_type = acc_details['bt']
    13151525        bedticket.bed = bed
    13161526        hall_title = bed.__parent__.hostel_name
    1317         coordinates = bed.getBedCoordinates()[1:]
     1527        coordinates = bed.coordinates[1:]
    13181528        block, room_nr, bed_nr = coordinates
    13191529        bc = _('${a}, Block ${b}, Room ${c}, Bed ${d} (${e})', mapping = {
     
    13381548    grok.require('waeup.handleAccommodation')
    13391549    form_fields = grok.AutoFields(IBedTicket)
     1550    form_fields['booking_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
    13401551    pnav = 4
    13411552
     
    13641575    def label(self):
    13651576        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
    1366         return translate(_('Bed Allocation: '),
     1577        #return translate(_('Bed Allocation: '),
     1578        #    'waeup.kofa', target_language=portal_language) \
     1579        #    + ' %s' % self.context.bed_coordinates
     1580        return translate(_('Bed Allocation Slip'),
    13671581            'waeup.kofa', target_language=portal_language) \
    1368             + ' %s' % self.context.bed_coordinates
     1582            + ' %s' % self.context.getSessionString()
    13691583
    13701584    def render(self):
    1371         studentview = StudentBaseDisplayFormPage(self.context.student,
     1585        studentview = StudentBasePDFFormPage(self.context.student,
    13721586            self.request)
    13731587        students_utils = getUtility(IStudentsUtils)
     
    14311645        self.context.bed = new_bed
    14321646        hall_title = new_bed.__parent__.hostel_name
    1433         coordinates = new_bed.getBedCoordinates()[1:]
     1647        coordinates = new_bed.coordinates[1:]
    14341648        block, room_nr, bed_nr = coordinates
    14351649        bc = _('${a}, Block ${b}, Room ${c}, Bed ${d} (${e})', mapping = {
     
    15691783            self.flash(_('Activation code is invalid.'))
    15701784            return
     1785        if code.state == USED:
     1786            self.flash(_('Activation code has already been used.'))
     1787            return
    15711788        # Mark pin as used (this also fires a pin related transition)
    15721789        # and fire transition start_clearance
    1573         if code.state == USED:
    1574             self.flash(_('Activation code has already been used.'))
    1575             return
    1576         else:
    1577             comment = _(u"invalidated")
    1578             # Here we know that the ac is in state initialized so we do not
    1579             # expect an exception, but the owner might be different
    1580             if not invalidate_accesscode(pin,comment,self.context.student_id):
    1581                 self.flash(_('You are not the owner of this access code.'))
    1582                 return
    1583             self.context.clr_code = pin
     1790        comment = _(u"invalidated")
     1791        # Here we know that the ac is in state initialized so we do not
     1792        # expect an exception, but the owner might be different
     1793        if not invalidate_accesscode(pin, comment, self.context.student_id):
     1794            self.flash(_('You are not the owner of this access code.'))
     1795            return
     1796        self.context.clr_code = pin
    15841797        IWorkflowInfo(self.context).fireTransition('start_clearance')
    15851798        self.flash(_('Clearance process has been started.'))
     
    15981811    def form_fields(self):
    15991812        if self.context.is_postgrad:
    1600             form_fields = grok.AutoFields(IPGStudentClearance).omit('clearance_locked')
    1601         else:
    1602             form_fields = grok.AutoFields(IUGStudentClearance).omit('clearance_locked')
     1813            form_fields = grok.AutoFields(IPGStudentClearance).omit(
     1814                'clearance_locked', 'clr_code')
     1815        else:
     1816            form_fields = grok.AutoFields(IUGStudentClearance).omit(
     1817                'clearance_locked', 'clr_code')
    16031818        return form_fields
    16041819
     
    16271842            return
    16281843        self.flash(_('Clearance form has been saved.'))
    1629         self.redirect(self.url(self.context,'request_clearance'))
     1844        if self.context.clr_code:
     1845            self.redirect(self.url(self.context, 'request_clearance'))
     1846        else:
     1847            # We bypass the request_clearance page if student
     1848            # has been imported in state 'clearance started' and
     1849            # no clr_code was entered before.
     1850            state = IWorkflowState(self.context).getState()
     1851            if state != CLEARANCE:
     1852                # This shouldn't happen, but the application officer
     1853                # might have forgotten to lock the form after changing the state
     1854                self.flash(_('This form cannot be submitted. Wrong state!'))
     1855                return
     1856            IWorkflowInfo(self.context).fireTransition('request_clearance')
     1857            self.flash(_('Clearance has been requested.'))
     1858            self.redirect(self.url(self.context))
    16301859        return
    16311860
     
    16471876            return
    16481877        pin = '%s-%s-%s' % (self.ac_prefix, self.ac_series, self.ac_number)
    1649         if self.context.clr_code != pin:
     1878        if self.context.clr_code and self.context.clr_code != pin:
    16501879            self.flash(_("This isn't your CLR access code."))
    16511880            return
    16521881        state = IWorkflowState(self.context).getState()
    1653         # This shouldn't happen, but the application officer
    1654         # might have forgotten to lock the form after changing the state
    16551882        if state != CLEARANCE:
     1883            # This shouldn't happen, but the application officer
     1884            # might have forgotten to lock the form after changing the state
    16561885            self.flash(_('This form cannot be submitted. Wrong state!'))
    16571886            return
     
    16731902
    16741903    def update(self, SUBMIT=None):
     1904        if not self.context.is_current:
     1905            emit_lock_message(self)
     1906            return
     1907        super(StartSessionPage, self).update()
    16751908        if not self.context.next_session_allowed:
    16761909            self.flash(_("You are not entitled to start session."))
     
    17301963
    17311964    def update(self):
     1965        if not self.context.is_current:
     1966            emit_lock_message(self)
     1967            return
    17321968        if self.context.student.state != PAID:
    17331969            emit_lock_message(self)
     
    17621998
    17631999    def update(self):
     2000        if not self.context.__parent__.is_current:
     2001            emit_lock_message(self)
     2002            return
    17642003        if self.context.student.state != PAID:
    17652004            emit_lock_message(self)
     
    17762015        level_title = translate(self.context.level_title, 'waeup.kofa',
    17772016            target_language=lang)
    1778         return _('Add and remove course tickets of study level ${a}',
     2017        return _('Edit course list of ${a}',
    17792018            mapping = {'a':level_title})
    17802019
     
    17852024            total_credits += val.credits
    17862025        return total_credits
     2026
     2027    @property
     2028    def translated_values(self):
     2029        return translated_values(self)
    17872030
    17882031    @action(_('Add course ticket'))
     
    18472090        ticket = createObject(u'waeup.CourseTicket')
    18482091        course = data['course']
    1849         for name in ['code', 'title', 'credits', 'passmark', 'semester']:
    1850             setattr(ticket, name, getattr(course, name))
    18512092        ticket.automatic = False
     2093        ticket.carry_over = False
    18522094        try:
    1853             self.context.addCourseTicket(ticket)
     2095            self.context.addCourseTicket(ticket, course)
    18542096        except KeyError:
    18552097            self.flash(_('The ticket exists.'))
     
    19272169    grok.template('requestpw')
    19282170    form_fields = grok.AutoFields(IStudentRequestPW).select(
    1929         'firstname','reg_number','email')
     2171        'firstname','number','email')
    19302172    label = _('Request password for first-time login')
    19312173
     
    19482190        return True
    19492191
    1950     @action(_('Get login credentials'), style='primary')
     2192    @action(_('Send login credentials to email address'), style='primary')
    19512193    def get_credentials(self, **data):
    19522194        if not self.captcha_result.is_valid:
     
    19542196            # No need to flash something.
    19552197            return
    1956         reg_number = data.get('reg_number','')
     2198        number = data.get('number','')
    19572199        firstname = data.get('firstname','')
    19582200        cat = getUtility(ICatalog, name='students_catalog')
    19592201        results = list(
    1960             cat.searchResults(reg_number=(reg_number, reg_number)))
     2202            cat.searchResults(reg_number=(number, number)))
     2203        if not results:
     2204            results = list(
     2205                cat.searchResults(matric_number=(number, number)))
    19612206        if results:
    19622207            student = results[0]
     
    19842229        kofa_utils = getUtility(IKofaUtils)
    19852230        password = kofa_utils.genPassword()
    1986         IUserAccount(student).setPassword(password)
     2231        mandate = PasswordMandate()
     2232        mandate.params['password'] = password
     2233        mandate.params['user'] = student
     2234        site = grok.getSite()
     2235        site['mandates'].addMandate(mandate)
    19872236        # Send email with credentials
    1988         login_url = self.url(grok.getSite(), 'login')
     2237        args = {'mandate_id':mandate.mandate_id}
     2238        mandate_url = self.url(site) + '/mandate?%s' % urlencode(args)
     2239        url_info = u'Confirmation link: %s' % mandate_url
    19892240        msg = _('You have successfully requested a password for the')
    19902241        if kofa_utils.sendCredentials(IUserAccount(student),
    1991             password, login_url, msg):
     2242            password, url_info, msg):
    19922243            email_sent = student.email
    19932244        else:
     
    19952246        self._redirect(email=email_sent, password=password,
    19962247            student_id=student.student_id)
     2248        ob_class = self.__implemented__.__name__.replace('waeup.kofa.','')
     2249        self.context.logger.info(
     2250            '%s - %s (%s) - %s' % (ob_class, number, student.student_id, email_sent))
    19972251        return
    19982252
Note: See TracChangeset for help on using the changeset viewer.