#-*- mode: python; mode: fold -*- # $Id: Students.py 469 2006-09-01 20:23:38Z joachim $ from Globals import InitializeClass from AccessControl import ClassSecurityInfo from AccessControl.SecurityManagement import newSecurityManager from zExceptions import BadRequest from Products.CMFCore.utils import UniqueObject, getToolByName from Products.CMFCore.permissions import View from Products.CMFCore.permissions import ModifyPortalContent from Products.CPSCore.CPSBase import CPSBase_adder, CPSBaseFolder #from Products.CPSCore.CPSBase import CPSBaseDocument as BaseDocument from Products.CPSDocument.CPSDocument import CPSDocument from Products.CPSCore.CPSBase import CPSBaseBTreeFolder as BaseBTreeFolder from Products.CPSCore.CPSMembershipTool import CPSUnrestrictedUser from Products.WAeUP_SRP.Academics import makeCertificateCode import logging import csv,re import Globals p_home = Globals.package_home(globals()) i_home = Globals.INSTANCE_HOME MAX_TRANS = 1000 def generateStudentId(): import random r = random return "%c%d" % (r.choice('ABCDEFGHKLMNPQRSTUVWXY'),r.randint(99999,1000000)) class StudentsFolder(CPSDocument): ###( """ WAeUP container for the various WAeUP containers data """ meta_type = 'StudentsFolder' portal_type = meta_type security = ClassSecurityInfo() security.declareProtected(ModifyPortalContent,"loadFullTimeStudentsFromCSV")###( def loadFullTimeStudentsFromCSV(self): """load Fulltime Studentdata from CSV values""" #return import transaction tr_count = 0 name = 'short_full_time' no_import = False if not no_import: no_import = open("%s/import/%s_not_imported.csv" % (i_home,name),"w") 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') logger = logging.getLogger('%s_import' % name) logger.info('Start loading from %s.csv' % name) students_folder = self.portal_catalog({'meta_type': 'StudentsFolder'})[-1].getObject() try: students = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb")) except: logger.error('Error reading %s.csv' % name) return l = self.portal_catalog({'meta_type': "StudentClearance",}) matrics = [] for s in l: matrics.append(s.getObject().getContent().matric_no) print matrics l = self.portal_catalog({'meta_type': "Certificate"}) certs = {} for c in l: certs[c.id] = c.getObject() for student in students: 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) sid = student.get('MatricNo') if sid == "": em = 'Empty MatricNo\n' logger.info(em) no_import.write(em) 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) continue certcode = makeCertificateCode(student.get('CourseMajor')) if certcode not in certs.keys(): em = 'Certificate with ID %s %s not found\n' % (certcode, student.get('CourseMajor')) logger.info(em) no_import.write(em) 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) continue level = student.get('StudentLevel') try: int(level) except: em = 'Student with ID %(MatricNo)s StudentLevel is empty\n' % student logger.info(em) no_import.write(em) 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) continue matric_no = student.get('MatricNo') if matric_no not in matrics: matrics.append(matric_no) sid = generateStudentId() #self.log('Creating Faculty %(id)s = %(Title)s' % faculty) logger.info('%(tr_count)s: Creating Student with ID %(sid)s Matric_no %(matric_no)s ' % vars()) not_created = True while not_created: try: students_folder.invokeFactory('Student', sid) not_created = False except BadRequest: sid = generateStudentId() logger.info('%(tr_count)s: Creating Student with ID %(sid)s Matric_no %(matric_no)s ' % vars()) s = getattr(self,sid) s.invokeFactory('StudentAdmission','admission') da = {'Title': 'Admission Data'} s.invokeFactory('StudentPersonal','personal') da['jamb_reg_no'] = student.get('EntryRegNo') sp = s.personal d = {'Title': 'Personal Data'} s.invokeFactory('StudentClearance','clearance') sc = s.clearance dc = {'Title': 'Clearance Data'} dc['matric_no'] = matric_no lga = student.get('State') + ' / ' + student.get('LGA') dc['lga'] = lga dc['nationality'] = student.get('Nationality') dc['email'] = student.get('Emailaddress') d['firstname'] = student.get('FirstName') d['middlename'] = student.get('MiddleName') d['lastname'] = student.get('Lastname') d['former_surname'] = student.get('FormerSurname') d['sex'] = student.get('Sex') == 'F' d['perm_address'] = student.get('PermanentAddress') d['perm_city'] = student.get('PermanentAddressCity') d['campus_address'] = student.get('CampusAddress') d['phone'] = student.get('PhoneNumber') s.admission.getContent().edit(mapping=da) sp.getContent().edit(mapping=d) sc.getContent().edit(mapping=dc) # # Study Course # s.invokeFactory('StudentStudyCourse','study_course') sc = s.study_course d = {} #d['matricel_no'] = student.get('MatricNo') #d['entry_reg_no'] = student.get('EntryRegNo') #d['faculty'] = student.get('Faculty') #d['department'] = student.get('Dept') d['study_course'] = certcode css = student.get('CurrentSession') or '2004-2005' cs = int(css.split('-')[0]) - 2000 cl = int(student.get('StudentLevel'))/100 d['entry_session'] = "200%s" % (cs - cl) sc.getContent().edit(mapping=d) # # Level # l = getattr(sc,level,None) if l is None: #self.log('Creating Department %(DeptCode)s = %(Description)s' % dep) logger.info('Creating Level %(StudentLevel)s for %(fullname)s' % student) sc.invokeFactory('StudentStudyLevel', level) l = getattr(sc, level) certificate = certs[certcode] cert_level = getattr(certificate,level,None) if cert_level is None: logger.info('Level %(level)s not in %(certcode)s' % vars()) l.getContent().edit(mapping={'Title': "Level %s" % level}) l.invokeFactory('StudentSemester','first') l.invokeFactory('StudentSemester','second') first_s = getattr(l,'first') first_s.getContent().edit(mapping={'Title': 'First Semester'}) second_s = getattr(l,'second') second_s.getContent().edit(mapping={'Title': 'Second Semester'}) else: em = 'Student with ID %(MatricNo)s %(fullname)s already exists\n' % student logger.info(em) no_import.write(em) 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) if tr_count > MAX_TRANS: transaction.commit() em = 'Transaction commited\n' % student logger.info(em) tr_count = 0 tr_count += 1 return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1')) return self.students.academics_contents() ###) security.declareProtected(ModifyPortalContent,"loadFullTimeStudentsResultsFromCSV") ###( def loadFullTimeStudentsResultsFromCSV(self): """load Fulltime Studentdata from CSV values""" #return import transaction tr_count = 0 name = 'short_full_time_results_2004_2005' no_import = False if not no_import: no_import = open("%s/import/%s_not_imported.csv" % (i_home,name),"w") no_import.write('"Matnumber","CosCode","Ansbook","CosStuatus","Session","Mat_Cos","Score","CarryLevel","Grade","Weight","Semster","Verdict","Level","id","GPA"\n') logger = logging.getLogger('%s_import' % name) logger.info('Start loading from %s.csv' % name) students_folder = self.portal_catalog({'meta_type': 'StudentsFolder'})[-1].getObject() try: results = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb")) except: logger.error('Error reading %s.csv' % name) return l = self.portal_catalog({'meta_type': "Course"}) courses = {} for c in l: courses[c.id] = c.getObject() for result in results: sid = result.get('Matnumber') res = self.portal_catalog({'meta_type': "StudentClearance", 'matric_no': sid }) if not res: em = 'Student with ID %(Matnumber)s not found\n' % result logger.info(em) no_import.write(em) 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) continue sf = res[0].getObject().aq_parent result['StudentId'] = sf.getId() course = result.get('CosCode') if course not in courses.keys(): em = 'Course with ID %(CosCode)s not found\n' % result logger.info(em) no_import.write(em) 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) continue level = result.get('Level') try: int(level) except: em = 'Result for result with ID %(Matnumber)s Course %(CosCode)s Level is empty\n' % result logger.info(em) no_import.write(em) 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) continue sc = getattr(sf,'study_course') l = getattr(sc,level,None) if l is None: #self.log('Creating Department %(DeptCode)s = %(Description)s' % dep) logger.info('Creating Level %(Level)s for %(StudentId)s %(Matnumber)s' % result) sc.invokeFactory('StudentStudyLevel', level) l = getattr(sc, level) l.invokeFactory('StudentSemester','first') l.invokeFactory('StudentSemester','second') first_s = getattr(l,'first') first_s.getContent().edit(mapping={'Title': 'First Semester'}) second_s = getattr(l,'second') second_s.getContent().edit(mapping={'Title': 'Second Semester'}) snr = result.get('Semster') semester = getattr(l,'first') if snr == "2": semester = getattr(l,'second') logger.info('Creating StudentCourseResult %(CosCode)s in Level %(Level)s for %(StudentId)s %(Matnumber)s' % result) semester.invokeFactory('StudentCourseResult',course) ct = getattr(semester,course) d = {} dlev = {} d['ansbook'] = result.get('Ansbook') d['status'] = result.get('CosStuatus') d['score'] = result.get('Score') dlev['session'] = result.get('Session') dlev['carry_level'] = result.get('CarryLevel') d['grade'] = result.get('Grade') #d['weight'] = result.get('Weight') dlev['verdict'] = result.get('Verdict') #d['import_id'] = result.get('id') #gpa = result.get('GPA').replace(',','.') #d['gpa'] = float(gpa) ct.getContent().edit(mapping = d) l.getContent().edit(mapping = dlev) if tr_count > MAX_TRANS: transaction.commit() tr_count = 0 tr_count += 1 return self.students.academics_contents() ###) security.declareProtected(ModifyPortalContent,"loadJAMBFromCSV")###( def loadJAMBFromCSV(self): """load JAMB data from CSV values""" #return students_folder = self.portal_catalog({'meta_type': 'StudentsFolder'})[-1].getObject() import transaction tr_count = 0 name = 'SampleJAMBDataII' no_import = False if not no_import: no_import = open("%s/import/%s_not_imported.csv" % (i_home,name),"w") no_import.write('REG-NO,NAME,SEX,STATE,LGA,ENG-SCORE,SUBJ1,SUBJ1-SCORE,SUBJ2,SUBJ2-SCORE,SUBJ3,SUBJ3-SCORE,AGGREGATE,UNIV1,FACULTY1,COURSE1,UNIV2,FACULTY2,COURSE2') logger = logging.getLogger('%s_import' % name) logger.info('Start loading from %s.csv' % name) try: result = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb")) except: logger.error('Error reading %s.csv' % name) return for jamb in result: logger.info('processing %(REG-NO)s,%(NAME)s,%(SEX)s,%(STATE)s,%(LGA)s,%(ENG-SCORE)s,%(SUBJ1)s,%(SUBJ1-SCORE)s,%(SUBJ2)s,%(SUBJ2-SCORE)s,%(SUBJ3)s,%(SUBJ3-SCORE)s,%(AGGREGATE)s,%(UNIV1)s,%(FACULTY1)s,%(COURSE1)s,%(UNIV2)s,%(FACULTY2)s,%(COURSE2)s\n' % jamb) jamb_reg_no = jamb.get('REG-NO') res = self.portal_catalog({'meta_type': "StudentAdmission", 'jamb_reg_no': jamb_reg_no }) if res: em = 'Student with REG-NO %(REG-NO)s already exists\n' % jamb logger.info(em) no_import.write(em) no_import.write('%(REG-NO)s,%(NAME)s,%(SEX)s,%(STATE)s,%(LGA)s,%(ENG-SCORE)s,%(SUBJ1)s,%(SUBJ1-SCORE)s,%(SUBJ2)s,%(SUBJ2-SCORE)s,%(SUBJ3)s,%(SUBJ3-SCORE)s,%(AGGREGATE)s,%(UNIV1)s,%(FACULTY1)s,%(COURSE1)s,%(UNIV2)s,%(FACULTY2)s,%(COURSE2)s\n' % jamb) continue sid = generateStudentId() #self.log('Creating Faculty %(id)s = %(Title)s' % faculty) not_created = True while not_created: try: students_folder.invokeFactory('Student', sid) not_created = False except BadRequest: sid = generateStudentId() logger.info('%(tr_count)s: Creating Student with ID %(sid)s REG-NO %(jamb_reg_no)s ' % vars()) s = getattr(self,sid) s.invokeFactory('StudentAdmission','admission') da = {'Title': 'Admission Data'} ## s.invokeFactory('StudentPersonal','personal') ## sp = s.personal ## d = {'Title': 'Personal Data'} ## s.invokeFactory('StudentClearance','clearance') ## sc = s.clearance ## dc = {'Title': 'Clearance Data'} da["jamb_reg_no"] = jamb.get("REG-NO") da["jamb_lastname"] = jamb.get("NAME") ## d["lastname"] = jamb.get("NAME") da["jamb_sex"] = jamb.get("SEX") da["jamb_state"] = jamb.get("STATE") da["jamb_lga"] = jamb.get("LGA") da["jamb_score"] = jamb.get("AGGREGATE") da["jamb_first_cos"] = jamb.get("COURSE1") da["jamb_second_cos"] = jamb.get("COURSE2") da["jamb_first_uni"] = jamb.get("UNIV1") da["jamb_second_uni"] = jamb.get("UNIV2") ## s.personal.getContent().edit(mapping=d) s.admission.getContent().edit(mapping=da) return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1')) ###) security.declareProtected(View,"Title") def Title(self): """compose title""" return "Student Section" InitializeClass(StudentsFolder) def addStudentsFolder(container, id, REQUEST=None, **kw): """Add a Student.""" ob = StudentsFolder(id, **kw) return CPSBase_adder(container, ob, REQUEST=REQUEST) ###) class Student(CPSDocument): ###( """ WAeUP Student container for the various student data """ meta_type = 'Student' portal_type = meta_type security = ClassSecurityInfo() security.declareProtected(View,"Title") def Title(self): """compose title""" reg_nr = self.getId()[1:] data = getattr(self,'personal',None) if data: content = data.getContent() return "%s %s" % (content.firstname,content.lastname) data = getattr(self,'admission',None) if data: content = data.getContent() return "%s" % (content.jamb_lastname) return self.title InitializeClass(Student) def addStudent(container, id, REQUEST=None, **kw): """Add a Student.""" ob = Student(id, **kw) return CPSBase_adder(container, ob, REQUEST=REQUEST) ###) class StudentPersonal(CPSDocument): ###( """ WAeUP Student container for the various student data """ meta_type = 'StudentPersonal' portal_type = meta_type security = ClassSecurityInfo() security.declareProtected(View,"Title") def Title(self): """compose title""" content = self.getContent() #return "Personal Data for %s %s" % (content.firstname,content.lastname) return "Personal Data" InitializeClass(StudentPersonal) def addStudentPersonal(container, id, REQUEST=None, **kw): """Add a Students personal data.""" ob = StudentPersonal(id, **kw) return CPSBase_adder(container, ob, REQUEST=REQUEST) ###) class StudentClearance(CPSDocument): ###( """ WAeUP Student container for the various student data """ meta_type = 'StudentClearance' portal_type = meta_type security = ClassSecurityInfo() security.declareProtected(View,"Title") def Title(self): """compose title""" content = self.getContent() #return "Clearance Data for %s %s" % (content.firstname,content.lastname) return "Clearance Data" InitializeClass(StudentClearance) def addStudentClearance(container, id, REQUEST=None, **kw): """Add a Students personal data.""" ob = StudentClearance(id, **kw) return CPSBase_adder(container, ob, REQUEST=REQUEST) ###) class StudyLevel(CPSDocument): ###( """ WAeUP StudyLevel containing the courses and students """ meta_type = 'StudyLevel' portal_type = meta_type security = ClassSecurityInfo() security.declareProtected(View,"Title") def Title(self): """compose title""" return "Level %s" % self.aq_parent.getId() InitializeClass(StudyLevel) def addStudyLevel(container, id, REQUEST=None, **kw): """Add a StudyLevel.""" ob = StudyLevel(id, **kw) return CPSBase_adder(container, ob, REQUEST=REQUEST) ###) class StudentStudyLevel(CPSDocument): ###( """ WAeUP Student container for the various student data """ meta_type = 'StudentStudyLevel' portal_type = meta_type security = ClassSecurityInfo() security.declareProtected(View,"Title") def Title(self): """compose title""" return "Level %s" % self.aq_parent.getId() security.declareProtected(View,"gpa") def gpa(self): """calculate the gpa""" sum = 0 course_count = 0 for semester in ('first','second'): sf=getattr(self,semester) for sc in sf.objectValues(): result = sc.getContent() res = self.portal_catalog({'meta_type': 'Course', 'id': sc.aq_parent.id}) if len(res) != 1: continue course = res[0].getObject().getContent() sum += course.credits * ['F','E','D','C','B','A'].index(result.grade) course_count += 1 if course_count: return sum/course_count return 0.0 InitializeClass(StudentStudyLevel) def addStudentStudyLevel(container, id, REQUEST=None, **kw): """Add a Students personal data.""" ob = StudentStudyLevel(id, **kw) return CPSBase_adder(container, ob, REQUEST=REQUEST) ###) class StudentStudyCourse(CPSDocument): ###( """ WAeUP Student container for the various student data """ meta_type = 'StudentStudyCourse' portal_type = meta_type security = ClassSecurityInfo() security.declareProtected(View,"Title") def Title(self): """compose title""" content = self.getContent() return "Study Course" InitializeClass(StudentStudyCourse) def addStudentStudyCourse(container, id, REQUEST=None, **kw): """Add a Students personal data.""" ob = StudentStudyCourse(id, **kw) return CPSBase_adder(container, ob, REQUEST=REQUEST) ###) class StudentAdmission(CPSDocument): ###( """ WAeUP Student container for the various student data """ meta_type = 'StudentAdmission' portal_type = meta_type security = ClassSecurityInfo() security.declareProtected(View,"Title") def Title(self): """compose title""" return "Admission Data" InitializeClass(StudentAdmission) def addStudentAdmission(container, id, REQUEST=None, **kw): """Add a Students eligibility data.""" ob = StudentAdmission(id, **kw) return CPSBase_adder(container, ob, REQUEST=REQUEST) ###) class StudentSemester(CPSDocument): ###( """ WAeUP StudentSemester containing the courses and students """ meta_type = 'StudentSemester' portal_type = meta_type security = ClassSecurityInfo() InitializeClass(StudentSemester) def addStudentSemester(container, id, REQUEST=None, **kw): """Add a StudentSemester.""" ob = StudentSemester(id, **kw) return CPSBase_adder(container, ob, REQUEST=REQUEST) ###) class Semester(CPSDocument): ###( """ WAeUP Semester containing the courses and students """ meta_type = 'Semester' portal_type = meta_type security = ClassSecurityInfo() InitializeClass(Semester) def addSemester(container, id, REQUEST=None, **kw): """Add a Semester.""" ob = Semester(id, **kw) return CPSBase_adder(container, ob, REQUEST=REQUEST) ###) class StudentCourseResult(CPSDocument): ###( """ WAeUP StudentCourseResult """ meta_type = 'StudentCourseResult' portal_type = meta_type security = ClassSecurityInfo() def getCourseEntry(self,cid): res = self.portal_catalog({'meta_type': "StudentCourse", 'id': cid}) if res: return res[-1] else: return None security.declareProtected(View,"Title") def Title(self): """compose title""" cid = self.getId() ce = self.getCourseEntry(cid) if ce: return "%s" % ce.Title return "No course with id %s" % cid InitializeClass(StudentCourseResult) def addStudentCourseResult(container, id, REQUEST=None, **kw): """Add a StudentCourseResult.""" ob = StudentCourseResult(id, **kw) return CPSBase_adder(container, ob, REQUEST=REQUEST) ###) class ScratchCardBatchesFolder(CPSDocument): ###( """ WAeUP Student container for the various student data """ meta_type = 'ScratchCardBatchesFolder' portal_type = meta_type security = ClassSecurityInfo() security.declareProtected(View,"Title") def Title(self): """compose title""" return "Pin Batches" InitializeClass(ScratchCardBatchesFolder) def addScratchCardBatchesFolder(container, id, REQUEST=None, **kw): """Add a Students personal data.""" ob = ScratchCardBatchesFolder(id, **kw) return CPSBase_adder(container, ob, REQUEST=REQUEST) ###) from Products.WAeUP_SRP.WAeUPTables import PinTable class ScratchCardBatch(CPSDocument): ###( """ WAeUP Student container for the various student data """ meta_type = 'ScratchCardBatch' portal_type = meta_type security = ClassSecurityInfo() security.declareProtected(View,"Title") def Title(self): """compose title""" doc = self.getContent() return "Pin Batch %s BatchNo %d" % (doc.prefix, doc.batch_no) InitializeClass(ScratchCardBatch) def addScratchCardBatch(container, id, REQUEST=None, **kw): """Add a Students personal data.""" ob = ScratchCardBatch(id, **kw) return CPSBase_adder(container, ob, REQUEST=REQUEST) ###)