Index: WAeUP_SRP/branches/uli/PatchCPSUserFolderUserFolder.py
===================================================================
--- WAeUP_SRP/branches/uli/PatchCPSUserFolderUserFolder.py	(revision 1614)
+++ WAeUP_SRP/branches/uli/PatchCPSUserFolderUserFolder.py	(revision 1653)
@@ -86,7 +86,9 @@
                                                    "StudentStudyLevel"):
             break
-        # don't test if it is not a proxy 
-        if real_object.portal_type == real_object.meta_type:
-            break
+
+        # don't test if it is not a proxy
+        #if real_object.portal_type == real_object.meta_type:
+        #    break
+        
         # can be later simplified by replacing by students_catalog values - Henrik
         # getattr works always because of acquisition ?! Henrik
@@ -94,5 +96,4 @@
         if sc is None:
             break
-        #from pdb import set_trace;set_trace()
         sc_obj = sc.getContent()
         cert_id = sc_obj.study_course
@@ -121,10 +122,14 @@
                                                 )
         if real_object.portal_type == "StudentStudyLevel":
-            context_obj = getattr(certificate_obj,real_object.getId(),None)
+            if real_object.meta_type != "StudentStudyLevel":
+                context_obj = getattr(certificate_obj,real_object.getId(),None)
+            else:
+                context_obj = getattr(certificate_obj,real_object.aq_parent.getId(),None)
             if context_obj is None:
+                #from pdb import set_trace;set_trace()
                 break
             allowed = set(('CourseAdviser', 'SectionManager'))
         elif real_object.portal_type == "Student" and "CourseAdvisers" in groups:
-            #we need some special processing since CourseAdvisers are only 
+            #we need some special processing since CourseAdvisers are only
             #specified per StudyLevel
             allowed = set(('CourseAdviser', 'SectionManager'))
Index: WAeUP_SRP/branches/uli/PatchCatalogToolXMLAdapter.py
===================================================================
--- WAeUP_SRP/branches/uli/PatchCatalogToolXMLAdapter.py	(revision 1614)
+++ WAeUP_SRP/branches/uli/PatchCatalogToolXMLAdapter.py	(revision 1653)
@@ -21,12 +21,10 @@
         inds[ind.attributes.items()[1][1]] = ind.attributes.items()[0][1]
         #print ind.attributes.items()
-    #print "indexes: ", inds
+    #from pdb import set_trace; set_trace()
     na = node.attributes.items()
     not_found = True
     new_indexes = []
     new_columns = []
-    if na[0][1] in ("WAeUP Table"):
-        not_found = False
-    elif na[0][1] == "CMF Catalog":
+    if na[0][1] in ("CMF Catalog","WAeUP Table"):
         #print na[1][1]
         not_found = False
@@ -49,11 +47,13 @@
             not_found = True
     if not_found:
-        self._initProperties(node)
-        self._initObjects(node)
-        self._initIndexes(node)
+        self._logger.info("%s modified." % na[1][1])
+        #self._initProperties(node)
+        #self._initObjects(node)
+        if new_indexes and len(self.context()) == 0: #disable creation of new indexes if records in the table
+            self._initIndexes(node)
         self._initColumns(node)
-        self._refreshCatalog()
+        #self._refreshCatalog()
 
-    self._logger.info("Catalog tool imported.")
+    self._logger.info("Catalog tool %s imported."  % na[1][1])
     
 from Products.CPSCore.exportimport.catalog import CatalogToolXMLAdapter
Index: WAeUP_SRP/branches/uli/Students.py
===================================================================
--- WAeUP_SRP/branches/uli/Students.py	(revision 1614)
+++ WAeUP_SRP/branches/uli/Students.py	(revision 1653)
@@ -16,4 +16,5 @@
 from Products.CPSCore.CPSMembershipTool import CPSUnrestrictedUser
 from Products.WAeUP_SRP.Academics import makeCertificateCode
+from Products.AdvancedQuery import Eq, Between, Le,In
 import logging
 import csv,re,os
@@ -22,4 +23,6 @@
 i_home = Globals.INSTANCE_HOME
 MAX_TRANS = 1000
+from urllib import urlencode
+
 import DateTime
 # import PIL.Image
@@ -36,4 +39,13 @@
 
 ###)
+
+def response_write(response,s):
+    response.setHeader('Content-type','text/html; charset=ISO-8859-15')
+    while s.find('<') > -1:
+        s = s.replace('<','&lt;')
+    while s.find('>') > -1:
+        #from pdb import set_trace;set_trace()
+        s = s.replace('>','&gt;')
+    response.write("%s<br>\n" % s)
 
 def getInt(s): ###(
@@ -81,6 +93,4 @@
     portal_type = meta_type
     security = ClassSecurityInfo()
-
-
 
     security.declareProtected(ModifyPortalContent,"createDEStudents")###(
@@ -537,4 +547,5 @@
         current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
         students_folder = self.portal_catalog({'meta_type': 'StudentsFolder'})[-1].getObject()
+        #students_folder = self.portal_url().getPortalObject().campus.students
         tr_count = 1
         total = 0
@@ -701,4 +712,103 @@
         logger.info(em)
         return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
+    ###)
+
+    security.declareProtected(ModifyPortalContent,"fixAllNames")###(
+    def fixAllNames(self):
+        "fix all students names"
+        import transaction
+        response = self.REQUEST.RESPONSE
+        logger = logging.getLogger('fixAllNames')
+        logger.info('Start')
+        students = self.portal_catalog(portal_type='Student')
+        count = 0
+        total = 0
+        for student in students:
+            scat_res = self.students_catalog(id = student.getId)
+            if not scat_res:
+                self.students_catalog.addRecord(id = student.getId)
+                scat_res = self.students_catalog(id = student.getId)
+            student_entry = scat_res[0]
+            old_new = self.fixName(student,student_entry)
+            count += 1
+            response_write(response,'"%d","%s",%s' % (count + total,student_entry.id,old_new))
+            if count > 2000:
+                transaction.commit()
+                logger.info("%d transactions commited" % count)
+                total += count
+                count = 0
+    ###)
+
+    security.declareProtected(ModifyPortalContent,"fixName")###(
+    def fixName(self,student_brain, student_entry):
+        "fix the name of a student"
+        fix = "first"
+        if student_entry.get('name_fixed',None) == fix:
+            return "Name already fixed"
+        student_id = student_entry.id
+        new_student = student_entry.jamb_reg_no.startswith('6')
+        student_obj = student_brain.getObject()
+        personal = getattr(student_obj,'personal',None)
+        invalid = ''
+        if personal is None:
+            return '"%s","Returning","%s","%s"' % (invalid,student_entry.name,"not logged in")
+        per_doc = personal.getContent()
+        old_first = per_doc.firstname
+        old_middle = per_doc.middlename
+        old_last = per_doc.lastname
+        new_first = ''
+        new_middle = ''
+        new_last = ''
+        if new_student:
+            if not old_first and not old_middle and old_last:
+                new_names = [n.capitalize() for n in old_last.split()]
+                if len(new_names) > 1:
+                    old_first = new_names[0]
+                    old_last = new_names[-1]
+                    old_middle = ' '.join(new_names[1:-1])
+                else:
+                    old_last = new_names[0]
+                    old_first = ''
+                    old_middle = ''
+            if old_first:
+                new_first = old_first
+            if old_middle:
+                new_middle = old_middle
+            if old_last:
+                new_last = old_last
+            if old_first.find('<') != -1 or\
+               old_first.find('>') != -1 or\
+               old_middle.find('<') != -1 or\
+               old_middle.find('>') != -1 or\
+               old_last.find('<') != -1 or\
+               old_last.find('>') != -1:
+                   invalid = "invalid characters"
+        else:
+            new_first = old_first
+            if new_first.strip() == '-':
+                new_first = ''
+            new_middle = old_middle
+            if new_middle.strip() == '-':
+                new_middle = ''
+            new_last = old_last
+            if new_last.strip() == '-':
+                new_last = ''
+        name = "%(new_first)s %(new_middle)s %(new_last)s" % vars()
+        if new_student:
+            text = "New"
+        else:
+            text = "Returning"
+        old_new = '"%s","%s","%s","%s"' % (invalid,text,
+                                           student_entry.name,
+                                           name)
+        if not invalid:
+            self.students_catalog.modifyRecord(id = student_id,
+                                      name_fixed = fix,
+                                      name = name)
+            per_doc.edit(mapping = {'firstname' : new_first,
+                                'middlename' : new_middle,
+                                'lastname' : new_last,
+                                })
+        return old_new
     ###)
 
@@ -1114,7 +1224,5 @@
     ###)
 
-
-
-    security.declareProtected(View,"fixOwnership")
+    security.declareProtected(View,"fixOwnership") ###(
     def fixOwnership(self):
         """fix Ownership"""
@@ -1125,9 +1233,11 @@
             student.application.manage_setLocalRoles(sid, ['Owner',])
             student.personal.manage_setLocalRoles(sid, ['Owner',])
-
-    security.declareProtected(View,"Title")
+    ###)
+
+    security.declareProtected(View,"Title") ###(
     def Title(self):
         """compose title"""
         return "Student Section"
+    ###)
 
     def generateStudentId(self,letter): ###(
@@ -1146,9 +1256,12 @@
 InitializeClass(StudentsFolder)
 
-def addStudentsFolder(container, id, REQUEST=None, **kw):
+def addStudentsFolder(container, id, REQUEST=None, **kw): ###(
     """Add a Student."""
     ob = StudentsFolder(id, **kw)
     return CPSBase_adder(container, ob, REQUEST=REQUEST)
+    ###)
+
 ###)
+
 
 class Student(CPSDocument): ###(
@@ -1316,23 +1429,26 @@
         return "Level %s" % self.aq_parent.getId()
 
-##    security.declarePublic("gpa")
-##    def gpa(self):
-##        """calculate the gpa"""
-##        sum = 0
-##        course_count = 0
-##        for sc in self.objectValues():
-##            result = sc.getContent()
-##            if not result.grade:
-##                continue
-##            res = self.portal_catalog({'meta_type': 'Course',
-##                                          'id': sc.aq_parent.id})
-##            if len(res) != 1:
-##                continue
-##            course = res[0].getObject().getContent()
-##            sum += course.credits * ['F','E','D','C','B','A'].index(result.grade)
-##            course_count += 1
-##        if course_count:
-##            return sum/course_count
-##        return 0.0
+    def create_course_results(self,cert_id,current_level):
+        "create all courses in a level"
+        aq_portal = self.portal_catalog.evalAdvancedQuery
+        res = self.portal_catalog(portal_type="Certificate", id = cert_id)
+        l = []
+        import transaction
+        if res:
+            cert = res[0]
+            path = cert.getPath()
+            query = Eq("path","%s/%s" % (path,current_level)) &\
+                    Eq('portal_type','CertificateCourse')
+            courses = aq_portal(query)
+            #from pdb import set_trace;set_trace()
+            self_proxy = self.aq_parent
+            for c in courses:
+                d = self.getCourseInfo(c.getId)
+                cr_id = self_proxy.invokeFactory('StudentCourseResult',c.getId)
+                course_result = getattr(self_proxy,cr_id)
+                self.portal_workflow.doActionFor(course_result,'open')
+                d['core_or_elective'] = getattr(c.getObject().getContent(),'core_or_elective')
+                course_result.getContent().edit(mapping=d)
+                transaction.commit()
 
 InitializeClass(StudentStudyLevel)
