Ignore:
Timestamp:
3 Jul 2020, 07:11:31 (4 years ago)
Author:
Henrik Bettermann
Message:

Implement transcript application.

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

Legend:

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

    r16068 r16142  
    2828from kofacustom.iuokada.applicants.interfaces import(
    2929    ICustomApplicant, ICustomUGApplicantEdit, ICustomPGApplicantEdit,
    30     IPUTMEApplicantEdit, ICustomApplicantRefereeReport)
     30    IPUTMEApplicantEdit, ICustomApplicantRefereeReport, ITranscriptApplicant)
    3131
    3232class CustomApplicant(NigeriaApplicant):
    3333
    3434    grok.implements(ICustomApplicant, ICustomUGApplicantEdit,
    35         ICustomPGApplicantEdit, IPUTMEApplicantEdit)
     35        ICustomPGApplicantEdit, IPUTMEApplicantEdit, ITranscriptApplicant)
    3636    grok.provides(ICustomApplicant)
    3737
  • main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/applicants/browser.py

    r16077 r16142  
    5454    ICustomPGApplicant, ICustomUGApplicant, ICustomApplicant,
    5555    ICustomPGApplicantEdit, ICustomUGApplicantEdit,
    56     ICustomApplicantOnlinePayment, ICustomApplicantRefereeReport
     56    ICustomApplicantOnlinePayment, ICustomApplicantRefereeReport,
     57    ITranscriptApplicant
    5758    )
    5859from kofacustom.iuokada.interfaces import MessageFactory as _
     
    120121    'screening_date',)
    121122
     123TRANS_OMIT_FIELDS = ('locked', 'suspended', 'applicant_id',)
     124
     125TRANS_SHORT_OMIT_FIELDS = TRANS_OMIT_FIELDS + (
     126    'date_of_birth',
     127    'sex',
     128    'nationality',
     129    'entry_mode',
     130    'entry_session',
     131    'end_session',
     132    'course_studied',
     133    'course_changed',
     134    'change_level',
     135    )
     136
    122137class CustomApplicantsContainerPage(ApplicantsContainerPage):
    123138    """The standard view for regular applicant containers.
     
    143158    @property
    144159    def form_fields(self):
     160        if self.target is not None and self.target == 'transfull':
     161            form_fields = grok.AutoFields(ITranscriptApplicant)
     162            for field in TRANS_OMIT_FIELDS:
     163                form_fields = form_fields.omit(field)
     164            form_fields['dispatch_address'].custom_widget = BytesDisplayWidget
     165            form_fields['perm_address'].custom_widget = BytesDisplayWidget
     166            return form_fields
     167        if self.target is not None and self.target == 'transshort':
     168            form_fields = grok.AutoFields(ITranscriptApplicant)
     169            for field in TRANS_SHORT_OMIT_FIELDS:
     170                form_fields = form_fields.omit(field)
     171            form_fields['dispatch_address'].custom_widget = BytesDisplayWidget
     172            form_fields['perm_address'].custom_widget = BytesDisplayWidget
     173            return form_fields
    145174        if self.target is not None and self.target.startswith('pg'):
    146175            form_fields = grok.AutoFields(ICustomPGApplicant)
     
    207236    @property
    208237    def form_fields(self):
     238        if self.target is not None and self.target == 'transfull':
     239            form_fields = grok.AutoFields(ITranscriptApplicant)
     240            for field in TRANS_OMIT_FIELDS:
     241                form_fields = form_fields.omit(field)
     242            return form_fields
     243        if self.target is not None and self.target == 'transshort':
     244            form_fields = grok.AutoFields(ITranscriptApplicant)
     245            for field in TRANS_SHORT_OMIT_FIELDS:
     246                form_fields = form_fields.omit(field)
     247            return form_fields
    209248        if self.target is not None and self.target.startswith('pg'):
    210249            form_fields = grok.AutoFields(ICustomPGApplicant)
     
    281320    @property
    282321    def form_fields(self):
     322        if self.target is not None and self.target == 'transfull':
     323            form_fields = grok.AutoFields(ITranscriptApplicant)
     324            for field in TRANS_OMIT_FIELDS:
     325                form_fields = form_fields.omit(field)
     326            return form_fields
     327        if self.target is not None and self.target == 'transshort':
     328            form_fields = grok.AutoFields(ITranscriptApplicant)
     329            for field in TRANS_SHORT_OMIT_FIELDS:
     330                form_fields = form_fields.omit(field)
     331            return form_fields
    283332        if self.target is not None and self.target.startswith('pg'):
    284333            form_fields = grok.AutoFields(ICustomPGApplicantEdit)
  • main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/applicants/interfaces.py

    r16105 r16142  
     1# -*- coding: utf-8 -*-
    12## $Id$
    23##
     
    2021
    2122from zope import schema
     23from zc.sourcefactory.basic import BasicSourceFactory
    2224from waeup.kofa.applicants.interfaces import (
    2325    IApplicantBaseData,
    2426    AppCatCertificateSource, CertificateSource)
    2527from waeup.kofa.schoolgrades import ResultEntryField
     28from waeup.kofa.university.vocabularies import StudyModeSource
    2629from waeup.kofa.interfaces import (
    27     SimpleKofaVocabulary, academic_sessions_vocab, validate_email)
     30    SimpleKofaVocabulary, academic_sessions_vocab, validate_email,
     31    IKofaObject)
    2832from waeup.kofa.schema import FormattedDate, TextLineChoice, PhoneNumber
    29 from waeup.kofa.students.vocabularies import nats_vocab, GenderSource
     33from waeup.kofa.students.vocabularies import (
     34    nats_vocab, GenderSource, StudyLevelSource)
    3035from waeup.kofa.applicants.interfaces import (
    3136    contextual_reg_num_source, IApplicantBaseData, IApplicantRefereeReport)
     
    8893    )
    8994
     95DESTINATION_COST = {
     96    'none': ('To the moon', 1000000000.0, 1),
     97    #'nigeria': ('Nigeria', 2000.0, 1),
     98    #'africa': ('Africa ', 3000.0, 2),
     99    #'eurasia': ('Europe/Asia ', 3000.0, 3),
     100    }
     101
     102class DestinationCostSource(BasicSourceFactory):
     103    """A source that delivers continents and shipment costs.
     104    """
     105    def getValues(self):
     106        sorted_items = sorted(DESTINATION_COST.items(),
     107                              key=lambda element: element[1][2])
     108        return [item[0] for item in sorted_items]
     109
     110    def getTitle(self, value):
     111        return u"%s (₦ %s)" % (
     112            DESTINATION_COST[value][0],
     113            DESTINATION_COST[value][1])
     114
    90115class ICustomUGApplicant(IApplicantBaseData):
    91116    """An undergraduate applicant.
     
    370395    'nysc_number'].order =  ICustomPGApplicant['nysc_year'].order
    371396
    372 class ICustomApplicant(ICustomUGApplicant, ICustomPGApplicant):
     397class ITranscriptApplicant(IKofaObject):
     398    """A transcript applicant.
     399    """
     400
     401    suspended = schema.Bool(
     402        title = _(u'Account suspended'),
     403        default = False,
     404        required = False,
     405        )
     406
     407    locked = schema.Bool(
     408        title = _(u'Form locked'),
     409        default = False,
     410        required = False,
     411        )
     412
     413    applicant_id = schema.TextLine(
     414        title = _(u'Transcript Application Id'),
     415        required = False,
     416        readonly = False,
     417        )
     418
     419    #student_id = schema.TextLine(
     420    #    title = _(u'Kofa Student Id'),
     421    #    required = False,
     422    #    readonly = False,
     423    #    )
     424
     425    #reg_number = schema.TextLine(
     426    #    title = _(u'Registration Number'),
     427    #    readonly = False,
     428    #    required = False,
     429    #    )
     430
     431    matric_number = schema.TextLine(
     432        title = _(u'Matriculation Number'),
     433        readonly = False,
     434        required = True,
     435        )
     436
     437    firstname = schema.TextLine(
     438        title = _(u'First Name'),
     439        required = True,
     440        )
     441
     442    middlename = schema.TextLine(
     443        title = _(u'Middle Name'),
     444        required = False,
     445        )
     446
     447    lastname = schema.TextLine(
     448        title = _(u'Last Name (Surname)'),
     449        required = True,
     450        )
     451
     452    date_of_birth = FormattedDate(
     453        title = _(u'Date of Birth'),
     454        required = False,
     455        #date_format = u'%d/%m/%Y', # Use grok-instance-wide default
     456        show_year = True,
     457        )
     458
     459    sex = schema.Choice(
     460        title = _(u'Gender'),
     461        source = GenderSource(),
     462        required = True,
     463        )
     464
     465    nationality = schema.Choice(
     466        vocabulary = nats_vocab,
     467        title = _(u'Nationality'),
     468        required = False,
     469        )
     470
     471    email = schema.ASCIILine(
     472        title = _(u'Email Address'),
     473        required = True,
     474        constraint=validate_email,
     475        )
     476
     477    phone = PhoneNumber(
     478        title = _(u'Phone'),
     479        description = u'',
     480        required = False,
     481        )
     482
     483    perm_address = schema.Text(
     484        title = _(u'Current Local Address'),
     485        required = False,
     486        readonly = False,
     487        )
     488
     489    dispatch_address = schema.Text(
     490        title = _(u'Dispatch Addresses'),
     491        description = u'Addresses to which transcripts should be posted. '
     492                       'Addresses must involve same courier charges.',
     493        required = False,
     494        readonly = False,
     495        )
     496
     497    charge = schema.Choice(
     498        title = _(u'Courier Charge'),
     499        source = DestinationCostSource(),
     500        required = True,
     501        )
     502
     503    entry_mode = schema.Choice(
     504        title = _(u'Entry Mode'),
     505        source = StudyModeSource(),
     506        required = False,
     507        readonly = False,
     508        )
     509
     510    entry_session = schema.Choice(
     511        title = _(u'Entry Session'),
     512        source = academic_sessions_vocab,
     513        required = False,
     514        readonly = False,
     515        )
     516
     517    end_session = schema.Choice(
     518        title = _(u'End Session'),
     519        source = academic_sessions_vocab,
     520        required = False,
     521        readonly = False,
     522        )
     523
     524    course_studied = schema.Choice(
     525        title = _(u'Course of Study / Degree'),
     526        source = CertificateSource(),
     527        required = False,
     528        readonly = False,
     529        )
     530
     531    course_changed = schema.Choice(
     532        title = _(u'Change of Study Course'),
     533        description = u'If yes, select previous course of study.',
     534        source = CertificateSource(),
     535        readonly = False,
     536        required = False,
     537        )
     538
     539    change_level = schema.Choice(
     540        title = _(u'Change Level'),
     541        description = u'If yes, select level at which you changed course of study.',
     542        source = StudyLevelSource(),
     543        required = False,
     544        readonly = False,
     545        )
     546
     547    no_copies = schema.Choice(
     548        title = _(u'Number of Copies'),
     549        description = u'Must correspond with the number of dispatch addresses above.',
     550        values=[1, 2, 3, 4],
     551        required = False,
     552        readonly = False,
     553        default = 1,
     554        )
     555
     556class ICustomApplicant(ICustomUGApplicant, ICustomPGApplicant,
     557    ITranscriptApplicant):
    373558    """An interface for both types of applicants.
    374559
  • main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/applicants/utils.py

    r16070 r16142  
    1919"""
    2020
     21import grok
     22from time import time
    2123from kofacustom.nigeria.applicants.utils import NigeriaApplicantsUtils
    2224from waeup.kofa.applicants.workflow import (INITIALIZED,
    2325    STARTED, PAID, ADMITTED, NOT_ADMITTED, SUBMITTED, CREATED)
     26from kofacustom.iuokada.applicants.interfaces import DESTINATION_COST
    2427from kofacustom.iuokada.interfaces import MessageFactory as _
    2528
     
    5558        'pg': ['Postgraduate Programmes', 'PG'],
    5659        'ug': ['Undergraduate Programmes', 'UG'],
     60        'transfull': ['Transcript Application (without student record)', 'TRF'],
     61        'transshort': ['Transcript Application (with student record)', 'TRS'],
    5762        }
    5863
     
    97102            title = "NA / %s (%s)" % (value.title, value.code)
    98103        return title
     104
     105    def setPaymentDetails(self, container, payment, applicant):
     106        """Set the payment data of an applicant.
     107        In contrast to its `StudentsUtils` counterpart, the payment ticket
     108        must exist and is an argument of this method.
     109        """
     110        timestamp = ("%d" % int(time()*10000))[1:]
     111        session = str(container.year)
     112        try:
     113            session_config = grok.getSite()['configuration'][session]
     114        except KeyError:
     115            return _(u'Session configuration object is not available.')
     116        payment.p_id = "p%s" % timestamp
     117        payment.p_item = container.title
     118        payment.p_session = container.year
     119        payment.amount_auth = 0.0
     120        if applicant.special:
     121            if applicant.special_application:
     122                fee_name = applicant.special_application + '_fee'
     123                payment.amount_auth = getattr(session_config, fee_name, None)
     124                if payment.amount_auth in (0.0, None):
     125                    return _('Amount could not be determined.')
     126                payment.p_category = applicant.special_application
     127            return
     128        elif applicant.container_code.startswith('trans'):
     129            cost = DESTINATION_COST[applicant.charge][1]
     130            payment.amount_auth = applicant.no_copies * cost
     131            payment.p_category = 'transcript'
     132            return
     133        else:
     134            payment.p_category = 'application'
     135            container_fee = container.application_fee
     136            if not container_fee:
     137                return _('Amount could not be determined.')
     138            payment.amount_auth = container_fee
     139        return
Note: See TracChangeset for help on using the changeset viewer.