source: main/waeup.uniben/trunk/src/waeup/uniben/applicants/interfaces.py @ 18082

Last change on this file since 18082 was 18082, checked in by Henrik Bettermann, 8 days ago

Make phone field required.

  • Property svn:keywords set to Id
File size: 29.4 KB
Line 
1# -*- coding: utf-8 -*-
2## $Id: interfaces.py 18082 2025-06-04 15:41:30Z 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
22#from grok import getSite
23import re
24from zope import schema
25from zope.interface import invariant, Invalid
26from zope.component import getUtility
27from zope.catalog.interfaces import ICatalog
28from zc.sourcefactory.basic import BasicSourceFactory
29from waeup.kofa.applicants.interfaces import (
30    IApplicantBaseData,
31    AppCatCertificateSource, CertificateSource)
32from waeup.kofa.university.vocabularies import StudyModeSource
33from waeup.kofa.students.vocabularies import (
34    nats_vocab, GenderSource, StudyLevelSource)
35from waeup.kofa.schoolgrades import ResultEntryField
36from waeup.kofa.interfaces import (
37    SimpleKofaVocabulary, academic_sessions_vocab, validate_email,
38    IKofaObject, ContextualDictSourceFactoryBase)
39from waeup.kofa.schema import FormattedDate, TextLineChoice, PhoneNumber
40from waeup.kofa.students.vocabularies import (
41    nats_vocab, GenderSource)
42from waeup.kofa.refereeentries import RefereeEntryField
43from waeup.kofa.applicants.interfaces import contextual_reg_num_source
44from kofacustom.nigeria.interfaces import DisabilitiesSource
45from kofacustom.nigeria.applicants.interfaces import (
46    LGASource, high_qual, high_grade, exam_types,
47    programme_types_vocab, jambsubjects,
48    INigeriaUGApplicant, INigeriaPGApplicant,
49    INigeriaApplicantOnlinePayment,
50    INigeriaUGApplicantEdit, INigeriaPGApplicantEdit,
51    INigeriaApplicantUpdateByRegNo,
52    IPUTMEApplicantEdit,
53    IBankAccount,
54    )
55from waeup.uniben.interfaces import MessageFactory as _
56from waeup.uniben.payments.interfaces import ICustomOnlinePayment
57
58
59# Define a validation method for JAMB reg numbers
60class NotMatricRegNumber(schema.ValidationError):
61    __doc__ = u"Invalid matriculation number"
62
63#: Regular expression to check matric_number formats.
64check_matric_number = re.compile(r"^[^0-9\s][^\s]*$").match
65
66def validate_matric_number(value):
67    if not check_matric_number(value):
68        raise NotMatricRegNumber(value)
69    return True
70
71class TranscriptCertificateSource(CertificateSource):
72    """Include Department and Faculty in Title.
73    """
74    def getValues(self, context):
75        catalog = getUtility(ICatalog, name='certificates_catalog')
76        resultset = catalog.searchResults(code=(None, None))
77        resultlist = sorted(resultset, key=lambda
78            value: value.__parent__.__parent__.__parent__.code +
79            value.__parent__.__parent__.code +
80            value.code)
81        return resultlist
82
83    def getTitle(self, context, value):
84        """
85        """
86        try: title = "%s / %s / %s (%s)" % (
87            value.__parent__.__parent__.__parent__.title,
88            value.__parent__.__parent__.title,
89            value.title, value.code)
90        except AttributeError:
91            title = "NA / %s (%s)" % (value.title, value.code)
92        return title
93
94REGISTRATION_CATS = {
95    'corporate': ('Corporate Registration', 250000, 1),
96    'group': ('Group Registration', 200000, 2),
97    'individual': ('Individual Registration', 45000, 3),
98    'student': ('Student Registration', 5000, 4),
99    'fullpage': ('Full Page Advert', 250000, 5),
100    'halfpage': ('Half Page Advert', 150000, 6),
101    'quarterpage': ('Quarter Page Advert', 100000, 7),
102    }
103
104class RegTypesSource(BasicSourceFactory):
105    """A source that delivers all kinds of registrations.
106    """
107    def getValues(self):
108        sorted_items = sorted(REGISTRATION_CATS.items(),
109                              key=lambda element: element[1][2])
110        return [item[0] for item in sorted_items]
111
112    def getTitle(self, value):
113        return u"%s @ ₦ %s" % (
114            REGISTRATION_CATS[value][0],
115            REGISTRATION_CATS[value][1])
116
117DESTINATION_COST = {
118    #'none': ('To the moon', 1000000000.0, 1),
119    'local': ('Local', 27500.0, 1),
120    'inter2': ('International', 37500.0, 2),
121    'nigeria': ('Within Nigeria (deprecated)', 20000.0, 3),
122    'africa': ('Within Africa (deprecated)', 30000.0, 4),
123    'inter': ('International (deprecated)', 35000.0, 5),
124    'cert_nigeria': ('Certified Copy - Within Nigeria (deprecated)', 13000.0, 6),
125    'cert_africa': ('Certified Copy - Within Africa (deprecated)', 23000.0, 7),
126    'cert_inter': ('Certified Copy - International (deprecated)', 28000.0, 8),
127    }
128
129class DestinationCostSource(BasicSourceFactory):
130    """A source that delivers continents and shipment costs.
131    """
132    def getValues(self):
133        sorted_items = sorted(DESTINATION_COST.items(),
134                              key=lambda element: element[1][2])
135        return [item[0] for item in sorted_items]
136
137    def getToken(self, value):
138        return value
139
140    def getTitle(self, value):
141        return u"%s (₦ %s)" % (
142            DESTINATION_COST[value][0],
143            DESTINATION_COST[value][1])
144
145class OrderSource(BasicSourceFactory):
146    """
147    """
148    def getValues(self):
149        return ['o', 'c']
150
151    def getToken(self, value):
152        return value
153
154    def getTitle(self, value):
155        if value == 'o':
156            return _('Original')
157        if value == 'c':
158            return _('Certified True Copy')
159
160class ProficiencySource(BasicSourceFactory):
161    """
162    """
163    def getValues(self):
164        return ['n', 'c', 'p']
165
166    def getToken(self, value):
167        return value
168
169    def getTitle(self, value):
170        if value == 'n':
171            return _('none')
172        if value == 'c':
173            return _('conversational')
174        if value == 'p':
175            return _('professional')
176
177class PreferredSessionSource(BasicSourceFactory):
178    """
179    """
180    def getValues(self):
181        return ['m', 'e', 'w']
182
183    def getToken(self, value):
184        return value
185
186    def getTitle(self, value):
187        if value == 'm':
188            return _('morning')
189        if value == 'e':
190            return _('evening')
191        if value == 'w':
192            return _('weekend')
193
194class IUnibenRegistration(IKofaObject):
195    """A Uniben registrant.
196    """
197
198    suspended = schema.Bool(
199        title = _(u'Account suspended'),
200        default = False,
201        required = False,
202        )
203
204    locked = schema.Bool(
205        title = _(u'Form locked'),
206        default = False,
207        required = False,
208        )
209
210    applicant_id = schema.TextLine(
211        title = _(u'Registrant Id'),
212        required = False,
213        readonly = False,
214        )
215
216    firstname = schema.TextLine(
217        title = _(u'First Name'),
218        required = True,
219        )
220
221    middlename = schema.TextLine(
222        title = _(u'Middle Name'),
223        required = False,
224        )
225
226    lastname = schema.TextLine(
227        title = _(u'Last Name (Surname)'),
228        required = True,
229        )
230
231    sex = schema.Choice(
232        title = _(u'Sex'),
233        source = GenderSource(),
234        required = True,
235        )
236
237    nationality = schema.Choice(
238        vocabulary = nats_vocab,
239        title = _(u'Nationality'),
240        required = False,
241        )
242
243    email = schema.ASCIILine(
244        title = _(u'Email Address'),
245        required = True,
246        constraint=validate_email,
247        )
248
249    phone = PhoneNumber(
250        title = _(u'Phone'),
251        description = u'',
252        required = True,
253        )
254
255    #perm_address = schema.Text(
256    #    title = _(u'Current Local Address'),
257    #    required = False,
258    #    readonly = False,
259    #    )
260
261    institution = schema.TextLine(
262        title = _(u'Institution/Organisation'),
263        required = False,
264        readonly = False,
265        )
266
267    city = schema.TextLine(
268        title = _(u'City'),
269        required = False,
270        readonly = False,
271        )
272
273    lga = schema.Choice(
274        source = LGASource(),
275        title = _(u'State/LGA'),
276        required = False,
277        )
278
279    matric_number = schema.TextLine(
280        title = _(u'Uniben Matriculation Number'),
281        required = False,
282        readonly = False,
283        )
284
285    registration_cats = schema.List(
286        title = _(u'Registration Categories'),
287        value_type = schema.Choice(source=RegTypesSource()),
288        required = True,
289        defaultFactory=list,
290        )
291
292#    @invariant
293#    def matric_number_exists(applicant):
294#        if applicant.matric_number:
295#            catalog = getUtility(ICatalog, name='students_catalog')
296#            accommodation_session = getSite()['hostels'].accommodation_session
297#            student = catalog.searchResults(matric_number=(
298#                applicant.matric_number, applicant.matric_number))
299#            if len(student) != 1:
300#                raise Invalid(_("Matriculation number not found."))
301
302class ITranscriptApplicant(IKofaObject):
303    """A transcript applicant.
304    """
305
306    suspended = schema.Bool(
307        title = _(u'Account suspended'),
308        default = False,
309        required = False,
310        )
311
312    locked = schema.Bool(
313        title = _(u'Form locked'),
314        default = False,
315        required = False,
316        )
317
318    applicant_id = schema.TextLine(
319        title = _(u'Transcript Application Id'),
320        required = False,
321        readonly = False,
322        )
323
324    student_id = schema.TextLine(
325        title = _(u'Kofa Student Id'),
326        required = False,
327        readonly = False,
328        )
329
330    matric_number = schema.TextLine(
331        title = _(u'Matriculation Number'),
332        readonly = False,
333        required = True,
334        constraint = validate_matric_number,
335        )
336
337    firstname = schema.TextLine(
338        title = _(u'First Name in School'),
339        required = True,
340        )
341
342    middlename = schema.TextLine(
343        title = _(u'Middle Name in School'),
344        required = False,
345        )
346
347    lastname = schema.TextLine(
348        title = _(u'Surname in School'),
349        required = True,
350        )
351
352    date_of_birth = FormattedDate(
353        title = _(u'Date of Birth'),
354        required = False,
355        #date_format = u'%d/%m/%Y', # Use grok-instance-wide default
356        show_year = True,
357        )
358
359    sex = schema.Choice(
360        title = _(u'Gender'),
361        source = GenderSource(),
362        required = True,
363        )
364
365    #nationality = schema.Choice(
366    #    vocabulary = nats_vocab,
367    #    title = _(u'Nationality'),
368    #    required = False,
369    #    )
370
371    email = schema.ASCIILine(
372        title = _(u'Email Address'),
373        required = True,
374        constraint=validate_email,
375        )
376
377    phone = PhoneNumber(
378        title = _(u'Phone'),
379        description = u'',
380        required = False,
381        )
382
383    #perm_address = schema.Text(
384    #    title = _(u'Current Local Address'),
385    #    required = False,
386    #    readonly = False,
387    #    )
388
389    collected = schema.Bool(
390        title = _(u'Have you collected transcript before?'),
391        default = False,
392        required = False,
393        )
394
395    entry_session = schema.Choice(
396        title = _(u'Academic Session of Entry'),
397        source = academic_sessions_vocab,
398        required = False,
399        readonly = False,
400        )
401
402    end_session = schema.Choice(
403        title = _(u'Academic Session of Graduation'),
404        source = academic_sessions_vocab,
405        required = False,
406        readonly = False,
407        )
408
409    entry_mode = schema.Choice(
410        title = _(u'Mode of Entry'),
411        source = StudyModeSource(),
412        required = False,
413        readonly = False,
414        )
415
416    course_studied = schema.Choice(
417        title = _(u'Course of Study'),
418        source = TranscriptCertificateSource(),
419        description = u'Faculty / Department / Course',
420        required = True,
421        readonly = False,
422        )
423
424    course_changed = schema.Choice(
425        title = _(u'Change of Study Course / Transfer'),
426        description = u'If yes, select previous course of study.',
427        source = TranscriptCertificateSource(),
428        readonly = False,
429        required = False,
430        )
431
432    spillover_level = schema.Choice(
433        title = _(u'Spill-over'),
434        description = u'Any spill-over? If yes, select session of spill-over.',
435        source = academic_sessions_vocab,
436        required = False,
437        readonly = False,
438        )
439
440    purpose = schema.TextLine(
441        title = _(u'Transcript Purpose'),
442        required = False,
443        )
444
445    order = schema.Choice(
446        source = OrderSource(),
447        title = _(u'Type of Order'),
448        required = False,
449        )
450
451    dispatch_address = schema.Text(
452        title = _(u'Recipient Body'),
453        description = u'Addresses to which transcripts should be posted. '
454                       'All addresses must involve same courier charges.',
455        required = True,
456        readonly = False,
457        )
458
459    dispatch_email = schema.ASCIILine(
460        title = _(u'Recipient Email Address'),
461        required = False,
462        constraint=validate_email,
463        )
464
465    dispatch_phone = PhoneNumber(
466        title = _(u'Recipient Phone'),
467        description = u'',
468        required = False,
469        )
470
471    charge = schema.Choice(
472        title = _(u'Transcript Charge'),
473        source = DestinationCostSource(),
474        required = False,
475        readonly = False,
476        )
477
478    no_copies = schema.Choice(
479        title = _(u'Number of Copies'),
480        description = u'Must correspond with the number of dispatch addresses above.',
481        values=[1, 2, 3, 4],
482        required = False,
483        readonly = False,
484        default = 1,
485        )
486
487    courier_tno = schema.TextLine(
488        title = _(u'Courier Tracking Number'),
489        required = False,
490        )
491
492    proc_date = FormattedDate(
493        title = _(u'Processing Date'),
494        required = False,
495        #date_format = u'%d/%m/%Y', # Use grok-instance-wide default
496        show_year = True,
497        )
498
499    @invariant
500    def type_of_order(applicant):
501        if not applicant.collected and applicant.order != 'o':
502            raise Invalid(_("If you haven't collected transcript before, type of order must be 'original'."))
503        if applicant.order == 'o' and applicant.charge.startswith('cert_'):
504            raise Invalid(_("You've selected the wrong transcript charge."))
505        if applicant.order == 'c' and not applicant.charge.startswith('cert_'):
506            raise Invalid(_("You've selected the wrong transcript charge."))
507        if applicant.charge not in ('inter2', 'local'):
508            raise Invalid(_("This fee is deprecated. Please select a current transcript charge."))
509
510class IFrenchApplicant(IKofaObject):
511    """A transcript applicant.
512    """
513
514    suspended = schema.Bool(
515        title = _(u'Account suspended'),
516        default = False,
517        required = False,
518        )
519
520    locked = schema.Bool(
521        title = _(u'Form locked'),
522        default = False,
523        required = False,
524        )
525
526    applicant_id = schema.TextLine(
527        title = _(u'Applicant Id'),
528        required = False,
529        readonly = False,
530        )
531
532    firstname = schema.TextLine(
533        title = _(u'First Name'),
534        required = True,
535        )
536
537    middlename = schema.TextLine(
538        title = _(u'Middle Name'),
539        required = False,
540        )
541
542    lastname = schema.TextLine(
543        title = _(u'Surname'),
544        required = True,
545        )
546
547    date_of_birth = FormattedDate(
548        title = _(u'Date of Birth'),
549        required = False,
550        #date_format = u'%d/%m/%Y', # Use grok-instance-wide default
551        show_year = True,
552        )
553
554    sex = schema.Choice(
555        title = _(u'Gender'),
556        source = GenderSource(),
557        required = True,
558        )
559
560    nationality = schema.Choice(
561        vocabulary = nats_vocab,
562        title = _(u'Nationality'),
563        required = False,
564        )
565
566    email = schema.ASCIILine(
567        title = _(u'Email Address'),
568        required = True,
569        constraint=validate_email,
570        )
571
572    phone = PhoneNumber(
573        title = _(u'Phone'),
574        description = u'',
575        required = False,
576        )
577
578    work = schema.TextLine(
579        title = _(u'Place of Work'),
580        required = False,
581        )
582
583    hq_obtained = schema.Choice(
584        title = _(u'Highest Qualification Obtained'),
585        required = False,
586        readonly = False,
587        vocabulary = high_qual,
588        )
589
590    hq_date = FormattedDate(
591        title = _(u'Highest Qualification Date'),
592        required = False,
593        readonly = False,
594        show_year = True,
595        )
596
597    pref_session = schema.Choice(
598        source = PreferredSessionSource(),
599        title = _(u'Preferred Session'),
600        required = False,
601        )
602
603    proficiency = schema.Choice(
604        source = ProficiencySource(),
605        title = _(u'Level of Proficiency'),
606        required = False,
607        )
608
609    guarantor = schema.TextLine(
610        title = _(u'Name of Guarantor'),
611        required = False,
612        )
613
614    course_admitted = schema.Choice(
615        title = _(u'Admitted Course of Study'),
616        source = CertificateSource(),
617        required = False,
618        )
619
620class IAfrimalApplicant(IKofaObject):
621    """An AFRIMAL applicant.
622    """
623
624    suspended = schema.Bool(
625        title = _(u'Account suspended'),
626        default = False,
627        required = False,
628        )
629
630    locked = schema.Bool(
631        title = _(u'Form locked'),
632        default = False,
633        required = False,
634        )
635
636    applicant_id = schema.TextLine(
637        title = _(u'Applicant Id'),
638        required = False,
639        readonly = False,
640        )
641
642    firstname = schema.TextLine(
643        title = _(u'First Name'),
644        required = True,
645        )
646
647    middlename = schema.TextLine(
648        title = _(u'Middle Name'),
649        required = False,
650        )
651
652    lastname = schema.TextLine(
653        title = _(u'Surname'),
654        required = True,
655        )
656
657    date_of_birth = FormattedDate(
658        title = _(u'Date of Birth'),
659        required = False,
660        #date_format = u'%d/%m/%Y', # Use grok-instance-wide default
661        show_year = True,
662        )
663
664    sex = schema.Choice(
665        title = _(u'Gender'),
666        source = GenderSource(),
667        required = True,
668        )
669
670    nationality = schema.Choice(
671        vocabulary = nats_vocab,
672        title = _(u'Nationality'),
673        required = False,
674        )
675
676    email = schema.ASCIILine(
677        title = _(u'Email Address'),
678        required = True,
679        constraint=validate_email,
680        )
681
682    phone = PhoneNumber(
683        title = _(u'Phone'),
684        description = u'',
685        required = False,
686        )
687
688    hq_obtained = schema.Choice(
689        title = _(u'Highest Qualification Obtained'),
690        required = False,
691        readonly = False,
692        vocabulary = high_qual,
693        )
694
695    current_employer = schema.TextLine(
696        title = _(u'Current Employer'),
697        required = False,
698        )
699
700    course1 = schema.Choice(
701        title = _(u'Course of Study'),
702        source = AppCatCertificateSource(),
703        required = True,
704        )
705
706    course_admitted = schema.Choice(
707        title = _(u'Admitted Course of Study'),
708        source = CertificateSource(),
709        required = False,
710        )
711
712class ICustomUGApplicant(IApplicantBaseData, IBankAccount):
713    """An undergraduate applicant.
714
715    This interface defines the least common multiple of all fields
716    in ug application forms. In customized forms, fields can be excluded by
717    adding them to the UG_OMIT* tuples.
718    """
719
720    phone = PhoneNumber(
721        title = _(u'Phone'),
722        description = u'',
723        required = True,
724        )
725
726    disabilities = schema.Choice(
727        title = _(u'Disabilities'),
728        source = DisabilitiesSource(),
729        required = False,
730        )
731    nationality = schema.Choice(
732        source = nats_vocab,
733        title = _(u'Nationality'),
734        required = False,
735        )
736    lga = schema.Choice(
737        source = LGASource(),
738        title = _(u'State/LGA (Nigerians only)'),
739        required = False,
740        )
741    #perm_address = schema.Text(
742    #    title = _(u'Permanent Address'),
743    #    required = False,
744    #    )
745    course1 = schema.Choice(
746        title = _(u'1st Choice Course of Study'),
747        source = AppCatCertificateSource(),
748        required = True,
749        )
750    course2 = schema.Choice(
751        title = _(u'2nd Choice Course of Study'),
752        source = AppCatCertificateSource(),
753        required = False,
754        )
755
756    programme_type = schema.Choice(
757        title = _(u'Programme Type'),
758        vocabulary = programme_types_vocab,
759        required = False,
760        )
761
762    hq_type = schema.Choice(
763        title = _(u'Qualification Obtained'),
764        required = False,
765        readonly = False,
766        vocabulary = high_qual,
767        )
768    hq_matric_no = schema.TextLine(
769        title = _(u'Former Matric Number'),
770        required = False,
771        readonly = False,
772        )
773    hq_degree = schema.Choice(
774        title = _(u'Class of Degree'),
775        required = False,
776        readonly = False,
777        vocabulary = high_grade,
778        )
779    hq_school = schema.TextLine(
780        title = _(u'Institution Attended'),
781        required = False,
782        readonly = False,
783        )
784    hq_session = schema.TextLine(
785        title = _(u'Years Attended'),
786        required = False,
787        readonly = False,
788        )
789    hq_disc = schema.TextLine(
790        title = _(u'Discipline'),
791        required = False,
792        readonly = False,
793        )
794    fst_sit_fname = schema.TextLine(
795        title = _(u'Full Name'),
796        required = False,
797        readonly = False,
798        )
799    fst_sit_no = schema.TextLine(
800        title = _(u'Exam Number'),
801        required = False,
802        readonly = False,
803        )
804    fst_sit_date = FormattedDate(
805        title = _(u'Exam Date'),
806        required = False,
807        readonly = False,
808        show_year = True,
809        )
810    fst_sit_type = schema.Choice(
811        title = _(u'Exam Type'),
812        required = False,
813        readonly = False,
814        vocabulary = exam_types,
815        )
816    fst_sit_results = schema.List(
817        title = _(u'Exam Results'),
818        value_type = ResultEntryField(),
819        required = False,
820        readonly = False,
821        defaultFactory=list,
822        )
823    scd_sit_fname = schema.TextLine(
824        title = _(u'Full Name'),
825        required = False,
826        readonly = False,
827        )
828    scd_sit_no = schema.TextLine(
829        title = _(u'Exam Number'),
830        required = False,
831        readonly = False,
832        )
833    scd_sit_date = FormattedDate(
834        title = _(u'Exam Date'),
835        required = False,
836        readonly = False,
837        show_year = True,
838        )
839    scd_sit_type = schema.Choice(
840        title = _(u'Exam Type'),
841        required = False,
842        readonly = False,
843        vocabulary = exam_types,
844        )
845    scd_sit_results = schema.List(
846        title = _(u'Exam Results'),
847        value_type = ResultEntryField(),
848        required = False,
849        readonly = False,
850        defaultFactory=list,
851        )
852    jamb_reg_number = schema.TextLine(
853        title = _(u'JAMB Registration Number'),
854        required = False,
855        )
856    jamb_subjects = schema.Text(
857        title = _(u'Subjects and Scores'),
858        required = False,
859        )
860    jamb_subjects_list = schema.List(
861        title = _(u'JAMB Subjects'),
862        required = False,
863        defaultFactory=list,
864        value_type = schema.Choice(
865            vocabulary = jambsubjects
866            #source = JAMBSubjectSource(),
867            ),
868        )
869    jamb_score = schema.Float(
870        title = _(u'Total JAMB Score'),
871        required = False,
872        )
873    #jamb_age = schema.Int(
874    #    title = _(u'Age (provided by JAMB)'),
875    #    required = False,
876    #    )
877    course_admitted = schema.Choice(
878        title = _(u'Admitted Course of Study'),
879        source = CertificateSource(),
880        required = False,
881        )
882    notice = schema.Text(
883        title = _(u'Notice'),
884        required = False,
885        )
886    screening_venue = schema.TextLine(
887        title = _(u'Screening Venue'),
888        required = False,
889        )
890    screening_date = schema.TextLine(
891        title = _(u'Screening Date'),
892        required = False,
893        )
894    screening_score = schema.Float(
895        title = _(u'Screening Score (%)'),
896        required = False,
897        )
898    aggregate = schema.Float(
899        title = _(u'Aggregate Score (%)'),
900        description = _(u'(average of relative JAMB and PUTME scores)'),
901        required = False,
902        )
903    result_uploaded = schema.Bool(
904        title = _(u'Result uploaded'),
905        default = False,
906        required = False,
907        )
908    student_id = schema.TextLine(
909        title = _(u'Student Id'),
910        required = False,
911        readonly = False,
912        )
913    locked = schema.Bool(
914        title = _(u'Form locked'),
915        default = False,
916        required = False,
917        )
918
919ICustomUGApplicant[
920    'phone'].order =  IApplicantBaseData['phone'].order
921ICustomUGApplicant[
922    'locked'].order =  IApplicantBaseData['suspended'].order
923ICustomUGApplicant[
924    'result_uploaded'].order =  ICustomUGApplicant['suspended'].order
925
926class ICustomPGApplicant(INigeriaPGApplicant):
927    """A postgraduate applicant.
928
929    This interface defines the least common multiple of all fields
930    in pg application forms. In customized forms, fields can be excluded by
931    adding them to the PG_OMIT* tuples.
932    """
933
934    referees = schema.List(
935        title = _(u'Referees'),
936        value_type = RefereeEntryField(),
937        required = False,
938        defaultFactory=list,
939        )
940
941ICustomPGApplicant[
942    'referees'].order =  INigeriaPGApplicant['emp2_reason'].order
943
944class ICustomApplicant(ICustomUGApplicant, ICustomPGApplicant,
945    IUnibenRegistration, ITranscriptApplicant, IFrenchApplicant,
946    IAfrimalApplicant):
947    """An interface for both types of applicants.
948
949    Attention: The ICustomPGApplicant field seetings will be overwritten
950    by ICustomPGApplicant field settings. If a field is defined
951    in both interfaces zope.schema validates only against the
952    constraints in ICustomUGApplicant. This does not affect the forms
953    since they are build on either ICustomUGApplicant or ICustomPGApplicant.
954    """
955
956    def writeLogMessage(view, comment):
957        """Adds an INFO message to the log file
958        """
959
960    def createStudent():
961        """Create a student object from applicant data
962        and copy applicant object.
963        """
964
965class ICustomUGApplicantEdit(ICustomUGApplicant):
966    """An undergraduate applicant interface for edit forms.
967
968    Here we can repeat the fields from base data and set the
969    `required` and `readonly` attributes to True to further restrict
970    the data access. Or we can allow only certain certificates to be
971    selected by choosing the appropriate source.
972
973    We cannot omit fields here. This has to be done in the
974    respective form page.
975    """
976
977    email = schema.ASCIILine(
978        title = _(u'Email Address'),
979        required = True,
980        constraint=validate_email,
981        )
982    date_of_birth = FormattedDate(
983        title = _(u'Date of Birth'),
984        required = True,
985        show_year = True,
986        )
987
988ICustomUGApplicantEdit[
989    'date_of_birth'].order = ICustomUGApplicant['date_of_birth'].order
990ICustomUGApplicantEdit[
991    'email'].order = ICustomUGApplicant['email'].order
992
993class ICustomPGApplicantEdit(INigeriaPGApplicantEdit):
994    """A postgraduate applicant interface for editing.
995
996    Here we can repeat the fields from base data and set the
997    `required` and `readonly` attributes to True to further restrict
998    the data access. Or we can allow only certain certificates to be
999    selected by choosing the appropriate source.
1000
1001    We cannot omit fields here. This has to be done in the
1002    respective form page.
1003    """
1004
1005    referees = schema.List(
1006        title = _(u'Referees'),
1007        value_type = RefereeEntryField(),
1008        required = False,
1009        defaultFactory=list,
1010        )
1011
1012ICustomPGApplicantEdit[
1013    'referees'].order =  INigeriaPGApplicantEdit['emp2_reason'].order
1014
1015class ICustomApplicantOnlinePayment(INigeriaApplicantOnlinePayment):
1016    """An applicant payment via payment gateways.
1017
1018    """
1019
1020class IPUTMEApplicantEdit(ICustomUGApplicant):
1021    """An undergraduate applicant interface for editing.
1022
1023    Here we can repeat the fields from base data and set the
1024    `required` and `readonly` attributes to True to further restrict
1025    the data access. Or we can allow only certain certificates to be
1026    selected by choosing the appropriate source.
1027
1028    We cannot omit fields here. This has to be done in the
1029    respective form page.
1030    """
1031
1032    email = schema.ASCIILine(
1033        title = _(u'Email Address'),
1034        required = True,
1035        constraint=validate_email,
1036        )
1037    date_of_birth = FormattedDate(
1038        title = _(u'Date of Birth'),
1039        required = True,
1040        show_year = True,
1041        )
1042    nationality = schema.Choice(
1043        source = nats_vocab,
1044        title = _(u'Nationality'),
1045        required = True,
1046        )
1047
1048IPUTMEApplicantEdit[
1049    'date_of_birth'].order =  ICustomUGApplicant['date_of_birth'].order
1050IPUTMEApplicantEdit[
1051    'email'].order =  ICustomUGApplicant['email'].order
1052IPUTMEApplicantEdit[
1053    'nationality'].order =  ICustomUGApplicant['nationality'].order
1054
1055class ICustomApplicantUpdateByRegNo(INigeriaApplicantUpdateByRegNo):
1056    """Representation of an applicant.
1057
1058    Skip regular reg_number validation if reg_number is used for finding
1059    the applicant object.
1060    """
Note: See TracBrowser for help on using the repository browser.