Index: WAeUP_SRP/branches/uli/WAeUPTables.py
===================================================================
--- WAeUP_SRP/branches/uli/WAeUPTables.py	(revision 1614)
+++ WAeUP_SRP/branches/uli/WAeUPTables.py	(revision 1653)
@@ -22,8 +22,9 @@
 from Globals import InitializeClass
 from Products.ZCatalog.ZCatalog import ZCatalog
+from Products.ZCatalog.ProgressHandler import ZLogHandler
 from AccessControl import ClassSecurityInfo
 from Products.CMFCore.permissions import ModifyPortalContent
 
-import DateTime
+import DateTime,time
 import csv,re
 import logging
@@ -48,4 +49,21 @@
     implements(IWAeUPTable)
     security = ClassSecurityInfo()
+
+    def refreshCatalog(self, clear=0, pghandler=None):
+        """ don't refresh for a normal table """
+
+        if self.REQUEST and self.REQUEST.RESPONSE:
+            self.REQUEST.RESPONSE.redirect(
+              URL1 +
+              '/manage_catalogAdvanced?manage_tabs_message=Catalog%20refresh%20not%20implemented')
+
+    def manage_catalogClear(self, REQUEST=None, RESPONSE=None, URL1=None):
+        """ clears the whole enchilada """
+        #self._catalog.clear()
+
+        if REQUEST and RESPONSE:
+            RESPONSE.redirect(
+              URL1 +
+              '/manage_catalogAdvanced?manage_tabs_message=Catalog%20Clearing%20disabled')
 
     def addRecord(self, **data):
@@ -75,7 +93,4 @@
             raise KeyError("No record for uid %s" % uid)
         record = records[0]
-        record_data = {}
-        for field in self.schema() + self.indexes():
-            record_data[field] = getattr(record, field)
         record_data = {}
         for field in self.schema() + self.indexes():
@@ -210,10 +225,214 @@
 
 class StudentsCatalog(WAeUPTable): ###(
+    security = ClassSecurityInfo()
 
     meta_type = 'WAeUP Students Catalog'
     name = "students_catalog"
     key = "id"
+    interesting_types = ('Student',
+                         'StudentApplication',
+                         'StudentCLearance',
+                         'StudentPersonal',
+                         'StudentStudyCourse',
+                         )
+
     def __init__(self):
         WAeUPTable.__init__(self, 'students_catalog')
+        return
+
+    def get_review_state(self,sid,application_doc,clearance_doc,personal_doc,study_course_doc): ###(
+        "return the students review_state from portal_catalog"
+        cat_res = self.portal_catalog(id = sid)
+        if len(cat_res) != 1:
+            return None
+        return cat_res[0].review_state
+
+    def get_course(self,sid,application_doc,clearance_doc,personal_doc,study_course_doc):
+        "return the students study_course"
+        if study_course_doc is None:
+            return None
+        return getattr(study_course_doc,'study_course',None)
+
+    def get_department(self,sid,application_doc,clearance_doc,personal_doc,study_course_doc):
+        "return the students department"
+        if study_course_doc is None:
+            return None
+        certificate_res = self.portal_catalog(id = study_course_doc.study_course)
+        if len(certificate_res) != 1:
+            return None
+        return certificate_res[0].getPath().split('/')[-3]
+
+    def get_email(self,sid,application_doc,clearance_doc,personal_doc,study_course_doc):
+        "return the students email from the personal"
+        if personal_doc is None:
+            return None
+        return getattr(personal_doc,'email',None)
+
+    def get_entry_mode(self,sid,application_doc,clearance_doc,personal_doc,study_course_doc):
+        "return the students entry_mode from the application"
+        if application_doc is None:
+            return None
+        return getattr(application_doc,'entry_mode',None)
+
+    def get_jamb_reg_no(self,sid,application_doc,clearance_doc,personal_doc,study_course_doc):
+        "return the students jamb_reg_no from the application"
+        if application_doc is None:
+            return None
+        return getattr(application_doc,'jamb_reg_no',None)
+
+    def get_faculty(self,sid,application_doc,clearance_doc,personal_doc,study_course_doc):
+        "return the students faculty"
+        if study_course_doc is None:
+            return None
+        certificate_res = self.portal_catalog(id = study_course_doc.study_course)
+        if len(certificate_res) != 1:
+            return None
+        return certificate_res[0].getPath().split('/')[-4]
+
+    def get_level(self,sid,application_doc,clearance_doc,personal_doc,study_course_doc):
+        "return the students study_course"
+        if study_course_doc is None:
+            return None
+        #from pdb import set_trace;set_trace()
+        return getattr(study_course_doc,'current_level',None)
+
+    def get_matric_no(self,sid,application_doc,clearance_doc,personal_doc,study_course_doc):
+        "return the students matric_no from the clearance "
+        if clearance_doc is None:
+            return None
+        return getattr(clearance_doc,'matric_no',None)
+
+    def get_name(self,sid,application_doc,clearance_doc,personal_doc,study_course_doc):
+        "return the students name from the personal"
+        if personal_doc is None:
+            return None
+        doc = personal_doc
+        return "%s %s %s" % (doc.firstname,doc.middlename,doc.lastname)
+
+    def get_phone(self,sid,application_doc,clearance_doc,personal_doc,study_course_doc):
+        "return the students phone from the personal"
+        if personal_doc is None:
+            return None
+        return getattr(personal_doc,'phone',None)
+
+    def get_sex(self,sid,application_doc,clearance_doc,personal_doc,study_course_doc):
+        "return the students sex from the personal"
+        if personal_doc is None:
+            return None
+        return getattr(personal_doc,'sex',None)
+
+    def get_verdict(self,sid,application_doc,clearance_doc,personal_doc,study_course_doc):
+        "return the students study_course"
+        if study_course_doc is None:
+            return None
+        return getattr(study_course_doc,'current_verdict',None)
+    ###)
+
+    def refreshCatalog(self, clear=0, pghandler=None): ###(
+        """ re-index everything we can find """
+        students_folder = self.portal_url.getPortalObject().campus.students
+
+        cat = self._catalog
+        paths = self._catalog.uids.items()
+        if clear:
+            paths = tuple(paths)
+            cat.clear()
+
+        num_objects = len(paths)
+        if pghandler:
+            pghandler.init('Refreshing catalog: %s' % self.absolute_url(1), num_objects)
+        for i in xrange(num_objects):
+            if pghandler: pghandler.report(i)
+            p = paths[i]
+            sid = p[0]
+            pcat_res = self.portal_catalog(id=sid)
+            if len(pcat_res) != 1:
+                continue
+            student_brain = pcat_res[0]
+            student_obj = student_brain.getObject()
+            if student_obj.hasObject('application'):
+                application_doc = getattr(student_obj,'application').getContent()
+            else:
+                application_doc = None
+            if student_obj.hasObject('clearance'):
+                clearance_doc = getattr(student_obj,'clearance').getContent()
+            else:
+                clearance_doc = None
+            if student_obj.hasObject('personal'):
+                personal_doc = getattr(student_obj,'personal').getContent()
+            else:
+                personal_doc = None
+            if student_obj.hasObject('study_course'):
+                study_course_doc = getattr(student_obj,'study_course').getContent()
+            else:
+                study_course_doc = None
+            data = {}
+            data['id'] = sid
+            for field in self.schema():
+                function = getattr(self,"get_%s" % field, None)
+                if function is None:
+                    continue
+                value = function(sid,application_doc,clearance_doc,personal_doc,study_course_doc)
+                if value is not None:
+                    data[field] = value
+            self.modifyRecord(**data)
+        if pghandler: pghandler.finish()
+    ###)
+
+    def manage_catalogReindex(self, REQUEST, RESPONSE, URL1):
+        """ clear the catalog, then re-index everything """
+
+        elapse = time.time()
+        c_elapse = time.clock()
+
+        pgthreshold = self._getProgressThreshold()
+        handler = (pgthreshold > 0) and ZLogHandler(pgthreshold) or None
+        self.refreshCatalog(clear=0, pghandler=handler)
+
+        elapse = time.time() - elapse
+        c_elapse = time.clock() - c_elapse
+
+        RESPONSE.redirect(
+            URL1 +
+            '/manage_catalogAdvanced?manage_tabs_message=' +
+            urllib.quote('Catalog Updated \n'
+                         'Total time: %s\n'
+                         'Total CPU time: %s' % (`elapse`, `c_elapse`)))
+
+
+    security.declarePrivate('notify_event_listener')
+    def notify_event_listener(self,event_type,object,infos):
+        "listen for events"
+        pt = object.portal_type
+        mt = object.meta_type
+        students_catalog = self.students_catalog
+        #if pt not in self.interesting_types:
+        #    return
+        #print "%(pt)s\n %(event_type)s \n %(infos)s\n" % vars()
+        if not infos.has_key('rpath'):
+            return
+        if pt == 'Student' and event_type == "workflow":
+            pass
+        elif mt == 'StudentApplication':
+            if event_type not in ('sys_modify_object'):
+                return
+            print "%(pt)s\n %(event_type)s \n %(infos)s\n" % vars()
+            from pdb import set_trace;set_trace()
+            jamb_reg_no = getattr(object,'jamb_reg_no',None)
+            if jamb_reg_no is None:
+                return
+            student_id = infos['rpath'].split('/')[2]
+            self.fixName(student_id)
+            student_entry = students_catalog(id = student_id)[0]
+            if student_entry.jamb_reg_no == jamb_reg_no:
+                return
+            students_catalog.modifyRecord(id = student_id,
+                                          jamb_reg_no = jamb_reg_no)
+        elif mt == 'StudentPersonal':
+            if event_type not in ('sys_modify_object'):
+                return
+            print "%(pt)s\n %(event_type)s \n %(infos)s\n" % vars()
+            student_id = infos['rpath'].split('/')[2]
+            self.fixName(student_id)
 
 
@@ -234,4 +453,16 @@
 ###)
 
+class OnlinePaymentsImport(WAeUPTable): ###(
+
+    meta_type = 'WAeUP Online Payment Transactions'
+    name = "online_payments_import"
+    key = "order_id"
+    def __init__(self):
+        WAeUPTable.__init__(self, self.name)
+
+
+InitializeClass(CoursesCatalog)
+###)
+
 class ReturningImport(WAeUPTable): ###(
 
