source: WAeUP_SRP/trunk/Students.py @ 1986

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

add dumpStudentsCatalog

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