source: WAeUP_SRP/trunk/WAeUPTables.py @ 1962

Last change on this file since 1962 was 1954, checked in by joachim, 17 years ago

fix for #260 reindexing registered_courses index is now also faster

  • Property svn:keywords set to Id
File size: 27.5 KB
Line 
1#-*- mode: python; mode: fold -*-
2# (C) Copyright 2005 AixtraWare <http://aixtraware.de>
3# Author: Joachim Schmitz <js@aixtraware.de>
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License version 2 as published
7# by the Free Software Foundation.
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
17# 02111-1307, USA.
18#
19# $Id: WAeUPTables.py 1954 2007-06-25 08:28:28Z joachim $
20
21from zope.interface import implements
22from Globals import InitializeClass
23from Products.ZCatalog.ZCatalog import ZCatalog
24from Products.ZCatalog.ProgressHandler import ZLogHandler
25from AccessControl import ClassSecurityInfo
26from Products.CMFCore.permissions import ModifyPortalContent
27import urllib
28import DateTime,time
29import csv,re
30import logging
31import Globals
32p_home = Globals.package_home(globals())
33i_home = Globals.INSTANCE_HOME
34from Products.CMFCore.CatalogTool import CatalogTool
35from Products.AdvancedQuery import Eq, Between, Le,In
36
37from interfaces import IWAeUPTable
38
39class AttributeHolder(object):
40    pass
41
42def dict2ob(dict):
43    ob = AttributeHolder()
44    for key, value in dict.items():
45        setattr(ob, key, value)
46    return ob
47
48class WAeUPTable(ZCatalog): ###(
49
50    implements(IWAeUPTable)
51    security = ClassSecurityInfo()
52
53    def refreshCatalog(self, clear=0, pghandler=None):
54        """ don't refresh for a normal table """
55
56        if self.REQUEST and self.REQUEST.RESPONSE:
57            self.REQUEST.RESPONSE.redirect(
58              URL1 +
59              '/manage_catalogAdvanced?manage_tabs_message=Catalog%20refresh%20not%20implemented')
60
61    def manage_catalogClear(self, REQUEST=None, RESPONSE=None, URL1=None):
62        """ clears the whole enchilada """
63       
64        #if REQUEST and RESPONSE:
65        #    RESPONSE.redirect(
66        #      URL1 +
67        #      '/manage_catalogAdvanced?manage_tabs_message=Catalog%20Clearing%20disabled')
68
69
70        self._catalog.clear()
71        if REQUEST and RESPONSE:
72            RESPONSE.redirect(
73              URL1 +
74              '/manage_catalogAdvanced?manage_tabs_message=Catalog%20cleared')
75
76    def addRecord(self, **data):
77        # The uid is the same as "bed".
78        uid = data[self.key]
79        res = self.searchResults({"%s" % self.key : uid})
80        if len(res) > 0:
81            raise ValueError("More than one record with uid %s" % uid)
82        self.catalog_object(dict2ob(data), uid=uid)
83        return uid
84
85    def deleteRecord(self, uid):
86        self.uncatalog_object(uid)
87
88    def searchAndSetRecord(self, **data):
89        raise NotImplemented
90
91    def modifyRecord(self, **data):
92        #records = self.searchResults(uid=uid)
93        uid = data[self.key]
94        records = self.searchResults({"%s" % self.key : uid})
95        if len(records) > 1:
96            # Can not happen, but anyway...
97            raise ValueError("More than one record with uid %s" % uid)
98        if len(records) == 0:
99            raise KeyError("No record for uid %s" % uid)
100        record = records[0]
101        record_data = {}
102        for field in self.schema() + self.indexes():
103            record_data[field] = getattr(record, field)
104        # Add the updated data:
105        record_data.update(data)
106        self.catalog_object(dict2ob(record_data), uid)
107
108    def reindexIndex(self, name, REQUEST,pghandler=None):
109        if isinstance(name, str):
110            name = (name,)
111        paths = self._catalog.uids.items()
112        i = 0
113        #import pdb;pdb.set_trace()
114        for p,rid in paths:
115            i += 1
116            metadata = self.getMetadataForRID(rid)
117            record_data = {}
118            for field in name:
119                record_data[field] = metadata.get(field)
120            uid = metadata.get(self.key)
121            self.catalog_object(dict2ob(record_data), uid, idxs=name,
122                                update_metadata=0)
123
124    security.declareProtected(ModifyPortalContent,"exportAllRecords")
125    def exportAllRecords(self):
126        "export a WAeUPTable"
127        #import pdb;pdb.set_trace()
128        fields = [field for field in self.schema()]
129        format = ','.join(['"%%(%s)s"' % fn for fn in fields])
130        csv = []
131        csv.append(','.join(['"%s"' % fn for fn in fields]))
132        for uid in self._catalog.uids:
133            records = self.searchResults({"%s" % self.key : uid})
134            if len(records) > 1:
135                # Can not happen, but anyway...
136                raise ValueError("More than one record with uid %s" % uid)
137            if len(records) == 0:
138                raise KeyError("No record for uid %s" % uid)
139            rec = records[0]
140            csv.append(format % rec)
141        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
142        open("%s/import/%s-%s.csv" % (i_home,self.getId(),current),"w+").write('\n'.join(csv))
143    ###)
144
145class AccommodationTable(WAeUPTable): ###(
146
147    meta_type = 'WAeUP Accommodation Tool'
148    name = "accommodation"
149    key = "bed"
150    def __init__(self):
151        WAeUPTable.__init__(self, 'portal_accommodation')
152
153    def searchAndReserveBed(self, student_id,bed_type):
154        records = self.searchResults({'student' : student_id})
155        if len(records) > 0:
156            return -1,"Student with Id %s already booked bed %s." % (student_id,records[0].bed)
157
158        records = [r for r in self.searchResults({'bed_type' : bed_type}) if not r.student]
159        #import pdb;pdb.set_trace()
160        if len(records) == 0:
161            return -2,"No bed available"
162        rec = records[0]
163        self.modifyRecord(bed=rec.bed,student=student_id)
164        s_logger = logging.getLogger('WAeUPTables.AccommodationTable.searchAndReserveBed')
165        s_logger.info('%s reserved bed %s' % (student_id,rec.bed))
166        return 1,rec.bed
167
168
169InitializeClass(AccommodationTable)
170
171###)
172
173class PinTable(WAeUPTable): ###(
174    from ZODB.POSException import ConflictError
175    meta_type = 'WAeUP Pin Tool'
176    name = "pins"
177    key = 'pin'
178    def __init__(self):
179        WAeUPTable.__init__(self, 'portal_pins')
180
181
182    def searchAndSetRecord(self, uid, student_id,prefix):
183        #records = self.searchResults(uid=uid)
184        records = self.searchResults(student = student_id)
185        #import pdb;pdb.set_trace()
186        if len(records) > 0 and prefix in ('CLR','APP'):
187            for r in records:
188                if r.pin != uid and r.prefix_batch.startswith(prefix):
189                    return -2
190        records = self.searchResults({"%s" % self.key : uid})
191        if len(records) > 1:
192            # Can not happen, but anyway...
193            raise ValueError("More than one record with uid %s" % uid)
194        if len(records) == 0:
195            return -1
196        record = records[0]
197        if record.student == "":
198            record_data = {}
199            for field in self.schema() + self.indexes():
200                record_data[field] = getattr(record, field)
201            # Add the updated data:
202            record_data['student'] = student_id
203            try:
204                self.catalog_object(dict2ob(record_data), uid)
205                return 1
206            except ConflictError:
207                return 2
208        if record.student.upper() != student_id.upper():
209            return 0
210        if record.student.upper() == student_id.upper():
211            return 2
212        return -3
213
214InitializeClass(PinTable)
215
216###)
217
218class PumeResultsTable(WAeUPTable): ###(
219
220    meta_type = 'WAeUP PumeResults Tool'
221    name = "pumeresults"
222    key = "jamb_reg_no"
223    def __init__(self):
224        WAeUPTable.__init__(self, 'portal_pumeresults')
225
226
227InitializeClass(PumeResultsTable)
228
229###)
230
231class StudentsCatalog(WAeUPTable): ###(
232    security = ClassSecurityInfo()
233
234    meta_type = 'WAeUP Students Catalog'
235    name = "students_catalog"
236    key = "id"
237    affected_types = {   ###(
238                      'StudentApplication':
239                          {'id': 'application',
240                           'fields':
241                             ('jamb_reg_no',
242                              'entry_mode',
243                              #'entry_level',
244                              'entry_session',
245                              )
246                              },
247                      'StudentClearance':
248                          {'id': 'clearance',
249                           'fields':
250                             ('matric_no',
251                              )
252                              },
253                         'StudentPersonal':
254                          {'id': 'personal',
255                           'fields':
256                             ('name',
257                              'sex',
258                              'email',
259                              'phone',
260                              )
261                              },
262                         'StudentStudyCourse':
263                          {'id': 'study_course',
264                           'fields':
265                             ('course',
266                              'faculty',
267                              'department',
268                              'level',
269                              'mode',
270                              'session',
271                              'verdict',
272                              )
273                              },
274                         }
275    ###)
276
277    def __init__(self):
278        WAeUPTable.__init__(self, 'students_catalog')
279        return
280
281    def manage_catalogClear(self, REQUEST=None, RESPONSE=None, URL1=None):
282        """ clears the whole enchilada """
283        self._catalog.clear()
284
285        if REQUEST and RESPONSE:
286            RESPONSE.redirect(
287              URL1 +
288              '/manage_catalogAdvanced?manage_tabs_message=Catalog%20Cleared')
289
290    def manage_catalogReindex(self, REQUEST, RESPONSE, URL1): ###(
291        """ clear the catalog, then re-index everything """
292
293        elapse = time.time()
294        c_elapse = time.clock()
295
296        pgthreshold = self._getProgressThreshold()
297        handler = (pgthreshold > 0) and ZLogHandler(pgthreshold) or None
298        self.refreshCatalog(clear=1, pghandler=handler)
299
300        elapse = time.time() - elapse
301        c_elapse = time.clock() - c_elapse
302
303        RESPONSE.redirect(
304            URL1 +
305            '/manage_catalogAdvanced?manage_tabs_message=' +
306            urllib.quote('Catalog Updated \n'
307                         'Total time: %s\n'
308                         'Total CPU time: %s' % (`elapse`, `c_elapse`)))
309    ###)
310
311    def get_from_doc_department(self,doc): ###(
312        "return the students department"
313        if doc is None:
314            return None
315        certificate_res = self.portal_catalog(id = doc.study_course)
316        if len(certificate_res) != 1:
317            return None
318        return certificate_res[0].getPath().split('/')[-3]
319
320    def get_from_doc_faculty(self,doc):
321        "return the students faculty"
322        if doc is None:
323            return None
324        certificate_res = self.portal_catalog(id = doc.study_course)
325        if len(certificate_res) != 1:
326            return None
327        return certificate_res[0].getPath().split('/')[-4]
328
329    def get_from_doc_level(self,doc):
330        "return the students level"
331        if doc is None:
332            return None
333        return getattr(doc,'current_level',None)
334
335    def get_from_doc_mode(self,doc):
336        "return the students mode"
337        if doc is None:
338            return None
339        cm = getattr(doc,'current_mode',None)
340        return cm
341
342
343    def get_from_doc_session(self,doc):
344        "return the students current_session"
345        if doc is None:
346            return None
347        return getattr(doc,'current_session',None)
348
349    def get_from_doc_entry_session(self,doc):
350        "return the students entry_session"
351        if doc is None:
352            return None
353        es = getattr(doc,'entry_session',None)
354        if es is not None and len(es) == 2:
355            return es
356        try:
357            digit = int(doc.jamb_reg_no[0])
358        except:
359            return "xx"
360        if digit < 8:
361            return "0%c" % doc.jamb_reg_no[0]
362        return "9%c" % doc.jamb_reg_no[0]
363
364    def get_from_doc_session(self,doc):
365        "return the students session"
366        if doc is None:
367            return None
368        return getattr(doc,'current_session',None)
369
370    def get_from_doc_course(self,doc):
371        "return the students study_course"
372        if doc is None:
373            return None
374        return getattr(doc,'study_course',None)
375
376    def get_from_doc_name(self,doc):
377        "return the students name from the personal"
378        if doc is None:
379            return None
380        return "%s %s %s" % (doc.firstname,doc.middlename,doc.lastname)
381
382    def get_from_doc_verdict(self,doc):
383        "return the students study_course"
384        if doc is None:
385            return None
386        return getattr(doc,'current_verdict',None)
387    ###)
388
389    def reindexIndex(self, name, REQUEST,pghandler=None): ###(
390        if isinstance(name, str):
391            name = (name,)
392        reindextypes = {}
393        reindex_special = []
394        for n in name:
395            if n in ("review_state","registered_courses"):
396                reindex_special.append(n)
397            else:
398                for pt in self.affected_types.keys():
399                    if n in self.affected_types[pt]['fields']:
400                        if reindextypes.has_key(pt):
401                            reindextypes[pt].append(n)
402                        else:
403                            reindextypes[pt]= [n]
404                        break
405        students = self.portal_catalog(portal_type="Student")
406        if hasattr(self,'portal_catalog_real'):
407            aq_portal = self.portal_catalog_real.evalAdvancedQuery
408        else:
409            aq_portal = self.portal_catalog.evalAdvancedQuery
410        num_objects = len(students)
411        if pghandler:
412            pghandler.init('Refreshing catalog: %s' % self.absolute_url(1), num_objects)
413        noattr = set(('StudentClearance','StudentPersonal')) & set(reindextypes.keys())
414        for i in xrange(num_objects):
415            if pghandler: pghandler.report(i)
416            student_brain = students[i]
417            student_object = student_brain.getObject()
418            data = {}
419            modified = False
420            sid = data['id'] = student_brain.getId
421            if reindex_special and 'review_state' in reindex_special:
422                modified = True
423                data['review_state'] = student_brain.review_state
424            sub_objects = False
425            for pt in reindextypes.keys():
426                modified = True
427                try:
428                    doc = getattr(student_object,self.affected_types[pt]['id']).getContent()
429                    sub_objects = True
430                except:
431                    continue
432                for field in self.affected_types[pt]['fields']:
433                    if hasattr(self,'get_from_doc_%s' % field):
434                        data[field] = getattr(self,'get_from_doc_%s' % field)(doc)
435                    else:
436                        data[field] = getattr(doc,field)
437            if not sub_objects and noattr:
438                import_res = self.returning_import(id = sid)
439                if not import_res:
440                    continue
441                import_record = import_res[0]
442                data['matric_no'] = import_record.matric_no
443                data['sex'] = import_record.Sex == 'F'
444                data['name'] = "%s %s %s" % (import_record.Firstname,
445                                             import_record.Middlename,
446                                             import_record.Lastname)
447                data['jamb_reg_no'] = import_record.Entryregno
448            if reindex_special and 'registered_courses' in reindex_special:
449                try:
450                    study_course = getattr(student_object,"study_course")
451                    level_ids = study_course.objectIds()
452                except:
453                    continue
454                if not level_ids:
455                    continue
456                modified = True
457                level_ids.sort()
458                course_ids = getattr(study_course,level_ids[-1]).objectIds()
459                courses = []
460                for c in course_ids:
461                    if c.endswith('_co'):
462                        courses.append(c[:-3])
463                    else:
464                        courses.append(c)
465                data['registered_courses'] = courses
466            if modified:
467                self.modifyRecord(**data)
468        if pghandler: pghandler.finish()
469    ###)
470
471    def refreshCatalog(self, clear=0, pghandler=None): ###(
472        """ re-index everything we can find """
473        students_folder = self.portal_url.getPortalObject().campus.students
474        if clear:
475            self._catalog.clear()
476        students = self.portal_catalog(portal_type="Student")
477        num_objects = len(students)
478        if pghandler:
479            pghandler.init('Refreshing catalog: %s' % self.absolute_url(1), num_objects)
480        for i in xrange(num_objects):
481            if pghandler: pghandler.report(i)
482            student_brain = students[i]
483            spath = student_brain.getPath()
484            student_object = student_brain.getObject()
485            data = {}
486            sid = data['id'] = student_brain.getId
487            data['review_state'] = student_brain.review_state
488            sub_objects = False
489            for pt in self.affected_types.keys():
490                modified = True
491                try:
492                    doc = getattr(student_object,self.affected_types[pt]['id']).getContent()
493                    sub_objects = True
494                except:
495                    #from pdb import set_trace;set_trace()
496                    continue
497                for field in self.affected_types[pt]['fields']:
498                    if hasattr(self,'get_from_doc_%s' % field):
499                        data[field] = getattr(self,'get_from_doc_%s' % field)(doc)
500                    else:
501                        data[field] = getattr(doc,field,None)
502            if not sub_objects:
503                import_res = self.returning_import(id = sid)
504                if not import_res:
505                    continue
506                import_record = import_res[0]
507                data['matric_no'] = import_record.matric_no
508                data['sex'] = import_record.Sex == 'F'
509                data['name'] = "%s %s %s" % (import_record.Firstname,
510                                             import_record.Middlename,
511                                             import_record.Lastname)
512                data['jamb_reg_no'] = import_record.Entryregno
513            else:
514                study_course = getattr(student_object,'study_course',None)
515                current_level = data.get('level',None)
516                data['registered_courses'] = []
517                if study_course and current_level and current_level in study_course.objectIds():
518                    level_obj = getattr(study_course,current_level)
519                    courses = []
520                    for c in level_obj.objectIds():
521                        if c.endswith('_co'):
522                            courses.append(c[:-3])
523                        else:
524                            courses.append(c)
525                    data['registered_courses'] = courses
526            self.addRecord(**data)
527        if pghandler: pghandler.finish()
528    ###)
529
530    security.declarePrivate('notify_event_listener') ###(
531    def notify_event_listener(self,event_type,object,infos):
532        "listen for events"
533        if not infos.has_key('rpath'):
534            return
535        pt = getattr(object,'portal_type',None)
536        mt = getattr(object,'meta_type',None)
537        students_catalog = self
538        data = {}
539        if pt == 'Student' and\
540           mt == 'CPS Proxy Folder' and\
541           event_type.startswith('workflow'):
542            data['id'] = object.getId()
543            data['review_state'] = self.portal_workflow.getInfoFor(object,'review_state',None)
544            students_catalog.modifyRecord(**data)
545            return
546        rpl = infos['rpath'].split('/')
547        if pt == 'Student' and mt == 'CPS Proxy Folder'\
548           and event_type == "sys_add_object":
549            student_id = object.id
550            try:
551                self.addRecord(id = student_id)
552            except ValueError:
553                pass
554            return
555        elif pt == 'StudentCourseResult' and mt == 'CPS Proxy Folder':
556            if event_type not in ("sys_add_object","sys_del_object"):
557                return
558            #import pdb;pdb.set_trace()
559            course_id = object.getId()
560            if course_id.endswith('_co'):
561                course_id = course_id[:-3]
562            student_id = object.absolute_url_path().split('/')[-4]
563            res = students_catalog(id = student_id)
564            if not res:
565                return
566            student_rec = res[0]
567            registered_courses = student_rec.registered_courses
568            if event_type == "sys_add_object" and course_id not in registered_courses:
569                registered_courses.append(course_id)
570            elif event_type == "sys_del_object":
571                while course_id in registered_courses:
572                    registered_courses.remove(course_id)
573            data['id'] = student_id
574            data['registered_courses'] = registered_courses
575            self.modifyRecord(**data)
576        if pt not in self.affected_types.keys():
577            return
578        if event_type not in ('sys_modify_object'):
579            return
580        if mt == 'CPS Proxy Folder':
581            return
582        for field in self.affected_types[pt]['fields']:
583            if hasattr(self,'get_from_doc_%s' % field):
584                data[field] = getattr(self,'get_from_doc_%s' % field)(object)
585            else:
586                data[field] = getattr(object,field)
587        data['id'] = rpl[2]
588        self.modifyRecord(**data)
589    ###)
590
591
592InitializeClass(StudentsCatalog)
593
594###)
595
596class CoursesCatalog(WAeUPTable): ###(
597    security = ClassSecurityInfo()
598
599    meta_type = 'WAeUP Courses Catalog'
600    name = "students_catalog"
601    key = "code"
602    def __init__(self):
603        WAeUPTable.__init__(self, 'courses_catalog')
604
605    def manage_catalogReindex(self, REQUEST, RESPONSE, URL1): ###(
606        """ clear the catalog, then re-index everything """
607
608        elapse = time.time()
609        c_elapse = time.clock()
610
611        pgthreshold = self._getProgressThreshold()
612        handler = (pgthreshold > 0) and ZLogHandler(pgthreshold) or None
613        self.refreshCatalog(clear=1, pghandler=handler)
614
615        elapse = time.time() - elapse
616        c_elapse = time.clock() - c_elapse
617
618        RESPONSE.redirect(
619            URL1 +
620            '/manage_catalogAdvanced?manage_tabs_message=' +
621            urllib.quote('Catalog Updated \n'
622                         'Total time: %s\n'
623                         'Total CPU time: %s' % (`elapse`, `c_elapse`)))
624    ###)
625
626    def reindexIndex(self, name, REQUEST,pghandler=None): ###(
627        if isinstance(name, str):
628            name = (name,)
629        courses = self.portal_catalog(portal_type="Course")
630        num_objects = len(courses)
631        if pghandler:
632            pghandler.init('Refreshing catalog: %s' % self.absolute_url(1), num_objects)
633        for i in xrange(num_objects):
634            if pghandler: pghandler.report(i)
635            course_brain = courses[i]
636            course_object = course_brain.getObject()
637            pl = course_brain.getPath().split('/')
638            data = {}
639            cid = data[self.key] = course_brain.getId
640            data['faculty'] = pl[-4]
641            data['department'] = pl[-3]
642            doc = course_object.getContent()
643            for field in name:
644                if field not in (self.key,'faculty','department'):
645                    data[field] = getattr(doc,field)
646            self.modifyRecord(**data)
647        if pghandler: pghandler.finish()
648    ###)
649
650    def refreshCatalog(self, clear=0, pghandler=None): ###(
651        """ re-index everything we can find """
652        if clear:
653            self._catalog.clear()
654        courses = self.portal_catalog(portal_type="Course")
655        num_objects = len(courses)
656        if pghandler:
657            pghandler.init('Refreshing catalog: %s' % self.absolute_url(1), num_objects)
658        #from pdb import set_trace;set_trace()
659        for i in xrange(num_objects):
660            if pghandler: pghandler.report(i)
661            course_brain = courses[i]
662            course_doc = course_brain.getObject().getContent()
663            pl = course_brain.getPath().split('/')
664            data = {}
665            for field in self.schema():
666                data[field] = getattr(course_doc,field,None)
667            data[self.key] = course_brain.getId
668            ai = pl.index('academics')
669            data['faculty'] = pl[ai +1]
670            data['department'] = pl[ai +2]
671            if clear:
672                self.addRecord(**data)
673            else:
674                self.modifyRecord(**data)
675        if pghandler: pghandler.finish()
676    ###)
677
678    security.declarePrivate('notify_event_listener') ###(
679    def notify_event_listener(self,event_type,object,infos):
680        "listen for events"
681        if not infos.has_key('rpath'):
682            return
683        pt = getattr(object,'portal_type',None)
684        mt = getattr(object,'meta_type',None)
685        if pt != 'Course':
686            return
687        data = {}
688        rpl = infos['rpath'].split('/')
689        if event_type not in ("sys_add_object","sys_modify_object","sys_del_object"):
690            return
691        course_id = object.getId()
692        data[self.key] = course_id
693        if event_type == "sys_add_object" and mt == 'CPS Proxy Folder':
694            try:
695                self.addRecord(**data)
696            except ValueError:
697                return
698            course_id = object.getId()
699            doc = object.getContent()
700            if doc is None:
701                return
702            for field in self.schema():
703                data[field] = getattr(doc,field,None)
704            data[self.key] = course_id
705            ai = rpl.index('academics')
706            data['faculty'] = rpl[ai +1]
707            data['department'] = rpl[ai +2]
708            self.modifyRecord(**data)
709            return
710        if event_type == "sys_del_object":
711            self.deleteRecord(course_id)
712            return
713        if event_type == "sys_modify_object" and mt == 'Course':
714            #from pdb import set_trace;set_trace()
715            for field in self.schema():
716                data[field] = getattr(object,field,None)
717            course_id = object.aq_parent.getId()
718            data[self.key] = course_id
719            ai = rpl.index('academics')
720            data['faculty'] = rpl[ai +1]
721            data['department'] = rpl[ai +2]
722            self.modifyRecord(**data)
723    ###)
724
725
726InitializeClass(CoursesCatalog)
727###)
728
729class OnlinePaymentsImport(WAeUPTable): ###(
730
731    meta_type = 'WAeUP Online Payment Transactions'
732    name = "online_payments_import"
733    key = "order_id"
734    def __init__(self):
735        WAeUPTable.__init__(self, self.name)
736
737
738InitializeClass(CoursesCatalog)
739###)
740
741class ReturningImport(WAeUPTable): ###(
742
743    meta_type = 'Returning Import Table'
744    name = "returning_import"
745    key = "matric_no"
746    def __init__(self):
747        WAeUPTable.__init__(self, 'returning_import')
748
749
750InitializeClass(ReturningImport)
751###)
752
753class ResultsImport(WAeUPTable): ###(
754
755    meta_type = 'Results Import Table'
756    name = "results_import"
757    key = "key"
758    def __init__(self):
759        WAeUPTable.__init__(self, 'results_import')
760
761
762InitializeClass(ResultsImport)
763
764###)
765
766class PaymentsCatalog(WAeUPTable): ###(
767
768    meta_type = 'WAeUP Payments Catalog'
769    name = "students_catalog"
770    key = "id"
771    def __init__(self):
772        WAeUPTable.__init__(self, 'payments_catalog')
773
774
775InitializeClass(PaymentsCatalog)
776
777###)
778
779# BBB:
780AccomodationTable = AccommodationTable
Note: See TracBrowser for help on using the repository browser.