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

Last change on this file since 16147 was 16147, checked in by Henrik Bettermann, 5 years ago

Configure DESTINATION_COST.

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