Index: WAeUP_SRP/trunk/PatchCPSWorkflowWorkflowDefinition.py
===================================================================
--- WAeUP_SRP/trunk/PatchCPSWorkflowWorkflowDefinition.py	(revision 511)
+++ WAeUP_SRP/trunk/PatchCPSWorkflowWorkflowDefinition.py	(revision 511)
@@ -0,0 +1,183 @@
+import logging
+from ZODB.loglevels import TRACE
+
+from AccessControl import ClassSecurityInfo
+from AccessControl import getSecurityManager
+from Acquisition import aq_parent
+from Acquisition import aq_inner
+from Globals import InitializeClass
+
+from Products.CMFCore.utils import getToolByName
+from Products.CMFCore.WorkflowCore import ObjectMoved
+from Products.CMFCore.WorkflowCore import ObjectDeleted
+from Products.CMFCore.WorkflowCore import WorkflowException
+
+from Products.DCWorkflow.DCWorkflow import DCWorkflowDefinition
+from Products.DCWorkflow.Transitions import TRIGGER_USER_ACTION
+
+#from expression import CPSStateChangeInfo as StateChangeInfo
+#from expression import createExprContext
+
+#from zope.interface import implements
+#from Products.CPSWorkflow.interfaces import ICPSWorkflowDefinition
+
+from Products.CPSCore.ProxyBase import ProxyBase
+from Products.CPSCore.EventServiceTool import getEventService
+
+#from constants import TRANSITION_FLAGS_EXPORT
+
+#
+# Backwards compatibility with CPS3 <= 3.2.x
+# Importing transition flags from here before.
+#
+
+from Products.CPSWorkflow.transitions import *
+from Products.CPSWorkflow.states import *
+
+
+logger = logging.getLogger('CPSWorkflow.workflow')
+security = ClassSecurityInfo()
+
+security.declarePrivate('updateStackDefinitionsRoleMappingFor')
+def updateStackDefinitionsRoleMappingsFor(self, ob, **kw):
+    """Update local roles for delegatees that are within workflow stacks
+    """
+    current_wf_var_id = kw.get('current_wf_var_id', '')
+
+    wftool = getToolByName(self, 'portal_workflow')
+    stackdefs = wftool.getStackDefinitionsFor(ob)
+
+    changed = 0
+
+    #
+    # First save the former local roles maping They will be
+    # overriden if defined on the state just after.  For the other
+    # ones, we need to keep the flrm's since the stackdef might be
+    # defined on another state further within the process
+    # definition or called by a stack flaged transition.
+    #
+    tdef = kw.get('tdef')
+    history = wftool.getHistoryOf(self.id, ob)
+    if history is not None:
+        try:
+            former_status = history[-2]
+        except IndexError:
+            # Virgin instance ;)
+            pass
+        else:
+            sflrm = former_status.get('sflrm', {})
+            for k, v in sflrm.items():
+                wftool.updateFormerLocalRoleMappingForStack(ob, self.id,
+                                                            k, v)
+
+    #
+    # Let's ask the stack definition for the list of local roles
+    #
+
+    for stackdef in stackdefs.keys():
+
+        # Update only the variable on wich the transition just applied
+        if not stackdef == current_wf_var_id:
+            continue
+
+        ds = wftool.getInfoFor(ob, stackdef, self.id)
+        former_mapping = wftool.getFormerLocalRoleMappingForStack(
+            ob, self.id, stackdef)
+        mapping = stackdefs[stackdef]._getLocalRolesMapping(ds)
+
+        #
+        # First remove associated local roles to the ones who are not
+        # supposed to have any (not a single one)
+        #
+
+        for id in former_mapping.keys():
+            old_local_roles = former_mapping[id]
+
+            # Remove all previous local roles in this case
+            if id not in mapping.keys():
+                roles_to_remove = old_local_roles
+
+            # Remove only local roles that are only within the
+            # previous mapping
+            else:
+                roles_to_remove = []
+                for old_role in old_local_roles:
+                    if old_role not in mapping[id]:
+                        roles_to_remove.append(old_role)
+
+
+            # Check that no other stack distributes currently this role
+            # to the current member
+            roles_to_keep = ()
+            for old_local_role in roles_to_remove:
+                stacks = wftool.getStacks(ob)
+                for stack_id, stack in stacks.items():
+                    if stack_id != current_wf_var_id:
+                        # The current transition is already
+                        # executed on ob thus we can take the
+                        # former mapping for this other given
+                        if (old_local_role in
+                            wftool.getFormerLocalRoleMappingForStack(
+                            ob, self.id, stack_id).get(id, ())):
+                            roles_to_keep += (old_local_role,)
+
+            # Do the actual job to remove absolete roles
+            for old_local_role in roles_to_remove:
+
+                # Don't remove those already managed by another stack
+                if old_local_role in roles_to_keep:
+                    continue
+
+                if not id.startswith('group:'):
+                    current_roles = list(
+                        ob.get_local_roles_for_userid(userid=id))
+                    new_roles = [role for role in current_roles
+                                 if role != old_local_role]
+                    ob.manage_delLocalRoles(userids=[id])
+                    if new_roles:
+                        ob.manage_setLocalRoles(id, new_roles)
+                else:
+                    id = id[len('group:'):]
+                    current_roles = list(
+                        ob.get_local_roles_for_groupid(groupid=id))
+                    new_roles = [role for role in current_roles
+                                 if role != old_local_role]
+                    ob.manage_delLocalGroupRoles(groupids=[id])
+                    if new_roles:
+                        ob.manage_setLocalGroupRoles(id, new_roles)
+
+            # Update ?
+            if roles_to_remove:
+                changed = 1
+
+        #
+        # Add local roles to member / groups within the mapping if
+        # they don't have the roles already in their merged local roles
+        #
+
+        for id in mapping.keys():
+            changed = 1
+            local_roles = mapping[id]
+            if not id.startswith('group:'):
+                current_roles = ob.get_local_roles_for_userid(userid=id)
+                new_roles = list(current_roles)
+                for role in local_roles:
+                    if role not in new_roles:
+                        new_roles.append(role)
+                ob.manage_setLocalRoles(id, new_roles)
+            else:
+                id = id[len('group:'):]
+                current_roles = ob.get_local_roles_for_groupid(groupid=id)
+                new_roles = list(current_roles)
+                for role in local_roles:
+                    if role not in new_roles:
+                        new_roles.append(role)
+                ob.manage_setLocalGroupRoles(id, new_roles)
+
+        # Update the former local role mapping
+        wftool.updateFormerLocalRoleMappingForStack(ob, self.id, stackdef,
+                                                    mapping)
+    return changed
+
+from Products.CPSWorkflow.workflow import WorkflowDefinition
+WorkflowDefinition.updateStackDefinitionsRoleMappingsFor = updateStackDefinitionsRoleMappingsFor
Index: WAeUP_SRP/trunk/Students.py
===================================================================
--- WAeUP_SRP/trunk/Students.py	(revision 510)
+++ WAeUP_SRP/trunk/Students.py	(revision 511)
@@ -22,8 +22,11 @@
 MAX_TRANS = 1000
 
