source: WAeUP_SRP/trunk/WAeUPImport.py @ 3823

Last change on this file since 3823 was 3823, checked in by Henrik Bettermann, 16 years ago

resolve Uniben #593

  • Property svn:keywords set to Id
File size: 62.2 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 3823 2008-12-18 06:45:38Z 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
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.portal_directories = waeup_tool.portal_directories
73        self.students_catalog = waeup_tool.students_catalog
74        self.courses_catalog = waeup_tool.courses_catalog
75        self.course_results = waeup_tool.course_results
76        self.applicants_catalog = waeup_tool.applicants_catalog
77        #self.mode = mode
78        # self.import_method = getattr(self, '%s' % mode,None)
79        errors = []
80        # if self.import_method is None:
81        #     errors.append('No importer method %s' % mode)
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)
85        self.pending_fn = os.path.split(self.pending_path)[1]
86        self.imported_path = "%s/import/%s.imported" % (i_home,self.plural_name)
87        self.imported_fn = os.path.split(self.imported_path)[1]
88        iname = "import_%s" % self.name
89        self.logger = logging.getLogger('WAeUPImport.%sImport' % self.plural_name.capitalize())
90        self.schema = self.schema_tool._getOb(iname,None)
91        #self.pending_schema = self.schema_tool._getOb("%s_pending" % iname,None)
92        self.layout = self.layout_tool._getOb(iname,None)
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'] = ''
106            info['import_record_no'] = 0
107            info['imported_by'] = self.imported_by
108            info['import_date'] = self.import_date.strftime("%d/%m/%y %H:%M:%S")
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
121        self.init_errors = ','.join(errors)
122    ###)
123
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:
148                    if mode == 'create':
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]
163            else:
164                msg = "neither id, matric_no nor reg_no specified"
165            break
166        d = {}
167        d['student_record'] = student_record
168        d['key_used'] = key_used
169        d['msg'] = msg
170        return d
171    ###)
172
173    def makeIdLists(self): ###(
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")
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
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,
191            datafile.close()
192            #copy2(self.pending_path,self.pending_backup)
193        return pending, pending_digests
194    ###)
195
196    def checkHeadline(self,headline): ###(
197        """ check the headline of a csv file """
198        import_keys = [k.strip() for k in headline if not (k.strip().startswith('ignore')
199                                                        or k.strip() in self.info.keys())]
200        # import_keys = [k.strip() for k in headline if not (k.strip() in self.info.keys())]
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 []
207    ###)
208
209    def getHeadlineFields(self,headline,values): ###(
210        """ check the headline of a csv file """
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())]
214        info_keys = [k.strip() for k in headline if k.strip() in self.info.keys()]
215        si = set(import_keys)
216        ss = set(self.schema.keys())
217
218        invalid_keys = si - ss
219        keys = []
220        i = 0
221        duplicates = False
222        singels = []
223        msg = ''
224        while True:
225            if len(values) != len(import_keys):
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))
230                break
231            for k in import_keys:
232                if k in singels:
233                    keys += (k,'%s' % k,values[i],'(duplicate)'),
234                    msg += ("duplicate %s," % k)
235                    keys[singels.index(k)] = (k,'%s' % k,values[singels.index(k)],'(duplicate)')
236                elif k in invalid_keys and not k.startswith(IGNORE):
237                    keys += (k,NO_KEY,values[i],'(invalid)'),
238                else:
239                    keys += (k,k,values[i],''),
240                i += 1
241                singels += k,
242            break
243        return msg,keys
244    ###)
245###)
246
247class ApplicationImport(WAeUPImport):###(
248    name = "application"
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:
294            departments = self.portal_catalog(portal_type = "Department")
295            self._v_department_certificates = {}
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                                                            }
301        department_id = mapping['department_code']
302        msg = ''
303        certificate_id = mapping.get('code')
304        while True:
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
308                break
309            certificates_container = department_certificates['container']
310            certificates = department_certificates['certificates']
311            if certificate_id in self._v_certificate_list:
312                msg =  "Duplicate Certificate ID: %s" % department_id
313                break
314            if certificate_id in certificates:
315                msg =  "Duplicate Certificate ID: %s" % department_id
316                break
317            try:
318                certificates_container.invokeFactory('Certificate', certificate_id)
319            except BadRequest,E:
320                msg =  "%s" % E
321                break
322            self._v_certificate_list.append(certificate_id)
323            certificate = getattr(certificates_container,certificate_id)
324            certificate.getContent().edit(mapping=mapping)
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:
335                msg =  "no certificate with id: %s" % certificate_id
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 = []
352        if getattr(self,'_v_department_courses',None) is None:
353            departments = self.portal_catalog(portal_type = "Department")
354            self._v_department_courses = {}
355            for department in departments:
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                                                                   }
361        department_id = mapping['department_code']
362        course_id = mapping.get('code','')
363        msg = ''
364        while True:
365            department_courses = self._v_department_courses.get(department_id,None)
366            if department_courses is None:
367                msg =  "no department with id: %(department_id)s" % vars()
368                break
369            courses_container = department_courses['container']
370            courses = department_courses['courses']
371            if course_id in self._v_course_list:
372                msg =  "duplicate course id: %(course_id)s" % vars()
373                break
374            if course_id in courses:
375                msg =  "course %(course_id)s already exists in department %(department_id)s" % vars()
376                break
377            try:
378                courses_container.invokeFactory('Course', course_id)
379            except BadRequest,E:
380                msg =  "%s" % E
381                break
382            self._v_course_list.append(course_id)
383            course = getattr(courses_container,course_id)
384            course.getContent().edit(mapping=mapping)
385            break
386        return course_id,msg,mapping
387    ###)
388
389    def edit(self,mapping): ###(
390        course_id = mapping.get('code','')
391        course = self.courses_catalog.getRecordByKey(course_id)
392        msg = ''
393        while True:
394            if course is None:
395                msg =  "no course with id: %s" % course_id
396                break
397            course_object = getattr(getattr(getattr(getattr(self.academics_folder,course.faculty),
398                                    course.department),
399                                    'courses'),
400                                    course_id)
401            course_object.getContent().edit(mapping=mapping)
402            break
403        return course_id,msg,mapping
404    ###)
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   
422###)
423
424class CourseResultImport(WAeUPImport):###(
425    """ CourseresultImport """
426    name = "course_result"
427    plural_name = "%ss" % name
428    commit_after = 1000000
429    required_modes = ('create','edit','remove')
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 = []
440        if getattr(self,'_v_student_study_course',None) is None:
441            self._v_student_study_course = {}
442        msg = ''
443        key = ''
444        matric_no = mapping.get('matric_no','')
445        id = mapping.get('id','')
446        while True:
447            course_id = mapping.get('code')
448            if course_id not in self._v_courses.keys():
449                msg = "no course with id: %s" % course_id
450                break
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')
475                    session_id = mapping.get('session_id','')
476                    if session_id:
477                        level.getContent().edit(mapping={'session': "%s" % session_id,})
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()
481            #overwrite semester and credits in create mode
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
492    def edit(self,mapping): ###(
493        msg = ''
494        key = ''
495        matric_no = mapping.get('matric_no','')
496        id = mapping.get('id','')
497        while True:
498            result = self.findStudent('edit',student_id=id,matric_no=matric_no)
499            msg = result['msg']
500            if msg:
501                break
502            student_record = result['student_record']
503            student_id = student_record.id
504            level_id = mapping.get('level_id','')
505            code = mapping.get('code','')
506            #code = mapping['code']
507            mapping['key'] = 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.modifyRecord(**mapping)
512            break
513        return key,msg,mapping
514    ###)
515
516    def remove(self,mapping):###(
517        key = ''
518        msg = ''
519        matric_no = mapping.get('matric_no','')
520        id = mapping.get('id','')
521        while True:
522            result = self.findStudent('edit',student_id=id,matric_no=matric_no)
523            msg = result['msg']
524            if msg:
525                break
526            student_record = result['student_record']
527            student_id = student_record.id
528            level_id = mapping.get('level_id','')
529            code = mapping.get('code','')
530            key = "%(student_id)s|%(level_id)s|%(code)s" % vars()
531            if self.course_results.getRecordByKey(key) is None:
532                msg =  "no course result with key %(key)s" % vars()
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
543    commit_after = 1000
544    required_modes = ('create','edit')
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:
559                msg =  "no course with id: %s" % certificate_course_id
560                break
561            cert_id = mapping['certificate_code']
562            cert = self._v_certificates.get(cert_id,None)
563            if cert is None:
564                msg =  "no certificate with id: %s" % cert_id
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):
572                msg =  "duplicate certificate course id: %(certificate_course_id)s " % vars()
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
585    commit_after = 1000
586
587    def create(self,mapping):###(
588        "create a department in the correct faculty"
589        faculty_id = mapping['faculty_code']
590        msg = ''
591        if getattr(self,'_v_faculties',None) is None:
592            res = self.portal_catalog(portal_type = "Faculty")
593            self._v_faculties = {}
594            for f in res:
595                self._v_faculties[f.getId] = f.getObject()
596        department_id = mapping.get('code','')
597        while True:
598            faculty = self._v_faculties.get(faculty_id,None)
599            if faculty is None:
600                msg =  "no faculty with id: %s" % faculty_id
601                break
602            else:
603                d = getattr(faculty,department_id,None)
604                if d is None or d.portal_type == "Faculty":
605                    try:
606                        faculty.invokeFactory('Department', department_id)
607                    except BadRequest,E:
608                        msg =  "%s" % E
609                        break
610                    d = getattr(faculty,department_id)
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
621        return department_id,msg,mapping
622    ###)
623
624    def edit(self,mapping): ###(
625        "edit a department in the correct faculty"
626        academics_folder = self.portal_url.getPortalObject().campus.academics
627        faculty_id = mapping['faculty_code']
628        department_id = mapping.get('code','')
629        msg = ''
630        while True:
631            try:
632                d = getattr(getattr(academics_folder,faculty_id),department_id,None)
633            except KeyError:
634                msg =  "department %s or faculty %s wrong" % (department_id,faculty_id)
635                break
636            if d is None or d.portal_type == "Faculty":
637                msg =  "department %s not found" % (department_id)
638                break
639            d.getContent().edit(mapping=mapping)
640            break
641        return department_id,msg,mapping
642    ###)
643###)
644
645class FacultyImport(WAeUPImport):###(
646    name = "faculty"
647    plural_name = "faculties"
648    commit_after = 100
649   
650
651    def create(self,mapping): ###(
652        "create a faculty"
653        academics_folder = self.portal_url.getPortalObject().campus.academics
654        faculty_id = mapping.get('code','')
655        msg = ''
656        while True:
657            if faculty_id in academics_folder.objectIds():
658                msg =  "faculty with id: %s exists" % faculty_id
659                break
660            try:
661                academics_folder.invokeFactory('Faculty', faculty_id)
662            except BadRequest,E:
663                msg =  "%s" % E
664                break
665            f = getattr(academics_folder,faculty_id,None)
666            f.getContent().edit(mapping=mapping)
667            break
668        return faculty_id,msg,mapping
669        ###)
670
671    def edit(self,mapping): ###(
672        "edit a faculty"
673        academics_folder = self.portal_url.getPortalObject().campus.academics
674        faculty_id = mapping['code']
675        msg = ''
676        while True:
677            f = getattr(academics_folder,faculty_id,None)
678            if f is None:
679                msg =  "faculty with id: %s does not exist" % faculty_id
680            f.getContent().edit(mapping=mapping)
681            break
682        return faculty_id,msg,mapping
683    ###)
684###)
685
686class StudentImport(WAeUPImport):###(
687    name = "student"
688    plural_name = "%ss" % name
689    commit_after = 100
690
691    field2types_student = {   ###(
692                      'StudentApplication':
693                          {'id': 'application',
694                           #'title': 'Application Data',
695                           'wf_transition_return': 'close',
696                           'wf_transition_admit': 'remain',
697                           'wf_transition_graduate': 'close',
698                           'wf_transition_pay_school_fee': 'close',
699                           'wf_transition_validate_courses': 'close',
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',
723                           #'title': 'Clearance/Eligibility Record',
724                           'wf_transition_return': 'close',
725                           'wf_transition_admit': 'remain',
726                           'wf_transition_graduate': 'close',
727                           'wf_transition_pay_school_fee': 'close',
728                           'wf_transition_validate_courses': 'close',
729                           'fields':
730                             ('matric_no',
731                              'nationality',
732                              'lga',
733                              'birthday',
734                              )
735                              },
736                         'StudentPersonal':
737                          {'id': 'personal',
738                           #'title': 'Personal Data',
739                           'wf_transition_return': 'open',
740                           'wf_transition_admit': 'remain',
741                           'wf_transition_graduate': 'close',
742                           'wf_transition_pay_school_fee': 'open',
743                           'wf_transition_validate_courses': 'open',
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',
756                           #'title': 'Study Course',
757                           'wf_transition_return': 'open',
758                           'wf_transition_admit': 'remain',
759                           'wf_transition_graduate': 'close',
760                           'wf_transition_pay_school_fee': 'open',
761                           'wf_transition_validate_courses': 'open',
762                           'fields':
763                             ('study_course',
764                              'current_level',
765                              'current_session',
766                              'current_mode',  #is no longer used and visible but can still be imported
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',
783                           #'title': 'Payments',
784                           'wf_transition_return': 'open',
785                           'wf_transition_admit': 'open',
786                           'wf_transition_graduate': 'close',
787                           'wf_transition_pay_school_fee': 'open',
788                           'wf_transition_validate_courses': 'open',
789                           'fields':
790                             ()
791                              },
792                         }
793    ###)
794
795    def create(self,mapping): ###(
796        "create student records due import"
797        logger = logging.getLogger('WAeUPImport.StudentImport.create')
798        students_folder = self.portal_url.getPortalObject().campus.students
799        jamb_reg_no = mapping.get('jamb_reg_no',None)
800        matric_no = mapping.get('matric_no',None)
801        entry_mode = mapping.get('entry_mode',None)
802        msg = ''
803        student_id = mapping.get('id',None)
804        while True:
805            if student_id:
806                msg = "student_id must not be specified in create mode"
807                break
808            if jamb_reg_no and not entry_mode == 'transfer':
809                res = self.students_catalog(jamb_reg_no = jamb_reg_no)
810                if res:
811                    msg = "jamb_reg_no already assigned to student %s" % res[0].id
812                    break
813            if matric_no:
814                res = self.students_catalog(matric_no = matric_no)
815                if res:
816                    msg = "matric_no already assigned to student %s" % res[0].id
817                    break
818            if not matric_no and not jamb_reg_no:
819                msg = "jamb_reg_no or matric_no must be specified"
820                break
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')
827            if transition not in ('admit','return','pay_school_fee','validate_courses'):
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()
834                #d['Title'] = f2t[pt]['title']
835                for field in f2t[pt]['fields']:
836                    d[field] = mapping.get(field,'')
837
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)
845
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)
852
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',])
859            mapping['id'] = student_id
860            break
861        return student_id,msg,mapping
862    ###)
863
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')
912                # end export
913                students_folder.manage_delObjects((student_id),)         
914            else:
915                msg = "Student object not found"
916                break
917            if hasattr(stdir, student_id):
918                stdir.deleteEntry(student_id)
919            self.waeup_tool.removePictureFolder(student_id)           
920            break
921        return student_id,msg,mapping     
922
923
924    def edit(self,mapping): ###(
925        "edit student records due import"
926        wftool = self.portal_workflow
927        logger = logging.getLogger('WAeUPImport.StudentImport.edit')
928        students_folder = self.portal_url.getPortalObject().campus.students
929        student_id = mapping.get('id',None)
930        jamb_reg_no = mapping.get('jamb_reg_no',None)
931        matric_no = mapping.get('matric_no',None)
932        editable_keys = mapping.keys()
933        msg = ''
934        while True:
935            if student_id:
936                res = self.students_catalog(id = student_id)
937                if not res:
938                    msg = "no student with id %s" % student_id
939                    break
940                student_record = res[0]
941                if matric_no and student_record.matric_no:
942                    if  matric_no != student_record.matric_no and not matric_no == 'transferred':
943                        res = self.students_catalog(matric_no = matric_no)
944                        if res:
945                            msg = "matric_no already assigned to student %s" % res[0].id
946                            break
947                        msg = "old matric_no %s overwritten with %s" % (student_record.matric_no,matric_no)
948                        #logger.info("%s, old matric_no %s overwritten with %s" % (student_record.id,student_record.matric_no,matric_no))
949                if jamb_reg_no and student_record.jamb_reg_no:
950                    if jamb_reg_no != student_record.jamb_reg_no:
951                        res = self.students_catalog(jamb_reg_no = jamb_reg_no)
952                        if res:
953                            msg = "jamb_reg_no already assigned to student %s" % res[0].id
954                            break
955                        msg = "old jamb_reg_no %s overwritten with %s" % (student_record.jamb_reg_no,jamb_reg_no)
956                        #logger.info("%s, old reg_no %s overwritten with %s" % (student_record.id,student_record.jamb_reg_no,jamb_reg_no))
957            elif jamb_reg_no:
958                res = self.students_catalog(jamb_reg_no = jamb_reg_no)
959                if not res:
960                    msg = "no student with jamb_reg_no %s" % jamb_reg_no
961                    break
962                student_record = res[0]
963                editable_keys.remove('jamb_reg_no')
964            elif matric_no:
965                res = self.students_catalog(matric_no = matric_no)
966                if not res:
967                    msg = "no student with matric_no %s" % matric_no
968                    break
969                student_record = res[0]
970                editable_keys.remove('matric_no')
971            student_id = student_record.id
972            student_obj = getattr(students_folder,student_id)
973            f2t = self.field2types_student
974            d = {}
975            any_change = False
976            #special treatment for StudentStudyLevel
977            d['verdict']  = mapping.get('current_verdict','')
978            d['session']  = mapping.get('current_session','')
979            current_level = mapping.get('current_level','')
980            transition = mapping.get('reg_transition',None)
981            # the validate_courses import transition is not really useful because it does not execute validate_courses.py
982            if transition and transition not in ('admit','return','graduate','pay_school_fee','validate_courses'):
983                msg = "no valid transition provided"
984                break     
985            while d['session'] and d['verdict'] and current_level:
986                sub_obj = getattr(student_obj,'study_course',None)
987                if sub_obj is None:
988                    break
989                level_obj = getattr(sub_obj,current_level,None)
990                if  level_obj is None:
991                    break
992                any_change = True
993                level_obj.getContent().edit(mapping = d)
994                try:
995                    wftool.doActionFor(level_obj,'close')
996                except:
997                    pass
998                break
999           
1000            for pt in f2t.keys():
1001                #if pt == "StudentApplication":
1002                #    d['jamb_sex']  = 'M'
1003                #    if mapping.get('sex'):
1004                #        d['jamb_sex']  = 'F'
1005                intersect = set(f2t[pt]['fields']).intersection(set(editable_keys))
1006                #import pdb;pdb.set_trace()
1007                object_id = f2t[pt]['id']
1008                sub_obj = getattr(student_obj,object_id,None)
1009                if intersect and pt not in ('StudentStudyLevel',):
1010                    if sub_obj is None:
1011                        try:
1012                            student_obj.invokeFactory(pt,object_id)
1013                        except:
1014                            continue
1015                        sub_obj = getattr(student_obj,object_id)
1016                        #if f2t[pt]['title'] != '':
1017                        #    d['Title'] = f2t[pt]['title']
1018                    sub_doc = sub_obj.getContent()
1019                    for field in intersect:
1020                        changed = False
1021                        if getattr(sub_doc,field,None) != mapping.get(field,''):
1022                            any_change = True
1023                            changed = True
1024                            d[field] = mapping.get(field,'')
1025                        if changed:
1026                            sub_doc.edit(mapping = d)
1027                if transition:
1028                    new_state = f2t[pt]['wf_transition_%(transition)s' % vars()]
1029                    if new_state != "remain":
1030                        try:
1031                            self.portal_workflow.doActionFor(sub_obj,new_state,dest_container=sub_obj)
1032                        except:
1033                            pass
1034            if transition:
1035                try:
1036                    self.portal_workflow.doActionFor(student_obj,transition)
1037                except:
1038                    msg = "reg_transition not allowed"
1039            break
1040        return student_id,msg,mapping
1041    ###)
1042###)
1043
1044class StudentStudyLevelImport(WAeUPImport):###(
1045    """ StudentStudyLevelImport """
1046    name = "student_study_level"
1047    plural_name = "%ss" % name
1048    commit_after = 1000000
1049    required_modes = ('create',)
1050
1051    def create(self,mapping): ###(
1052        "edit student levels and create StudentStudyLevel object if not existent"
1053        wftool = self.portal_workflow
1054        logger = logging.getLogger('WAeUPTool.mass_create_level')
1055        students_folder = self.portal_url.getPortalObject().campus.students
1056        student_id = mapping.get('id',None)
1057        matric_no = mapping.get('matric_no',None)
1058        editable_keys = mapping.keys()
1059        key = ''
1060        msg = ''
1061        while True:
1062            result = self.findStudent('create',student_id=student_id,matric_no=matric_no)
1063            msg = result['msg']
1064            if msg:
1065                break
1066            student_record = result['student_record']
1067            student_id = student_record.id
1068            mapping['id'] = student_id
1069            session = mapping.get('session','')
1070            level = key = mapping.get('code','')
1071            if not level.isdigit():
1072                msg = 'student %s: imported level is empty' % (student_id,)
1073                break
1074            study_course_obj = getattr(getattr(students_folder,student_id),'study_course',None)
1075            if study_course_obj is None:
1076                msg = 'student %s: no study_course object' % student_id
1077                break
1078            level_obj = getattr(study_course_obj,level,None)
1079            if  level_obj is None:
1080                # The only difference to the edit method is that we create a StudentStudyLevel object
1081                try:
1082                    study_course_obj.invokeFactory('StudentStudyLevel',"%s" % level)
1083                    level_obj = getattr(context,"%s" % level)
1084                except:
1085                    continue
1086            level_obj.getContent().edit(mapping = mapping)
1087            level_review_state = wftool.getInfoFor(level_obj,'review_state',None)
1088            if level_review_state != "closed":
1089                wftool.doActionFor(level_obj,'close')
1090            break
1091        return key,msg,mapping
1092    ###)
1093
1094    def edit(self,mapping): ###(
1095        "edit student levels"
1096        wftool = self.portal_workflow
1097        logger = logging.getLogger('WAeUPTool.mass_edit_level')
1098        students_folder = self.portal_url.getPortalObject().campus.students
1099        student_id = mapping.get('id',None)
1100        matric_no = mapping.get('matric_no',None)
1101        key = ''
1102        msg = ''
1103        while True:
1104            result = self.findStudent('create',student_id=student_id,matric_no=matric_no)
1105            msg = result['msg']
1106            if msg:
1107                break
1108            student_record = result['student_record']
1109            student_id = student_record.id
1110            mapping['id'] = student_id
1111            session = mapping.get('session','')
1112            level = key = mapping.get('code','')
1113            #import pdb;pdb.set_trace()
1114            if not level.isdigit():
1115                msg = 'student %s: imported level is empty' % (student_id,)
1116                break
1117            study_course_obj = getattr(getattr(students_folder,student_id),'study_course',None)
1118            if study_course_obj is None:
1119                msg = 'student %s: no study_course object' % student_id
1120                break
1121            level_obj = getattr(study_course_obj,level,None)
1122            if  level_obj is None:
1123                msg = 'student %s: no study_level object for level %s' % (student_id,level)
1124                break
1125            level_obj.getContent().edit(mapping = mapping)
1126            break
1127        return key,msg,mapping
1128    ###)
1129###)
1130
1131class VerdictImport(WAeUPImport):###(
1132    """ VerdictImport """
1133    name = "verdict"
1134    plural_name = "%ss" % name
1135    commit_after = 100000
1136    required_modes = ('create','edit')
1137
1138    def create(self,mapping): ###(
1139        "edit student verdicts and create StudentStudyLevel object if not existent"
1140        wftool = self.portal_workflow
1141        logger = logging.getLogger('WAeUPTool.mass_edit_verdict')
1142        students_folder = self.portal_url.getPortalObject().campus.students
1143        student_id = mapping.get('id',None)
1144        matric_no = mapping.get('matric_no',None)
1145        editable_keys = mapping.keys()
1146        key = ''
1147        while True:
1148            result = self.findStudent('create',student_id=student_id,matric_no=matric_no)
1149            #student_record,msg = self.getStudentRecord(mapping)
1150            msg = result['msg']
1151            if msg:
1152                break
1153            student_record = result['student_record']
1154            student_id = student_record.id
1155            mapping['id'] = student_id
1156            d = {}
1157            #import pdb;pdb.set_trace()
1158            any_change = False
1159            #special treatment for StudentStudyLevel
1160            current_session = d['session'] = mapping.get('current_session','')
1161            if current_session and student_record.session != current_session:
1162                msg = 'student %s: imported session %s does not match current_session %s' % (student_id,
1163                                                                                            current_session,
1164                                                                                            student_record.session)
1165                break
1166            current_level = mapping.get('current_level','')
1167            if not current_level.isdigit():
1168                msg = 'student %s: imported level is empty' % (student_id,)
1169                break
1170            if current_level and student_record.level != current_level:
1171                msg = 'student %s: imported level %s does not match current_level %s' % (student_id,
1172                                                                                        current_level,
1173                                                                                        student_record.level)
1174                break
1175            student_review_state =  student_record.review_state
1176            if student_review_state == 'deactivated':
1177                msg = "student %s in review_state %s" % (student_id, student_review_state)
1178                break
1179            if student_review_state not in ('courses_validated','returning'):
1180                msg = "student %s in wrong review_state %s" % (student_id, student_review_state)
1181                break
1182            student_obj = getattr(students_folder,student_id)
1183            # f2t = self.field2types_student
1184            study_course_obj = getattr(student_obj,'study_course',None)
1185            if study_course_obj is None:
1186                msg = 'student %s: no study_course object' % student_id
1187                break
1188            level_obj = getattr(study_course_obj,current_level,None)
1189
1190            if  level_obj is None:
1191                # The only difference to the edit method is that we create a StudentStudyLevel object
1192                try:
1193                    study_course_obj.invokeFactory('StudentStudyLevel',"%s" % current_level)
1194                    level_obj = getattr(context,"%s" % current_level)
1195                    level_obj.portal_workflow.doActionFor(level,'open')
1196                except:
1197                    continue
1198                #msg = 'student %s: no study_level object for level %s' % (student_id,
1199                #                                                                current_level)
1200                #break
1201
1202            verdict = d['verdict'] = d['current_verdict']  = mapping.get('current_verdict','')
1203
1204            #if verdict == student_record.verdict:
1205            #    msg = 'student %s: verdict already set to %s' % (student_id,
1206            #                                                            verdict)
1207
1208            level_review_state = wftool.getInfoFor(level_obj,'review_state',None)
1209            if level_review_state != "closed":
1210                wftool.doActionFor(level_obj,'close')
1211                # msg = 'student %s: level %s is not closed' % (student_id,
1212                #                                                      current_level)
1213
1214            study_course_obj.getContent().edit(mapping = d)
1215            level_obj.getContent().edit(mapping = d)
1216            if student_review_state != "returning":
1217                wftool.doActionFor(student_obj,'return')
1218            # try:
1219            #     wftool.doActionFor(level_obj,'close')
1220            # except:
1221            #     pass
1222            break
1223        return student_id,msg,mapping
1224    ###)
1225
1226
1227    def edit(self,mapping): ###(
1228        "edit student verdicts"
1229        wftool = self.portal_workflow
1230        logger = logging.getLogger('WAeUPTool.mass_edit_verdict')
1231        students_folder = self.portal_url.getPortalObject().campus.students
1232        student_id = mapping.get('id',None)
1233        matric_no = mapping.get('matric_no',None)
1234        editable_keys = mapping.keys()
1235        key = ''
1236        while True:
1237            result = self.findStudent('edit',student_id=student_id,matric_no=matric_no)
1238            #student_record,msg = self.getStudentRecord(mapping)
1239            msg = result['msg']
1240            if msg:
1241                break
1242            student_record = result['student_record']
1243            key_used = result['key_used']
1244            if key_used in editable_keys:
1245                editable_keys.remove(key_used)
1246            student_id = student_record.id
1247            mapping['id'] = student_id
1248            d = {}
1249            #import pdb;pdb.set_trace()
1250            any_change = False
1251            #special treatment for StudentStudyLevel
1252            current_session = d['session'] = mapping.get('current_session','')
1253            if current_session and student_record.session != current_session:
1254                msg = 'student %s: imported session %s does not match current_session %s' % (student_id,
1255                                                                                            current_session,
1256                                                                                            student_record.session)
1257                break
1258            current_level = mapping.get('current_level','')
1259            if not current_level.isdigit():
1260                msg = 'student %s: imported level is empty' % (student_id,)
1261                break
1262            if current_level and student_record.level != current_level:
1263                msg = 'student %s: imported level %s does not match current_level %s' % (student_id,
1264                                                                                        current_level,
1265                                                                                        student_record.level)
1266                break
1267            student_review_state =  student_record.review_state
1268            if student_review_state == 'deactivated':
1269                msg = "student %s in review_state %s" % (student_id, student_review_state)
1270                break
1271            if student_review_state not in ('courses_validated','returning'):
1272                msg = "student %s in wrong review_state %s" % (student_id, student_review_state)
1273                break
1274            student_obj = getattr(students_folder,student_id)
1275            # f2t = self.field2types_student
1276            study_course_obj = getattr(student_obj,'study_course',None)
1277            if study_course_obj is None:
1278                msg = 'student %s: no study_course object' % student_id
1279                break
1280            level_obj = getattr(study_course_obj,current_level,None)
1281            if  level_obj is None:
1282                msg = 'student %s: no study_level object for level %s' % (student_id,
1283                                                                                current_level)
1284                break
1285            verdict = d['verdict'] = d['current_verdict']  = mapping.get('current_verdict','')
1286
1287            #if verdict == student_record.verdict:
1288            #    msg = 'student %s: verdict already set to %s' % (student_id,
1289            #                                                            verdict)
1290
1291            level_review_state = wftool.getInfoFor(level_obj,'review_state',None)
1292            if level_review_state != "closed":
1293                wftool.doActionFor(level_obj,'close')
1294                # msg = 'student %s: level %s is not closed' % (student_id,
1295                #                                                      current_level)
1296
1297            study_course_obj.getContent().edit(mapping = d)
1298            level_obj.getContent().edit(mapping = d)
1299            if student_review_state != "returning":
1300                wftool.doActionFor(student_obj,'return')
1301            # try:
1302            #     wftool.doActionFor(level_obj,'close')
1303            # except:
1304            #     pass
1305            break
1306        return student_id,msg,mapping
1307    ###)
1308
1309    def edit_old(self,mapping): ###(
1310        "edit student verdicts"
1311        wftool = self.portal_workflow
1312        logger = logging.getLogger('WAeUPTool.mass_edit_verdict')
1313        students_folder = self.portal_url.getPortalObject().campus.students
1314        student_id = mapping.get('id',None)
1315        matric_no = mapping.get('matric_no',None)
1316        editable_keys = mapping.keys()
1317        key = ''
1318        while True:
1319            msg = ''
1320            if student_id:
1321                student_record = self.students_catalog.getRecordByKey(student_id)
1322                if student_record is None:
1323                    #return '',"no student with id %s" % student_id
1324                    msg = "no student with id %s" % student_id
1325                    break
1326                if matric_no and student_record.matric_no and matric_no != student_record.matric_no:
1327                    msg = 'student %s: matric_no %s does not match %s' % (student_record.id,
1328                                                                          student_record.matric_no,
1329                                                                          matric_no)
1330                    break
1331                mapping['matric_no'] = student_record.matric_no
1332            elif matric_no:
1333                res = self.students_catalog(matric_no = matric_no)
1334                if not res:
1335                    msg = "no student with matric_no %s" % matric_no
1336                    break
1337                student_record = res[0]
1338                editable_keys.remove('matric_no')
1339            else:
1340                msg = "no id or matric_no specified"
1341                break
1342            student_id = student_record.id
1343            mapping['id'] = student_id
1344            d = {}
1345            #import pdb;pdb.set_trace()
1346            any_change = False
1347            #special treatment for StudentStudyLevel
1348            current_session = d['session'] = mapping.get('current_session','')
1349            if current_session and student_record.session != current_session:
1350                msg = 'student %s: imported session %s does not match current_session %s' % (student_id,
1351                                                                                            current_session,
1352                                                                                            student_record.session)
1353                break
1354            current_level = mapping.get('current_level','')
1355            if not current_level.isdigit():
1356                msg = 'student %s: imported level is empty' % (student_id,)
1357                break
1358            if current_level and student_record.level != current_level:
1359                msg = 'student %s: imported level %s does not match current_level %s' % (student_id,
1360                                                                                        current_level,
1361                                                                                        student_record.level)
1362                break
1363            student_review_state =  student_record.review_state
1364            if student_review_state == 'deactivated':
1365                msg = "student %s in review_state %s" % (student_id, student_review_state)
1366                break
1367            if student_review_state not in ('courses_validated','returning'):
1368                msg = "student %s in wrong review_state %s" % (student_id, student_review_state)
1369                break
1370            student_obj = getattr(students_folder,student_id)
1371            # f2t = self.field2types_student
1372            study_course_obj = getattr(student_obj,'study_course',None)
1373            if study_course_obj is None:
1374                msg = 'student %s: no study_course object' % student_id
1375                break
1376            level_obj = getattr(study_course_obj,current_level,None)
1377            if  level_obj is None:
1378                msg = 'student %s: no study_level object for level %s' % (student_id,
1379                                                                                current_level)
1380                break
1381            verdict = d['verdict'] = d['current_verdict']  = mapping.get('current_verdict','')
1382
1383            #if verdict == student_record.verdict:
1384            #    msg = 'student %s: verdict already set to %s' % (student_id,
1385            #                                                            verdict)
1386
1387            level_review_state = wftool.getInfoFor(level_obj,'review_state',None)
1388            if level_review_state != "closed":
1389                wftool.doActionFor(level_obj,'close')
1390                # msg = 'student %s: level %s is not closed' % (student_id,
1391                #                                                      current_level)
1392
1393            study_course_obj.getContent().edit(mapping = d)
1394            level_obj.getContent().edit(mapping = d)
1395            if student_review_state != "returning":
1396                wftool.doActionFor(student_obj,'return')
1397            # try:
1398            #     wftool.doActionFor(level_obj,'close')
1399            # except:
1400            #     pass
1401            break
1402        return student_id,msg,mapping
1403    ###)
1404###)
Note: See TracBrowser for help on using the repository browser.