source: WAeUP_SRP/trunk/WAeUPImport.py @ 3785

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