Ignore:
Timestamp:
23 Jul 2022, 08:08:45 (2 years ago)
Author:
Henrik Bettermann
Message:

Implement transcript application (fee calculation not yet configured).

Location:
main/kofacustom.edocons/trunk/src/kofacustom/edocons/applicants
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • main/kofacustom.edocons/trunk/src/kofacustom/edocons/applicants/applicant.py

    r16639 r17029  
    2323from kofacustom.nigeria.applicants.applicant import NigeriaApplicant
    2424from kofacustom.edocons.applicants.interfaces import(
    25     ICustomApplicant, ICustomUGApplicantEdit, ICustomPGApplicantEdit, IPUTMEApplicantEdit)
     25    ICustomApplicant, ICustomUGApplicantEdit, ICustomPGApplicantEdit,
     26    IPUTMEApplicantEdit, ITranscriptApplicant)
    2627
    2728class CustomApplicant(NigeriaApplicant):
    2829
    2930    grok.implements(ICustomApplicant, ICustomUGApplicantEdit,
    30         ICustomPGApplicantEdit, IPUTMEApplicantEdit)
     31        ICustomPGApplicantEdit, IPUTMEApplicantEdit,
     32        ITranscriptApplicant)
    3133    grok.provides(ICustomApplicant)
    3234
  • main/kofacustom.edocons/trunk/src/kofacustom/edocons/applicants/browser.py

    r16853 r17029  
    5454    ICustomPGApplicant, ICustomUGApplicant, ICustomApplicant,
    5555    ICustomPGApplicantEdit, ICustomUGApplicantEdit,
    56     ICustomApplicantOnlinePayment,
     56    ICustomApplicantOnlinePayment, ITranscriptApplicant,
    5757    )
    5858from kofacustom.nigeria.interfaces import MessageFactory as _
     
    9494    'aggregate')
    9595
     96TSC_OMIT_FIELDS = ('locked', 'suspended',
     97    )
     98   
     99
     100TSC_OMIT_EDIT_FIELDS = TSC_OMIT_FIELDS + (
     101    'applicant_id',
     102    'proc_date',
     103    )
     104
     105TSC_OMIT_MANAGE_FIELDS = TSC_OMIT_FIELDS + (
     106    'applicant_id',)     
     107
    96108class CustomApplicantDisplayFormPage(NigeriaApplicantDisplayFormPage):
    97109    """A display view for applicant data.
     
    104116            for field in PG_OMIT_DISPLAY_FIELDS:
    105117                form_fields = form_fields.omit(field)
     118        elif self.target is not None and self.target.startswith('tsc'):
     119            form_fields = grok.AutoFields(ITranscriptApplicant)
     120            for field in TSC_OMIT_FIELDS:
     121                form_fields = form_fields.omit(field)           
     122            return form_fields
    106123        else:
    107124            form_fields = grok.AutoFields(ICustomUGApplicant)
    108125            for field in UG_OMIT_DISPLAY_FIELDS:
    109126                form_fields = form_fields.omit(field)
     127            form_fields['notice'].custom_widget = BytesDisplayWidget
    110128        #form_fields['perm_address'].custom_widget = BytesDisplayWidget
    111         form_fields['notice'].custom_widget = BytesDisplayWidget
    112129        if not getattr(self.context, 'student_id'):
    113130            form_fields = form_fields.omit('student_id')
     
    134151            for field in PG_OMIT_PDF_FIELDS:
    135152                form_fields = form_fields.omit(field)
     153        elif self.target is not None and self.target.startswith('tsc'):
     154            form_fields = grok.AutoFields(ITranscriptApplicant)
     155            for field in TSC_OMIT_FIELDS:
     156                form_fields = form_fields.omit(field)             
     157            return form_fields
    136158        else:
    137159            form_fields = grok.AutoFields(ICustomUGApplicant)
     
    164186            for field in PG_OMIT_MANAGE_FIELDS:
    165187                form_fields = form_fields.omit(field)
     188        elif self.target is not None and self.target.startswith('tsc'):
     189            form_fields = grok.AutoFields(ITranscriptApplicant)
     190            for field in TSC_OMIT_MANAGE_FIELDS:
     191                form_fields = form_fields.omit(field)             
     192            return form_fields
    166193        else:
    167194            form_fields = grok.AutoFields(ICustomUGApplicant)
     
    185212            for field in PG_OMIT_EDIT_FIELDS:
    186213                form_fields = form_fields.omit(field)
     214        elif self.target is not None and self.target.startswith('tsc'):
     215            form_fields = grok.AutoFields(ITranscriptApplicant)
     216            for field in TSC_OMIT_EDIT_FIELDS:
     217                form_fields = form_fields.omit(field)           
     218            return form_fields
    187219        else:
    188220            form_fields = grok.AutoFields(ICustomUGApplicantEdit)
  • main/kofacustom.edocons/trunk/src/kofacustom/edocons/applicants/interfaces.py

    r16883 r17029  
     1# -*- coding: utf-8 -*-
    12## $Id$
    23##
     
    2021
    2122from zope import schema
     23from zope.interface import invariant, Invalid
     24from zope.component import getUtility
     25from zope.catalog.interfaces import ICatalog
     26from zc.sourcefactory.basic import BasicSourceFactory
     27from waeup.kofa.university.vocabularies import StudyModeSource
    2228from waeup.kofa.applicants.interfaces import (
    2329    IApplicantBaseData,
     
    2531from waeup.kofa.schoolgrades import ResultEntryField
    2632from waeup.kofa.interfaces import (
    27     SimpleKofaVocabulary, academic_sessions_vocab, validate_email)
     33    SimpleKofaVocabulary, academic_sessions_vocab, validate_email,
     34    IKofaObject)
    2835from waeup.kofa.schema import FormattedDate, TextLineChoice, PhoneNumber
    2936from waeup.kofa.students.vocabularies import nats_vocab, GenderSource
     
    5461    )
    5562
     63DESTINATION_COST = {
     64    #'none': ('To the moon', 1000000000.0, 1),
     65    'nigeria': ('Within Nigeria', 20000.0, 1),
     66    'africa': ('Within Africa ', 30000.0, 2),
     67    'inter': ('International', 35000.0, 3),
     68    'cert_nigeria': ('Certified Copy - Within Nigeria', 13000.0, 4),
     69    'cert_africa': ('Certified Copy - Within Africa', 23000.0, 5),
     70    'cert_inter': ('Certified Copy - International', 28000.0, 6),
     71    }
     72
     73class DestinationCostSource(BasicSourceFactory):
     74    """A source that delivers continents and shipment costs.
     75    """
     76    def getValues(self):
     77        sorted_items = sorted(DESTINATION_COST.items(),
     78                              key=lambda element: element[1][2])
     79        return [item[0] for item in sorted_items]
     80
     81    def getToken(self, value):
     82        return value
     83
     84    def getTitle(self, value):
     85        return u"%s (₦ %s)" % (
     86            DESTINATION_COST[value][0],
     87            DESTINATION_COST[value][1])
     88
     89class OrderSource(BasicSourceFactory):
     90    """
     91    """
     92    def getValues(self):
     93        return ['o', 'c']
     94
     95    def getToken(self, value):
     96        return value
     97
     98    def getTitle(self, value):
     99        if value == 'o':
     100            return _('Original')
     101        if value == 'c':
     102            return _('Certified True Copy')
     103
     104class TranscriptCertificateSource(CertificateSource):
     105    """Include Department and Faculty in Title.
     106    """
     107    def getValues(self, context):
     108        catalog = getUtility(ICatalog, name='certificates_catalog')
     109        resultset = catalog.searchResults(code=(None, None))
     110        resultlist = sorted(resultset, key=lambda
     111            value: value.__parent__.__parent__.__parent__.code +
     112            value.__parent__.__parent__.code +
     113            value.code)
     114        return resultlist
     115
     116    def getTitle(self, context, value):
     117        """
     118        """
     119        try: title = "%s / %s / %s (%s)" % (
     120            value.__parent__.__parent__.__parent__.title,
     121            value.__parent__.__parent__.title,
     122            value.title, value.code)
     123        except AttributeError:
     124            title = "NA / %s (%s)" % (value.title, value.code)
     125        return title
     126
    56127class ICustomUGApplicant(INigeriaUGApplicant):
    57128    """An undergraduate applicant.
     
    308379    """
    309380
    310 
    311 class ICustomApplicant(ICustomUGApplicant, ICustomPGApplicant):
     381class ITranscriptApplicant(IKofaObject):
     382    """A transcript applicant.
     383    """
     384
     385    suspended = schema.Bool(
     386        title = _(u'Account suspended'),
     387        default = False,
     388        required = False,
     389        )
     390
     391    locked = schema.Bool(
     392        title = _(u'Form locked'),
     393        default = False,
     394        required = False,
     395        )
     396
     397    applicant_id = schema.TextLine(
     398        title = _(u'Transcript Application Id'),
     399        required = False,
     400        readonly = False,
     401        )
     402
     403    student_id = schema.TextLine(
     404        title = _(u'Kofa Student Id'),
     405        required = False,
     406        readonly = False,
     407        )
     408
     409    matric_number = schema.TextLine(
     410        title = _(u'Matriculation Number'),
     411        readonly = False,
     412        required = True,
     413        )
     414
     415    firstname = schema.TextLine(
     416        title = _(u'First Name in School'),
     417        required = True,
     418        )
     419
     420    middlename = schema.TextLine(
     421        title = _(u'Middle Name in School'),
     422        required = False,
     423        )
     424
     425    lastname = schema.TextLine(
     426        title = _(u'Surname in School'),
     427        required = True,
     428        )
     429
     430    date_of_birth = FormattedDate(
     431        title = _(u'Date of Birth'),
     432        required = False,
     433        #date_format = u'%d/%m/%Y', # Use grok-instance-wide default
     434        show_year = True,
     435        )
     436
     437    sex = schema.Choice(
     438        title = _(u'Gender'),
     439        source = GenderSource(),
     440        required = True,
     441        )
     442
     443    #nationality = schema.Choice(
     444    #    vocabulary = nats_vocab,
     445    #    title = _(u'Nationality'),
     446    #    required = False,
     447    #    )
     448
     449    email = schema.ASCIILine(
     450        title = _(u'Email Address'),
     451        required = True,
     452        constraint=validate_email,
     453        )
     454
     455    phone = PhoneNumber(
     456        title = _(u'Phone'),
     457        description = u'',
     458        required = False,
     459        )
     460
     461    #perm_address = schema.Text(
     462    #    title = _(u'Current Local Address'),
     463    #    required = False,
     464    #    readonly = False,
     465    #    )
     466
     467    collected = schema.Bool(
     468        title = _(u'Have you collected transcript before?'),
     469        default = False,
     470        required = False,
     471        )
     472
     473    entry_session = schema.Choice(
     474        title = _(u'Academic Session of Entry'),
     475        source = academic_sessions_vocab,
     476        required = False,
     477        readonly = False,
     478        )
     479
     480    end_session = schema.Choice(
     481        title = _(u'Academic Session of Graduation'),
     482        source = academic_sessions_vocab,
     483        required = False,
     484        readonly = False,
     485        )
     486
     487    entry_mode = schema.Choice(
     488        title = _(u'Mode of Entry'),
     489        source = StudyModeSource(),
     490        required = False,
     491        readonly = False,
     492        )
     493
     494    course_studied = schema.Choice(
     495        title = _(u'Course of Study'),
     496        source = TranscriptCertificateSource(),
     497        description = u'Faculty / Department / Course',
     498        required = True,
     499        readonly = False,
     500        )
     501
     502    course_changed = schema.Choice(
     503        title = _(u'Change of Study Course / Transfer'),
     504        description = u'If yes, select previous course of study.',
     505        source = TranscriptCertificateSource(),
     506        readonly = False,
     507        required = False,
     508        )
     509
     510    spillover_level = schema.Choice(
     511        title = _(u'Spill-over'),
     512        description = u'Any spill-over? If yes, select session of spill-over.',
     513        source = academic_sessions_vocab,
     514        required = False,
     515        readonly = False,
     516        )
     517
     518    purpose = schema.TextLine(
     519        title = _(u'Transcript Purpose'),
     520        required = False,
     521        )
     522
     523    order = schema.Choice(
     524        source = OrderSource(),
     525        title = _(u'Type of Order'),
     526        required = True,
     527        )
     528
     529    dispatch_address = schema.Text(
     530        title = _(u'Recipient Body'),
     531        description = u'Addresses (including email address and phone number) '
     532                       'to which transcripts should be posted. '
     533                       'All addresses must involve same courier charges.',
     534        required = True,
     535        readonly = False,
     536        )
     537
     538    charge = schema.Choice(
     539        title = _(u'Transcript Charge'),
     540        source = DestinationCostSource(),
     541        required = True,
     542        readonly = False,
     543        )
     544
     545    no_copies = schema.Choice(
     546        title = _(u'Number of Copies'),
     547        description = u'Must correspond with the number of dispatch addresses above.',
     548        values=[1, 2, 3, 4],
     549        required = False,
     550        readonly = False,
     551        default = 1,
     552        )
     553
     554    courier_tno = schema.TextLine(
     555        title = _(u'Courier Tracking Number'),
     556        required = False,
     557        )
     558
     559    proc_date = FormattedDate(
     560        title = _(u'Processing Date'),
     561        required = False,
     562        #date_format = u'%d/%m/%Y', # Use grok-instance-wide default
     563        show_year = True,
     564        )
     565
     566    @invariant
     567    def type_of_order(applicant):
     568        if not applicant.collected and applicant.order != 'o':
     569            raise Invalid(_("If you haven't collected transcript before, type of order must be 'original'."))
     570        if applicant.order == 'o' and applicant.charge.startswith('cert_'):
     571            raise Invalid(_("You've selected the wrong transcript charge."))
     572        if applicant.order == 'c' and not applicant.charge.startswith('cert_'):
     573            raise Invalid(_("You've selected the wrong transcript charge."))
     574
     575
     576class ICustomApplicant(ICustomUGApplicant, ICustomPGApplicant,
     577                       ITranscriptApplicant):
    312578    """An interface for both types of applicants.
    313579
  • main/kofacustom.edocons/trunk/src/kofacustom/edocons/applicants/utils.py

    r16767 r17029  
    4747        'form.cbt_score': _(u'CBT Data'),
    4848        }
     49
     50    APP_TYPES_DICT = {
     51        'app': ['General Studies', 'APP'],
     52        'tsc': ['Transcript', 'TRF'],
     53        }
Note: See TracChangeset for help on using the changeset viewer.