source: WAeUP_SRP/trunk/Students.py @ 429

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

check for duplicate student_id

  • Property svn:keywords set to Id
File size: 22.6 KB
Line 
1#-*- mode: python; mode: fold -*-
2# $Id: Students.py 429 2006-08-26 14:06:48Z 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('StudentPersonal','personal')
105                sp = s.personal
106                d = {'Title': 'Personal Data'}
107                s.invokeFactory('StudentClearance','clearance')
108                sc = s.clearance
109                dc = {'Title': 'Clearance Data'}
110                dc['matric_no'] = matric_no
111                dc['jamb_reg_no'] = student.get('EntryRegNo')
112                lga = student.get('State') + ' / ' + student.get('LGA')               
113                dc['lga'] = lga
114                dc['nationality'] = student.get('Nationality')
115                dc['email'] = student.get('Emailaddress')
116                d['firstname'] = student.get('FirstName')
117                d['middlename'] = student.get('MiddleName')
118                d['lastname'] = student.get('Lastname')
119                d['former_surname'] = student.get('FormerSurname')
120                d['sex'] = student.get('Sex') == 'F'
121                d['perm_address'] = student.get('PermanentAddress')
122                d['perm_city'] = student.get('PermanentAddressCity')
123                d['campus_address'] = student.get('CampusAddress')
124                d['phone'] = student.get('PhoneNumber')
125                sp.getContent().edit(mapping=d)
126                sc.getContent().edit(mapping=dc)
127                #
128                # Study Course
129                #
130                s.invokeFactory('StudentStudyCourse','study_course')
131                sc = s.study_course
132                d = {}
133                #d['matricel_no'] = student.get('MatricNo')
134                #d['entry_reg_no'] = student.get('EntryRegNo')
135                #d['faculty'] = student.get('Faculty')
136                #d['department'] = student.get('Dept')
137                d['course_major'] = certcode
138                css = student.get('CurrentSession') or '2004-2005'
139                cs = int(css.split('-')[0]) - 2000
140                cl = int(student.get('StudentLevel'))/100
141                d['entry_session'] = "200%s" % (cs - cl)
142                sc.getContent().edit(mapping=d)
143                #
144                # Level
145                #
146                l = getattr(sc,level,None)
147                if l is None:
148                    #self.log('Creating Department %(DeptCode)s = %(Description)s' % dep)
149                    logger.info('Creating Level %(StudentLevel)s for %(fullname)s' % student)
150                    sc.invokeFactory('StudyLevel', level)
151                    l = getattr(sc, level)
152                    certificate = certs[certcode]
153                    cert_level = getattr(certificate,level,None)
154                    if cert_level is None:
155                        logger.info('Level %(level)s not in %(certcode)s' % vars())
156                    l.getContent().edit(mapping={'Title': "Level %s" % level})
157                    l.invokeFactory('Semester','first')
158                    l.invokeFactory('Semester','second')
159                    first_s = getattr(l,'first')
160                    first_s.getContent().edit(mapping={'Title': 'First Semester'})
161                    second_s = getattr(l,'second')
162                    second_s.getContent().edit(mapping={'Title': 'Second Semester'})
163            else:
164                em = 'Student with ID %(MatricNo)s %(fullname)s already exists\n' % student
165                logger.info(em)
166                no_import.write(em)
167                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)
168            if tr_count > MAX_TRANS:
169                transaction.commit()
170                em = 'Transaction commited\n' % student
171                logger.info(em)
172                tr_count = 0
173            tr_count += 1
174        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
175        return self.students.academics_contents()
176    ###)
177
178    security.declareProtected(ModifyPortalContent,"loadFullTimeStudentsResultsFromCSV") ###(
179    def loadFullTimeStudentsResultsFromCSV(self):
180        """load Fulltime Studentdata from CSV values"""
181        #return
182        import transaction
183        tr_count = 0
184        name = 'short_full_time_results_2004_2005'
185        no_import = False
186        if not no_import:
187            no_import = open("%s/import/%s_not_imported.csv" % (i_home,name),"w")
188            no_import.write('"Matnumber","CosCode","Ansbook","CosStuatus","Session","Mat_Cos","Score","CarryLevel","Grade","Weight","Semster","Verdict","Level","id","GPA"\n')
189        logger = logging.getLogger('%s_import' % name)
190        logger.info('Start loading from %s.csv' % name)
191        students_folder = self.portal_catalog({'meta_type': 'StudentsFolder'})[-1].getObject()
192        try:
193            results = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
194        except:
195            logger.error('Error reading %s.csv' % name)
196            return
197        l = self.portal_catalog({'meta_type': "Student"})
198        students = {}
199        for s in l:
200            students[s.id] = s.getObject()
201        l = self.portal_catalog({'meta_type': "Course"})
202        courses = {}
203        for c in l:
204            courses[c.id] = c.getObject()
205        for result in results:
206            sid = result.get('Matnumber')
207            if sid not in students.keys():
208                em = 'Student with ID %(Matnumber)s not found\n' % result
209                logger.info(em)
210                no_import.write(em)
211                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)
212                continue
213            course = result.get('CosCode')
214            if course not in courses.keys():
215                em = 'Course with ID %(CosCode)s not found\n' % result
216                logger.info(em)
217                no_import.write(em)
218                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)
219                continue
220            level = result.get('Level')
221            try:
222                int(level)
223            except:
224                em = 'Result for result with ID %(Matnumber)s Course %(CosCode)s Level is empty\n' % result
225                logger.info(em)
226                no_import.write(em)
227                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)
228                continue
229            sf = students.get(sid)
230            sc = getattr(sf,'study_course')
231            l = getattr(sc,level,None)
232            if l is None:
233                #self.log('Creating Department %(DeptCode)s = %(Description)s' % dep)
234                logger.info('Creating Level %(Level)s for %(Matnumber)s' % result)
235                sc.invokeFactory('StudyLevel', level)
236                l = getattr(sc, level)
237                l.getContent().edit(mapping={'Title': "Level %s" % level})
238                l.invokeFactory('Semester','first')
239                l.invokeFactory('Semester','second')
240                first_s = getattr(l,'first')
241                first_s.getContent().edit(mapping={'Title': 'First Semester'})
242                second_s = getattr(l,'second')
243                second_s.getContent().edit(mapping={'Title': 'Second Semester'})
244            snr = result.get('Semester')
245            semester = getattr(l,'first')
246            if snr == "2":
247                semester = getattr(l,'second')
248            logger.info('Creating CourseTicket %(CourseTicket)s in Level %(Level)s for %(Matnumber)s' % result)
249            semester.invokeFactory('CourseTicket',course)
250            ct = getattr(semester,course)
251            d = {}
252            d['ansbook'] = result.get('Ansbook')
253            d['status'] = result.get('CosStuatus')
254            d['score'] = result.get('Score')
255            d['carry_level'] = result.get('CarryLevel')
256            d['grade'] = result.get('Grade')
257            d['weight'] = result.get('Weight')
258            d['verdict'] = result.get('Verdict')
259            d['import_id'] = result.get('id')
260            gpa = result.get('GPA').replace(',','.')
261            d['gpa'] = float(gpa)
262            ct.getContent().edit(mapping = d)
263            if tr_count > MAX_TRANS:
264                transaction.commit()
265                tr_count = 0
266            tr_count += 1
267        return self.students.academics_contents()
268
269###)
270
271
272    security.declareProtected(View,"Title")
273    def Title(self):
274        """compose title"""
275        return "Student Section"
276
277InitializeClass(StudentsFolder)
278
279def addStudentsFolder(container, id, REQUEST=None, **kw):
280    """Add a Student."""
281    ob = StudentsFolder(id, **kw)
282    return CPSBase_adder(container, ob, REQUEST=REQUEST)
283###)
284
285class Student(CPSDocument): ###(
286    """
287    WAeUP Student container for the various student data
288    """
289    meta_type = 'Student'
290    portal_type = meta_type
291    security = ClassSecurityInfo()
292
293    security.declareProtected(View,"Title")
294    def Title(self):
295        """compose title"""
296        reg_nr = self.getId()[1:]
297        data = getattr(self,'personal',None)
298        if data is None:
299            data = getattr(self,'jamb',None)
300        if data:
301            content = data.getContent()
302            return "%s %s" % (content.firstname,content.lastname)
303        return self.title
304
305    def Description(self):
306        """compose description"""
307        data = getattr(self,'PERSONAL',None)
308        if data is None:
309            return "none"
310        if data:
311            content = data.getContent()
312            return "%s" % (content.description)
313        return self.description
314
315    security.declareProtected(View,"setScratchCardData")
316    def setScratchCardData(self,ident,ds):
317        """set this data """
318        dict = {'%s_sc_pin' % ident : ds.get('sc_pin'),
319                '%s_sc_id' % ident : ds.get('sc_id'),
320                '%s_sc_value' % ident : ds.get('sc_value'),
321                '%s_date' % ident : ds.get('sc_date'),
322                }
323
324        old_user = self.portal_membership.getAuthenticatedMember()
325        if self.portal_membership.isAnonymousUser():
326            tmp_user = CPSUnrestrictedUser('s%(jamb_id)s' % ds, '',
327                                       ['StudentManager'], '')
328            tmp_user = tmp_user.__of__(self.acl_users)
329            newSecurityManager(None, tmp_user)
330        #print str(dict)
331        self.edit(mapping=dict)
332        newSecurityManager(None, old_user)
333
334    security.declareProtected(View,"memberIsOwner")
335    def memberIsOwner(self):
336        """is the current user the owner"""
337        member = self.portal_membership.getAuthenticatedMember()
338        #print member, self.getId(),self.aq_parent.getId()
339        if self.aq_parent.getId() == str(member):
340            return True
341        return False
342
343    security.declareProtected(View,"accommodationIsBooked")
344    def accommodationIsBooked(self):
345        """is the accommodation booked"""
346        if self.accommodation_sc_pin != '':
347            return True
348        return False
349
350    security.declareProtected(View,"accommodationIsPayed")
351    def accommodationIsPayed(self):
352        """is the accommodation payed"""
353        if self.hostel_fee_sc_pin != '':
354            return True
355        return False
356
357    security.declareProtected(View,"isRegisteredForCurrentLevel")
358    def isRegisteredForCurrentLevel(self):
359        """is the student registered for the current level"""
360        for l in  self.aq_parent.objectValues():
361            if l.portal_type == 'StudyLevel':
362                return True
363        return False
364
365InitializeClass(Student)
366
367def addStudent(container, id, REQUEST=None, **kw):
368    """Add a Student."""
369    ob = Student(id, **kw)
370    return CPSBase_adder(container, ob, REQUEST=REQUEST)
371
372###)
373
374class StudentPersonal(CPSDocument): ###(
375    """
376    WAeUP Student container for the various student data
377    """
378    meta_type = 'StudentPersonal'
379    portal_type = meta_type
380    security = ClassSecurityInfo()
381
382    security.declareProtected(View,"Title")
383    def Title(self):
384        """compose title"""
385        content = self.getContent()
386        #return "Personal Data for %s %s" % (content.firstname,content.lastname)
387        return "Personal Data"
388
389
390InitializeClass(StudentPersonal)
391
392def addStudentPersonal(container, id, REQUEST=None, **kw):
393    """Add a Students personal data."""
394    ob = StudentPersonal(id, **kw)
395    return CPSBase_adder(container, ob, REQUEST=REQUEST)
396
397###)
398
399class StudentClearance(CPSDocument): ###(
400    """
401    WAeUP Student container for the various student data
402    """
403    meta_type = 'StudentClearance'
404    portal_type = meta_type
405    security = ClassSecurityInfo()
406
407    security.declareProtected(View,"Title")
408    def Title(self):
409        """compose title"""
410        content = self.getContent()
411        #return "Clearance Data for %s %s" % (content.firstname,content.lastname)
412        return "Clearance Data"
413
414
415InitializeClass(StudentClearance)
416
417def addStudentClearance(container, id, REQUEST=None, **kw):
418    """Add a Students personal data."""
419    ob = StudentClearance(id, **kw)
420    return CPSBase_adder(container, ob, REQUEST=REQUEST)
421
422###)
423
424class StudentStudyCourse(CPSDocument): ###(
425    """
426    WAeUP Student container for the various student data
427    """
428    meta_type = 'StudentStudyCourse'
429    portal_type = meta_type
430    security = ClassSecurityInfo()
431
432    security.declareProtected(View,"Title")
433    def Title(self):
434        """compose title"""
435        content = self.getContent()
436        return "Course Major"
437
438
439InitializeClass(StudentStudyCourse)
440
441def addStudentStudyCourse(container, id, REQUEST=None, **kw):
442    """Add a Students personal data."""
443    ob = StudentStudyCourse(id, **kw)
444    return CPSBase_adder(container, ob, REQUEST=REQUEST)
445
446###)
447
448class StudentAdmission(CPSDocument): ###(
449    """
450    WAeUP Student container for the various student data
451    """
452    meta_type = 'StudentAdmission'
453    portal_type = meta_type
454    security = ClassSecurityInfo()
455
456    security.declareProtected(View,"Title")
457    def Title(self):
458        """compose title"""
459        return "Admission Data"
460
461
462InitializeClass(StudentAdmission)
463
464def addStudentAdmission(container, id, REQUEST=None, **kw):
465    """Add a Students eligibility data."""
466    ob = StudentAdmission(id, **kw)
467    return CPSBase_adder(container, ob, REQUEST=REQUEST)
468
469###)
470
471class StudentDocuments(CPSDocument): ###(
472    """
473    WAeUP Student container for the various student data
474    """
475    meta_type = 'StudentDocuments'
476    portal_type = meta_type
477    security = ClassSecurityInfo()
478
479    security.declareProtected(View,"Title")
480    def Title(self):
481        """compose title"""
482        content = self.getContent()
483        return "Scanned Documents"
484
485
486InitializeClass(StudentDocuments)
487
488def addStudentDocuments(container, id, REQUEST=None, **kw):
489    """Add a Students documents"""
490    ob = StudentDocuments(id, **kw)
491    return CPSBase_adder(container, ob, REQUEST=REQUEST)
492
493###)
494
495class Jamb(CPSDocument): ###(
496    """
497    WAeUP Jamb containing the courses and students
498    """
499    meta_type = 'Jamb'
500    portal_type = meta_type
501    security = ClassSecurityInfo()
502
503    security.declareProtected(View,"Title")
504    def Title(self):
505        """compose title"""
506        content = self.getContent()
507        return "JAMB Data for %s %s" % (content.firstname,content.lastname)
508
509    security.declareProtected(View,"setOwnership")
510    def setOwnership(self,member_id):
511        """set ownership"""
512        pm = getattr(self,'portal_membership')
513        member = pm.getMemberById(member_id)
514        self.changeOwnership(member)
515
516InitializeClass(Jamb)
517
518def addJamb(container, id, REQUEST=None, **kw):
519    """Add a Jamb."""
520    ob = Jamb(id, **kw)
521    return CPSBase_adder(container, ob, REQUEST=REQUEST)
522
523###)
524
525class StudyLevel(CPSDocument): ###(
526    """
527    WAeUP StudyLevel containing the courses and students
528    """
529    meta_type = 'StudyLevel'
530    portal_type = meta_type
531    security = ClassSecurityInfo()
532
533InitializeClass(StudyLevel)
534
535def addStudyLevel(container, id, REQUEST=None, **kw):
536    """Add a StudyLevel."""
537    ob = StudyLevel(id, **kw)
538    return CPSBase_adder(container, ob, REQUEST=REQUEST)
539
540###)
541
542class Semester(CPSDocument): ###(
543    """
544    WAeUP Semester containing the courses and students
545    """
546    meta_type = 'Semester'
547    portal_type = meta_type
548    security = ClassSecurityInfo()
549
550InitializeClass(Semester)
551
552def addSemester(container, id, REQUEST=None, **kw):
553    """Add a Semester."""
554    ob = Semester(id, **kw)
555    return CPSBase_adder(container, ob, REQUEST=REQUEST)
556
557###)
558
Note: See TracBrowser for help on using the repository browser.