source: WAeUP_SRP/base/WAeUPImport.py @ 3373

Last change on this file since 3373 was 3372, checked in by joachim, 17 years ago

new import for levels (not yet tested)
fix for creating course_results, tested with NCERESULT7.csv on my local
system.
edit-mode not tested yet.

  • Property svn:keywords set to Id
File size: 68.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 3372 2008-03-25 19:03:53Z 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 old_getStudentRecord(self,mapping): ###(
412        id_field_found = False
413        msg = ''
414        student_record = None
415        id_count = 0
416        for id_key in ('matric_no','id'):
417            id_field = mapping.get(id_key,'')
418            if id_field:
419                id_count += 1
420                search_key = id_key
421                search_field = id_field
422        while True:
423            #if id_count > 1:
424            #    msg = "both id and matric_no are provided"
425            #    break
426            if id_count == 0:
427                msg = "neither id nor matric_no provided"
428                break
429            query = Eq(search_key,search_field)
430            res = self.students_catalog.evalAdvancedQuery(query)
431            if res:
432                student_record = res[0]
433                if search_key == "matric_no":
434                    mapping['id'] = student_record.id
435                elif search_key == "id":
436                    mapping['matric_no'] = student_record.matric_no
437            else:
438                msg = "no student with %(search_key)s %(search_field)s" % vars()
439            break
440        return student_record,msg
441    ###)
442
443    def create(self,mapping):###(
444        students_folder = self.portal_url.getPortalObject().campus.students
445        if getattr(self,'_v_courses',None) is None:
446            res = self.courses_catalog()
447            self._v_courses = {}
448            for brain in res:
449                self._v_courses[brain.code] = brain
450        if getattr(self,'_v_level_created',None) is None:
451            self._v_level_created = []
452        if getattr(self,'_v_student_study_course',None) is None:
453            self._v_student_study_course = {}
454        msg = ''
455        key = ''
456        matric_no = mapping.get('matric_no','')
457        id = mapping.get('id','')
458        while True:
459            course_id = mapping.get('code')
460            if course_id not in self._v_courses.keys():
461                msg = "no course with id: %s" % course_id
462                break
463            result = self.findStudent('create',student_id=id,matric_no=matric_no)
464            #student_record,msg = self.getStudentRecord(mapping)
465            msg = result['msg']
466            if msg:
467                break
468            student_record = result['student_record']
469            student_id = mapping['student_id']  = student_record.id
470            level_id = mapping.get('level_id','')
471            code = mapping.get('code','')
472            level_ident = "%(student_id)s_%(level_id)s" % vars()
473            if level_ident not in self._v_level_created:
474                context = self._v_student_study_course.get(student_id,None)
475                if context is None:
476                    try:
477                        context = getattr(getattr(students_folder,
478                                                "%(student_id)s" % vars()),
479                                        'study_course')
480                        self._v_student_study_course[student_id] = context
481                    except:
482                        msg = "could not create level %(level_id)s for %(student_id)s" % vars()
483                        break
484                if level_id not in context.objectIds():
485                    context.invokeFactory('StudentStudyLevel',"%(level_id)s" % vars())
486                    level = getattr(context,"%(level_id)s" % vars())
487                    self.portal_workflow.doActionFor(level,'open')
488                    level.getContent().edit(mapping={'session': "%(session_id)s" % mapping,})
489                    self.portal_workflow.doActionFor(level,'close')
490                    self._v_level_created += level_ident,
491            mapping['key'] = key = "%(student_id)s|%(level_id)s|%(code)s" % vars()
492            for k in ('semester','credits',):
493                mapping[k] = getattr(self._v_courses[course_id],k)
494            try:
495                self.course_results.addRecord(**mapping)
496            except ValueError:
497                msg = "course result already exists: %s" % key
498            break
499        return key,msg,mapping
500    ###)
501
502    def create_old(self,mapping):###(
503        students_folder = self.portal_url.getPortalObject().campus.students
504        if getattr(self,'_v_courses',None) is None:
505            res = self.courses_catalog()
506            self._v_courses = {}
507            for brain in res:
508                self._v_courses[brain.code] = brain
509        if getattr(self,'_v_level_created',None) is None:
510            self._v_level_created = []
511        msg = ''
512        key = ''
513        matric_no = mapping.get('matric_no','')
514        student_id = mapping.get('id','')
515        while True:
516            course_id = mapping.get('code')
517            if course_id not in self._v_courses.keys():
518                msg = "no course with id: %s" % course_id
519                break
520            student_record,msg = self.getStudentRecord(mapping)
521            if msg:
522                break
523            student_id = student_record.id
524            level_id = mapping.get('level_id','')
525            code = mapping.get('code','')
526            if student_id not in self._v_level_created:
527                try:
528                    context = getattr(getattr(students_folder,
529                                            "%(student_id)s" % vars()),
530                                    'study_course')
531                except:
532                    msg = "could not create level %(level_id)s for %(student_id)s" % vars()
533                    break
534                if level_id not in context.objectIds():
535                    context.invokeFactory('StudentStudyLevel',"%(level_id)s" % vars())
536                    level = getattr(context,"%(level_id)s" % vars())
537                    self.portal_workflow.doActionFor(level,'open')
538                    # the session string must not be copied into the level object
539                    current_verdict = getattr(student_record,'current_verdict','')
540                    current_session = getattr(student_record,'current_session','')
541                    if current_verdict and student_record.current_level == level_id:
542                        level.getContent().edit(mapping={'verdict': "%s" %
543                                                        current_verdict,
544                                                        'session': "%s" %
545                                                        current_session,
546                                                        })
547                        self.portal_workflow.doActionFor(level,'close')
548                self._v_level_created += student_id,
549            mapping['key'] = key = "%(student_id)s|%(level_id)s|%(code)s" % vars()
550            for k in ('semester','credits',):
551                mapping[k] = getattr(self._v_courses[course_id],k)
552            try:
553                self.course_results.addRecord(**mapping)
554            except ValueError:
555                msg = "course result already exists: %s" % key
556            break
557        return key,msg,mapping
558    ###)
559
560    def edit(self,mapping): ###(
561        msg = ''
562        key = ''
563        while True:
564            result = self.findStudent('edit',student_id=id,matric_no=matric_no)
565            #student_record,msg = self.getStudentRecord(mapping)
566            msg = result['msg']
567            if msg:
568                break
569            student_record = result['student_record']
570            student_id = student_record.id
571            level_id = mapping.get('level_id','')
572            code = mapping.get('code','')
573            code = mapping['code']
574            mapping['key'] = key = "%(student_id)s|%(level_id)s|%(code)s" % vars()
575            if self.course_results.getRecordByKey(key) is None:
576                msg =  "no course result with key %(key)s" % vars()
577                break
578            self.course_results.modifyRecord(**mapping)
579            break
580        return key,msg,mapping
581    ###)
582
583    def remove(self,mapping):###(
584        key = ''
585        msg = ''
586        while True:
587            student_record,msg = self.getStudentRecord(mapping)
588            if msg:
589                break
590            student_id = student_record.id
591            level_id = mapping.get('level_id','')
592            code = mapping.get('code','')
593            key = "%(student_id)s|%(level_id)s|%(code)s" % vars()
594            if self.course_results.getRecordByKey(key) is None:
595                msg =  "no course result with key %(key)s" % vars()
596                break
597            self.course_results.deleteRecord(key)
598            break
599        return key,msg,mapping
600    ###)
601###)
602
603class CertificateCourseImport(WAeUPImport):###(
604    name = "certificate_course"
605    plural_name = "%ss" % name
606    commit_after = 100000
607    required_modes = ('create','edit')
608
609    def create(self,mapping):
610        if getattr(self,'_v_courses',None) is None:
611            res = self.courses_catalog()
612            self._v_courses= [course.code for course in res]
613        if getattr(self,'_v_ceritficates',None) is None:
614            res = self.portal_catalog(portal_type = "Certificate")
615            self._v_certificates = {}
616            for cert in res:
617                self._v_certificates[cert.getId] = cert.getObject()
618        msg = ''
619        while True:
620            certificate_course_id = mapping.get('code')
621            if certificate_course_id not in self._v_courses:
622                msg =  "no course with id: %s" % certificate_course_id
623                break
624            cert_id = mapping['certificate_code']
625            cert = self._v_certificates.get(cert_id,None)
626            if cert is None:
627                msg =  "no certificate with id: %s" % cert_id
628                break
629            level_id = mapping.get('level')
630            level = getattr(cert,level_id,None)
631            if level is None:
632                cert.invokeFactory('StudyLevel', level_id)
633                level = getattr(cert,level_id,None)
634            elif hasattr(level,certificate_course_id):
635                msg =  "duplicate certificate course id: %(certificate_course_id)s " % vars()
636                msg += "in %(cert_id)s/ %(level_id)s" % vars()
637                break
638            level.invokeFactory('CertificateCourse', certificate_course_id)
639            c = getattr(level,certificate_course_id)
640            c.getContent().edit(mapping=mapping)
641            break
642        return certificate_course_id,msg,mapping
643    ###)
644
645class DepartmentImport(WAeUPImport):###(
646    name = "department"
647    plural_name = "%ss" % name
648    commit_after = 1000
649
650    def create(self,mapping):###(
651        "create a department in the correct faculty"
652        faculty_id = mapping['faculty_code']
653        msg = ''
654        if getattr(self,'_v_faculties',None) is None:
655            res = self.portal_catalog(portal_type = "Department")
656            self._v_faculties = {}
657            for f in res:
658                self._v_faculties[f.getId] = f.getObject()
659        department_id = mapping.get('code','')
660        while True:
661            faculty = self._v_faculties.get(faculty_id,None)
662            if faculty is None:
663                msg =  "no faculty with id: %s" % faculty_id
664                break
665            else:
666                d = getattr(faculty,department_id,None)
667                if d is None or d.portal_type == "Faculty":
668                    try:
669                        faculty.invokeFactory('Department', department_id)
670                    except BadRequest,E:
671                        msg =  "%s" % E
672                        break
673                    d = getattr(faculty,department_id)
674                    d.invokeFactory('CoursesFolder','courses')
675                    courses = getattr(d,'courses')
676                    dict = {'Title': 'Courses'}
677                    courses.getContent().edit(mapping=dict)
678                    d.invokeFactory('CertificatesFolder','certificates')
679                    certificates = getattr(d,'certificates')
680                    dict = {'Title': 'Certificates'}
681                    certificates.getContent().edit(mapping=dict)
682                    d.getContent().edit(mapping=mapping)
683            break
684        return department_id,msg,mapping
685    ###)
686
687    def edit(self,mapping): ###(
688        "edit a department in the correct faculty"
689        academics_folder = self.portal_url.getPortalObject().campus.academics
690        faculty_id = mapping['faculty_code']
691        department_id = mapping.get('code','')
692        msg = ''
693        while True:
694            try:
695                d = getattr(getattr(academics_folder,faculty_id),department_id,None)
696            except KeyError:
697                msg =  "department %s or faculty %s wrong" % (department_id,faculty_id)
698                break
699            if d is None or d.portal_type == "Faculty":
700                msg =  "department %s not found" % (department_id)
701                break
702            d.getContent().edit(mapping=mapping)
703            break
704        return department_id,msg,mapping
705    ###)
706###)
707
708class FacultyImport(WAeUPImport):###(
709    name = "faculty"
710    plural_name = "faculties"
711    commit_after = 100
712
713    def create(self,mapping): ###(
714        "create a faculty"
715        academics_folder = self.portal_url.getPortalObject().campus.academics
716        faculty_id = mapping.get('code','')
717        msg = ''
718        while True:
719            if faculty_id in academics_folder.objectIds():
720                msg =  "faculty with id: %s exists" % faculty_id
721                break
722            logger.info('Creating Faculty %(code)s, %(title)s' % mapping)
723            try:
724                academics_folder.invokeFactory('Faculty', faculty_id)
725            except BadRequest,E:
726                msg =  "%s" % E
727                break
728            f = getattr(academics_folder,faculty_id,None)
729            f.getContent().edit(mapping=mapping)
730            break
731        return faculty_id,msg,mapping
732        ###)
733
734    def edit(self,mapping): ###(
735        "edit a faculty"
736        academics_folder = self.portal_url.getPortalObject().campus.academics
737        faculty_id = mapping['code']
738        msg = ''
739        while True:
740            f = getattr(academics_folder,faculty_id,None)
741            if f is None:
742                msg =  "faculty with id: %s does not exist" % faculty_id
743            f.getContent().edit(mapping=mapping)
744            break
745        return faculty_id,msg,mapping
746    ###)
747###)
748
749class StudentImport(WAeUPImport):###(
750    name = "student"
751    plural_name = "%ss" % name
752    commit_after = 100
753
754    field2types_student = {   ###(
755                      'StudentApplication':
756                          {'id': 'application',
757                           'title': 'Application Data',
758                           'wf_transition_return': 'close',
759                           'wf_transition_admit': 'remain',
760                           'fields':
761                             ('jamb_reg_no',
762                              'entry_mode',
763                              'entry_session',
764                              'jamb_score',
765                              'app_email',
766                              'jamb_age',
767                              'jamb_state',
768                              'jamb_lga',
769                              'jamb_sex',
770                              )
771                              },
772                      #'StudentPume':
773                      #    {'id': 'pume',
774                      #     'title': 'Pume Data',
775                      #     'wf_transition_return': 'close',
776                      #     'wf_transition_admit': 'close',
777                      #     'fields':
778                      #       ('pume_score',
779                      #        )
780                      #        },
781                      'StudentClearance':
782                          {'id': 'clearance',
783                           'title': 'Clearance/Eligibility Record',
784                           'wf_transition_return': 'close',
785                           'wf_transition_admit': 'remain',
786                           'fields':
787                             ('matric_no',
788                              'nationality',
789                              'lga',
790                              'birthday',
791                              )
792                              },
793                         'StudentPersonal':
794                          {'id': 'personal',
795                           'title': 'Personal Data',
796                           'wf_transition_return': 'open',
797                           'wf_transition_admit': 'remain',
798                           'fields':
799                             ('firstname',
800                              'middlename',
801                              'lastname',
802                              'sex',
803                              'email',
804                              'phone',
805                              'perm_address',
806                              )
807                              },
808                         'StudentStudyCourse':
809                          {'id': 'study_course',
810                           'title': 'Study Course',
811                           'wf_transition_return': 'open',
812                           'wf_transition_admit': 'remain',
813                           'fields':
814                             ('study_course',
815                              'current_level',
816                              'current_session',
817                              'current_mode',
818                              'current_verdict',
819                              'previous_verdict',
820                              )
821                              },
822                         # 'StudentStudyLevel':
823                         #  {'id': 'current_level',
824                         #   'title': '',
825                         #   'wf_transition_return': 'open',
826                         #   'wf_transition_admit': 'remain',
827                         #   'fields':
828                         #     ('verdict',
829                         #      'session',
830                         #      )
831                         #      },
832                         'PaymentsFolder':
833                          {'id': 'payments',
834                           'title': 'Payments',
835                           'wf_transition_return': 'open',
836                           'wf_transition_admit': 'open',
837                           'fields':
838                             ()
839                              },
840                         }
841    ###)
842
843    def create(self,mapping): ###(
844        "create student records due import"
845        logger = logging.getLogger('WAeUPTool.mass_create_student')
846        students_folder = self.portal_url.getPortalObject().campus.students
847        jamb_reg_no = mapping.get('jamb_reg_no',None)
848        matric_no = mapping.get('matric_no',None)
849        msg = ''
850        student_id = mapping.get('id',None)
851        while True:
852            if student_id:
853                msg = "student_id must not be specified in create mode"
854                break
855            if jamb_reg_no:
856                res = self.students_catalog(jamb_reg_no = jamb_reg_no)
857                if res:
858                    msg = "jamb_reg_no exists"
859                    break
860            if matric_no:
861                res = self.students_catalog(matric_no = matric_no)
862                if res:
863                    msg = "matric_no exists"
864                    break
865            if not matric_no and not jamb_reg_no:
866                msg = "jamb_reg_no or matric_no must be specified"
867                break
868            student_id = self.waeup_tool.generateStudentId('?')
869            students_folder.invokeFactory('Student', student_id)
870            student_obj = getattr(students_folder,student_id)
871            f2t = self.field2types_student
872            d = {}
873            transition = mapping.get('reg_transition','admit')
874            if transition not in ('admit','return'):
875                msg = "no valid transition provided"
876                break
877            for pt in f2t.keys():
878                student_obj.invokeFactory(pt,f2t[pt]['id'])
879                sub_obj = getattr(student_obj,f2t[pt]['id'])
880                sub_doc = sub_obj.getContent()
881                d['Title'] = f2t[pt]['title']
882                for field in f2t[pt]['fields']:
883                    d[field] = mapping.get(field,'')
884
885                if pt == "StudentApplication":
886                    #d['jamb_sex']  = 'M'
887                    #if mapping.get('sex'):
888                    #    d['jamb_sex']  = 'F'
889                    d['jamb_firstname'] = mapping.get('firstname',None)
890                    d['jamb_middlename'] = mapping.get('middlename',None)
891                    d['jamb_lastname'] = mapping.get('lastname',None)
892
893                # if pt == "StudyCourse":
894                #     for von,zu in (('entry_mode','current_mode'),
895                #                    ('entry_session','current_session')):
896                #         if mapping.get(zu,None) is None and mapping.get(von,None) is not None:
897                #             d[zu] = mapping[von]
898                sub_doc.edit(mapping = d)
899
900                #import pdb;pdb.set_trace()
901                new_state = f2t[pt]['wf_transition_%(transition)s' % vars()]
902                if new_state != "remain":
903                    self.portal_workflow.doActionFor(sub_obj,new_state,dest_container=sub_obj)
904            self.portal_workflow.doActionFor(student_obj,transition)
905            student_obj.manage_setLocalRoles(student_id, ['Owner',])
906            mapping['id'] = student_id
907            break
908        return student_id,msg,mapping
909    ###)
910
911    def edit(self,mapping): ###(
912        wftool = self.portal_workflow
913        "edit student records due import"
914        logger = logging.getLogger('WAeUPTool.mass_edit_student')
915        students_folder = self.portal_url.getPortalObject().campus.students
916        student_id = mapping.get('id',None)
917        jamb_reg_no = mapping.get('jamb_reg_no',None)
918        matric_no = mapping.get('matric_no',None)
919        editable_keys = mapping.keys()
920        msg = ''
921        while True:
922            if student_id:
923                res = self.students_catalog(id = student_id)
924                if not res:
925                    msg = "no student with id %s" % student_id
926                    break
927                student_record = res[0]
928                if matric_no and student_record.matric_no:
929                    if  matric_no != student_record.matric_no:
930                        msg = "old matric_no %s overwritten with %s" % (student_record.matric_no,matric_no)
931                        #logger.info("%s, old matric_no %s overwritten with %s" % (student_record.id,student_record.matric_no,matric_no))
932                if jamb_reg_no and student_record.jamb_reg_no:
933                    if jamb_reg_no != student_record.jamb_reg_no:
934                        msg = "old reg_no %s overwritten with %s" % (student_record.jamb_reg_no,jamb_reg_no)
935                        #logger.info("%s, old reg_no %s overwritten with %s" % (student_record.id,student_record.jamb_reg_no,jamb_reg_no))
936            elif jamb_reg_no:
937                res = self.students_catalog(jamb_reg_no = jamb_reg_no)
938                if not res:
939                    msg = "no student with jamb_reg_no %s" % jamb_reg_no
940                    break
941                student_record = res[0]
942                editable_keys.remove('jamb_reg_no')
943            elif matric_no:
944                res = self.students_catalog(matric_no = matric_no)
945                if not res:
946                    msg = "no student with matric_no %s" % matric_no
947                    break
948                student_record = res[0]
949                editable_keys.remove('matric_no')
950            ## included only to change wf state from admitted to returning
951            #if student_record.review_state not in ('admitted','objection_raised'):
952            #    return '%s' % student_record.id ,"student is not in state admitted or objection_raised"
953            ## end inclusion
954            student_id = student_record.id
955            student_obj = getattr(students_folder,student_id)
956            f2t = self.field2types_student
957            d = {}
958            any_change = False
959            #special treatment for StudentStudyLevel
960            d['verdict']  = mapping.get('current_verdict','')
961            d['session']  = mapping.get('current_session','')
962            current_level = mapping.get('current_level','')
963            while d['session'] and d['verdict'] and current_level:
964                sub_obj = getattr(student_obj,'study_course',None)
965                if sub_obj is None:
966                    break
967                level_obj = getattr(sub_obj,current_level,None)
968                if  level_obj is None:
969                    break
970                any_change = True
971                level_obj.getContent().edit(mapping = d)
972                try:
973                    wftool.doActionFor(level_obj,'close')
974                except:
975                    pass
976                break
977            for pt in f2t.keys():
978                #if pt == "StudentApplication":
979                #    d['jamb_sex']  = 'M'
980                #    if mapping.get('sex'):
981                #        d['jamb_sex']  = 'F'
982                intersect = set(f2t[pt]['fields']).intersection(set(editable_keys))
983                if intersect and pt not in ('StudentStudyLevel',):
984                    object_id = f2t[pt]['id']
985                    sub_obj = getattr(student_obj,object_id,None)
986                    if sub_obj is None:
987                        try:
988                            student_obj.invokeFactory(pt,object_id)
989                        except:
990                            continue
991                        sub_obj = getattr(student_obj,object_id)
992                        if f2t[pt]['title'] != '':
993                            d['Title'] = f2t[pt]['title']
994                    sub_doc = sub_obj.getContent()
995                    for field in intersect:
996                        changed = False
997                        if getattr(sub_doc,field,None) != mapping.get(field,''):
998                            any_change = True
999                            changed = True
1000                            d[field] = mapping.get(field,'')
1001                        if changed:
1002                            sub_doc.edit(mapping = d)
1003            ## included only to change wf state from admitted to returning
1004            #    if student_record.review_state in ('admitted','objection_raised'):
1005            #        new_state = f2t[pt]['wf_transition_return']
1006            #        sub_obj = getattr(student_obj,f2t[pt]['id'],None)
1007            #        if sub_obj and new_state != "remain":
1008            #            try:
1009            #                self.portal_workflow.doActionFor(sub_obj,new_state,dest_container=sub_obj)
1010            #            except:
1011            #                #logger.info('%s, wf transition %s of %s failed' % (student_id,new_state,sub_obj.id))
1012            #                pass
1013            #if student_record.review_state in ('admitted','objection_raised'):
1014            #    wfaction = 'return'
1015            #    try:
1016            #        self.portal_workflow.doActionFor(student_obj,wfaction)
1017            #        logger.info('%s, wf state changed' % student_id)
1018            #        any_change = True
1019            #    except:
1020            #        logger.info('%s, wf transition failed, old state = %s' % (student_id,student_record.review_state))
1021            #        pass
1022            ## end inclusion
1023            break
1024        # if not any_change:
1025        #     msg = 'not modified'
1026        return student_id,msg,mapping
1027    ###)
1028###)
1029
1030class StudentStudyLevelImport(WAeUPImport):###(
1031    """ StudentStudyLevelImport """
1032    name = "student_study_level"
1033    plural_name = "%ss" % name
1034    commit_after = 1000000
1035    required_modes = ('create',)
1036
1037    def create(self,mapping):
1038        "edit student levels and create StudentStudyLevel object if not existent"
1039        wftool = self.portal_workflow
1040        logger = logging.getLogger('WAeUPTool.mass_create_level')
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        msg = ''
1047        while True:
1048            result = self.findStudent('create',student_id=student_id,matric_no=matric_no)
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            session = mapping.get('session','')
1056            level = key = mapping.get('code','')
1057            if not level.isdigit():
1058                msg = 'student %s: imported level is empty' % (student_id,)
1059                break
1060            student_course_obj = getattr(getattr(students_folder,student_id),student_obj,'study_course',None)
1061            if study_course_obj is None:
1062                msg = 'student %s: no study_course object' % student_id
1063                break
1064            level_obj = getattr(study_course_obj,level,None)
1065            if  level_obj is None:
1066                # The only difference to the edit method is that we create a StudentStudyLevel object
1067                try:
1068                    study_course_obj.invokeFactory('StudentStudyLevel',"%s" % level)
1069                    level_obj = getattr(context,"%s" % level)
1070                except:
1071                    continue
1072            level_obj.getContent().edit(mapping = mapping)
1073            level_review_state = wftool.getInfoFor(level_obj,'review_state',None)
1074            if level_review_state != "closed":
1075                wftool.doActionFor(level_obj,'close')
1076            break
1077        return key,msg,mapping
1078    ###)
1079
1080    def edit(self,mapping): ###(
1081        "edit student levels"
1082        wftool = self.portal_workflow
1083        logger = logging.getLogger('WAeUPTool.mass_edit_level')
1084        students_folder = self.portal_url.getPortalObject().campus.students
1085        student_id = mapping.get('id',None)
1086        matric_no = mapping.get('matric_no',None)
1087        key = ''
1088        msg = ''
1089        while True:
1090            result = self.findStudent('create',student_id=student_id,matric_no=matric_no)
1091            msg = result['msg']
1092            if msg:
1093                break
1094            student_record = result['student_record']
1095            student_id = student_record.id
1096            mapping['id'] = student_id
1097            #import pdb;pdb.set_trace()
1098            session = d['session'] = mapping.get('session','')
1099            level = key = mapping.get('level','')
1100            if not level.isdigit():
1101                msg = 'student %s: imported level is empty' % (student_id,)
1102                break
1103            student_course_obj = getattr(getattr(students_folder,student_id),student_obj,'study_course',None)
1104            if study_course_obj is None:
1105                msg = 'student %s: no study_course object' % student_id
1106                break
1107            level_obj = getattr(study_course_obj,level,None)
1108            if  level_obj is None:
1109                msg = 'student %s: no study_level object for level %s' % (student_id,level)
1110                break
1111            level_obj.getContent().edit(mapping = mapping)
1112            break
1113        return key,msg,mapping
1114    ###)
1115
1116class VerdictImport(WAeUPImport):###(
1117    """ VerdictImport """
1118    name = "verdict"
1119    plural_name = "%ss" % name
1120    commit_after = 100000
1121    required_modes = ('create','edit')
1122
1123    def create(self,mapping): ###(
1124        "edit student verdicts and create StudentStudyLevel object if not existent"
1125        wftool = self.portal_workflow
1126        logger = logging.getLogger('WAeUPTool.mass_edit_verdict')
1127        students_folder = self.portal_url.getPortalObject().campus.students
1128        student_id = mapping.get('id',None)
1129        matric_no = mapping.get('matric_no',None)
1130        editable_keys = mapping.keys()
1131        key = ''
1132        while True:
1133            result = self.findStudent('create',student_id=student_id,matric_no=matric_no)
1134            #student_record,msg = self.getStudentRecord(mapping)
1135            msg = result['msg']
1136            if msg:
1137                break
1138            student_record = result['student_record']
1139            student_id = student_record.id
1140            mapping['id'] = student_id
1141            d = {}
1142            #import pdb;pdb.set_trace()
1143            any_change = False
1144            #special treatment for StudentStudyLevel
1145            current_session = d['session'] = mapping.get('current_session','')
1146            if current_session and student_record.session != current_session:
1147                msg = 'student %s: imported session %s does not match current_session %s' % (student_id,
1148                                                                                            current_session,
1149                                                                                            student_record.session)
1150                break
1151            current_level = mapping.get('current_level','')
1152            if not current_level.isdigit():
1153                msg = 'student %s: imported level is empty' % (student_id,)
1154                break
1155            if current_level and student_record.level != current_level:
1156                msg = 'student %s: imported level %s does not match current_level %s' % (student_id,
1157                                                                                        current_level,
1158                                                                                        student_record.level)
1159                break
1160            student_review_state =  student_record.review_state
1161            if student_review_state == 'deactivated':
1162                msg = "student %s in review_state %s" % (student_id, student_review_state)
1163                break
1164            if student_review_state not in ('courses_validated','returning'):
1165                msg = "student %s in wrong review_state %s" % (student_id, student_review_state)
1166                break
1167            student_obj = getattr(students_folder,student_id)
1168            # f2t = self.field2types_student
1169            study_course_obj = getattr(student_obj,'study_course',None)
1170            if study_course_obj is None:
1171                msg = 'student %s: no study_course object' % student_id
1172                break
1173            level_obj = getattr(study_course_obj,current_level,None)
1174
1175            if  level_obj is None:
1176                # The only difference to the edit method is that we create a StudentStudyLevel object
1177                try:
1178                    study_course_obj.invokeFactory('StudentStudyLevel',"%s" % current_level)
1179                    level_obj = getattr(context,"%s" % current_level)
1180                    level_obj.portal_workflow.doActionFor(level,'open')
1181                except:
1182                    continue
1183                #msg = 'student %s: no study_level object for level %s' % (student_id,
1184                #                                                                current_level)
1185                #break
1186
1187            verdict = d['verdict'] = d['current_verdict']  = mapping.get('current_verdict','')
1188
1189            #if verdict == student_record.verdict:
1190            #    msg = 'student %s: verdict already set to %s' % (student_id,
1191            #                                                            verdict)
1192
1193            level_review_state = wftool.getInfoFor(level_obj,'review_state',None)
1194            if level_review_state != "closed":
1195                wftool.doActionFor(level_obj,'close')
1196                # msg = 'student %s: level %s is not closed' % (student_id,
1197                #                                                      current_level)
1198
1199            study_course_obj.getContent().edit(mapping = d)
1200            level_obj.getContent().edit(mapping = d)
1201            if student_review_state != "returning":
1202                wftool.doActionFor(student_obj,'return')
1203            # try:
1204            #     wftool.doActionFor(level_obj,'close')
1205            # except:
1206            #     pass
1207            break
1208        return student_id,msg,mapping
1209    ###)
1210
1211    def create_old(self,mapping): ###(
1212        "edit student verdicts and create StudentStudyLevel object if not existent"
1213        wftool = self.portal_workflow
1214        logger = logging.getLogger('WAeUPTool.mass_edit_verdict')
1215        students_folder = self.portal_url.getPortalObject().campus.students
1216        student_id = mapping.get('id',None)
1217        matric_no = mapping.get('matric_no',None)
1218        editable_keys = mapping.keys()
1219        while True:
1220            key = ''
1221            msg = ''
1222            if student_id:
1223                student_record = self.students_catalog.getRecordByKey(student_id)
1224                if student_record is None:
1225                    #return '',"no student with id %s" % student_id
1226                    msg = "no student with id %s" % student_id
1227                    break
1228                if matric_no and student_record.matric_no and matric_no != student_record.matric_no:
1229                    msg = 'student %s: matric_no %s does not match %s' % (student_record.id,
1230                                                                          student_record.matric_no,
1231                                                                          matric_no)
1232                    break
1233                mapping['matric_no'] = student_record.matric_no
1234            elif matric_no:
1235                res = self.students_catalog(matric_no = matric_no)
1236                if not res:
1237                    msg = "no student with matric_no %s" % matric_no
1238                    break
1239                student_record = res[0]
1240                editable_keys.remove('matric_no')
1241            else:
1242                msg = "no id or matric_no specified"
1243                break
1244            student_id = student_record.id
1245            mapping['id'] = student_id
1246            d = {}
1247            #import pdb;pdb.set_trace()
1248            any_change = False
1249            #special treatment for StudentStudyLevel
1250            current_session = d['session'] = mapping.get('current_session','')
1251            if current_session and student_record.session != current_session:
1252                msg = 'student %s: imported session %s does not match current_session %s' % (student_id,
1253                                                                                            current_session,
1254                                                                                            student_record.session)
1255                break
1256            current_level = mapping.get('current_level','')
1257            if not current_level.isdigit():
1258                msg = 'student %s: imported level is empty' % (student_id,)
1259                break
1260            if current_level and student_record.level != current_level:
1261                msg = 'student %s: imported level %s does not match current_level %s' % (student_id,
1262                                                                                        current_level,
1263                                                                                        student_record.level)
1264                break
1265            student_review_state =  student_record.review_state
1266            if student_review_state == 'deactivated':
1267                msg = "student %s in review_state %s" % (student_id, student_review_state)
1268                break
1269            if student_review_state not in ('courses_validated','returning'):
1270                msg = "student %s in wrong review_state %s" % (student_id, student_review_state)
1271                break
1272            student_obj = getattr(students_folder,student_id)
1273            # f2t = self.field2types_student
1274            study_course_obj = getattr(student_obj,'study_course',None)
1275            if study_course_obj is None:
1276                msg = 'student %s: no study_course object' % student_id
1277                break
1278            level_obj = getattr(study_course_obj,current_level,None)
1279
1280            if  level_obj is None:
1281                # The only difference to the edit method is that we create a StudentStudyLevel object
1282                try:
1283                    study_course_obj.invokeFactory('StudentStudyLevel',"%s" % current_level)
1284                    level_obj = getattr(context,"%s" % current_level)
1285                    level_obj.portal_workflow.doActionFor(level,'open')
1286                except:
1287                    continue
1288                #msg = 'student %s: no study_level object for level %s' % (student_id,
1289                #                                                                current_level)
1290                #break
1291
1292            verdict = d['verdict'] = d['current_verdict']  = mapping.get('current_verdict','')
1293
1294            #if verdict == student_record.verdict:
1295            #    msg = 'student %s: verdict already set to %s' % (student_id,
1296            #                                                            verdict)
1297
1298            level_review_state = wftool.getInfoFor(level_obj,'review_state',None)
1299            if level_review_state != "closed":
1300                wftool.doActionFor(level_obj,'close')
1301                # msg = 'student %s: level %s is not closed' % (student_id,
1302                #                                                      current_level)
1303
1304            study_course_obj.getContent().edit(mapping = d)
1305            level_obj.getContent().edit(mapping = d)
1306            if student_review_state != "returning":
1307                wftool.doActionFor(student_obj,'return')
1308            # try:
1309            #     wftool.doActionFor(level_obj,'close')
1310            # except:
1311            #     pass
1312            break
1313        return student_id,msg,mapping
1314    ###)
1315
1316    def edit(self,mapping): ###(
1317        "edit student verdicts"
1318        wftool = self.portal_workflow
1319        logger = logging.getLogger('WAeUPTool.mass_edit_verdict')
1320        students_folder = self.portal_url.getPortalObject().campus.students
1321        student_id = mapping.get('id',None)
1322        matric_no = mapping.get('matric_no',None)
1323        editable_keys = mapping.keys()
1324        key = ''
1325        while True:
1326            result = self.findStudent('edit',student_id=student_id,matric_no=matric_no)
1327            #student_record,msg = self.getStudentRecord(mapping)
1328            msg = result['msg']
1329            if msg:
1330                break
1331            student_record = result['student_record']
1332            key_used = result['key_used']
1333            # if student_id:
1334            #     student_record = self.students_catalog.getRecordByKey(student_id)
1335            #     if student_record is None:
1336            #         #return '',"no student with id %s" % student_id
1337            #         msg = "no student with id %s" % student_id
1338            #         break
1339            #     if matric_no and student_record.matric_no and matric_no != student_record.matric_no:
1340            #         msg = 'student %s: matric_no %s does not match %s' % (student_record.id,
1341            #                                                               student_record.matric_no,
1342            #                                                               matric_no)
1343            #         break
1344            #     mapping['matric_no'] = student_record.matric_no
1345            # elif matric_no:
1346            #     res = self.students_catalog(matric_no = matric_no)
1347            #     if not res:
1348            #         msg = "no student with matric_no %s" % matric_no
1349            #         break
1350            #     student_record = res[0]
1351            #     editable_keys.remove('matric_no')
1352            # else:
1353            #     msg = "no id or matric_no specified"
1354            #     break
1355            editable_keys.remove(key_used)
1356            student_id = student_record.id
1357            mapping['id'] = student_id
1358            d = {}
1359            #import pdb;pdb.set_trace()
1360            any_change = False
1361            #special treatment for StudentStudyLevel
1362            current_session = d['session'] = mapping.get('current_session','')
1363            if current_session and student_record.session != current_session:
1364                msg = 'student %s: imported session %s does not match current_session %s' % (student_id,
1365                                                                                            current_session,
1366                                                                                            student_record.session)
1367                break
1368            current_level = mapping.get('current_level','')
1369            if not current_level.isdigit():
1370                msg = 'student %s: imported level is empty' % (student_id,)
1371                break
1372            if current_level and student_record.level != current_level:
1373                msg = 'student %s: imported level %s does not match current_level %s' % (student_id,
1374                                                                                        current_level,
1375                                                                                        student_record.level)
1376                break
1377            student_review_state =  student_record.review_state
1378            if student_review_state == 'deactivated':
1379                msg = "student %s in review_state %s" % (student_id, student_review_state)
1380                break
1381            if student_review_state not in ('courses_validated','returning'):
1382                msg = "student %s in wrong review_state %s" % (student_id, student_review_state)
1383                break
1384            student_obj = getattr(students_folder,student_id)
1385            # f2t = self.field2types_student
1386            study_course_obj = getattr(student_obj,'study_course',None)
1387            if study_course_obj is None:
1388                msg = 'student %s: no study_course object' % student_id
1389                break
1390            level_obj = getattr(study_course_obj,current_level,None)
1391            if  level_obj is None:
1392                msg = 'student %s: no study_level object for level %s' % (student_id,
1393                                                                                current_level)
1394                break
1395            verdict = d['verdict'] = d['current_verdict']  = mapping.get('current_verdict','')
1396
1397            #if verdict == student_record.verdict:
1398            #    msg = 'student %s: verdict already set to %s' % (student_id,
1399            #                                                            verdict)
1400
1401            level_review_state = wftool.getInfoFor(level_obj,'review_state',None)
1402            if level_review_state != "closed":
1403                wftool.doActionFor(level_obj,'close')
1404                # msg = 'student %s: level %s is not closed' % (student_id,
1405                #                                                      current_level)
1406
1407            study_course_obj.getContent().edit(mapping = d)
1408            level_obj.getContent().edit(mapping = d)
1409            if student_review_state != "returning":
1410                wftool.doActionFor(student_obj,'return')
1411            # try:
1412            #     wftool.doActionFor(level_obj,'close')
1413            # except:
1414            #     pass
1415            break
1416        return student_id,msg,mapping
1417    ###)
1418
1419    def edit_old(self,mapping): ###(
1420        "edit student verdicts"
1421        wftool = self.portal_workflow
1422        logger = logging.getLogger('WAeUPTool.mass_edit_verdict')
1423        students_folder = self.portal_url.getPortalObject().campus.students
1424        student_id = mapping.get('id',None)
1425        matric_no = mapping.get('matric_no',None)
1426        editable_keys = mapping.keys()
1427        key = ''
1428        while True:
1429            msg = ''
1430            if student_id:
1431                student_record = self.students_catalog.getRecordByKey(student_id)
1432                if student_record is None:
1433                    #return '',"no student with id %s" % student_id
1434                    msg = "no student with id %s" % student_id
1435                    break
1436                if matric_no and student_record.matric_no and matric_no != student_record.matric_no:
1437                    msg = 'student %s: matric_no %s does not match %s' % (student_record.id,
1438                                                                          student_record.matric_no,
1439                                                                          matric_no)
1440                    break
1441                mapping['matric_no'] = student_record.matric_no
1442            elif matric_no:
1443                res = self.students_catalog(matric_no = matric_no)
1444                if not res:
1445                    msg = "no student with matric_no %s" % matric_no
1446                    break
1447                student_record = res[0]
1448                editable_keys.remove('matric_no')
1449            else:
1450                msg = "no id or matric_no specified"
1451                break
1452            student_id = student_record.id
1453            mapping['id'] = student_id
1454            d = {}
1455            #import pdb;pdb.set_trace()
1456            any_change = False
1457            #special treatment for StudentStudyLevel
1458            current_session = d['session'] = mapping.get('current_session','')
1459            if current_session and student_record.session != current_session:
1460                msg = 'student %s: imported session %s does not match current_session %s' % (student_id,
1461                                                                                            current_session,
1462                                                                                            student_record.session)
1463                break
1464            current_level = mapping.get('current_level','')
1465            if not current_level.isdigit():
1466                msg = 'student %s: imported level is empty' % (student_id,)
1467                break
1468            if current_level and student_record.level != current_level:
1469                msg = 'student %s: imported level %s does not match current_level %s' % (student_id,
1470                                                                                        current_level,
1471                                                                                        student_record.level)
1472                break
1473            student_review_state =  student_record.review_state
1474            if student_review_state == 'deactivated':
1475                msg = "student %s in review_state %s" % (student_id, student_review_state)
1476                break
1477            if student_review_state not in ('courses_validated','returning'):
1478                msg = "student %s in wrong review_state %s" % (student_id, student_review_state)
1479                break
1480            student_obj = getattr(students_folder,student_id)
1481            # f2t = self.field2types_student
1482            study_course_obj = getattr(student_obj,'study_course',None)
1483            if study_course_obj is None:
1484                msg = 'student %s: no study_course object' % student_id
1485                break
1486            level_obj = getattr(study_course_obj,current_level,None)
1487            if  level_obj is None:
1488                msg = 'student %s: no study_level object for level %s' % (student_id,
1489                                                                                current_level)
1490                break
1491            verdict = d['verdict'] = d['current_verdict']  = mapping.get('current_verdict','')
1492
1493            #if verdict == student_record.verdict:
1494            #    msg = 'student %s: verdict already set to %s' % (student_id,
1495            #                                                            verdict)
1496
1497            level_review_state = wftool.getInfoFor(level_obj,'review_state',None)
1498            if level_review_state != "closed":
1499                wftool.doActionFor(level_obj,'close')
1500                # msg = 'student %s: level %s is not closed' % (student_id,
1501                #                                                      current_level)
1502
1503            study_course_obj.getContent().edit(mapping = d)
1504            level_obj.getContent().edit(mapping = d)
1505            if student_review_state != "returning":
1506                wftool.doActionFor(student_obj,'return')
1507            # try:
1508            #     wftool.doActionFor(level_obj,'close')
1509            # except:
1510            #     pass
1511            break
1512        return student_id,msg,mapping
1513    ###)
1514###)
Note: See TracBrowser for help on using the repository browser.