Index: WAeUP_SRP/trunk/Students.py
===================================================================
--- WAeUP_SRP/trunk/Students.py	(revision 1819)
+++ WAeUP_SRP/trunk/Students.py	(revision 1820)
@@ -17,4 +17,5 @@
 from Products.WAeUP_SRP.Academics import makeCertificateCode
 from Products.AdvancedQuery import Eq, Between, Le,In
+import DateTime
 import logging
 import csv,re,os
@@ -420,4 +421,158 @@
     ###)
 
+    security.declareProtected(ModifyPortalContent,"transferStudents")###(
+    def transferStudents(self,filename):
+        """
+        load Interfaculty transferStudents Studentdata from CSV values.
+        """
+        import transaction
+        import random
+        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
+        pm = self.portal_membership
+        member = pm.getAuthenticatedMember()
+        logger = logging.getLogger('Students.StudentsFolder.transferStudents')
+        #students_folder = self.portal_catalog({'meta_type': 'StudentsFolder'})[-1].getObject()
+        students_folder = self.portal_url.getPortalObject().campus.students
+        csv_fields = ('old_matric_no',
+                      'matric_no',
+                      'study_course',
+                      'current_mode',
+                      'current_level',
+                      )
+        tr_count = 0
+        total = 0
+        total_imported = 0
+        total_not_imported = 0
+        imported = []
+        not_imported = []
+        certs = {}
+        try:
+            results = csv.DictReader(open("%s/import/%s.csv" % (i_home,filename),"rb"))
+        except:
+            logger.error('Error reading %s.csv' % filename)
+            return
+        start = True
+        for result in results:
+            total += 1
+            if start:
+                start = False
+                logger.info('%s starts import from %s.csv' % (member,filename))
+                import_keys = [k for k in result.keys() if not k.startswith('ignore')]
+                diff2schema = set(import_keys).difference(set(csv_fields))
+                if diff2schema:
+                    em = "not ignorable key(s) %s found in heading" % diff2schema
+                    return em
+                s = ','.join(['"%s"' % fn for fn in import_keys])
+                open("%s/import/%s_not_imported%s.csv" % (i_home,filename,current),"a").write(s + ',"Error"'+ '\n')
+                s = '"id",' + s
+                open("%s/import/%s_imported%s.csv" % (i_home,filename,current),"a").write(s + '\n')
+                format = ','.join(['"%%(%s)s"' % fn for fn in import_keys])
+                format_error = format + ',"%(Error)s"'
+                format = '"%(id)s",'+ format
+            old_matric_no = result.get('old_matric_no')
+            res = self.students_catalog(matric_no = old_matric_no)
+            result['id'] = "None"
+            if not res:
+                em = 'Student with Matric_no %s not found' % old_matric_no
+                logger.info(em)
+                result['Error'] = "Student not exists"
+                not_imported.append(format_error % result)
+                total_not_imported += 1
+                continue
+            student_brain = res[0]
+            student_object = getattr(students_folder,student_brain.id)
+            result['id'] = student_brain.id
+            cert_id = makeCertificateCode(result.get('study_course'))
+            if cert_id not in certs.keys():
+                res = self.portal_catalog(meta_type = "Certificate",id = cert_id)
+                if not res:
+                    em = 'No Certificate with ID %s \n' % cert_id
+                    logger.info(em)
+                    result['Error'] = "No Certificate %s" % cert_id
+                    not_imported.append( format_error % result)
+                    total_not_imported += 1
+                    continue
+                cert = res[0]
+                cert_path = cert.getPath().split('/')
+                certificate = certs[cert_id] = {'faculty': cert_path[-4],
+                                     'department': cert_path[-3]}
+            cert_doc = certs[cert_id]
+            clearance = getattr(student_object,'clearance',None)
+            if clearance is None:
+                em = 'Student has no clearance object'
+                logger.info(em)
+                result['Error'] = em
+                not_imported.append( format_error % result)
+                total_not_imported += 1
+                continue
+            clearance_doc = clearance.getContent()
+            study_course = student_object.study_course
+            study_course_doc = study_course.getContent()
+            old_study_course = study_course_doc.study_course
+            old_current_level = study_course_doc.current_level
+            current_level = result.get('current_level',None)
+            try:
+                icl = int(current_level)
+            except:
+                em = 'Invalid new level %s' % current_level
+                logger.info(em)
+                result['Error'] = em
+                not_imported.append( format_error % result)
+                total_not_imported += 1
+                continue
+            if icl <= int(old_current_level) and study_course.objectIds():
+                em = 'Already registered level %s new %s' % (old_current_level,current_level)
+                logger.info(em)
+                result['Error'] = em
+                not_imported.append( format_error % result)
+                total_not_imported += 1
+                continue
+            #from pdb import set_trace; set_trace()
+            cd = {}
+            matric_no_history = getattr(clearance_doc,'matric_no_history',[])
+            if not matric_no_history:
+                matric_no_history = []
+            matric_no_history.append(old_matric_no)
+            cd['matric_no_history'] = matric_no_history
+            cd['matric_no'] = result.get('matric_no')
+            clearance_doc.edit(mapping = cd)
+            dsc = {}
+            study_course_history = getattr(study_course_doc,'study_course_history',[])
+            if not study_course_history:
+                study_course_history = []
+            study_course_history.append(old_study_course)
+            dsc['study_course_history'] = study_course_history
+            dsc['study_course'] = result.get('study_course')
+            dsc['current_level'] = current_level
+            dsc['current_mode'] = result.get('current_mode')
+            study_course_doc.edit(mapping=dsc)
+            imported.append( format % result)
+            tr_count += 1
+            total_imported += 1
+            if tr_count > 1000:
+                if len(not_imported) > 0:
+                    open("%s/import/%s_not_imported%s.csv" % (i_home,filename,current),"a").write(
+                             '\n'.join(not_imported) + '\n')
+                    not_imported = []
+                if len(imported) > 0:
+                    open("%s/import/%s_imported%s.csv" % (i_home,filename,current),"a").write(
+                             '\n'.join(imported) + '\n')
+                    imported = []
+                em = '%d transactions committed\n' % (tr_count)
+                transaction.commit()
+                regs = []
+                logger.info(em)
+                tr_count = 0
+        if len(imported) > 0:
+            open("%s/import/%s_imported%s.csv" % (i_home,filename,current),"a").write(
+                                                '\n'.join(imported))
+        if len(not_imported) > 0:
+            open("%s/import/%s_not_imported%s.csv" % (i_home,filename,current),"a").write(
+                                                '\n'.join(not_imported))
+        em = "Imported: %d, not imported: %d of total %d" % (total_imported,total_not_imported,total)
+        logger.info(em)
+        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
+    ###)
+
     security.declareProtected(ModifyPortalContent,"importReturningStudents")###(
     def importReturningStudents(self):
