Index: /WAeUP_SRP/base/WAeUPImport.py
===================================================================
--- /WAeUP_SRP/base/WAeUPImport.py	(revision 3371)
+++ /WAeUP_SRP/base/WAeUPImport.py	(revision 3372)
@@ -121,4 +121,51 @@
     ###)
 
+    def findStudent(self,mode,student_id=None, matric_no=None, jamb_reg_no=None): ###(
+        student_record = None
+        msg = ''
+        key_used = ''
+        while True:
+            if student_id:
+                key_used = 'student_id'
+                res = self.students_catalog(id = student_id)
+                if not res:
+                    msg = "no student with id %s" % student_id
+                    break
+                student_record = res[0]
+                if matric_no and student_record.matric_no:
+                    if  matric_no != student_record.matric_no:
+                        msg = "old matric_no %s overwritten with %s" % (student_record.matric_no,matric_no)
+                        #logger.info("%s, old matric_no %s overwritten with %s" % (student_record.id,student_record.matric_no,matric_no))
+                if jamb_reg_no and student_record.jamb_reg_no:
+                    if jamb_reg_no != student_record.jamb_reg_no:
+                        msg = "old reg_no %s overwritten with %s" % (student_record.jamb_reg_no,jamb_reg_no)
+                        #logger.info("%s, old reg_no %s overwritten with %s" % (student_record.id,student_record.jamb_reg_no,jamb_reg_no))
+            elif jamb_reg_no:
+                key_used = 'jamb_reg_no'
+                res = self.students_catalog(jamb_reg_no = jamb_reg_no)
+                if res:
+                    if mode == 'create': 
+                        msg = "jamb_reg_no exists"
+                        break
+                else:
+                    if mode == 'edit':
+                        msg = "no student with jamb_reg_no %s" % jamb_reg_no
+                        break
+                student_record = res[0]
+            elif matric_no:
+                key_used = 'matric_no'
+                res = self.students_catalog(matric_no = matric_no)
+                if not res:
+                    msg = "no student with matric_no %s" % matric_no
+                    break
+                student_record = res[0]
+            break
+        d = {}
+        d['student_record'] = student_record
+        d['key_used'] = key_used 
+        d['msg'] = msg 
+        return d
+    ###)
+
     def makeIdLists(self): ###(
         pending_digests = []
@@ -362,5 +409,5 @@
     required_modes = ('create','edit','remove')
 
-    def getStudentRecord(self,mapping): ###(
+    def old_getStudentRecord(self,mapping): ###(
         id_field_found = False
         msg = ''
@@ -403,6 +450,67 @@
         if getattr(self,'_v_level_created',None) is None:
             self._v_level_created = []
+        if getattr(self,'_v_student_study_course',None) is None:
+            self._v_student_study_course = {}
         msg = ''
         key = ''
+        matric_no = mapping.get('matric_no','')
+        id = mapping.get('id','')
+        while True:
+            course_id = mapping.get('code')
+            if course_id not in self._v_courses.keys():
+                msg = "no course with id: %s" % course_id
+                break
+            result = self.findStudent('create',student_id=id,matric_no=matric_no)
+            #student_record,msg = self.getStudentRecord(mapping)
+            msg = result['msg']
+            if msg:
+                break
+            student_record = result['student_record']
+            student_id = mapping['student_id']  = student_record.id
+            level_id = mapping.get('level_id','')
+            code = mapping.get('code','')
+            level_ident = "%(student_id)s_%(level_id)s" % vars()
+            if level_ident not in self._v_level_created:
+                context = self._v_student_study_course.get(student_id,None)
+                if context is None:
+                    try:
+                        context = getattr(getattr(students_folder,
+                                                "%(student_id)s" % vars()),
+                                        'study_course')
+                        self._v_student_study_course[student_id] = context
+                    except:
+                        msg = "could not create level %(level_id)s for %(student_id)s" % vars()
+                        break
+                if level_id not in context.objectIds():
+                    context.invokeFactory('StudentStudyLevel',"%(level_id)s" % vars())
+                    level = getattr(context,"%(level_id)s" % vars())
+                    self.portal_workflow.doActionFor(level,'open')
+                    level.getContent().edit(mapping={'session': "%(session_id)s" % mapping,})
+                    self.portal_workflow.doActionFor(level,'close')
+                    self._v_level_created += level_ident,
+            mapping['key'] = key = "%(student_id)s|%(level_id)s|%(code)s" % vars()
+            for k in ('semester','credits',):
+                mapping[k] = getattr(self._v_courses[course_id],k)
+            try:
+                self.course_results.addRecord(**mapping)
+            except ValueError:
+                msg = "course result already exists: %s" % key
+            break
+        return key,msg,mapping
+    ###)
+
+    def create_old(self,mapping):###(
+        students_folder = self.portal_url.getPortalObject().campus.students
+        if getattr(self,'_v_courses',None) is None:
+            res = self.courses_catalog()
+            self._v_courses = {}
+            for brain in res:
+                self._v_courses[brain.code] = brain
+        if getattr(self,'_v_level_created',None) is None:
+            self._v_level_created = []
+        msg = ''
+        key = ''
+        matric_no = mapping.get('matric_no','')
+        student_id = mapping.get('id','')
         while True:
             course_id = mapping.get('code')
