source: WAeUP_SRP/trunk/Students.py @ 1941

Last change on this file since 1941 was 1941, checked in by joachim, 18 years ago

faster version of exportStudents

  • Property svn:keywords set to Id
File size: 63.7 KB
Line 
1#-*- mode: python; mode: fold -*-
2# $Id: Students.py 1941 2007-06-21 14:36:15Z joachim $
3from string import Template
4from Globals import InitializeClass
5from AccessControl import ClassSecurityInfo
6from AccessControl.SecurityManagement import newSecurityManager
7from zExceptions import BadRequest
8from Products.ZCatalog.ZCatalog import ZCatalog
9from Products.CMFCore.utils import UniqueObject, getToolByName
10from Products.CMFCore.permissions import View
11from Products.CMFCore.permissions import ModifyPortalContent
12from Products.CPSCore.CPSBase import CPSBase_adder, CPSBaseFolder
13#from Products.CPSCore.CPSBase import CPSBaseDocument as BaseDocument
14from Products.CPSDocument.CPSDocument import CPSDocument
15from Products.CPSCore.CPSBase import CPSBaseBTreeFolder as BaseBTreeFolder
16from Products.CPSCore.CPSMembershipTool import CPSUnrestrictedUser
17from Products.WAeUP_SRP.Academics import makeCertificateCode
18from Products.AdvancedQuery import Eq, Between, Le,In
19import DateTime
20import logging
21import csv,re,os
22import Globals
23p_home = Globals.package_home(globals())
24i_home = Globals.INSTANCE_HOME
25MAX_TRANS = 1000
26from urllib import urlencode
27
28import DateTime
29#import PIL.Image
30from StringIO import StringIO
31
32def makeCertificateCode(code): ###(
33    code = code.replace('.','')
34    code = code.replace('(','')
35    code = code.replace(')','')
36    code = code.replace('/','')
37    code = code.replace(' ','')
38    code = code.replace('_','')
39    return code
40
41###)
42
43def response_write(response,s): ###(
44    response.setHeader('Content-type','text/html; charset=ISO-8859-15')
45    while s.find('<') > -1:
46        s = s.replace('<','&lt;')
47    while s.find('>') > -1:
48        #from pdb import set_trace;set_trace()
49        s = s.replace('>','&gt;')
50    response.write("%s<br>\n" % s)
51
52###)
53
54def getInt(s): ###(
55    try:
56        return int(s)
57    except:
58        return 0
59
60def getFloat(s):
61    try:
62        return float(s)
63    except:
64        return 0.0
65
66###)
67
68def getStudentByRegNo(self,reg_no): ###(
69    """search student by JAMB Reg No and return StudentFolder"""
70    res = self.students_catalog(jamb_reg_no = reg_no)
71    if len(res) == 1:
72        return getattr(self.portal_url.getPortalObject().campus.students,res[0].id)
73    else:
74        return None
75    # don't search in portal_catalog
76    # search = ZCatalog.searchResults(self.portal_catalog_real,{'meta_type': 'StudentApplication',
77    #                               'SearchableText': reg_no,
78    #                               })
79    # if len(search) < 1:
80    #     return None
81    # return search[0].getObject().aq_parent
82
83###)
84
85def checkJambNo(jnr): ###(
86    try:
87        if len(jnr) != 10:
88            return False
89    except:
90        return False
91    try:
92        int(jnr[:8])
93        return True
94    except:
95        return False
96
97###)
98
99def formatLGA(lga):
100    if lga.find('_') > -1:
101        return "%s / %s" % (lga.split('_')[0].upper(),lga.split('_')[1].upper())
102    return lga
103
104class StudentsFolder(CPSDocument): ###(
105    """
106    WAeUP container for the various WAeUP containers data
107    """
108    meta_type = 'StudentsFolder'
109    portal_type = meta_type
110    security = ClassSecurityInfo()
111
112    security.declareProtected(ModifyPortalContent,"loadPumeResultsFromCSV")###(
113    def loadPumeResultsFromCSV(self):
114        """load Fulltime Studentdata from CSV values into pumeresults catalog"""
115        import transaction
116        import random
117##        csv_d = {'jamb_reg_no': "RegNumber", ###(
118##                 'status': "Admission Status",
119##                 'name': "Name",
120##                 'score': "Score",
121##                 'sex': "Sex",
122##                 'faculty': "Faculty",
123##                 'department': "Dept",
124##                 'course': "Course",
125##                 'course_code_org': "Course Code",
126##                 }
127###)
128##        csv_d = {'jamb_reg_no': "JAMBRegno",
129##                'name': "Name",
130##                'score': "Score",
131##                 'sex': "Sex",
132##                 'course': "Course",
133##                 'faculty': "Faculty",
134##                 'department': "Dept",
135##                 'course_code_org': "Course Code",
136##                 'status': "Admission Status",
137##                 'result_type': None,
138##                 }
139
140        csv_d = {'jamb_reg_no': "reg_no",
141                 'name': "fullname",
142                 'score': "pume_score",
143                 'sex': "sex",
144                 'course': "study_course",
145                 'course_code_org': "study_course",
146                 'status': "admission_status",
147                 'result_type': "entry_mode",
148                 }
149
150        csv_fields = [f[1] for f in csv_d.items() if f[1]]
151        tr_count = 0
152        total = 0
153        #name = 'pup_new'
154        #name = 'pup_update'
155        name = 'Admitted_update'
156        update = name.endswith('update')
157        no_import = []
158        ok_import = []
159        ok_import.append('%s' % ','.join(['"%s"' % fn for fn in csv_d.keys()]))
160        no_import.append('%s' % ','.join(['"%s"' % fn for fn in csv_fields]))
161        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
162        ok_import_name = "%s/import/%s_imported_%s.csv" % (i_home,name,current)
163        #open(ok_import_name,"w").write('\n'.join(no_import))
164        no_import_name = "%s/import/%s_not_imported_%s.csv" % (i_home,name,current)
165        #open(no_import_name,"w").write('\n'.join(no_import))
166        logger = logging.getLogger('Students.loadPumeResultsFromCSV')
167        starttime = DateTime.now()
168        logger.info('Start loading from %s.csv' % name)
169        try:
170            result = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
171        except:
172            logger.error('Error reading %s.csv' % name)
173            return
174        pume = self.portal_pumeresults
175        format = ','.join(['"%%(%s)s"' % fn for fn in csv_fields])
176        import_format = ','.join(['"%%(%s)s"' % fn for fn in csv_d.keys()])
177        eduplicate = '%s,"duplicate"' % format
178        eoriginal = '%s,"original"' % format
179        einvalidjamb = '%s,"invalid JambRegNo"' % format
180        added = 'added ,%s' % format
181        #from pdb import set_trace;set_trace()
182        for jamb in result:
183            dict = {}
184            for f,fn in csv_d.items():
185                dict[f] = jamb.get(csv_d[f])
186            dict['result_type'] = 'CEST'
187            jnr = jamb.get(csv_d['jamb_reg_no'])
188            #if not checkJambNo(jnr):
189            #    logger.info(einvalidjamb % jamb)
190            #    dd = {}
191            #    for f,fn in csv_d.items():
192            #        dd[fn] = getattr(data,f)
193            #        no_import.append(eduplicate % dd)
194            #        no_import.append(eduplicate % jamb)
195            #    continue
196            res = pume(jamb_reg_no=jnr)
197            if len(res) > 0:
198                if update:
199                    try:
200                        pume.modifyRecord(**dict)
201                    # Can not happen, but anyway...
202                    except ValueError:
203                        logger.info(eduplicate % jamb)
204                        continue
205                    # Can not happen, but anyway...
206                    except KeyError:
207                        pume.addRecord(**dict)
208                        logger.info(added % jamb)
209                        continue
210                else:
211                    data = res[0]
212                    if data.name != jamb.get(csv_d['name']):
213                        #set_trace()
214                        logger.info(eduplicate % jamb)
215                        #em = 'Student with REG-NO %(jamb_reg_no)s already exists\n' % dict
216                        #logger.info(em)
217                        dd = {}
218                        for f,fn in csv_d.items():
219                            dd[fn] = getattr(data,f)
220                        no_import.append(eoriginal % dd)
221                        no_import.append(eduplicate % jamb)
222                    continue
223            else:
224                try:
225                    pume.addRecord(**dict)
226                    ok_import.append(import_format % dict)
227                except ValueError:
228                    logger.info(eduplicate % jamb)
229                    #em = 'Student with REG-NO %(jamb_reg_no)s already exists\n' % dict
230                    #logger.info(em)
231                    no_import.append(eduplicate % jamb)
232        logger.info('End loading from %s.csv' % name)
233        if len(no_import) > 1:
234            open(no_import_name,"w+").write('\n'.join(no_import))
235        open(ok_import_name,"w+").write('\n'.join(ok_import))
236        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
237    ###)
238
239    security.declareProtected(ModifyPortalContent,"createStudents")###(
240    def createStudents(self):
241        """
242        load addmitted Studentdata from CSV values and create Studentobjects.
243        This is the current method to create new addmitted Students.
244        Before running the eventservice for the students_catalog must be disabled.
245        """
246        import transaction
247        import random
248        #from pdb import set_trace
249        wftool = self.portal_workflow
250        #students_folder = self.portal_catalog({'meta_type': 'StudentsFolder'})[-1].getObject()
251        students_folder = self.portal_url.getPortalObject().campus.students
252        levels =       {'ume_ft':'100',
253                        'de_ft': '200',
254                        'ug_pt': '100',
255                        'de_pt': '200',
256                        'pg_ft': '700',
257                        'pg_pt': '700',
258                        'dp_pt': '100',
259                        'dp_ft': '100',
260                        }
261        csv_d = {'jamb_reg_no': "reg_no",
262                 'entry_mode': 'entry_mode',
263                 'jamb_firstname': "firstname",
264                 'jamb_middlename': "middlename",
265                 'jamb_lastname': "lastname",
266                 'jamb_sex': "sex",
267                 'jamb_state': "state",
268                 'birthday': "date_of_birth",
269                 'app_email': "email",
270                 'study_course': "study_course",
271                 'perm_address': "address",
272                 'admission_status': "admission_status",
273                 }
274        csv_fields = [f[1] for f in csv_d.items()]
275        tr_count = 0
276        total = 0
277        #name = 'pume_results'
278        name = 'Admitted'
279        no_import = []
280        s = ','.join(['"%s"' % fn for fn in csv_fields])
281        no_import.append('"Error",%s' % s)
282        format = '"%(Error)s",' + ','.join(['"%%(%s)s"' % fn for fn in csv_fields])
283        no_certificate = "no certificate %s" % format
284        open("%s/import/%s_not_imported.csv" % (i_home,name),"w").write('\n'.join(no_import))
285        logger = logging.getLogger('Students.StudentsFolder.createStudents')
286        logger.info('Start loading from %s.csv' % name)
287        certs = {}
288        try:
289            results = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
290        except:
291            logger.error('Error reading %s.csv' % name)
292            return
293        for result in results:
294            if not result.get(csv_d['admission_status']).startswith('Admitted'):
295                continue
296            #result['Error'] = "Processing "
297            #logger.info(format % result)
298            jamb_reg_no = result.get(csv_d['jamb_reg_no'])
299            res = self.students_catalog(jamb_reg_no = jamb_reg_no)
300            if res:
301                em = 'Student with RegNo %s already exists\n' % jamb_reg_no
302                logger.info(em)
303                result['Error'] = "Student exists"
304                no_import.append(format % result)
305                continue
306            cert_id = makeCertificateCode(result.get(csv_d['study_course']))
307            if cert_id not in certs.keys():
308                res = self.portal_catalog(meta_type = "Certificate",id = cert_id)
309                if not res:
310                    em = 'No Certificate with ID %s \n' % cert_id
311                    logger.info(em)
312                    result['Error'] = "No Certificate %s" % cert_id
313                    no_import.append( format % result)
314                    continue
315                cert = res[0]
316                cert_path = cert.getPath().split('/')
317                certificate = certs[cert_id] = {'faculty': cert_path[-4],
318                                     'department': cert_path[-3]}
319            cert_doc = certs[cert_id]
320            catalog_entry = {}
321            catalog_entry['jamb_reg_no'] = jamb_reg_no
322            firstname = result.get(csv_d['jamb_firstname'])
323            middlename = result.get(csv_d['jamb_middlename'])
324            lastname = result.get(csv_d['jamb_lastname'])
325            if len(firstname) < 3\
326               and len(middlename) < 3\
327               and len(lastname) < 3:
328                em = 'Student Names to short \n'
329                logger.info(em)
330                result['Error'] = "Names to short"
331                no_import.append( format % result)
332                continue
333            perm_address = result.get(csv_d['perm_address'])
334            sid = self.generateStudentId('x')
335            students_folder.invokeFactory('Student', sid)
336            catalog_entry['id'] = sid
337            tr_count += 1
338            logger.info('%(total)s+%(tr_count)s: Creating Student with ID %(sid)s reg_no %(jamb_reg_no)s ' % vars())
339            student = getattr(self,sid)
340            student.manage_setLocalRoles(sid, ['Owner',])
341            student.invokeFactory('StudentApplication','application')
342            da = {'Title': 'Application Data'}
343            da["jamb_firstname"] = firstname
344            da["jamb_middlename"] = middlename
345            da["jamb_lastname"] = lastname
346            catalog_entry['entry_session'] = da["entry_session"] = self.getSessionId()[-2:]
347            catalog_entry['sex'] = sex = result.get(csv_d['jamb_sex']).startswith('F')
348            da_fields = ('jamb_reg_no',
349                         'jamb_sex',
350                         'jamb_state',
351                         'entry_mode',
352                         'app_email',
353                         )
354            for f in da_fields:
355                da[f] = result.get(csv_d[f])
356            catalog_entry['email'] = da['app_email']
357            catalog_entry['entry_mode'] = da['entry_mode']
358            app = student.application
359            app_doc = app.getContent()
360            app.getContent().edit(mapping=da)
361            picture ="%s/import/pictures/%s.jpg" % (i_home,jamb_reg_no)
362            app.manage_setLocalRoles(sid, ['Owner',])
363
364            picture_id = da['jamb_reg_no'].replace('/','_')
365            file = None
366            for ext in ('jpg','JPG'):
367                picture ="%s/import/pictures_admitted_latest/%s.%s" % (i_home,picture_id,ext)
368                if os.path.exists(picture):
369                    file = open(picture)
370                    break
371            if file is not None:
372
373                ## file conversion does not work
374                #img = PIL.Image.open(file)
375                #img.thumbnail((150,200),
376                #              resample=PIL.Image.ANTIALIAS)
377                #outfile = StringIO()
378                #img.save(outfile, format=img.format)
379
380                outfile = file.read()
381                app_doc.manage_addFile('passport',
382                                       file=outfile,
383                                       title="%s.jpg" % jamb_reg_no)
384            #wftool.doActionFor(app,'close')
385            dp = {}
386            dp['firstname'] = firstname
387            dp['middlename'] = middlename
388            dp['lastname'] = lastname
389            dp['email'] = da['app_email']
390            dp['sex'] = sex
391            dp['perm_address'] = perm_address
392            catalog_entry['name'] = "%(firstname)s %(middlename)s %(lastname)s" % dp
393            student.invokeFactory('StudentPersonal','personal')
394            per = student.personal
395            per_doc = per.getContent()
396            per_doc.edit(mapping = dp)
397            per.manage_setLocalRoles(sid, ['Owner',])
398            wftool.doActionFor(student,'pume_pass')
399            wftool.doActionFor(student,'admit')
400            #
401            # Clearance
402            #
403            student.invokeFactory('StudentClearance','clearance')
404            #wftool.doActionFor(student.clearance,'open')
405            clearance = student.clearance
406            dc = {'Title': 'Clearance/Eligibility Record'}
407            clearance = student.clearance
408            date_str = result.get(csv_d['birthday'])
409            try:
410                date = DateTime.DateTime(date_str)
411            except:
412                #import pdb;pdb.set_trace()
413                date = None
414            dc['birthday'] = date
415            clearance.getContent().edit(mapping=dc)
416            clearance.manage_setLocalRoles(sid, ['Owner',])
417            #
418            # Study Course
419            #
420            student.invokeFactory('StudentStudyCourse','study_course')
421            study_course = student.study_course
422            dsc = {}
423            catalog_entry['level'] = dsc['current_level'] = levels.get(da['entry_mode'],'100')
424            #catalog_entry['level'] = dsc['current_level'] = '100'  # Attention: not for DE students
425            catalog_entry['session'] = dsc['current_session'] = da['entry_session']
426            catalog_entry['mode'] = dsc['current_mode'] = da['entry_mode']
427            catalog_entry['course'] = dsc['study_course'] = cert_id
428            catalog_entry['faculty'] = certificate['faculty']
429            catalog_entry['department'] = certificate['department']
430            catalog_entry['verdict'] = dsc['current_verdict'] = 'N/A'
431            catalog_entry['review_state'] = self.portal_workflow.getInfoFor(student,'review_state',None)
432            study_course.getContent().edit(mapping=dsc)
433            #import pdb;pdb.set_trace()
434            self.students_catalog.addRecord(**catalog_entry)
435            if tr_count > 100:
436                if len(no_import) > 0:
437                    open("%s/import/%s_not_imported.csv" % (i_home,name),"a").write(
438                             '\n'.join(no_import) + "\n")
439                    no_import = []
440                em = '%d transactions commited\n' % tr_count
441                transaction.commit()
442                logger.info(em)
443                total += tr_count
444                tr_count = 0
445        open("%s/import/%s_not_imported.csv" % (i_home,name),"a").write(
446                                                '\n'.join(no_import))
447        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
448    ###)
449
450    security.declareProtected(ModifyPortalContent,"transferStudents")###(
451    def transferStudents(self,filename):
452        """
453        load Interfaculty transferStudents Studentdata from CSV values.
454        """
455        import transaction
456        import random
457        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
458        pm = self.portal_membership
459        member = pm.getAuthenticatedMember()
460        logger = logging.getLogger('Students.StudentsFolder.transferStudents')
461        #students_folder = self.portal_catalog({'meta_type': 'StudentsFolder'})[-1].getObject()
462        students_folder = self.portal_url.getPortalObject().campus.students
463        csv_fields = ('old_matric_no',
464                      'matric_no',
465                      'study_course',
466                      'current_mode',
467                      'current_level',
468                      )
469        tr_count = 0
470        total = 0
471        total_imported = 0
472        total_not_imported = 0
473        imported = []
474        not_imported = []
475        certs = {}
476        try:
477            results = csv.DictReader(open("%s/import/%s.csv" % (i_home,filename),"rb"))
478        except:
479            logger.error('Error reading %s.csv' % filename)
480            return
481        start = True
482        for result in results:
483            total += 1
484            if start:
485                start = False
486                logger.info('%s starts import from %s.csv' % (member,filename))
487                import_keys = [k for k in result.keys() if not k.startswith('ignore')]
488                diff2schema = set(import_keys).difference(set(csv_fields))
489                if diff2schema:
490                    em = "not ignorable key(s) %s found in heading" % diff2schema
491                    return em
492                s = ','.join(['"%s"' % fn for fn in import_keys])
493                open("%s/import/%s_not_imported%s.csv" % (i_home,filename,current),"a").write(s + ',"Error"'+ '\n')
494                s = '"id",' + s
495                open("%s/import/%s_imported%s.csv" % (i_home,filename,current),"a").write(s + '\n')
496                format = ','.join(['"%%(%s)s"' % fn for fn in import_keys])
497                format_error = format + ',"%(Error)s"'
498                format = '"%(id)s",'+ format
499            old_matric_no = result.get('old_matric_no')
500            res = self.students_catalog(matric_no = old_matric_no)
501            result['id'] = "None"
502            if not res:
503                em = 'Student with matric_no %s not found' % old_matric_no
504                logger.info(em)
505                result['Error'] = "Student does not exist"
506                not_imported.append(format_error % result)
507                total_not_imported += 1
508                continue
509            student_brain = res[0]
510            student_object = getattr(students_folder,student_brain.id)
511            result['id'] = student_brain.id
512            cert_id = makeCertificateCode(result.get('study_course'))
513            if cert_id not in certs.keys():
514                res = self.portal_catalog(meta_type = "Certificate",id = cert_id)
515                if not res:
516                    em = 'No certificate with ID %s \n' % cert_id
517                    logger.info(em)
518                    result['Error'] = "No Certificate %s" % cert_id
519                    not_imported.append( format_error % result)
520                    total_not_imported += 1
521                    continue
522                cert = res[0]
523                cert_path = cert.getPath().split('/')
524                certificate = certs[cert_id] = {'faculty': cert_path[-4],
525                                     'department': cert_path[-3]}
526            cert_doc = certs[cert_id]
527            clearance = getattr(student_object,'clearance',None)
528            if clearance is None:
529                em = 'Student has no clearance object'
530                logger.info(em)
531                result['Error'] = em
532                not_imported.append( format_error % result)
533                total_not_imported += 1
534                continue
535            clearance_doc = clearance.getContent()
536            study_course = student_object.study_course
537            study_course_doc = study_course.getContent()
538            old_study_course = study_course_doc.study_course
539            old_current_level = study_course_doc.current_level
540            current_level = result.get('current_level',None)
541            new_study_course = result.get('study_course',None)
542            try:
543                icl = int(current_level)
544            except:
545                em = 'Invalid new level %s' % current_level
546                logger.info(em)
547                result['Error'] = em
548                not_imported.append( format_error % result)
549                total_not_imported += 1
550                continue
551            if icl == int(old_current_level) and old_study_course == new_study_course:
552                em = 'Already transferred'
553                logger.info(em)
554                result['Error'] = em
555                not_imported.append( format_error % result)
556                total_not_imported += 1
557                continue
558            if study_course.objectIds():
559                em = 'Already registered level %s for %s, but is supposed to study %s at level %s' % (old_current_level,old_study_course,new_study_course,current_level)
560                logger.info(em)
561                result['Error'] = em
562                not_imported.append( format_error % result)
563                total_not_imported += 1
564                continue
565            #from pdb import set_trace; set_trace()
566            cd = {}
567            matric_no_history = getattr(clearance_doc,'matric_no_history',[])
568            if not matric_no_history:
569                matric_no_history = []
570            matric_no_history.append(old_matric_no)
571            cd['matric_no_history'] = matric_no_history
572            cd['matric_no'] = result.get('matric_no')
573            clearance_doc.edit(mapping = cd)
574            dsc = {}
575            study_course_history = getattr(study_course_doc,'study_course_history',[])
576            if not study_course_history:
577                study_course_history = []
578            study_course_history.append(old_study_course)
579            dsc['study_course_history'] = study_course_history
580            dsc['study_course'] = new_study_course
581            dsc['current_level'] = current_level
582            dsc['current_mode'] = result.get('current_mode')
583            study_course_doc.edit(mapping=dsc)
584            imported.append( format % result)
585            tr_count += 1
586            total_imported += 1
587            if tr_count > 1000:
588                if len(not_imported) > 0:
589                    open("%s/import/%s_not_imported%s.csv" % (i_home,filename,current),"a").write(
590                             '\n'.join(not_imported) + '\n')
591                    not_imported = []
592                if len(imported) > 0:
593                    open("%s/import/%s_imported%s.csv" % (i_home,filename,current),"a").write(
594                             '\n'.join(imported) + '\n')
595                    imported = []
596                em = '%d transactions committed\n' % (tr_count)
597                transaction.commit()
598                regs = []
599                logger.info(em)
600                tr_count = 0
601        if len(imported) > 0:
602            open("%s/import/%s_imported%s.csv" % (i_home,filename,current),"a").write(
603                                                '\n'.join(imported))
604        if len(not_imported) > 0:
605            open("%s/import/%s_not_imported%s.csv" % (i_home,filename,current),"a").write(
606                                                '\n'.join(not_imported))
607        em = "Imported: %d, not imported: %d of total %d" % (total_imported,total_not_imported,total)
608        logger.info(em)
609        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
610    ###)
611
612    security.declareProtected(ModifyPortalContent,"importReturningStudents")###(
613    def importReturningStudents(self):
614        """load Returning Studentdata from CSV values"""
615        import transaction
616        import random
617        #from pdb import set_trace
618        wftool = self.portal_workflow
619        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
620        #students_folder = self.portal_catalog({'meta_type': 'StudentsFolder'})[-1].getObject()
621        students_folder = self.portal_url.getPortalObject().campus.students
622        tr_count = 1
623        total = 0
624        #name = 'pume_results'
625        name = 'Returning'
626        table = self.returning_import
627        no_import = []
628        imported = []
629        logger = logging.getLogger('Students.StudentsFolder.importReturningStudents')
630        try:
631            returning = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
632        except:
633            logger.error('Error reading %s.csv' % name)
634            return
635        l = self.portal_catalog({'meta_type': "Certificate"})
636        certs = {}
637        cert_docs = {}
638        for f in l:
639            certs[f.getId] = f.getObject().getContent()
640        start = True
641        res = table()
642        regs = []
643        if len(res) > 0:
644            regs = [s.matric_no for s in res]
645        #import pdb;pdb.set_trace()
646        for student in returning:
647            if start:
648                start = False
649                logger.info('Start loading from %s.csv' % name)
650                s = ','.join(['"%s"' % fn for fn in student.keys()])
651                imported.append(s)
652                no_import.append('%s,"Error"' % s)
653                format = ','.join(['"%%(%s)s"' % fn for fn in student.keys()])
654                format_error = format + ',"%(Error)s"'
655                no_certificate = "no certificate %s" % format
656            student['matric_no'] = matric_no = student.get('matric_no').upper()
657            student['Mode_of_Entry'] = entry_mode = student.get('Mode of Entry').upper()
658            student['Permanent_Address'] = perm_address = student.get('Permanent Address')
659            if matric_no == '':
660                student['Error'] = "Empty matric_no"
661                no_import.append( format_error % student)
662                continue
663            if matric_no in regs or self.returning_import(matric_no = matric_no):
664                student['Error'] = "Duplicate"
665                no_import.append( format_error % student)
666                continue
667            cert_id = makeCertificateCode(student.get('Coursemajorcode'))
668            if cert_id not in certs.keys():
669                student['Error'] = "No Certificate %s" % cert_id
670                no_import.append( format_error % student)
671                continue
672            try:
673                table.addRecord(**student)
674            except ValueError:
675                student['Error'] = "Duplicate"
676                no_import.append( format_error % student)
677                continue
678            regs.append(student.get('matric_no'))
679            imported.append(format % student)
680            tr_count += 1
681            if tr_count > 1000:
682                if len(no_import) > 0:
683                    open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
684                             '\n'.join(no_import) + '\n')
685                    no_import = []
686                open("%s/import/%simported%s.csv" % (i_home,name,current),"a").write(
687                                            '\n'.join(no_import) + "\n")
688                imported = []
689                em = '%d transactions commited total %s\n' % (tr_count,total)
690                transaction.commit()
691                regs = []
692                logger.info(em)
693                total += tr_count
694                tr_count = 0
695        open("%s/import/%simported%s.csv" % (i_home,name,current),"a").write(
696                                            '\n'.join(imported))
697        open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
698                                                '\n'.join(no_import))
699        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
700    ###)
701
702    security.declareProtected(ModifyPortalContent,"fixAllNames")###(
703    def fixAllNames(self):
704        "fix all students names"
705        import transaction
706        response = self.REQUEST.RESPONSE
707        logger = logging.getLogger('fixAllNames')
708        logger.info('Start')
709        students = self.portal_catalog(portal_type='Student')
710        count = 0
711        total = 0
712        for student in students:
713            scat_res = self.students_catalog(id = student.getId)
714            if not scat_res:
715                self.students_catalog.addRecord(id = student.getId)
716                scat_res = self.students_catalog(id = student.getId)
717            student_entry = scat_res[0]
718            old_new = self.fixName(student,student_entry)
719            count += 1
720            response_write(response,'"%d","%s",%s' % (count + total,student_entry.id,old_new))
721            if count > 2000:
722                transaction.commit()
723                logger.info("%d transactions commited" % count)
724                total += count
725                count = 0
726    ###)
727
728    security.declareProtected(ModifyPortalContent,"fixName")###(
729    def fixName(self,student_brain, student_entry):
730        "fix the name of a student"
731        fix = "first"
732        if student_entry.get('name_fixed',None) == fix:
733            return "Name already fixed"
734        student_id = student_entry.id
735        new_student = student_entry.jamb_reg_no.startswith('6')
736        student_obj = student_brain.getObject()
737        personal = getattr(student_obj,'personal',None)
738        invalid = ''
739        if personal is None:
740            return '"%s","Returning","%s","%s"' % (invalid,student_entry.name,"not logged in")
741        per_doc = personal.getContent()
742        old_first = per_doc.firstname
743        old_middle = per_doc.middlename
744        old_last = per_doc.lastname
745        new_first = ''
746        new_middle = ''
747        new_last = ''
748        if new_student:
749            if not old_first and not old_middle and old_last:
750                new_names = [n.capitalize() for n in old_last.split()]
751                if len(new_names) > 1:
752                    old_first = new_names[0]
753                    old_last = new_names[-1]
754                    old_middle = ' '.join(new_names[1:-1])
755                else:
756                    old_last = new_names[0]
757                    old_first = ''
758                    old_middle = ''
759            if old_first:
760                new_first = old_first
761            if old_middle:
762                new_middle = old_middle
763            if old_last:
764                new_last = old_last
765            if old_first.find('<') != -1 or\
766               old_first.find('>') != -1 or\
767               old_middle.find('<') != -1 or\
768               old_middle.find('>') != -1 or\
769               old_last.find('<') != -1 or\
770               old_last.find('>') != -1:
771                   invalid = "invalid characters"
772        else:
773            new_first = old_first
774            if new_first.strip() == '-':
775                new_first = ''
776            new_middle = old_middle
777            if new_middle.strip() == '-':
778                new_middle = ''
779            new_last = old_last
780            if new_last.strip() == '-':
781                new_last = ''
782        name = "%(new_first)s %(new_middle)s %(new_last)s" % vars()
783        if new_student:
784            text = "New"
785        else:
786            text = "Returning"
787        old_new = '"%s","%s","%s","%s"' % (invalid,text,
788                                           student_entry.name,
789                                           name)
790        if not invalid:
791            self.students_catalog.modifyRecord(id = student_id,
792                                      name_fixed = fix,
793                                      name = name)
794            per_doc.edit(mapping = {'firstname' : new_first,
795                                'middlename' : new_middle,
796                                'lastname' : new_last,
797                                })
798        return old_new
799    ###)
800
801    security.declareProtected(ModifyPortalContent,"updateReturningStudents")###(
802    def updateReturningStudents(self):
803        """load and overwrite Returning Student Data from CSV values"""
804        import transaction
805        import random
806        #from pdb import set_trace
807        wftool = self.portal_workflow
808        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
809        #students_folder = self.portal_catalog({'meta_type': 'StudentsFolder'})[-1].getObject()
810        students_folder = self.portal_url.getPortalObject().campus.students
811        tr_count = 1
812        total = 0
813        #name = 'pume_results'
814        name = 'Returning_update'
815        table = self.returning_import
816        no_import = []
817        imported = []
818        logger = logging.getLogger('Students.StudentsFolder.updateReturningStudents')
819        try:
820            returning = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
821        except:
822            logger.error('Error reading %s.csv' % name)
823            return
824        l = self.portal_catalog({'meta_type': "Certificate"})
825        certs = {}
826        cert_docs = {}
827        for f in l:
828            certs[f.getId] = f.getObject().getContent()
829        start = True
830        res = table()
831        regs = []
832        if len(res) > 0:
833            regs = [s.matric_no for s in res]
834        for student in returning:
835            if start:
836                start = False
837                logger.info('Start loading from %s.csv' % name)
838                s = ','.join(['"%s"' % fn for fn in student.keys()])
839                imported.append(s)
840                no_import.append('%s,"Error"' % s)
841                format = ','.join(['"%%(%s)s"' % fn for fn in student.keys()])
842                format_error = format + ',"%(Error)s"'
843                no_certificate = "no certificate %s" % format
844            matric_no = student.get('matric_no').upper()
845            student['matric_no'] = matric_no
846            if matric_no == '':
847                student['Error'] = "Empty matric_no"
848                no_import.append( format_error % student)
849                continue
850#            if matric_no in regs or self.returning_import(matric_no = matric_no):
851#                student['Error'] = "Duplicate"
852#                no_import.append( format_error % student)
853#                continue
854#            cert_id = makeCertificateCode(student.get('Coursemajorcode'))
855#            if cert_id not in certs.keys():
856#                student['Error'] = "No Certificate %s" % cert_id
857#                no_import.append( format_error % student)
858#                continue
859            try:
860                table.modifyRecord(**student)
861            except KeyError:
862                #import pdb;pdb.set_trace()
863                student['Error'] = "no Student found to update"
864                no_import.append( format_error % student)
865                continue
866            #s = self.students_catalog(matric_no=matric_no)
867            #if s:
868            #    level = "%s" % (int(student.get('Level')) + 100)
869            #    self.students_catalog.modifyRecord(id = s[0].id,
870            #                                           level=level)
871
872            regs.append(student.get('matric_no'))
873            imported.append(format % student)
874            tr_count += 1
875            if tr_count > 1000:
876                if len(no_import) > 0:
877                    open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
878                             '\n'.join(no_import) + '\n')
879                    no_import = []
880                open("%s/import/%simported%s.csv" % (i_home,name,current),"a").write(
881                                            '\n'.join(no_import) + "\n")
882                imported = []
883                em = '%d transactions commited total %s\n' % (tr_count,total)
884                transaction.commit()
885                regs = []
886                logger.info(em)
887                total += tr_count
888                tr_count = 0
889        open("%s/import/%simported%s.csv" % (i_home,name,current),"a").write(
890                                            '\n'.join(imported))
891        open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
892                                                '\n'.join(no_import))
893        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
894    ###)
895
896    security.declareProtected(ModifyPortalContent,"exportStudents")###(
897    def exportStudents(self):
898        """export Studentsdata to a file"""
899        member = self.portal_membership.getAuthenticatedMember()
900        logger = logging.getLogger('Students.exportStudents')
901        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
902        students_folder = self.portal_url.getPortalObject().campus.students
903        export_file = "%s/export/students_%s.csv" % (i_home,current)
904       
905        from Products.AdvancedQuery import Eq, Between, Le,In,MatchRegexp
906        aq_students = self.students_catalog.evalAdvancedQuery
907        toexport = {'students_catalog': ("id",
908                                         "matric_no",
909                                         "jamb_reg_no",
910                                         "review_state",
911                                         "sex",
912                                         "email",
913                                         "faculty",
914                                         "department",
915                                         "course",
916                                         "level",
917                                        ),
918                    'personal': ('firstname',
919                                 'middlename',
920                                 'lastname',
921                                 'perm_address',
922                                ),
923                    'clearance': ('state',
924                                  'lga',
925                                 )
926                  }
927        res_list = []
928        lines = []
929        fields = []
930        with_lga = False
931        for k in toexport.keys():
932            for f in toexport[k]:
933                if f == 'lga' :
934                    with_lga = True
935                fields.append(f)
936        headline = ','.join(fields).replace('level','current_level')
937        open(export_file,"a").write(headline +'\n')
938        format = '"%(' + ')s","%('.join(fields) + ')s"'
939        query = In('review_state',('cleared_and_validated',
940                                'school_fee_paid',
941                                'courses_registered',
942                                'courses_validated'))
943        students = aq_students(query)
944        nr2export = len(students)
945        logger.info('%s starts exportStudents, %s student records to export' % (member,nr2export))
946        chunk = 2000
947        total = 0
948        start = DateTime.DateTime().timeTime()
949        start_chunk = DateTime.DateTime().timeTime()
950        ## alternative method slightly slower
951        # student_recs = {}
952        # for s in students:
953        #      student_recs[s.id] = s
954        # catalog_recs = {}
955        # brains = self.portal_catalog(portal_type = 'Student')
956        # for cat_rec in brains:
957        #     sid = cat_rec.getId
958        #     catalog_recs[sid] = cat_rec
959        # #import pdb;pdb.set_trace()
960        # start = DateTime.DateTime().timeTime()
961        # start_chunk = DateTime.DateTime().timeTime()
962        # for student in students:
963        #     if student.id not in student_recs.keys():
964        #         continue
965        #     not_all = False
966        #     d = self.getFormattedStudentEntry(student_recs[student.id])
967        #     student_obj = catalog_recs[student.id].getObject()
968        for student in students:
969            not_all = False
970            d = self.getFormattedStudentEntry(student)
971            student_obj = getattr(students_folder,student.id)
972            for k in toexport.keys()[1:]:
973                try:
974                    object = getattr(student_obj,k)
975                    object_doc = object.getContent()
976                except:
977                    logger.info('%s %s record not found' % (student.id,k))
978                    not_all = True
979                    continue
980                for f in toexport[k]:
981                    d[f] = getattr(object_doc,f,'')
982            if not_all:
983                continue
984            if with_lga:
985                d['lga'] = formatLGA(d['lga'])
986            lines.append(format % d)
987            total += 1
988            if total and not total % chunk or total == len(students):
989                open(export_file,"a").write('\n'.join(lines) +'\n')
990                anz = len(lines)
991                logger.info("wrote %(anz)d  total written %(total)d" % vars())
992                end_chunk = DateTime.DateTime().timeTime()
993                duration = end_chunk-start_chunk
994                per_record = duration/anz
995                till_now = end_chunk - start
996                avarage_per_record = till_now/total
997                estimated_end = DateTime.DateTime(start + avarage_per_record * nr2export)
998                estimated_end = estimated_end.strftime("%H:%M:%S")
999                logger.info('%(duration)4.1f, %(per_record)4.3f,end %(estimated_end)s' % vars())
1000                start_chunk = DateTime.DateTime().timeTime()
1001                lines = []
1002        end = DateTime.DateTime().timeTime()
1003        logger.info('total time %6.2f m' % ((end-start)/60))
1004        filename, extension = os.path.splitext(export_file)
1005        from subprocess import call
1006        msg = "wrote %(total)d records to %(export_file)s" % vars()
1007        try:
1008            retcode = call('gzip %s' % (export_file),shell=True)
1009            if retcode == 0:
1010                msg = "wrote %(total)d records to %(export_file)s.gz" % vars()
1011        except OSError, e:
1012            retcode = -99
1013            logger.info("zip failed with %s" % e)
1014        logger.info(msg)
1015        args = {'portal_status_message': msg}
1016        #url = self.REQUEST.get('URL1') + '?' + urlencode(args)
1017        url = self.REQUEST.get('URL2')
1018        return self.REQUEST.RESPONSE.redirect(url)
1019    ###)
1020
1021    security.declareProtected(ModifyPortalContent,"importResults")###(
1022    def importResults(self):
1023        """load Returning Students Results from CSV"""
1024        import transaction
1025        import random
1026        #from pdb import set_trace
1027        wftool = self.portal_workflow
1028        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
1029        #students_folder = self.portal_catalog({'meta_type': 'StudentsFolder'})[-1].getObject()
1030        students_folder = self.portal_url.getPortalObject().campus.students
1031        tr_count = 1
1032        total = 0
1033        #name = 'pume_results'
1034        name = 'Results'
1035        table = self.results_import
1036        no_import = []
1037        imported = []
1038        logger = logging.getLogger('Students.StudentsFolder.importResults')
1039        try:
1040            results = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
1041        except:
1042            logger.error('Error reading %s.csv' % name)
1043            return
1044        l = self.portal_catalog({'meta_type': "Course"})
1045        courses = [f.getId for f in l]
1046        start = True
1047        res = table()
1048        regs = []
1049        if len(res) > 0:
1050            regs = [s.key for s in res]
1051        no_course = []
1052        no_course_list = []
1053        course_count = 0
1054        for result in results:
1055            if start:
1056                start = False
1057                logger.info('Start loading from %s.csv' % name)
1058                s = ','.join(['"%s"' % fn for fn in result.keys()])
1059                imported.append(s)
1060                no_import.append('%s,"Error"' % s)
1061                format = ','.join(['"%%(%s)s"' % fn for fn in result.keys()])
1062                format_error = format + ',"%(Error)s"'
1063                no_certificate = "no certificate %s" % format
1064            course_id = result.get('CosCode')
1065            if not course_id:
1066                course_id = 'N/A'
1067                result['CosCode'] = course_id
1068            matric_no = result.get('matric_no').upper()
1069            result['matric_no'] = matric_no
1070            key = matric_no+course_id
1071            if matric_no == '':
1072                result['Error'] = "Empty matric_no"
1073                no_import.append( format_error % result)
1074                continue
1075            if key in regs or self.results_import(key = key):
1076                result['Error'] = "Duplicate"
1077                no_import.append( format_error % result)
1078                continue
1079            if course_id not in courses:
1080                if course_id not in no_course:
1081                    course_count +=1
1082                    no_course.append(course_id)
1083                    no_course_list.append('"%s"' % course_id)
1084                    #result['Error'] = "No Course"
1085                    #logger.info(format_error % result)
1086
1087            result['key'] = key
1088            try:
1089                table.addRecord(**result)
1090            except ValueError:
1091                #import pdb;pdb.set_trace()
1092                result['Error'] = "Duplicate"
1093                no_import.append( format_error % result)
1094                continue
1095
1096            regs.append(key)
1097            imported.append(format % result)
1098            tr_count += 1
1099            if tr_count > 1000:
1100                if len(no_import) > 0:
1101                    open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
1102                             '\n'.join(no_import)+'\n')
1103                    no_import = []
1104                open("%s/import/%simported%s.csv" % (i_home,name,current),"a").write(
1105                                            '\n'.join(imported) + '\n')
1106                imported = []
1107                if no_course_list:
1108                    open("%s/import/%sno_courses%s.csv" % (i_home,name,current),"a").write(
1109                                            '\n'.join(no_course_list) + '\n')
1110                    no_course_list = []
1111                em = '%d transactions commited total %s\n courses not found %s' % (tr_count,total,course_count)
1112                transaction.commit()
1113                logger.info(em)
1114                regs = []
1115                total += tr_count
1116                tr_count = 0
1117        open("%s/import/%simported%s.csv" % (i_home,name,current),"a").write(
1118                                            '\n'.join(imported))
1119        open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
1120                                                '\n'.join(no_import))
1121        if no_course_list:
1122            open("%s/import/%sno_courses%s.csv" % (i_home,name,current),"a").write(
1123                                    '\n'.join(no_course_list))
1124        em = '%d transactions commited total %s\n courses not found %s' % (tr_count,total,course_count)
1125        logger.info(em)
1126        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
1127    ###)
1128
1129    security.declareProtected(ModifyPortalContent,"updateStudyCourse")###(
1130    def updateStudyCourse(self):
1131        """update StudyCourse from CSV values"""
1132        import transaction
1133        import random
1134        from pdb import set_trace
1135        wftool = self.portal_workflow
1136        #students_folder = self.portal_catalog({'meta_type': 'StudentsFolder'})[-1].getObject()
1137        students_folder = self.portal_url.getPortalObject().campus.students
1138        csv_d = {'jamb_reg_no': "RegNumber",
1139                 'jamb_lastname': "Name",
1140                 'session': "Session",
1141                 'pume_tot_score': "PUME SCORE",
1142                 'jamb_score': "JambScore",
1143                 'jamb_sex': "Sex",
1144                 'jamb_state': "State",
1145##                 'jamb_first_cos': "AdminCourse",
1146                 'faculty': "AdminFaculty",
1147                 'course_code': "AdmitCoscode",
1148                 'stud_status':"AdmitStatus",
1149                 'department': "AdmitDept",
1150                 'jamb_lga': "LGA",
1151                 'app_email': "email",
1152                 'app_mobile': "PhoneNumbers",
1153                 }
1154        csv_fields = [f[1] for f in csv_d.items()]
1155        tr_count = 0
1156        total = 0
1157        #name = 'pume_results'
1158        name = 'StudyCourseChange'
1159        no_import = []
1160        s = ','.join(['"%s"' % fn for fn in csv_fields])
1161        no_import.append('"Error",%s' % s)
1162        format = '"%(Error)s",' + ','.join(['"%%(%s)s"' % fn for fn in csv_fields])
1163        no_certificate = "no certificate %s" % format
1164        open("%s/import/%s_not_imported.csv" % (i_home,name),"w").write(
1165                    '\n'.join(no_import))
1166        logger = logging.getLogger('Students.StudentsFolder.updateStudyCourse')
1167        logger.info('Start loading from %s.csv' % name)
1168        l = self.portal_catalog({'meta_type': "Certificate"})
1169        try:
1170            result = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
1171        except:
1172            logger.error('Error reading %s.csv' % name)
1173            return
1174        for jamb in result:
1175            jamb['Error'] = "Processing "
1176            logger.info(format % jamb)
1177            jamb_reg_no = jamb.get(csv_d['jamb_reg_no'])
1178            res = self.portal_catalog({'portal_type': "StudentApplication",
1179                                     'SearchableText': jamb_reg_no })
1180            if not res:
1181                em = 'Student with jamb_reg_no %s does not exists\n' % jamb_reg_no
1182                logger.info(em)
1183                jamb['Error'] = "Student does not exist"
1184                no_import.append(format % jamb)
1185                continue
1186            sid = res[0].getPath().split('/')[-2]
1187            cert_id = makeCertificateCode(jamb.get(csv_d['course_code']))
1188            res = self.portal_catalog(portal_type = "Certificate", id = cert_id)
1189            if not res:
1190                em = 'No Certificate with ID %s \n' % cert_id
1191                logger.info(em)
1192                jamb['Error'] = "No Certificate %s" % cert_id
1193                no_import.append( format % jamb)
1194                continue
1195            cert_brain = res[0]
1196            catalog_entry = {}
1197            student = getattr(self,sid)
1198            #
1199            # Study Course
1200            #
1201            study_course = student.study_course
1202            dsc = {}
1203            cert_pl = cert_brain.getPath().split('/')
1204            catalog_entry['id'] = sid
1205            catalog_entry['faculty'] = cert_pl[-4]
1206            catalog_entry['department'] = cert_pl[-3]
1207            catalog_entry['course'] = cert_id
1208            dsc['study_course'] = cert_id
1209            study_course.getContent().edit(mapping=dsc)
1210            self.students_catalog.modifyRecord(**catalog_entry)
1211            if tr_count > 10:
1212                if len(no_import) > 1:
1213                    open("%s/import/%s_not_imported.csv" % (i_home,name),"w+").write(
1214                             '\n'.join(no_import))
1215                    no_import = []
1216                em = '%d transactions commited\n' % tr_count
1217                transaction.commit()
1218                logger.info(em)
1219                total += tr_count
1220                tr_count = 0
1221            tr_count += 1
1222        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
1223    ###)
1224
1225    security.declareProtected(View,"fixOwnership") ###(
1226    def fixOwnership(self):
1227        """fix Ownership"""
1228        for s in self.portal_catalog(meta_type = 'Student'):
1229            student = s.getObject()
1230            sid = s.getId
1231            import pdb;pdb.set_trace()
1232            student.application.manage_setLocalRoles(sid, ['Owner',])
1233            student.personal.manage_setLocalRoles(sid, ['Owner',])
1234    ###)
1235
1236    security.declareProtected(View,"Title") ###(
1237    def Title(self):
1238        """compose title"""
1239        return "Student Section"
1240    ###)
1241
1242    def generateStudentId(self,letter,students = None): ###(
1243        import random
1244        r = random
1245        if students is None:
1246            students = self.portal_url.getPortalObject().campus.students
1247        if letter not in ('ABCDEFGIHKLMNOPQRSTUVWXY'):
1248            letter= r.choice('ABCDEFGHKLMNPQRSTUVWXY')
1249        sid = "%c%d" % (letter,r.randint(99999,1000000))
1250        while hasattr(students, sid):
1251            sid = "%c%d" % (letter,r.randint(99999,1000000))
1252        return sid
1253        #return "%c%d" % (r.choice('ABCDEFGHKLMNPQRSTUVWXY'),r.randint(99999,1000000))
1254    ###)
1255
1256InitializeClass(StudentsFolder)
1257
1258def addStudentsFolder(container, id, REQUEST=None, **kw): ###(
1259    """Add a Student."""
1260    ob = StudentsFolder(id, **kw)
1261    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1262    ###)
1263
1264###)
1265
1266class Student(CPSDocument): ###(
1267    """
1268    WAeUP Student container for the various student data
1269    """
1270    meta_type = 'Student'
1271    portal_type = meta_type
1272    security = ClassSecurityInfo()
1273
1274    security.declareProtected(View,"Title")
1275    def Title(self):
1276        """compose title"""
1277        reg_nr = self.getId()[1:]
1278        data = getattr(self,'personal',None)
1279        if data:
1280            content = data.getContent()
1281            return "%s %s %s" % (content.firstname,content.middlename,content.lastname)
1282        data = getattr(self,'application',None)
1283        if data:
1284            content = data.getContent()
1285            return "%s" % (content.jamb_lastname)
1286        return self.title
1287
1288    security.declarePrivate('makeStudentMember') ###(
1289    def makeStudentMember(self,sid,password='uNsEt'):
1290        """make the student a member"""
1291        membership = self.portal_membership
1292        membership.addMember(sid,
1293                             password ,
1294                             roles=('Member',
1295                                     'Student',
1296                                     ),
1297                             domains='',
1298                             properties = {'memberareaCreationFlag': False,
1299                                           'homeless': True},)
1300        member = membership.getMemberById(sid)
1301        self.portal_registration.afterAdd(member, sid, password, None)
1302        self.manage_setLocalRoles(sid, ['Owner',])
1303
1304###)
1305
1306    security.declareProtected(View,'createSubObjects') ###(
1307    def createSubObjects(self):
1308        """make the student a member"""
1309        dp = {'Title': 'Personal Data'}
1310        app_doc = self.application.getContent()
1311        names = app_doc.jamb_lastname.split()
1312        if len(names) == 3:
1313            dp['firstname'] = names[0].capitalize()
1314            dp['middlename'] = names[1].capitalize()
1315            dp['lastname'] = names[2].capitalize()
1316        elif len(names) == 2:
1317            dp['firstname'] = names[0].capitalize()
1318            dp['lastname'] = names[1].capitalize()
1319        else:
1320            dp['lastname'] = app_doc.jamb_lastname
1321        dp['sex'] = app_doc.jamb_sex == 'F'
1322        dp['lga'] = "%s/%s" % (app_doc.jamb_state,app_doc.jamb_lga )
1323        proxy = self.aq_parent
1324        proxy.invokeFactory('StudentPersonal','personal')
1325        per = proxy.personal
1326        per_doc = per.getContent()
1327        per_doc.edit(mapping = dp)
1328        per.manage_setLocalRoles(proxy.getId(), ['Owner',])
1329        #self.portal_workflow.doActionFor(per,'open',dest_container=per)
1330
1331###)
1332
1333InitializeClass(Student)
1334
1335def addStudent(container, id, REQUEST=None, **kw):
1336    """Add a Student."""
1337    ob = Student(id, **kw)
1338    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1339
1340###)
1341
1342class StudentAccommodation(CPSDocument): ###(
1343    """
1344    WAeUP Student container for the various student data
1345    """
1346    meta_type = 'StudentAccommodation'
1347    portal_type = meta_type
1348    security = ClassSecurityInfo()
1349
1350    security.declareProtected(View,"Title")
1351    def Title(self):
1352        """compose title"""
1353        content = self.getContent()
1354        #return "Accommodation Data for %s %s" % (content.firstname,content.lastname)
1355        return "Accommodation Data for Session %s" % content.session
1356
1357
1358InitializeClass(StudentAccommodation)
1359
1360def addStudentAccommodation(container, id, REQUEST=None, **kw):
1361    """Add a Students personal data."""
1362    ob = StudentAccommodation(id, **kw)
1363    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1364
1365###)
1366
1367class StudentPersonal(CPSDocument): ###(
1368    """
1369    WAeUP Student container for the various student data
1370    """
1371    meta_type = 'StudentPersonal'
1372    portal_type = meta_type
1373    security = ClassSecurityInfo()
1374
1375    security.declareProtected(View,"Title")
1376    def Title(self):
1377        """compose title"""
1378        content = self.getContent()
1379        #return "Personal Data for %s %s" % (content.firstname,content.lastname)
1380        return "Personal Data"
1381
1382
1383InitializeClass(StudentPersonal)
1384
1385def addStudentPersonal(container, id, REQUEST=None, **kw):
1386    """Add a Students personal data."""
1387    ob = StudentPersonal(id, **kw)
1388    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1389
1390###)
1391
1392class StudentClearance(CPSDocument): ###(
1393    """
1394    WAeUP Student container for the various student data
1395    """
1396    meta_type = 'StudentClearance'
1397    portal_type = meta_type
1398    security = ClassSecurityInfo()
1399
1400    security.declareProtected(View,"Title")
1401    def Title(self):
1402        """compose title"""
1403        content = self.getContent()
1404        #return "Clearance/Eligibility Record for %s %s" % (content.firstname,content.lastname)
1405        return "Clearance/Eligibility Record"
1406
1407
1408InitializeClass(StudentClearance)
1409
1410def addStudentClearance(container, id, REQUEST=None, **kw):
1411    """Add a Students personal data."""
1412    ob = StudentClearance(id, **kw)
1413    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1414
1415###)
1416
1417class StudentStudyLevel(CPSDocument): ###(
1418    """
1419    WAeUP Student container for the various student data
1420    """
1421    meta_type = 'StudentStudyLevel'
1422    portal_type = meta_type
1423    security = ClassSecurityInfo()
1424
1425    security.declareProtected(View,"Title")
1426    def Title(self):
1427        """compose title"""
1428        return "Level %s" % self.aq_parent.getId()
1429
1430    def create_course_results(self,cert_id,current_level): ###(
1431        "create all courses in a level"
1432        aq_portal = self.portal_catalog.evalAdvancedQuery
1433        res = self.portal_catalog(portal_type="Certificate", id = cert_id)
1434        l = []
1435        import transaction
1436        if res:
1437            cert = res[0]
1438            path = cert.getPath()
1439            query = Eq("path","%s/%s" % (path,current_level)) &\
1440                    Eq('portal_type','CertificateCourse')
1441            courses = aq_portal(query)
1442            #from pdb import set_trace;set_trace()
1443            self_proxy = self.aq_parent
1444            for c in courses:
1445                d = self.getCourseInfo(c.getId)
1446                cr_id = self_proxy.invokeFactory('StudentCourseResult',c.getId)
1447                course_result = getattr(self_proxy,cr_id)
1448                self.portal_workflow.doActionFor(course_result,'open')
1449                d['core_or_elective'] = getattr(c.getObject().getContent(),'core_or_elective')
1450                course_result.getContent().edit(mapping=d)
1451                #transaction.commit()
1452    ###)
1453
1454InitializeClass(StudentStudyLevel)
1455
1456def addStudentStudyLevel(container, id, REQUEST=None, **kw):
1457    """Add a Students personal data."""
1458    ob = StudentStudyLevel(id, **kw)
1459    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1460
1461###)
1462
1463class StudentStudyCourse(CPSDocument): ###(
1464    """
1465    WAeUP Student container for the various student data
1466    """
1467    meta_type = 'StudentStudyCourse'
1468    portal_type = meta_type
1469    security = ClassSecurityInfo()
1470
1471    security.declareProtected(View,"Title")
1472    def Title(self):
1473        """compose title"""
1474        content = self.getContent()
1475        return "Study Course"
1476
1477
1478InitializeClass(StudentStudyCourse)
1479
1480def addStudentStudyCourse(container, id, REQUEST=None, **kw):
1481    """Add a Students personal data."""
1482    ob = StudentStudyCourse(id, **kw)
1483    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1484
1485###)
1486
1487class StudentApplication(CPSDocument): ###(
1488    """
1489    WAeUP Student container for the various student data
1490    """
1491    meta_type = 'StudentApplication'
1492    portal_type = meta_type
1493    security = ClassSecurityInfo()
1494
1495    security.declareProtected(View,"Title")
1496    def Title(self):
1497        """compose title"""
1498        return "Application Data"
1499
1500
1501InitializeClass(StudentApplication)
1502
1503def addStudentApplication(container, id, REQUEST=None, **kw):
1504    """Add a Students eligibility data."""
1505    ob = StudentApplication(id, **kw)
1506    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1507###)
1508
1509class StudentPume(CPSDocument): ###(
1510    """
1511    WAeUP Student container for the various student data
1512    """
1513    meta_type = 'StudentPume'
1514    portal_type = meta_type
1515    security = ClassSecurityInfo()
1516
1517    security.declareProtected(View,"Title")
1518    def Title(self):
1519        """compose title"""
1520        return "PUME Results"
1521
1522
1523InitializeClass(StudentPume)
1524
1525def addStudentPume(container, id, REQUEST=None, **kw):
1526    """Add a Students PUME data."""
1527    ob = StudentPume(id, **kw)
1528    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1529###)
1530
1531##class StudentSemester(CPSDocument): ###(
1532##    """
1533##    WAeUP StudentSemester containing the courses and students
1534##    """
1535##    meta_type = 'StudentSemester'
1536##    portal_type = meta_type
1537##    security = ClassSecurityInfo()
1538##
1539##InitializeClass(StudentSemester)
1540##
1541##def addStudentSemester(container, id, REQUEST=None, **kw):
1542##    """Add a StudentSemester."""
1543##    ob = StudentSemester(id, **kw)
1544##    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1545##
1546#####)
1547
1548##class Semester(CPSDocument): ###(
1549##    """
1550##    WAeUP Semester containing the courses and students
1551##    """
1552##    meta_type = 'Semester'
1553##    portal_type = meta_type
1554##    security = ClassSecurityInfo()
1555##
1556##InitializeClass(Semester)
1557##
1558##def addSemester(container, id, REQUEST=None, **kw):
1559##    """Add a Semester."""
1560##    ob = Semester(id, **kw)
1561##    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1562##
1563#####)
1564
1565class StudentCourseResult(CPSDocument): ###(
1566    """
1567    WAeUP StudentCourseResult
1568    """
1569    meta_type = 'StudentCourseResult'
1570    portal_type = meta_type
1571    security = ClassSecurityInfo()
1572
1573    def getCourseEntry(self,cid):
1574        res = self.portal_catalog({'meta_type': "Course",
1575                                           'id': cid})
1576        if res:
1577            return res[-1]
1578        else:
1579            return None
1580
1581    security.declareProtected(View,"Title")
1582    def Title(self):
1583        """compose title"""
1584        cid = self.aq_parent.getId()
1585        ce = self.getCourseEntry(cid)
1586        if ce:
1587            return "%s" % ce.Title
1588        return "No course with id %s" % cid
1589
1590InitializeClass(StudentCourseResult)
1591
1592def addStudentCourseResult(container, id, REQUEST=None, **kw):
1593    """Add a StudentCourseResult."""
1594    ob = StudentCourseResult(id, **kw)
1595    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1596###)
1597
1598# Backward Compatibility StudyLevel
1599
1600from Products.WAeUP_SRP.Academics import StudyLevel
1601
1602from Products.WAeUP_SRP.Academics import addStudyLevel
1603
Note: See TracBrowser for help on using the repository browser.