source: WAeUP_SRP/trunk/WAeUPImport.py @ 3841

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