@@ -454,7 +562,10 @@
         key = ''
         while True:
-            student_record,msg = self.getStudentRecord(mapping)
+            result = self.findStudent('edit',student_id=id,matric_no=matric_no)
+            #student_record,msg = self.getStudentRecord(mapping)
+            msg = result['msg']
             if msg:
                 break
+            student_record = result['student_record']
             student_id = student_record.id
             level_id = mapping.get('level_id','')
@@ -488,14 +599,5 @@
         return key,msg,mapping
     ###)
-
 ###)
-
-
-class StudentStudyLevelImport(WAeUPImport):###(
-    """ StudentStudyLevelImport """
-    name = "student_study_level"
-    plural_name = "%ss" % name
-    commit_after = 1000000
-    required_modes = ('create','edit','remove')
 
 class CertificateCourseImport(WAeUPImport):###(
@@ -926,4 +1028,90 @@
 ###)
 
+class StudentStudyLevelImport(WAeUPImport):###(
+    """ StudentStudyLevelImport """
+    name = "student_study_level"
+    plural_name = "%ss" % name
+    commit_after = 1000000
+    required_modes = ('create',)
+
+    def create(self,mapping):
+        "edit student levels and create StudentStudyLevel object if not existent"
+        wftool = self.portal_workflow
+        logger = logging.getLogger('WAeUPTool.mass_create_level')
+        students_folder = self.portal_url.getPortalObject().campus.students
+        student_id = mapping.get('id',None)
+        matric_no = mapping.get('matric_no',None)
+        editable_keys = mapping.keys()
+        key = ''
+        msg = ''
+        while True:
+            result = self.findStudent('create',student_id=student_id,matric_no=matric_no)
+            msg = result['msg']
+            if msg:
+                break
+            student_record = result['student_record']
+            student_id = student_record.id
+            mapping['id'] = student_id
+            session = mapping.get('session','')
+            level = key = mapping.get('code','')
+            if not level.isdigit():
+                msg = 'student %s: imported level is empty' % (student_id,)
+                break
+            student_course_obj = getattr(getattr(students_folder,student_id),student_obj,'study_course',None)
+            if study_course_obj is None:
+                msg = 'student %s: no study_course object' % student_id
+                break
+            level_obj = getattr(study_course_obj,level,None)
+            if  level_obj is None:
+                # The only difference to the edit method is that we create a StudentStudyLevel object
+                try:
+                    study_course_obj.invokeFactory('StudentStudyLevel',"%s" % level)
+                    level_obj = getattr(context,"%s" % level)
+                except:
+                    continue
+            level_obj.getContent().edit(mapping = mapping)
+            level_review_state = wftool.getInfoFor(level_obj,'review_state',None)
+            if level_review_state != "closed":
+                wftool.doActionFor(level_obj,'close')
+            break
+        return key,msg,mapping
+    ###)
+
+    def edit(self,mapping): ###(
+        "edit student levels"
+        wftool = self.portal_workflow
+        logger = logging.getLogger('WAeUPTool.mass_edit_level')
+        students_folder = self.portal_url.getPortalObject().campus.students
+        student_id = mapping.get('id',None)
+        matric_no = mapping.get('matric_no',None)
+        key = ''
+        msg = ''
+        while True:
+            result = self.findStudent('create',student_id=student_id,matric_no=matric_no)
+            msg = result['msg']
+            if msg:
+                break
+            student_record = result['student_record']
+            student_id = student_record.id
+            mapping['id'] = student_id
+            #import pdb;pdb.set_trace()
+            session = d['session'] = mapping.get('session','')
+            level = key = mapping.get('level','')
+            if not level.isdigit():
+                msg = 'student %s: imported level is empty' % (student_id,)
+                break
+            student_course_obj = getattr(getattr(students_folder,student_id),student_obj,'study_course',None)
+            if study_course_obj is None:
+                msg = 'student %s: no study_course object' % student_id
+                break
+            level_obj = getattr(study_course_obj,level,None)
+            if  level_obj is None:
+                msg = 'student %s: no study_level object for level %s' % (student_id,level)
+                break
+            level_obj.getContent().edit(mapping = mapping)
+            break
+        return key,msg,mapping
+    ###)
+
 class VerdictImport(WAeUPImport):###(
     """ VerdictImport """
