source: WAeUP_SRP/trunk/Students.py @ 1963

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

fixed

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