@@ -1134,5 +1289,5 @@
                 d['core_or_elective'] = getattr(c.getObject().getContent(),'core_or_elective')
                 course_result.getContent().edit(mapping=d)
-                transaction.commit()
+                #transaction.commit()
     ###)
 
Index: WAeUP_SRP/trunk/Widgets.py
===================================================================
--- WAeUP_SRP/trunk/Widgets.py	(revision 1819)
+++ WAeUP_SRP/trunk/Widgets.py	(revision 1820)
@@ -175,4 +175,73 @@
 ###)
 
+class WAeUPStudyModeWidget(CPSSelectWidget): ###(
+    """WAeUP StudyMode widget."""
+    meta_type = 'WAeUP StudyMode Widget'
+    vocabulary = 'entry_modes'
+
+    def _getStudyModes(self):
+        voc = getattr(self.portal_vocabularies,self.vocabulary)
+        d = {}
+        for k,v in voc.items():
+            d[k] = v
+        return d
+
+    def validate(self, datastructure, **kw):
+        """Validate datastructure and update datamodel."""
+        widget_id = self.getWidgetId()
+        value = datastructure[widget_id]
+        try:
+            v = str(value)
+        except ValueError:
+            datastructure.setError(widget_id, "'%s' not a valid session key" % value)
+            return 0
+        studymodes = self._getStudyModes()
+        if not value:
+            v = value = 'ume_ft' 
+        #import pdb;pdb.set_trace()
+        if not studymodes.has_key(value):
+            datastructure.setError(widget_id, "'%s' not a valid session key" % v)
+            return 0
+        if self.is_required and not len(v):
+            datastructure.setError(widget_id, "session key required")
+            return 0
+
+        datamodel = datastructure.getDataModel()
+        datamodel[self.fields[0]] = v
+        return 1
+
+    def render(self, mode, datastructure, **kw):
+        """Render in mode from datastructure."""
+        value = datastructure[self.getWidgetId()]
+        studymodes = self._getStudyModes()
+        if mode == 'view':
+            return escape(studymodes.get(value, value))
+        elif mode == 'edit':
+            html_widget_id = self.getHtmlWidgetId()
+            res = renderHtmlTag('select', name=html_widget_id, id=html_widget_id)
+            in_selection = 0
+            vocabulary_items = studymodes.items()
+            if self.sorted:
+                vocabulary_items.sort(key=operator.itemgetter(1))
+            for k, v in vocabulary_items:
+                kw = {'value': k, 'contents': v}
+                if value == k:
+                    kw['selected'] = 'selected'
+                    in_selection = 1
+                res += renderHtmlTag('option', **kw)
+            if value and not in_selection:
+                kw = {'value': value, 'contents': 'invalid: '+ str(value),
+                      'selected': 'selected'}
+                res += renderHtmlTag('option', **kw)
+            res += '</select>'
+            return res
+        raise RuntimeError('unknown mode %s' % mode)
+
+InitializeClass(WAeUPStudyModeWidget)
+
+widgetRegistry.register(WAeUPStudyModeWidget)
+
+###)
+
 class WAeUPSessionWidget(CPSSelectWidget): ###(
     """WAeUP Session widget."""
