source: WAeUP_SRP/trunk/WAeUPImport.py @ 3822

Last change on this file since 3822 was 3822, checked in by Henrik Bettermann, 16 years ago

add student remove method

  • Property svn:keywords set to Id
File size: 61.6 KB
Line 
1#-*- mode: python; mode: fold -*-
2# (C) Copyright 2005 The WAeUP group  <http://www.waeup.org>
3# Author: Joachim Schmitz (js@aixtraware.de)
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License version 2 as published
7# by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program; if not, write to the Free Software
16# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17# 02111-1307, USA.
18#
19# $Id: WAeUPImport.py 3822 2008-12-17 22:19:08Z henrik $
20"""The WAeUP Tool Box.
21"""
22
23#from AccessControl import ClassSecurityInfo
24#from Acquisition import aq_inner
25#from Acquisition import aq_parent
26#from Globals import DTMLFile
27#from Globals import InitializeClass
28from OFS.SimpleItem import SimpleItem
29from zExceptions import BadRequest
30
31#from Products.CMFCore.utils import getToolByName
32#from Products.CPSSchemas.DataStructure import DataStructure
33#from Products.CPSSchemas.DataModel import DataModel
34#from Products.CPSSchemas.StorageAdapter import MappingStorageAdapter
35from Products.CMFCore.ActionProviderBase import ActionProviderBase
36#from Products.CMFCore.permissions import View
37#from Products.ZCatalog.ZCatalog import ZCatalog
38#from Products.CMFCore.permissions import ModifyPortalContent
39#from Products.CMFCore.permissions import ManagePortal
40from Products.CMFCore.utils import UniqueObject
41#from Products.CMFCore.URLTool import URLTool
42from Products.CMFCore.utils import getToolByName
43from Globals import package_home,INSTANCE_HOME
44from Products.AdvancedQuery import Eq, Between, Le,In
45import csv,re,os,sys
46from shutil import copy2
47import DateTime,time
48import logging
49p_home = package_home(globals())
50i_home = INSTANCE_HOME
51from utils import makeDigest
52
53NO_KEY = '----'
54IGNORE = 'ignore'
55class WAeUPImport(UniqueObject, SimpleItem, ActionProviderBase): ###(
56    """ WAeUPImport """
57    required_modes = ('create',)
58
59    def __init__(self,waeup_tool): ###(
60        self.students_folder = waeup_tool.portal_url.getPortalObject().campus.students
61        self.member = member = waeup_tool.portal_membership.getAuthenticatedMember()
62        self.import_date = DateTime.DateTime()
63        self.imported_by = str(member)
64        #self.current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
65        self.waeup_tool = waeup_tool
66        self.academics_folder = waeup_tool.portal_url.getPortalObject().campus.academics
67        self.schema_tool = getToolByName(waeup_tool, 'portal_schemas')
68        self.layout_tool = getToolByName(waeup_tool, 'portal_layouts')
69        self.portal_workflow = getToolByName(waeup_tool, 'portal_workflow')
70        self.portal_url = getToolByName(waeup_tool, 'portal_url')
71        self.portal_catalog = waeup_tool.portal_catalog
72        self.portal_directories = waeup_tool.portal_directories
73        self.students_catalog = waeup_tool.students_catalog
74        self.courses_catalog = waeup_tool.courses_catalog
75        self.course_results = waeup_tool.course_results
76        self.applicants_catalog = waeup_tool.applicants_catalog
77        #self.mode = mode
78        # self.import_method = getattr(self, '%s' % mode,None)
79        errors = []
80        # if self.import_method is None:
81        #     errors.append('No importer method %s' % mode)
82        self.pending_path = "%s/import/%s.pending" % (i_home,self.plural_name)
83        self.pending_tmp = "%s/import/%s.pending.tmp" % (i_home,self.plural_name)
84        self.pending_backup = "%s/import/%s.pending.old" % (i_home,self.plural_name)
85        self.pending_fn = os.path.split(self.pending_path)[1]
86        self.imported_path = "%s/import/%s.imported" % (i_home,self.plural_name)
87        self.imported_fn = os.path.split(self.imported_path)[1]
88        iname = "import_%s" % self.name
89        self.logger = logging.getLogger('WAeUPImport.%sImport' % self.plural_name.capitalize())
90        self.schema = self.schema_tool._getOb(iname,None)
91        #self.pending_schema = self.schema_tool._getOb("%s_pending" % iname,None)
92        self.layout = self.layout_tool._getOb(iname,None)
93        while True:
94            if self.schema is None:
95                errors.append('no schema %s' % iname)
96            # if self.pending_schema is None:
97            #     self.pending_schema = self.schema
98            if self.layout is None:
99                errors.append('no such layout %s' % iname)
100            if errors:
101                break
102            self.data_keys = self.schema.keys()
103            self.csv_keys = self.schema.keys()
104            info = {}
105            info['imported_from'] = ''
106            info['import_record_no'] = 0
107            info['imported_by'] = self.imported_by
108            info['import_date'] = self.import_date.strftime("%d/%m/%y %H:%M:%S")
109            info['error'] = ''
110            self.info = info
111            self.csv_keys.extend(self.info)
112            self.validators = {}
113            for widget in self.layout.keys():
114                self.validators[widget] = self.layout[widget].validate
115            self.required_keys = {}
116            for mode in self.required_modes:
117                self.required_keys[mode] = [self.layout.getIdUnprefixed(id)
118                                    for id,widget in self.layout.objectItems()
119                                    if widget.is_required]
120            break
121        self.init_errors = ','.join(errors)
122    ###)
123
124    def findStudent(self,mode,student_id=None, matric_no=None, jamb_reg_no=None): ###(
125        student_record = None
126        msg = ''
127        key_used = ''
128        while True:
129            if student_id:
130                key_used = 'student_id'
131                res = self.students_catalog(id = student_id)
132                if not res:
133                    msg = "no student with id %s" % student_id
134                    break
135                student_record = res[0]
136                if matric_no and student_record.matric_no:
137                    if  matric_no != student_record.matric_no:
138                        msg = "old matric_no %s overwritten with %s" % (student_record.matric_no,matric_no)
139                        #logger.info("%s, old matric_no %s overwritten with %s" % (student_record.id,student_record.matric_no,matric_no))
140                if jamb_reg_no and student_record.jamb_reg_no:
141                    if jamb_reg_no != student_record.jamb_reg_no:
142                        msg = "old reg_no %s overwritten with %s" % (student_record.jamb_reg_no,jamb_reg_no)
143                        #logger.info("%s, old reg_no %s overwritten with %s" % (student_record.id,student_record.jamb_reg_no,jamb_reg_no))
144            elif jamb_reg_no:
145                key_used = 'jamb_reg_no'
146                res = self.students_catalog(jamb_reg_no = jamb_reg_no)
147                if res:
148                    if mode == 'create':
149                        msg = "jamb_reg_no exists"
150                        break
151                else:
152                    if mode == 'edit':
153                        msg = "no student with jamb_reg_no %s" % jamb_reg_no
154                        break
155                student_record = res[0]
156            elif matric_no:
157                key_used = 'matric_no'
158                res = self.students_catalog(matric_no = matric_no)
159                if not res:
160                    msg = "no student with matric_no %s" % matric_no
161                    break
162                student_record = res[0]
163            else:
164                msg = "neither id, matric_no nor reg_no specified"
165            break
166        d = {}
167        d['student_record'] = student_record
168        d['key_used'] = key_used
169        d['msg'] = msg
170        return d
171    ###)
172
173    def makeIdLists(self): ###(
174        pending_digests = []
175        pending = []
176        # pending_student_ids = []
177        # pending_matric_nos = []
178        # pending_reg_ns = []
179        if os.path.exists(self.pending_path):
180            datafile = open(self.pending_path,"r")
181            reader = csv.reader(datafile)
182            old_headline = reader.next()
183            #datafile.seek(0)
184            pending_csv_reader = csv.DictReader(datafile,old_headline,)
185            #pending_csv_reader.next() # skip headline
186            for item in pending_csv_reader:
187                digest = makeDigest(item,self.data_keys)
188                if digest not in pending_digests:
189                    pending_digests += digest,
190                    pending += item,
191            datafile.close()
192            #copy2(self.pending_path,self.pending_backup)
193        return pending, pending_digests
194    ###)
195
196    def checkHeadline(self,headline): ###(
197        """ check the headline of a csv file """
198        import_keys = [k.strip() for k in headline if not (k.strip().startswith('ignore')
199                                                        or k.strip() in self.info.keys())]
200        # import_keys = [k.strip() for k in headline if not (k.strip() in self.info.keys())]
201        diff2schema = set(import_keys).difference(set(self.schema.keys()))
202        diff2layout = set(import_keys).difference(set(self.layout.keys()))
203        #if diff2schema and diff2schema != set(['id',]):
204        if diff2schema:
205            return list(diff2schema)
206        return []
207    ###)
208
209    def getHeadlineFields(self,headline,values): ###(
210        """ check the headline of a csv file """
211        # import_keys = [k.strip() for k in headline if not (k.strip().startswith('ignore')
212        #                                                 or k.strip() in self.info.keys())]
213        import_keys = [k.strip() for k in headline if not (k.strip() in self.info.keys())]
214        info_keys = [k.strip() for k in headline if k.strip() in self.info.keys()]
215        si = set(import_keys)
216        ss = set(self.schema.keys())
217
218        invalid_keys = si - ss
219        keys = []
220        i = 0
221        duplicates = False
222        singels = []
223        msg = ''
224        while True:
225            if len(values) != len(import_keys):
226                if len(values) == len(import_keys) + len(info_keys):
227                    msg += "fields from pending file in headline"
228                else:
229                    msg += "%d fields in headline but %d values" % (len(import_keys),len(values))
230                break
231            for k in import_keys:
232                if k in singels:
233                    keys += (k,'%s' % k,values[i],'(duplicate)'),
234                    msg += ("duplicate %s," % k)
235                    keys[singels.index(k)] = (k,'%s' % k,values[singels.index(k)],'(duplicate)')
236                elif k in invalid_keys and not k.startswith(IGNORE):
237                    keys += (k,NO_KEY,values[i],'(invalid)'),
238                else:
239                    keys += (k,k,values[i],''),
240                i += 1
241                singels += k,
242            break
243        return msg,keys
244    ###)
245###)
246
247class ApplicationImport(WAeUPImport):###(
248    name = "application"
249    plural_name = "%ss" % name
250    commit_after = 1000
251
252    def create(self,mapping):###(
253        reg_no = mapping.get('reg_no')
254        msg = ''
255        while True:
256            try:
257                self.applicants_catalog.addRecord(**mapping)
258            except ValueError:
259                msg =  "applicant record with reg_no %s already exists" % reg_no
260            break
261        return reg_no,msg,mapping
262    ###)
263
264    def edit(self,mapping):###(
265        reg_no = mapping.get('reg_no')
266        status = mapping.get('status')
267        msg = ''
268        while True:
269            res = self.applicants_catalog(reg_no = reg_no)
270            if len(res):
271                if res[0].status == 'created' and status != 'created':
272                    msg =  "student object with id %s for %s already created, status cannot be changed" % (res[0].student_id, reg_no)
273                elif status == 'created' and res[0].status != 'created':
274                    msg =  "student object for %s has not yet been created, status cannot be set to 'created'" % (reg_no)
275                else:
276                    self.applicants_catalog.modifyRecord(**mapping)
277            else:
278                msg =  "applicant record with reg_no %s does not exist" % reg_no
279            break
280        return reg_no,msg,mapping
281    ###)
282
283###)
284
285class CertificateImport(WAeUPImport):###(
286    name = "certificate"
287    plural_name = "%ss" % name
288    commit_after = 100000
289
290    def create(self,mapping):###(
291        if getattr(self,'_v_certificate_list',None) is None:
292            self._v_certificate_list = []
293        if getattr(self,'_v_department_certificates',None) is None:
294            departments = self.portal_catalog(portal_type = "Department")
295            self._v_department_certificates = {}
296            for department  in departments:
297                certificates_container = getattr(department.getObject(),"certificates",None)
298                self._v_department_certificates[department.getId] = {'container': certificates_container,
299                                                            'certificates': certificates_container.objectIds(),
300                                                            }
301        department_id = mapping['department_code']
302        msg = ''
303        certificate_id = mapping.get('code')
304        while True:
305            department_certificates = self._v_department_certificates.get(department_id,None)
306            if department_certificates is None:
307                msg =  "No Department with ID: %s" % department_id
308                break
309            certificates_container = department_certificates['container']
310            certificates = department_certificates['certificates']
311            if certificate_id in self._v_certificate_list:
312                msg =  "Duplicate Certificate ID: %s" % department_id
313                break
314            if certificate_id in certificates:
315                msg =  "Duplicate Certificate ID: %s" % department_id
316                break
317            try:
318                certificates_container.invokeFactory('Certificate', certificate_id)
319            except BadRequest,E:
320                msg =  "%s" % E
321                break
322            self._v_certificate_list.append(certificate_id)
323            certificate = getattr(certificates_container,certificate_id)
324            certificate.getContent().edit(mapping=mapping)
325            break
326        return certificate_id,msg,mapping
327    ###)
328
329    def edit(self,mapping):###(
330        certificate_id = mapping.get('code')
331        res = self.portal_catalog(id=certificate_id)
332        msg = ''
333        while True:
334            if not res:
335                msg =  "no certificate with id: %s" % certificate_id
336                break
337            c = res[0].getObject()
338            c.getContent().edit(mapping=mapping)
339            break
340        return certificate_id,msg,mapping
341    ###)
342###)
343
344class CourseImport(WAeUPImport):###(
345    name = "course"
346    plural_name = "%ss" % name
347    commit_after = 1000
348
349    def create(self,mapping):###(
350        if getattr(self,'_v_course_list',None) is None:
351            self._v_course_list = []
352        if getattr(self,'_v_department_courses',None) is None:
353            departments = self.portal_catalog(portal_type = "Department")
354            self._v_department_courses = {}
355            for department in departments:
356                courses_container = getattr(department.getObject(),"courses",None)
357                if courses_container is not None:
358                    self._v_department_courses[department.getId] = {'container': courses_container,
359                                                                    'courses': courses_container.objectIds(),
360                                                                   }
361        department_id = mapping['department_code']
362        course_id = mapping.get('code','')
363        msg = ''
364        while True:
365            department_courses = self._v_department_courses.get(department_id,None)
366            if department_courses is None:
367                msg =  "no department with id: %(department_id)s" % vars()
368                break
369            courses_container = department_courses['container']
370            courses = department_courses['courses']
371            if course_id in self._v_course_list:
372                msg =  "duplicate course id: %(course_id)s" % vars()
373                break
374            if course_id in courses:
375                msg =  "course %(course_id)s already exists in department %(department_id)s" % vars()
376                break
377            try:
378                courses_container.invokeFactory('Course', course_id)
379            except BadRequest,E:
380                msg =  "%s" % E
381                break
382            self._v_course_list.append(course_id)
383            course = getattr(courses_container,course_id)
384            course.getContent().edit(mapping=mapping)
385            break
386        return course_id,msg,mapping
387    ###)
388
389    def edit(self,mapping): ###(
390        course_id = mapping.get('code','')
391        course = self.courses_catalog.getRecordByKey(course_id)
392        msg = ''
393        while True:
394            if course is None:
395                msg =  "no course with id: %s" % course_id
396                break
397            course_object = getattr(getattr(getattr(getattr(self.academics_folder,course.faculty),
398                                    course.department),
399                                    'courses'),
400                                    course_id)
401            course_object.getContent().edit(mapping=mapping)
402            break
403        return course_id,msg,mapping
404    ###)
405###)
406
407class CourseResultImport(WAeUPImport):###(
408    """ CourseresultImport """
409    name = "course_result"
410    plural_name = "%ss" % name
411    commit_after = 1000000
412    required_modes = ('create','edit','remove')
413
414    def create(self,mapping):###(
415        students_folder = self.portal_url.getPortalObject().campus.students
416        if getattr(self,'_v_courses',None) is None:
417            res = self.courses_catalog()
418            self._v_courses = {}
419            for brain in res:
420                self._v_courses[brain.code] = brain
421        if getattr(self,'_v_level_created',None) is None:
422            self._v_level_created = []
423        if getattr(self,'_v_student_study_course',None) is None:
424            self._v_student_study_course = {}
425        msg = ''
426        key = ''
427        matric_no = mapping.get('matric_no','')
428        id = mapping.get('id','')
429        while True:
430            course_id = mapping.get('code')
431            if course_id not in self._v_courses.keys():
432                msg = "no course with id: %s" % course_id
433                break
434            result = self.findStudent('create',student_id=id,matric_no=matric_no)
435            msg = result['msg']
436            if msg:
437                break
438            student_record = result['student_record']
439            student_id = mapping['student_id']  = student_record.id
440            level_id = mapping.get('level_id','')
441            code = mapping.get('code','')
442            level_ident = "%(student_id)s_%(level_id)s" % vars()
443            if level_ident not in self._v_level_created:
444                context = self._v_student_study_course.get(student_id,None)
445                if context is None:
446                    try:
447                        context = getattr(getattr(students_folder,
448                                                "%(student_id)s" % vars()),
449                                        'study_course')
450                        self._v_student_study_course[student_id] = context
451                    except:
452                        msg = "could not create level %(level_id)s for %(student_id)s" % vars()
453                        break
454                if level_id not in context.objectIds():
455                    context.invokeFactory('StudentStudyLevel',"%(level_id)s" % vars())
456                    level = getattr(context,"%(level_id)s" % vars())
457                    self.portal_workflow.doActionFor(level,'open')
458                    session_id = mapping.get('session_id','')
459                    if session_id:
460                        level.getContent().edit(mapping={'session': "%s" % session_id,})
461                    self.portal_workflow.doActionFor(level,'close')
462                    self._v_level_created += level_ident,
463            mapping['key'] = key = "%(student_id)s|%(level_id)s|%(code)s" % vars()
464            #overwrite semester and credits in create mode
465            for k in ('semester','credits',):
466                mapping[k] = getattr(self._v_courses[course_id],k)
467            try:
468                self.course_results.addRecord(**mapping)
469            except ValueError:
470                msg = "course result already exists: %s" % key
471            break
472        return key,msg,mapping
473    ###)
474
475    def edit(self,mapping): ###(
476        msg = ''
477        key = ''
478        matric_no = mapping.get('matric_no','')
479        id = mapping.get('id','')
480        while True:
481            result = self.findStudent('edit',student_id=id,matric_no=matric_no)
482            msg = result['msg']
483            if msg:
484                break
485            student_record = result['student_record']
486            student_id = student_record.id
487            level_id = mapping.get('level_id','')
488            code = mapping.get('code','')
489            #code = mapping['code']
490            mapping['key'] = key = "%(student_id)s|%(level_id)s|%(code)s" % vars()
491            if self.course_results.getRecordByKey(key) is None:
492                msg =  "no course result with key %(key)s" % vars()
493                break
494            self.course_results.modifyRecord(**mapping)
495            break
496        return key,msg,mapping
497    ###)
498
499    def remove(self,mapping):###(
500        key = ''
501        msg = ''
502        matric_no = mapping.get('matric_no','')
503        id = mapping.get('id','')
504        while True:
505            result = self.findStudent('edit',student_id=id,matric_no=matric_no)
506            msg = result['msg']
507            if msg:
508                break
509            student_record = result['student_record']
510            student_id = student_record.id
511            level_id = mapping.get('level_id','')
512            code = mapping.get('code','')
513            key = "%(student_id)s|%(level_id)s|%(code)s" % vars()
514            if self.course_results.getRecordByKey(key) is None:
515                msg =  "no course result with key %(key)s" % vars()
516                break
517            self.course_results.deleteRecord(key)
518            break
519        return key,msg,mapping
520    ###)
521###)
522
523class CertificateCourseImport(WAeUPImport):###(
524    name = "certificate_course"
525    plural_name = "%ss" % name
526    commit_after = 1000
527    required_modes = ('create','edit')
528
529    def create(self,mapping):
530        if getattr(self,'_v_courses',None) is None:
531            res = self.courses_catalog()
532            self._v_courses= [course.code for course in res]
533        if getattr(self,'_v_ceritficates',None) is None:
534            res = self.portal_catalog(portal_type = "Certificate")
535            self._v_certificates = {}
536            for cert in res:
537                self._v_certificates[cert.getId] = cert.getObject()
538        msg = ''
539        while True:
540            certificate_course_id = mapping.get('code')
541            if certificate_course_id not in self._v_courses:
542                msg =  "no course with id: %s" % certificate_course_id
543                break
544            cert_id = mapping['certificate_code']
545            cert = self._v_certificates.get(cert_id,None)
546            if cert is None:
547                msg =  "no certificate with id: %s" % cert_id
548                break
549            level_id = mapping.get('level')
550            level = getattr(cert,level_id,None)
551            if level is None:
552                cert.invokeFactory('StudyLevel', level_id)
553                level = getattr(cert,level_id,None)
554            elif hasattr(level,certificate_course_id):
555                msg =  "duplicate certificate course id: %(certificate_course_id)s " % vars()
556                msg += "in %(cert_id)s/ %(level_id)s" % vars()
557                break
558            level.invokeFactory('CertificateCourse', certificate_course_id)
559            c = getattr(level,certificate_course_id)
560            c.getContent().edit(mapping=mapping)
561            break
562        return certificate_course_id,msg,mapping
563    ###)
564
565class DepartmentImport(WAeUPImport):###(
566    name = "department"
567    plural_name = "%ss" % name
568    commit_after = 1000
569
570    def create(self,mapping):###(
571        "create a department in the correct faculty"
572        faculty_id = mapping['faculty_code']
573        msg = ''
574        if getattr(self,'_v_faculties',None) is None:
575            res = self.portal_catalog(portal_type = "Faculty")
576            self._v_faculties = {}
577            for f in res:
578                self._v_faculties[f.getId] = f.getObject()
579        department_id = mapping.get('code','')
580        while True:
581            faculty = self._v_faculties.get(faculty_id,None)
582            if faculty is None:
583                msg =  "no faculty with id: %s" % faculty_id
584                break
585            else:
586                d = getattr(faculty,department_id,None)
587                if d is None or d.portal_type == "Faculty":
588                    try:
589                        faculty.invokeFactory('Department', department_id)
590                    except BadRequest,E:
591                        msg =  "%s" % E
592                        break
593                    d = getattr(faculty,department_id)
594                    d.invokeFactory('CoursesFolder','courses')
595                    courses = getattr(d,'courses')
596                    dict = {'Title': 'Courses'}
597                    courses.getContent().edit(mapping=dict)
598                    d.invokeFactory('CertificatesFolder','certificates')
599                    certificates = getattr(d,'certificates')
600                    dict = {'Title': 'Certificates'}
601                    certificates.getContent().edit(mapping=dict)
602                    d.getContent().edit(mapping=mapping)
603            break
604        return department_id,msg,mapping
605    ###)
606
607    def edit(self,mapping): ###(
608        "edit a department in the correct faculty"
609        academics_folder = self.portal_url.getPortalObject().campus.academics
610        faculty_id = mapping['faculty_code']
611        department_id = mapping.get('code','')
612        msg = ''
613        while True:
614            try:
615                d = getattr(getattr(academics_folder,faculty_id),department_id,None)
616            except KeyError:
617                msg =  "department %s or faculty %s wrong" % (department_id,faculty_id)
618                break
619            if d is None or d.portal_type == "Faculty":
620                msg =  "department %s not found" % (department_id)
621                break
622            d.getContent().edit(mapping=mapping)
623            break
624        return department_id,msg,mapping
625    ###)
626###)
627
628class FacultyImport(WAeUPImport):###(
629    name = "faculty"
630    plural_name = "faculties"
631    commit_after = 100
632   
633
634    def create(self,mapping): ###(
635        "create a faculty"
636        academics_folder = self.portal_url.getPortalObject().campus.academics
637        faculty_id = mapping.get('code','')
638        msg = ''
639        while True:
640            if faculty_id in academics_folder.objectIds():
641                msg =  "faculty with id: %s exists" % faculty_id
642                break
643            try:
644                academics_folder.invokeFactory('Faculty', faculty_id)
645            except BadRequest,E:
646                msg =  "%s" % E
647                break
648            f = getattr(academics_folder,faculty_id,None)
649            f.getContent().edit(mapping=mapping)
650            break
651        return faculty_id,msg,mapping
652        ###)
653
654    def edit(self,mapping): ###(
655        "edit a faculty"
656        academics_folder = self.portal_url.getPortalObject().campus.academics
657        faculty_id = mapping['code']
658        msg = ''
659        while True:
660            f = getattr(academics_folder,faculty_id,None)
661            if f is None:
662                msg =  "faculty with id: %s does not exist" % faculty_id
663            f.getContent().edit(mapping=mapping)
664            break
665        return faculty_id,msg,mapping
666    ###)
667###)
668
669class StudentImport(WAeUPImport):###(
670    name = "student"
671    plural_name = "%ss" % name
672    commit_after = 100
673
674    field2types_student = {   ###(
675                      'StudentApplication':
676                          {'id': 'application',
677                           #'title': 'Application Data',
678                           'wf_transition_return': 'close',
679                           'wf_transition_admit': 'remain',
680                           'wf_transition_graduate': 'close',
681                           'wf_transition_pay_school_fee': 'close',
682                           'wf_transition_validate_courses': 'close',
683                           'fields':
684                             ('jamb_reg_no',
685                              'entry_mode',
686                              'entry_session',
687                              'jamb_score',
688                              'app_email',
689                              'jamb_age',
690                              'jamb_state',
691                              'jamb_lga',
692                              'jamb_sex',
693                              )
694                              },
695                      #'StudentPume':
696                      #    {'id': 'pume',
697                      #     'title': 'Pume Data',
698                      #     'wf_transition_return': 'close',
699                      #     'wf_transition_admit': 'close',
700                      #     'fields':
701                      #       ('pume_score',
702                      #        )
703                      #        },
704                      'StudentClearance':
705                          {'id': 'clearance',
706                           #'title': 'Clearance/Eligibility Record',
707                           'wf_transition_return': 'close',
708                           'wf_transition_admit': 'remain',
709                           'wf_transition_graduate': 'close',
710                           'wf_transition_pay_school_fee': 'close',
711                           'wf_transition_validate_courses': 'close',
712                           'fields':
713                             ('matric_no',
714                              'nationality',
715                              'lga',
716                              'birthday',
717                              )
718                              },
719                         'StudentPersonal':
720                          {'id': 'personal',
721                           #'title': 'Personal Data',
722                           'wf_transition_return': 'open',
723                           'wf_transition_admit': 'remain',
724                           'wf_transition_graduate': 'close',
725                           'wf_transition_pay_school_fee': 'open',
726                           'wf_transition_validate_courses': 'open',
727                           'fields':
728                             ('firstname',
729                              'middlename',
730                              'lastname',
731                              'sex',
732                              'email',
733                              'phone',
734                              'perm_address',
735                              )
736                              },
737                         'StudentStudyCourse':
738                          {'id': 'study_course',
739                           #'title': 'Study Course',
740                           'wf_transition_return': 'open',
741                           'wf_transition_admit': 'remain',
742                           'wf_transition_graduate': 'close',
743                           'wf_transition_pay_school_fee': 'open',
744                           'wf_transition_validate_courses': 'open',
745                           'fields':
746                             ('study_course',
747                              'current_level',
748                              'current_session',
749                              'current_mode',  #is no longer used and visible but can still be imported
750                              'current_verdict',
751                              'previous_verdict',
752                              )
753                              },
754                         # 'StudentStudyLevel':
755                         #  {'id': 'current_level',
756                         #   'title': '',
757                         #   'wf_transition_return': 'open',
758                         #   'wf_transition_admit': 'remain',
759                         #   'fields':
760                         #     ('verdict',
761                         #      'session',
762                         #      )
763                         #      },
764                         'PaymentsFolder':
765                          {'id': 'payments',
766                           #'title': 'Payments',
767                           'wf_transition_return': 'open',
768                           'wf_transition_admit': 'open',
769                           'wf_transition_graduate': 'close',
770                           'wf_transition_pay_school_fee': 'open',
771                           'wf_transition_validate_courses': 'open',
772                           'fields':
773                             ()
774                              },
775                         }
776    ###)
777
778    def create(self,mapping): ###(
779        "create student records due import"
780        logger = logging.getLogger('WAeUPImport.StudentImport.create')
781        students_folder = self.portal_url.getPortalObject().campus.students
782        jamb_reg_no = mapping.get('jamb_reg_no',None)
783        matric_no = mapping.get('matric_no',None)
784        entry_mode = mapping.get('entry_mode',None)
785        msg = ''
786        student_id = mapping.get('id',None)
787        while True:
788            if student_id:
789                msg = "student_id must not be specified in create mode"
790                break
791            if jamb_reg_no and not entry_mode == 'transfer':
792                res = self.students_catalog(jamb_reg_no = jamb_reg_no)
793                if res:
794                    msg = "jamb_reg_no already assigned to student %s" % res[0].id
795                    break
796            if matric_no:
797                res = self.students_catalog(matric_no = matric_no)
798                if res:
799                    msg = "matric_no already assigned to student %s" % res[0].id
800                    break
801            if not matric_no and not jamb_reg_no:
802                msg = "jamb_reg_no or matric_no must be specified"
803                break
804            student_id = self.waeup_tool.generateStudentId('?')
805            students_folder.invokeFactory('Student', student_id)
806            student_obj = getattr(students_folder,student_id)
807            f2t = self.field2types_student
808            d = {}
809            transition = mapping.get('reg_transition','admit')
810            if transition not in ('admit','return','pay_school_fee','validate_courses'):
811                msg = "no valid transition provided"
812                break
813            for pt in f2t.keys():
814                student_obj.invokeFactory(pt,f2t[pt]['id'])
815                sub_obj = getattr(student_obj,f2t[pt]['id'])
816                sub_doc = sub_obj.getContent()
817                #d['Title'] = f2t[pt]['title']
818                for field in f2t[pt]['fields']:
819                    d[field] = mapping.get(field,'')
820
821                if pt == "StudentApplication":
822                    #d['jamb_sex']  = 'M'
823                    #if mapping.get('sex'):
824                    #    d['jamb_sex']  = 'F'
825                    d['jamb_firstname'] = mapping.get('firstname',None)
826                    d['jamb_middlename'] = mapping.get('middlename',None)
827                    d['jamb_lastname'] = mapping.get('lastname',None)
828
829                # if pt == "StudyCourse":
830                #     for von,zu in (('entry_mode','current_mode'),
831                #                    ('entry_session','current_session')):
832                #         if mapping.get(zu,None) is None and mapping.get(von,None) is not None:
833                #             d[zu] = mapping[von]
834                sub_doc.edit(mapping = d)
835
836                #import pdb;pdb.set_trace()
837                new_state = f2t[pt]['wf_transition_%(transition)s' % vars()]
838                if new_state != "remain":
839                    self.portal_workflow.doActionFor(sub_obj,new_state,dest_container=sub_obj)
840            self.portal_workflow.doActionFor(student_obj,transition)
841            student_obj.manage_setLocalRoles(student_id, ['Owner',])
842            mapping['id'] = student_id
843            break
844        return student_id,msg,mapping
845    ###)
846
847    def remove(self,mapping): ###(
848        "remove student records due import"
849        logger = logging.getLogger('WAeUPImport.StudentImport.remove')
850        students_folder = self.portal_url.getPortalObject().campus.students
851        stdir = self.portal_directories.students
852        student_id = mapping.get('id',None)
853        msg = ''
854        export_file = "%s/export/students_removed.csv" % (i_home)
855        toexport = {
856       
857                    'personal': ('firstname',
858                                 'middlename',
859                                 'lastname',
860                                 'perm_address',
861                                 ),
862                    'clearance': ('lga',
863                                  'birthday',
864                                 )
865                    }
866        while True:
867            if hasattr(students_folder,student_id):
868                # begin export
869                line = []
870                fields = []
871                for f in self.students_catalog.schema():
872                    fields.append(f)               
873                for k in toexport.keys():
874                    for f in toexport[k]:
875                        fields.append(f)
876                if not os.path.exists(export_file):       
877                    #headline = ','.join(fields).replace('level','current_level')
878                    headline = ','.join(fields)
879                    open(export_file,"a").write(headline +'\n')
880                format = '"%(' + ')s","%('.join(fields) + ')s"'
881                res = self.students_catalog(id = student_id)
882                student = res[0]
883                student_obj = getattr(students_folder,student_id)
884                d = student.getFormattedStudentEntry(student)
885                for k in toexport.keys()[0:]:
886                    try:
887                        object = getattr(student_obj,k)
888                        object_doc = object.getContent()
889                    except:
890                        continue
891                    for f in toexport[k]:
892                        d[f] = getattr(object_doc,f,'')
893                line.append(format % d)
894                open(export_file,"a").write('\n'.join(line) +'\n')
895                # end export
896                students_folder.manage_delObjects((student_id),)         
897            else:
898                msg = "Student object not found"
899                break
900            if hasattr(stdir, student_id):
901                stdir.deleteEntry(student_id)
902            self.waeup_tool.removePictureFolder(student_id)           
903            break
904        return student_id,msg,mapping     
905
906
907    def edit(self,mapping): ###(
908        "edit student records due import"
909        wftool = self.portal_workflow
910        logger = logging.getLogger('WAeUPImport.StudentImport.edit')
911        students_folder = self.portal_url.getPortalObject().campus.students
912        student_id = mapping.get('id',None)
913        jamb_reg_no = mapping.get('jamb_reg_no',None)
914        matric_no = mapping.get('matric_no',None)
915        editable_keys = mapping.keys()
916        msg = ''
917        while True:
918            if student_id:
919                res = self.students_catalog(id = student_id)
920                if not res:
921                    msg = "no student with id %s" % student_id
922                    break
923                student_record = res[0]
924                if matric_no and student_record.matric_no:
925                    if  matric_no != student_record.matric_no and not matric_no == 'transferred':
926                        res = self.students_catalog(matric_no = matric_no)
927                        if res:
928                            msg = "matric_no already assigned to student %s" % res[0].id
929                            break
930                        msg = "old matric_no %s overwritten with %s" % (student_record.matric_no,matric_no)
931                        #logger.info("%s, old matric_no %s overwritten with %s" % (student_record.id,student_record.matric_no,matric_no))
932                if jamb_reg_no and student_record.jamb_reg_no:
933                    if jamb_reg_no != student_record.jamb_reg_no:
934                        res = self.students_catalog(jamb_reg_no = jamb_reg_no)
935                        if res:
936                            msg = "jamb_reg_no already assigned to student %s" % res[0].id
937                            break
938                        msg = "old jamb_reg_no %s overwritten with %s" % (student_record.jamb_reg_no,jamb_reg_no)
939                        #logger.info("%s, old reg_no %s overwritten with %s" % (student_record.id,student_record.jamb_reg_no,jamb_reg_no))
940            elif jamb_reg_no:
941                res = self.students_catalog(jamb_reg_no = jamb_reg_no)
942                if not res:
943                    msg = "no student with jamb_reg_no %s" % jamb_reg_no
944                    break
945                student_record = res[0]
946                editable_keys.remove('jamb_reg_no')
947            elif matric_no:
948                res = self.students_catalog(matric_no = matric_no)
949                if not res:
950                    msg = "no student with matric_no %s" % matric_no
951                    break
952                student_record = res[0]
953                editable_keys.remove('matric_no')
954            student_id = student_record.id
955            student_obj = getattr(students_folder,student_id)
956            f2t = self.field2types_student
957            d = {}
958            any_change = False
959            #special treatment for StudentStudyLevel
960            d['verdict']  = mapping.get('current_verdict','')
961            d['session']  = mapping.get('current_session','')
962            current_level = mapping.get('current_level','')
963            transition = mapping.get('reg_transition',None)
964            # the validate_courses import transition is not really useful because it does not execute validate_courses.py
965            if transition and transition not in ('admit','return','graduate','pay_school_fee','validate_courses'):
966                msg = "no valid transition provided"
967                break     
968            while d['session'] and d['verdict'] and current_level:
969                sub_obj = getattr(student_obj,'study_course',None)
970                if sub_obj is None:
971                    break
972                level_obj = getattr(sub_obj,current_level,None)
973                if  level_obj is None:
974                    break
975                any_change = True
976                level_obj.getContent().edit(mapping = d)
977                try:
978                    wftool.doActionFor(level_obj,'close')
979                except:
980                    pass
981                break
982           
983            for pt in f2t.keys():
984                #if pt == "StudentApplication":
985                #    d['jamb_sex']  = 'M'
986                #    if mapping.get('sex'):
987                #        d['jamb_sex']  = 'F'
988                intersect = set(f2t[pt]['fields']).intersection(set(editable_keys))
989                #import pdb;pdb.set_trace()
990                object_id = f2t[pt]['id']
991                sub_obj = getattr(student_obj,object_id,None)
992                if intersect and pt not in ('StudentStudyLevel',):
993                    if sub_obj is None:
994                        try:
995                            student_obj.invokeFactory(pt,object_id)
996                        except:
997                            continue
998                        sub_obj = getattr(student_obj,object_id)
999                        #if f2t[pt]['title'] != '':
1000                        #    d['Title'] = f2t[pt]['title']
1001                    sub_doc = sub_obj.getContent()
1002                    for field in intersect:
1003                        changed = False
1004                        if getattr(sub_doc,field,None) != mapping.get(field,''):
1005                            any_change = True
1006                            changed = True
1007                            d[field] = mapping.get(field,'')
1008                        if changed:
1009                            sub_doc.edit(mapping = d)
1010                if transition:
1011                    new_state = f2t[pt]['wf_transition_%(transition)s' % vars()]
1012                    if new_state != "remain":
1013                        try:
1014                            self.portal_workflow.doActionFor(sub_obj,new_state,dest_container=sub_obj)
1015                        except:
1016                            pass
1017            if transition:
1018                try:
1019                    self.portal_workflow.doActionFor(student_obj,transition)
1020                except:
1021                    msg = "reg_transition not allowed"
1022            break
1023        return student_id,msg,mapping
1024    ###)
1025###)
1026
1027class StudentStudyLevelImport(WAeUPImport):###(
1028    """ StudentStudyLevelImport """
1029    name = "student_study_level"
1030    plural_name = "%ss" % name
1031    commit_after = 1000000
1032    required_modes = ('create',)
1033
1034    def create(self,mapping): ###(
1035        "edit student levels and create StudentStudyLevel object if not existent"
1036        wftool = self.portal_workflow
1037        logger = logging.getLogger('WAeUPTool.mass_create_level')
1038        students_folder = self.portal_url.getPortalObject().campus.students
1039        student_id = mapping.get('id',None)
1040        matric_no = mapping.get('matric_no',None)
1041        editable_keys = mapping.keys()
1042        key = ''
1043        msg = ''
1044        while True:
1045            result = self.findStudent('create',student_id=student_id,matric_no=matric_no)
1046            msg = result['msg']
1047            if msg:
1048                break
1049            student_record = result['student_record']
1050            student_id = student_record.id
1051            mapping['id'] = student_id
1052            session = mapping.get('session','')
1053            level = key = mapping.get('code','')
1054            if not level.isdigit():
1055                msg = 'student %s: imported level is empty' % (student_id,)
1056                break
1057            study_course_obj = getattr(getattr(students_folder,student_id),'study_course',None)
1058            if study_course_obj is None:
1059                msg = 'student %s: no study_course object' % student_id
1060                break
1061            level_obj = getattr(study_course_obj,level,None)
1062            if  level_obj is None:
1063                # The only difference to the edit method is that we create a StudentStudyLevel object
1064                try:
1065                    study_course_obj.invokeFactory('StudentStudyLevel',"%s" % level)
1066                    level_obj = getattr(context,"%s" % level)
1067                except:
1068                    continue
1069            level_obj.getContent().edit(mapping = mapping)
1070            level_review_state = wftool.getInfoFor(level_obj,'review_state',None)
1071            if level_review_state != "closed":
1072                wftool.doActionFor(level_obj,'close')
1073            break
1074        return key,msg,mapping
1075    ###)
1076
1077    def edit(self,mapping): ###(
1078        "edit student levels"
1079        wftool = self.portal_workflow
1080        logger = logging.getLogger('WAeUPTool.mass_edit_level')
1081        students_folder = self.portal_url.getPortalObject().campus.students
1082        student_id = mapping.get('id',None)
1083        matric_no = mapping.get('matric_no',None)
1084        key = ''
1085        msg = ''
1086        while True:
1087            result = self.findStudent('create',student_id=student_id,matric_no=matric_no)
1088            msg = result['msg']
1089            if msg:
1090                break
1091            student_record = result['student_record']
1092            student_id = student_record.id
1093            mapping['id'] = student_id
1094            session = mapping.get('session','')
1095            level = key = mapping.get('code','')
1096            #import pdb;pdb.set_trace()
1097            if not level.isdigit():
1098                msg = 'student %s: imported level is empty' % (student_id,)
1099                break
1100            study_course_obj = getattr(getattr(students_folder,student_id),'study_course',None)
1101            if study_course_obj is None:
1102                msg = 'student %s: no study_course object' % student_id
1103                break
1104            level_obj = getattr(study_course_obj,level,None)
1105            if  level_obj is None:
1106                msg = 'student %s: no study_level object for level %s' % (student_id,level)
1107                break
1108            level_obj.getContent().edit(mapping = mapping)
1109            break
1110        return key,msg,mapping
1111    ###)
1112###)
1113
1114class VerdictImport(WAeUPImport):###(
1115    """ VerdictImport """
1116    name = "verdict"
1117    plural_name = "%ss" % name
1118    commit_after = 100000
1119    required_modes = ('create','edit')
1120
1121    def create(self,mapping): ###(
1122        "edit student verdicts and create StudentStudyLevel object if not existent"
1123        wftool = self.portal_workflow
1124        logger = logging.getLogger('WAeUPTool.mass_edit_verdict')
1125        students_folder = self.portal_url.getPortalObject().campus.students
1126        student_id = mapping.get('id',None)
1127        matric_no = mapping.get('matric_no',None)
1128        editable_keys = mapping.keys()
1129        key = ''
1130        while True:
1131            result = self.findStudent('create',student_id=student_id,matric_no=matric_no)
1132            #student_record,msg = self.getStudentRecord(mapping)
1133            msg = result['msg']
1134            if msg:
1135                break
1136            student_record = result['student_record']
1137            student_id = student_record.id
1138            mapping['id'] = student_id
1139            d = {}
1140            #import pdb;pdb.set_trace()
1141            any_change = False
1142            #special treatment for StudentStudyLevel
1143            current_session = d['session'] = mapping.get('current_session','')
1144            if current_session and student_record.session != current_session:
1145                msg = 'student %s: imported session %s does not match current_session %s' % (student_id,
1146                                                                                            current_session,
1147                                                                                            student_record.session)
1148                break
1149            current_level = mapping.get('current_level','')
1150            if not current_level.isdigit():
1151                msg = 'student %s: imported level is empty' % (student_id,)
1152                break
1153            if current_level and student_record.level != current_level:
1154                msg = 'student %s: imported level %s does not match current_level %s' % (student_id,
1155                                                                                        current_level,
1156                                                                                        student_record.level)
1157                break
1158            student_review_state =  student_record.review_state
1159            if student_review_state == 'deactivated':
1160                msg = "student %s in review_state %s" % (student_id, student_review_state)
1161                break
1162            if student_review_state not in ('courses_validated','returning'):
1163                msg = "student %s in wrong review_state %s" % (student_id, student_review_state)
1164                break
1165            student_obj = getattr(students_folder,student_id)
1166            # f2t = self.field2types_student
1167            study_course_obj = getattr(student_obj,'study_course',None)
1168            if study_course_obj is None:
1169                msg = 'student %s: no study_course object' % student_id
1170                break
1171            level_obj = getattr(study_course_obj,current_level,None)
1172
1173            if  level_obj is None:
1174                # The only difference to the edit method is that we create a StudentStudyLevel object
1175                try:
1176                    study_course_obj.invokeFactory('StudentStudyLevel',"%s" % current_level)
1177                    level_obj = getattr(context,"%s" % current_level)
1178                    level_obj.portal_workflow.doActionFor(level,'open')
1179                except:
1180                    continue
1181                #msg = 'student %s: no study_level object for level %s' % (student_id,
1182                #                                                                current_level)
1183                #break
1184
1185            verdict = d['verdict'] = d['current_verdict']  = mapping.get('current_verdict','')
1186
1187            #if verdict == student_record.verdict:
1188            #    msg = 'student %s: verdict already set to %s' % (student_id,
1189            #                                                            verdict)
1190
1191            level_review_state = wftool.getInfoFor(level_obj,'review_state',None)
1192            if level_review_state != "closed":
1193                wftool.doActionFor(level_obj,'close')
1194                # msg = 'student %s: level %s is not closed' % (student_id,
1195                #                                                      current_level)
1196
1197            study_course_obj.getContent().edit(mapping = d)
1198            level_obj.getContent().edit(mapping = d)
1199            if student_review_state != "returning":
1200                wftool.doActionFor(student_obj,'return')
1201            # try:
1202            #     wftool.doActionFor(level_obj,'close')
1203            # except:
1204            #     pass
1205            break
1206        return student_id,msg,mapping
1207    ###)
1208
1209
1210    def edit(self,mapping): ###(
1211        "edit student verdicts"
1212        wftool = self.portal_workflow
1213        logger = logging.getLogger('WAeUPTool.mass_edit_verdict')
1214        students_folder = self.portal_url.getPortalObject().campus.students
1215        student_id = mapping.get('id',None)
1216        matric_no = mapping.get('matric_no',None)
1217        editable_keys = mapping.keys()
1218        key = ''
1219        while True:
1220            result = self.findStudent('edit',student_id=student_id,matric_no=matric_no)
1221            #student_record,msg = self.getStudentRecord(mapping)
1222            msg = result['msg']
1223            if msg:
1224                break
1225            student_record = result['student_record']
1226            key_used = result['key_used']
1227            if key_used in editable_keys:
1228                editable_keys.remove(key_used)
1229            student_id = student_record.id
1230            mapping['id'] = student_id
1231            d = {}
1232            #import pdb;pdb.set_trace()
1233            any_change = False
1234            #special treatment for StudentStudyLevel
1235            current_session = d['session'] = mapping.get('current_session','')
1236            if current_session and student_record.session != current_session:
1237                msg = 'student %s: imported session %s does not match current_session %s' % (student_id,
1238                                                                                            current_session,
1239                                                                                            student_record.session)
1240                break
1241            current_level = mapping.get('current_level','')
1242            if not current_level.isdigit():
1243                msg = 'student %s: imported level is empty' % (student_id,)
1244                break
1245            if current_level and student_record.level != current_level:
1246                msg = 'student %s: imported level %s does not match current_level %s' % (student_id,
1247                                                                                        current_level,
1248                                                                                        student_record.level)
1249                break
1250            student_review_state =  student_record.review_state
1251            if student_review_state == 'deactivated':
1252                msg = "student %s in review_state %s" % (student_id, student_review_state)
1253                break
1254            if student_review_state not in ('courses_validated','returning'):
1255                msg = "student %s in wrong review_state %s" % (student_id, student_review_state)
1256                break
1257            student_obj = getattr(students_folder,student_id)
1258            # f2t = self.field2types_student
1259            study_course_obj = getattr(student_obj,'study_course',None)
1260            if study_course_obj is None:
1261                msg = 'student %s: no study_course object' % student_id
1262                break
1263            level_obj = getattr(study_course_obj,current_level,None)
1264            if  level_obj is None:
1265                msg = 'student %s: no study_level object for level %s' % (student_id,
1266                                                                                current_level)
1267                break
1268            verdict = d['verdict'] = d['current_verdict']  = mapping.get('current_verdict','')
1269
1270            #if verdict == student_record.verdict:
1271            #    msg = 'student %s: verdict already set to %s' % (student_id,
1272            #                                                            verdict)
1273
1274            level_review_state = wftool.getInfoFor(level_obj,'review_state',None)
1275            if level_review_state != "closed":
1276                wftool.doActionFor(level_obj,'close')
1277                # msg = 'student %s: level %s is not closed' % (student_id,
1278                #                                                      current_level)
1279
1280            study_course_obj.getContent().edit(mapping = d)
1281            level_obj.getContent().edit(mapping = d)
1282            if student_review_state != "returning":
1283                wftool.doActionFor(student_obj,'return')
1284            # try:
1285            #     wftool.doActionFor(level_obj,'close')
1286            # except:
1287            #     pass
1288            break
1289        return student_id,msg,mapping
1290    ###)
1291
1292    def edit_old(self,mapping): ###(
1293        "edit student verdicts"
1294        wftool = self.portal_workflow
1295        logger = logging.getLogger('WAeUPTool.mass_edit_verdict')
1296        students_folder = self.portal_url.getPortalObject().campus.students
1297        student_id = mapping.get('id',None)
1298        matric_no = mapping.get('matric_no',None)
1299        editable_keys = mapping.keys()
1300        key = ''
1301        while True:
1302            msg = ''
1303            if student_id:
1304                student_record = self.students_catalog.getRecordByKey(student_id)
1305                if student_record is None:
1306                    #return '',"no student with id %s" % student_id
1307                    msg = "no student with id %s" % student_id
1308                    break
1309                if matric_no and student_record.matric_no and matric_no != student_record.matric_no:
1310                    msg = 'student %s: matric_no %s does not match %s' % (student_record.id,
1311                                                                          student_record.matric_no,
1312                                                                          matric_no)
1313                    break
1314                mapping['matric_no'] = student_record.matric_no
1315            elif matric_no:
1316                res = self.students_catalog(matric_no = matric_no)
1317                if not res:
1318                    msg = "no student with matric_no %s" % matric_no
1319                    break
1320                student_record = res[0]
1321                editable_keys.remove('matric_no')
1322            else:
1323                msg = "no id or matric_no specified"
1324                break
1325            student_id = student_record.id
1326            mapping['id'] = student_id
1327            d = {}
1328            #import pdb;pdb.set_trace()
1329            any_change = False
1330            #special treatment for StudentStudyLevel
1331            current_session = d['session'] = mapping.get('current_session','')
1332            if current_session and student_record.session != current_session:
1333                msg = 'student %s: imported session %s does not match current_session %s' % (student_id,
1334                                                                                            current_session,
1335                                                                                            student_record.session)
1336                break
1337            current_level = mapping.get('current_level','')
1338            if not current_level.isdigit():
1339                msg = 'student %s: imported level is empty' % (student_id,)
1340                break
1341            if current_level and student_record.level != current_level:
1342                msg = 'student %s: imported level %s does not match current_level %s' % (student_id,
1343                                                                                        current_level,
1344                                                                                        student_record.level)
1345                break
1346            student_review_state =  student_record.review_state
1347            if student_review_state == 'deactivated':
1348                msg = "student %s in review_state %s" % (student_id, student_review_state)
1349                break
1350            if student_review_state not in ('courses_validated','returning'):
1351                msg = "student %s in wrong review_state %s" % (student_id, student_review_state)
1352                break
1353            student_obj = getattr(students_folder,student_id)
1354            # f2t = self.field2types_student
1355            study_course_obj = getattr(student_obj,'study_course',None)
1356            if study_course_obj is None:
1357                msg = 'student %s: no study_course object' % student_id
1358                break
1359            level_obj = getattr(study_course_obj,current_level,None)
1360            if  level_obj is None:
1361                msg = 'student %s: no study_level object for level %s' % (student_id,
1362                                                                                current_level)
1363                break
1364            verdict = d['verdict'] = d['current_verdict']  = mapping.get('current_verdict','')
1365
1366            #if verdict == student_record.verdict:
1367            #    msg = 'student %s: verdict already set to %s' % (student_id,
1368            #                                                            verdict)
1369
1370            level_review_state = wftool.getInfoFor(level_obj,'review_state',None)
1371            if level_review_state != "closed":
1372                wftool.doActionFor(level_obj,'close')
1373                # msg = 'student %s: level %s is not closed' % (student_id,
1374                #                                                      current_level)
1375
1376            study_course_obj.getContent().edit(mapping = d)
1377            level_obj.getContent().edit(mapping = d)
1378            if student_review_state != "returning":
1379                wftool.doActionFor(student_obj,'return')
1380            # try:
1381            #     wftool.doActionFor(level_obj,'close')
1382            # except:
1383            #     pass
1384            break
1385        return student_id,msg,mapping
1386    ###)
1387###)
Note: See TracBrowser for help on using the repository browser.