source: WAeUP_SRP/trunk/Students.py @ 3999

Last change on this file since 3999 was 3682, checked in by Henrik Bettermann, 16 years ago
  • Implement Student Pastoral Report for secondary schools
  • Property svn:keywords set to Id
File size: 35.7 KB
Line 
1#-*- mode: python; mode: fold -*-
2# $Id: Students.py 3682 2008-09-21 06:01:55Z henrik $
3from string import Template
4from Globals import InitializeClass
5from AccessControl import ClassSecurityInfo
6from AccessControl.SecurityManagement import newSecurityManager
7from zExceptions import BadRequest
8from Products.ZCatalog.ZCatalog import ZCatalog
9from Products.CMFCore.utils import UniqueObject, getToolByName
10from Products.CMFCore.permissions import View
11from Products.CMFCore.permissions import ModifyPortalContent
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
16from Products.CPSCore.CPSMembershipTool import CPSUnrestrictedUser
17from Products.WAeUP_SRP.Academics import makeCertificateCode
18
19from Products.AdvancedQuery import Eq, Between, Le,In
20import DateTime
21import logging
22import csv,re,os
23import Globals
24p_home = Globals.package_home(globals())
25i_home = Globals.INSTANCE_HOME
26MAX_TRANS = 1000
27from urllib import urlencode
28
29import DateTime
30#import PIL.Image
31from StringIO import StringIO
32
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
44def response_write(response,s): ###(
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
53###)
54
55def getInt(s): ###(
56    try:
57        return int(s)
58    except:
59        return 0
60
61def getFloat(s):
62    try:
63        return float(s)
64    except:
65        return 0.0
66
67###)
68
69def getStudentByRegNo(self,reg_no): ###(
70    """search student by JAMB Reg No and return StudentFolder"""
71    res = self.students_catalog(jamb_reg_no = reg_no.upper())
72    if len(res) == 1:
73        return getattr(self.portal_url.getPortalObject().campus.students,res[0].id)
74    else:
75        return None
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
83
84###)
85
86def checkJambNo(jnr): ###(
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
97
98###)
99
100def formatLGA(lga,voc=None):
101    if voc is not None:
102        if voc.has_key(lga):
103            state,lga = voc[lga].split(' / ')
104        elif lga.find(' / ') > -1:
105            state,lga = lga.split(' / ')
106        else:
107            state,lga = "",lga
108    return state.upper(),lga.upper()
109
110class StudentsFolder(CPSDocument): ###(
111    """
112    WAeUP container for the various WAeUP containers data
113    """
114    meta_type = 'StudentsFolder'
115    portal_type = meta_type
116    security = ClassSecurityInfo()
117
118
119    security.declareProtected(ModifyPortalContent,"transferStudents")###(
120    def transferStudents(self,filename):
121        """
122        load Interfaculty transferStudents Studentdata from CSV values.
123        """
124        import transaction
125        import random
126        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
127        pm = self.portal_membership
128        member = pm.getAuthenticatedMember()
129        logger = logging.getLogger('Students.StudentsFolder.transferStudents')
130        #students_folder = self.portal_catalog({'meta_type': 'StudentsFolder'})[-1].getObject()
131        students_folder = self.portal_url.getPortalObject().campus.students
132        csv_fields = ('old_matric_no',
133                      'matric_no',
134                      'study_course',
135                      'current_mode',
136                      'current_level',
137                      )
138        tr_count = 0
139        total = 0
140        total_imported = 0
141        total_not_imported = 0
142        imported = []
143        not_imported = []
144        certs = {}
145        try:
146            results = csv.DictReader(open("%s/import/%s.csv" % (i_home,filename),"rb"))
147        except:
148            logger.error('Error reading %s.csv' % filename)
149            return
150        start = True
151        for result in results:
152            total += 1
153            if start:
154                start = False
155                logger.info('%s starts import from %s.csv' % (member,filename))
156                import_keys = [k for k in result.keys() if not k.startswith('ignore')]
157                diff2schema = set(import_keys).difference(set(csv_fields))
158                if diff2schema:
159                    em = "not ignorable key(s) %s found in heading" % diff2schema
160                    return em
161                s = ','.join(['"%s"' % fn for fn in import_keys])
162                open("%s/import/%s_not_imported%s.csv" % (i_home,filename,current),"a").write(s + ',"Error"'+ '\n')
163                s = '"id",' + s
164                open("%s/import/%s_imported%s.csv" % (i_home,filename,current),"a").write(s + '\n')
165                format = ','.join(['"%%(%s)s"' % fn for fn in import_keys])
166                format_error = format + ',"%(Error)s"'
167                format = '"%(id)s",'+ format
168            old_matric_no = result.get('old_matric_no')
169            res = self.students_catalog(matric_no = old_matric_no)
170            result['id'] = "None"
171            if not res:
172                em = 'Student with matric_no %s not found' % old_matric_no
173                logger.info(em)
174                result['Error'] = "Student does not exist"
175                not_imported.append(format_error % result)
176                total_not_imported += 1
177                continue
178            student_record = res[0]
179            if getattr(student_record,'review_state','') in ('courses_registered','courses_validated'):
180                em = 'already registered course list'
181                logger.info('%s (%s) %s' % (student_record.id, old_matric_no, em))
182                result['Error'] = em
183                not_imported.append( format_error % result)
184                total_not_imported += 1
185                continue
186            student_object = getattr(students_folder,student_record.id)
187            result['id'] = student_record.id
188            cert_id = makeCertificateCode(result.get('study_course'))
189            if cert_id not in certs.keys():
190                res = self.portal_catalog(meta_type = "Certificate",id = cert_id)
191                if not res:
192                    em = 'No certificate with ID %s \n' % cert_id
193                    logger.info(em)
194                    result['Error'] = "No Certificate %s" % cert_id
195                    not_imported.append( format_error % result)
196                    total_not_imported += 1
197                    continue
198                cert = res[0]
199                cert_path = cert.getPath().split('/')
200                certificate = certs[cert_id] = {'faculty': cert_path[-4],
201                                     'department': cert_path[-3]}
202            cert_doc = certs[cert_id]
203            clearance = getattr(student_object,'clearance',None)
204            if clearance is None:
205                em = 'Student has no clearance object'
206                logger.info('%s (%s) %s' % (student_record.id, old_matric_no, em))
207                result['Error'] = em
208                not_imported.append( format_error % result)
209                total_not_imported += 1
210                continue
211            clearance_doc = clearance.getContent()
212            study_course = student_object.study_course
213            study_course_doc = study_course.getContent()
214            old_study_course = study_course_doc.study_course
215            old_current_level = study_course_doc.current_level
216            current_level = result.get('current_level',None)
217            new_study_course = result.get('study_course',None)
218            try:
219                icl = int(current_level)
220            except:
221                em = 'Invalid new level %s' % current_level
222                logger.info(em)
223                result['Error'] = em
224                not_imported.append( format_error % result)
225                total_not_imported += 1
226                continue
227            try:
228                icl = int(old_current_level)
229                if icl == int(old_current_level) and old_study_course == new_study_course:
230                    em = 'Already transferred'
231                    logger.info('%s (%s) %s' % (student_record.id, old_matric_no, em))
232                    result['Error'] = em
233                    not_imported.append( format_error % result)
234                    total_not_imported += 1
235                    continue
236            except:
237                pass
238
239            #from pdb import set_trace; set_trace()
240            cd = {}
241            matric_no_history = getattr(clearance_doc,'matric_no_history',[])
242            if not matric_no_history:
243                matric_no_history = []
244            matric_no_history.append(old_matric_no)
245            cd['matric_no_history'] = matric_no_history
246            cd['matric_no'] = result.get('matric_no')
247            clearance_doc.edit(mapping = cd)
248            dsc = {}
249            study_course_history = getattr(study_course_doc,'study_course_history',[])
250            if not study_course_history:
251                study_course_history = []
252            study_course_history.append(old_study_course)
253            dsc['study_course_history'] = study_course_history
254            dsc['study_course'] = new_study_course
255            dsc['current_level'] = current_level
256            dsc['current_mode'] = result.get('current_mode')
257            study_course_doc.edit(mapping=dsc)
258            imported.append( format % result)
259            tr_count += 1
260            total_imported += 1
261            if tr_count > 1000:
262                if len(not_imported) > 0:
263                    open("%s/import/%s_not_imported%s.csv" % (i_home,filename,current),"a").write(
264                             '\n'.join(not_imported) + '\n')
265                    not_imported = []
266                if len(imported) > 0:
267                    open("%s/import/%s_imported%s.csv" % (i_home,filename,current),"a").write(
268                             '\n'.join(imported) + '\n')
269                    imported = []
270                em = '%d transactions committed\n' % (tr_count)
271                transaction.commit()
272                regs = []
273                logger.info(em)
274                tr_count = 0
275        if len(imported) > 0:
276            open("%s/import/%s_imported%s.csv" % (i_home,filename,current),"a").write(
277                                                '\n'.join(imported))
278        if len(not_imported) > 0:
279            open("%s/import/%s_not_imported%s.csv" % (i_home,filename,current),"a").write(
280                                                '\n'.join(not_imported))
281        em = "Imported: %d, not imported: %d of total %d" % (total_imported,total_not_imported,total)
282        logger.info(em)
283        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
284    ###)
285
286    security.declareProtected(ModifyPortalContent,"exportStudents")###(
287    def exportStudents(self):
288        """export Studentsdata to a file"""
289        member = self.portal_membership.getAuthenticatedMember()
290        logger = logging.getLogger('Students.exportStudents')
291        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
292        students_folder = self.portal_url.getPortalObject().campus.students
293        export_file = "%s/export/students_%s.csv" % (i_home,current)
294
295        from Products.AdvancedQuery import Eq, Between, Le,In,MatchRegexp
296        #aq_students = self.students_catalog.evalAdvancedQuery
297        toexport = {'students_catalog': ("id",
298                                         "matric_no",
299                                         "jamb_reg_no",
300                                         "name",
301                                         #"review_state",
302                                         #"entry_session",
303                                         #"session",
304                                         #"entry_mode",
305                                         #"mode",
306                                         #"verdict",
307                                         #"sex",
308                                         #"email",
309                                         #"phone",
310                                         #"faculty",
311                                         #"department",
312                                         #"course",
313                                         #"level",
314                                        ),
315                    #'personal': ('firstname',
316                    #             'middlename',
317                    #             'lastname',
318                    #             'perm_address',
319                    #             ),
320                    'clearance': (#'state',  # is not an attribute of clearance but is needed for splitting lga
321                                  #'lga',
322                                  'birthday',
323                                 )
324                  }
325        res_list = []
326        lines = []
327        fields = []
328        with_lga = False
329        for k in toexport.keys():
330            for f in toexport[k]:
331                if f == 'lga' :
332                    with_lga = True
333                fields.append(f)
334        headline = ','.join(fields).replace('level','current_level')
335        open(export_file,"a").write(headline +'\n')
336        format = '"%(' + ')s","%('.join(fields) + ')s"'
337        #query = In('review_state',('cleared_and_validated',
338        #                        'clearance_requested',
339        #                        'school_fee_paid',
340        #                        'courses_registered',
341        #                        'courses_validated'))
342        #query = In('review_state',('clearance_requested'))
343        #students = aq_students(query)
344        students = self.students_catalog()
345        nr2export = len(students)
346        logger.info('%s starts exportStudents, %s student records to export' % (member,nr2export))
347        chunk = 1000
348        total = 0
349        start = DateTime.DateTime().timeTime()
350        start_chunk = DateTime.DateTime().timeTime()
351        for student in students:
352            not_all = False
353            d = self.getFormattedStudentEntry(student)
354            student_obj = getattr(students_folder,student.id)
355            for k in toexport.keys()[1:]:
356                try:
357                    object = getattr(student_obj,k)
358                    object_doc = object.getContent()
359                except:
360                    logger.info('%s %s record not found' % (student.id,k))
361                    not_all = True
362                    continue
363                for f in toexport[k]:
364                    d[f] = getattr(object_doc,f,'')
365            if not_all:
366                continue
367            if with_lga:
368                d['state'],d['lga'] = formatLGA(d['lga'],voc = self.portal_vocabularies.local_gov_areas)
369            lines.append(format % d)
370            total += 1
371            if total and not total % chunk or total == len(students):
372                open(export_file,"a").write('\n'.join(lines) +'\n')
373                anz = len(lines)
374                logger.info("wrote %(anz)d  total written %(total)d" % vars())
375                end_chunk = DateTime.DateTime().timeTime()
376                duration = end_chunk-start_chunk
377                per_record = duration/anz
378                till_now = end_chunk - start
379                avarage_per_record = till_now/total
380                estimated_end = DateTime.DateTime(start + avarage_per_record * nr2export)
381                estimated_end = estimated_end.strftime("%H:%M:%S")
382                logger.info('%(duration)4.1f, %(per_record)4.3f,end %(estimated_end)s' % vars())
383                start_chunk = DateTime.DateTime().timeTime()
384                lines = []
385        end = DateTime.DateTime().timeTime()
386        logger.info('total time %6.2f m' % ((end-start)/60))
387        filename, extension = os.path.splitext(export_file)
388        from subprocess import call
389        msg = "wrote %(total)d records to %(export_file)s" % vars()
390        try:
391            retcode = call('gzip %s' % (export_file),shell=True)
392            if retcode == 0:
393                msg = "wrote %(total)d records to %(export_file)s.gz" % vars()
394        except OSError, e:
395            retcode = -99
396            logger.info("zip failed with %s" % e)
397        logger.info(msg)
398        args = {'portal_status_message': msg}
399        url = self.REQUEST.get('URL2')
400        return self.REQUEST.RESPONSE.redirect(url)
401    ###)
402
403    security.declareProtected(ModifyPortalContent,"dumpStudentsCatalog")###(
404    def dumpStudentsCatalog(self):
405        """dump all data in students_catalog to a csv"""
406        member = self.portal_membership.getAuthenticatedMember()
407        logger = logging.getLogger('Students.dumpStudentsCatalog')
408        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
409        export_file = "%s/export/students_catalog_%s.csv" % (i_home,current)
410        res_list = []
411        lines = []
412        fields = []
413        for f in self.students_catalog.schema():
414            fields.append(f)
415        fields.append('state')
416        headline = ','.join(fields)
417        #open(export_file,"a").write(headline +'\n')
418        out = open(export_file,"wb")
419        out.write(headline +'\n')
420        out.close()
421        out = open(export_file,"a")
422        csv_writer = csv.DictWriter(out,fields,)
423        format = '"%(' + ')s","%('.join(fields) + ')s"'
424        students = self.students_catalog()
425        nr2export = len(students)
426        logger.info('%s starts dumpStudentsCatalog, %s student records to export' % (member,nr2export))
427        chunk = 2000
428        total = 0
429        start = DateTime.DateTime().timeTime()
430        start_chunk = DateTime.DateTime().timeTime()
431        for student in students:
432            not_all = False
433            d = self.getFormattedStudentEntry(student)
434            d['state'],d['lga'] = formatLGA(d['lga'],voc = self.portal_vocabularies.local_gov_areas)
435            #lines.append(format % d)
436            lines.append(d)
437            total += 1
438            if total and not total % chunk or total == len(students):
439                #open(export_file,"a").write('\n'.join(lines) +'\n')
440                csv_writer.writerows(lines)
441                anz = len(lines)
442                logger.info("wrote %(anz)d  total written %(total)d" % vars())
443                end_chunk = DateTime.DateTime().timeTime()
444                duration = end_chunk-start_chunk
445                per_record = duration/anz
446                till_now = end_chunk - start
447                avarage_per_record = till_now/total
448                estimated_end = DateTime.DateTime(start + avarage_per_record * nr2export)
449                estimated_end = estimated_end.strftime("%H:%M:%S")
450                logger.info('%(duration)4.1f, %(per_record)4.3f,end %(estimated_end)s' % vars())
451                start_chunk = DateTime.DateTime().timeTime()
452                lines = []
453        end = DateTime.DateTime().timeTime()
454        logger.info('total time %6.2f m' % ((end-start)/60))
455        filename, extension = os.path.splitext(export_file)
456        from subprocess import call
457        msg = "wrote %(total)d records to %(export_file)s" % vars()
458        try:
459            retcode = call('gzip %s' % (export_file),shell=True)
460            if retcode == 0:
461                msg = "wrote %(total)d records to %(export_file)s.gz" % vars()
462        except OSError, e:
463            retcode = -99
464            logger.info("zip failed with %s" % e)
465        logger.info(msg)
466        args = {'portal_status_message': msg}
467        #url = self.REQUEST.get('URL1') + '?' + urlencode(args)
468        url = self.REQUEST.get('URL2')
469        return self.REQUEST.RESPONSE.redirect(url)
470    ###)
471
472
473    security.declareProtected(ModifyPortalContent,"importResults")###(
474    def importResults(self):
475        """load Returning Students Results from CSV"""
476        import transaction
477        import random
478        #from pdb import set_trace
479        wftool = self.portal_workflow
480        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
481        #students_folder = self.portal_catalog({'meta_type': 'StudentsFolder'})[-1].getObject()
482        students_folder = self.portal_url.getPortalObject().campus.students
483        tr_count = 1
484        total = 0
485        #name = 'pume_results'
486        name = 'Results'
487        table = self.results_import
488        no_import = []
489        imported = []
490        logger = logging.getLogger('Students.StudentsFolder.importResults')
491        try:
492            results = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
493        except:
494            logger.error('Error reading %s.csv' % name)
495            return
496
497        l = self.portal_catalog({'meta_type': "Course"})
498        courses = [f.getId for f in l]
499        start = True
500        res = table()
501        regs = []
502        if len(res) > 0:
503            regs = [s.key for s in res]
504        no_course = []
505        no_course_list = []
506        course_count = 0
507        for result in results:
508            if start:
509                start = False
510                logger.info('Start loading from %s.csv' % name)
511                s = ','.join(['"%s"' % fn for fn in result.keys()])
512                imported.append(s)
513                no_import.append('%s,"Error"' % s)
514                format = ','.join(['"%%(%s)s"' % fn for fn in result.keys()])
515                format_error = format + ',"%(Error)s"'
516                no_certificate = "no certificate %s" % format
517            course_id = result.get('CosCode')
518            if not course_id:
519                course_id = 'N/A'
520                result['CosCode'] = course_id
521            matric_no = result.get('matric_no').upper()
522            result['matric_no'] = matric_no
523            key = matric_no+course_id
524            if matric_no == '':
525                result['Error'] = "Empty matric_no"
526                no_import.append( format_error % result)
527                continue
528            if key in regs or self.results_import(key = key):
529                result['Error'] = "Duplicate"
530                no_import.append( format_error % result)
531                continue
532            if course_id not in courses:
533                if course_id not in no_course:
534                    course_count +=1
535                    no_course.append(course_id)
536                    no_course_list.append('"%s"' % course_id)
537                    #result['Error'] = "No Course"
538                    #logger.info(format_error % result)
539
540            result['key'] = key
541            try:
542                table.addRecord(**result)
543            except ValueError:
544                #import pdb;pdb.set_trace()
545                result['Error'] = "Duplicate"
546                no_import.append( format_error % result)
547                continue
548
549            regs.append(key)
550            imported.append(format % result)
551            tr_count += 1
552            if tr_count > 1000:
553                if len(no_import) > 0:
554                    open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
555                             '\n'.join(no_import)+'\n')
556                    no_import = []
557                open("%s/import/%simported%s.csv" % (i_home,name,current),"a").write(
558                                            '\n'.join(imported) + '\n')
559                imported = []
560                if no_course_list:
561                    open("%s/import/%sno_courses%s.csv" % (i_home,name,current),"a").write(
562                                            '\n'.join(no_course_list) + '\n')
563                    no_course_list = []
564                transaction.commit()
565                regs = []
566                total += tr_count
567                em = '%d transactions totally comitted, %s courses not found ' % (total,course_count)
568                logger.info(em)
569                tr_count = 0
570        open("%s/import/%simported%s.csv" % (i_home,name,current),"a").write(
571                                            '\n'.join(imported))
572        open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
573                                                '\n'.join(no_import))
574        if no_course_list:
575            open("%s/import/%sno_courses%s.csv" % (i_home,name,current),"a").write(
576                                    '\n'.join(no_course_list))
577        em = '%d transactions totally committed, %s courses not found ' % (total,course_count)
578        logger.info(em)
579        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
580    ###)
581
582
583
584    security.declareProtected(View,"fixOwnership") ###(
585    def fixOwnership(self):
586        """fix Ownership"""
587        for s in self.portal_catalog(meta_type = 'Student'):
588            student = s.getObject()
589            sid = s.getId
590            import pdb;pdb.set_trace()
591            student.application.manage_setLocalRoles(sid, ['Owner',])
592            student.personal.manage_setLocalRoles(sid, ['Owner',])
593    ###)
594
595    security.declareProtected(View,"Title") ###(
596    def Title(self):
597        """compose title"""
598        return "Student Section"
599    ###)
600
601    def generateStudentId(self,letter,students = None): ###(
602        import random
603        r = random
604        if students is None:
605            students = self.portal_url.getPortalObject().campus.students
606        if letter not in ('ABCDEFGIHKLMNOPQRSTUVWXY'):
607            letter= r.choice('ABCDEFGHKLMNPQRSTUVWXY')
608        sid = "%c%d" % (letter,r.randint(99999,1000000))
609        while hasattr(students, sid):
610            sid = "%c%d" % (letter,r.randint(99999,1000000))
611        return sid
612        #return "%c%d" % (r.choice('ABCDEFGHKLMNPQRSTUVWXY'),r.randint(99999,1000000))
613    ###)
614
615InitializeClass(StudentsFolder)
616
617def addStudentsFolder(container, id, REQUEST=None, **kw): ###(
618    """Add a Student."""
619    ob = StudentsFolder(id, **kw)
620    return CPSBase_adder(container, ob, REQUEST=REQUEST)
621    ###)
622
623###)
624
625class Student(CPSDocument): ###(
626    """
627    WAeUP Student container for the various student data
628    """
629    meta_type = 'Student'
630    portal_type = meta_type
631    security = ClassSecurityInfo()
632
633    # security.declareProtected(View,"Title")
634    # def Title(self):
635    #     """compose title"""
636    #     reg_nr = self.getId()[1:]
637    #     data = getattr(self,'personal',None)
638    #     if data:
639    #         content = data.getContent()
640    #         return "%s %s %s" % (content.firstname,content.middlename,content.lastname)
641    #     data = getattr(self,'application',None)
642    #     if data:
643    #         content = data.getContent()
644    #         return "%s" % (content.jamb_lastname)
645    #     return self.title
646
647    security.declarePrivate('makeStudentMember') ###(
648    def makeStudentMember(self,sid,password='uNsEt'):
649        """make the student a member"""
650        membership = self.portal_membership
651        membership.addMember(sid,
652                             password ,
653                             roles=('Member',
654                                     'Student',
655                                     ),
656                             domains='',
657                             properties = {'memberareaCreationFlag': False,
658                                           'homeless': True},)
659        member = membership.getMemberById(sid)
660        self.portal_registration.afterAdd(member, sid, password, None)
661        self.manage_setLocalRoles(sid, ['Owner',])
662
663###)
664
665    security.declareProtected(View,'createSubObjects') ###(
666    def createSubObjects(self):
667        """make the student a member"""
668        #dp = {'Title': 'Personal Data'}
669        app_doc = self.application.getContent()
670        names = app_doc.jamb_lastname.split()
671        if len(names) == 3:
672            dp['firstname'] = names[0].capitalize()
673            dp['middlename'] = names[1].capitalize()
674            dp['lastname'] = names[2].capitalize()
675        elif len(names) == 2:
676            dp['firstname'] = names[0].capitalize()
677            dp['lastname'] = names[1].capitalize()
678        else:
679            dp['lastname'] = app_doc.jamb_lastname
680        dp['sex'] = app_doc.jamb_sex == 'F'
681        dp['lga'] = "%s/%s" % (app_doc.jamb_state,app_doc.jamb_lga )
682        proxy = self.aq_parent
683        proxy.invokeFactory('StudentPersonal','personal')
684        per = proxy.personal
685        per_doc = per.getContent()
686        per_doc.edit(mapping = dp)
687        per.manage_setLocalRoles(proxy.getId(), ['Owner',])
688        #self.portal_workflow.doActionFor(per,'open',dest_container=per)
689
690###)
691
692InitializeClass(Student)
693
694def addStudent(container, id, REQUEST=None, **kw):
695    """Add a Student."""
696    ob = Student(id, **kw)
697    return CPSBase_adder(container, ob, REQUEST=REQUEST)
698
699###)
700
701class StudentAccommodation(CPSDocument): ###(
702    """
703    WAeUP Student container for the various student data
704    """
705    meta_type = 'StudentAccommodation'
706    portal_type = meta_type
707    security = ClassSecurityInfo()
708
709    # security.declareProtected(View,"Title")
710    # def Title(self):
711    #     """compose title"""
712    #     content = self.getContent()
713    #     session_id = content.session
714    #     try:
715    #         y = int(session_id[-2:])
716    #     except:
717    #         return "Accommodation Data for Session %s" % session_id
718    #     session_str = self.portal_vocabularies.sessions.get(y)
719    #     #return "Accommodation Data for %s %s" % (content.firstname,content.lastname)
720    #     return "Accommodation Data for Session %s" % session_str
721
722
723InitializeClass(StudentAccommodation)
724
725def addStudentAccommodation(container, id, REQUEST=None, **kw):
726    """Add a Students personal data."""
727    ob = StudentAccommodation(id, **kw)
728    return CPSBase_adder(container, ob, REQUEST=REQUEST)
729
730###)
731
732class StudentPersonal(CPSDocument): ###(
733    """
734    WAeUP Student container for the various student data
735    """
736    meta_type = 'StudentPersonal'
737    portal_type = meta_type
738    security = ClassSecurityInfo()
739
740    # security.declareProtected(View,"Title")
741    # def Title(self):
742    #     """compose title"""
743    #     #content = self.getContent()
744    #     #return "Personal Data for %s %s" % (content.firstname,content.lastname)
745    #     return "Personal Data"
746
747
748InitializeClass(StudentPersonal)
749
750def addStudentPersonal(container, id, REQUEST=None, **kw):
751    """Add a Students personal data."""
752    ob = StudentPersonal(id, **kw)
753    return CPSBase_adder(container, ob, REQUEST=REQUEST)
754
755###)
756
757class StudentClearance(CPSDocument): ###(
758    """
759    WAeUP Student container for the various student data
760    """
761    meta_type = 'StudentClearance'
762    portal_type = meta_type
763    security = ClassSecurityInfo()
764
765    # security.declareProtected(View,"Title")
766    # def Title(self):
767    #     """compose title"""
768    #     #content = self.getContent()
769    #     #return "Clearance/Eligibility Record for %s %s" % (content.firstname,content.lastname)
770    #     return "Clearance/Eligibility Record"
771
772
773InitializeClass(StudentClearance)
774
775def addStudentClearance(container, id, REQUEST=None, **kw):
776    """Add a Students personal data."""
777    ob = StudentClearance(id, **kw)
778    return CPSBase_adder(container, ob, REQUEST=REQUEST)
779
780###)
781
782class StudentStudyLevel(CPSDocument): ###(
783    """
784    WAeUP Student container for the various student data
785    """
786    meta_type = 'StudentStudyLevel'
787    portal_type = meta_type
788    security = ClassSecurityInfo()
789
790    # security.declareProtected(View,"Title")
791    # def Title(self):
792    #     """compose title"""
793    #     return self.portal_vocabularies.student_levels.get(self.aq_parent.getId())
794    #     #return "Level %s" % self.aq_parent.getId()
795
796    def create_course_results(self,cert_id,current_level): ###(
797        "create all courses in a level"
798        aq_portal = self.portal_catalog.evalAdvancedQuery
799        res = self.portal_catalog(portal_type="Certificate", id = cert_id)
800        l = []
801        import transaction
802        if res:
803            cert = res[0]
804            path = cert.getPath()
805            query = Eq("path","%s/%s" % (path,current_level)) &\
806                    Eq('portal_type','CertificateCourse')
807            courses = aq_portal(query)
808            #from pdb import set_trace;set_trace()
809            self_proxy = self.aq_parent
810            for c in courses:
811                d = self.getCourseInfo(c.getId)
812                cr_id = self_proxy.invokeFactory('StudentCourseResult',c.getId)
813                course_result = getattr(self_proxy,cr_id)
814                self.portal_workflow.doActionFor(course_result,'open')
815                d['core_or_elective'] = getattr(c.getObject().getContent(),'core_or_elective')
816                course_result.getContent().edit(mapping=d)
817                #transaction.commit()
818    ###)
819
820InitializeClass(StudentStudyLevel)
821
822def addStudentStudyLevel(container, id, REQUEST=None, **kw):
823    """Add a Students personal data."""
824    ob = StudentStudyLevel(id, **kw)
825    return CPSBase_adder(container, ob, REQUEST=REQUEST)
826
827###)
828
829class StudentStudyCourse(CPSDocument): ###(
830    """
831    WAeUP Student container for the various student data
832    """
833    meta_type = 'StudentStudyCourse'
834    portal_type = meta_type
835    security = ClassSecurityInfo()
836
837    # security.declareProtected(View,"Title")
838    # def Title(self):
839    #     """compose title"""
840    #     #content = self.getContent()
841    #     return "Study Course"
842
843
844InitializeClass(StudentStudyCourse)
845
846def addStudentStudyCourse(container, id, REQUEST=None, **kw):
847    """Add a Students personal data."""
848    ob = StudentStudyCourse(id, **kw)
849    return CPSBase_adder(container, ob, REQUEST=REQUEST)
850
851###)
852
853class StudentApplication(CPSDocument): ###(
854    """
855    WAeUP Student container for the various student data
856    """
857    meta_type = 'StudentApplication'
858    portal_type = meta_type
859    security = ClassSecurityInfo()
860
861    # security.declareProtected(View,"Title")
862    # def Title(self):
863    #     """compose title"""
864    #     return "Application Data"
865
866
867InitializeClass(StudentApplication)
868
869def addStudentApplication(container, id, REQUEST=None, **kw):
870    """Add a Students eligibility data."""
871    ob = StudentApplication(id, **kw)
872    return CPSBase_adder(container, ob, REQUEST=REQUEST)
873###)
874
875
876class StudentCourseResult(CPSDocument): ###(
877    """
878    WAeUP StudentCourseResult
879    """
880    meta_type = 'StudentCourseResult'
881    portal_type = meta_type
882    security = ClassSecurityInfo()
883
884    def getCourseEntry(self,cid):
885        res = self.portal_catalog({'meta_type': "Course",
886                                           'id': cid})
887        if res:
888            return res[-1]
889        else:
890            return None
891
892    # security.declareProtected(View,"Title")
893    # def Title(self):
894    #     """compose title"""
895    #     cid = self.aq_parent.getId()
896    #     ce = self.getCourseEntry(cid)
897    #     if ce:
898    #         return "%s" % ce.Title
899    #     return "No course with id %s" % cid
900
901InitializeClass(StudentCourseResult)
902
903def addStudentCourseResult(container, id, REQUEST=None, **kw):
904    """Add a StudentCourseResult."""
905    ob = StudentCourseResult(id, **kw)
906    return CPSBase_adder(container, ob, REQUEST=REQUEST)
907###)
908
909
910class StudentPume(CPSDocument): ###(
911    """
912    WAeUP Student container for the various student data
913    """
914    meta_type = 'StudentPume'
915    portal_type = meta_type
916    security = ClassSecurityInfo()
917
918    # security.declareProtected(View,"Title")
919    # def Title(self):
920    #     """compose title"""
921    #     return "PUME Results"
922
923
924InitializeClass(StudentPume)
925
926def addStudentPume(container, id, REQUEST=None, **kw):
927    """Add a Students PUME data."""
928    ob = StudentPume(id, **kw)
929    return CPSBase_adder(container, ob, REQUEST=REQUEST)
930###)
931
932
933class StudentPastoralReport(CPSDocument): ###(
934    """
935    Student Pastoral Report
936    """
937    meta_type = 'StudentPastoralReport'
938    portal_type = meta_type
939    security = ClassSecurityInfo()
940
941InitializeClass(StudentPastoralReport)
942
943def addStudentPastoralReport(container, id, REQUEST=None, **kw):
944    """Add a Student Pastoral Report."""
945    ob = StudentPastoralReport(id, **kw)
946    return CPSBase_adder(container, ob, REQUEST=REQUEST)
947###)
948
949# Backward Compatibility StudyLevel
950
951from Products.WAeUP_SRP.Academics import StudyLevel
952
953from Products.WAeUP_SRP.Academics import addStudyLevel
954
Note: See TracBrowser for help on using the repository browser.