source: main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/applicants/interfaces.py @ 16233

Last change on this file since 16233 was 16165, checked in by Henrik Bettermann, 4 years ago

Configure transcript applications.

  • Property svn:keywords set to Id
File size: 22.4 KB
Line 
1# -*- coding: utf-8 -*-
2## $Id: interfaces.py 16165 2020-07-14 14:19:29Z henrik $
3##
4## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
5## This program is free software; you can redistribute it and/or modify
6## it under the terms of the GNU General Public License as published by
7## the Free Software Foundation; either version 2 of the License, or
8## (at your option) any later version.
9##
10## This program is distributed in the hope that it will be useful,
11## but WITHOUT ANY WARRANTY; without even the implied warranty of
12## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13## GNU General Public License for more details.
14##
15## You should have received a copy of the GNU General Public License
16## along with this program; if not, write to the Free Software
17## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18##
19"""Customized interfaces of the university application package.
20"""
21
22from zope import schema
23from zope.component import getUtility
24from zope.catalog.interfaces import ICatalog
25from zc.sourcefactory.basic import BasicSourceFactory
26from waeup.kofa.applicants.interfaces import (
27    IApplicantBaseData,
28    AppCatCertificateSource, CertificateSource)
29from waeup.kofa.schoolgrades import ResultEntryField
30from waeup.kofa.university.vocabularies import StudyModeSource
31from waeup.kofa.interfaces import (
32    SimpleKofaVocabulary, academic_sessions_vocab, validate_email,
33    IKofaObject)
34from waeup.kofa.schema import FormattedDate, TextLineChoice, PhoneNumber
35from waeup.kofa.students.vocabularies import (
36    nats_vocab, GenderSource, StudyLevelSource)
37from waeup.kofa.applicants.interfaces import (
38    contextual_reg_num_source, IApplicantBaseData, IApplicantRefereeReport)
39from waeup.kofa.refereeentries import RefereeEntryField
40from kofacustom.nigeria.applicants.interfaces import (
41    LGASource, high_qual, high_grade, exam_types, DisabilitiesSource,
42    programme_types_vocab, jambsubjects, validate_jamb_reg_number,
43    INigeriaUGApplicant, INigeriaPGApplicant,
44    INigeriaApplicantOnlinePayment,
45    INigeriaUGApplicantEdit, INigeriaPGApplicantEdit,
46    INigeriaApplicantUpdateByRegNo,
47    IPUTMEApplicantEdit,
48    )
49from kofacustom.iuokada.interfaces import MessageFactory as _
50from kofacustom.iuokada.payments.interfaces import ICustomOnlinePayment
51
52sponsors_vocab = SimpleKofaVocabulary(
53    (_('Bauchi Government'), 'bauchi'),
54    (_('Company'), 'company'),
55    (_('Federal Government of Nigeria'), 'federalgov'),
56    #(_('Dangote Group'), 'dangote'),
57    (_('Kano Government'), 'kano'),
58    (_('Parent/Guardian'), 'parent'),
59    (_('Rosula Organization'), 'rosula'),
60    (_('Self'), 'self'),
61    #(_('Social Impact Project'), 'social'),
62    )
63
64heard_about_types_vocab = SimpleKofaVocabulary(
65    (_('Facebook/Twitter/Other Social Media'), 'socmedia'),
66    (_('From a Friend'), 'friend'),
67    (_('Newspaper Advertisement'), 'newspaper'),
68    (_('Radio Advertisement'), 'radio'),
69    (_('Television Advertisement'), 'television'),
70    (_('SMS'), 'sms'),
71    )
72
73subtype_vocab = SimpleKofaVocabulary(
74    (_('UTME'), 'utme'),
75    (_('Direct Entry'), 'de'),
76    (_('Inter Uni Transfer'), 'transfer'),
77    )
78
79rating_vocab = SimpleKofaVocabulary(
80    (_('Excellent'), 'e'),
81    (_('Very good'), 'vg'),
82    (_('Good'), 'g'),
83    (_('Slightly above average'), 'saa'),
84    (_('Average'), 'a'),
85    (_('Below average'), 'ba'),
86    (_('Unable to assess'), 'unable'),
87    )
88
89
90overallpromise_vocab = SimpleKofaVocabulary(
91    (_('Very good (highest 10%)'), 'vg'),
92    (_('Above average (next 15%)'), 'aa'),
93    (_('Average (middle 20%)'), 'a'),
94    (_('Below average (middle 40%)'), 'ba'),
95    )
96
97DESTINATION_COST = {
98    'local': ('Local (Nigeria)', 15000.0, 1),
99    'overseas': ('Overseas', 25000.0, 2),
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
115class TranscriptCertificateSource(CertificateSource):
116    """Include Department and Faculty in Title.
117    """
118    def getValues(self, context):
119        catalog = getUtility(ICatalog, name='certificates_catalog')
120        resultset = catalog.searchResults(code=(None, None))
121        resultlist = sorted(resultset, key=lambda
122            value: value.__parent__.__parent__.__parent__.code +
123            value.__parent__.__parent__.code +
124            value.code)
125        return resultlist
126
127    def getTitle(self, context, value):
128        """
129        """
130        try: title = "%s / %s / %s (%s)" % (
131            value.__parent__.__parent__.__parent__.title,
132            value.__parent__.__parent__.title,
133            value.title, value.code)
134        except AttributeError:
135            title = "NA / %s (%s)" % (value.title, value.code)
136        return title
137
138class ICustomUGApplicant(IApplicantBaseData):
139    """An undergraduate applicant.
140
141    This interface defines the least common multiple of all fields
142    in ug application forms. In customized forms, fields can be excluded by
143    adding them to the UG_OMIT* tuples.
144    """
145
146    subtype = schema.Choice(
147        title = _(u'Application Subtype'),
148        vocabulary = subtype_vocab,
149        required = False,
150        )
151    disabilities = schema.Choice(
152        title = _(u'Disability'),
153        source = DisabilitiesSource(),
154        required = False,
155        )
156    nationality = schema.Choice(
157        source = nats_vocab,
158        title = _(u'Nationality'),
159        required = False,
160        )
161    lga = schema.Choice(
162        source = LGASource(),
163        title = _(u'State/LGA (Nigerians only)'),
164        required = False,
165        )
166    sponsor = schema.Choice(
167        title = _(u'Sponsor'),
168        vocabulary = sponsors_vocab,
169        required = False,
170        )
171    heard_about = schema.Choice(
172        title = _(u'How did you hear about IUO?'),
173        vocabulary = heard_about_types_vocab,
174        required = False,
175        )
176    #perm_address = schema.Text(
177    #    title = _(u'Permanent Address'),
178    #    required = False,
179    #    )
180    parents_name = schema.TextLine(
181        title = _(u'Full Name'),
182        required = False,
183        readonly = False,
184        )
185    parents_email = schema.ASCIILine(
186        title = _(u'Email Address'),
187        required = False,
188        constraint=validate_email,
189        )
190    parents_phone = PhoneNumber(
191        title = _(u'Phone'),
192        required = False,
193        )
194    course1 = schema.Choice(
195        title = _(u'1st Choice Course of Study'),
196        source = AppCatCertificateSource(),
197        required = True,
198        )
199    course2 = schema.Choice(
200        title = _(u'2nd Choice Course of Study'),
201        source = AppCatCertificateSource(),
202        required = False,
203        )
204    programme_type = schema.Choice(
205        title = _(u'Programme Type'),
206        vocabulary = programme_types_vocab,
207        required = False,
208        )
209    fst_sit_fname = schema.TextLine(
210        title = _(u'Full Name'),
211        required = False,
212        readonly = False,
213        )
214    fst_sit_no = schema.TextLine(
215        title = _(u'Exam Number'),
216        required = False,
217        readonly = False,
218        )
219    fst_sit_date = FormattedDate(
220        title = _(u'Exam Date'),
221        required = False,
222        readonly = False,
223        show_year = True,
224        )
225    fst_sit_type = schema.Choice(
226        title = _(u'Exam Type'),
227        required = False,
228        readonly = False,
229        vocabulary = exam_types,
230        )
231    fst_sit_results = schema.List(
232        title = _(u'Exam Results'),
233        value_type = ResultEntryField(),
234        required = False,
235        readonly = False,
236        defaultFactory=list,
237        )
238    scd_sit_fname = schema.TextLine(
239        title = _(u'Full Name'),
240        required = False,
241        readonly = False,
242        )
243    scd_sit_no = schema.TextLine(
244        title = _(u'Exam Number'),
245        required = False,
246        readonly = False,
247        )
248    scd_sit_date = FormattedDate(
249        title = _(u'Exam Date'),
250        required = False,
251        readonly = False,
252        show_year = True,
253        )
254    scd_sit_type = schema.Choice(
255        title = _(u'Exam Type'),
256        required = False,
257        readonly = False,
258        vocabulary = exam_types,
259        )
260    scd_sit_results = schema.List(
261        title = _(u'Exam Results'),
262        value_type = ResultEntryField(),
263        required = False,
264        readonly = False,
265        defaultFactory=list,
266        )
267    hq_type = schema.Choice(
268        title = _(u'Qualification Obtained'),
269        required = False,
270        readonly = False,
271        vocabulary = high_qual,
272        )
273    hq_matric_no = schema.TextLine(
274        title = _(u'Former Matric Number'),
275        required = False,
276        readonly = False,
277        )
278    hq_degree = schema.Choice(
279        title = _(u'Class of Degree'),
280        required = False,
281        readonly = False,
282        vocabulary = high_grade,
283        )
284    hq_school = schema.TextLine(
285        title = _(u'Institution Attended'),
286        required = False,
287        readonly = False,
288        )
289    hq_session = schema.TextLine(
290        title = _(u'Years Attended'),
291        required = False,
292        readonly = False,
293        )
294    hq_disc = schema.TextLine(
295        title = _(u'Discipline'),
296        required = False,
297        readonly = False,
298        )
299    #jamb_subjects = schema.Text(
300    #    title = _(u'Subjects and Scores'),
301    #    required = False,
302    #    )
303    jamb_subjects_list = schema.List(
304        title = _(u'JAMB Subjects'),
305        required = False,
306        defaultFactory=list,
307        value_type = schema.Choice(
308            vocabulary = jambsubjects
309            #source = JAMBSubjectSource(),
310            ),
311        )
312    jamb_score = schema.Int(
313        title = _(u'Total JAMB Score'),
314        required = False,
315        )
316    #jamb_age = schema.Int(
317    #    title = _(u'Age (provided by JAMB)'),
318    #    required = False,
319    #    )
320    jamb_reg_number = schema.TextLine(
321        title = _(u'JAMB Registration Number'),
322        required = False,
323        constraint=validate_jamb_reg_number,
324        )
325    notice = schema.Text(
326        title = _(u'Notice'),
327        required = False,
328        )
329    screening_venue = schema.TextLine(
330        title = _(u'Screening Venue'),
331        required = False,
332        )
333    screening_date = schema.TextLine(
334        title = _(u'Screening Date'),
335        required = False,
336        )
337    screening_score = schema.Int(
338        title = _(u'Screening Score (%)'),
339        required = False,
340        )
341    aggregate = schema.Int(
342        title = _(u'Aggregate Score (%)'),
343        description = _(u'(average of relative JAMB and PUTME scores)'),
344        required = False,
345        )
346    result_uploaded = schema.Bool(
347        title = _(u'Result uploaded'),
348        default = False,
349        required = False,
350        )
351    student_id = schema.TextLine(
352        title = _(u'Student Id'),
353        required = False,
354        readonly = False,
355        )
356    course_admitted = schema.Choice(
357        title = _(u'Admitted Course of Study'),
358        source = CertificateSource(),
359        required = False,
360        )
361    locked = schema.Bool(
362        title = _(u'Form locked'),
363        default = False,
364        required = False,
365        )
366
367ICustomUGApplicant[
368    'subtype'].order =  ICustomUGApplicant['lga'].order
369ICustomUGApplicant[
370    'locked'].order =  ICustomUGApplicant['suspended'].order
371ICustomUGApplicant[
372    'result_uploaded'].order =  ICustomUGApplicant['suspended'].order
373
374class ICustomPGApplicant(INigeriaPGApplicant):
375    """A postgraduate applicant.
376
377    This interface defines the least common multiple of all fields
378    in pg application forms. In customized forms, fields can be excluded by
379    adding them to the PG_OMIT* tuples.
380    """
381
382    sponsor = schema.Choice(
383        title = _(u'Sponsor'),
384        vocabulary = sponsors_vocab,
385        required = False,
386        )
387
388    heard_about = schema.Choice(
389        title = _(u'How did you hear about IU?'),
390        vocabulary = heard_about_types_vocab,
391        required = False,
392        )
393
394    nysc_number = schema.Int(
395        title = _(u'Nysc Number'),
396        required = False,
397        readonly = False,
398        )
399
400    referees = schema.List(
401        title = _(u'Referees'),
402        value_type = RefereeEntryField(),
403        required = False,
404        defaultFactory=list,
405        )
406
407ICustomPGApplicant[
408    'referees'].order =  INigeriaPGApplicant['emp2_reason'].order
409ICustomPGApplicant[
410    'sponsor'].order =  ICustomPGApplicant['lga'].order
411ICustomPGApplicant[
412    'heard_about'].order =  ICustomPGApplicant['lga'].order
413ICustomPGApplicant[
414    'sponsor'].order =  ICustomPGApplicant['lga'].order
415ICustomPGApplicant[
416    'lga'].order =  ICustomPGApplicant['nationality'].order
417ICustomPGApplicant[
418    'nysc_number'].order =  ICustomPGApplicant['nysc_year'].order
419
420class ITranscriptApplicant(IKofaObject):
421    """A transcript applicant.
422    """
423
424    suspended = schema.Bool(
425        title = _(u'Account suspended'),
426        default = False,
427        required = False,
428        )
429
430    locked = schema.Bool(
431        title = _(u'Form locked'),
432        default = False,
433        required = False,
434        )
435
436    applicant_id = schema.TextLine(
437        title = _(u'Transcript Application Id'),
438        required = False,
439        readonly = False,
440        )
441
442    matric_number = schema.TextLine(
443        title = _(u'Matriculation Number'),
444        readonly = False,
445        required = True,
446        )
447
448    firstname = schema.TextLine(
449        title = _(u'First Name'),
450        required = True,
451        )
452
453    middlename = schema.TextLine(
454        title = _(u'Middle Name'),
455        required = False,
456        )
457
458    lastname = schema.TextLine(
459        title = _(u'Last Name (Surname)'),
460        required = True,
461        )
462
463    #date_of_birth = FormattedDate(
464    #    title = _(u'Date of Birth'),
465    #    required = False,
466    #    #date_format = u'%d/%m/%Y', # Use grok-instance-wide default
467    #    show_year = True,
468    #    )
469
470    sex = schema.Choice(
471        title = _(u'Gender'),
472        source = GenderSource(),
473        required = True,
474        )
475
476    #nationality = schema.Choice(
477    #    vocabulary = nats_vocab,
478    #    title = _(u'Nationality'),
479    #    required = False,
480    #    )
481
482    email = schema.ASCIILine(
483        title = _(u'Email Address'),
484        required = True,
485        constraint=validate_email,
486        )
487
488    #phone = PhoneNumber(
489    #    title = _(u'Phone'),
490    #    description = u'',
491    #    required = False,
492    #    )
493
494    #perm_address = schema.Text(
495    #    title = _(u'Current Local Address'),
496    #    required = False,
497    #    readonly = False,
498    #    )
499
500    dispatch_address = schema.Text(
501        title = _(u'Dispatch Addresses'),
502        description = u'Addresses to which transcripts should be posted. '
503                       'Addresses must involve same courier charges.',
504        required = False,
505        readonly = False,
506        )
507
508    charge = schema.Choice(
509        title = _(u'Courier Charge'),
510        source = DestinationCostSource(),
511        required = True,
512        )
513
514    #entry_mode = schema.Choice(
515    #    title = _(u'Entry Mode'),
516    #    source = StudyModeSource(),
517    #    required = False,
518    #    readonly = False,
519    #    )
520
521    #entry_session = schema.Choice(
522    #    title = _(u'Entry Session'),
523    #    source = academic_sessions_vocab,
524    #    required = False,
525    #    readonly = False,
526    #    )
527
528    end_session = schema.Choice(
529        title = _(u'Academic Session of Graduation'),
530        source = academic_sessions_vocab,
531        required = False,
532        readonly = False,
533        )
534
535    course_studied = schema.Choice(
536        title = _(u'Course of Study'),
537        source = TranscriptCertificateSource(),
538        description = u'Faculty / Department / Course',
539        required = False,
540        readonly = False,
541        )
542
543    #course_changed = schema.Choice(
544    #    title = _(u'Change of Study Course'),
545    #    description = u'If yes, select previous course of study.',
546    #    source = CertificateSource(),
547    #    readonly = False,
548    #    required = False,
549    #    )
550
551    #change_level = schema.Choice(
552    #    title = _(u'Change Level'),
553    #    description = u'If yes, select level at which you changed course of study.',
554    #    source = StudyLevelSource(),
555    #    required = False,
556    #    readonly = False,
557    #    )
558
559    no_copies = schema.Choice(
560        title = _(u'Number of Copies'),
561        description = u'Must correspond with the number of dispatch addresses above.',
562        values=[1, 2, 3, 4],
563        required = False,
564        readonly = False,
565        default = 1,
566        )
567
568class ICustomApplicant(ICustomUGApplicant, ICustomPGApplicant,
569    ITranscriptApplicant):
570    """An interface for both types of applicants.
571
572    Attention: The ICustomPGApplicant field seetings will be overwritten
573    by ICustomPGApplicant field settings. If a field is defined
574    in both interfaces zope.schema validates only against the
575    constraints in ICustomUGApplicant. This does not affect the forms
576    since they are build on either ICustomUGApplicant or ICustomPGApplicant.
577    """
578
579    def writeLogMessage(view, comment):
580        """Adds an INFO message to the log file
581        """
582
583    def createStudent():
584        """Create a student object from applicant data
585        and copy applicant object.
586        """
587
588class ICustomUGApplicantEdit(ICustomUGApplicant):
589    """An undergraduate applicant interface for edit forms.
590
591    Here we can repeat the fields from base data and set the
592    `required` and `readonly` attributes to True to further restrict
593    the data access. Or we can allow only certain certificates to be
594    selected by choosing the appropriate source.
595
596    We cannot omit fields here. This has to be done in the
597    respective form page.
598    """
599
600    phone = PhoneNumber(
601        title = _(u'Phone'),
602        description = u'',
603        required = True,
604        )
605    email = schema.ASCIILine(
606        title = _(u'Email Address'),
607        required = True,
608        constraint=validate_email,
609        )
610    date_of_birth = FormattedDate(
611        title = _(u'Date of Birth'),
612        required = True,
613        show_year = True,
614        )
615
616ICustomUGApplicantEdit[
617    'date_of_birth'].order = ICustomUGApplicant['date_of_birth'].order
618ICustomUGApplicantEdit[
619    'email'].order = ICustomUGApplicant['email'].order
620ICustomUGApplicantEdit[
621    'phone'].order =  ICustomUGApplicantEdit['email'].order
622
623class ICustomPGApplicantEdit(ICustomPGApplicant):
624    """A postgraduate applicant interface for editing.
625
626    Here we can repeat the fields from base data and set the
627    `required` and `readonly` attributes to True to further restrict
628    the data access. Or we can allow only certain certificates to be
629    selected by choosing the appropriate source.
630
631    We cannot omit fields here. This has to be done in the
632    respective form page.
633    """
634
635    phone = PhoneNumber(
636        title = _(u'Phone'),
637        description = u'',
638        required = True,
639        )
640    email = schema.ASCIILine(
641        title = _(u'Email Address'),
642        required = True,
643        constraint=validate_email,
644        )
645    date_of_birth = FormattedDate(
646        title = _(u'Date of Birth'),
647        required = True,
648        show_year = True,
649        )
650
651ICustomPGApplicantEdit[
652    'date_of_birth'].order = ICustomPGApplicant['date_of_birth'].order
653ICustomPGApplicantEdit[
654    'email'].order = ICustomPGApplicant['email'].order
655ICustomPGApplicantEdit[
656    'phone'].order =  ICustomPGApplicantEdit['email'].order
657
658class ICustomApplicantOnlinePayment(INigeriaApplicantOnlinePayment):
659    """An applicant payment via payment gateways.
660
661    """
662
663class IPUTMEApplicantEdit(IPUTMEApplicantEdit):
664    """An undergraduate applicant interface for editing.
665
666    Here we can repeat the fields from base data and set the
667    `required` and `readonly` attributes to True to further restrict
668    the data access. Or we can allow only certain certificates to be
669    selected by choosing the appropriate source.
670
671    We cannot omit fields here. This has to be done in the
672    respective form page.
673    """
674
675class ICustomApplicantUpdateByRegNo(INigeriaApplicantUpdateByRegNo):
676    """Representation of an applicant.
677
678    Skip regular reg_number validation if reg_number is used for finding
679    the applicant object.
680    """
681
682class ICustomApplicantRefereeReport(IApplicantRefereeReport):
683    """A referee report.
684    """
685
686    duration = schema.Text(
687        title = _(u'How long and in what capacity have you known the candidate?'),
688        required = False,
689        )
690
691    itellectual = schema.Choice(
692        title = _(u'Intellectual Capacity'),
693        required = False,
694        readonly = False,
695        vocabulary = rating_vocab,
696        )
697
698    persistent = schema.Choice(
699        title = _(u'Capacity for Persistent and Independent Academic Study'),
700        required = False,
701        readonly = False,
702        vocabulary = rating_vocab,
703        )
704
705    imaginative = schema.Choice(
706        title = _(u'Ability for Imaginative Thought'),
707        required = False,
708        readonly = False,
709        vocabulary = rating_vocab,
710        )
711
712    productive = schema.Choice(
713        title = _(u'Promise of Productive Scholarship'),
714        required = False,
715        readonly = False,
716        vocabulary = rating_vocab,
717        )
718
719    previous = schema.Choice(
720        title = _(u'Quality of Previous Work'),
721        required = False,
722        readonly = False,
723        vocabulary = rating_vocab,
724        )
725
726    expression = schema.Choice(
727        title = _(u'Oral and Written Expression in English'),
728        required = False,
729        readonly = False,
730        vocabulary = rating_vocab,
731        )
732
733    personality = schema.Text(
734        title = _(u'Please comment on the candidate\'s personality '
735            'with particular reference to his/her moral character, emotional '
736            'and physical stabilty'),
737        required = False,
738        )
739
740    promise = schema.Choice(
741        title = _(u'Candidate\'s overall promise'),
742        required = False,
743        readonly = False,
744        vocabulary = overallpromise_vocab,
745        )
746
747    report = schema.Text(
748        title = _(u'Any other relevant information which would help '
749            'in determining the candidate\'s suitability?'),
750        required = False,
751        )
752
753    objection = schema.Text(
754        title = _(u'Have you any objection to the contents of this '
755            'evaluation being disclosed to any award-given body if '
756            'the need arises?'),
757        required = False,
758        )
Note: See TracBrowser for help on using the repository browser.