source: WAeUP_SRP/trunk/Students.py @ 455

Last change on this file since 455 was 454, checked in by joachim, 18 years ago

add student_study_level,
adopted result_import
results import now is broken because of missing wf_state.

  • Property svn:keywords set to Id
File size: 22.3 KB
Line 
1#-*- mode: python; mode: fold -*-
2# $Id: Students.py 454 2006-08-31 10:37:54Z joachim $
3from Globals import InitializeClass
4from AccessControl import ClassSecurityInfo
5from AccessControl.SecurityManagement import newSecurityManager
6from zExceptions import BadRequest
7from Products.CMFCore.utils import UniqueObject, getToolByName
8from Products.CMFCore.permissions import View
9from Products.CMFCore.permissions import ModifyPortalContent
10from Products.CPSCore.CPSBase import CPSBase_adder, CPSBaseFolder
11#from Products.CPSCore.CPSBase import CPSBaseDocument as BaseDocument
12from Products.CPSDocument.CPSDocument import CPSDocument
13from Products.CPSCore.CPSBase import CPSBaseBTreeFolder as BaseBTreeFolder
14from Products.CPSCore.CPSMembershipTool import CPSUnrestrictedUser
15from Products.WAeUP_SRP.Academics import makeCertificateCode
16import logging
17import csv,re
18import Globals
19p_home = Globals.package_home(globals())
20i_home = Globals.INSTANCE_HOME
21MAX_TRANS = 1000
22
23def generateStudentId():
24    import random
25    r = random
26    return "%c%d" % (r.choice('ABCDEFGHKLMNPQRSTUVWXY'),r.randint(99999,1000000))
27
28class StudentsFolder(CPSDocument): ###(
29    """
30    WAeUP container for the various WAeUP containers data
31    """
32    meta_type = 'StudentsFolder'
33    portal_type = meta_type
34    security = ClassSecurityInfo()
35
36    security.declareProtected(ModifyPortalContent,"loadFullTimeStudentsFromCSV")###(
37    def loadFullTimeStudentsFromCSV(self):
38        """load Fulltime Studentdata from CSV values"""
39        #return
40        import transaction
41        tr_count = 0
42        name = 'short_full_time'
43        no_import = False
44        if not no_import:
45            no_import = open("%s/import/%s_not_imported.csv" % (i_home,name),"w")
46            no_import.write('"MatricNo","EntryRegNo","CurrentSession","StudentLevel","fullname","FirstName","MiddleName","Lastname","FormerSurname","Sex","Nationality","State","LGA","PermanentAddress","PermanentAddressCity","CampusAddress","PhoneNumber","Emailaddress","Mode","CourseMajor","Faculty","Dept"\n')
47        logger = logging.getLogger('%s_import' % name)
48        logger.info('Start loading from %s.csv' % name)
49        students_folder = self.portal_catalog({'meta_type': 'StudentsFolder'})[-1].getObject()
50        try:
51            students = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
52        except:
53            logger.error('Error reading %s.csv' % name)
54            return
55        l = self.portal_catalog({'meta_type': "StudentClearance",})
56        matrics = []
57        for s in l:
58            matrics.append(s.getObject().getContent().matric_no)
59        print matrics
60        l = self.portal_catalog({'meta_type': "Certificate"})
61        certs = {}
62        for c in l:
63            certs[c.id] = c.getObject()
64        for student in students:
65            logger.info('processing "%(MatricNo)s","%(EntryRegNo)s","%(CurrentSession)s","%(StudentLevel)s","%(fullname)s","%(FirstName)s","%(MiddleName)s","%(Lastname)s","%(FormerSurname)s","%(Sex)s","%(Nationality)s","%(State)s","%(LGA)s","%(PermanentAddress)s","%(PermanentAddressCity)s","%(CampusAddress)s","%(PhoneNumber)s","%(Emailaddress)s","%(Mode)s","%(CourseMajor)s","%(Faculty)s","%(Dept)s"\n' % student)
66            sid = student.get('MatricNo')
67            if sid == "":
68                em = 'Empty MatricNo\n'
69                logger.info(em)
70                no_import.write(em)
71                no_import.write('"%(MatricNo)s","%(EntryRegNo)s","%(CurrentSession)s","%(StudentLevel)s","%(fullname)s","%(FirstName)s","%(MiddleName)s","%(Lastname)s","%(FormerSurname)s","%(Sex)s","%(Nationality)s","%(State)s","%(LGA)s","%(PermanentAddress)s","%(PermanentAddressCity)s","%(CampusAddress)s","%(PhoneNumber)s","%(Emailaddress)s","%(Mode)s","%(CourseMajor)s","%(Faculty)s","%(Dept)s"\n' % student)
72                continue
73            certcode = makeCertificateCode(student.get('CourseMajor'))
74            if certcode not in certs.keys():
75                em = 'Certificate with ID %s %s not found\n' % (certcode, student.get('CourseMajor'))
76                logger.info(em)
77                no_import.write(em)
78                no_import.write('"%(MatricNo)s","%(EntryRegNo)s","%(CurrentSession)s","%(StudentLevel)s","%(fullname)s","%(FirstName)s","%(MiddleName)s","%(Lastname)s","%(FormerSurname)s","%(Sex)s","%(Nationality)s","%(State)s","%(LGA)s","%(PermanentAddress)s","%(PermanentAddressCity)s","%(CampusAddress)s","%(PhoneNumber)s","%(Emailaddress)s","%(Mode)s","%(CourseMajor)s","%(Faculty)s","%(Dept)s"\n' % student)
79                continue
80            level = student.get('StudentLevel')
81            try:
82                int(level)
83            except:
84                em = 'Student with ID %(MatricNo)s StudentLevel is empty\n' % student
85                logger.info(em)
86                no_import.write(em)
87                no_import.write('"%(MatricNo)s","%(EntryRegNo)s","%(CurrentSession)s","%(StudentLevel)s","%(fullname)s","%(FirstName)s","%(MiddleName)s","%(Lastname)s","%(FormerSurname)s","%(Sex)s","%(Nationality)s","%(State)s","%(LGA)s","%(PermanentAddress)s","%(PermanentAddressCity)s","%(CampusAddress)s","%(PhoneNumber)s","%(Emailaddress)s","%(Mode)s","%(CourseMajor)s","%(Faculty)s","%(Dept)s"\n' % student)
88                continue
89            matric_no = student.get('MatricNo')
90            if matric_no not in matrics:
91                matrics.append(matric_no)
92                sid = generateStudentId()
93                #self.log('Creating Faculty %(id)s = %(Title)s' % faculty)
94                logger.info('%(tr_count)s: Creating Student with ID %(sid)s Matric_no %(matric_no)s ' % vars())
95                not_created = True
96                while not_created:
97                    try:
98                        students_folder.invokeFactory('Student', sid)
99                        not_created = False
100                    except BadRequest:
101                        sid = generateStudentId()
102                logger.info('%(tr_count)s: Creating Student with ID %(sid)s Matric_no %(matric_no)s ' % vars())
103                s = getattr(self,sid)
104                s.invokeFactory('StudentAdmission','admission')
105                da = {'Title': 'Admission Data'}
106                s.invokeFactory('StudentPersonal','personal')
107                da['jamb_reg_no'] = student.get('EntryRegNo')
108                sp = s.personal
109                d = {'Title': 'Personal Data'}
110                s.invokeFactory('StudentClearance','clearance')
111                sc = s.clearance
112                dc = {'Title': 'Clearance Data'}
113                dc['matric_no'] = matric_no
114                lga = student.get('State') + ' / ' + student.get('LGA')               
115                dc['lga'] = lga
116                dc['nationality'] = student.get('Nationality')
117                dc['email'] = student.get('Emailaddress')
118                d['firstname'] = student.get('FirstName')
119                d['middlename'] = student.get('MiddleName')
120                d['lastname'] = student.get('Lastname')
121                d['former_surname'] = student.get('FormerSurname')
122                d['sex'] = student.get('Sex') == 'F'
123                d['perm_address'] = student.get('PermanentAddress')
124                d['perm_city'] = student.get('PermanentAddressCity')
125                d['campus_address'] = student.get('CampusAddress')
126                d['phone'] = student.get('PhoneNumber')
127                s.admission.getContent().edit(mapping=da)
128                sp.getContent().edit(mapping=d)
129                sc.getContent().edit(mapping=dc)
130                #
131                # Study Course
132                #
133                s.invokeFactory('StudentStudyCourse','study_course')
134                sc = s.study_course
135                d = {}
136                #d['matricel_no'] = student.get('MatricNo')
137                #d['entry_reg_no'] = student.get('EntryRegNo')
138                #d['faculty'] = student.get('Faculty')
139                #d['department'] = student.get('Dept')
140                d['study_course'] = certcode
141                css = student.get('CurrentSession') or '2004-2005'
142                cs = int(css.split('-')[0]) - 2000
143                cl = int(student.get('StudentLevel'))/100
144                d['entry_session'] = "200%s" % (cs - cl)
145                sc.getContent().edit(mapping=d)
146                #
147                # Level
148                #
149                l = getattr(sc,level,None)
150                if l is None:
151                    #self.log('Creating Department %(DeptCode)s = %(Description)s' % dep)
152                    logger.info('Creating Level %(StudentLevel)s for %(fullname)s' % student)
153                    sc.invokeFactory('StudentStudyLevel', level)
154                    l = getattr(sc, level)
155                    certificate = certs[certcode]
156                    cert_level = getattr(certificate,level,None)
157                    if cert_level is None:
158                        logger.info('Level %(level)s not in %(certcode)s' % vars())
159                    l.getContent().edit(mapping={'Title': "Level %s" % level})
160                    l.invokeFactory('Semester','first')
161                    l.invokeFactory('Semester','second')
162                    first_s = getattr(l,'first')
163                    first_s.getContent().edit(mapping={'Title': 'First Semester'})
164                    second_s = getattr(l,'second')
165                    second_s.getContent().edit(mapping={'Title': 'Second Semester'})
166            else:
167                em = 'Student with ID %(MatricNo)s %(fullname)s already exists\n' % student
168                logger.info(em)
169                no_import.write(em)
170                no_import.write('"%(MatricNo)s","%(EntryRegNo)s","%(CurrentSession)s","%(StudentLevel)s","%(fullname)s","%(FirstName)s","%(MiddleName)s","%(Lastname)s","%(FormerSurname)s","%(Sex)s","%(Nationality)s","%(State)s","%(LGA)s","%(PermanentAddress)s","%(PermanentAddressCity)s","%(CampusAddress)s","%(PhoneNumber)s","%(Emailaddress)s","%(Mode)s","%(CourseMajor)s","%(Faculty)s","%(Dept)s"\n' % student)
171            if tr_count > MAX_TRANS:
172                transaction.commit()
173                em = 'Transaction commited\n' % student
174                logger.info(em)
175                tr_count = 0
176            tr_count += 1
177        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
178        return self.students.academics_contents()
179    ###)
180
181    security.declareProtected(ModifyPortalContent,"loadFullTimeStudentsResultsFromCSV") ###(
182    def loadFullTimeStudentsResultsFromCSV(self):
183        """load Fulltime Studentdata from CSV values"""
184        #return
185        import transaction
186        tr_count = 0
187        name = 'short_full_time_results_2004_2005'
188        no_import = False
189        if not no_import:
190            no_import = open("%s/import/%s_not_imported.csv" % (i_home,name),"w")
191            no_import.write('"Matnumber","CosCode","Ansbook","CosStuatus","Session","Mat_Cos","Score","CarryLevel","Grade","Weight","Semster","Verdict","Level","id","GPA"\n')
192        logger = logging.getLogger('%s_import' % name)
193        logger.info('Start loading from %s.csv' % name)
194        students_folder = self.portal_catalog({'meta_type': 'StudentsFolder'})[-1].getObject()
195        try:
196            results = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
197        except:
198            logger.error('Error reading %s.csv' % name)
199            return
200        l = self.portal_catalog({'meta_type': "Course"})
201        courses = {}
202        for c in l:
203            courses[c.id] = c.getObject()
204        for result in results:
205            sid = result.get('Matnumber')
206            res = self.portal_catalog({'meta_type': "StudentClearance",
207                                     'matric_no': sid })
208            if not res:
209                em = 'Student with ID %(Matnumber)s not found\n' % result
210                logger.info(em)
211                no_import.write(em)
212                no_import.write('"%(Matnumber)s","%(CosCode)s","%(Ansbook)s","%(CosStuatus)s","%(Session)s","%(Mat_Cos)s","%(Score)s","%(CarryLevel)s","%(Grade)s","%(Weight)s","%(Semster)s","%(Verdict)s","%(Level)s","%(id)s","%(GPA)s"\n' % result)
213                continue
214            sf = res[0].getObject().aq_parent
215            result['StudentId'] = sf.getId()
216            course = result.get('CosCode')
217            if course not in courses.keys():
218                em = 'Course with ID %(CosCode)s not found\n' % result
219                logger.info(em)
220                no_import.write(em)
221                no_import.write('"%(Matnumber)s","%(CosCode)s","%(Ansbook)s","%(CosStuatus)s","%(Session)s","%(Mat_Cos)s","%(Score)s","%(CarryLevel)s","%(Grade)s","%(Weight)s","%(Semster)s","%(Verdict)s","%(Level)s","%(id)s","%(GPA)s"\n' % result)
222                continue
223            level = result.get('Level')
224            try:
225                int(level)
226            except:
227                em = 'Result for result with ID %(Matnumber)s Course %(CosCode)s Level is empty\n' % result
228                logger.info(em)
229                no_import.write(em)
230                no_import.write('"%(Matnumber)s","%(CosCode)s","%(Ansbook)s","%(CosStuatus)s","%(Session)s","%(Mat_Cos)s","%(Score)s","%(CarryLevel)s","%(Grade)s","%(Weight)s","%(Semster)s","%(Verdict)s","%(Level)s","%(id)s","%(GPA)s"\n' % result)
231                continue
232            sc = getattr(sf,'study_course')
233            l = getattr(sc,level,None)
234            if l is None:
235                #self.log('Creating Department %(DeptCode)s = %(Description)s' % dep)
236                logger.info('Creating Level %(Level)s for %(StudentId)s %(Matnumber)s' % result)
237                sc.invokeFactory('StudentStudyLevel', level)
238                l = getattr(sc, level)
239                l.invokeFactory('Semester','first')
240                l.invokeFactory('Semester','second')
241                first_s = getattr(l,'first')
242                first_s.getContent().edit(mapping={'Title': 'First Semester'})
243                second_s = getattr(l,'second')
244                second_s.getContent().edit(mapping={'Title': 'Second Semester'})
245            snr = result.get('Semster')
246            semester = getattr(l,'first')
247            if snr == "2":
248                semester = getattr(l,'second')
249            logger.info('Creating CourseTicket %(CosCode)s in Level %(Level)s for %(StudentId)s %(Matnumber)s' % result)
250            semester.invokeFactory('CourseTicket',course)
251            ct = getattr(semester,course)
252            d = {}
253            dlev = {}
254            d['ansbook'] = result.get('Ansbook')
255            d['status'] = result.get('CosStuatus')
256            d['score'] = result.get('Score')
257            dlev['session'] = result.get('Session')
258            dlev['carry_level'] = result.get('CarryLevel')
259            d['grade'] = result.get('Grade')
260            #d['weight'] = result.get('Weight')
261            dlev['verdict'] = result.get('Verdict')
262            #d['import_id'] = result.get('id')
263            #gpa = result.get('GPA').replace(',','.')
264            #d['gpa'] = float(gpa)
265            ct.getContent().edit(mapping = d)
266            l.getContent().edit(mapping = dlev)
267            if tr_count > MAX_TRANS:
268                transaction.commit()
269                tr_count = 0
270            tr_count += 1
271        return self.students.academics_contents()
272
273###)
274
275
276    security.declareProtected(View,"Title")
277    def Title(self):
278        """compose title"""
279        return "Student Section"
280
281InitializeClass(StudentsFolder)
282
283def addStudentsFolder(container, id, REQUEST=None, **kw):
284    """Add a Student."""
285    ob = StudentsFolder(id, **kw)
286    return CPSBase_adder(container, ob, REQUEST=REQUEST)
287###)
288
289class Student(CPSDocument): ###(
290    """
291    WAeUP Student container for the various student data
292    """
293    meta_type = 'Student'
294    portal_type = meta_type
295    security = ClassSecurityInfo()
296
297    security.declareProtected(View,"Title")
298    def Title(self):
299        """compose title"""
300        reg_nr = self.getId()[1:]
301        data = getattr(self,'personal',None)
302        if data:
303            content = data.getContent()
304            return "%s %s" % (content.firstname,content.lastname)
305        return self.title
306
307InitializeClass(Student)
308
309def addStudent(container, id, REQUEST=None, **kw):
310    """Add a Student."""
311    ob = Student(id, **kw)
312    return CPSBase_adder(container, ob, REQUEST=REQUEST)
313
314###)
315
316class StudentPersonal(CPSDocument): ###(
317    """
318    WAeUP Student container for the various student data
319    """
320    meta_type = 'StudentPersonal'
321    portal_type = meta_type
322    security = ClassSecurityInfo()
323
324    security.declareProtected(View,"Title")
325    def Title(self):
326        """compose title"""
327        content = self.getContent()
328        #return "Personal Data for %s %s" % (content.firstname,content.lastname)
329        return "Personal Data"
330
331
332InitializeClass(StudentPersonal)
333
334def addStudentPersonal(container, id, REQUEST=None, **kw):
335    """Add a Students personal data."""
336    ob = StudentPersonal(id, **kw)
337    return CPSBase_adder(container, ob, REQUEST=REQUEST)
338
339###)
340
341class StudentClearance(CPSDocument): ###(
342    """
343    WAeUP Student container for the various student data
344    """
345    meta_type = 'StudentClearance'
346    portal_type = meta_type
347    security = ClassSecurityInfo()
348
349    security.declareProtected(View,"Title")
350    def Title(self):
351        """compose title"""
352        content = self.getContent()
353        #return "Clearance Data for %s %s" % (content.firstname,content.lastname)
354        return "Clearance Data"
355
356
357InitializeClass(StudentClearance)
358
359def addStudentClearance(container, id, REQUEST=None, **kw):
360    """Add a Students personal data."""
361    ob = StudentClearance(id, **kw)
362    return CPSBase_adder(container, ob, REQUEST=REQUEST)
363
364###)
365
366class StudentStudyLevel(CPSDocument): ###(
367    """
368    WAeUP Student container for the various student data
369    """
370    meta_type = 'StudentStudyLevel'
371    portal_type = meta_type
372    security = ClassSecurityInfo()
373
374    security.declareProtected(View,"Title")
375    def Title(self):
376        """compose title"""
377        return "Level %s" % self.aq_parent.getId()
378
379    security.declareProtected(View,"gpa")
380    def gpa(self):
381        """calculate the gpa"""
382        sum = 0
383        course_count = 0
384        for semester in ('first','second'):
385            sf=getattr(self,semester)
386            for sc in sf.objectValues():
387                result = sc.getContent()
388                res = self.portal_catalog({'meta_type': 'Course',
389                                              'id': sc.aq_parent.id})
390                if len(res) != 1:
391                    continue
392                course = res[0].getObject().getContent()
393                sum += course.credits * ['F','E','D','C','B','A'].index(result.grade)
394                course_count += 1
395        if course_count:
396            return sum/course_count
397        return 0.0
398   
399InitializeClass(StudentStudyLevel)
400
401def addStudentStudyLevel(container, id, REQUEST=None, **kw):
402    """Add a Students personal data."""
403    ob = StudentStudyLevel(id, **kw)
404    return CPSBase_adder(container, ob, REQUEST=REQUEST)
405
406###)
407
408class StudentStudyCourse(CPSDocument): ###(
409    """
410    WAeUP Student container for the various student data
411    """
412    meta_type = 'StudentStudyCourse'
413    portal_type = meta_type
414    security = ClassSecurityInfo()
415
416    security.declareProtected(View,"Title")
417    def Title(self):
418        """compose title"""
419        content = self.getContent()
420        return "Study Course"
421
422
423InitializeClass(StudentStudyCourse)
424
425def addStudentStudyCourse(container, id, REQUEST=None, **kw):
426    """Add a Students personal data."""
427    ob = StudentStudyCourse(id, **kw)
428    return CPSBase_adder(container, ob, REQUEST=REQUEST)
429
430###)
431
432class StudentAdmission(CPSDocument): ###(
433    """
434    WAeUP Student container for the various student data
435    """
436    meta_type = 'StudentAdmission'
437    portal_type = meta_type
438    security = ClassSecurityInfo()
439
440    security.declareProtected(View,"Title")
441    def Title(self):
442        """compose title"""
443        return "Admission Data"
444
445
446InitializeClass(StudentAdmission)
447
448def addStudentAdmission(container, id, REQUEST=None, **kw):
449    """Add a Students eligibility data."""
450    ob = StudentAdmission(id, **kw)
451    return CPSBase_adder(container, ob, REQUEST=REQUEST)
452
453###)
454
455class Semester(CPSDocument): ###(
456    """
457    WAeUP Semester containing the courses and students
458    """
459    meta_type = 'Semester'
460    portal_type = meta_type
461    security = ClassSecurityInfo()
462
463InitializeClass(Semester)
464
465def addSemester(container, id, REQUEST=None, **kw):
466    """Add a Semester."""
467    ob = Semester(id, **kw)
468    return CPSBase_adder(container, ob, REQUEST=REQUEST)
469
470###)
471
472class CourseTicket(CPSDocument): ###(
473    """
474    WAeUP CourseTicket
475    """
476    meta_type = 'CourseTicket'
477    portal_type = meta_type
478    security = ClassSecurityInfo()
479    def getCourseEntry(self,cid):
480        res = self.portal_catalog({'meta_type': "Course",
481                                           'id': cid})
482        if res:
483            return res[-1]
484        else:
485            return None
486
487    security.declareProtected(View,"Title")
488    def Title(self):
489        """compose title"""
490        cid = self.getId()
491        ce = self.getCourseEntry(cid)
492        if ce:
493            return "%s" % ce.Title
494        return "No course with id %s" % cid
495
496InitializeClass(CourseTicket)
497
498def addCourseTicket(container, id, REQUEST=None, **kw):
499    """Add a CourseTicket."""
500    ob = CourseTicket(id, **kw)
501    return CPSBase_adder(container, ob, REQUEST=REQUEST)
502###)
503
504class ScratchCardBatchesFolder(CPSDocument): ###(
505    """
506    WAeUP Student container for the various student data
507    """
508    meta_type = 'ScratchCardBatchesFolder'
509    portal_type = meta_type
510    security = ClassSecurityInfo()
511
512    security.declareProtected(View,"Title")
513    def Title(self):
514        """compose title"""
515        return "Pin Batches"
516
517
518InitializeClass(ScratchCardBatchesFolder)
519
520def addScratchCardBatchesFolder(container, id, REQUEST=None, **kw):
521    """Add a Students personal data."""
522    ob = ScratchCardBatchesFolder(id, **kw)
523    return CPSBase_adder(container, ob, REQUEST=REQUEST)
524
525###)
526
527from Products.WAeUP_SRP.WAeUPTables import PinTable
528
529class ScratchCardBatch(CPSDocument): ###(
530    """
531    WAeUP Student container for the various student data
532    """
533    meta_type = 'ScratchCardBatch'
534    portal_type = meta_type
535    security = ClassSecurityInfo()
536
537    security.declareProtected(View,"Title")
538    def Title(self):
539        """compose title"""
540        doc = self.getContent()
541        return "Pin Batch %s BatchNo %d" % (doc.prefix, doc.batch_no)
542
543
544InitializeClass(ScratchCardBatch)
545
546def addScratchCardBatch(container, id, REQUEST=None, **kw):
547    """Add a Students personal data."""
548    ob = ScratchCardBatch(id, **kw)
549    return CPSBase_adder(container, ob, REQUEST=REQUEST)
550
551###)
Note: See TracBrowser for help on using the repository browser.