source: WAeUP_SRP/trunk/Students.py @ 2015

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

see ticket #276 comment 07/13/07 14:29:19: Modified by med

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