@@ -933,5 +1121,93 @@
     required_modes = ('create','edit')
 
-    def create(self,mapping):
+    def create(self,mapping): ###(
+        "edit student verdicts and create StudentStudyLevel object if not existent"
+        wftool = self.portal_workflow
+        logger = logging.getLogger('WAeUPTool.mass_edit_verdict')
+        students_folder = self.portal_url.getPortalObject().campus.students
+        student_id = mapping.get('id',None)
+        matric_no = mapping.get('matric_no',None)
+        editable_keys = mapping.keys()
+        key = ''
+        while True:
+            result = self.findStudent('create',student_id=student_id,matric_no=matric_no)
+            #student_record,msg = self.getStudentRecord(mapping)
+            msg = result['msg']
+            if msg:
+                break
+            student_record = result['student_record']
+            student_id = student_record.id
+            mapping['id'] = student_id
+            d = {}
+            #import pdb;pdb.set_trace()
+            any_change = False
+            #special treatment for StudentStudyLevel
+            current_session = d['session'] = mapping.get('current_session','')
+            if current_session and student_record.session != current_session:
+                msg = 'student %s: imported session %s does not match current_session %s' % (student_id,
+                                                                                            current_session,
+                                                                                            student_record.session)
+                break
+            current_level = mapping.get('current_level','')
+            if not current_level.isdigit():
+                msg = 'student %s: imported level is empty' % (student_id,)
+                break
+            if current_level and student_record.level != current_level:
+                msg = 'student %s: imported level %s does not match current_level %s' % (student_id,
+                                                                                        current_level,
+                                                                                        student_record.level)
+                break
+            student_review_state =  student_record.review_state
+            if student_review_state == 'deactivated':
+                msg = "student %s in review_state %s" % (student_id, student_review_state)
+                break
+            if student_review_state not in ('courses_validated','returning'):
+                msg = "student %s in wrong review_state %s" % (student_id, student_review_state)
+                break
+            student_obj = getattr(students_folder,student_id)
+            # f2t = self.field2types_student
+            study_course_obj = getattr(student_obj,'study_course',None)
+            if study_course_obj is None:
+                msg = 'student %s: no study_course object' % student_id
+                break
+            level_obj = getattr(study_course_obj,current_level,None)
+
+            if  level_obj is None:
+                # The only difference to the edit method is that we create a StudentStudyLevel object
+                try:
+                    study_course_obj.invokeFactory('StudentStudyLevel',"%s" % current_level)
+                    level_obj = getattr(context,"%s" % current_level)
+                    level_obj.portal_workflow.doActionFor(level,'open')
+                except:
+                    continue
+                #msg = 'student %s: no study_level object for level %s' % (student_id,
+                #                                                                current_level)
+                #break
+
+            verdict = d['verdict'] = d['current_verdict']  = mapping.get('current_verdict','')
+
+            #if verdict == student_record.verdict:
+            #    msg = 'student %s: verdict already set to %s' % (student_id,
+            #                                                            verdict)
+
+            level_review_state = wftool.getInfoFor(level_obj,'review_state',None)
+            if level_review_state != "closed":
+                wftool.doActionFor(level_obj,'close')
+                # msg = 'student %s: level %s is not closed' % (student_id,
+                #                                                      current_level)
+
+            study_course_obj.getContent().edit(mapping = d)
+            level_obj.getContent().edit(mapping = d)
+            if student_review_state != "returning":
+                wftool.doActionFor(student_obj,'return')
+            # try:
+            #     wftool.doActionFor(level_obj,'close')
+            # except:
+            #     pass
+            break
+        return student_id,msg,mapping
+    ###)
+
+    def create_old(self,mapping): ###(
         "edit student verdicts and create StudentStudyLevel object if not existent"
         wftool = self.portal_workflow
@@ -1036,7 +1312,7 @@
             break
         return student_id,msg,mapping
-
-
-    def edit(self,mapping):
+    ###)
+
+    def edit(self,mapping): ###(
         "edit student verdicts"
         wftool = self.portal_workflow