-def generateStudentId():
+def generateStudentId(letter):
     import random
     r = random
-    return "%c%d" % (r.choice('ABCDEFGHKLMNPQRSTUVWXY'),r.randint(99999,1000000))
+    if letter not in ('ABCDEFGIHKLMNOPQRSTUVWXY'):
+        letter= r.choice('ABCDEFGHKLMNPQRSTUVWXY')
+    return "%c%d" % (letter,r.randint(99999,1000000))
+    #return "%c%d" % (r.choice('ABCDEFGHKLMNPQRSTUVWXY'),r.randint(99999,1000000))
 
 def getStudentByRegNo(self,reg_no):
@@ -294,5 +297,6 @@
         import transaction
         tr_count = 0
-        name = 'SampleJAMBDataII'
+        name = 'SampleJAMBDataII_short'
+        wftool = self.portal_workflow
         no_import = False
         if not no_import:
@@ -317,5 +321,8 @@
                 no_import.write('%(REG-NO)s,%(NAME)s,%(SEX)s,%(STATE)s,%(LGA)s,%(ENG-SCORE)s,%(SUBJ1)s,%(SUBJ1-SCORE)s,%(SUBJ2)s,%(SUBJ2-SCORE)s,%(SUBJ3)s,%(SUBJ3-SCORE)s,%(AGGREGATE)s,%(UNIV1)s,%(FACULTY1)s,%(COURSE1)s,%(UNIV2)s,%(FACULTY2)s,%(COURSE2)s\n' % jamb)
                 continue
