source: WAeUP_SRP/trunk/Students.py @ 1812

Last change on this file since 1812 was 1809, checked in by Henrik Bettermann, 18 years ago

set current_level correctly

  • Property svn:keywords set to Id
File size: 49.3 KB
Line 
1#-*- mode: python; mode: fold -*-
2# $Id: Students.py 1809 2007-05-23 04:56:35Z henrik $
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 logging
20import csv,re,os
21import Globals
22p_home = Globals.package_home(globals())
23i_home = Globals.INSTANCE_HOME
24MAX_TRANS = 1000
25from urllib import urlencode
26
27import DateTime
28#import PIL.Image
29from StringIO import StringIO
30
31def makeCertificateCode(code): ###(
32    code = code.replace('.','')
33    code = code.replace('(','')
34    code = code.replace(')','')
35    code = code.replace('/','')
36    code = code.replace(' ','')
37    code = code.replace('_','')
38    return code
39
40###)
41
42def response_write(response,s):
43    response.setHeader('Content-type','text/html; charset=ISO-8859-15')
44    while s.find('<') > -1:
45        s = s.replace('<','&lt;')
46    while s.find('>') > -1:
47        #from pdb import set_trace;set_trace()
48        s = s.replace('>','&gt;')
49    response.write("%s<br>\n" % s)
50
51def getInt(s): ###(
52    try:
53        return int(s)
54    except:
55        return 0
56
57def getFloat(s):
58    try:
59        return float(s)
60    except:
61        return 0.0
62
63###)
64
65def getStudentByRegNo(self,reg_no): ###(
66    """search student by JAMB Reg No and return StudentFolder"""
67    search = ZCatalog.searchResults(self.portal_catalog,{'meta_type': 'StudentApplication',
68                                  'SearchableText': reg_no,
69                                  })
70    if len(search) < 1:
71        return None
72    return search[0].getObject().aq_parent
73
74###)
75
76def checkJambNo(jnr):
77    try:
78        if len(jnr) != 10:
79            return False
80    except:
81        return False
82    try:
83        int(jnr[:8])
84        return True
85    except:
86        return False
87
88class StudentsFolder(CPSDocument): ###(
89    """
90    WAeUP container for the various WAeUP containers data
91    """
92    meta_type = 'StudentsFolder'
93    portal_type = meta_type
94    security = ClassSecurityInfo()
95
96    security.declareProtected(ModifyPortalContent,"loadPumeResultsFromCSV")###(
97    def loadPumeResultsFromCSV(self):
98        """load Fulltime Studentdata from CSV values into pumeresults catalog"""
99        import transaction
100        import random
101##        csv_d = {'jamb_reg_no': "RegNumber", ###(
102##                 'status': "Admission Status",
103##                 'name': "Name",
104##                 'score': "Score",
105##                 'sex': "Sex",
106##                 'faculty': "Faculty",
107##                 'department': "Dept",
108##                 'course': "Course",
109##                 'course_code_org': "Course Code",
110##                 }
111###)
112##        csv_d = {'jamb_reg_no': "JAMBRegno",
113##                'name': "Name",
114##                'score': "Score",
115##                 'sex': "Sex",
116##                 'course': "Course",
117##                 'faculty': "Faculty",
118##                 'department': "Dept",
119##                 'course_code_org': "Course Code",
120##                 'status': "Admission Status",
121##                 'result_type': None,
122##                 }
123
124        csv_d = {'jamb_reg_no': "reg_no",
125                 'name': "fullname",
126                 'score': "pume_score",
127                 'sex': "sex",
128                 'course': "study_course",
129                 'course_code_org': "study_course",
130                 'status': "admission_status",
131                 'result_type': "entry_mode",
132                 }
133
134        csv_fields = [f[1] for f in csv_d.items() if f[1]]
135        tr_count = 0
136        total = 0
137        #name = 'pup_new'
138        #name = 'pup_update'
139        name = 'Admitted'
140        update = name.endswith('update')
141        no_import = []
142        ok_import = []
143        ok_import.append('%s' % ','.join(['"%s"' % fn for fn in csv_d.keys()]))
144        no_import.append('%s' % ','.join(['"%s"' % fn for fn in csv_fields]))
145        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
146        ok_import_name = "%s/import/%s_imported_%s.csv" % (i_home,name,current)
147        #open(ok_import_name,"w").write('\n'.join(no_import))
148        no_import_name = "%s/import/%s_not_imported_%s.csv" % (i_home,name,current)
149        #open(no_import_name,"w").write('\n'.join(no_import))
150        logger = logging.getLogger('Import.%s' % name)
151        starttime = DateTime.now()
152        logger.info('Start loading from %s.csv' % name)
153        try:
154            result = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
155        except:
156            logger.error('Error reading %s.csv' % name)
157            return
158        pume = self.portal_pumeresults
159        format = ','.join(['"%%(%s)s"' % fn for fn in csv_fields])
160        import_format = ','.join(['"%%(%s)s"' % fn for fn in csv_d.keys()])
161        eduplicate = '%s,"duplicate"' % format
162        einvalidjamb = '%s,"invalid JambRegNo"' % format
163        added = 'added ,%s' % format
164        #from pdb import set_trace;set_trace()
165        for jamb in result:
166            dict = {}
167            for f,fn in csv_d.items():
168                dict[f] = jamb.get(csv_d[f])
169            dict['result_type'] = 'CEST'
170            jnr = jamb.get(csv_d['jamb_reg_no'])
171            #if not checkJambNo(jnr):
172            #    logger.info(einvalidjamb % jamb)
173            #    dd = {}
174            #    for f,fn in csv_d.items():
175            #        dd[fn] = getattr(data,f)
176            #        no_import.append(eduplicate % dd)
177            #        no_import.append(eduplicate % jamb)
178            #    continue
179            res = pume(jamb_reg_no=jnr)
180            if len(res) > 0:
181                if update:
182                    try:
183                        pume.modifyRecord(**dict)
184                    except ValueError:
185                        logger.info(eduplicate % jamb)
186                        continue
187                    except KeyError:
188                        pume.addRecord(**dict)
189                        logger.info(added % jamb)
190                        continue
191                else:
192                    data = res[0]
193                    if data.name != jamb.get(csv_d['name']):
194                        #set_trace()
195                        logger.info(eduplicate % jamb)
196                        #em = 'Student with REG-NO %(jamb_reg_no)s already exists\n' % dict
197                        #logger.info(em)
198                        dd = {}
199                        for f,fn in csv_d.items():
200                            dd[fn] = getattr(data,f)
201                        no_import.append(eduplicate % dd)
202                        no_import.append(eduplicate % jamb)
203                    continue
204            try:
205                pume.addRecord(**dict)
206                ok_import.append(import_format % dict)
207            except ValueError:
208                logger.info(eduplicate % jamb)
209                #em = 'Student with REG-NO %(jamb_reg_no)s already exists\n' % dict
210                #logger.info(em)
211                no_import.append(eduplicate % jamb)
212        logger.info('End loading from %s.csv' % name)
213        if len(no_import) > 1:
214            open(no_import_name,"w+").write('\n'.join(no_import))
215        open(ok_import_name,"w+").write('\n'.join(ok_import))
216        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
217    ###)
218
219    security.declareProtected(ModifyPortalContent,"createStudents")###(
220    def createStudents(self):
221        """
222        load addmitted Studentdata from CSV values and create Studentobjects.
223        This is the current method to create new addmitted Students.
224        Before running the eventservice for the students_catalog must be disabled.
225        """
226        import transaction
227        import random
228        #from pdb import set_trace
229        wftool = self.portal_workflow
230        #students_folder = self.portal_catalog({'meta_type': 'StudentsFolder'})[-1].getObject()
231        students_folder = self.portal_url.getPortalObject().campus.students
232        levels =       {'ume_ft':'100',
233                        'de_ft': '200',
234                        'ug_pt': '100',
235                        'de_pt': '200',
236                        'pg_ft': '700',
237                        'pg_pt': '700',
238                        'dp_pt': '100',
239                        'dp_ft': '100',
240                        }
241        csv_d = {'jamb_reg_no': "reg_no",
242                 'entry_mode': 'entry_mode',
243                 'jamb_firstname': "firstname",
244                 'jamb_middlename': "middlename",
245                 'jamb_lastname': "lastname",
246                 'jamb_sex': "sex",
247                 'jamb_state': "state",
248                 'birthday': "date_of_birth",
249                 'app_email': "email",
250                 'study_course': "study_course",
251                 'perm_address': "address",
252                 'admission_status': "admission_status",
253                 }
254        csv_fields = [f[1] for f in csv_d.items()]
255        tr_count = 0
256        total = 0
257        #name = 'pume_results'
258        name = 'Admitted'
259        no_import = []
260        s = ','.join(['"%s"' % fn for fn in csv_fields])
261        no_import.append('"Error",%s' % s)
262        format = '"%(Error)s",' + ','.join(['"%%(%s)s"' % fn for fn in csv_fields])
263        no_certificate = "no certificate %s" % format
264        open("%s/import/%s_not_imported.csv" % (i_home,name),"w").write('\n'.join(no_import))
265        logger = logging.getLogger('Students.StudentsFolder.createStudents')
266        logger.info('Start loading from %s.csv' % name)
267        certs = {}
268        try:
269            results = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
270        except:
271            logger.error('Error reading %s.csv' % name)
272            return
273        for result in results:
274            if not result.get(csv_d['admission_status']).startswith('Admitted'):
275                continue
276            #result['Error'] = "Processing "
277            #logger.info(format % result)
278            jamb_reg_no = result.get(csv_d['jamb_reg_no'])
279            res = self.students_catalog(jamb_reg_no = jamb_reg_no)
280            if res:
281                em = 'Student with RegNo %s already exists\n' % jamb_reg_no
282                logger.info(em)
283                result['Error'] = "Student exists"
284                no_import.append(format % result)
285                continue
286            cert_id = makeCertificateCode(result.get(csv_d['study_course']))
287            if cert_id not in certs.keys():
288                res = self.portal_catalog(meta_type = "Certificate",id = cert_id)
289                if not res:
290                    em = 'No Certificate with ID %s \n' % cert_id
291                    logger.info(em)
292                    result['Error'] = "No Certificate %s" % cert_id
293                    no_import.append( format % result)
294                    continue
295                cert = res[0]
296                cert_path = cert.getPath().split('/')
297                certificate = certs[cert_id] = {'faculty': cert_path[-4],
298                                     'department': cert_path[-3]}
299            cert_doc = certs[cert_id]
300            catalog_entry = {}
301            catalog_entry['jamb_reg_no'] = jamb_reg_no
302            firstname = result.get(csv_d['jamb_firstname'])
303            middlename = result.get(csv_d['jamb_middlename'])
304            lastname = result.get(csv_d['jamb_lastname'])
305            perm_address = result.get(csv_d['perm_address'])
306            sid = self.generateStudentId('x')
307            students_folder.invokeFactory('Student', sid)
308            catalog_entry['id'] = sid
309            tr_count += 1
310            logger.info('%(total)s+%(tr_count)s: Creating Student with ID %(sid)s reg_no %(jamb_reg_no)s ' % vars())
311            student = getattr(self,sid)
312            student.manage_setLocalRoles(sid, ['Owner',])
313            student.invokeFactory('StudentApplication','application')
314            da = {'Title': 'Application Data'}
315            da["jamb_firstname"] = firstname
316            da["jamb_middlename"] = middlename
317            da["jamb_lastname"] = lastname
318            catalog_entry['entry_session'] = da["entry_session"] = self.getSessionId()[-2:]
319            catalog_entry['sex'] = sex = result.get(csv_d['jamb_sex']).startswith('F')
320            da_fields = ('jamb_reg_no',
321                         'jamb_sex',
322                         'jamb_state',
323                         'entry_mode',
324                         'app_email',
325                         )
326            for f in da_fields:
327                da[f] = result.get(csv_d[f])
328            catalog_entry['email'] = da['app_email']
329            catalog_entry['entry_mode'] = da['entry_mode']
330            app = student.application
331            app_doc = app.getContent()
332            app.getContent().edit(mapping=da)
333            picture ="%s/import/pictures/%s.jpg" % (i_home,jamb_reg_no)
334            app.manage_setLocalRoles(sid, ['Owner',])
335
336            picture_id = da['jamb_reg_no'].replace('/','_')
337            file = None
338            for ext in ('jpg','JPG'):
339                picture ="%s/import/pictures_admitted_latest/%s.%s" % (i_home,picture_id,ext)
340                if os.path.exists(picture):
341                    file = open(picture)
342                    break
343            if file is not None:
344
345                ## file conversion does not work
346                #img = PIL.Image.open(file)
347                #img.thumbnail((150,200),
348                #              resample=PIL.Image.ANTIALIAS)
349                #outfile = StringIO()
350                #img.save(outfile, format=img.format)
351
352                outfile = file.read()
353                app_doc.manage_addFile('passport',
354                                       file=outfile,
355                                       title="%s.jpg" % jamb_reg_no)
356            #wftool.doActionFor(app,'close')
357            dp = {}
358            dp['firstname'] = firstname
359            dp['middlename'] = middlename
360            dp['lastname'] = lastname
361            dp['email'] = da['app_email']
362            dp['sex'] = sex
363            dp['perm_address'] = perm_address
364            catalog_entry['name'] = "%(firstname)s %(middlename)s %(lastname)s" % dp
365            student.invokeFactory('StudentPersonal','personal')
366            per = student.personal
367            per_doc = per.getContent()
368            per_doc.edit(mapping = dp)
369            per.manage_setLocalRoles(sid, ['Owner',])
370            wftool.doActionFor(student,'pume_pass')
371            wftool.doActionFor(student,'admit')
372            #
373            # Clearance
374            #
375            student.invokeFactory('StudentClearance','clearance')
376            #wftool.doActionFor(student.clearance,'open')
377            clearance = student.clearance
378            dc = {'Title': 'Clearance/Eligibility Record'}
379            clearance = student.clearance
380            date_str = result.get(csv_d['birthday'])
381            try:
382                date = DateTime.DateTime(date_str)
383            except:
384                #import pdb;pdb.set_trace()
385                date = None
386            dc['birthday'] = date
387            clearance.getContent().edit(mapping=dc)
388            clearance.manage_setLocalRoles(sid, ['Owner',])
389            #
390            # Study Course
391            #
392            student.invokeFactory('StudentStudyCourse','study_course')
393            study_course = student.study_course
394            dsc = {}
395            catalog_entry['level'] = dsc['current_level'] = entry_levels.get(da['entry_mode'],'100')
396            #catalog_entry['level'] = dsc['current_level'] = '100'  # Attention: not for DE students           
397            catalog_entry['session'] = dsc['current_session'] = da['entry_session']
398            catalog_entry['mode'] = dsc['current_mode'] = da['entry_mode']
399            catalog_entry['course'] = dsc['study_course'] = cert_id
400            catalog_entry['faculty'] = certificate['faculty']
401            catalog_entry['department'] = certificate['department']
402            catalog_entry['verdict'] = dsc['current_verdict'] = 'N/A'
403            catalog_entry['review_state'] = self.portal_workflow.getInfoFor(student,'review_state',None)
404            study_course.getContent().edit(mapping=dsc)
405            #import pdb;pdb.set_trace()
406            self.students_catalog.addRecord(**catalog_entry)
407            if tr_count > 1000:
408                if len(no_import) > 0:
409                    open("%s/import/%s_not_imported.csv" % (i_home,name),"a").write(
410                             '\n'.join(no_import) + "\n")
411                    no_import = []
412                em = '%d transactions commited\n' % tr_count
413                transaction.commit()
414                logger.info(em)
415                total += tr_count
416                tr_count = 0
417        open("%s/import/%s_not_imported.csv" % (i_home,name),"a").write(
418                                                '\n'.join(no_import))
419        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
420    ###)
421
422    security.declareProtected(ModifyPortalContent,"importReturningStudents")###(
423    def importReturningStudents(self):
424        """load Returning Studentdata from CSV values"""
425        import transaction
426        import random
427        #from pdb import set_trace
428        wftool = self.portal_workflow
429        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
430        #students_folder = self.portal_catalog({'meta_type': 'StudentsFolder'})[-1].getObject()
431        students_folder = self.portal_url.getPortalObject().campus.students
432        tr_count = 1
433        total = 0
434        #name = 'pume_results'
435        name = 'Returning'
436        table = self.returning_import
437        no_import = []
438        imported = []
439        logger = logging.getLogger('Students.StudentsFolder.importReturningStudents')
440        try:
441            returning = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
442        except:
443            logger.error('Error reading %s.csv' % name)
444            return
445        l = self.portal_catalog({'meta_type': "Certificate"})
446        certs = {}
447        cert_docs = {}
448        for f in l:
449            certs[f.getId] = f.getObject().getContent()
450        start = True
451        res = table()
452        regs = []
453        if len(res) > 0:
454            regs = [s.matric_no for s in res]
455        #import pdb;pdb.set_trace()
456        for student in returning:
457            if start:
458                start = False
459                logger.info('Start loading from %s.csv' % name)
460                s = ','.join(['"%s"' % fn for fn in student.keys()])
461                imported.append(s)
462                no_import.append('%s,"Error"' % s)
463                format = ','.join(['"%%(%s)s"' % fn for fn in student.keys()])
464                format_error = format + ',"%(Error)s"'
465                no_certificate = "no certificate %s" % format
466            student['matric_no'] = matric_no = student.get('matric_no').upper()
467            student['Mode_of_Entry'] = entry_mode = student.get('Mode of Entry').upper()
468            student['Permanent_Address'] = perm_address = student.get('Permanent Address')
469            if matric_no == '':
470                student['Error'] = "Empty matric_no"
471                no_import.append( format_error % student)
472                continue
473            if matric_no in regs or self.returning_import(matric_no = matric_no):
474                student['Error'] = "Duplicate"
475                no_import.append( format_error % student)
476                continue
477            cert_id = makeCertificateCode(student.get('Coursemajorcode'))
478            if cert_id not in certs.keys():
479                student['Error'] = "No Certificate %s" % cert_id
480                no_import.append( format_error % student)
481                continue
482            try:
483                table.addRecord(**student)
484            except ValueError:
485                student['Error'] = "Duplicate"
486                no_import.append( format_error % student)
487                continue
488            regs.append(student.get('matric_no'))
489            imported.append(format % student)
490            tr_count += 1
491            if tr_count > 1000:
492                if len(no_import) > 0:
493                    open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
494                             '\n'.join(no_import) + '\n')
495                    no_import = []
496                open("%s/import/%simported%s.csv" % (i_home,name,current),"a").write(
497                                            '\n'.join(no_import) + "\n")
498                imported = []
499                em = '%d transactions commited total %s\n' % (tr_count,total)
500                transaction.commit()
501                regs = []
502                logger.info(em)
503                total += tr_count
504                tr_count = 0
505        open("%s/import/%simported%s.csv" % (i_home,name,current),"a").write(
506                                            '\n'.join(imported))
507        open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
508                                                '\n'.join(no_import))
509        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
510    ###)
511
512    security.declareProtected(ModifyPortalContent,"fixAllNames")###(
513    def fixAllNames(self):
514        "fix all students names"
515        import transaction
516        response = self.REQUEST.RESPONSE
517        logger = logging.getLogger('fixAllNames')
518        logger.info('Start')
519        students = self.portal_catalog(portal_type='Student')
520        count = 0
521        total = 0
522        for student in students:
523            scat_res = self.students_catalog(id = student.getId)
524            if not scat_res:
525                self.students_catalog.addRecord(id = student.getId)
526                scat_res = self.students_catalog(id = student.getId)
527            student_entry = scat_res[0]
528            old_new = self.fixName(student,student_entry)
529            count += 1
530            response_write(response,'"%d","%s",%s' % (count + total,student_entry.id,old_new))
531            if count > 2000:
532                transaction.commit()
533                logger.info("%d transactions commited" % count)
534                total += count
535                count = 0
536    ###)
537
538    security.declareProtected(ModifyPortalContent,"fixName")###(
539    def fixName(self,student_brain, student_entry):
540        "fix the name of a student"
541        fix = "first"
542        if student_entry.get('name_fixed',None) == fix:
543            return "Name already fixed"
544        student_id = student_entry.id
545        new_student = student_entry.jamb_reg_no.startswith('6')
546        student_obj = student_brain.getObject()
547        personal = getattr(student_obj,'personal',None)
548        invalid = ''
549        if personal is None:
550            return '"%s","Returning","%s","%s"' % (invalid,student_entry.name,"not logged in")
551        per_doc = personal.getContent()
552        old_first = per_doc.firstname
553        old_middle = per_doc.middlename
554        old_last = per_doc.lastname
555        new_first = ''
556        new_middle = ''
557        new_last = ''
558        if new_student:
559            if not old_first and not old_middle and old_last:
560                new_names = [n.capitalize() for n in old_last.split()]
561                if len(new_names) > 1:
562                    old_first = new_names[0]
563                    old_last = new_names[-1]
564                    old_middle = ' '.join(new_names[1:-1])
565                else:
566                    old_last = new_names[0]
567                    old_first = ''
568                    old_middle = ''
569            if old_first:
570                new_first = old_first
571            if old_middle:
572                new_middle = old_middle
573            if old_last:
574                new_last = old_last
575            if old_first.find('<') != -1 or\
576               old_first.find('>') != -1 or\
577               old_middle.find('<') != -1 or\
578               old_middle.find('>') != -1 or\
579               old_last.find('<') != -1 or\
580               old_last.find('>') != -1:
581                   invalid = "invalid characters"
582        else:
583            new_first = old_first
584            if new_first.strip() == '-':
585                new_first = ''
586            new_middle = old_middle
587            if new_middle.strip() == '-':
588                new_middle = ''
589            new_last = old_last
590            if new_last.strip() == '-':
591                new_last = ''
592        name = "%(new_first)s %(new_middle)s %(new_last)s" % vars()
593        if new_student:
594            text = "New"
595        else:
596            text = "Returning"
597        old_new = '"%s","%s","%s","%s"' % (invalid,text,
598                                           student_entry.name,
599                                           name)
600        if not invalid:
601            self.students_catalog.modifyRecord(id = student_id,
602                                      name_fixed = fix,
603                                      name = name)
604            per_doc.edit(mapping = {'firstname' : new_first,
605                                'middlename' : new_middle,
606                                'lastname' : new_last,
607                                })
608        return old_new
609    ###)
610
611    security.declareProtected(ModifyPortalContent,"updateReturningStudents")###(
612    def updateReturningStudents(self):
613        """load and overwrite Returning Student Data from CSV values"""
614        import transaction
615        import random
616        #from pdb import set_trace
617        wftool = self.portal_workflow
618        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
619        #students_folder = self.portal_catalog({'meta_type': 'StudentsFolder'})[-1].getObject()
620        students_folder = self.portal_url.getPortalObject().campus.students
621        tr_count = 1
622        total = 0
623        #name = 'pume_results'
624        name = 'Returning_update'
625        table = self.returning_import
626        no_import = []
627        imported = []
628        logger = logging.getLogger('Students.StudentsFolder.updateReturningStudents')
629        try:
630            returning = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
631        except:
632            logger.error('Error reading %s.csv' % name)
633            return
634        l = self.portal_catalog({'meta_type': "Certificate"})
635        certs = {}
636        cert_docs = {}
637        for f in l:
638            certs[f.getId] = f.getObject().getContent()
639        start = True
640        res = table()
641        regs = []
642        if len(res) > 0:
643            regs = [s.matric_no for s in res]
644        for student in returning:
645            if start:
646                start = False
647                logger.info('Start loading from %s.csv' % name)
648                s = ','.join(['"%s"' % fn for fn in student.keys()])
649                imported.append(s)
650                no_import.append('%s,"Error"' % s)
651                format = ','.join(['"%%(%s)s"' % fn for fn in student.keys()])
652                format_error = format + ',"%(Error)s"'
653                no_certificate = "no certificate %s" % format
654            matric_no = student.get('matric_no').upper()
655            student['matric_no'] = matric_no
656            if matric_no == '':
657                student['Error'] = "Empty matric_no"
658                no_import.append( format_error % student)
659                continue
660#            if matric_no in regs or self.returning_import(matric_no = matric_no):
661#                student['Error'] = "Duplicate"
662#                no_import.append( format_error % student)
663#                continue
664#            cert_id = makeCertificateCode(student.get('Coursemajorcode'))
665#            if cert_id not in certs.keys():
666#                student['Error'] = "No Certificate %s" % cert_id
667#                no_import.append( format_error % student)
668#                continue
669            try:
670                table.modifyRecord(**student)
671            except KeyError:
672                #import pdb;pdb.set_trace()
673                student['Error'] = "no Student found to update"
674                no_import.append( format_error % student)
675                continue
676            #s = self.students_catalog(matric_no=matric_no)
677            #if s:
678            #    level = "%s" % (int(student.get('Level')) + 100)
679            #    self.students_catalog.modifyRecord(id = s[0].id,
680            #                                           level=level)
681
682            regs.append(student.get('matric_no'))
683            imported.append(format % student)
684            tr_count += 1
685            if tr_count > 1000:
686                if len(no_import) > 0:
687                    open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
688                             '\n'.join(no_import) + '\n')
689                    no_import = []
690                open("%s/import/%simported%s.csv" % (i_home,name,current),"a").write(
691                                            '\n'.join(no_import) + "\n")
692                imported = []
693                em = '%d transactions commited total %s\n' % (tr_count,total)
694                transaction.commit()
695                regs = []
696                logger.info(em)
697                total += tr_count
698                tr_count = 0
699        open("%s/import/%simported%s.csv" % (i_home,name,current),"a").write(
700                                            '\n'.join(imported))
701        open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
702                                                '\n'.join(no_import))
703        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
704    ###)
705
706    security.declareProtected(ModifyPortalContent,"importResults")###(
707    def importResults(self):
708        """load Returning Students Results from CSV"""
709        import transaction
710        import random
711        #from pdb import set_trace
712        wftool = self.portal_workflow
713        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
714        #students_folder = self.portal_catalog({'meta_type': 'StudentsFolder'})[-1].getObject()
715        students_folder = self.portal_url.getPortalObject().campus.students
716        tr_count = 1
717        total = 0
718        #name = 'pume_results'
719        name = 'Results'
720        table = self.results_import
721        no_import = []
722        imported = []
723        logger = logging.getLogger('Students.StudentsFolder.importResults')
724        try:
725            results = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
726        except:
727            logger.error('Error reading %s.csv' % name)
728            return
729        l = self.portal_catalog({'meta_type': "Course"})
730        courses = [f.getId for f in l]
731        start = True
732        res = table()
733        regs = []
734        if len(res) > 0:
735            regs = [s.key for s in res]
736        no_course = []
737        no_course_list = []
738        course_count = 0
739        for result in results:
740            if start:
741                start = False
742                logger.info('Start loading from %s.csv' % name)
743                s = ','.join(['"%s"' % fn for fn in result.keys()])
744                imported.append(s)
745                no_import.append('%s,"Error"' % s)
746                format = ','.join(['"%%(%s)s"' % fn for fn in result.keys()])
747                format_error = format + ',"%(Error)s"'
748                no_certificate = "no certificate %s" % format
749            course_id = result.get('CosCode')
750            if not course_id:
751                course_id = 'N/A'
752                result['CosCode'] = course_id
753            matric_no = result.get('matric_no').upper()
754            result['matric_no'] = matric_no
755            key = matric_no+course_id
756            if matric_no == '':
757                result['Error'] = "Empty matric_no"
758                no_import.append( format_error % result)
759                continue
760            if key in regs or self.results_import(key = key):
761                result['Error'] = "Duplicate"
762                no_import.append( format_error % result)
763                continue
764            if course_id not in courses:
765                if course_id not in no_course:
766                    course_count +=1
767                    no_course.append(course_id)
768                    no_course_list.append('"%s"' % course_id)
769                    #result['Error'] = "No Course"
770                    #logger.info(format_error % result)
771            regs.append(key)
772            imported.append(format % result)
773            tr_count += 1
774            if tr_count > 1000:
775                if len(no_import) > 0:
776                    open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
777                             '\n'.join(no_import)+'\n')
778                    no_import = []
779                open("%s/import/%simported%s.csv" % (i_home,name,current),"a").write(
780                                            '\n'.join(imported) + '\n')
781                imported = []
782                if no_course_list:
783                    open("%s/import/%sno_courses%s.csv" % (i_home,name,current),"a").write(
784                                            '\n'.join(no_course_list) + '\n')
785                    no_course_list = []
786                em = '%d transactions commited total %s\n courses not found %s' % (tr_count,total,course_count)
787                transaction.commit()
788                logger.info(em)
789                regs = []
790                total += tr_count
791                tr_count = 0
792        open("%s/import/%simported%s.csv" % (i_home,name,current),"a").write(
793                                            '\n'.join(imported))
794        open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
795                                                '\n'.join(no_import))
796        if no_course_list:
797            open("%s/import/%sno_courses%s.csv" % (i_home,name,current),"a").write(
798                                    '\n'.join(no_course_list))
799        em = '%d transactions commited total %s\n courses not found %s' % (tr_count,total,course_count)
800        logger.info(em)
801        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
802    ###)
803
804    security.declareProtected(ModifyPortalContent,"updateStudyCourse")###(
805    def updateStudyCourse(self):
806        """update StudyCourse from CSV values"""
807        import transaction
808        import random
809        from pdb import set_trace
810        wftool = self.portal_workflow
811        #students_folder = self.portal_catalog({'meta_type': 'StudentsFolder'})[-1].getObject()
812        students_folder = self.portal_url.getPortalObject().campus.students
813        csv_d = {'jamb_reg_no': "RegNumber",
814                 'jamb_lastname': "Name",
815                 'session': "Session",
816                 'pume_tot_score': "PUME SCORE",
817                 'jamb_score': "JambScore",
818                 'jamb_sex': "Sex",
819                 'jamb_state': "State",
820##                 'jamb_first_cos': "AdminCourse",
821                 'faculty': "AdminFaculty",
822                 'course_code': "AdmitCoscode",
823                 'stud_status':"AdmitStatus",
824                 'department': "AdmitDept",
825                 'jamb_lga': "LGA",
826                 'app_email': "email",
827                 'app_mobile': "PhoneNumbers",
828                 }
829        csv_fields = [f[1] for f in csv_d.items()]
830        tr_count = 0
831        total = 0
832        #name = 'pume_results'
833        name = 'StudyCourseChange'
834        no_import = []
835        s = ','.join(['"%s"' % fn for fn in csv_fields])
836        no_import.append('"Error",%s' % s)
837        format = '"%(Error)s",' + ','.join(['"%%(%s)s"' % fn for fn in csv_fields])
838        no_certificate = "no certificate %s" % format
839        open("%s/import/%s_not_imported.csv" % (i_home,name),"w").write(
840                    '\n'.join(no_import))
841        logger = logging.getLogger('Students.StudentsFolder.updateStudyCourse')
842        logger.info('Start loading from %s.csv' % name)
843        l = self.portal_catalog({'meta_type': "Certificate"})
844        try:
845            result = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
846        except:
847            logger.error('Error reading %s.csv' % name)
848            return
849        for jamb in result:
850            jamb['Error'] = "Processing "
851            logger.info(format % jamb)
852            jamb_reg_no = jamb.get(csv_d['jamb_reg_no'])
853            res = self.portal_catalog({'portal_type': "StudentApplication",
854                                     'SearchableText': jamb_reg_no })
855            if not res:
856                em = 'Student with jamb_reg_no %s does not exists\n' % jamb_reg_no
857                logger.info(em)
858                jamb['Error'] = "Student does not exist"
859                no_import.append(format % jamb)
860                continue
861            sid = res[0].getPath().split('/')[-2]
862            cert_id = makeCertificateCode(jamb.get(csv_d['course_code']))
863            res = self.portal_catalog(portal_type = "Certificate", id = cert_id)
864            if not res:
865                em = 'No Certificate with ID %s \n' % cert_id
866                logger.info(em)
867                jamb['Error'] = "No Certificate %s" % cert_id
868                no_import.append( format % jamb)
869                continue
870            cert_brain = res[0]
871            catalog_entry = {}
872            student = getattr(self,sid)
873            #
874            # Study Course
875            #
876            study_course = student.study_course
877            dsc = {}
878            cert_pl = cert_brain.getPath().split('/')
879            catalog_entry['id'] = sid
880            catalog_entry['faculty'] = cert_pl[-4]
881            catalog_entry['department'] = cert_pl[-3]
882            catalog_entry['course'] = cert_id
883            dsc['study_course'] = cert_id
884            study_course.getContent().edit(mapping=dsc)
885            self.students_catalog.modifyRecord(**catalog_entry)
886            if tr_count > 10:
887                if len(no_import) > 1:
888                    open("%s/import/%s_not_imported.csv" % (i_home,name),"w+").write(
889                             '\n'.join(no_import))
890                    no_import = []
891                em = '%d transactions commited\n' % tr_count
892                transaction.commit()
893                logger.info(em)
894                total += tr_count
895                tr_count = 0
896            tr_count += 1
897        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
898    ###)
899
900    security.declareProtected(View,"fixOwnership") ###(
901    def fixOwnership(self):
902        """fix Ownership"""
903        for s in self.portal_catalog(meta_type = 'Student'):
904            student = s.getObject()
905            sid = s.getId
906            import pdb;pdb.set_trace()
907            student.application.manage_setLocalRoles(sid, ['Owner',])
908            student.personal.manage_setLocalRoles(sid, ['Owner',])
909    ###)
910
911    security.declareProtected(View,"Title") ###(
912    def Title(self):
913        """compose title"""
914        return "Student Section"
915    ###)
916
917    def generateStudentId(self,letter,students = None): ###(
918        import random
919        r = random
920        if students is None:
921            students = self.portal_url.getPortalObject().campus.students
922        if letter not in ('ABCDEFGIHKLMNOPQRSTUVWXY'):
923            letter= r.choice('ABCDEFGHKLMNPQRSTUVWXY')
924        sid = "%c%d" % (letter,r.randint(99999,1000000))
925        while hasattr(students, sid):
926            sid = "%c%d" % (letter,r.randint(99999,1000000))
927        return sid
928        #return "%c%d" % (r.choice('ABCDEFGHKLMNPQRSTUVWXY'),r.randint(99999,1000000))
929    ###)
930
931InitializeClass(StudentsFolder)
932
933def addStudentsFolder(container, id, REQUEST=None, **kw): ###(
934    """Add a Student."""
935    ob = StudentsFolder(id, **kw)
936    return CPSBase_adder(container, ob, REQUEST=REQUEST)
937    ###)
938
939###)
940
941class Student(CPSDocument): ###(
942    """
943    WAeUP Student container for the various student data
944    """
945    meta_type = 'Student'
946    portal_type = meta_type
947    security = ClassSecurityInfo()
948
949    security.declareProtected(View,"Title")
950    def Title(self):
951        """compose title"""
952        reg_nr = self.getId()[1:]
953        data = getattr(self,'personal',None)
954        if data:
955            content = data.getContent()
956            return "%s %s %s" % (content.firstname,content.middlename,content.lastname)
957        data = getattr(self,'application',None)
958        if data:
959            content = data.getContent()
960            return "%s" % (content.jamb_lastname)
961        return self.title
962
963    security.declarePrivate('makeStudentMember') ###(
964    def makeStudentMember(self,sid,password='uNsEt'):
965        """make the student a member"""
966        membership = self.portal_membership
967        membership.addMember(sid,
968                             password ,
969                             roles=('Member',
970                                     'Student',
971                                     ),
972                             domains='',
973                             properties = {'memberareaCreationFlag': False,
974                                           'homeless': True},)
975        member = membership.getMemberById(sid)
976        self.portal_registration.afterAdd(member, sid, password, None)
977        self.manage_setLocalRoles(sid, ['Owner',])
978
979###)
980
981    security.declareProtected(View,'createSubObjects') ###(
982    def createSubObjects(self):
983        """make the student a member"""
984        dp = {'Title': 'Personal Data'}
985        app_doc = self.application.getContent()
986        names = app_doc.jamb_lastname.split()
987        if len(names) == 3:
988            dp['firstname'] = names[0].capitalize()
989            dp['middlename'] = names[1].capitalize()
990            dp['lastname'] = names[2].capitalize()
991        elif len(names) == 2:
992            dp['firstname'] = names[0].capitalize()
993            dp['lastname'] = names[1].capitalize()
994        else:
995            dp['lastname'] = app_doc.jamb_lastname
996        dp['sex'] = app_doc.jamb_sex == 'F'
997        dp['lga'] = "%s/%s" % (app_doc.jamb_state,app_doc.jamb_lga )
998        proxy = self.aq_parent
999        proxy.invokeFactory('StudentPersonal','personal')
1000        per = proxy.personal
1001        per_doc = per.getContent()
1002        per_doc.edit(mapping = dp)
1003        per.manage_setLocalRoles(proxy.getId(), ['Owner',])
1004        #self.portal_workflow.doActionFor(per,'open',dest_container=per)
1005
1006###)
1007
1008InitializeClass(Student)
1009
1010def addStudent(container, id, REQUEST=None, **kw):
1011    """Add a Student."""
1012    ob = Student(id, **kw)
1013    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1014
1015###)
1016
1017class StudentAccommodation(CPSDocument): ###(
1018    """
1019    WAeUP Student container for the various student data
1020    """
1021    meta_type = 'StudentAccommodation'
1022    portal_type = meta_type
1023    security = ClassSecurityInfo()
1024
1025    security.declareProtected(View,"Title")
1026    def Title(self):
1027        """compose title"""
1028        content = self.getContent()
1029        #return "Accommodation Data for %s %s" % (content.firstname,content.lastname)
1030        return "Accommodation Data for Session %s" % content.session
1031
1032
1033InitializeClass(StudentAccommodation)
1034
1035def addStudentAccommodation(container, id, REQUEST=None, **kw):
1036    """Add a Students personal data."""
1037    ob = StudentAccommodation(id, **kw)
1038    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1039
1040###)
1041
1042class StudentPersonal(CPSDocument): ###(
1043    """
1044    WAeUP Student container for the various student data
1045    """
1046    meta_type = 'StudentPersonal'
1047    portal_type = meta_type
1048    security = ClassSecurityInfo()
1049
1050    security.declareProtected(View,"Title")
1051    def Title(self):
1052        """compose title"""
1053        content = self.getContent()
1054        #return "Personal Data for %s %s" % (content.firstname,content.lastname)
1055        return "Personal Data"
1056
1057
1058InitializeClass(StudentPersonal)
1059
1060def addStudentPersonal(container, id, REQUEST=None, **kw):
1061    """Add a Students personal data."""
1062    ob = StudentPersonal(id, **kw)
1063    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1064
1065###)
1066
1067class StudentClearance(CPSDocument): ###(
1068    """
1069    WAeUP Student container for the various student data
1070    """
1071    meta_type = 'StudentClearance'
1072    portal_type = meta_type
1073    security = ClassSecurityInfo()
1074
1075    security.declareProtected(View,"Title")
1076    def Title(self):
1077        """compose title"""
1078        content = self.getContent()
1079        #return "Clearance/Eligibility Record for %s %s" % (content.firstname,content.lastname)
1080        return "Clearance/Eligibility Record"
1081
1082
1083InitializeClass(StudentClearance)
1084
1085def addStudentClearance(container, id, REQUEST=None, **kw):
1086    """Add a Students personal data."""
1087    ob = StudentClearance(id, **kw)
1088    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1089
1090###)
1091
1092class StudentStudyLevel(CPSDocument): ###(
1093    """
1094    WAeUP Student container for the various student data
1095    """
1096    meta_type = 'StudentStudyLevel'
1097    portal_type = meta_type
1098    security = ClassSecurityInfo()
1099
1100    security.declareProtected(View,"Title")
1101    def Title(self):
1102        """compose title"""
1103        return "Level %s" % self.aq_parent.getId()
1104
1105    def create_course_results(self,cert_id,current_level): ###(
1106        "create all courses in a level"
1107        aq_portal = self.portal_catalog.evalAdvancedQuery
1108        res = self.portal_catalog(portal_type="Certificate", id = cert_id)
1109        l = []
1110        import transaction
1111        if res:
1112            cert = res[0]
1113            path = cert.getPath()
1114            query = Eq("path","%s/%s" % (path,current_level)) &\
1115                    Eq('portal_type','CertificateCourse')
1116            courses = aq_portal(query)
1117            #from pdb import set_trace;set_trace()
1118            self_proxy = self.aq_parent
1119            for c in courses:
1120                d = self.getCourseInfo(c.getId)
1121                cr_id = self_proxy.invokeFactory('StudentCourseResult',c.getId)
1122                course_result = getattr(self_proxy,cr_id)
1123                self.portal_workflow.doActionFor(course_result,'open')
1124                d['core_or_elective'] = getattr(c.getObject().getContent(),'core_or_elective')
1125                course_result.getContent().edit(mapping=d)
1126                transaction.commit()
1127    ###)
1128
1129InitializeClass(StudentStudyLevel)
1130
1131def addStudentStudyLevel(container, id, REQUEST=None, **kw):
1132    """Add a Students personal data."""
1133    ob = StudentStudyLevel(id, **kw)
1134    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1135
1136###)
1137
1138class StudentStudyCourse(CPSDocument): ###(
1139    """
1140    WAeUP Student container for the various student data
1141    """
1142    meta_type = 'StudentStudyCourse'
1143    portal_type = meta_type
1144    security = ClassSecurityInfo()
1145
1146    security.declareProtected(View,"Title")
1147    def Title(self):
1148        """compose title"""
1149        content = self.getContent()
1150        return "Study Course"
1151
1152
1153InitializeClass(StudentStudyCourse)
1154
1155def addStudentStudyCourse(container, id, REQUEST=None, **kw):
1156    """Add a Students personal data."""
1157    ob = StudentStudyCourse(id, **kw)
1158    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1159
1160###)
1161
1162class StudentApplication(CPSDocument): ###(
1163    """
1164    WAeUP Student container for the various student data
1165    """
1166    meta_type = 'StudentApplication'
1167    portal_type = meta_type
1168    security = ClassSecurityInfo()
1169
1170    security.declareProtected(View,"Title")
1171    def Title(self):
1172        """compose title"""
1173        return "Application Data"
1174
1175
1176InitializeClass(StudentApplication)
1177
1178def addStudentApplication(container, id, REQUEST=None, **kw):
1179    """Add a Students eligibility data."""
1180    ob = StudentApplication(id, **kw)
1181    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1182###)
1183
1184class StudentPume(CPSDocument): ###(
1185    """
1186    WAeUP Student container for the various student data
1187    """
1188    meta_type = 'StudentPume'
1189    portal_type = meta_type
1190    security = ClassSecurityInfo()
1191
1192    security.declareProtected(View,"Title")
1193    def Title(self):
1194        """compose title"""
1195        return "PUME Results"
1196
1197
1198InitializeClass(StudentPume)
1199
1200def addStudentPume(container, id, REQUEST=None, **kw):
1201    """Add a Students PUME data."""
1202    ob = StudentPume(id, **kw)
1203    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1204###)
1205
1206##class StudentSemester(CPSDocument): ###(
1207##    """
1208##    WAeUP StudentSemester containing the courses and students
1209##    """
1210##    meta_type = 'StudentSemester'
1211##    portal_type = meta_type
1212##    security = ClassSecurityInfo()
1213##
1214##InitializeClass(StudentSemester)
1215##
1216##def addStudentSemester(container, id, REQUEST=None, **kw):
1217##    """Add a StudentSemester."""
1218##    ob = StudentSemester(id, **kw)
1219##    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1220##
1221#####)
1222
1223##class Semester(CPSDocument): ###(
1224##    """
1225##    WAeUP Semester containing the courses and students
1226##    """
1227##    meta_type = 'Semester'
1228##    portal_type = meta_type
1229##    security = ClassSecurityInfo()
1230##
1231##InitializeClass(Semester)
1232##
1233##def addSemester(container, id, REQUEST=None, **kw):
1234##    """Add a Semester."""
1235##    ob = Semester(id, **kw)
1236##    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1237##
1238#####)
1239
1240class StudentCourseResult(CPSDocument): ###(
1241    """
1242    WAeUP StudentCourseResult
1243    """
1244    meta_type = 'StudentCourseResult'
1245    portal_type = meta_type
1246    security = ClassSecurityInfo()
1247
1248    def getCourseEntry(self,cid):
1249        res = self.portal_catalog({'meta_type': "Course",
1250                                           'id': cid})
1251        if res:
1252            return res[-1]
1253        else:
1254            return None
1255
1256    security.declareProtected(View,"Title")
1257    def Title(self):
1258        """compose title"""
1259        cid = self.aq_parent.getId()
1260        ce = self.getCourseEntry(cid)
1261        if ce:
1262            return "%s" % ce.Title
1263        return "No course with id %s" % cid
1264
1265InitializeClass(StudentCourseResult)
1266
1267def addStudentCourseResult(container, id, REQUEST=None, **kw):
1268    """Add a StudentCourseResult."""
1269    ob = StudentCourseResult(id, **kw)
1270    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1271###)
1272
1273# Backward Compatibility StudyLevel
1274
1275from Products.WAeUP_SRP.Academics import StudyLevel
1276
1277from Products.WAeUP_SRP.Academics import addStudyLevel
1278
Note: See TracBrowser for help on using the repository browser.