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

Last change on this file since 17939 was 17659, checked in by Henrik Bettermann, 12 months ago

Ticket #1328 (second part)

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