@@ -320,6 +389,4 @@
     # XXX make a menu for the vocabulary.
     vocabulary = 'verdicts'
-    translated = False
-    sorted = False
 
     # Associating the widget label with an input area to improve the widget
Index: WAeUP_SRP/trunk/profiles/default/layouts/student_clearance.xml
===================================================================
--- WAeUP_SRP/trunk/profiles/default/layouts/student_clearance.xml	(revision 1819)
+++ WAeUP_SRP/trunk/profiles/default/layouts/student_clearance.xml	(revision 1820)
@@ -305,5 +305,18 @@
   <property name="hidden_readonly_layout_modes"/>
  </widget>
- <widget name="fst_sit_date" meta_type="Date Widget">
+  <widget name="matric_no_history" meta_type="String Widget">
+    <property name="title">Previous Matric No(s)</property>
+    <property name="fields">
+      <element value="matric_no_history"/>
+    </property>
+    <property name="label">Previous Matric No(s)</property>
+    <property name="label_edit">Previous Matric No(s)</property>
+    <property name="readonly_layout_modes"/>
+    <property name="hidden_layout_modes">
+      <element value="create"/>
+    </property>
+    <property name="hidden_readonly_layout_modes"/>
+  </widget>
+  <widget name="fst_sit_date" meta_type="Date Widget">
   <property name="title">Exam Date</property>
   <property name="fields">
@@ -742,4 +755,7 @@
   </row>
   <row>
+   <cell name="matric_no_history"/>
+  </row>
+  <row>
    <cell name="clr_ac_pin"/>
   </row>
Index: WAeUP_SRP/trunk/profiles/default/layouts/student_clearance_fe.xml
===================================================================
--- WAeUP_SRP/trunk/profiles/default/layouts/student_clearance_fe.xml	(revision 1819)
+++ WAeUP_SRP/trunk/profiles/default/layouts/student_clearance_fe.xml	(revision 1820)
@@ -293,17 +293,19 @@
   <property name="allow_resize">True</property>
  </widget>