Index: WAeUP_SRP/branches/uli/WAeUPTool.py
===================================================================
--- WAeUP_SRP/branches/uli/WAeUPTool.py	(revision 1614)
+++ WAeUP_SRP/branches/uli/WAeUPTool.py	(revision 1653)
@@ -38,9 +38,8 @@
 p_home = package_home(globals())
 i_home = INSTANCE_HOME
-import logging,os
+import DateTime
+import logging
 import transaction
-
-
-
+import csv,re,os
 
 class WAeUPTool(UniqueObject, SimpleItem, ActionProviderBase):
@@ -113,5 +112,5 @@
     ###)
 
-    security.declareProtected(ModifyPortalContent,'doCommit') ###(
+    security.declareProtected(View,'doCommit') ###(
     def doCommit(self,logger=None):
         "commit some transactions"
@@ -532,3 +531,82 @@
     ###)
 
+    security.declareProtected(ModifyPortalContent,"importOnlinePaymentTransactions")###(
+    def importOnlinePaymentTransactions(self):
+        """load Online Payment Transactions from CSV values"""
+        import transaction
+        import random
+        #from pdb import set_trace
+        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
+        opt = self.online_payments_import
+        students_folder = self.portal_url.getPortalObject().campus.students
+        start = True
+        tr_count = 1
+        total = 0
+        #name = 'pume_results'
+        name = 'OnlineTransactions'
+        no_import = []
+        imported = []
+        logger = logging.getLogger('WAeUPTool.importOnlinePaymentTransactions')
+        try:
+            transactions = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
+        except:
+            logger.error('Error reading %s.csv' % name)
+            return
+        for pay_transaction in transactions:
+            if start:
+                start = False
+                logger.info('Start loading from %s.csv' % name)
+                s = ','.join(['"%s"' % fn for fn in pay_transaction.keys()])
+                no_import.append('%s,"Error"' % s)
+                format = ','.join(['"%%(%s)s"' % fn for fn in pay_transaction.keys()])
+                format_error = format + ',"%(Error)s"'
+            data = {}
+
+            # format of the first file sent from Tayo
+            #data['datetime'] = date = DateTime.DateTime(pay_transaction['Date'])
+            #data['student_id'] = student_id = pay_transaction['Payer ID']
+            #data['order_id'] = order_id = pay_transaction['Order ID (Tranx Ref)']
+            #data['response_code'] = response_code = pay_transaction['Resp Code']
+            #data['amount'] = amount = pay_transaction['Amount']
+
+            # format of the second file sent from Tayo
+            data['datetime'] = date = 0
+            data['student_id'] = student_id = pay_transaction['Payer ID']
+            data['order_id'] = order_id = pay_transaction['Order ID (Tranx Ref)']
+            data['response_code'] = response_code = '00'
+            data['amount'] = amount = pay_transaction['Amount']
+
+            dup = False
+            if response_code == "12":
+                continue
+            try:
+                opt.addRecord(**data)
+            except ValueError:
+                dup = True
+            #from pdb import set_trace;set_trace()
+            if dup:
+                if response_code == "00":
+                    opt.modifyRecord(**data)
+                else:
+                    pay_transaction['Error'] = "Duplicate order Id"
+                    no_import.append( format_error % pay_transaction)
+                    logger.info("dupplicate order_id %(order_id)s for %(student_id)s %(response_code)s" % data)
+                    continue
+            tr_count += 1
+            if tr_count > 1000:
+                if len(no_import) > 0:
+                    open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
+                             '\n'.join(no_import) + '\n')
+                    no_import = []
+                em = '%d transactions committed\n' % (tr_count)
+                transaction.commit()
+                regs = []
+                logger.info(em)
+                total += tr_count
+                tr_count = 0
+        open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
+                                                '\n'.join(no_import))
+        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
+    ###)
+
 InitializeClass(WAeUPTool)
Index: WAeUP_SRP/branches/uli/doc/srp_documentation.mm
===================================================================
--- WAeUP_SRP/branches/uli/doc/srp_documentation.mm	(revision 1614)
+++ WAeUP_SRP/branches/uli/doc/srp_documentation.mm	(revision 1653)
@@ -8,5 +8,5 @@
 </node>
 <node CREATED="1172489529057" ID="Freemind_Link_43083883" MODIFIED="1172489545651" POSITION="right" TEXT="SRP Data Structure">
-<node CREATED="1170079621592" FOLDED="true" ID="Freemind_Link_1297017754" MODIFIED="1170079640872" TEXT="Campus">
+<node CREATED="1170079621592" ID="Freemind_Link_1297017754" MODIFIED="1170079640872" TEXT="Campus">
 <node CREATED="1171710559043" ID="Freemind_Link_1592396213" MODIFIED="1171710565212" TEXT="Id: campus"/>
 <node CREATED="1170079643589" FOLDED="true" ID="Freemind_Link_1231068129" MODIFIED="1171710686426" TEXT="Academic Section">
@@ -48,8 +48,8 @@
 </node>
 </node>
-<node CREATED="1170082138244" FOLDED="true" ID="Freemind_Link_1354366927" MODIFIED="1171710679266" TEXT="Student Section">
+<node CREATED="1170082138244" ID="Freemind_Link_1354366927" MODIFIED="1171710679266" TEXT="Student Section">
 <node CREATED="1171709784119" ID="_" MODIFIED="1171709937449" TEXT="Type: StudentsFolder" VSHIFT="104"/>
 <node CREATED="1171710545564" ID="Freemind_Link_221165828" MODIFIED="1171710551332" TEXT="Id: students"/>
-<node CREATED="1170082147831" FOLDED="true" ID="Freemind_Link_115332414" MODIFIED="1171709774415" TEXT="{Student}">
+<node CREATED="1170082147831" ID="Freemind_Link_115332414" MODIFIED="1171709774415" TEXT="{Student}">
 <node CREATED="1171114205479" ID="Freemind_Link_1051911128" LINK="../profiles/default/types/Student.xml" MODIFIED="1171353141707" TEXT="Type: Student"/>
 <node CREATED="1171124926993" ID="Freemind_Link_1838352082" LINK="../profiles/default/schemas/student.xml" MODIFIED="1171353152905" TEXT="Schema: student"/>
@@ -171,5 +171,5 @@
 </node>
 </node>
-<node CREATED="1170082392807" FOLDED="true" ID="Freemind_Link_1979443941" MODIFIED="1171711179966" TEXT="Study Course">
+<node CREATED="1170082392807" ID="Freemind_Link_1979443941" MODIFIED="1171711179966" TEXT="Study Course">
 <node CREATED="1170930140692" ID="Freemind_Link_607082969" MODIFIED="1171009488850" TEXT="Id: study_course"/>
 <node CREATED="1170930264337" ID="Freemind_Link_1384807180" LINK="../profiles/default/types/StudentStudyCourse.xml" MODIFIED="1172159914623" TEXT="Type: StudentStudyCourse"/>
Index: WAeUP_SRP/branches/uli/exportimport.py
===================================================================
--- WAeUP_SRP/branches/uli/exportimport.py	(revision 1614)
+++ WAeUP_SRP/branches/uli/exportimport.py	(revision 1653)
@@ -90,5 +90,5 @@
                                               roles=('SectionReader',))
             students.manage_setLocalGroupRoles(groupid = 'CourseAdvisers',
-                                              roles=('SectionReader',))                                              
+                                              roles=('SectionReader',))
             students.manage_setLocalGroupRoles(groupid='MemberAdmins',
                                          roles=('SectionOfficer',))
@@ -120,4 +120,5 @@
     importWAeUPTable(site.courses_catalog, '', context,'courses_catalog')
     importWAeUPTable(site.payments_catalog, '', context,'payments_catalog')
+    importWAeUPTable(site.online_payments_import, '', context,'online_payments_import')
     importWAeUPTable(site.portal_pins, '', context,'pins')
     importWAeUPTable(site.portal_pumeresults, '', context,'pumeresults')
Index: WAeUP_SRP/branches/uli/profiles/default/actions.xml
===================================================================
--- WAeUP_SRP/branches/uli/profiles/default/actions.xml	(revision 1614)
+++ WAeUP_SRP/branches/uli/profiles/default/actions.xml	(revision 1653)
@@ -177,5 +177,5 @@
   <action title="Change Password" action_id="change_password"
      category="student" condition_expr="member"
-     url_expr="string:${portal_url}/change_password" visible="True">
+     url_expr="string:${portal_url}/change_password" visible="False">
    <permission>View</permission>
   </action>
Index: WAeUP_SRP/branches/uli/profiles/default/courses_catalog.xml
===================================================================
--- WAeUP_SRP/branches/uli/profiles/default/courses_catalog.xml	(revision 1614)
+++ WAeUP_SRP/branches/uli/profiles/default/courses_catalog.xml	(revision 1653)
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
 <?xml-stylesheet type="text/xsl" href="catalog.xsl"?>
-<object name="courses_catalog" meta_type="WAeUP Table">
+<object name="courses_catalog" meta_type="CMF Catalog">
  <column value="code"/>
  <column value="faculty"/>
Index: WAeUP_SRP/branches/uli/profiles/default/layouts/student_change_password.xml
===================================================================
--- WAeUP_SRP/branches/uli/profiles/default/layouts/student_change_password.xml	(revision 1614)
+++ WAeUP_SRP/branches/uli/profiles/default/layouts/student_change_password.xml	(revision 1653)
@@ -35,5 +35,5 @@
     <property name="hidden_readonly_layout_modes"/>
     <property name="password_widget"></property>
-    <property name="check_digit">False</property>
+    <property name="check_digit">True</property>
     <property name="size_min">6</property>
     <property name="size_max">10</property>
Index: WAeUP_SRP/branches/uli/profiles/default/online_payments_import.xml
===================================================================
--- WAeUP_SRP/branches/uli/profiles/default/online_payments_import.xml	(revision 1653)
+++ WAeUP_SRP/branches/uli/profiles/default/online_payments_import.xml	(revision 1653)
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="catalog.xsl"?>
+<object name="online_payments_import" meta_type="WAeUP Table">
+ <column value="datetime"/>
+ <column value="student_id"/>
+ <column value="order_id"/>
+ <column value="response_code"/>
+ <column value="amount"/>
+ <index name="student_id" meta_type="FieldIndex">
+  <indexed_attr value="student_id"/>
+ </index>
+ <index name="datetime" meta_type="DateIndex">
+  <indexed_attr value="datetime"/>
+ </index>
+ <index name="order_id" meta_type="FieldIndex">
+  <indexed_attr value="order_id"/>
+ </index>
+</object>
Index: WAeUP_SRP/branches/uli/profiles/default/schemas/payment.xml
===================================================================
--- WAeUP_SRP/branches/uli/profiles/default/schemas/payment.xml	(revision 1614)
+++ WAeUP_SRP/branches/uli/profiles/default/schemas/payment.xml	(revision 1653)
@@ -6,5 +6,5 @@
   <field name="type_description" meta_type="CPS String Field" >
     <property name="is_searchabletext">True</property>