-            sid = generateStudentId()
+            jamb_name = jamb.get("NAME")
+            names = jamb_name.split()
+            letter = names[-1][0].upper()
+            sid = generateStudentId(letter)
             #self.log('Creating Faculty %(id)s = %(Title)s' % faculty)
             not_created = True
@@ -325,22 +332,11 @@
                     not_created = False
                 except BadRequest:
-                    sid = generateStudentId()
+                    sid = generateStudentId(letter)
             logger.info('%(tr_count)s: Creating Student with ID %(sid)s REG-NO %(jamb_reg_no)s ' % vars())
-            s = getattr(self,sid)
-            self.portal_registration.addMember(sid, 
-                                               'uNsEt' ,
-                                               roles=('Member',
-                                                      'Student',))
-            s.invokeFactory('StudentApplication','application')
+            student = getattr(self,sid)
+            student.invokeFactory('StudentApplication','application')
             da = {'Title': 'Application Data'}
-##            s.invokeFactory('StudentPersonal','personal')
-##            sp = s.personal
-##            d = {'Title': 'Personal Data'}
-##            s.invokeFactory('StudentClearance','clearance')
-##            sc = s.clearance
-##            dc = {'Title': 'Clearance Data'}
             da["jamb_reg_no"] = jamb.get("REG-NO")
-            da["jamb_lastname"] = jamb.get("NAME")
-##            d["lastname"] = jamb.get("NAME")
+            da["jamb_lastname"] = jamb_name
             da["jamb_sex"] = jamb.get("SEX")
             da["jamb_state"] = jamb.get("STATE")
@@ -351,12 +347,24 @@
             da["jamb_first_uni"] = jamb.get("UNIV1")
             da["jamb_second_uni"] = jamb.get("UNIV2")
-##            s.personal.getContent().edit(mapping=d)
-            s.application.getContent().edit(mapping=da)
-            s.application.getContent().content_status_modify(workflow_action="open")
-            s.application.manage_setLocalRoles(s_id, ['Owner',])
+            app = student.application
+            app_doc = app.getContent()
+            app_doc.edit(mapping=da)
+            wftool.doActionFor(app,'open',dest_container=app)
+            app.manage_setLocalRoles(sid, ['Owner',])
+            student.getContent().createSubObjects()
         return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
     ###)
 
 
+    security.declareProtected(View,"fixOwnership")
+    def fixOwnership(self):
+        """fix Ownership"""
+        for s in self.portal_catalog(meta_type = 'Student'):
+            student = s.getObject()
+            sid = s.getId
+            import pdb;pdb.set_trace()
+            student.application.manage_setLocalRoles(sid, ['Owner',])
+            student.personal.manage_setLocalRoles(sid, ['Owner',])
+            
     security.declareProtected(View,"Title")
     def Title(self):
@@ -393,4 +401,47 @@
             return "%s" % (content.jamb_lastname)
         return self.title
