source: WAeUP_SRP/branches/joachim-azax-branch/Students.py @ 17487

Last change on this file since 17487 was 1997, checked in by joachim, 17 years ago

starting

  • Property svn:keywords set to Id
File size: 67.7 KB
RevLine 
[57]1#-*- mode: python; mode: fold -*-
[200]2# $Id: Students.py 1997 2007-07-08 09:16:21Z joachim $
[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
[1997]19from Products.azax import AzaxBaseView
[1820]20import DateTime
[362]21import logging
[971]22import csv,re,os
[362]23import Globals
24p_home = Globals.package_home(globals())
25i_home = Globals.INSTANCE_HOME
[981]26MAX_TRANS = 1000
[1599]27from urllib import urlencode
28
[966]29import DateTime
[1801]30#import PIL.Image
[971]31from StringIO import StringIO
[154]32
[958]33def makeCertificateCode(code): ###(
34    code = code.replace('.','')
35    code = code.replace('(','')
36    code = code.replace(')','')
37    code = code.replace('/','')
38    code = code.replace(' ','')
39    code = code.replace('_','')
40    return code
41
42###)
43
[1939]44def response_write(response,s): ###(
[1599]45    response.setHeader('Content-type','text/html; charset=ISO-8859-15')
46    while s.find('<') > -1:
47        s = s.replace('<','&lt;')
48    while s.find('>') > -1:
49        #from pdb import set_trace;set_trace()
50        s = s.replace('>','&gt;')
51    response.write("%s<br>\n" % s)
52
[1939]53###)
54
[958]55def getInt(s): ###(
[723]56    try:
57        return int(s)
58    except:
59        return 0
[422]60
[725]61def getFloat(s):
62    try:
63        return float(s)
64    except:
65        return 0.0
66
[958]67###)
68
[714]69def getStudentByRegNo(self,reg_no): ###(
[502]70    """search student by JAMB Reg No and return StudentFolder"""
[1969]71    res = self.students_catalog(jamb_reg_no = reg_no.upper())
[1902]72    if len(res) == 1:
73        return getattr(self.portal_url.getPortalObject().campus.students,res[0].id)
74    else:
[502]75        return None
[1902]76    # don't search in portal_catalog
77    # search = ZCatalog.searchResults(self.portal_catalog_real,{'meta_type': 'StudentApplication',
78    #                               'SearchableText': reg_no,
79    #                               })
80    # if len(search) < 1:
81    #     return None
82    # return search[0].getObject().aq_parent
[502]83
[714]84###)
85
[1939]86def checkJambNo(jnr): ###(
[1111]87    try:
88        if len(jnr) != 10:
89            return False
90    except:
91        return False
92    try:
93        int(jnr[:8])
94        return True
95    except:
96        return False
[1119]97
[1939]98###)
99
100def formatLGA(lga):
101    if lga.find('_') > -1:
102        return "%s / %s" % (lga.split('_')[0].upper(),lga.split('_')[1].upper())
103    return lga
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",
914                                         "review_state",
915                                         "sex",
916                                         "email",
917                                         "faculty",
918                                         "department",
919                                         "course",
920                                         "level",
921                                        ),
922                    'personal': ('firstname',
923                                 'middlename',
924                                 'lastname',
925                                 'perm_address',
926                                ),
927                    'clearance': ('state',
928                                  'lga',
929                                 )
930                  }
931        res_list = []
932        lines = []
933        fields = []
934        with_lga = False
935        for k in toexport.keys():
936            for f in toexport[k]:
937                if f == 'lga' :
938                    with_lga = True
939                fields.append(f)
[1940]940        headline = ','.join(fields).replace('level','current_level')
[1939]941        open(export_file,"a").write(headline +'\n')
942        format = '"%(' + ')s","%('.join(fields) + ')s"'
943        query = In('review_state',('cleared_and_validated',
944                                'school_fee_paid',
945                                'courses_registered',
946                                'courses_validated'))
947        students = aq_students(query)
[1941]948        nr2export = len(students)
949        logger.info('%s starts exportStudents, %s student records to export' % (member,nr2export))
950        chunk = 2000
[1939]951        total = 0
[1941]952        start = DateTime.DateTime().timeTime()
953        start_chunk = DateTime.DateTime().timeTime()
954        ## alternative method slightly slower
955        # student_recs = {}
956        # for s in students:
957        #      student_recs[s.id] = s
958        # catalog_recs = {}
959        # brains = self.portal_catalog(portal_type = 'Student')
960        # for cat_rec in brains:
961        #     sid = cat_rec.getId
962        #     catalog_recs[sid] = cat_rec
963        # #import pdb;pdb.set_trace()
964        # start = DateTime.DateTime().timeTime()
965        # start_chunk = DateTime.DateTime().timeTime()
966        # for student in students:
967        #     if student.id not in student_recs.keys():
968        #         continue
969        #     not_all = False
970        #     d = self.getFormattedStudentEntry(student_recs[student.id])
971        #     student_obj = catalog_recs[student.id].getObject()
[1939]972        for student in students:
973            not_all = False
974            d = self.getFormattedStudentEntry(student)
[1941]975            student_obj = getattr(students_folder,student.id)
[1939]976            for k in toexport.keys()[1:]:
977                try:
[1941]978                    object = getattr(student_obj,k)
[1939]979                    object_doc = object.getContent()
980                except:
981                    logger.info('%s %s record not found' % (student.id,k))
982                    not_all = True
983                    continue
984                for f in toexport[k]:
985                    d[f] = getattr(object_doc,f,'')
986            if not_all:
987                continue
988            if with_lga:
989                d['lga'] = formatLGA(d['lga'])
990            lines.append(format % d)
991            total += 1
992            if total and not total % chunk or total == len(students):
993                open(export_file,"a").write('\n'.join(lines) +'\n')
994                anz = len(lines)
[1941]995                logger.info("wrote %(anz)d  total written %(total)d" % vars())
996                end_chunk = DateTime.DateTime().timeTime()
997                duration = end_chunk-start_chunk
998                per_record = duration/anz
999                till_now = end_chunk - start
1000                avarage_per_record = till_now/total
1001                estimated_end = DateTime.DateTime(start + avarage_per_record * nr2export)
1002                estimated_end = estimated_end.strftime("%H:%M:%S")
1003                logger.info('%(duration)4.1f, %(per_record)4.3f,end %(estimated_end)s' % vars())
1004                start_chunk = DateTime.DateTime().timeTime()
[1939]1005                lines = []
[1941]1006        end = DateTime.DateTime().timeTime()
1007        logger.info('total time %6.2f m' % ((end-start)/60))
[1939]1008        filename, extension = os.path.splitext(export_file)
[1941]1009        from subprocess import call
1010        msg = "wrote %(total)d records to %(export_file)s" % vars()
1011        try:
1012            retcode = call('gzip %s' % (export_file),shell=True)
1013            if retcode == 0:
1014                msg = "wrote %(total)d records to %(export_file)s.gz" % vars()
1015        except OSError, e:
1016            retcode = -99
1017            logger.info("zip failed with %s" % e)
[1939]1018        logger.info(msg)
1019        args = {'portal_status_message': msg}
[1953]1020        #url = self.REQUEST.get('URL1') + '?' + urlencode(args)
[1941]1021        url = self.REQUEST.get('URL2')
[1939]1022        return self.REQUEST.RESPONSE.redirect(url)
[1940]1023    ###)
[1939]1024
[1970]1025    security.declareProtected(ModifyPortalContent,"dumpStudentsCatalog")###(
1026    def dumpStudentsCatalog(self):
1027        """dump all data in students_catalog to a csv"""
1028        member = self.portal_membership.getAuthenticatedMember()
1029        logger = logging.getLogger('Students.dumpStudentsCatalog')
1030        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
1031        export_file = "%s/export/students_catalog_%s.csv" % (i_home,current)
1032        res_list = []
1033        lines = []
1034        fields = []
1035        for f in self.students_catalog.schema():
1036            fields.append(f)
1037        headline = ','.join(fields)
1038        open(export_file,"a").write(headline +'\n')
1039        format = '"%(' + ')s","%('.join(fields) + ')s"'
1040        students = self.students_catalog()
1041        nr2export = len(students)
1042        logger.info('%s starts exportStudents, %s student records to export' % (member,nr2export))
1043        chunk = 2000
1044        total = 0
1045        start = DateTime.DateTime().timeTime()
1046        start_chunk = DateTime.DateTime().timeTime()
1047        for student in students:
1048            not_all = False
1049            d = self.getFormattedStudentEntry(student)
1050            lines.append(format % d)
1051            total += 1
1052            if total and not total % chunk or total == len(students):
1053                open(export_file,"a").write('\n'.join(lines) +'\n')
1054                anz = len(lines)
1055                logger.info("wrote %(anz)d  total written %(total)d" % vars())
1056                end_chunk = DateTime.DateTime().timeTime()
1057                duration = end_chunk-start_chunk
1058                per_record = duration/anz
1059                till_now = end_chunk - start
1060                avarage_per_record = till_now/total
1061                estimated_end = DateTime.DateTime(start + avarage_per_record * nr2export)
1062                estimated_end = estimated_end.strftime("%H:%M:%S")
1063                logger.info('%(duration)4.1f, %(per_record)4.3f,end %(estimated_end)s' % vars())
1064                start_chunk = DateTime.DateTime().timeTime()
1065                lines = []
1066        end = DateTime.DateTime().timeTime()
1067        logger.info('total time %6.2f m' % ((end-start)/60))
1068        filename, extension = os.path.splitext(export_file)
1069        from subprocess import call
1070        msg = "wrote %(total)d records to %(export_file)s" % vars()
1071        try:
1072            retcode = call('gzip %s' % (export_file),shell=True)
1073            if retcode == 0:
1074                msg = "wrote %(total)d records to %(export_file)s.gz" % vars()
1075        except OSError, e:
1076            retcode = -99
1077            logger.info("zip failed with %s" % e)
1078        logger.info(msg)
1079        args = {'portal_status_message': msg}
1080        #url = self.REQUEST.get('URL1') + '?' + urlencode(args)
1081        url = self.REQUEST.get('URL2')
1082        return self.REQUEST.RESPONSE.redirect(url)
1083    ###)
1084
1085
[1146]1086    security.declareProtected(ModifyPortalContent,"importResults")###(
1087    def importResults(self):
[1151]1088        """load Returning Students Results from CSV"""
[1146]1089        import transaction
1090        import random
1091        #from pdb import set_trace
1092        wftool = self.portal_workflow
1093        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
[1802]1094        #students_folder = self.portal_catalog({'meta_type': 'StudentsFolder'})[-1].getObject()
1095        students_folder = self.portal_url.getPortalObject().campus.students
[1146]1096        tr_count = 1
1097        total = 0
1098        #name = 'pume_results'
1099        name = 'Results'
1100        table = self.results_import
1101        no_import = []
1102        imported = []
[1571]1103        logger = logging.getLogger('Students.StudentsFolder.importResults')
[1146]1104        try:
1105            results = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
1106        except:
1107            logger.error('Error reading %s.csv' % name)
1108            return
1109        l = self.portal_catalog({'meta_type': "Course"})
1110        courses = [f.getId for f in l]
1111        start = True
1112        res = table()
1113        regs = []
1114        if len(res) > 0:
1115            regs = [s.key for s in res]
1116        no_course = []
1117        no_course_list = []
1118        course_count = 0
1119        for result in results:
1120            if start:
1121                start = False
[1571]1122                logger.info('Start loading from %s.csv' % name)
[1321]1123                s = ','.join(['"%s"' % fn for fn in result.keys()])
[1146]1124                imported.append(s)
1125                no_import.append('%s,"Error"' % s)
1126                format = ','.join(['"%%(%s)s"' % fn for fn in result.keys()])
1127                format_error = format + ',"%(Error)s"'
1128                no_certificate = "no certificate %s" % format
1129            course_id = result.get('CosCode')
[1448]1130            if not course_id:
1131                course_id = 'N/A'
1132                result['CosCode'] = course_id
[1168]1133            matric_no = result.get('matric_no').upper()
1134            result['matric_no'] = matric_no
1135            key = matric_no+course_id
1136            if matric_no == '':
[1252]1137                result['Error'] = "Empty matric_no"
[1146]1138                no_import.append( format_error % result)
1139                continue
[1168]1140            if key in regs or self.results_import(key = key):
[1252]1141                result['Error'] = "Duplicate"
[1146]1142                no_import.append( format_error % result)
1143                continue
1144            if course_id not in courses:
1145                if course_id not in no_course:
1146                    course_count +=1
1147                    no_course.append(course_id)
1148                    no_course_list.append('"%s"' % course_id)
1149                    #result['Error'] = "No Course"
1150                    #logger.info(format_error % result)
[1829]1151
[1816]1152            result['key'] = key
1153            try:
1154                table.addRecord(**result)
1155            except ValueError:
1156                #import pdb;pdb.set_trace()
1157                result['Error'] = "Duplicate"
1158                no_import.append( format_error % result)
1159                continue
[1829]1160
[1146]1161            regs.append(key)
1162            imported.append(format % result)
1163            tr_count += 1
1164            if tr_count > 1000:
1165                if len(no_import) > 0:
1166                    open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
[1151]1167                             '\n'.join(no_import)+'\n')
[1146]1168                    no_import = []
1169                open("%s/import/%simported%s.csv" % (i_home,name,current),"a").write(
[1151]1170                                            '\n'.join(imported) + '\n')
[1146]1171                imported = []
1172                if no_course_list:
1173                    open("%s/import/%sno_courses%s.csv" % (i_home,name,current),"a").write(
[1151]1174                                            '\n'.join(no_course_list) + '\n')
[1146]1175                    no_course_list = []
1176                em = '%d transactions commited total %s\n courses not found %s' % (tr_count,total,course_count)
1177                transaction.commit()
1178                logger.info(em)
[1168]1179                regs = []
[1146]1180                total += tr_count
1181                tr_count = 0
1182        open("%s/import/%simported%s.csv" % (i_home,name,current),"a").write(
1183                                            '\n'.join(imported))
1184        open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
1185                                                '\n'.join(no_import))
1186        if no_course_list:
1187            open("%s/import/%sno_courses%s.csv" % (i_home,name,current),"a").write(
1188                                    '\n'.join(no_course_list))
[1393]1189        em = '%d transactions commited total %s\n courses not found %s' % (tr_count,total,course_count)
1190        logger.info(em)
[1146]1191        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
1192    ###)
1193
[1065]1194    security.declareProtected(ModifyPortalContent,"updateStudyCourse")###(
1195    def updateStudyCourse(self):
1196        """update StudyCourse from CSV values"""
1197        import transaction
1198        import random
1199        from pdb import set_trace
1200        wftool = self.portal_workflow
[1802]1201        #students_folder = self.portal_catalog({'meta_type': 'StudentsFolder'})[-1].getObject()
1202        students_folder = self.portal_url.getPortalObject().campus.students
[1065]1203        csv_d = {'jamb_reg_no': "RegNumber",
1204                 'jamb_lastname': "Name",
1205                 'session': "Session",
1206                 'pume_tot_score': "PUME SCORE",
1207                 'jamb_score': "JambScore",
1208                 'jamb_sex': "Sex",
1209                 'jamb_state': "State",
1210##                 'jamb_first_cos': "AdminCourse",
1211                 'faculty': "AdminFaculty",
1212                 'course_code': "AdmitCoscode",
1213                 'stud_status':"AdmitStatus",
1214                 'department': "AdmitDept",
1215                 'jamb_lga': "LGA",
1216                 'app_email': "email",
1217                 'app_mobile': "PhoneNumbers",
1218                 }
1219        csv_fields = [f[1] for f in csv_d.items()]
1220        tr_count = 0
1221        total = 0
1222        #name = 'pume_results'
1223        name = 'StudyCourseChange'
1224        no_import = []
[1321]1225        s = ','.join(['"%s"' % fn for fn in csv_fields])
[1065]1226        no_import.append('"Error",%s' % s)
1227        format = '"%(Error)s",' + ','.join(['"%%(%s)s"' % fn for fn in csv_fields])
1228        no_certificate = "no certificate %s" % format
1229        open("%s/import/%s_not_imported.csv" % (i_home,name),"w").write(
1230                    '\n'.join(no_import))
[1571]1231        logger = logging.getLogger('Students.StudentsFolder.updateStudyCourse')
[1065]1232        logger.info('Start loading from %s.csv' % name)
1233        l = self.portal_catalog({'meta_type': "Certificate"})
1234        try:
1235            result = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
1236        except:
1237            logger.error('Error reading %s.csv' % name)
1238            return
1239        for jamb in result:
1240            jamb['Error'] = "Processing "
1241            logger.info(format % jamb)
1242            jamb_reg_no = jamb.get(csv_d['jamb_reg_no'])
1243            res = self.portal_catalog({'portal_type': "StudentApplication",
1244                                     'SearchableText': jamb_reg_no })
1245            if not res:
[1571]1246                em = 'Student with jamb_reg_no %s does not exists\n' % jamb_reg_no
[1065]1247                logger.info(em)
[1571]1248                jamb['Error'] = "Student does not exist"
[1065]1249                no_import.append(format % jamb)
1250                continue
1251            sid = res[0].getPath().split('/')[-2]
1252            cert_id = makeCertificateCode(jamb.get(csv_d['course_code']))
1253            res = self.portal_catalog(portal_type = "Certificate", id = cert_id)
1254            if not res:
1255                em = 'No Certificate with ID %s \n' % cert_id
1256                logger.info(em)
1257                jamb['Error'] = "No Certificate %s" % cert_id
1258                no_import.append( format % jamb)
1259                continue
1260            cert_brain = res[0]
1261            catalog_entry = {}
1262            student = getattr(self,sid)
1263            #
1264            # Study Course
1265            #
1266            study_course = student.study_course
1267            dsc = {}
1268            cert_pl = cert_brain.getPath().split('/')
1269            catalog_entry['id'] = sid
1270            catalog_entry['faculty'] = cert_pl[-4]
1271            catalog_entry['department'] = cert_pl[-3]
1272            catalog_entry['course'] = cert_id
1273            dsc['study_course'] = cert_id
1274            study_course.getContent().edit(mapping=dsc)
1275            self.students_catalog.modifyRecord(**catalog_entry)
1276            if tr_count > 10:
1277                if len(no_import) > 1:
1278                    open("%s/import/%s_not_imported.csv" % (i_home,name),"w+").write(
1279                             '\n'.join(no_import))
1280                    no_import = []
1281                em = '%d transactions commited\n' % tr_count
1282                transaction.commit()
1283                logger.info(em)
1284                total += tr_count
1285                tr_count = 0
1286            tr_count += 1
1287        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
1288    ###)
1289
[1594]1290    security.declareProtected(View,"fixOwnership") ###(
[511]1291    def fixOwnership(self):
1292        """fix Ownership"""
1293        for s in self.portal_catalog(meta_type = 'Student'):
1294            student = s.getObject()
1295            sid = s.getId
1296            import pdb;pdb.set_trace()
1297            student.application.manage_setLocalRoles(sid, ['Owner',])
1298            student.personal.manage_setLocalRoles(sid, ['Owner',])
[1594]1299    ###)
[603]1300
[1594]1301    security.declareProtected(View,"Title") ###(
[364]1302    def Title(self):
1303        """compose title"""
[382]1304        return "Student Section"
[1594]1305    ###)
[361]1306
[1700]1307    def generateStudentId(self,letter,students = None): ###(
[714]1308        import random
1309        r = random
[1700]1310        if students is None:
1311            students = self.portal_url.getPortalObject().campus.students
[714]1312        if letter not in ('ABCDEFGIHKLMNOPQRSTUVWXY'):
1313            letter= r.choice('ABCDEFGHKLMNPQRSTUVWXY')
1314        sid = "%c%d" % (letter,r.randint(99999,1000000))
1315        while hasattr(students, sid):
1316            sid = "%c%d" % (letter,r.randint(99999,1000000))
[758]1317        return sid
[714]1318        #return "%c%d" % (r.choice('ABCDEFGHKLMNPQRSTUVWXY'),r.randint(99999,1000000))
1319    ###)
1320
[361]1321InitializeClass(StudentsFolder)
1322
[1594]1323def addStudentsFolder(container, id, REQUEST=None, **kw): ###(
[361]1324    """Add a Student."""
1325    ob = StudentsFolder(id, **kw)
1326    return CPSBase_adder(container, ob, REQUEST=REQUEST)
[1594]1327    ###)
1328
[361]1329###)
1330
[57]1331class Student(CPSDocument): ###(
1332    """
[154]1333    WAeUP Student container for the various student data
[57]1334    """
1335    meta_type = 'Student'
1336    portal_type = meta_type
1337    security = ClassSecurityInfo()
[154]1338
[152]1339    security.declareProtected(View,"Title")
1340    def Title(self):
1341        """compose title"""
[153]1342        reg_nr = self.getId()[1:]
[362]1343        data = getattr(self,'personal',None)
[152]1344        if data:
1345            content = data.getContent()
[1143]1346            return "%s %s %s" % (content.firstname,content.middlename,content.lastname)
[472]1347        data = getattr(self,'application',None)
[464]1348        if data:
1349            content = data.getContent()
1350            return "%s" % (content.jamb_lastname)
[152]1351        return self.title
[154]1352
[511]1353    security.declarePrivate('makeStudentMember') ###(
1354    def makeStudentMember(self,sid,password='uNsEt'):
1355        """make the student a member"""
1356        membership = self.portal_membership
[603]1357        membership.addMember(sid,
[511]1358                             password ,
1359                             roles=('Member',
1360                                     'Student',
[522]1361                                     ),
[511]1362                             domains='',
[904]1363                             properties = {'memberareaCreationFlag': False,
1364                                           'homeless': True},)
[511]1365        member = membership.getMemberById(sid)
1366        self.portal_registration.afterAdd(member, sid, password, None)
1367        self.manage_setLocalRoles(sid, ['Owner',])
1368
1369###)
1370
[764]1371    security.declareProtected(View,'createSubObjects') ###(
1372    def createSubObjects(self):
1373        """make the student a member"""
1374        dp = {'Title': 'Personal Data'}
1375        app_doc = self.application.getContent()
1376        names = app_doc.jamb_lastname.split()
1377        if len(names) == 3:
1378            dp['firstname'] = names[0].capitalize()
1379            dp['middlename'] = names[1].capitalize()
1380            dp['lastname'] = names[2].capitalize()
1381        elif len(names) == 2:
1382            dp['firstname'] = names[0].capitalize()
1383            dp['lastname'] = names[1].capitalize()
1384        else:
1385            dp['lastname'] = app_doc.jamb_lastname
1386        dp['sex'] = app_doc.jamb_sex == 'F'
1387        dp['lga'] = "%s/%s" % (app_doc.jamb_state,app_doc.jamb_lga )
1388        proxy = self.aq_parent
1389        proxy.invokeFactory('StudentPersonal','personal')
1390        per = proxy.personal
1391        per_doc = per.getContent()
1392        per_doc.edit(mapping = dp)
[927]1393        per.manage_setLocalRoles(proxy.getId(), ['Owner',])
[764]1394        #self.portal_workflow.doActionFor(per,'open',dest_container=per)
[603]1395
[511]1396###)
1397
[57]1398InitializeClass(Student)
1399
1400def addStudent(container, id, REQUEST=None, **kw):
1401    """Add a Student."""
1402    ob = Student(id, **kw)
1403    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1404
1405###)
[91]1406
[639]1407class StudentAccommodation(CPSDocument): ###(
1408    """
1409    WAeUP Student container for the various student data
1410    """
1411    meta_type = 'StudentAccommodation'
1412    portal_type = meta_type
1413    security = ClassSecurityInfo()
1414
1415    security.declareProtected(View,"Title")
1416    def Title(self):
1417        """compose title"""
1418        content = self.getContent()
1419        #return "Accommodation Data for %s %s" % (content.firstname,content.lastname)
1420        return "Accommodation Data for Session %s" % content.session
1421
1422
1423InitializeClass(StudentAccommodation)
1424
1425def addStudentAccommodation(container, id, REQUEST=None, **kw):
1426    """Add a Students personal data."""
1427    ob = StudentAccommodation(id, **kw)
1428    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1429
1430###)
1431
[89]1432class StudentPersonal(CPSDocument): ###(
1433    """
[154]1434    WAeUP Student container for the various student data
[89]1435    """
1436    meta_type = 'StudentPersonal'
1437    portal_type = meta_type
1438    security = ClassSecurityInfo()
[152]1439
1440    security.declareProtected(View,"Title")
1441    def Title(self):
1442        """compose title"""
1443        content = self.getContent()
[364]1444        #return "Personal Data for %s %s" % (content.firstname,content.lastname)
1445        return "Personal Data"
[152]1446
[154]1447
[89]1448InitializeClass(StudentPersonal)
1449
1450def addStudentPersonal(container, id, REQUEST=None, **kw):
1451    """Add a Students personal data."""
1452    ob = StudentPersonal(id, **kw)
1453    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1454
1455###)
1456
[423]1457class StudentClearance(CPSDocument): ###(
1458    """
1459    WAeUP Student container for the various student data
1460    """
1461    meta_type = 'StudentClearance'
1462    portal_type = meta_type
1463    security = ClassSecurityInfo()
1464
1465    security.declareProtected(View,"Title")
1466    def Title(self):
1467        """compose title"""
1468        content = self.getContent()
[840]1469        #return "Clearance/Eligibility Record for %s %s" % (content.firstname,content.lastname)
1470        return "Clearance/Eligibility Record"
[423]1471
1472
1473InitializeClass(StudentClearance)
1474
1475def addStudentClearance(container, id, REQUEST=None, **kw):
1476    """Add a Students personal data."""
1477    ob = StudentClearance(id, **kw)
1478    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1479
1480###)
1481
[1997]1482class StudentStudyLevel(CPSDocument,AzaxBaseView): ###(
[454]1483    """
1484    WAeUP Student container for the various student data
1485    """
1486    meta_type = 'StudentStudyLevel'
1487    portal_type = meta_type
1488    security = ClassSecurityInfo()
1489
1490    security.declareProtected(View,"Title")
1491    def Title(self):
1492        """compose title"""
1493        return "Level %s" % self.aq_parent.getId()
1494
[1997]1495    def getCorrespondingSelect(self, value):
1496        """ returns select content """
1497        import pdb;pdb.set_trace()
1498        mapping = {}
1499        mapping['']=[]
1500        mapping['animals']=['dog', 'cat', 'cow']
1501        mapping['machines']=['computer', 'car', 'airplane']
1502        # XXX Note that originally we just used replaceInnerHTML to just put
1503        # the options inside the select, however this is principally broken
1504        # on IE due to an IE bug. Microsoft has confirmed the bug but is not
1505        # giving information on whether it has or it will ever be fixed.
1506        # For further info, see http://support.microsoft.com/default.aspx?scid=kb;en-us;276228
1507        # The current solution, replace the outer node, works solidly.
1508        result = ['<select id="second">']
1509        result.extend(['<option>%s</option>' % item for item in mapping[value]])
1510        result.append('</select>')
1511        self.getCommandSet('core').replaceHTML('select#second', ' '.join(result))
1512        return self.render()
1513
[1700]1514    def create_course_results(self,cert_id,current_level): ###(
[1649]1515        "create all courses in a level"
1516        aq_portal = self.portal_catalog.evalAdvancedQuery
1517        res = self.portal_catalog(portal_type="Certificate", id = cert_id)
1518        l = []
1519        import transaction
1520        if res:
1521            cert = res[0]
1522            path = cert.getPath()
1523            query = Eq("path","%s/%s" % (path,current_level)) &\
1524                    Eq('portal_type','CertificateCourse')
1525            courses = aq_portal(query)
1526            #from pdb import set_trace;set_trace()
1527            self_proxy = self.aq_parent
1528            for c in courses:
1529                d = self.getCourseInfo(c.getId)
1530                cr_id = self_proxy.invokeFactory('StudentCourseResult',c.getId)
1531                course_result = getattr(self_proxy,cr_id)
1532                self.portal_workflow.doActionFor(course_result,'open')
1533                d['core_or_elective'] = getattr(c.getObject().getContent(),'core_or_elective')
1534                course_result.getContent().edit(mapping=d)
[1820]1535                #transaction.commit()
[1700]1536    ###)
[472]1537
[454]1538InitializeClass(StudentStudyLevel)
1539
1540def addStudentStudyLevel(container, id, REQUEST=None, **kw):
1541    """Add a Students personal data."""
1542    ob = StudentStudyLevel(id, **kw)
1543    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1544
1545###)
1546
[362]1547class StudentStudyCourse(CPSDocument): ###(
1548    """
1549    WAeUP Student container for the various student data
1550    """
1551    meta_type = 'StudentStudyCourse'
1552    portal_type = meta_type
1553    security = ClassSecurityInfo()
1554
[364]1555    security.declareProtected(View,"Title")
1556    def Title(self):
1557        """compose title"""
1558        content = self.getContent()
[453]1559        return "Study Course"
[362]1560
1561
1562InitializeClass(StudentStudyCourse)
1563
1564def addStudentStudyCourse(container, id, REQUEST=None, **kw):
1565    """Add a Students personal data."""
1566    ob = StudentStudyCourse(id, **kw)
1567    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1568
1569###)
1570
[472]1571class StudentApplication(CPSDocument): ###(
[179]1572    """
1573    WAeUP Student container for the various student data
1574    """
[472]1575    meta_type = 'StudentApplication'
[179]1576    portal_type = meta_type
1577    security = ClassSecurityInfo()
1578
[181]1579    security.declareProtected(View,"Title")
1580    def Title(self):
1581        """compose title"""
[472]1582        return "Application Data"
[179]1583
[181]1584
[472]1585InitializeClass(StudentApplication)
[179]1586
[472]1587def addStudentApplication(container, id, REQUEST=None, **kw):
[179]1588    """Add a Students eligibility data."""
[472]1589    ob = StudentApplication(id, **kw)
[179]1590    return CPSBase_adder(container, ob, REQUEST=REQUEST)
[763]1591###)
[179]1592
[758]1593class StudentPume(CPSDocument): ###(
1594    """
1595    WAeUP Student container for the various student data
1596    """
1597    meta_type = 'StudentPume'
1598    portal_type = meta_type
1599    security = ClassSecurityInfo()
1600
1601    security.declareProtected(View,"Title")
1602    def Title(self):
1603        """compose title"""
1604        return "PUME Results"
1605
1606
1607InitializeClass(StudentPume)
1608
1609def addStudentPume(container, id, REQUEST=None, **kw):
1610    """Add a Students PUME data."""
1611    ob = StudentPume(id, **kw)
1612    return CPSBase_adder(container, ob, REQUEST=REQUEST)
[179]1613###)
[181]1614
[565]1615##class StudentSemester(CPSDocument): ###(
1616##    """
1617##    WAeUP StudentSemester containing the courses and students
1618##    """
1619##    meta_type = 'StudentSemester'
1620##    portal_type = meta_type
1621##    security = ClassSecurityInfo()
1622##
1623##InitializeClass(StudentSemester)
1624##
1625##def addStudentSemester(container, id, REQUEST=None, **kw):
1626##    """Add a StudentSemester."""
1627##    ob = StudentSemester(id, **kw)
1628##    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1629##
1630#####)
[464]1631
[758]1632##class Semester(CPSDocument): ###(
1633##    """
1634##    WAeUP Semester containing the courses and students
1635##    """
1636##    meta_type = 'Semester'
1637##    portal_type = meta_type
1638##    security = ClassSecurityInfo()
1639##
1640##InitializeClass(Semester)
1641##
1642##def addSemester(container, id, REQUEST=None, **kw):
1643##    """Add a Semester."""
1644##    ob = Semester(id, **kw)
1645##    return CPSBase_adder(container, ob, REQUEST=REQUEST)
1646##
1647#####)
[464]1648
1649class StudentCourseResult(CPSDocument): ###(
[89]1650    """
[464]1651    WAeUP StudentCourseResult
[89]1652    """
[464]1653    meta_type = 'StudentCourseResult'
[89]1654    portal_type = meta_type
1655    security = ClassSecurityInfo()
[472]1656
[454]1657    def getCourseEntry(self,cid):
[723]1658        res = self.portal_catalog({'meta_type': "Course",
[454]1659                                           'id': cid})
1660        if res:
1661            return res[-1]
1662        else:
1663            return None
[154]1664
[454]1665    security.declareProtected(View,"Title")
1666    def Title(self):
1667        """compose title"""
[723]1668        cid = self.aq_parent.getId()
[454]1669        ce = self.getCourseEntry(cid)
1670        if ce:
1671            return "%s" % ce.Title
1672        return "No course with id %s" % cid
[152]1673
[464]1674InitializeClass(StudentCourseResult)
[454]1675
[464]1676def addStudentCourseResult(container, id, REQUEST=None, **kw):
1677    """Add a StudentCourseResult."""
1678    ob = StudentCourseResult(id, **kw)
[89]1679    return CPSBase_adder(container, ob, REQUEST=REQUEST)
[139]1680###)
1681
[579]1682# Backward Compatibility StudyLevel
1683
1684from Products.WAeUP_SRP.Academics import StudyLevel
1685
1686from Products.WAeUP_SRP.Academics import addStudyLevel
1687
Note: See TracBrowser for help on using the repository browser.