-  </field> <field name="order_id" meta_type="CPS String Field"/>
+  </field> 
   <field name="amount" meta_type="CPS String Field"/>
   <field name="resp_pay_reference" meta_type="CPS String Field"/>
Index: WAeUP_SRP/branches/uli/profiles/default/schemas/student_study_level.xml
===================================================================
--- WAeUP_SRP/branches/uli/profiles/default/schemas/student_study_level.xml	(revision 1614)
+++ WAeUP_SRP/branches/uli/profiles/default/schemas/student_study_level.xml	(revision 1653)
@@ -4,7 +4,6 @@
  <field name="code" meta_type="CPS String Field"/>
  <field name="session" meta_type="CPS String Field"/>
- <field name="gpa" meta_type="CPS Float Field"/>
- <field name="status" meta_type="CPS String Field"/>
  <field name="verdict" meta_type="CPS String Field"/>
-  <field name="imported_gpa" meta_type="CPS Float Field"/>
+ <field name="validated_by" meta_type="CPS String Field"/>
+ <field name="validation_date" meta_type="CPS DateTime Field"/>
 </object>
Index: WAeUP_SRP/branches/uli/profiles/default/students_catalog.xml
===================================================================
--- WAeUP_SRP/branches/uli/profiles/default/students_catalog.xml	(revision 1614)
+++ WAeUP_SRP/branches/uli/profiles/default/students_catalog.xml	(revision 1653)
@@ -19,8 +19,8 @@
  </index>
  <index name="jamb_reg_no" meta_type="FieldIndex">
-  <indexed_attr value="student_application:jamb_reg_no"/>
+  <indexed_attr value="jamb_reg_no"/>
  </index>
  <index name="matric_no" meta_type="FieldIndex">
-  <indexed_attr value="student_clearance:matric_no"/>
+  <indexed_attr value="matric_no"/>
  </index>
  <index name="faculty" meta_type="KeywordIndex">
@@ -28,5 +28,5 @@
  </index>
  <index name="entry_mode" meta_type="KeywordIndex">
-  <indexed_attr value="student_application:entry_mode"/>
+  <indexed_attr value="entry_mode"/>
  </index>
  <index name="department" meta_type="KeywordIndex">
@@ -34,11 +34,11 @@
  </index>
  <index name="level" meta_type="KeywordIndex">
-  <indexed_attr value="student_study_course:current_level"/>
+  <indexed_attr value="current_level"/>
  </index>
  <index name="verdict" meta_type="KeywordIndex">
-  <indexed_attr value="student_study_course:current_verdict"/>
+  <indexed_attr value="current_verdict"/>
  </index>
  <index name="course" meta_type="KeywordIndex">
-  <indexed_attr value="student_study_course:study_course"/>
+  <indexed_attr value="study_course"/>
  </index>
 </object>
Index: WAeUP_SRP/branches/uli/profiles/default/toolset.xml
===================================================================
--- WAeUP_SRP/branches/uli/profiles/default/toolset.xml	(revision 1614)
+++ WAeUP_SRP/branches/uli/profiles/default/toolset.xml	(revision 1653)
@@ -7,4 +7,6 @@
  <required tool_id="payments_catalog"
            class="Products.WAeUP_SRP.WAeUPTables.PaymentsCatalog"/>
+ <required tool_id="online_payments_import"
+           class="Products.WAeUP_SRP.WAeUPTables.OnlinePaymentsImport"/>
  <required tool_id="portal_pins"
            class="Products.WAeUP_SRP.WAeUPTables.PinTable"/>
Index: WAeUP_SRP/branches/uli/profiles/default/workflows/waeup_student_subobject_wf/definition.xml
===================================================================
--- WAeUP_SRP/branches/uli/profiles/default/workflows/waeup_student_subobject_wf/definition.xml	(revision 1614)
+++ WAeUP_SRP/branches/uli/profiles/default/workflows/waeup_student_subobject_wf/definition.xml	(revision 1653)
@@ -9,5 +9,7 @@
  <permission>Modify portal content</permission>
  <permission>View</permission>
+ <permission>View</permission>
  <state state_id="closed" title="">
+  <exit-transition transition_id="create_content"/>
   <exit-transition transition_id="open"/>
   <permission-map name="Add portal content" acquired="True">
@@ -103,5 +105,5 @@
              new_state="closed" trigger="USER"
              before_script="" after_script="">
-  
+
   <guard>
    <guard-role>SectionOfficer</guard-role>
@@ -115,5 +117,5 @@
              new_state="content_addable" trigger="USER"
              before_script="" after_script="">
-  
+
   <guard>
    <guard-role>SectionOfficer</guard-role>
@@ -127,5 +129,5 @@
              new_state="created" trigger="USER"
              before_script="" after_script="">
-  
+
   <guard>
   </guard>
@@ -136,5 +138,5 @@
              new_state="" trigger="USER" before_script=""
              after_script="">
-  
+
   <guard>
   </guard>
@@ -144,5 +146,5 @@
              new_state="opened" trigger="USER"
              before_script="" after_script="">
-  
+
   <guard>
    <guard-role>SectionOfficer</guard-role>
Index: WAeUP_SRP/branches/uli/skins/waeup_academics/getCertificateInfo.py
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_academics/getCertificateInfo.py	(revision 1614)
+++ WAeUP_SRP/branches/uli/skins/waeup_academics/getCertificateInfo.py	(revision 1653)
@@ -18,5 +18,5 @@
 
 info = {}
-info['action'] = "%s" % context.campus.absolute_url()
+info['action'] = "%s" % context.absolute_url()
 info['choosen_ids'] = request.get('ids',[])
 info['doc'] = context.getContent()
Index: WAeUP_SRP/branches/uli/skins/waeup_academics/getLevelInfo.py
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_academics/getLevelInfo.py	(revision 1614)
+++ WAeUP_SRP/branches/uli/skins/waeup_academics/getLevelInfo.py	(revision 1653)
@@ -16,4 +16,5 @@
 wf = context.portal_workflow
 mtool = context.portal_membership
+academics_path = "%s/campus/academics" % context.portal_url()
 path_info = request.get('PATH_INFO').split('/')
 try:
@@ -44,5 +45,5 @@
     ro = r.getObject()
     rd = ro.getContent()
-    row['id'] = r.getId
+    course_id = row['id'] = r.getId
     row['title'] = rd.Title()
     row['core'] = rd.core_or_elective
@@ -50,5 +51,10 @@
     row['url'] = ro.absolute_url()
     row['review_state'] = wf.getInfoFor(ro,'review_state','None')
-    row['is_editable'] = mtool.checkPermission('Modify portal content', ro)
+    editable = row['is_editable'] = mtool.checkPermission('Modify portal content', ro)
+    if editable:
+        course_res = context.courses_catalog(code=course_id)
+        if course_res:
+            rc = course_res[0]
+            row['real_course_path'] = "%s/%s/%s/courses/%s" % (academics_path,rc.faculty,rc.department,course_id)
     if rd.semester == 'first':
         first.append(row)
Index: WAeUP_SRP/branches/uli/skins/waeup_academics/level_view.pt
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_academics/level_view.pt	(revision 1614)
+++ WAeUP_SRP/branches/uli/skins/waeup_academics/level_view.pt	(revision 1653)
@@ -48,4 +48,8 @@
                     [edit]
                     </a> 
+                <a tal:condition="row/real_course_path|nothing" 
+                   href="edit" tal:attributes="href string:${row/real_course_path}">
+                    [goto course]
+                    </a> 
                 </td>
               </tr>
Index: WAeUP_SRP/branches/uli/skins/waeup_default/mail2admin.py
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_default/mail2admin.py	(revision 1614)
+++ WAeUP_SRP/branches/uli/skins/waeup_default/mail2admin.py	(revision 1653)
@@ -37,5 +37,5 @@
      email,
      'kehindesamuel@waeup.org',
-     'henrik@waeup.org',
+     'waeup@saoas.org',
 #    'js@aixtraware.de',
      email,
