source: WAeUP_SRP/base/WAeUPImport.py @ 3379

Last change on this file since 3379 was 3375, checked in by joachim, 17 years ago

fix for #515

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