source: WAeUP_SRP/base/WAeUPImport.py @ 3427

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

correct logging message

Also jamb_reg_nos must be unique, condtion added.

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