Index: WAeUP_SRP/branches/uli/skins/waeup_epayment/check_online_payments.py
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_epayment/check_online_payments.py	(revision 1653)
+++ WAeUP_SRP/branches/uli/skins/waeup_epayment/check_online_payments.py	(revision 1653)
@@ -0,0 +1,69 @@
+## Script (Python) "check_online_payments"
+##bind container=container
+##bind context=context
+##bind namespace=
+##bind script=script
+##bind subpath=traverse_subpath
+##parameters=
+##title=
+##
+# $Id$
+"""
+payment callback
+"""
+import logging
+logger = logging.getLogger('Skins.check_online_payments')
+from AccessControl import Unauthorized
+import DateTime
+if context.portal_membership.isAnonymousUser():
+    return None
+
+request = context.REQUEST
+response = request.RESPONSE
+students = context.portal_url.getPortalObject().campus.students
+wftool = context.portal_workflow
+mtool = context.portal_membership
+member = mtool.getAuthenticatedMember()
+member_id = str(member)
+student_id = context.getStudentId()
+online_transactions = context.online_payments_import
+try:
+    from Products.zdb import set_trace
+except:
+    def set_trace():
+        pass
+def rwrite(s):
+    response.setHeader('Content-type','text/html; charset=ISO-8859-15')
+    response.write("%s<br>\n" % s)
+try:
+    from Products.AdvancedQuery import Eq, Between, Le,In
+    aq_portal = context.portal_catalog.evalAdvancedQuery
+    aq_students = context.students_catalog.evalAdvancedQuery
+except:
+    aq_portal = None
+
+query1 = Eq('portal_type','Payment')
+query2 = Eq('SearchableText',"Approved Successful")	 	
+online_payments = aq_portal(query1 & query2)
+set_trace()
+online_transactions = context.online_payments_import
+
+for op_brain in online_payments:
+    student_id = op_brain.getPath().split('/')[-3]
+    payment_doc = op_brain.getObject().getContent()
+    order_id = "%s%s" % (student_id[1:],op_brain.getId[1:])
+    transactions = online_transactions(student_id = student_id)
+    payment_id = op_brain.getId
+    if payment_doc.resp_code == "00" and not transactions:
+        rwrite('"%s","%s","no transaction for successfull payment","","%s"' % (student_id,payment_id,payment_doc.date))
+        continue
+    for transaction in transactions:
+        t_order_id = transaction.order_id
+        if t_order_id == order_id:
+            rwrite('"%s","%s","%s","%s","%s"' % (student_id,
+                                                                        op_brain.getId,
+                                                                        transaction.response_code,
+                                                                        payment_doc.resp_code,
+                                                                        payment_doc.date
+                                                                        ))
+            continue
Index: WAeUP_SRP/branches/uli/skins/waeup_epayment/check_transactions.py
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_epayment/check_transactions.py	(revision 1653)
+++ WAeUP_SRP/branches/uli/skins/waeup_epayment/check_transactions.py	(revision 1653)
@@ -0,0 +1,92 @@
+## Script (Python) "check_transactions"
+##bind container=container
+##bind context=context
+##bind namespace=
+##bind script=script
+##bind subpath=traverse_subpath
+##parameters=
+##title=
+##
+# $Id$
+"""
+payment callback
+"""
+import logging
+logger = logging.getLogger('Skins.check_transactions')
+from AccessControl import Unauthorized
+import DateTime
+if context.portal_membership.isAnonymousUser():
+    return None
+
+request = context.REQUEST
+response = request.RESPONSE
+students = context.portal_url.getPortalObject().campus.students
+wftool = context.portal_workflow
+mtool = context.portal_membership
+member = mtool.getAuthenticatedMember()
+member_id = str(member)
+student_id = context.getStudentId()
+online_transactions = context.online_payments_import
+def rwrite(s):
+    response.setHeader('Content-type','text/html; charset=ISO-8859-15')
+    response.write("%s<br>\n" % s)
+correct = 0
+count = 0
+approved = 0
+for ot_brain in online_transactions():
+    student_id = ot_brain.student_id
+    if not students.hasObject(student_id):
+        rwrite("%s not found" % student_id)
+        continue
+    student_obj = getattr(students,student_id)
+    if not student_obj.hasObject('payments'):
+        rwrite("%s payments-folder not found" % student_id)
+        continue
+    payments_folder = getattr(student_obj,'payments')
+    payment_id = "p%s" % ot_brain.order_id[6:]
+    if not payments_folder.hasObject(payment_id):
+        rwrite("%s payment %s not found" % (student_id,payment_id))
+        continue
+    payment_obj = getattr(payments_folder,payment_id)
+    payment_doc = payment_obj.getContent()
+    response_code = ot_brain.response_code
+    count +=1
+    if payment_doc.resp_code != response_code:
+        rwrite('"%d","%d","%s","%s","%s","%s"' % (
+                                                  count,correct,
+                                                  student_id,
+                                                  payment_id,
+                                                  response_code,
+                                                  payment_doc.resp_code
+                                                  ))
+    elif payment_doc.resp_code == response_code:
+        correct +=1
+        rwrite('"%d","%d","%s","%s","%s","%s"' % (
+                                                  count,correct,
+                                                  student_id,
+                                                  payment_id,
+                                                  response_code,
+                                                  payment_doc.resp_code
+                                                  ))
+    if payment_doc.resp_code == "" and response_code == "00":
+        pd = {}
+        review_state = wftool.getInfoFor(payment_obj,'review_state',None)
+        if review_state != "opened":
+            logger.info('payment object of %s closed' % (student_id))
+            continue
+        review_state = wftool.getInfoFor(student_obj,'review_state',None)
+        if review_state != "cleared_and_validated":
+            logger.info('%s review_state = %s' % (student_id,review_state))
+            continue
+        pd['resp_code'] = 'IP'
+        pd['resp_desc'] = 'Payment approved by import, %s' % (DateTime.DateTime())
+        payment_doc.edit(mapping=pd)
+        if payment_doc.type_description.startswith('School Fee'):
+            wftool.doActionFor(student_obj,'pay_school_fee')
+        logger.info('%s approves epayment for %s by import' % (member,student_id))
+        wftool.doActionFor(payment_obj,'close')
+        approved += 1
+        if approved > 50:
+            context.waeup_tool.doCommit()
+            logger.info('%s transactions commited' % (approved))
+            approved = 0
Index: WAeUP_SRP/branches/uli/skins/waeup_epayment/epayment_cb.py
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_epayment/epayment_cb.py	(revision 1614)
+++ WAeUP_SRP/branches/uli/skins/waeup_epayment/epayment_cb.py	(revision 1653)
@@ -14,4 +14,5 @@
 import logging
 logger = logging.getLogger('Skins.epayment_cb')
+from AccessControl import Unauthorized
 import DateTime
 if context.portal_membership.isAnonymousUser():
@@ -21,6 +22,14 @@
 students = context.portal_url.getPortalObject().campus.students
 wftool = context.portal_workflow
+mtool = context.portal_membership
+member = mtool.getAuthenticatedMember()
+member_id = str(member)
 student_id = context.getStudentId()
-if student_id is None:
+if student_id is None or student_id != member_id:
+    logger.info('%s tried to access payment object of %s' % (member_id,student_id))
+    referer = request.get('HTTP_REFERER','none')
+    logger.info('%s:%s illegal access, referer = %s' % (member_id,student_id,referer))
+    real_ip = request.get('HTTP_X_REAL_IP',"none")
+    logger.info('%s:%s illegal access, real_x_ip = %s' % (member_id,student_id,real_ip))
     return context.REQUEST.RESPONSE.redirect("%s/srp_anonymous_view" % context.portal_url())
 
@@ -37,5 +46,9 @@
 for rc,pdk in resp_codes:
     pd[pdk] = request.get(rc)
-context.getContent().edit(mapping=pd)
+try:
+    context.getContent().edit(mapping=pd)
+except UnAuthorized,E:
+    logger.info('%s ' % student_id)
+
 #resp = pd['resp_desc']
 #if  resp.startswith('Appro') and resp.endswith('essful'):
@@ -44,4 +57,8 @@
     wftool.doActionFor(student,'pay_school_fee')
     logger.info('%s received valid callback' % student_id)
+    referer = request.get('HTTP_REFERER','none')
+    logger.info('%s valid callback referer = %s' % (student_id,referer))
+    real_ip = request.get('HTTP_X_REAL_IP',"none")
+    logger.info('%s valid callback real_ip = %s' % (student_id,real_ip))
 
 elif len(resp) < 3:
Index: WAeUP_SRP/branches/uli/skins/waeup_epayment/getPaymentsFolderInfo.py
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_epayment/getPaymentsFolderInfo.py	(revision 1614)
+++ WAeUP_SRP/branches/uli/skins/waeup_epayment/getPaymentsFolderInfo.py	(revision 1653)
@@ -53,5 +53,9 @@
     else:
         row['is_approvable'] = is_so and (review_state == "opened")
-    if (review_state == "closed") and so_object.resp_code in ('SC','00','AP',):
+    if so_object.type_description.startswith('School Fee'):
+        row['is_requeryable'] = (review_state == "opened") and info['review_state'] == 'cleared_and_validated'
+    else:
+        row['is_requeryable'] = is_so and (review_state == "opened")
+    if (review_state == "closed") and so_object.resp_code in ('SC','00','AP','IP',):
         row['confirmed'] = 'active'
     else:
Index: WAeUP_SRP/branches/uli/skins/waeup_epayment/pay_online.py
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_epayment/pay_online.py	(revision 1614)
+++ WAeUP_SRP/branches/uli/skins/waeup_epayment/pay_online.py	(revision 1653)
@@ -91,5 +91,5 @@
 info['callback_url'] = "%s/payments/%s/epayment_cb" % (student.absolute_url(),p_id)
 
