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

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

More fields.

  • Property svn:keywords set to Id
File size: 21.9 KB
Line 
1# -*- coding: utf-8 -*-
2## $Id: interfaces.py 16153 2020-07-09 03:40:50Z 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
23from zope import schema
24#from zope.interface import invariant, Invalid
25from zope.component import getUtility
26from zope.catalog.interfaces import ICatalog
27from zc.sourcefactory.basic import BasicSourceFactory
28from waeup.kofa.applicants.interfaces import (
29    IApplicantBaseData,
30    AppCatCertificateSource, CertificateSource)
31from waeup.kofa.university.vocabularies import StudyModeSource
32from waeup.kofa.students.vocabularies import (
33    nats_vocab, GenderSource, StudyLevelSource)
34from waeup.kofa.schoolgrades import ResultEntryField
35from waeup.kofa.interfaces import (
36    SimpleKofaVocabulary, academic_sessions_vocab, validate_email,
37    IKofaObject, ContextualDictSourceFactoryBase)
38from waeup.kofa.schema import FormattedDate, TextLineChoice, PhoneNumber
39from waeup.kofa.students.vocabularies import (
40    nats_vocab, GenderSource)
41from waeup.kofa.refereeentries import RefereeEntryField
42from waeup.kofa.applicants.interfaces import contextual_reg_num_source
43from kofacustom.nigeria.interfaces import DisabilitiesSource
44from kofacustom.nigeria.applicants.interfaces import (
45    LGASource, high_qual, high_grade, exam_types,
46    programme_types_vocab, jambsubjects,
47    INigeriaUGApplicant, INigeriaPGApplicant,
48    INigeriaApplicantOnlinePayment,
49    INigeriaUGApplicantEdit, INigeriaPGApplicantEdit,
50    INigeriaApplicantUpdateByRegNo,
51    IPUTMEApplicantEdit,
52    IBankAccount,
53    )
54from waeup.uniben.interfaces import MessageFactory as _
55from waeup.uniben.payments.interfaces import ICustomOnlinePayment
56
57class TranscriptCertificateSource(CertificateSource):
58    """Include Department and Faculty in Title.
59    """
60    def getValues(self, context):
61        catalog = getUtility(ICatalog, name='certificates_catalog')
62        resultset = catalog.searchResults(code=(None, None))
63        resultlist = sorted(resultset, key=lambda
64            value: value.__parent__.__parent__.__parent__.code +
65            value.__parent__.__parent__.code +
66            value.code)
67        return resultlist
68
69    def getTitle(self, context, value):
70        """
71        """
72        try: title = "%s / %s / %s (%s)" % (
73            value.__parent__.__parent__.__parent__.title,
74            value.__parent__.__parent__.title,
75            value.title, value.code)
76        except AttributeError:
77            title = "NA / %s (%s)" % (value.title, value.code)
78        return title
79
80REGISTRATION_CATS = {
81    'corporate': ('Corporate Registration', 250000, 1),
82    'group': ('Group Registration', 200000, 2),
83    'individual': ('Individual Registration', 45000, 3),
84    'student': ('Student Registration', 5000, 4),
85    'fullpage': ('Full Page Advert', 250000, 5),
86    'halfpage': ('Half Page Advert', 150000, 6),
87    'quarterpage': ('Quarter Page Advert', 100000, 7),
88    }
89
90class RegTypesSource(BasicSourceFactory):
91    """A source that delivers all kinds of registrations.
92    """
93    def getValues(self):
94        sorted_items = sorted(REGISTRATION_CATS.items(),
95                              key=lambda element: element[1][2])
96        return [item[0] for item in sorted_items]
97
98    def getTitle(self, value):
99        return u"%s @ ₦ %s" % (
100            REGISTRATION_CATS[value][0],
101            REGISTRATION_CATS[value][1])
102
103DESTINATION_COST = {
104    #'none': ('To the moon', 1000000000.0, 1),
105    'nigeria': ('Within Nigeria', 20000.0, 1),
106    'africa': ('Within Africa ', 30000.0, 2),
107    'inter': ('International', 35000.0, 3),
108    }
109
110class DestinationCostSource(BasicSourceFactory):
111    """A source that delivers continents and shipment costs.
112    """
113    def getValues(self):
114        sorted_items = sorted(DESTINATION_COST.items(),
115                              key=lambda element: element[1][2])
116        return [item[0] for item in sorted_items]
117
118    def getToken(self, value):
119        return value
120
121    def getTitle(self, value):
122        return u"%s (₦ %s)" % (
123            DESTINATION_COST[value][0],
124            DESTINATION_COST[value][1])
125
126class OrderSource(BasicSourceFactory):
127    """
128    """
129    def getValues(self):
130        return ['o', 'c']
131
132    def getToken(self, value):
133        return value
134
135    def getTitle(self, value):
136        if value == 'o':
137            return _('Original')
138        if value == 'c':
139            return _('Certified True Copy')
140
141class IUnibenRegistration(IKofaObject):
142    """A Uniben registrant.
143    """
144
145    suspended = schema.Bool(
146        title = _(u'Account suspended'),
147        default = False,
148        required = False,
149        )
150
151    locked = schema.Bool(
152        title = _(u'Form locked'),
153        default = False,
154        required = False,
155        )
156
157    applicant_id = schema.TextLine(
158        title = _(u'Registrant Id'),
159        required = False,
160        readonly = False,
161        )
162
163    firstname = schema.TextLine(
164        title = _(u'First Name'),
165        required = True,
166        )
167
168    middlename = schema.TextLine(
169        title = _(u'Middle Name'),
170        required = False,
171        )
172
173    lastname = schema.TextLine(
174        title = _(u'Last Name (Surname)'),
175        required = True,
176        )
177
178    sex = schema.Choice(
179        title = _(u'Sex'),
180        source = GenderSource(),
181        required = True,
182        )
183
184    nationality = schema.Choice(
185        vocabulary = nats_vocab,
186        title = _(u'Nationality'),
187        required = False,
188        )
189
190    email = schema.ASCIILine(
191        title = _(u'Email Address'),
192        required = True,
193        constraint=validate_email,
194        )
195
196    phone = PhoneNumber(
197        title = _(u'Phone'),
198        description = u'',
199        required = False,
200        )
201
202    #perm_address = schema.Text(
203    #    title = _(u'Current Local Address'),
204    #    required = False,
205    #    readonly = False,
206    #    )
207
208    institution = schema.TextLine(
209        title = _(u'Institution/Organisation'),
210        required = False,
211        readonly = False,
212        )
213
214    city = schema.TextLine(
215        title = _(u'City'),
216        required = False,
217        readonly = False,
218        )
219
220    lga = schema.Choice(
221        source = LGASource(),
222        title = _(u'State/LGA'),
223        required = False,
224        )
225
226    matric_number = schema.TextLine(
227        title = _(u'Uniben Matriculation Number'),
228        required = False,
229        readonly = False,
230        )
231
232    registration_cats = schema.List(
233        title = _(u'Registration Categories'),
234        value_type = schema.Choice(source=RegTypesSource()),
235        required = True,
236        defaultFactory=list,
237        )
238
239#    @invariant
240#    def matric_number_exists(applicant):
241#        if applicant.matric_number:
242#            catalog = getUtility(ICatalog, name='students_catalog')
243#            accommodation_session = getSite()['hostels'].accommodation_session
244#            student = catalog.searchResults(matric_number=(
245#                applicant.matric_number, applicant.matric_number))
246#            if len(student) != 1:
247#                raise Invalid(_("Matriculation number not found."))
248
249class ITranscriptApplicant(IKofaObject):
250    """A transcript applicant.
251    """
252
253    suspended = schema.Bool(
254        title = _(u'Account suspended'),
255        default = False,
256        required = False,
257        )
258
259    locked = schema.Bool(
260        title = _(u'Form locked'),
261        default = False,
262        required = False,
263        )
264
265    applicant_id = schema.TextLine(
266        title = _(u'Transcript Application Id'),
267        required = False,
268        readonly = False,
269        )
270
271    student_id = schema.TextLine(
272        title = _(u'Kofa Student Id'),
273        required = False,
274        readonly = False,
275        )
276
277    matric_number = schema.TextLine(
278        title = _(u'Matriculation Number'),
279        readonly = False,
280        required = True,
281        )
282
283    firstname = schema.TextLine(
284        title = _(u'First Name in School'),
285        required = True,
286        )
287
288    middlename = schema.TextLine(
289        title = _(u'Middle Name in School'),
290        required = False,
291        )
292
293    lastname = schema.TextLine(
294        title = _(u'Surname in School'),
295        required = True,
296        )
297
298    date_of_birth = FormattedDate(
299        title = _(u'Date of Birth'),
300        required = False,
301        #date_format = u'%d/%m/%Y', # Use grok-instance-wide default
302        show_year = True,
303        )
304
305    sex = schema.Choice(
306        title = _(u'Gender'),
307        source = GenderSource(),
308        required = True,
309        )
310
311    #nationality = schema.Choice(
312    #    vocabulary = nats_vocab,
313    #    title = _(u'Nationality'),
314    #    required = False,
315    #    )
316
317    email = schema.ASCIILine(
318        title = _(u'Email Address'),
319        required = True,
320        constraint=validate_email,
321        )
322
323    phone = PhoneNumber(
324        title = _(u'Phone'),
325        description = u'',
326        required = False,
327        )
328
329    #perm_address = schema.Text(
330    #    title = _(u'Current Local Address'),
331    #    required = False,
332    #    readonly = False,
333    #    )
334
335    collected = schema.Bool(
336        title = _(u'Have you collected transcript before?'),
337        default = False,
338        required = False,
339        )
340
341    entry_session = schema.Choice(
342        title = _(u'Academic Session of Entry'),
343        source = academic_sessions_vocab,
344        required = False,
345        readonly = False,
346        )
347
348    end_session = schema.Choice(
349        title = _(u'Academic Session of Graduation'),
350        source = academic_sessions_vocab,
351        required = False,
352        readonly = False,
353        )
354
355    entry_mode = schema.Choice(
356        title = _(u'Mode of Entry'),
357        source = StudyModeSource(),
358        required = False,
359        readonly = False,
360        )
361
362    course_studied = schema.Choice(
363        title = _(u'Course of Study'),
364        source = TranscriptCertificateSource(),
365        description = u'Faculty / Department / Study Course',
366        required = False,
367        readonly = False,
368        )
369
370    course_changed = schema.Choice(
371        title = _(u'Change of Study Course / Transfer'),
372        description = u'If yes, select previous course of study.',
373        source = TranscriptCertificateSource(),
374        readonly = False,
375        required = False,
376        )
377
378    spillover_level = schema.Choice(
379        title = _(u'Spill-over'),
380        description = u'Any spill-over? If yes, select session of spill-over.',
381        source = academic_sessions_vocab,
382        required = False,
383        readonly = False,
384        )
385
386    purpose = schema.TextLine(
387        title = _(u'Transcript Purpose'),
388        required = False,
389        )
390
391    order = schema.Choice(
392        source = OrderSource(),
393        title = _(u'Type of Order'),
394        required = False,
395        )
396
397    dispatch_address = schema.Text(
398        title = _(u'Recipient Body'),
399        description = u'Addresses (including email address and phone number) '
400                       'to which transcripts should be posted. '
401                       'All addresses must involve same courier charges.',
402        required = False,
403        readonly = False,
404        )
405
406    charge = schema.Choice(
407        title = _(u'Courier Charge'),
408        source = DestinationCostSource(),
409        required = True,
410        )
411
412    no_copies = schema.Choice(
413        title = _(u'Number of Copies'),
414        description = u'Must correspond with the number of dispatch addresses above.',
415        values=[1, 2, 3, 4],
416        required = False,
417        readonly = False,
418        default = 1,
419        )
420
421class ICustomUGApplicant(IApplicantBaseData, IBankAccount):
422    """An undergraduate applicant.
423
424    This interface defines the least common multiple of all fields
425    in ug application forms. In customized forms, fields can be excluded by
426    adding them to the UG_OMIT* tuples.
427    """
428
429    disabilities = schema.Choice(
430        title = _(u'Disabilities'),
431        source = DisabilitiesSource(),
432        required = False,
433        )
434    nationality = schema.Choice(
435        source = nats_vocab,
436        title = _(u'Nationality'),
437        required = False,
438        )
439    lga = schema.Choice(
440        source = LGASource(),
441        title = _(u'State/LGA (Nigerians only)'),
442        required = False,
443        )
444    #perm_address = schema.Text(
445    #    title = _(u'Permanent Address'),
446    #    required = False,
447    #    )
448    course1 = schema.Choice(
449        title = _(u'1st Choice Course of Study'),
450        source = AppCatCertificateSource(),
451        required = True,
452        )
453    course2 = schema.Choice(
454        title = _(u'2nd Choice Course of Study'),
455        source = AppCatCertificateSource(),
456        required = False,
457        )
458
459    programme_type = schema.Choice(
460        title = _(u'Programme Type'),
461        vocabulary = programme_types_vocab,
462        required = False,
463        )
464
465    hq_type = schema.Choice(
466        title = _(u'Qualification Obtained'),
467        required = False,
468        readonly = False,
469        vocabulary = high_qual,
470        )
471    hq_matric_no = schema.TextLine(
472        title = _(u'Former Matric Number'),
473        required = False,
474        readonly = False,
475        )
476    hq_degree = schema.Choice(
477        title = _(u'Class of Degree'),
478        required = False,
479        readonly = False,
480        vocabulary = high_grade,
481        )
482    hq_school = schema.TextLine(
483        title = _(u'Institution Attended'),
484        required = False,
485        readonly = False,
486        )
487    hq_session = schema.TextLine(
488        title = _(u'Years Attended'),
489        required = False,
490        readonly = False,
491        )
492    hq_disc = schema.TextLine(
493        title = _(u'Discipline'),
494        required = False,
495        readonly = False,
496        )
497    fst_sit_fname = schema.TextLine(
498        title = _(u'Full Name'),
499        required = False,
500        readonly = False,
501        )
502    fst_sit_no = schema.TextLine(
503        title = _(u'Exam Number'),
504        required = False,
505        readonly = False,
506        )
507    fst_sit_date = FormattedDate(
508        title = _(u'Exam Date'),
509        required = False,
510        readonly = False,
511        show_year = True,
512        )
513    fst_sit_type = schema.Choice(
514        title = _(u'Exam Type'),
515        required = False,
516        readonly = False,
517        vocabulary = exam_types,
518        )
519    fst_sit_results = schema.List(
520        title = _(u'Exam Results'),
521        value_type = ResultEntryField(),
522        required = False,
523        readonly = False,
524        defaultFactory=list,
525        )
526    scd_sit_fname = schema.TextLine(
527        title = _(u'Full Name'),
528        required = False,
529        readonly = False,
530        )
531    scd_sit_no = schema.TextLine(
532        title = _(u'Exam Number'),
533        required = False,
534        readonly = False,
535        )
536    scd_sit_date = FormattedDate(
537        title = _(u'Exam Date'),
538        required = False,
539        readonly = False,
540        show_year = True,
541        )
542    scd_sit_type = schema.Choice(
543        title = _(u'Exam Type'),
544        required = False,
545        readonly = False,
546        vocabulary = exam_types,
547        )
548    scd_sit_results = schema.List(
549        title = _(u'Exam Results'),
550        value_type = ResultEntryField(),
551        required = False,
552        readonly = False,
553        defaultFactory=list,
554        )
555    jamb_subjects = schema.Text(
556        title = _(u'Subjects and Scores'),
557        required = False,
558        )
559    jamb_subjects_list = schema.List(
560        title = _(u'JAMB Subjects'),
561        required = False,
562        defaultFactory=list,
563        value_type = schema.Choice(
564            vocabulary = jambsubjects
565            #source = JAMBSubjectSource(),
566            ),
567        )
568    jamb_score = schema.Int(
569        title = _(u'Total JAMB Score'),
570        required = False,
571        )
572    #jamb_age = schema.Int(
573    #    title = _(u'Age (provided by JAMB)'),
574    #    required = False,
575    #    )
576    jamb_reg_number = schema.TextLine(
577        title = _(u'JAMB Registration Number'),
578        required = False,
579        )
580    notice = schema.Text(
581        title = _(u'Notice'),
582        required = False,
583        )
584    screening_venue = schema.TextLine(
585        title = _(u'Screening Venue'),
586        required = False,
587        )
588    screening_date = schema.TextLine(
589        title = _(u'Screening Date'),
590        required = False,
591        )
592    screening_score = schema.Int(
593        title = _(u'Screening Score (%)'),
594        required = False,
595        )
596    aggregate = schema.Int(
597        title = _(u'Aggregate Score (%)'),
598        description = _(u'(average of relative JAMB and PUTME scores)'),
599        required = False,
600        )
601    result_uploaded = schema.Bool(
602        title = _(u'Result uploaded'),
603        default = False,
604        required = False,
605        )
606    student_id = schema.TextLine(
607        title = _(u'Student Id'),
608        required = False,
609        readonly = False,
610        )
611    course_admitted = schema.Choice(
612        title = _(u'Admitted Course of Study'),
613        source = CertificateSource(),
614        required = False,
615        )
616    locked = schema.Bool(
617        title = _(u'Form locked'),
618        default = False,
619        required = False,
620        )
621
622ICustomUGApplicant[
623    'locked'].order =  IApplicantBaseData['suspended'].order
624ICustomUGApplicant[
625    'result_uploaded'].order =  ICustomUGApplicant['suspended'].order
626
627class ICustomPGApplicant(INigeriaPGApplicant):
628    """A postgraduate applicant.
629
630    This interface defines the least common multiple of all fields
631    in pg application forms. In customized forms, fields can be excluded by
632    adding them to the PG_OMIT* tuples.
633    """
634
635    referees = schema.List(
636        title = _(u'Referees'),
637        value_type = RefereeEntryField(),
638        required = False,
639        defaultFactory=list,
640        )
641
642ICustomPGApplicant[
643    'referees'].order =  INigeriaPGApplicant['emp2_reason'].order
644
645class ICustomApplicant(ICustomUGApplicant, ICustomPGApplicant,
646    IUnibenRegistration, ITranscriptApplicant):
647    """An interface for both types of applicants.
648
649    Attention: The ICustomPGApplicant field seetings will be overwritten
650    by ICustomPGApplicant field settings. If a field is defined
651    in both interfaces zope.schema validates only against the
652    constraints in ICustomUGApplicant. This does not affect the forms
653    since they are build on either ICustomUGApplicant or ICustomPGApplicant.
654    """
655
656    def writeLogMessage(view, comment):
657        """Adds an INFO message to the log file
658        """
659
660    def createStudent():
661        """Create a student object from applicant data
662        and copy applicant object.
663        """
664
665class ICustomUGApplicantEdit(ICustomUGApplicant):
666    """An undergraduate applicant interface for edit forms.
667
668    Here we can repeat the fields from base data and set the
669    `required` and `readonly` attributes to True to further restrict
670    the data access. Or we can allow only certain certificates to be
671    selected by choosing the appropriate source.
672
673    We cannot omit fields here. This has to be done in the
674    respective form page.
675    """
676
677    email = schema.ASCIILine(
678        title = _(u'Email Address'),
679        required = True,
680        constraint=validate_email,
681        )
682    date_of_birth = FormattedDate(
683        title = _(u'Date of Birth'),
684        required = True,
685        show_year = True,
686        )
687
688ICustomUGApplicantEdit[
689    'date_of_birth'].order = ICustomUGApplicant['date_of_birth'].order
690ICustomUGApplicantEdit[
691    'email'].order = ICustomUGApplicant['email'].order
692
693class ICustomPGApplicantEdit(INigeriaPGApplicantEdit):
694    """A postgraduate applicant interface for editing.
695
696    Here we can repeat the fields from base data and set the
697    `required` and `readonly` attributes to True to further restrict
698    the data access. Or we can allow only certain certificates to be
699    selected by choosing the appropriate source.
700
701    We cannot omit fields here. This has to be done in the
702    respective form page.
703    """
704
705    referees = schema.List(
706        title = _(u'Referees'),
707        value_type = RefereeEntryField(),
708        required = False,
709        defaultFactory=list,
710        )
711
712ICustomPGApplicantEdit[
713    'referees'].order =  INigeriaPGApplicantEdit['emp2_reason'].order
714
715class ICustomApplicantOnlinePayment(INigeriaApplicantOnlinePayment):
716    """An applicant payment via payment gateways.
717
718    """
719
720class IPUTMEApplicantEdit(ICustomUGApplicant):
721    """An undergraduate applicant interface for editing.
722
723    Here we can repeat the fields from base data and set the
724    `required` and `readonly` attributes to True to further restrict
725    the data access. Or we can allow only certain certificates to be
726    selected by choosing the appropriate source.
727
728    We cannot omit fields here. This has to be done in the
729    respective form page.
730    """
731
732    email = schema.ASCIILine(
733        title = _(u'Email Address'),
734        required = True,
735        constraint=validate_email,
736        )
737    date_of_birth = FormattedDate(
738        title = _(u'Date of Birth'),
739        required = True,
740        show_year = True,
741        )
742    nationality = schema.Choice(
743        source = nats_vocab,
744        title = _(u'Nationality'),
745        required = True,
746        )
747
748IPUTMEApplicantEdit[
749    'date_of_birth'].order =  ICustomUGApplicant['date_of_birth'].order
750IPUTMEApplicantEdit[
751    'email'].order =  ICustomUGApplicant['email'].order
752IPUTMEApplicantEdit[
753    'nationality'].order =  ICustomUGApplicant['nationality'].order
754
755class ICustomApplicantUpdateByRegNo(INigeriaApplicantUpdateByRegNo):
756    """Representation of an applicant.
757
758    Skip regular reg_number validation if reg_number is used for finding
759    the applicant object.
760    """
Note: See TracBrowser for help on using the repository browser.