+
+    security.declarePrivate('makeStudentMember') ###(
+    def makeStudentMember(self,sid,password='uNsEt'):
+        """make the student a member"""
+        membership = self.portal_membership
+        membership.addMember(sid, 
+                             password ,
+                             roles=('Member',
+                                     'Student',
+                                     'Owner'),
+                             domains='',
+                             properties = None,)
+        member = membership.getMemberById(sid)
+        self.portal_registration.afterAdd(member, sid, password, None)
+        self.manage_setLocalRoles(sid, ['Owner',])
+
+###)
+
+    security.declareProtected(View,'createSubObjects') ###(
+    def createSubObjects(self):
+        """make the student a member"""
+        dp = {'Title': 'Personal Data'}
+        names = self.application.getContent().jamb_lastname.split()
+        if len(names) == 3:
+            dp['firstname'] = names[0].capitalize()
+            dp['middlename'] = names[1].capitalize()
+            dp['lastname'] = names[2].capitalize()
+        elif len(names) == 2:
+            dp['firstname'] = names[0].capitalize()
+            dp['lastname'] = names[1].capitalize()
+        else:
+            dp['lastname'] = app_doc.jamb_lastname
+            dp['sex'] = app_doc.jamb_sex == 'F'
+            dp['lga'] = "%s/%s" % (app_doc.jamb_state,app_doc.jamb_lga )
+        proxy = self.aq_parent
+        proxy.invokeFactory('StudentPersonal','personal')
+        per = proxy.personal
+        per_doc = per.getContent()
+        per.manage_setLocalRoles(self.getId(), ['Owner',])
+        self.portal_workflow.doActionFor(per,'open',dest_container=per)
+        per_doc.edit(mapping = dp)
+        
+###)
 
 InitializeClass(Student)
Index: WAeUP_SRP/trunk/Widgets.py
===================================================================
--- WAeUP_SRP/trunk/Widgets.py	(revision 510)
+++ WAeUP_SRP/trunk/Widgets.py	(revision 511)
@@ -316,5 +316,5 @@
         pin = "%(p)s%(b)s%(n)s" % vars()
         ref = datastructure[self.reference]
-        import pdb;pdb.set_trace()
+        #import pdb;pdb.set_trace()
         ok = pins.searchAndSetRecord(pin,ref)
         while 1:
@@ -333,4 +333,6 @@
                 if ok == 2:
                     break
+                student.getContent().makeStudentMember(s_id,password=pin[4:])
+                #student.getContent().createSubObjects()
             break
         if err:
Index: WAeUP_SRP/trunk/__init__.py
===================================================================
--- WAeUP_SRP/trunk/__init__.py	(revision 510)
+++ WAeUP_SRP/trunk/__init__.py	(revision 511)
@@ -11,7 +11,8 @@
 from Products.CPSCore.interfaces import ICPSSite
 
+import PatchCPSWorkflowWorkflowDefinition
+import PatchCatalogToolXMLAdapter
 # Only for CPS 3.4.1. In 3.4.2 and later this should be fixed.
 import PatchCPSDefaultImportExport
-import PatchCatalogToolXMLAdapter
 
 import Products.WAeUP_SRP.WAeUPPermissions
Index: WAeUP_SRP/trunk/profiles/default/rolemap.xml
===================================================================
--- WAeUP_SRP/trunk/profiles/default/rolemap.xml	(revision 510)
+++ WAeUP_SRP/trunk/profiles/default/rolemap.xml	(revision 511)
@@ -2,4 +2,5 @@
 <rolemap>
   <roles>
+    <role name="Staff"/>
     <role name="Student"/>
     <role name="SectionReader"/>
Index: WAeUP_SRP/trunk/skins/waeup_default/process_waeup_login.py
===================================================================
--- WAeUP_SRP/trunk/skins/waeup_default/process_waeup_login.py	(revision 510)
+++ WAeUP_SRP/trunk/skins/waeup_default/process_waeup_login.py	(revision 511)
@@ -13,70 +13,12 @@
     if "Manager" in member.getRoles():
         return
-return
 member_id = str(member)
 student = getattr(context.students,member_id)
 application = student.application
-student.invokeFactory('StudentPersonal','personal')
-apdoc = application.getContent()
-names = apdoc.jamb_lastname.split()
-dp = {}
-if len(names) == 3:
-    dp['firstname'] = names[0].capitalize()
-    dp['middlename'] = names[1].capitalize()
-    dp['lastname'] = names[2].capitalize()
-elif len(names) == 2:
-    dp['firstname'] = names[0].capitalize()
-    dp['lastname'] = names[1].capitalize()
-else:
-    dp['lastname'] = apdoc.jamb_lastname
-    dp['sex'] = apdoc.jamb_sex == 'F'
-    dp['lga'] = "%s/%s" % (apdoc.jamb_state,apdoc.jamb_lga )
-student.personal.getContent().edit(mapping = dp)
 ##student.content_status_modify(workflow_action="enter_application_pin")
