source: main/kofacustom.nigeria/trunk/src/kofacustom/nigeria/applicants/interfaces.py @ 13334

Last change on this file since 13334 was 13290, checked in by Henrik Bettermann, 9 years ago

Add hq fullname field.

  • Property svn:keywords set to Id
File size: 21.3 KB
Line 
1## $Id: interfaces.py 13290 2015-10-07 09:13:57Z henrik $
2##
3## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
18"""Customized interfaces of the university application package.
19"""
20
21from zope import schema
22from zope.component import getUtility
23from zope.schema import getFields
24from waeup.kofa.applicants.interfaces import (
25    contextual_reg_num_source,
26    IApplicantBaseData,
27    AppCatCertificateSource, CertificateSource)
28from waeup.kofa.schoolgrades import ResultEntryField
29from waeup.kofa.interfaces import (
30    SimpleKofaVocabulary,
31    academic_sessions_vocab,
32    validate_email,
33    SubjectSource,
34    IKofaUtils)
35from waeup.kofa.schema import FormattedDate, TextLineChoice
36from waeup.kofa.students.vocabularies import nats_vocab, GenderSource
37from kofacustom.nigeria.interfaces import (
38    LGASource, high_qual, high_grade, exam_types)
39from kofacustom.nigeria.interfaces import MessageFactory as _
40from kofacustom.nigeria.payments.interfaces import INigeriaOnlinePayment
41
42jambsubjects = SimpleKofaVocabulary(
43    (_('Use of English'),'english_language'),
44    (_('Agricultural Science'),'agricultural_science'),
45    (_('Arabic'),'arabic'),
46    (_('Biology'),'biology'),
47    (_('Book Keeping'),'book_keeping'),
48    (_('Chemistry'),'chemistry'),
49    (_('Christian Religious Studies'),'christian_religious_studies'),
50    (_('Commerce'),'commerce'),
51    (_('Economics'),'economics'),
52    (_('Financial Accounting'),'financial_accounting'),
53    (_('Fine Art'),'fine_art'),
54    (_('Food and Nutrition'),'food_and_nutrition'),
55    (_('French'),'french'),
56    (_('Geography'),'geography'),
57    (_('German'),'german'),
58    (_('Government'),'government'),
59    (_('Hausa'),'hausa'),
60    (_('Home Economics'),'home_economics'),
61    (_('History'),'history'),
62    (_('Igbo'),'igbo'),
63    (_('Literature in English'),'literature_in_english'),
64    (_('Literature in Nigerian Languages'),'literature_in_nigerian_languages'),
65    (_('Mathematics'),'mathematics'),
66    (_('Music'),'music'),
67    (_('Physics'),'physics'),
68    (_('Yoruba'),'yoruba'),
69    )
70
71# Define a validation method for jamb subjects
72class NotExactNumberOfItems(schema.ValidationError):
73    __doc__ = u"Not exactly 4 items selected."
74
75def four_items(value):
76    if len(value) != 4:
77        raise NotExactNumberOfItems(value)
78    return True
79
80class JAMBSubjectSource(SubjectSource):
81    """A source for school subjects used in exam documentation.
82    """
83
84    def getTitle(self, value):
85        subjects_dict = getUtility(IKofaUtils).EXAM_SUBJECTS_DICT
86        return "%s" % subjects_dict[value]
87
88# Fields to be omitted in all display forms. course_admitted is
89# rendered separately.
90
91OMIT_DISPLAY_FIELDS = ('locked', 'course_admitted',
92    'result_uploaded', 'suspended', 'special_application')
93
94# UG students are all undergraduate students.
95UG_OMIT_DISPLAY_FIELDS = OMIT_DISPLAY_FIELDS + ('jamb_subjects_list',)
96UG_OMIT_PDF_FIELDS = UG_OMIT_DISPLAY_FIELDS + ('phone',)
97UG_OMIT_MANAGE_FIELDS = ('special_application','jamb_subjects_list',)
98UG_OMIT_EDIT_FIELDS = UG_OMIT_MANAGE_FIELDS + OMIT_DISPLAY_FIELDS + (
99    'student_id',
100    'notice',
101    'screening_score',
102    'screening_venue',
103    'screening_date',
104    'jamb_age',
105    'jamb_subjects',
106    'jamb_score',
107    'jamb_reg_number',
108    'aggregate')
109
110# CBT is a subgroup of UG with the same interface.
111CBT_OMIT_FIELDS = (
112    'hq_type', 'hq_matric_no',
113    'hq_degree', 'hq_school',
114    'hq_session', 'hq_disc',
115    'aggregate', 'jamb_subjects')
116CBT_OMIT_DISPLAY_FIELDS = OMIT_DISPLAY_FIELDS + CBT_OMIT_FIELDS
117CBT_OMIT_MANAGE_FIELDS = CBT_OMIT_FIELDS + ('special_application',)
118CBT_OMIT_EDIT_FIELDS = OMIT_DISPLAY_FIELDS + CBT_OMIT_FIELDS + (
119    'special_application',
120    'student_id',
121    'notice',
122    'screening_score',
123    'screening_venue',
124    'screening_date',
125    #'jamb_age',
126    #'jamb_subjects',
127    #'jamb_score',
128    #'jamb_reg_number',
129    )
130CBT_OMIT_PDF_FIELDS = CBT_OMIT_DISPLAY_FIELDS + ('phone',)
131
132# PUTME is a subgroup of UG with the same interface.
133PUTME_OMIT_FIELDS = (
134    'hq_type', 'hq_matric_no',
135    'hq_degree', 'hq_school',
136    'hq_session', 'hq_disc', 'jamb_subjects_list')
137PUTME_OMIT_DISPLAY_FIELDS = OMIT_DISPLAY_FIELDS + PUTME_OMIT_FIELDS
138PUTME_OMIT_MANAGE_FIELDS = UG_OMIT_MANAGE_FIELDS + PUTME_OMIT_FIELDS
139PUTME_OMIT_EDIT_FIELDS = UG_OMIT_EDIT_FIELDS + PUTME_OMIT_FIELDS + (
140    'firstname', 'middlename', 'lastname', 'sex',
141    'course1', 'lga')
142PUTME_OMIT_PDF_FIELDS = PUTME_OMIT_DISPLAY_FIELDS + ('phone',)
143PUTME_OMIT_RESULT_SLIP_FIELDS = PUTME_OMIT_DISPLAY_FIELDS + (
144    'phone',
145    'date_of_birth', 'sex',
146    'nationality', 'lga', #'perm_address',
147    'course2', 'screening_venue',
148    'screening_date')
149
150# PUDE is a subgroup of UG with the same interface.
151PUDE_OMIT_FIELDS = (
152    'jamb_subjects','jamb_score', 'jamb_age', 'aggregate', 'jamb_subjects_list')
153PUDE_OMIT_DISPLAY_FIELDS = OMIT_DISPLAY_FIELDS + PUDE_OMIT_FIELDS
154PUDE_OMIT_MANAGE_FIELDS = UG_OMIT_MANAGE_FIELDS + PUDE_OMIT_FIELDS
155PUDE_OMIT_EDIT_FIELDS = set(UG_OMIT_EDIT_FIELDS + PUDE_OMIT_FIELDS + (
156    'firstname', 'middlename', 'lastname', 'sex',
157    'course1', 'lga'))
158PUDE_OMIT_PDF_FIELDS = PUDE_OMIT_DISPLAY_FIELDS + ('phone',)
159PUDE_OMIT_RESULT_SLIP_FIELDS = PUDE_OMIT_DISPLAY_FIELDS + (
160    'phone',
161    'date_of_birth', 'sex',
162    'nationality', 'lga', #'perm_address',
163    'course2', 'screening_venue',
164    'screening_date')
165
166# PG has its own interface
167PG_OMIT_DISPLAY_FIELDS = OMIT_DISPLAY_FIELDS
168PG_OMIT_PDF_FIELDS = PG_OMIT_DISPLAY_FIELDS + ('phone',)
169PG_OMIT_MANAGE_FIELDS = ('special_application',)
170PG_OMIT_EDIT_FIELDS = PG_OMIT_MANAGE_FIELDS + PG_OMIT_DISPLAY_FIELDS + (
171    'student_id', 'notice',
172    'screening_score', 'screening_venue',
173    'screening_date',)
174
175class INigeriaUGApplicant(IApplicantBaseData):
176    """An undergraduate applicant.
177
178    This interface defines the least common multiple of all fields
179    in ug application forms. In customized forms, fields can be excluded by
180    adding them to the UG_OMIT* tuples.
181    """
182
183    nationality = schema.Choice(
184        source = nats_vocab,
185        title = _(u'Nationality'),
186        required = False,
187        )
188    lga = schema.Choice(
189        source = LGASource(),
190        title = _(u'State/LGA (Nigerians only)'),
191        required = False,
192        )
193    #perm_address = schema.Text(
194    #    title = _(u'Permanent Address'),
195    #    required = False,
196    #    )
197    course1 = schema.Choice(
198        title = _(u'1st Choice Course of Study'),
199        source = AppCatCertificateSource(),
200        required = True,
201        )
202    course2 = schema.Choice(
203        title = _(u'2nd Choice Course of Study'),
204        source = AppCatCertificateSource(),
205        required = False,
206        )
207    hq_type = schema.Choice(
208        title = _(u'Qualification Obtained'),
209        required = False,
210        readonly = False,
211        vocabulary = high_qual,
212        )
213    hq_matric_no = schema.TextLine(
214        title = _(u'Former Matric Number'),
215        required = False,
216        readonly = False,
217        )
218    hq_degree = schema.Choice(
219        title = _(u'Class of Degree'),
220        required = False,
221        readonly = False,
222        vocabulary = high_grade,
223        )
224    hq_school = schema.TextLine(
225        title = _(u'Institution Attended'),
226        required = False,
227        readonly = False,
228        )
229    hq_session = schema.TextLine(
230        title = _(u'Years Attended'),
231        required = False,
232        readonly = False,
233        )
234    hq_disc = schema.TextLine(
235        title = _(u'Discipline'),
236        required = False,
237        readonly = False,
238        )
239    jamb_subjects = schema.Text(
240        title = _(u'Subjects and Scores'),
241        required = False,
242        )
243    jamb_subjects_list = schema.List(
244        title = _(u'JAMB Subjects'),
245        required = False,
246        default = [],
247        value_type = schema.Choice(
248            vocabulary = jambsubjects
249            #source = JAMBSubjectSource(),
250            ),
251        )
252    jamb_score = schema.Int(
253        title = _(u'Total JAMB Score'),
254        required = False,
255        )
256    #jamb_age = schema.Int(
257    #    title = _(u'Age (provided by JAMB)'),
258    #    required = False,
259    #    )
260    jamb_reg_number = schema.TextLine(
261        title = _(u'JAMB Registration Number'),
262        required = False,
263        )
264    notice = schema.Text(
265        title = _(u'Notice'),
266        required = False,
267        )
268    screening_venue = schema.TextLine(
269        title = _(u'Screening Venue'),
270        required = False,
271        )
272    screening_date = schema.TextLine(
273        title = _(u'Screening Date'),
274        required = False,
275        )
276    screening_score = schema.Int(
277        title = _(u'Screening Score (%)'),
278        required = False,
279        )
280    aggregate = schema.Int(
281        title = _(u'Aggregate Score (%)'),
282        description = _(u'(average of relative JAMB and PUTME scores)'),
283        required = False,
284        )
285    result_uploaded = schema.Bool(
286        title = _(u'Result uploaded'),
287        default = False,
288        required = False,
289        )
290    student_id = schema.TextLine(
291        title = _(u'Student Id'),
292        required = False,
293        readonly = False,
294        )
295    course_admitted = schema.Choice(
296        title = _(u'Admitted Course of Study'),
297        source = CertificateSource(),
298        required = False,
299        )
300    locked = schema.Bool(
301        title = _(u'Form locked'),
302        default = False,
303        required = False,
304        )
305
306INigeriaUGApplicant[
307    'locked'].order =  IApplicantBaseData['suspended'].order
308INigeriaUGApplicant[
309    'result_uploaded'].order =  INigeriaUGApplicant['suspended'].order
310
311class INigeriaPGApplicant(IApplicantBaseData):
312    """A postgraduate applicant.
313
314    This interface defines the least common multiple of all fields
315    in pg application forms. In customized forms, fields can be excluded by
316    adding them to the PG_OMIT* tuples.
317    """
318
319    nationality = schema.Choice(
320        source = nats_vocab,
321        title = _(u'Nationality'),
322        required = True,
323        )
324    lga = schema.Choice(
325        source = LGASource(),
326        title = _(u'State/LGA (Nigerians only)'),
327        required = False,
328        )
329    #perm_address = schema.Text(
330    #    title = _(u'Permanent Address'),
331    #    required = False,
332    #    )
333    course1 = schema.Choice(
334        title = _(u'1st Choice Course of Study'),
335        source = AppCatCertificateSource(),
336        required = True,
337        )
338    course2 = schema.Choice(
339        title = _(u'2nd Choice Course of Study'),
340        source = AppCatCertificateSource(),
341        required = False,
342        )
343    hq_type = schema.Choice(
344        title = _(u'Qualification Obtained'),
345        required = False,
346        readonly = False,
347        vocabulary = high_qual,
348        )
349    hq_fname = schema.TextLine(
350        title = _(u'Full Name'),
351        required = False,
352        readonly = False,
353        )
354    hq_matric_no = schema.TextLine(
355        title = _(u'Former Matric Number'),
356        required = False,
357        readonly = False,
358        )
359    hq_degree = schema.Choice(
360        title = _(u'Class of Degree'),
361        required = False,
362        readonly = False,
363        vocabulary = high_grade,
364        )
365    hq_school = schema.TextLine(
366        title = _(u'Institution Attended'),
367        required = False,
368        readonly = False,
369        )
370    hq_session = schema.TextLine(
371        title = _(u'Years Attended'),
372        required = False,
373        readonly = False,
374        )
375    hq_disc = schema.TextLine(
376        title = _(u'Discipline'),
377        required = False,
378        readonly = False,
379        )
380    fst_sit_fname = schema.TextLine(
381        title = _(u'Full Name'),
382        required = False,
383        readonly = False,
384        )
385    fst_sit_no = schema.TextLine(
386        title = _(u'Exam Number'),
387        required = False,
388        readonly = False,
389        )
390    fst_sit_date = FormattedDate(
391        title = _(u'Exam Date'),
392        required = False,
393        readonly = False,
394        show_year = True,
395        )
396    fst_sit_type = schema.Choice(
397        title = _(u'Exam Type'),
398        required = False,
399        readonly = False,
400        vocabulary = exam_types,
401        )
402    fst_sit_results = schema.List(
403        title = _(u'Exam Results'),
404        value_type = ResultEntryField(),
405        required = False,
406        readonly = False,
407        default = [],
408        )
409    scd_sit_fname = schema.TextLine(
410        title = _(u'Full Name'),
411        required = False,
412        readonly = False,
413        )
414    scd_sit_no = schema.TextLine(
415        title = _(u'Exam Number'),
416        required = False,
417        readonly = False,
418        )
419    scd_sit_date = FormattedDate(
420        title = _(u'Exam Date'),
421        required = False,
422        readonly = False,
423        show_year = True,
424        )
425    scd_sit_type = schema.Choice(
426        title = _(u'Exam Type'),
427        required = False,
428        readonly = False,
429        vocabulary = exam_types,
430        )
431    scd_sit_results = schema.List(
432        title = _(u'Exam Results'),
433        value_type = ResultEntryField(),
434        required = False,
435        readonly = False,
436        default = [],
437        )
438    # Replaced by first and second sitting
439    #pp_school = schema.Choice(
440    #    title = _(u'Qualification Obtained'),
441    #    required = False,
442    #    readonly = False,
443    #    vocabulary = exam_types,
444    #    )
445    presently_inst = schema.TextLine(
446        title = _(u'If yes, name of institution'),
447        required = False,
448        readonly = False,
449        )
450    nysc_year = schema.Int(
451        title = _(u'Nysc Year'),
452        required = False,
453        readonly = False,
454        )
455    nysc_lga = schema.Choice(
456        source = LGASource(),
457        title = _(u'Nysc Location'),
458        required = False,
459        )
460    employer = schema.TextLine(
461        title = _(u'Employer'),
462        required = False,
463        readonly = False,
464        )
465    emp_position = schema.TextLine(
466        title = _(u'Employer Position'),
467        required = False,
468        readonly = False,
469        )
470    emp_start = FormattedDate(
471        title = _(u'Start Date'),
472        required = False,
473        readonly = False,
474        show_year = True,
475        )
476    emp_end = FormattedDate(
477        title = _(u'End Date'),
478        required = False,
479        readonly = False,
480        show_year = True,
481        )
482    emp_reason = schema.TextLine(
483        title = _(u'Reason for Leaving'),
484        required = False,
485        readonly = False,
486        )
487    employer2 = schema.TextLine(
488        title = _(u'2nd Employer'),
489        required = False,
490        readonly = False,
491        )
492    emp2_position = schema.TextLine(
493        title = _(u'2nd Employer Position'),
494        required = False,
495        readonly = False,
496        )
497    emp2_start = FormattedDate(
498        title = _(u'Start Date'),
499        required = False,
500        readonly = False,
501        show_year = True,
502        )
503    emp2_end = FormattedDate(
504        title = _(u'End Date'),
505        required = False,
506        readonly = False,
507        show_year = True,
508        )
509    emp2_reason = schema.TextLine(
510        title = _(u'Reason for Leaving'),
511        required = False,
512        readonly = False,
513        )
514    notice = schema.Text(
515        title = _(u'Notice'),
516        required = False,
517        readonly = False,
518        )
519    screening_venue = schema.TextLine(
520        title = _(u'Screening Venue'),
521        required = False,
522        )
523    screening_date = schema.TextLine(
524        title = _(u'Screening Date'),
525        required = False,
526        )
527    screening_score = schema.Int(
528        title = _(u'Screening Score (%)'),
529        required = False,
530        )
531    student_id = schema.TextLine(
532        title = _(u'Student Id'),
533        required = False,
534        readonly = False,
535        )
536    course_admitted = schema.Choice(
537        title = _(u'Admitted Course of Study'),
538        source = CertificateSource(),
539        required = False,
540        readonly = False,
541        )
542    locked = schema.Bool(
543        title = _(u'Form locked'),
544        default = False,
545        required = False,
546        )
547
548INigeriaPGApplicant[
549    'locked'].order =  IApplicantBaseData['suspended'].order
550
551# PRE is used by Uniben
552#  med: "it is as named... PRE - DEGREE... much like a 1 year diploma programme"
553PRE_OMIT_FIELDS = tuple([
554    i for i in getFields(INigeriaPGApplicant).keys()
555        if i[:3] in ('hq_', 'emp', 'nys')])
556PRE_OMIT_DISPLAY_FIELDS = OMIT_DISPLAY_FIELDS + PRE_OMIT_FIELDS
557PRE_OMIT_MANAGE_FIELDS = PG_OMIT_MANAGE_FIELDS + PRE_OMIT_FIELDS
558PRE_OMIT_EDIT_FIELDS = set(PG_OMIT_EDIT_FIELDS + PRE_OMIT_FIELDS)
559PRE_OMIT_PDF_FIELDS = PRE_OMIT_DISPLAY_FIELDS
560PRE_OMIT_RESULT_SLIP_FIELDS = PRE_OMIT_DISPLAY_FIELDS
561
562class INigeriaApplicant(INigeriaUGApplicant, INigeriaPGApplicant):
563    """An interface for both types of applicants.
564
565    Attention: The INigeriaPGApplicant field seetings will be overwritten
566    by INigeriaPGApplicant field settings. If a field is defined
567    in both interfaces zope.schema validates only against the
568    constraints in INigeriaUGApplicant. This does not affect the forms
569    since they are build on either INigeriaUGApplicant or INigeriaPGApplicant.
570    """
571
572    def writeLogMessage(view, comment):
573        """Adds an INFO message to the log file
574        """
575
576    def createStudent():
577        """Create a student object from applicant data
578        and copy applicant object.
579        """
580
581class INigeriaUGApplicantEdit(INigeriaUGApplicant):
582    """An undergraduate applicant interface for edit forms.
583
584    Here we can repeat the fields from base data and set the
585    `required` and `readonly` attributes to True to further restrict
586    the data access. Or we can allow only certain certificates to be
587    selected by choosing the appropriate source.
588
589    We cannot omit fields here. This has to be done in the
590    respective form page.
591    """
592
593    email = schema.ASCIILine(
594        title = _(u'Email Address'),
595        required = True,
596        constraint=validate_email,
597        )
598    date_of_birth = FormattedDate(
599        title = _(u'Date of Birth'),
600        required = True,
601        show_year = True,
602        )
603    jamb_subjects_list = schema.List(
604        title = _(u'JAMB Subjects'),
605        description = _(u'Select four subjects.'),
606        required = True,
607        constraint = four_items,
608        value_type = schema.Choice(
609            vocabulary = jambsubjects
610            #source = JAMBSubjectSource(),
611            ),
612        )
613
614INigeriaUGApplicantEdit[
615    'date_of_birth'].order = INigeriaUGApplicant['date_of_birth'].order
616INigeriaUGApplicantEdit[
617    'email'].order = INigeriaUGApplicant['email'].order
618INigeriaUGApplicantEdit[
619    'jamb_subjects_list'].order = INigeriaUGApplicant['jamb_subjects_list'].order
620
621class INigeriaPGApplicantEdit(INigeriaPGApplicant):
622    """A postgraduate applicant interface for editing.
623
624    Here we can repeat the fields from base data and set the
625    `required` and `readonly` attributes to True to further restrict
626    the data access. Or we can allow only certain certificates to be
627    selected by choosing the appropriate source.
628
629    We cannot omit fields here. This has to be done in the
630    respective form page.
631    """
632
633    email = schema.ASCIILine(
634        title = _(u'Email Address'),
635        required = True,
636        constraint=validate_email,
637        )
638    date_of_birth = FormattedDate(
639        title = _(u'Date of Birth'),
640        required = True,
641        show_year = True,
642        )
643
644INigeriaPGApplicantEdit[
645    'date_of_birth'].order =  INigeriaPGApplicant['date_of_birth'].order
646INigeriaPGApplicantEdit[
647    'email'].order =  INigeriaPGApplicant['email'].order
648
649class INigeriaApplicantOnlinePayment(INigeriaOnlinePayment):
650    """An applicant payment via payment gateways.
651    """
652
653class IPUTMEApplicantEdit(INigeriaUGApplicant):
654    """An undergraduate applicant interface for editing.
655
656    Here we can repeat the fields from base data and set the
657    `required` and `readonly` attributes to True to further restrict
658    the data access. Or we can allow only certain certificates to be
659    selected by choosing the appropriate source.
660
661    We cannot omit fields here. This has to be done in the
662    respective form page.
663    """
664    email = schema.ASCIILine(
665        title = _(u'Email Address'),
666        required = True,
667        constraint=validate_email,
668        )
669    date_of_birth = FormattedDate(
670        title = _(u'Date of Birth'),
671        required = True,
672        show_year = True,
673        )
674    nationality = schema.Choice(
675        source = nats_vocab,
676        title = _(u'Nationality'),
677        required = True,
678        )
679
680IPUTMEApplicantEdit[
681    'date_of_birth'].order =  INigeriaUGApplicant['date_of_birth'].order
682IPUTMEApplicantEdit[
683    'email'].order =  INigeriaUGApplicant['email'].order
684IPUTMEApplicantEdit[
685    'nationality'].order =  INigeriaUGApplicant['nationality'].order
686
687class INigeriaApplicantUpdateByRegNo(INigeriaApplicant):
688    """Representation of an applicant.
689
690    Skip regular reg_number validation if reg_number is used for finding
691    the applicant object.
692    """
693    reg_number = schema.TextLine(
694        title = u'Registration Number',
695        required = False,
696        )
Note: See TracBrowser for help on using the repository browser.