source: main/waeup.sirp/trunk/src/waeup/sirp/applicants/jambtables/interfaces.py @ 5742

Last change on this file since 5742 was 5723, checked in by uli, 14 years ago

Add interface for JambData? root.

File size: 20.8 KB
Line 
1##
2## interfaces.py
3## Login : <uli@pu.smp.net>
4## Started on  Sun Jun 27 11:06:23 2010 Uli Fouquet
5## $Id$
6##
7## Copyright (C) 2010 Uli Fouquet
8## This program is free software; you can redistribute it and/or modify
9## it under the terms of the GNU General Public License as published by
10## the Free Software Foundation; either version 2 of the License, or
11## (at your option) any later version.
12##
13## This program is distributed in the hope that it will be useful,
14## but WITHOUT ANY WARRANTY; without even the implied warranty of
15## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16## GNU General Public License for more details.
17##
18## You should have received a copy of the GNU General Public License
19## along with this program; if not, write to the Free Software
20## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21##
22"""Interfaces for JAMB data tables and related components.
23"""
24import os
25import waeup.sirp.browser
26from hurry.file import HurryFile
27from zc.sourcefactory.basic import BasicSourceFactory
28from zope import schema
29from zope.app.file.interfaces import IImage
30from zope.interface import Interface, Attribute
31from zope.pluggableauth.interfaces import IPrincipalInfo
32from zope.security.interfaces import IGroupClosureAwarePrincipal as IPrincipal
33from waeup.sirp.interfaces import IWAeUPObject
34from waeup.sirp.image.schema import ImageFile
35
36IMAGE_PATH = os.path.join(
37    os.path.dirname(waeup.sirp.browser.__file__),
38    'static'
39    )
40DEFAULT_PASSPORT_IMAGE_MALE = HurryFile(
41    'passport.jpg',
42    open(os.path.join(IMAGE_PATH, 'placeholder_m.jpg')).read(),
43    )
44DEFAULT_PASSPORT_IMAGE_FEMALE = HurryFile(
45    'passport.jpg',
46    open(os.path.join(IMAGE_PATH, 'placeholder_f.jpg')).read(),
47    )
48
49class GenderSource(BasicSourceFactory):
50    """A gender source delivers basically a mapping
51       ``{'m': 'male', 'f': 'female'}``
52
53       Using a source, we make sure that the tokens (which are
54       stored/expected for instance from CSV files) are something one
55       can expect and not cryptic IntIDs.
56    """
57    def getValues(self):
58        return ['m', 'f']
59
60    def getToken(self, value):
61        return value[0].lower()
62       
63    def getTitle(self, value):
64        if value == 'm':
65            return 'male'
66        if value == 'f':
67            return 'female'
68
69class IJAMBDataRoot(IWAeUPObject):
70    """A container that holds JAMB data tables.
71    """
72   
73class IJAMBDataTable(IWAeUPObject):
74    """A table containing JAMB data.
75    """
76    import_datetime = schema.Datetime(
77        title = u'Datetime of import of contained data.',
78        required = False,
79        )
80
81    importer_username = schema.TextLine(
82        title = u'Name of user who initiated import.',
83        required = False,
84        )
85
86    def __iter__():
87        """An iterator over all data elements.
88        """
89
90    def keys():
91        """Get iterator over all registration numbers of data.
92        """
93
94    def items():
95        """Get iterator over tuples of registration numbers and datasets.
96        """
97
98    def clear():
99        """Clear all data contained.
100
101        This will also erase any import data.
102        """
103
104    def importFromCSV(filepath, username=None):
105        """Import data from filepath.
106
107        `filepath` - the path to the CSV file to import data from.
108
109        `username` - the (optional) username of the importing person.
110        """
111       
112class IResultEntry(IWAeUPObject):
113    subject = schema.TextLine(
114        title = u'Subject',
115        description = u'The subject',
116        required=False,
117        )
118    score = schema.TextLine(
119        title = u'Score',
120        description = u'The score',
121        required=False,
122        )
123
124class IApplicantBaseData(IWAeUPObject):
125    """The data for an applicant.
126
127    This is a base interface with no field (except ``reg_no``)
128    required. For use with importers, forms, etc., please use one of
129    the derived interfaces below, which set more fields to required
130    state, depending on use-case.
131    """
132    reg_no = schema.TextLine(
133        title = u'JAMB Registration Number',
134        )
135    access_code = schema.TextLine(
136        title = u'Access Code',
137        required = False,
138        )
139    serial = schema.TextLine(
140        title = u'Serial Number',
141        required = False,
142        )
143    course1 = schema.TextLine(
144        title = u'1st Choice Course of Study',
145        required = False,
146        )
147    course2 = schema.TextLine(
148        title = u'2nd Choice Course of Study',
149        required = False,
150        )
151    course3 = schema.TextLine(
152        title = u'3rd Choice Course of Study',
153        required = False,
154        )
155    firstname = schema.TextLine(
156        title = u'First Name',
157        required = False,
158        )
159    middlenames = schema.TextLine(
160        title = u'Middle Names',
161        required = False,
162        )
163    lastname = schema.TextLine(
164        title = u'Surname/Full Name',
165        required = False,
166        )
167    jamb_age = schema.Int(
168        title = u'Age (provided by JAMB)',
169        required = False,
170        )
171    date_of_birth = schema.Date(
172        title = u'Date of Birth',
173        required = False,
174        )
175    jamb_state = schema.TextLine(
176        title = u'State (provided by JAMB)',
177        required = False,
178        )
179    jamb_lga = schema.TextLine(
180        title = u'LGA (provided by JAMB)',
181        required = False,
182        )
183    lga = schema.TextLine(
184        # XXX: should be choice
185        title = u'State/LGA (confirmed by applicant)',
186        required = False,
187        )
188    sex = schema.Choice(
189        title = u'Sex',
190        source = GenderSource(),
191        default = u'm',
192        required = False,
193        )
194    email = schema.TextLine(
195        title = u'Email',
196        required = False,
197        )
198    phone = schema.TextLine(
199        title = u'Phone',
200        required = False,
201        )
202    #passport = schema.Bool(
203    #    title = u'Passport Photograph',
204    #    default = True,
205    #    required = False,
206    #    )
207    passport = ImageFile(
208        title = u'Passport Photograph',
209        default = DEFAULT_PASSPORT_IMAGE_MALE,
210        required = True,
211        )
212    aos = schema.TextLine(
213        # XXX: should be choice
214        title = u'Area of Specialisation',
215        required = False,
216        )
217    subj1 = schema.TextLine(
218        # XXX: should be choice
219        title = u'1st Choice of Study',
220        required = False,
221        )
222    subj2 = schema.TextLine(
223        # XXX: should be choice
224        title = u'2nd Choice of Study',
225        required = False,
226        )
227    subj3 = schema.TextLine(
228        # XXX: should be choice
229        title = u'3rd Choice of Study',
230        required = False,
231        )
232    #
233    # Higher Educational Data
234    #
235    hq_matric_no = schema.TextLine(
236        title = u'Former Matric Number',
237        required = False,
238        )
239    hq_type = schema.TextLine(
240        title = u'Higher Qualification',
241        required = False,
242        )
243    hq_grade = schema.TextLine(
244        title = u'Higher Qualification Grade',
245        required = False,
246        )
247    hq_school = schema.TextLine(
248        title = u'School Attended',
249        required = False,
250        )
251    hq_session = schema.TextLine(
252        title = u'Session Obtained',
253        required = False,
254        )
255    hq_disc = schema.TextLine(
256        title = u'Discipline',
257        required = False,
258        )
259    #
260    # First sitting data
261    #
262    fst_sit_fname = schema.TextLine(
263        title = u'Full Name',
264        required = False,
265        )
266    fst_sit_no = schema.TextLine(
267        title = u'Exam Number',
268        required = False,
269        )
270    fst_sit_date = schema.Date(
271        title = u'Exam Date (dd/mm/yyyy)',
272        required = False,
273        )
274    fst_sit_type = schema.TextLine(
275        # XXX: Should be choice
276        title = u'Exam Type',
277        required = False,
278        )
279    fst_sit_results = schema.List(
280        title = u'Results',
281        required = False,
282        value_type = schema.Object(
283            title = u'Entries',
284            schema = IResultEntry,
285            required = False,
286            )
287        )
288    scd_sit_fname = schema.TextLine(
289        title = u'Full Name',
290        required = False,
291        )
292    scd_sit_no = schema.TextLine(
293        title = u'Exam Number',
294        required = False,
295        )
296    scd_sit_date = schema.Date(
297        title = u'Exam Date (dd/mm/yyyy)',
298        required = False,
299        )
300    scd_sit_type = schema.TextLine(
301        # XXX: Should be choice
302        title = u'Exam Type',
303        required = False,
304        )
305    scd_sit_results = schema.TextLine(
306        # XXX: Should be nested list of choices
307        title = u'Results',
308        required = False,
309        )
310    #
311    # JAMB scores
312    #
313    eng_score = schema.TextLine(
314        title = u"'English' score",
315        required = False,
316        )
317    subj1score = schema.TextLine(
318        title = u'1st Choice of Study Score',
319        required = False,
320        )
321    subj2score = schema.TextLine(
322        title = u'2nd Choice of Study Score',
323        required = False,
324        )
325    subj3score = schema.TextLine(
326        title = u'3rd Choice of Study Score',
327        required = False,
328        )
329    # XXX: Total score???
330   
331    #
332    # Application Data
333    #
334    application_date = schema.Date(
335        title = u'Application Date',
336        required = False,
337        )
338    status = schema.TextLine(
339        # XXX: should be 'status' type
340        title = u'Application Status',
341        required = False,
342        )
343    screening_date = schema.Date(
344        title = u'Screening Date',
345        required = False,
346        )
347    screening_type = schema.TextLine(
348        # XXX: schould be choice
349        title = u'Screening Type',
350        required = False,
351        )
352    screening_score = schema.TextLine(
353        title = u'Screening Score',
354        required = False,
355        )
356    screening_venue = schema.TextLine(
357        title = u'Screening Venue',
358        required = False,
359        )
360    total_score = schema.TextLine(
361        title = u'Total Score',
362        required = False,
363        )
364    course_admitted = schema.TextLine(
365        # XXX: should be choice
366        title = u'Admitted Course of Study',
367        required = False,
368        )
369    department = schema.TextLine(
370        # XXX: if we have a course, dept. is not necessary
371        title = u'Department',
372        required = False,
373        )
374    faculty = schema.TextLine(
375        # XXX: if we have a course, faculty is not necessary
376        title = u'Faculty',
377        required = False,
378        )
379    entry_session = schema.TextLine(
380        # XXX: should be choice, should have sensible default: upcoming session
381        title = u'Entry Session',
382        required = False,
383        )
384    notice = schema.Text(
385        title = u'Notice',
386        required = False,
387        )
388    student_id = schema.TextLine(
389        title = u'Student ID',
390        required = False,
391        )
392    import_record_no = schema.TextLine(
393        title = u'Import Record No.',
394        required = False,
395        )
396    imported_by = schema.TextLine(
397        title = u'Imported By',
398        required = False,
399        )
400    import_date = schema.Datetime(
401        title = u'Import Date',
402        required = False,
403        )
404    import_from = schema.TextLine(
405        title = u'Import Source',
406        required = False,
407        )
408
409   
410class IApplicant(IApplicantBaseData):
411    """An applicant.
412
413    This is basically the applicant base data. Here we repeat the
414    fields from base data only with the `required` attribute of
415    required attributes set to True (which is the default).
416    """
417    access_code = schema.TextLine(
418        title = u'Access Code',
419        )
420    course1 = schema.TextLine(
421        title = u'1st Choice Course of Study',
422        )
423    firstname = schema.TextLine(
424        title = u'First Name',
425        )
426    middlenames = schema.TextLine(
427        title = u'Middle Names',
428        )
429    lastname = schema.TextLine(
430        title = u'Surname/Full Name',
431        )
432    date_of_birth = schema.Date(
433        title = u'Date of Birth',
434        )
435    jamb_state = schema.TextLine(
436        title = u'State (provided by JAMB)',
437        )
438    jamb_lga = schema.TextLine(
439        title = u'LGA (provided by JAMB)',
440        )
441    lga = schema.TextLine(
442        # XXX: should be choice
443        title = u'State/LGA (confirmed by applicant)',
444        )
445    sex = schema.Choice(
446        title = u'Sex',
447        source = GenderSource(),
448        default = u'm',
449        )
450    #passport = schema.Bool(
451    #    title = u'Passport Photograph',
452    #    default = True,
453    #    )
454    passport = ImageFile(
455        title = u'Passport Photograph',
456        default = DEFAULT_PASSPORT_IMAGE_MALE,
457        required = True,
458        )
459    #
460    # Higher Educational Data
461    #
462
463    #
464    # First sitting data
465    #
466    fst_sit_fname = schema.TextLine(
467        title = u'Full Name',
468        )
469
470    #
471    # Second sitting data
472    #
473    scd_sit_fname = schema.TextLine(
474        title = u'Full Name',
475        )
476    #
477    # JAMB scores
478    #
479   
480    #
481    # Application Data
482    #
483    application_date = schema.Date(
484        title = u'Application Date',
485        )
486    status = schema.TextLine(
487        # XXX: should be 'status' type
488        title = u'Application Status',
489        )
490    screening_date = schema.Date(
491        title = u'Screening Date',
492        )
493    screening_type = schema.TextLine(
494        # XXX: schould be choice
495        title = u'Screening Type',
496        )
497    screening_score = schema.TextLine(
498        title = u'Screening Score',
499        )
500    entry_session = schema.TextLine(
501        # XXX: should be choice
502        # XXX: should have sensible default: upcoming session
503        title = u'Entry Session',
504        )
505    import_record_no = schema.TextLine(
506        title = u'Import Record No.',
507        )
508    imported_by = schema.TextLine(
509        title = u'Imported By',
510        )
511    import_date = schema.Datetime(
512        title = u'Import Date',
513        )
514    import_from = schema.TextLine(
515        title = u'Import Source',
516        )
517
518class IApplicantPDEEditData(IWAeUPObject):
519    """The data set presented to PDE applicants.
520    """
521    reg_no = schema.TextLine(
522        title = u'JAMB Registration Number',
523        readonly = True,
524        )
525    access_code = schema.TextLine(
526        title = u'Access Code',
527        readonly = True,
528        )
529    course1 = schema.TextLine(
530        title = u'1st Choice Course of Study',
531        readonly = True,
532        )
533    course2 = schema.TextLine(
534        title = u'2nd Choice Course of Study',
535        required = False,
536        )
537    course3 = schema.TextLine(
538        title = u'3rd Choice Course of Study',
539        required = False,
540        )
541    lastname = schema.TextLine(
542        title = u'Name',
543        readonly = True,
544        )
545    jamb_age = schema.Int(
546        title = u'Age',
547        readonly = True,
548        )
549    date_of_birth = schema.Date(
550        title = u'Date of Birth',
551        required = True,
552        )
553    jamb_state = schema.TextLine(
554        title = u'State (provided by JAMB)',
555        readonly = True,
556        )
557    jamb_lga = schema.TextLine(
558        title = u'LGA (provided by JAMB)',
559        readonly = True,
560        )
561    lga = schema.TextLine(
562        # XXX: should be choice
563        title = u'State/LGA (confirmed by applicant)',
564        required = False,
565        )
566    email = schema.TextLine(
567        title = u'Email',
568        required = False,
569        )
570    phone = schema.TextLine(
571        title = u'Phone',
572        required = False,
573        )
574    aos = schema.TextLine(
575        # XXX: should be choice
576        title = u'Area of Specialisation',
577        required = False,
578        )
579    subj1 = schema.TextLine(
580        # XXX: should be choice
581        title = u'1st Choice of Study',
582        readonly = True,
583        )
584    subj2 = schema.TextLine(
585        # XXX: should be choice
586        title = u'2nd Choice of Study',
587        required = False,
588        )
589    subj3 = schema.TextLine(
590        # XXX: should be choice
591        title = u'3rd Choice of Study',
592        required = False,
593        )
594   
595    #
596    # Application Data
597    #
598    application_date = schema.Date(
599        title = u'Application Date',
600        readonly = True,
601        )
602    status = schema.TextLine(
603        # XXX: should be 'status' type
604        title = u'Application Status',
605        readonly = True,
606        )
607    screening_date = schema.Date(
608        title = u'Screening Date',
609        readonly = True,
610        )
611    #passport = schema.Bool(
612    #    title = u'Passport Photograph',
613    #    default = True,
614    #    required = False,
615    #    ),
616    #passport = schema.Bytes(
617    #    title = u'Passport Photograph',
618    #    required = True,
619    #    )
620    #passport = schema.Object(
621    #    title = u'Passport Photograph',
622    #    required = True,
623    #    schema = IImage)
624    passport = ImageFile(
625        title = u'Passport Photograph',
626        default = DEFAULT_PASSPORT_IMAGE_MALE,
627        required = True,
628        )
629
630class IApplicantPDEImportData(IApplicantBaseData):
631    """Data for applicants, that passed PDE screening.
632
633    This data set should be suitable for imports from JAMB tables. It
634    is also basicall the basic applicant data from
635    :class:`IApplicantBaseData` only with the required fields set.
636
637    """
638    firstname = schema.TextLine(
639        title = u'First Name',
640        required = True,
641        )
642    middlenames = schema.TextLine(
643        title = u'Middle Names',
644        required = True,
645        )
646    lastname = schema.TextLine(
647        title = u'Surname/Full Name',
648        required = True,
649        )
650    date_of_birth = schema.Date(
651        title = u'Date of Birth',
652        required = True,
653        )
654    jamb_state = schema.TextLine(
655        title = u'State (provided by JAMB)',
656        required = True,
657        )
658    jamb_lga = schema.TextLine(
659        title = u'LGA (provided by JAMB)',
660        required = True,
661        )
662    course1 = schema.TextLine(
663        title = u'1st Choice Course of Study',
664        required = True,
665        )
666    screening_date = schema.Date(
667        title = u'Screening Date',
668        required = True,
669        )
670    screening_type = schema.TextLine(
671        # XXX: schould be choice
672        title = u'Screening Type',
673        required = True,
674        )
675    screening_venue = schema.TextLine(
676        title = u'Screening Venue',
677        required = True,
678        )
679    entry_session = schema.TextLine(
680        # XXX: should be choice
681        # XXX: should have sensible default: upcoming session
682        title = u'Entry Session',
683        required = True,
684        )
685   
686class IApplicantContainer(IWAeUPObject):
687    """A container for applicants.
688    """
689
690class IApplicantPrincipalInfo(IPrincipalInfo):
691    """Infos about principals that are applicants.
692    """
693    reg_no = Attribute("The JAMB registration no. of the user")
694
695    access_code = Attribute("The Access Code the user purchased")
696
697class IApplicantPrincipal(IPrincipal):
698    """A principal that is an applicant.
699
700    This interface extends zope.security.interfaces.IPrincipal and
701    requires also an `id` and other attributes defined there.
702    """
703    reg_no = schema.TextLine(
704        title = u'Registration number',
705        description = u'The JAMB registration number',
706        required = True,
707        readonly = True)
708
709    access_code = schema.TextLine(
710        title = u'Access Code',
711        description = u'The access code purchased by the user.',
712        required = True,
713        readonly = True)
714
715class IApplicantsFormChallenger(Interface):
716    """A challenger that uses a browser form to collect applicant
717       credentials.
718    """
719    loginpagename = schema.TextLine(
720        title = u'Loginpagename',
721        description = u"""Name of the login form used by challenger.
722
723        The form must provide an ``access_code`` input field.
724        """)
725
726    accesscode_field = schema.TextLine(
727        title = u'Access code field',
728        description = u'''Field of the login page which is looked up for
729                          access_code''',
730        default = u'access_code',
731        )
732
733class IJAMBApplicantsFormChallenger(IApplicantsFormChallenger):
734    """A challenger that uses a browser form to collect applicant
735       credentials for applicants in JAMB process.
736
737       JAMB-screened applicants have to provide an extra registration
738       no. provided by JAMB.
739    """
740    jamb_reg_no_field = schema.TextLine(
741        title = u'JAMB registration no.',
742        description = u'''Field of the login page which is looked up for
743                          the JAMB registration number.''',
744        default = u'jamb_reg_no',
745        )
746
747class IApplicantSessionCredentials(Interface):
748    """Interface for storing and accessing applicant credentials in a
749       session.
750    """
751
752    def __init__(access_code):
753        """Create applicant session credentials."""
754
755    def getAccessCode():
756        """Return the access code."""
757
758
759class IJAMBApplicantSessionCredentials(IApplicantSessionCredentials):
760    """Interface for storing and accessing JAMB applicant credentials in a
761       session.
762    """
763
764    def __init__(access_code, jamb_reg_no):
765        """Create credentials for JAMB screened applicants."""
766
767    def getJAMBRegNo():
768        """Return the JAMB registration no."""
Note: See TracBrowser for help on using the repository browser.