-
 da = {}
-da['app_ac_pin'] = request.get('pin')
+pin = request.get('pin')
+da['app_ac_pin'] = pin
 da['app_ac_date'] = current
-apdoc.edit(mapping = da)
-
+application.getContent().edit(mapping = da)
 return response.redirect("%s/application_form" % student.application.absolute_url())
-
-##ma = getattr(context,member_id)
-##jkw = {'application_sc_pin': sc_pin}
-##jamb = getattr(ma,'JAMB')
-##jamb.getContent().edit(mapping=jkw)
-###pdid = 'personal%s' % member_id
-##pdid = 'PERSONAL'
-##ma.invokeFactory('StudentPersonal', pdid)
-##pd = getattr(ma,pdid)
-##pkw = {}
-##jc = jamb.getContent()
-##pkw['sex'] = getattr(jc,'sex')
-##pkw['firstname'] = getattr(jc,'firstname')
-##pkw['middlename'] = getattr(jc,'middlename')
-##pkw['lastname'] = getattr(jc,'lastname')
-##pkw['aggregate'] = getattr(jc,'aggregate')
-##pkw['faculty'] = getattr(jc,'faculty')
-##pkw['course'] = getattr(jc,'course')
-##pkw['age'] = getattr(jc,'age')
-##pkw['jamb_results'] = getattr(jc,'exam_results')
-##pkw['jamb_aggregate'] = getattr(jc,'aggregate')
-##pkw['jamb_listing_date'] = getattr(jc,'listing_date')
-##pkw['state'] = getattr(jc,'state')
-##
-##pd.getContent().edit(mapping=pkw)
-##context.notifyCPSDocumentCreation(ob=pd)
-##
-##pdid = 'DOCUMENTS'
-##ma.invokeFactory('StudentDocuments', pdid)
-##pd = getattr(ma,pdid)
-##context.notifyCPSDocumentCreation(ob=pd)
-##
-##pdid = 'ELIGIBILITY'
-##ma.invokeFactory('StudentEligibility', pdid)
-##pd = getattr(ma,pdid)
-##pd.getContent().edit(mapping=pkw)
-##context.notifyCPSDocumentCreation(ob=pd)
-##
-###return ma.personal_addon(REQUEST=context.REQUEST)
-
Index: WAeUP_SRP/trunk/skins/waeup_student/apply_admission.py
===================================================================
--- WAeUP_SRP/trunk/skins/waeup_student/apply_admission.py	(revision 510)
+++ WAeUP_SRP/trunk/skins/waeup_student/apply_admission.py	(revision 511)
@@ -45,6 +45,7 @@
 elif psm == 'valid':
     s_id = ds.get('s_id')
+    pin = str(ds.get('app_ac_pin'))
     return context.REQUEST.RESPONSE.redirect("%s/logged_in?__ac_name=%s&__ac_password=%s&pin=%s"
-          % (context.absolute_url(),s_id,'uNsEt',ds.get('app_ac_pin')))
+          % (context.absolute_url(),s_id,pin.split('-')[2],pin))
     
 ##    jamb_id = ds.get('jamb_reg_no')
Index: WAeUP_SRP/trunk/skins/waeup_student/portlet_student_workflow_display.pt
===================================================================
--- WAeUP_SRP/trunk/skins/waeup_student/portlet_student_workflow_display.pt	(revision 510)
+++ WAeUP_SRP/trunk/skins/waeup_student/portlet_student_workflow_display.pt	(revision 511)
@@ -13,4 +13,11 @@
 <table class="registration">
   
+  <span tal:condition="python:1">
+    <tr>
+      <td class="active"><a href="apply" 
+                            tal:attributes="href string:${context/absolute_url}/students/apply_admission">
+        Apply for PUME</a></td>
+    </tr>
+  </span>
   <span tal:condition="python:path('info/review_state')=='application_pin_entered'">
   <tr><td class="active">Admission started</td></tr>