@@ -1046,6 +1322,109 @@
         matric_no = mapping.get('matric_no',None)
         editable_keys = mapping.keys()
-        while True:
-            key = ''
+        key = ''
+        while True:
+            result = self.findStudent('edit',student_id=student_id,matric_no=matric_no)
+            #student_record,msg = self.getStudentRecord(mapping)
+            msg = result['msg']
+            if msg:
+                break
+            student_record = result['student_record']
+            key_used = result['key_used']
+            # if student_id:
+            #     student_record = self.students_catalog.getRecordByKey(student_id)
+            #     if student_record is None:
+            #         #return '',"no student with id %s" % student_id
+            #         msg = "no student with id %s" % student_id
+            #         break
+            #     if matric_no and student_record.matric_no and matric_no != student_record.matric_no:
+            #         msg = 'student %s: matric_no %s does not match %s' % (student_record.id,
+            #                                                               student_record.matric_no,
+            #                                                               matric_no)
+            #         break
+            #     mapping['matric_no'] = student_record.matric_no
+            # elif matric_no:
+            #     res = self.students_catalog(matric_no = matric_no)
+            #     if not res:
+            #         msg = "no student with matric_no %s" % matric_no
+            #         break
+            #     student_record = res[0]
+            #     editable_keys.remove('matric_no')
+            # else:
+            #     msg = "no id or matric_no specified"
+            #     break
+            editable_keys.remove(key_used)
+            student_id = student_record.id
+            mapping['id'] = student_id
+            d = {}
+            #import pdb;pdb.set_trace()
+            any_change = False
+            #special treatment for StudentStudyLevel
+            current_session = d['session'] = mapping.get('current_session','')
+            if current_session and student_record.session != current_session:
+                msg = 'student %s: imported session %s does not match current_session %s' % (student_id,
+                                                                                            current_session,
+                                                                                            student_record.session)
+                break
+            current_level = mapping.get('current_level','')
+            if not current_level.isdigit():
+                msg = 'student %s: imported level is empty' % (student_id,)
+                break
+            if current_level and student_record.level != current_level:
+                msg = 'student %s: imported level %s does not match current_level %s' % (student_id,
+                                                                                        current_level,
+                                                                                        student_record.level)
+                break
+            student_review_state =  student_record.review_state
+            if student_review_state == 'deactivated':
+                msg = "student %s in review_state %s" % (student_id, student_review_state)
+                break
+            if student_review_state not in ('courses_validated','returning'):
+                msg = "student %s in wrong review_state %s" % (student_id, student_review_state)
+                break
+            student_obj = getattr(students_folder,student_id)
+            # f2t = self.field2types_student
+            study_course_obj = getattr(student_obj,'study_course',None)
+            if study_course_obj is None:
+                msg = 'student %s: no study_course object' % student_id
+                break
+            level_obj = getattr(study_course_obj,current_level,None)
+            if  level_obj is None:
+                msg = 'student %s: no study_level object for level %s' % (student_id,
+                                                                                current_level)
+                break
+            verdict = d['verdict'] = d['current_verdict']  = mapping.get('current_verdict','')
+
+            #if verdict == student_record.verdict:
+            #    msg = 'student %s: verdict already set to %s' % (student_id,
+            #                                                            verdict)
+
+            level_review_state = wftool.getInfoFor(level_obj,'review_state',None)
+            if level_review_state != "closed":
+                wftool.doActionFor(level_obj,'close')
+                # msg = 'student %s: level %s is not closed' % (student_id,
+                #                                                      current_level)
+
+            study_course_obj.getContent().edit(mapping = d)
+            level_obj.getContent().edit(mapping = d)
+            if student_review_state != "returning":
+                wftool.doActionFor(student_obj,'return')
+            # try:
+            #     wftool.doActionFor(level_obj,'close')
+            # except:
+            #     pass
+            break
+        return student_id,msg,mapping
+    ###)
+
+    def edit_old(self,mapping): ###(
+        "edit student verdicts"
+        wftool = self.portal_workflow
+        logger = logging.getLogger('WAeUPTool.mass_edit_verdict')
+        students_folder = self.portal_url.getPortalObject().campus.students
+        student_id = mapping.get('id',None)
+        matric_no = mapping.get('matric_no',None)
+        editable_keys = mapping.keys()
+        key = ''
+        while True:
             msg = ''
             if student_id:
@@ -1133,3 +1512,3 @@
         return student_id,msg,mapping
     ###)
-
+###)
