source: WAeUP_SRP/trunk/Students.py @ 1791

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