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

Merge changes from trunk r9171:9207.

Location:
main/waeup.kofa/branches/uli-async-update
Files:
8 edited

Legend:

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

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

    r9169 r9208  
    361361        return
    362362
     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
    363385class StudentBaseManageFormPage(KofaEditFormPage):
    364386    """ View to manage student base data
     
    12341256        if error is not None:
    12351257            self.flash(error)
    1236             if 'Would you like' in error:
     1258            if 'previous session' in error:
    12371259                self.redirect(self.url(self.context) + '/@@addpp')
    12381260                return
     
    14091431    buttonname = _('Create bed ticket')
    14101432    notice = ''
     1433    with_ac = True
    14111434
    14121435    def update(self, SUBMIT=None):
     
    14491472            self.redirect(self.url(self.context))
    14501473            return
    1451         self.ac_series = self.request.form.get('ac_series', None)
    1452         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)
    14531477        if SUBMIT is None:
    14541478            return
    1455         pin = '%s-%s-%s' % (self.ac_prefix, self.ac_series, self.ac_number)
    1456         code = get_access_code(pin)
    1457         if not code:
    1458             self.flash(_('Activation code is invalid.'))
    1459             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
    14601485        # Search and book bed
    14611486        cat = queryUtility(ICatalog, name='beds_catalog', default=None)
     
    14631488            owner=(student.student_id,student.student_id))
    14641489        if len(entries):
    1465             # If bed space has bee manually allocated use this bed
     1490            # If bed space has been manually allocated use this bed
    14661491            bed = [entry for entry in entries][0]
    14671492        else:
     
    14791504                    mapping = {'a':acc_details['bt']}))
    14801505                return
    1481         # Mark pin as used (this also fires a pin related transition)
    1482         if code.state == USED:
    1483             self.flash(_('Activation code has already been used.'))
    1484             return
    1485         else:
    1486             comment = _(u'invalidated')
    1487             # Here we know that the ac is in state initialized so we do not
    1488             # expect an exception, but the owner might be different
    1489             if not invalidate_accesscode(
    1490                 pin,comment,self.context.student.student_id):
    1491                 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.'))
    14921510                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
    14931519        # Create bed ticket
    14941520        bedticket = createObject(u'waeup.BedTicket')
    1495         bedticket.booking_code = pin
     1521        if self.with_ac:
     1522            bedticket.booking_code = pin
    14961523        bedticket.booking_session = acc_details['booking_session']
    14971524        bedticket.bed_type = acc_details['bt']
    14981525        bedticket.bed = bed
    14991526        hall_title = bed.__parent__.hostel_name
    1500         coordinates = bed.getBedCoordinates()[1:]
     1527        coordinates = bed.coordinates[1:]
    15011528        block, room_nr, bed_nr = coordinates
    15021529        bc = _('${a}, Block ${b}, Room ${c}, Bed ${d} (${e})', mapping = {
     
    15211548    grok.require('waeup.handleAccommodation')
    15221549    form_fields = grok.AutoFields(IBedTicket)
     1550    form_fields['booking_date'].custom_widget = FriendlyDatetimeDisplayWidget('le')
    15231551    pnav = 4
    15241552
     
    15471575    def label(self):
    15481576        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
    1549         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'),
    15501581            'waeup.kofa', target_language=portal_language) \
    1551             + ' %s' % self.context.bed_coordinates
     1582            + ' %s' % self.context.getSessionString()
    15521583
    15531584    def render(self):
     
    16141645        self.context.bed = new_bed
    16151646        hall_title = new_bed.__parent__.hostel_name
    1616         coordinates = new_bed.getBedCoordinates()[1:]
     1647        coordinates = new_bed.coordinates[1:]
    16171648        block, room_nr, bed_nr = coordinates
    16181649        bc = _('${a}, Block ${b}, Room ${c}, Bed ${d} (${e})', mapping = {
  • main/waeup.kofa/branches/uli-async-update/src/waeup/kofa/students/browser_templates/basepage.pt

    r7811 r9208  
    1818          <tal:password replace="view/hasPassword" />
    1919      </td>
    20     <tr>
     20    </tr>
    2121    <tal:files content="structure provider:files" />
    2222  </tbody>
  • main/waeup.kofa/branches/uli-async-update/src/waeup/kofa/students/interfaces.py

    r9169 r9208  
    156156    current_level = Attribute('The current level of the student')
    157157    current_mode = Attribute('The current mode of the student')
     158    current_verdict = Attribute('The current verdict of the student')
    158159    fullname = Attribute('All name parts separated by hyphens')
    159160    display_fullname = Attribute('The fullname of an applicant')
  • main/waeup.kofa/branches/uli-async-update/src/waeup/kofa/students/student.py

    r9169 r9208  
    134134        level = getattr(
    135135            self.get('studycourse', None), 'current_level', None)
     136        return level
     137
     138    @property
     139    def current_verdict(self):
     140        level = getattr(
     141            self.get('studycourse', None), 'current_verdict', None)
    136142        return level
    137143
  • main/waeup.kofa/branches/uli-async-update/src/waeup/kofa/students/tests/test_browser.py

    r9169 r9208  
    403403
    404404    layer = FunctionalLayer
     405
     406    def test_student_properties(self):
     407        self.student['studycourse'].current_level = 100
     408        self.assertEqual(self.student.current_level, 100)
     409        self.student['studycourse'].current_session = 2011
     410        self.assertEqual(self.student.current_session, 2011)
     411        self.student['studycourse'].current_verdict = 'A'
     412        self.assertEqual(self.student.current_verdict, 'A')
     413        return
    405414
    406415    def test_basic_auth(self):
     
    11831192        self.assertTrue(
    11841193            'You logged in.' in self.browser.contents)
    1185         # Student can upload a passport picture
     1194        # Admitted student can upload a passport picture
    11861195        self.browser.open(self.student_path + '/change_portrait')
    11871196        ctrl = self.browser.getControl(name='passportuploadedit')
     
    11941203            '<img align="middle" height="125px" src="passport.jpg" />'
    11951204            in self.browser.contents)
     1205        # Students can open admission letter
     1206        self.browser.getLink("Base Data").click()
     1207        self.browser.getLink("Download admission letter").click()
     1208        self.assertEqual(self.browser.headers['Status'], '200 Ok')
     1209        self.assertEqual(self.browser.headers['Content-Type'], 'application/pdf')
    11961210        # Student can view the clearance data
     1211        self.browser.open(self.student_path)
    11971212        self.browser.getLink("Clearance Data").click()
    11981213        # Student can't open clearance edit form before starting clearance
     
    15841599
    15851600    def test_student_previous_payments(self):
     1601        configuration = createObject('waeup.SessionConfiguration')
     1602        configuration.academic_session = 2000
     1603        configuration.clearance_fee = 3456.0
     1604        configuration.booking_fee = 123.4
     1605        self.student['studycourse'].entry_session = 2002
     1606        self.app['configuration'].addSessionConfiguration(configuration)
     1607        configuration2 = createObject('waeup.SessionConfiguration')
     1608        configuration2.academic_session = 2003
     1609        configuration2.clearance_fee = 3456.0
     1610        configuration2.booking_fee = 123.4
     1611        self.student['studycourse'].entry_session = 2002
     1612        self.app['configuration'].addSessionConfiguration(configuration2)
    15861613        # Login
    15871614        self.browser.open(self.login_path)
     
    16061633        # Previous session payment form is provided
    16071634        self.browser.getControl(name="form.p_category").value = ['schoolfee']
     1635        self.browser.getControl(name="form.p_session").value = ['2000']
     1636        self.browser.getControl(name="form.p_level").value = ['300']
     1637        self.browser.getControl("Create ticket").click()
     1638        self.assertMatches('...The previous session must not fall below...',
     1639                           self.browser.contents)
     1640        self.browser.getControl(name="form.p_category").value = ['schoolfee']
    16081641        self.browser.getControl(name="form.p_session").value = ['2004']
     1642        self.browser.getControl(name="form.p_level").value = ['300']
     1643        self.browser.getControl("Create ticket").click()
     1644        self.assertMatches('...This is not a previous session...',
     1645                           self.browser.contents)
     1646        self.browser.getControl(name="form.p_category").value = ['schoolfee']
     1647        self.browser.getControl(name="form.p_session").value = ['2003']
    16091648        self.browser.getControl(name="form.p_level").value = ['300']
    16101649        self.browser.getControl("Create ticket").click()
     
    16191658
    16201659        # Payment session is properly set
    1621         self.assertEqual(self.student['payments'][value].p_session, 2004)
     1660        self.assertEqual(self.student['payments'][value].p_session, 2003)
    16221661        self.assertEqual(self.student['payments'][value].p_level, 300)
    16231662
     
    19541993        self.browser.getControl(name="form.identifier").value = '123'
    19551994        self.browser.getControl(name="form.email").value = 'aa@aa.ng'
    1956         self.browser.getControl("Get login credentials").click()
     1995        self.browser.getControl("Send login credentials").click()
    19571996        self.assertTrue('An email with' in self.browser.contents)
    19581997
  • main/waeup.kofa/branches/uli-async-update/src/waeup/kofa/students/utils.py

    r9169 r9208  
    138138        f_label = formatted_label(size=12) % _('Study Course')
    139139        f_label = Paragraph(f_label, style["Normal"])
    140         f_text = formatted_text(studentview.context.certcode, size=12)
     140        f_text = formatted_text(
     141            studentview.context['studycourse'].certificate.longtitle(), size=12)
     142        f_text = Paragraph(f_text, style["Normal"])
     143        data_right.append([f_label,f_text])
     144
     145        f_label = formatted_label(size=12) % _('Department')
     146        f_label = Paragraph(f_label, style["Normal"])
     147        f_text = formatted_text(
     148            studentview.context[
     149            'studycourse'].certificate.__parent__.__parent__.longtitle(),
     150            size=12)
     151        f_text = Paragraph(f_text, style["Normal"])
     152        data_right.append([f_label,f_text])
     153
     154        f_label = formatted_label(size=12) % _('Faculty')
     155        f_label = Paragraph(f_label, style["Normal"])
     156        f_text = formatted_text(
     157            studentview.context[
     158            'studycourse'].certificate.__parent__.__parent__.__parent__.longtitle(),
     159            size=12)
    141160        f_text = Paragraph(f_text, style["Normal"])
    142161        data_right.append([f_label,f_text])
     
    309328                return _('Study course data are incomplete.'), None
    310329            if previous_session:
     330                if previous_session < student['studycourse'].entry_session:
     331                    return _('The previous session must not fall below '
     332                             'your entry session.'), None
     333                if previous_session > student['studycourse'].current_session - 1:
     334                    return _('This is not a previous session.'), None
    311335                if previous_level == 100:
    312336                    amount = getattr(certificate, 'school_fee_1', 0.0)
     
    328352                    amount = getattr(certificate, 'school_fee_2', 0.0)
    329353        elif category == 'clearance':
    330             p_item = student['studycourse'].certificate.code
     354            try:
     355                p_item = student['studycourse'].certificate.code
     356            except (AttributeError, TypeError):
     357                return _('Study course data are incomplete.'), None
    331358            amount = academic_session.clearance_fee
    332359        elif category == 'bed_allocation':
     
    371398        entry_session = studycourse.entry_session
    372399        current_level = studycourse.current_level
    373         if not (entry_session and current_level and certificate):
    374             return
     400        if None in (entry_session, current_level, certificate):
     401            return d
    375402        end_level = certificate.end_level
    376403        if current_level == 10:
     
    398425        return available_beds[0]
    399426
     427    def renderPDFAdmissionLetter(self, view, student=None):
     428        """Render pdf admission letter.
     429        """
     430        # XXX: we have to fix the import problems here.
     431        from waeup.kofa.browser.interfaces import IPDFCreator
     432        from waeup.kofa.browser.pdf import format_html, NOTE_STYLE
     433        if student is None:
     434            return
     435        style = getSampleStyleSheet()
     436        creator = getUtility(IPDFCreator)
     437        data = []
     438        doc_title = view.label
     439        author = '%s (%s)' % (view.request.principal.title,
     440                              view.request.principal.id)
     441        footer_text = view.label
     442        if getattr(student, 'student_id', None) is not None:
     443            footer_text = "%s - %s - " % (student.student_id, footer_text)
     444
     445        # Admission text
     446        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
     447        inst_name = grok.getSite()['configuration'].name
     448        text = trans(_(
     449            'This is to inform you that you have been provisionally'
     450            ' admitted into ${a} as follows:', mapping = {'a': inst_name}),
     451            portal_language)
     452        html = format_html(text)
     453        data.append(Paragraph(html, NOTE_STYLE))
     454        data.append(Spacer(1, 20))
     455
     456        # Student data
     457        data.append(render_student_data(view))
     458
     459        # Insert history
     460        data.append(Spacer(1, 20))
     461        datelist = student.history.messages[0].split()[0].split('-')
     462        creation_date = u'%s/%s/%s' % (datelist[2], datelist[1], datelist[0])
     463        text = trans(_(
     464            'Your Kofa student record was created on ${a}.',
     465            mapping = {'a': creation_date}),
     466            portal_language)
     467        html = format_html(text)
     468        data.append(Paragraph(html, NOTE_STYLE))
     469
     470        # Create pdf stream
     471        view.response.setHeader(
     472            'Content-Type', 'application/pdf')
     473        pdf_stream = creator.create_pdf(
     474            data, None, doc_title, author=author, footer=footer_text,
     475            note=None)
     476        return pdf_stream
     477
    400478    def renderPDF(self, view, filename='slip.pdf', student=None,
    401479                  studentview=None, tableheader=None, tabledata=None,
     
    428506
    429507        # Insert widgets
    430         data.append(Paragraph(view.title, style["Heading3"]))
    431         portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
    432         separators = getattr(self, 'SEPARATORS_DICT', {})
    433         table = creator.getWidgetsTable(
    434             view.form_fields, view.context, None, lang=portal_language,
    435             separators=separators)
    436         data.append(table)
     508        if view.form_fields:
     509            data.append(Paragraph(view.title, style["Heading3"]))
     510            portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
     511            separators = getattr(self, 'SEPARATORS_DICT', {})
     512            table = creator.getWidgetsTable(
     513                view.form_fields, view.context, None, lang=portal_language,
     514                separators=separators)
     515            data.append(table)
    437516
    438517        # Insert scanned docs
  • main/waeup.kofa/branches/uli-async-update/src/waeup/kofa/students/viewlets.py

    r9169 r9208  
    150150
    151151class ContactActionButton(ManageActionButton):
    152     grok.order(4)
     152    grok.order(5)
    153153    grok.context(IStudent)
    154154    grok.view(StudentBaseDisplayFormPage)
     
    166166    target = 'manage_base'
    167167
     168class AdmissionSlipActionButton(ManageActionButton):
     169    grok.order(4)
     170    grok.context(IStudent)
     171    grok.view(StudentBaseDisplayFormPage)
     172    grok.require('waeup.viewStudent')
     173    icon = 'actionicon_pdf.png'
     174    text = _('Download admission letter')
     175    target = 'admission_slip.pdf'
     176
    168177class StudentTransfernButton(ManageActionButton):
    169     grok.order(5)
     178    grok.order(6)
    170179    grok.context(IStudent)
    171180    grok.view(StudentBaseDisplayFormPage)
     
    176185
    177186class StudentDeactivateActionButton(ManageActionButton):
    178     grok.order(6)
     187    grok.order(7)
    179188    grok.context(IStudent)
    180189    grok.view(StudentBaseDisplayFormPage)
     
    196205
    197206class StudentActivateActionButton(ManageActionButton):
    198     grok.order(6)
     207    grok.order(7)
    199208    grok.context(IStudent)
    200209    grok.view(StudentBaseDisplayFormPage)
     
    624633    @property
    625634    def targets(self):
    626         student_url = self.view.application_url() + (
    627             '/students/%s' % self.request.principal.id)
    628         #app_slip = getUtility(IExtFileStore).getFileByContext(
    629         #    self.context.student, 'application_slip')
     635        student = grok.getSite()['students'][self.request.principal.id]
     636        student_url = self.view.url(student)
     637        app_slip = getUtility(IExtFileStore).getFileByContext(
     638            student, 'application_slip')
    630639        targets = []
    631         #if app_slip:
    632         #    targets = [{'url':student_url + '/application_slip', 'title':'Application Slip'},]
     640        if app_slip:
     641            targets = [{'url':student_url + '/application_slip', 'title':'Application Slip'},]
    633642        targets += [
    634643            {'url':student_url, 'title':'Base Data'},
Note: See TracChangeset for help on using the changeset viewer.