- <widget name="form_matric_no" meta_type="String Widget">
-  <property name="title">Former Matric/RegNo </property>
-  <property name="fields">
-   <element value="form_matric_no"/>
-  </property>
-  <property name="label">Former Matric/RegNo</property>
-  <property name="label_edit">Former Matric/RegNo</property>
-  <property name="readonly_layout_modes"/>
-  <property name="hidden_layout_modes">
-   <element value="create"/>
-  </property>
-  <property name="hidden_readonly_layout_modes"/>
- </widget>
+  <widget name="matric_no_history" meta_type="Lines Widget">
+    <property name="title">Previous Matric No(s)</property>
+    <property name="fields">
+      <element value="matric_no_history"/>
+    </property>
+    <property name="label">Previous Matric No(s)</property>
+    <property name="label_edit">Previous Matric No(s)</property>
+    <property name="readonly_layout_modes"/>
+    <property name="hidden_layout_modes">
+      <element value="create"/>
+    </property>
+    <property name="hidden_readonly_layout_modes"/>
+    <property name="width">50</property>
+    <property name="height">2</property>
+  </widget>
  <widget name="fst_sit_date" meta_type="Date Widget">
   <property name="title">Exam Date</property>
@@ -746,4 +748,7 @@
   </row>
   <row>
+   <cell name="matric_no_history"/>
+  </row>
+  <row>
    <cell name="clr_ac_pin"/>
   </row>
Index: WAeUP_SRP/trunk/profiles/default/layouts/student_study_course.xml
===================================================================
--- WAeUP_SRP/trunk/profiles/default/layouts/student_study_course.xml	(revision 1819)
+++ WAeUP_SRP/trunk/profiles/default/layouts/student_study_course.xml	(revision 1820)
@@ -20,5 +20,18 @@
   <property name="hidden_readonly_layout_modes"/>
  </widget>
- <widget name="current_session" meta_type="Select Widget">
+  <widget name="study_course_history" meta_type="Lines Widget">
+    <property name="title">Previous Studies</property>
+    <property name="fields">
+      <element value="study_course_history"/>
+    </property>
+    <property name="label">Previous Studies</property>
+    <property name="label_edit">Previous Studies</property>
+    <property name="readonly_layout_modes"/>
+    <property name="hidden_layout_modes"/>
+    <property name="hidden_readonly_layout_modes"/>
+    <property name="width">50</property>
+    <property name="height">2</property>
+  </widget>
+  <widget name="current_session" meta_type="Select Widget">
   <property name="title">Current Study session</property>
   <property name="fields">
@@ -77,4 +90,7 @@
   </row>
   <row>
+   <cell name="study_course_history"/>
+  </row>
+  <row>
    <cell name="current_session"/>
   </row>
Index: WAeUP_SRP/trunk/profiles/default/schemas/student_clearance.xml
===================================================================
--- WAeUP_SRP/trunk/profiles/default/schemas/student_clearance.xml	(revision 1819)
+++ WAeUP_SRP/trunk/profiles/default/schemas/student_clearance.xml	(revision 1820)
@@ -9,4 +9,7 @@
  <field name="matric_no" meta_type="CPS String Field">
    <property name="is_searchabletext">True</property>
+ </field>
+
+ <field name="matric_no_history" meta_type="CPS String List Field">
  </field>
 
Index: WAeUP_SRP/trunk/profiles/default/schemas/student_study_course.xml
===================================================================
--- WAeUP_SRP/trunk/profiles/default/schemas/student_study_course.xml	(revision 1819)
+++ WAeUP_SRP/trunk/profiles/default/schemas/student_study_course.xml	(revision 1820)
@@ -6,4 +6,6 @@
     <property name="is_searchabletext">True</property>
   </field>
+  <field name="study_course_history" meta_type="CPS String List Field">
+  </field>
   <field name="current_session" meta_type="CPS String Field"/>
   <field name="current_mode" meta_type="CPS String Field"/>