-logger.info('%(student_id)s initiated online school fee payment' % info)
+logger.info('%(student_id)s initiated online school fee payment with order_id %(order_id)s and callback url %(callback_url)s' % info)
 payment_fields = (('x_SiteID','site_id'),
                   ('x_Redirect_url','callback_url'),
Index: WAeUP_SRP/branches/uli/skins/waeup_epayment/payment_receipt.pt
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_epayment/payment_receipt.pt	(revision 1614)
+++ WAeUP_SRP/branches/uli/skins/waeup_epayment/payment_receipt.pt	(revision 1653)
@@ -8,5 +8,5 @@
       <span tal:condition="info">
       
-        <metal:block tal:condition="python:info_doc['doc'].resp_code in ('00','AP',)">            
+        <metal:block tal:condition="python:info_doc['doc'].resp_code in ('00','AP','IP')">            
         <h3>Online Payment Receipt</h3>
         <br />
@@ -106,5 +106,5 @@
         </metal:block>
         
-        <metal:block tal:condition="python:info_doc['doc'].resp_code not in ('SC','00','AP','')">            
+        <metal:block tal:condition="python:info_doc['doc'].resp_code not in ('SC','00','AP','IP','')">            
         <h3>Response from Bank: "<span tal:content="python:info_doc['doc'].resp_desc" />"</h3>
         <br />        
Index: WAeUP_SRP/branches/uli/skins/waeup_epayment/payments_view.pt
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_epayment/payments_view.pt	(revision 1614)
+++ WAeUP_SRP/branches/uli/skins/waeup_epayment/payments_view.pt	(revision 1653)
@@ -34,9 +34,17 @@
             </td>
             <td>
-            <a tal:condition="python:row['is_approvable']"
+            <a tal:condition="row/is_approvable"
                tal:attributes="href string:${context/absolute_url}/${row/id}/approve_epayment;
                                onclick python:'return window.confirm(\'%s\')' %(cpsmcat('Are you sure? You will not be able to undo the approval.'), );
                                ">
                 [approve payment]
+            </a>             
+            </td>
+            <td tal:condition="nothing">
+            <a tal:condition="row/is_requeryable"
+               tal:attributes="href string:${context/absolute_url}/${row/id}/requery_payment;
+                               onclick python:'return window.confirm(\'%s\')' %(cpsmcat('Are you sure? You will not be able to undo the approval.'), );
+                               ">
+                [requery payment]
             </a>             
             </td>
@@ -53,4 +61,8 @@
                 value="Initiate School Fee Online Payment" 
                 />
+                
+
+
+                
         </form>  
 
Index: WAeUP_SRP/branches/uli/skins/waeup_epayment/requery_payment.py
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_epayment/requery_payment.py	(revision 1653)
+++ WAeUP_SRP/branches/uli/skins/waeup_epayment/requery_payment.py	(revision 1653)
@@ -0,0 +1,66 @@
+## Script (Python) "pay_online"
+##bind container=container
+##bind context=context
+##bind namespace=
+##bind script=script
+##bind subpath=traverse_subpath
+##parameters=
+##title=
+##
+# $Id$
+"""
+requery online-payment
+"""
+from urllib import urlencode
+import logging
+logger = logging.getLogger('Skins.requery_payment')
+import DateTime
+
+if context.portal_membership.isAnonymousUser():
+    return None
+
+request = context.REQUEST
+wftool = context.portal_workflow
+students = context.portal_url.getPortalObject().campus.students
+
+student_id = context.getStudentId()
+student = getattr(students,student_id)
+
+sbrain = context.students_catalog(id=student_id)[0]
+info = {}
+info['site_id'] = '300100100'
+info['currency_id'] = '566'
+
+#from Products.zdb import set_trace;set_trace()
+if student_id is None:
+    return context.REQUEST.RESPONSE.redirect("%s/srp_anonymous_view" % context.portal_url())
+
+if context.portal_url().find('uniben-demo.waeup.org') >-1 or\
+   context.portal_url().find('uniben.waeup.org') >-1:
+    info['action'] = "http://www.wemaonlinepayments.biz/querytransaction.aspx"
+else:
+    #pass
+    #return None
+    info['action'] = "%s/payments/%s/simulate_queryatransaction" % (student.absolute_url(),p_id)
+
+
+payment = context
+if payment.portal_type != 'Payment':
+    return
+payment_doc = payment.getContent()
+#from Products.zdb import set_trace;set_trace()
+info['order_id'] = p_id = payment_doc.order_id
+info['callback_url'] = "%s/payments/%s/epayment_requery_cb" % (student.absolute_url(),p_id)
+info['type_description'] = payment_doc.type_description
+info['amount'] = payment_doc.amount
+info['student_id'] = student_id
+logger.info('%(student_id)s requeried online school fee payment for order_id %(order_id)s' % info)
+payment_fields = (('x_SiteID','site_id'),
+                  ('x_OrderID','order_id'),
+                  ('x_Redirect_url','callback_url'),
+                  )
+args = {}
+for arg,field in payment_fields:
+    args[arg] = info[field]
+info['args'] = args
+return context.requery_payment_form(info=info)
Index: WAeUP_SRP/branches/uli/skins/waeup_epayment/requery_payment_form.pt
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_epayment/requery_payment_form.pt	(revision 1653)
+++ WAeUP_SRP/branches/uli/skins/waeup_epayment/requery_payment_form.pt	(revision 1653)
@@ -0,0 +1,42 @@
+<metal:body use-macro="here/main_template/macros/master">
+    <metal:main fill-slot="main"
+                tal:define="info options/info">
+                
+        <h3>Requery Online Payment! </h3>
+        <br />
+                
+      <form method="post" action="pay_online"
+            tal:attributes="action info/action ">
+      <span tal:repeat="arg python:info['args'].items()"
+            tal:omit-tag="">
+          <input type="hidden" tal:attributes="name python:arg[0];value python:arg[1]" />
+      </span>          
+        <table>
+          <tr>
+            <td width="100px">
+            Payment:</td>
+            <td tal:content="info/type_description"></td>
+          </tr>
+          <tr>
+            <td >
+            Amount:
+            </td>
+            <td> Naira <span tal:content="info/amount" /></td>
+          </tr>
+          <tr>
+            <td >
+            Bank:
+            </td>
+            <td>Wema Bank</td>
+          </tr>          
+        </table>
+        <br />
+        <input type="submit" 
+               class="standalone" 
+               name="goto_bank" 
+               value="Requery this payment with Bank" 
+               />
+      </form>
+    </metal:main>
+</metal:body>
+
Index: WAeUP_SRP/branches/uli/skins/waeup_student/add_course_result.py
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_student/add_course_result.py	(revision 1614)
+++ WAeUP_SRP/branches/uli/skins/waeup_student/add_course_result.py	(revision 1653)
@@ -38,13 +38,13 @@
     if d['title'] == 'unknown':
         err = "No such course!"
-        logger.info('%s tried to add StudentCourseResult object %s for non-existing course' % (member,course_id))
+        #logger.info('%s tried to add StudentCourseResult object %s for non-existing course' % (member,course_id))
         break
     if context.hasObject(course_id):
         err = "Course already exists!"
-        logger.info('%s tried to add StudentCourseResult object %s which is already in course list' % (member,course_id))
+        #logger.info('%s tried to add StudentCourseResult object %s which is already in course list' % (member,course_id))
         break
     if context.hasObject("%s_co" % course_id):
         err = "Course already exists as carryover course!"
-        logger.info('%s tried to add StudentCourseResult object %s which already exists as carryover course' % (member,course_id))
+        #logger.info('%s tried to add StudentCourseResult object %s which already exists as carryover course' % (member,course_id))
         break
     break
@@ -54,5 +54,5 @@
     #args['error'] = err
     args['portal_status_message'] = err
-    url = "%s?%s" % (context.absolute_url(),urlencode(args))
+    url = context.absolute_url() + '/' + action_after_validate + '?' + urlencode(args)
     return request.RESPONSE.redirect(url)
 
@@ -66,10 +66,12 @@
 args['course_id'] = course_id
 
-logger.info('%s added StudentCourseResult object %s' % (member,course_id))
+logger.info('%s added StudentCourseResult object %s for %s' % (member,course_id,context.getStudentId()))
 
-args = {}
 psm = "You successfully added course %s!" % course_id
 args['portal_status_message'] = psm
-url = context.absolute_url() + '/' + action_after_validate + '?' + urlencode(args)
+if action_after_validate:
+    url = context.absolute_url() + '/' + action_after_validate + '?' + urlencode(args)
+else:
+    url = context.absolute_url() + '?' + urlencode(args)
 return REQUEST.RESPONSE.redirect(url)
 
Index: WAeUP_SRP/branches/uli/skins/waeup_student/change_password.py
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_student/change_password.py	(revision 1614)
+++ WAeUP_SRP/branches/uli/skins/waeup_student/change_password.py	(revision 1653)
@@ -4,4 +4,14 @@
 
 """
+
+return
+
+
+
+
+
+
+
+
 request = context.REQUEST
 import DateTime,logging
Index: WAeUP_SRP/branches/uli/skins/waeup_student/clearance_edit.py
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_student/clearance_edit.py	(revision 1614)
+++ WAeUP_SRP/branches/uli/skins/waeup_student/clearance_edit.py	(revision 1653)
@@ -120,5 +120,5 @@
         wftool.doActionFor(info['clear'],'open')
         wftool.doActionFor(info['student'],'reject_clearance')
-        action = "/contact_student_form"
+        action = "/external_contact_student_form"
         psm = "Student's clearance request has been rejected! Please fill and submit the form below!"
         subject = "Clearance request rejected"
Index: WAeUP_SRP/branches/uli/skins/waeup_student/contact_student_form.pt
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_student/contact_student_form.pt	(revision 1614)
+++ WAeUP_SRP/branches/uli/skins/waeup_student/contact_student_form.pt	(revision 1653)
@@ -28,4 +28,6 @@
       <input type="hidden" name="probtype" type="text" id="probtype"
              tal:attributes="value subject"/>     
+      <input type="hidden" name="action" type="text" id="action"
+             tal:attributes="value continue"/>  
              
       <table width="100%" border="0" cellspacing="5" cellpadding="0">
Index: WAeUP_SRP/branches/uli/skins/waeup_student/course_registration_slip.pt
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_student/course_registration_slip.pt	(revision 1614)
+++ WAeUP_SRP/branches/uli/skins/waeup_student/course_registration_slip.pt	(revision 1653)
@@ -19,5 +19,8 @@
       
       <div tal:condition="validated">
-        - validated by Course Adviser -
+        - validated by Course Adviser - 
+      <span tal:condition="info/doc/validated_by|nothing" tal:omit-tag="">
+        <span tal:replace="info/doc/validated_by" /> on <span tal:replace="info/doc/validation_date" />
+      </span>
       </div>
       <div tal:condition="not: validated">
Index: WAeUP_SRP/branches/uli/skins/waeup_student/create_level.py
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_student/create_level.py	(revision 1614)
+++ WAeUP_SRP/branches/uli/skins/waeup_student/create_level.py	(revision 1653)
@@ -31,27 +31,32 @@
 current_level = student.level
 in_progress =  request.get('in_progress','not started')
+level_created =  request.get('level_created','xxx')
+create_level =  request.get('create_level',None)
 
-if context.hasObject(current_level):
-    response.redirect("%s/%s" % (context.absolute_url(),current_level))
+if context.hasObject(current_level) and create_level :
+    logger.info('%s", level %s already exists' % (student.id,current_level))
     return
 
-if in_progress in ('not started','started'):
-    session.set('in_progress','started')
-    view = context.in_progress_view(refresh=3,page='create_level?in_progress=started')
-    response.setHeader('Content-type','text/html; charset=ISO-8859-15')
-    response.setHeader('Content-length','%d' % (len(view)))
-    response.setStatus('OK')
-    response.write(view)
-    response.write('')
-    if in_progress == 'started':
-        return
+##if in_progress in ('not started','started'):
+##    session.set('in_progress','started')
+##    view = context.in_progress_view(refresh=20,page='create_level?in_progress=started')
+##    response.setHeader('Content-type','text/html; charset=ISO-8859-15')
+##    response.setHeader('Content-length','%d' % (len(view)))
+##    response.setStatus('OK')
+##    response.write(view)
+##    response.write('')
+##    if in_progress == 'started':
+##        return
     
-
-context.invokeFactory('StudentStudyLevel',"%s" % current_level)
-level = getattr(context,"%s" % current_level)
-context.portal_workflow.doActionFor(level,'open')
-study_session = context.getSessionString()
-level.getContent().edit(mapping={'session': study_session})
-context.portal_workflow.doActionFor(level,'close_for_edit')
+if level_created == current_level:
+    level = getattr(context,"%s" % current_level)
+else:
+    context.invokeFactory('StudentStudyLevel',"%s" % current_level)
+    level = getattr(context,"%s" % current_level)
+    context.portal_workflow.doActionFor(level,'open')
+    study_session = context.getSessionString()
+    level.getContent().edit(mapping={'session': study_session})
+    context.portal_workflow.doActionFor(level,'close_for_edit')
+    response.redirect("%s?level_created=%s" % (context.absolute_url(),current_level))
 results = context.results_import(matric_no = student.matric_no)
 if results:
@@ -90,19 +95,22 @@
         context.portal_workflow.doActionFor(course_result,'open')
         course_result.getContent().edit(mapping=d)
-res = context.portal_catalog(portal_type="Certificate", id = cert_id)
-l = []
-if res:
-    cert = res[0]
-    path = cert.getPath()
-    query = Eq("path",path) &\
-            Eq('portal_type','CertificateCourse') &\
-            Eq('SearchableText', "%s" % student.level)
-    courses = aq_portal(query)
-    for c in courses:
-        d = context.getCourseInfo(c.getId)
-        cr_id = level.invokeFactory('StudentCourseResult',c.getId)
-        course_result = getattr(level,cr_id)
-        context.portal_workflow.doActionFor(course_result,'open')
-        d['core_or_elective'] = getattr(c.getObject().getContent(),'core_or_elective')
-        course_result.getContent().edit(mapping=d)
-return
+level['create_course_results'](cert_id,current_level)
+##res = context.portal_catalog(portal_type="Certificate", id = cert_id)
+##l = []
+##if res:
+##    cert = res[0]
+##    path = cert.getPath()
+##    #set_trace()
+##    query = Eq("path","%s/%s" % (path,current_level)) &\
+##            Eq('portal_type','CertificateCourse')
+##    courses = aq_portal(query)
+##    for c in courses:
+##        d = context.getCourseInfo(c.getId)
+##        cr_id = level.invokeFactory('StudentCourseResult',c.getId)
+##        course_result = getattr(level,cr_id)
+##        context.portal_workflow.doActionFor(course_result,'open')
+##        d['core_or_elective'] = getattr(c.getObject().getContent(),'core_or_elective')
+##        course_result.getContent().edit(mapping=d)
+        
+return response.redirect("%s/%s" % (context.absolute_url(),current_level))
+
Index: WAeUP_SRP/branches/uli/skins/waeup_student/delete_course_result.py
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_student/delete_course_result.py	(revision 1614)
+++ WAeUP_SRP/branches/uli/skins/waeup_student/delete_course_result.py	(revision 1653)
@@ -14,4 +14,6 @@
 
 from Products.CMFCore.utils import getToolByName
+from AccessControl import Unauthorized
+
 here = context
 from urllib import urlencode
@@ -30,13 +32,21 @@
             real_ids.append(id)
     if real_ids:
-        context.manage_delObjects(real_ids)
-        logger.info('%s deleted StudentCourseResult object %s' % (member,id))
-        message = 'psm_item(s)_deleted'
+        try:
+            context.manage_delObjects(real_ids)
+            logger.info('%s deleted StudentCourseResult object %s for %s' % (member,id,context.getStudentId()))
+            message = 'psm_item(s)_deleted'
+        except Unauthorized:
+            logger.info('%s has no permission to delete StudentCourseResult objects for %s' % (member,context.getStudentId()))
+            message = 'no item(s) deleted'
 else:
     message = 'psm_select_at_least_one_document'
-    
+
 args = {}
 args['portal_status_message'] = message
-url = context.absolute_url() + '/' + action_after_validate + '?' + urlencode(args)
+
+if action_after_validate:
+    url = context.absolute_url() + '/' + action_after_validate + '?' + urlencode(args)
+else:
+    url = context.absolute_url() + '?' + urlencode(args)
 if REQUEST is not None:
-    return REQUEST.RESPONSE.redirect(url)    
+    return REQUEST.RESPONSE.redirect(url)
Index: WAeUP_SRP/branches/uli/skins/waeup_student/getSessionResults.py
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_student/getSessionResults.py	(revision 1614)
+++ WAeUP_SRP/branches/uli/skins/waeup_student/getSessionResults.py	(revision 1653)
@@ -101,5 +101,5 @@
 #set_trace()
 verdict_voc = context.portal_vocabularies.verdicts
-verdict_code = student_from_cat.get('verdict',None)
+verdict_code = student_from_cat.verdict
 if verdict_code:
     info['verdict'] = verdict = verdict_voc.get(verdict_code,'N/A').upper()
Index: WAeUP_SRP/branches/uli/skins/waeup_student/getStudyCourseInfo.py
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_student/getStudyCourseInfo.py	(revision 1614)
+++ WAeUP_SRP/branches/uli/skins/waeup_student/getStudyCourseInfo.py	(revision 1653)
@@ -25,5 +25,5 @@
 info = {}
 info['is_so'] = context.isSectionOfficer()
-info['action'] = "%s" % context.campus.absolute_url()
+info['action'] = "%s" % context.absolute_url()
 info['choosen_ids'] = request.get('ids',[])
 course  = info['doc'] = context.getContent()
@@ -57,5 +57,5 @@
 may_register = (student_review_state in ('school_fee_paid',)) and\
                current_level not in levels and\
-               (sbrain.verdict in ('A','B') or sbrain.jamb_reg_no.startswith('6'))
+               (sbrain.verdict in ('A','B','C') or sbrain.jamb_reg_no.startswith('6'))
 
 levels.sort()
Index: WAeUP_SRP/branches/uli/skins/waeup_student/getStudyLevelInfo.py
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_student/getStudyLevelInfo.py	(revision 1614)
+++ WAeUP_SRP/branches/uli/skins/waeup_student/getStudyLevelInfo.py	(revision 1653)
@@ -40,8 +40,10 @@
     return 0.0
 
-def cmp_semester(a,b):
-    if a['semester'] == b['semester']:
+def cmp_semester_id(a,b):
+    s1 = "%(semester)s%(id)s" % a
+    s2 = "%(semester)s%(id)s" % b
+    if s1 == s2:
         return 0
-    if a['semester'] > b['semester']:
+    if s1 > s2:
         return 1
     return -1
@@ -104,7 +106,7 @@
         normal.append(d)
 info['credits_total'] = credits_total
-carry_overs.sort(cmp_semester)
+carry_overs.sort(cmp_semester_id)
 info['carry_overs'] = carry_overs
-normal.sort(cmp_semester)
+normal.sort(cmp_semester_id)
 info['normal'] = normal
 
Index: WAeUP_SRP/branches/uli/skins/waeup_student/layout_personal_view.pt
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_student/layout_personal_view.pt	(revision 1614)
+++ WAeUP_SRP/branches/uli/skins/waeup_student/layout_personal_view.pt	(revision 1653)
@@ -9,5 +9,5 @@
       <td><span class="dlabel">Student ID</span>:
       </td>
-      <td tal:condition="nothing"> 
+      <td> 
          <span tal:replace="context/getStudentId" />
       </td>      
Index: WAeUP_SRP/branches/uli/skins/waeup_student/mail2student.py
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_student/mail2student.py	(revision 1614)
+++ WAeUP_SRP/branches/uli/skins/waeup_student/mail2student.py	(revision 1653)
@@ -5,8 +5,10 @@
 ##bind script=script
 ##bind subpath=traverse_subpath
-##parameters=co_name=None,co_email=None,student_email=None,probtype=None,commt=None
+##parameters=co_name=None,co_email=None,student_email=None,probtype=None,commt=None, action=None
 ##title=
 ##
 # $Id: mail2admin.py 869 2006-11-15 13:46:49Z henrik $
+
+from urllib import urlencode
 
 mhost = context.MailHost
@@ -27,11 +29,13 @@
 #prop.email_from_address should be used for To:
 REQUEST = context.REQUEST
-url_tuple = REQUEST.HTTP_REFERER.split('?')
-if len(url_tuple) == 2:
-    url_tuple[1] ='portal_status_message=Your message has been sent!'
-else:
-    url_tuple.append('portal_status_message=Your message has been sent!')
-redirect_url = "?".join(url_tuple)
-REQUEST.set('rurl', redirect_url) # to see the result in the error log
+
+#url_tuple = REQUEST.HTTP_REFERER.split('?')
+#if len(url_tuple) == 2:
+#    url_tuple[1] ='portal_status_message=Your message has been sent!'
+#else:
+#    url_tuple.append('portal_status_message=Your message has been sent!')
+#redirect_url = "?".join(url_tuple)
+#REQUEST.set('rurl', redirect_url) # to see the result in the error log
+
 msg = message % (
      co_name,
@@ -39,5 +43,5 @@
      student_email,
      co_email,
-     'henrik@waeup.org',
+     'waeup@saoas.org',
 #    'js@aixtraware.de',
      co_email,
@@ -47,6 +51,18 @@
 mhost.send(msg)
 
-REQUEST = context.REQUEST
-RESPONSE = REQUEST.RESPONSE
 
-RESPONSE.redirect(redirect_url)
+#REQUEST = context.REQUEST
+#RESPONSE = REQUEST.RESPONSE
+#RESPONSE.redirect(redirect_url)
+
+args = {}
+psm = "Your message has been sent!"
+args['portal_status_message'] = psm
+if action:
+    url = context.absolute_url() + '/' + action + '?' + urlencode(args)
+else:
+    url = context.absolute_url() +'?' + urlencode(args)
+return REQUEST.RESPONSE.redirect(url)
+
+
+
Index: WAeUP_SRP/branches/uli/skins/waeup_student/refresh_level.py
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_student/refresh_level.py	(revision 1614)
+++ WAeUP_SRP/branches/uli/skins/waeup_student/refresh_level.py	(revision 1653)
@@ -112,4 +112,7 @@
 psm = "Course list updated!"
 args['portal_status_message'] = psm
-url = context.absolute_url() + '/' + action_after_validate + '?' + urlencode(args)
+if action_after_validate:
+    url = context.absolute_url() + '/' + action_after_validate + '?' + urlencode(args)
+else:
+    url = context.absolute_url() + '?' + urlencode(args)
 return REQUEST.RESPONSE.redirect(url)
Index: WAeUP_SRP/branches/uli/skins/waeup_student/register_courses.py
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_student/register_courses.py	(revision 1614)
+++ WAeUP_SRP/branches/uli/skins/waeup_student/register_courses.py	(revision 1653)
@@ -19,5 +19,5 @@
         pass
 
-from urllib import urlencode        
+from urllib import urlencode
 
 request = context.REQUEST
@@ -47,4 +47,7 @@
 psm = "You successfully submitted your course list!"
 args['portal_status_message'] = psm
-url = context.absolute_url() + '/' + action_after_validate + '?' + urlencode(args)
+if action_after_validate:
+    url = context.absolute_url() + '/' + action_after_validate + '?' + urlencode(args)
+else:
+    url = context.absolute_url() + '?' + urlencode(args)
 return REQUEST.RESPONSE.redirect(url)
Index: WAeUP_SRP/branches/uli/skins/waeup_student/reject_courses.py
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_student/reject_courses.py	(revision 1614)
+++ WAeUP_SRP/branches/uli/skins/waeup_student/reject_courses.py	(revision 1653)
@@ -46,4 +46,7 @@
 args['continue'] = action_after_validate
 args['portal_status_message'] = psm
-url = context.absolute_url() + '/' + action_after_reject + '?' + urlencode(args)
+if action_after_reject:
+    url = context.absolute_url() + '/' + action_after_reject + '?' + urlencode(args)
+else:
+    url = context.absolute_url() + '?' + urlencode(args)
 return REQUEST.RESPONSE.redirect(url)
Index: WAeUP_SRP/branches/uli/skins/waeup_student/statistics_new_view.pt
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_student/statistics_new_view.pt	(revision 1614)
+++ WAeUP_SRP/branches/uli/skins/waeup_student/statistics_new_view.pt	(revision 1653)
@@ -33,5 +33,5 @@
             <th align="right">CR</th>
             <th align="right">VC</th>
-            <th align="right">SFP</th>
+            <th align="right">SFP+</th>
           </tr>
           <tr tal:repeat="d departments"
@@ -74,5 +74,5 @@
         <tr><td>CR: </td> <td>Clearance requested</td></tr>
         <tr><td>VC: </td> <td>Validated and cleared</td></tr>
-        <tr><td>SFP: </td> <td>School fee paid</td></tr>
+        <tr><td>SFP+: </td> <td>School fee paid and further</td></tr>
         </table>
       </span>
Index: WAeUP_SRP/branches/uli/skins/waeup_student/statistics_ret_view.pt
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_student/statistics_ret_view.pt	(revision 1614)
+++ WAeUP_SRP/branches/uli/skins/waeup_student/statistics_ret_view.pt	(revision 1653)
@@ -34,5 +34,5 @@
             <th >Faculty</th>
             <th align="right">RET</th>
-            <th align="right">SFP</th>
+            <th align="right">SFP+</th>
           </tr>
           <tr tal:define="d python:departments[0]"
@@ -60,5 +60,5 @@
         <table>
         <tr><td>RET:</td> <td>Returning students who have logged in</td></tr>
-        <tr><td>SFP:</td> <td>Returning students who already paid their school fee</td></tr>
+        <tr><td>SFP:</td> <td>Returning students who paid their school fee</td></tr>
         </table>        
       </span>
Index: WAeUP_SRP/branches/uli/skins/waeup_student/study_course_view.pt
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_student/study_course_view.pt	(revision 1614)
+++ WAeUP_SRP/branches/uli/skins/waeup_student/study_course_view.pt	(revision 1653)
@@ -66,5 +66,5 @@
             tal:attributes="class python:test(repeat['row'].even(), 'even ajaxtd', 'odd ajaxtd')">
             <td align="left" valign="middle" style="width: 5px;" 
-                tal:condition="python: 0 and is_so">
+                tal:condition="python:is_so">
               <input type="checkbox" name="ids:list" value="" id="" class="noborder"
                      tal:condition="is_so"
@@ -84,9 +84,8 @@
                summary="contents of the folder"
                class="folderButtons">
-          <tr>
+          <tr tal:condition="python: is_so and info['items']">
             <td align="left" valign="top" rowspan="3"></td>
             <td align="left" valign="top">
-              <span tal:condition="python:0 and is_so">
-                <input type="button" value="button_select_all" class="context"
+              <input type="button" value="button_select_all" class="context"
                        onclick="someJavaScriptFunctionThatWillBeReplaced"
                        i18n:attributes="value"
@@ -94,10 +93,9 @@
                        % (cpsmcat('button_select_all'), cpsmcat('button_deselect_all'))"
                        />
-                <input type="submit" name="folder_delete:method" value="button_delete"
-                       class="destructive" i18n:attributes="value"
-                       tal:attributes="onclick python:'return window.confirm(\'%s\')' %
-                       (cpsmcat('description_confirm_delete'), )" 
-                       />
-              </span>
+              <input type="submit" name="folder_delete:method" value="button_delete"
+                     class="destructive" i18n:attributes="value"
+                     tal:attributes="onclick python:'return window.confirm(\'%s\')' %
+                     (cpsmcat('description_confirm_delete'), )" 
+                     />
             </td>
           </tr>
Index: WAeUP_SRP/branches/uli/skins/waeup_student/study_level_view.pt
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_student/study_level_view.pt	(revision 1614)
+++ WAeUP_SRP/branches/uli/skins/waeup_student/study_level_view.pt	(revision 1653)
@@ -64,5 +64,6 @@
         <br />
       <div class="" tal:condition="not: info/normal">
-        Your faculty has not yet provided the list of courses for your certificate. Please contact your faculty!
+        <font color="red">Your faculty has not yet provided the list of courses for your certificate. Please contact your faculty!</font>
+        <br /><br />
       </div>
         <table class="contentListing" width="100%" id="folder_content"
@@ -109,8 +110,21 @@
                        class="context" value="Update" 
                        />
+                      
+                       
                 <br /><br />
                 <input tal:condition="info/normal" 
                        type="submit" name="register_courses:method"
                        class="context" value="Submit" />
+                       
+                <input type="hidden" name="action_after_validate" type="text" id="action_after_validate"
+                       tal:attributes="value string:study_level_view"/>  
+                       
+                <br /><br />
+                
+                <strong>Note:</strong> 'Update' checks for all courses in your certificate and will add them to your course list irrespective of
+                prior deletion, i.e. already deleted courses will show up again. 
+                
+                Please use this function only if you are sure that your faculty has added courses which are not yet on your course list.                                
+                       
             </td>
           </tr>
@@ -142,4 +156,9 @@
                 <input tal:condition="python: review_state in ('courses_registered', 'courses_validated',)" type="submit" name="reject_courses:method"
                        class="context" value="Reject" />
+                       
+                <input type="hidden" name="action_after_validate" type="text" id="action_after_validate"
+                       tal:attributes="value string:study_level_view"/>                         
+                <input type="hidden" name="action_after_reject" type="text" id="action_after_reject"
+                       tal:attributes="value string:contact_student_form"/>                         
 
             </td>
@@ -176,7 +195,7 @@
                        
                 <input type="hidden" name="action_after_validate" type="text" id="action_after_validate"
-                       tal:attributes="value string:/study_level_view"/>                         
+                       tal:attributes="value string:study_level_view"/>                         
                 <input type="hidden" name="action_after_reject" type="text" id="action_after_reject"
-                       tal:attributes="value string:/contact_student_form"/>    
+                       tal:attributes="value string:contact_student_form"/>    
                                              
 
@@ -199,5 +218,5 @@
                      />
               <input type="hidden" name="action_after_validate" type="text" id="action_after_validate"
-                       tal:attributes="value string:/study_level_view"/>                       
+                       tal:attributes="value string:study_level_view"/>                       
             </td>                
         </table>
Index: WAeUP_SRP/branches/uli/skins/waeup_student/validate_courses.py
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_student/validate_courses.py	(revision 1614)
+++ WAeUP_SRP/branches/uli/skins/waeup_student/validate_courses.py	(revision 1653)
@@ -13,4 +13,6 @@
 """
 from Products.CMFCore.WorkflowCore import WorkflowException
+import DateTime
+current = DateTime.DateTime()
 try:
     from Products.zdb import set_trace
@@ -30,4 +32,8 @@
 student_id = context.getStudentId()
 student = getattr(students_folder,student_id)
+level_doc = context.getContent()
+if level_doc.portal_type == 'StudentStudyLevel':
+    level_doc.edit(mapping={'validated_by': member_id,
+                            'validation_date': current,})
 try:
     wftool.doActionFor(student,'validate_courses')
Index: WAeUP_SRP/branches/uli/skins/waeup_utilities/ti_151_resolve.py
===================================================================
--- WAeUP_SRP/branches/uli/skins/waeup_utilities/ti_151_resolve.py	(revision 1653)
+++ WAeUP_SRP/branches/uli/skins/waeup_utilities/ti_151_resolve.py	(revision 1653)
@@ -0,0 +1,114 @@
+## Script (Python) "ti_151_resolve"
+##bind container=container
+##bind context=context
+##bind namespace=
+##bind script=script
+##bind subpath=traverse_subpath
+##parameters=
+##title=
+##
+# $Id$
+"""
+resolve ticket #151
+"""
+try:
+    from Products.zdb import set_trace
+except:
+    def set_trace():
+        pass
+import logging
+#>>>>>>>>>>>>>>>><
+logger = logging.getLogger('Skins.ti_151_resolve')
+logger.info('already done on 26.3.07 by joachim')
+return
+#<<<<<<<<<<<<<<<<<
+request = context.REQUEST
+session = request.SESSION
+response = request.RESPONSE
+setheader = request.RESPONSE.setHeader
+students = context.portal_url.getPortalObject().campus.students
+#from string import Template
+def rwrite(s):
+    response.setHeader('Content-type','text/html; charset=ISO-8859-15')
+    response.write(s)
+def getObject(outer,object):
+    if outer.hasObject(object):
+        return getattr(outer,object)
+    return None
+
+try:
+    from Products.AdvancedQuery import Eq, Between, Le,In
+    aq_students = context.students_catalog.evalAdvancedQuery
+except:
+    evalAdvancedQuery = None
+
+students_cat = context.students_catalog
+query = Eq('faculty','PSC') & Eq('department','PHY') & In('level',('300','400'))
+brains = aq_students(query)
+#brains = students_cat(faculty = 'PSC',department='PHY', level='400')
+total = 0
+count_ok = 0
+count_nosc = 0
+count_nolevel = 0
+count_level = 0
+count_renamed = 0
+#set_trace()
+#template = Template('"$count","$id","$course"')
+to_rename = []
+for student in brains:
+    student_dict = {}
+    for field in students_cat.schema():
+        student_dict[field] = getattr(student,field)
+    #s = template.substitute(student_dict,count=count,)
+    student_dict['total'] = total
+    while True:
+        if student.course == "BSCINP":
+            student_dict['message'] = "OK"
+            count_ok += 1
+            student_dict['sp_count'] = count_ok
+            s = '"%(total)d","%(sp_count)s","%(id)s","%(course)s","%(message)s",' % student_dict
+            break
+        student_dict['message'] = ""
+        student_obj = getObject(students,student.id)
+        if student_obj is None:
+            student_dict['message'] = "No student object"
+            break
+        study_course_obj = getObject(student_obj,'study_course')
+        if study_course_obj is None:
+            student_dict['message'] = "No study_course object"
+            count_nosc += 1
+            student_dict['sp_count'] = count_nosc
+            break
+        level_obj = getObject(student_obj,student.level)
+        if level_obj:
+            count_level += 1
+            study_course.manage_delObjects((student.level,))
+            student_dict['message'] = "Level deleted"
+            student_dict['sp_count'] = count_level
+        count_renamed += 1
+        to_rename.append(student.id)
+        student_dict['sp_count'] = count_renamed
+        student_dict['message'] = student_dict['message'] + "renamed to BSCINP"
+        study_course_doc = study_course_obj.getContent()
+        study_course_obj.edit(mapping = {'study_course': "BSCINP"})
+        total += 1
+        s = '"%(total)d","%(sp_count)s","%(id)s","%(course)s","%(message)s",' % student_dict
+        rwrite("%s<br />\r\n" %s)
+        break
+    total += 1
+    s = '"%(total)d","%(sp_count)s","%(id)s","%(course)s","%(message)s",' % student_dict
+    rwrite("%s<br />\r\n" %s)
+for sid in to_rename:
+    students_cat.modifyRecord(id = sid,course="BSCINP")
+sum = count_ok + count_nosc + count_nolevel + count_level    
+rwrite("total=%d,sum of below=%d,<br>\r\n correct study_course=%d<br>\r\n no study_course=%d<br>\r\n no level=%d<br>\r\n with level =%d,<br />\n Done" %
+        (total,
+         sum,
+         count_ok,
+         count_nosc,
+         count_nolevel,
+         count_level)
+         )
+
+logger.info("total=%d,sum=%d,ok=%d,no study_course=%d,no level=%d,with level =%d,\n Done" %
+             (total,sum,count_ok,count_nosc,count_nolevel,count_level))
