source: WAeUP_SRP/base/WAeUPImport.py @ 3177

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

pending only only depends on "pending data only" some fixes for FacultyImport?

  • Property svn:keywords set to Id
File size: 38.6 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 3177 2008-02-18 10:06:25Z 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
28#from 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
35#from 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
40#from 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
53class WAeUPImport: ###(
54    """ WAeUPImport """
55    required_modes = ('create',)
56
57    def __init__(self,mode,waeup_tool):
58        self.member = member = waeup_tool.portal_membership.getAuthenticatedMember()
59        self.import_date = DateTime.DateTime().strftime("%d/%m/%y %H:%M:%S")
60        self.current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
61        self.waeup_tool = waeup_tool
62        self.schema_tool = getToolByName(waeup_tool, 'portal_schemas')
63        self.layout_tool = getToolByName(waeup_tool, 'portal_layouts')
64        self.portal_workflow = getToolByName(waeup_tool, 'portal_workflow')
65        self.portal_url = getToolByName(waeup_tool, 'portal_url')
66        self.students_catalog = waeup_tool.students_catalog
67        self.courses_catalog = waeup_tool.courses_catalog
68        self.course_results = waeup_tool.course_results
69        self.mode = mode
70        self.import_method = getattr(self, '%s' % mode,None)
71        errors = []
72        if self.import_method is None:
73            errors.append('No importer method %s' % mode)
74        self.pending_path = "%s/import/%s_pending.csv" % (i_home,self.plural_name)
75        self.pending_tmp = "%s/import/%s_pending.csv.tmp" % (i_home,self.plural_name)
76        self.pending_backup = "%s/import/%s_pending.csv.backup" % (i_home,self.plural_name)
77        self.pending_fn = os.path.split(self.pending_path)[1]
78        self.imported_path = "%s/import/%s_imported.csv" % (i_home,self.plural_name)
79        self.imported_fn = os.path.split(self.imported_path)[1]
80        iname = "import_%s" % self.name
81        self.logger = logging.getLogger('WAeUPTool.import%s' % self.plural_name.capitalize())
82        self.schema = self.schema_tool._getOb(iname,None)
83        self.pending_schema = self.schema_tool._getOb("%s_pending" % iname,None)
84        self.layout = self.layout_tool._getOb(iname,None)
85        if self.schema is None:
86            errors.append('No schema %s' % iname)
87        if self.pending_schema is None:
88            self.pending_schema = self.schema
89        if self.layout is None:
90            errors.append('No such layout %s' % iname)
91        self.data_keys = self.pending_schema.keys()
92        self.csv_keys = self.pending_schema.keys()
93        info = {}
94        info['imported_from'] = ''
95        info['imported_by'] = str(member)
96        info['import_date'] = self.import_date
97        info['import_mode'] = mode
98        info['error'] = ''
99        self.info = info
100        self.csv_keys.extend(self.info)
101        self.validators = {}
102        for widget in self.layout.keys():
103            self.validators[widget] = self.layout[widget].validate
104        self.init_errors = ','.join(errors)
105
106    def makeIdLists(self):
107        pending_digests = []
108        pending = []
109        # pending_student_ids = []
110        # pending_matric_nos = []
111        # pending_reg_ns = []
112        if os.path.exists(self.pending_path):
113            datafile = open(self.pending_path,"r")
114            pending_csv_reader = csv.DictReader(datafile,self.csv_keys,)
115            pending_csv_reader.next() # skip headline
116            for item in pending_csv_reader:
117                digest = makeDigest(item,self.data_keys)
118                if digest not in pending_digests:
119                    pending_digests += digest,
120                    pending += item,
121            copy2(self.pending_path,self.pending_backup)
122            pending_at_start = len(pending)               
123            datafile.close()
124        return pending, pending_digests
125###)
126
127class ApplicationImport(WAeUPImport):###(
128    name = "applications"
129    plural_name = "%ss" % name
130    commit_after = 1000
131
132    def create(self,mapping):###(
133        reg_no = mapping.get('reg_no')
134        msg = ''
135        while True:
136            try:
137                self.applicants_catalog.addRecord(**mapping)
138            except ValueError:
139                msg =  "applicant record with reg_no %s already exists" % reg_no
140            break
141        return reg_no,msg,mapping
142    ###)
143
144    def edit(self,mapping):###(
145        reg_no = mapping.get('reg_no')
146        status = mapping.get('status')
147        msg = ''
148        while True:
149            res = self.applicants_catalog(reg_no = reg_no)
150            if len(res):
151                if res[0].status == 'created' and status != 'created':
152                    msg =  "student object with id %s for %s already created, status cannot be changed" % (res[0].student_id, reg_no)
153                elif status == 'created' and res[0].status != 'created':
154                    msg =  "student object for %s has not yet been created, status cannot be set to 'created'" % (reg_no)
155                else:
156                    self.applicants_catalog.modifyRecord(**mapping)
157            else:
158                msg =  "applicant record with reg_no %s does not exist" % reg_no
159            break
160        return reg_no,msg,mapping
161    ###)
162
163###)
164
165class CertificateImport(WAeUPImport):###(
166    name = "certificate"
167    plural_name = "%ss" % name
168    commit_after = 100000
169
170    def create(self,mapping):###(
171        if getattr(self,'_v_certificate_list',None) is None:
172            self._v_certificate_list = []
173        if getattr(self,'_v_department_certificates',None) is None:
174            res = self.portal_catalog(portal_type = "Department")
175            self._v_department_certificates = {}
176            for d in res:
177                self._v_department_certificates[d.getId] = getattr(d.getObject(),"certificates",None)
178        did = mapping['department_code']
179        msg = ''
180        while True:
181            d = self._v_department_certificates.get(did,None)
182            if d is None:
183                msg =  "No Department with ID: %s" % did
184                break
185            certificate_id = mapping.get('code')
186            if certificate_id in self._v_certificate_list:
187                msg =  "Duplicate Certificate ID: %s" % did
188                break
189            c = getattr(d,certificate_id,None)
190            if c is not None:
191                msg =  "Duplicate Certificate ID: %s" % did
192                break
193            try:
194                d.invokeFactory('Certificate', certificate_id)
195            except BadRequest,E:
196                msg =  "%s" % E
197                break
198            self._v_certificate_list.append(certificate_id)
199            c = getattr(d,certificate_id)
200            c.getContent().edit(mapping=mapping)
201            break
202        return certificate_id,msg,mapping
203    ###)
204
205    def edit(self,mapping):###(
206        certificate_id = mapping.get('code')
207        res = self.portal_catalog(id=certificate_id)
208        msg = ''
209        while True:
210            if not res:
211                msg =  "No Certificate with ID: %s" % certificate_id
212                break
213            c = res[0].getObject()
214            c.getContent().edit(mapping=mapping)
215            break
216        return certificate_id,msg,mapping
217    ###)
218###)
219
220class CourseImport(WAeUPImport):###(
221    name = "course"
222    plural_name = "%ss" % name
223    commit_after = 1000
224
225    def create(self,mapping):###(
226        if getattr(self,'_v_course_list',None) is None:
227            self._v_course_list = []
228        if getattr(self,'_v_departments',None) is None:
229            res = self.portal_catalog(portal_type = "Department")
230            self._v_department_courses = {}
231            for d in res:
232                self._v_department_courses[d.getId] = getattr(d.getObject(),"courses",None)
233        did = mapping['department_code']
234        msg = ''
235        while True:
236            d = self._v_department_courses.get(did,None)
237            if d is None:
238                msg =  "No Department with ID: %s" % did
239                break
240            course_id = mapping.get('code')
241            if course_id in self._v_course_list:
242                msg =  "Duplicate Course ID: %s" % did
243                break
244            c = getattr(d,course_id,None)
245            if c is not None:
246                msg =  "Duplicate Course ID: %s" % did
247                break
248            try:
249                d.invokeFactory('Course', course_id)
250            except BadRequest,E:
251                msg =  "%s" % E
252                break
253            self._v_course_list.append(course_id)
254            c = getattr(d,course_id)
255            c.getContent().edit(mapping=mapping)
256            break
257        return course_id,msg,mapping
258    ###)
259
260    def edit(self,mapping): ###(
261        course_id = mapping.get('code')
262        res = self.portal_catalog(id=course_id)
263        while True:
264            if not res:
265                msg =  "No Course with ID: %s" % course_id
266                break
267            c = res[0].getObject()
268            c.getContent().edit(mapping=mapping)
269            break
270        return course_id,msg,mapping
271    ###)
272###)
273
274class CourseResultImport(WAeUPImport):###(
275    """ CourseresultImport """
276    name = "course_result"
277    plural_name = "%ss" % name
278    commit_after = 1000000
279
280    def getStudentRecord(self,mapping):
281        for id_key in ('student_id','matric_no'):
282            id_field = mapping.get(id_key,'')
283            if id_field:
284                search_key = id_key
285                search_field = id_field
286                break
287        if search_key == "student_id":
288            search_key = 'id'
289        query = Eq(search_key,search_field)
290        res = self.students_catalog.evalAdvancedQuery(query)
291        student_record = None
292        msg = ''
293        if res:
294            student_record = res[0]
295            if search_key == "matric_no":
296                mapping['student_id'] = student_record.id
297            elif search_key == "student_id":
298                mapping['matric_no'] = student_record.matric_no
299        else:
300            msg = "No student with %(search_key)s %(search_field)s" % vars()
301        return student_record,msg
302           
303    def create(self,mapping):###(
304        students_folder = self.portal_url.getPortalObject().campus.students
305        if getattr(self,'_v_courses',None) is None:
306            res = self.courses_catalog()
307            self._v_courses = {}
308            for brain in res:
309                self._v_courses[brain.code] = brain
310        if getattr(self,'_v_level_created',None) is None:
311            self._v_level_created = []
312        msg = ''
313        key = ''
314        while True:
315            course_id = mapping.get('code')
316            if course_id not in self._v_courses.keys():
317                msg = "No course with ID: %s" % course_id
318                break
319            student_record,msg = self.getStudentRecord(mapping)
320            if msg:
321                break
322            student_id = student_record.id
323            level_id = mapping['level_id']
324            code = mapping['code']
325            if student_id not in self._v_level_created:
326                try:
327                    context = getattr(getattr(students_folder,
328                                            "%(student_id)s" % vars()),
329                                    'study_course')
330                except:
331                    msg = "could not create level %(level_id)s for %(student_id)s" % vars()
332                    break
333                if level_id not in context.objectIds():
334                    context.invokeFactory('StudentStudyLevel',"%(level_id)s" % vars())
335                    level = getattr(context,"%(level_id)s" % vars())
336                    self.portal_workflow.doActionFor(level,'open')
337                    # the session string must not be copied into the level object
338                    current_verdict = getattr(student_record,'current_verdict','')
339                    current_session = getattr(student_record,'current_session','')
340                    if current_verdict and student_record.current_level == level_id:
341                        level.getContent().edit(mapping={'verdict': "%s" %
342                                                        current_verdict,
343                                                        'session': "%s" %
344                                                        current_session,
345                                                        })
346                        self.portal_workflow.doActionFor(level,'close')
347                self._v_level_created += student_id,
348            mapping['key'] = key = "%(student_id)s|%(level_id)s|%(code)s" % vars()
349            for k in ('semester','credits',):
350                mapping[k] = getattr(self._v_courses[course_id],k)
351            try:
352                self.course_results.addRecord(**mapping)
353            except ValueError:
354                msg = "course result already exists: %s" % key
355            break
356        return key,msg,mapping
357    ###)
358
359    def edit(self,mapping): ###(
360        #import pdb;pdb.set_trace()
361        msg = ''
362        key = ''
363        while True:
364            student_record,msg = self.getStudentRecord(mapping)
365            if msg:
366                break
367            student_id = student_record.id
368            level_id = mapping['level_id']
369            code = mapping['code']
370            mapping['key'] = key = "%(student_id)s|%(level_id)s|%(code)s" % vars()
371            break
372        try:
373            self.course_results.modifyRecord(**mapping)
374        except KeyError:
375            msg = "No course result to edit: %s" % key
376        return key,msg,mapping
377    ###)
378
379    def delete(self,mapping):###(
380        id_key = ''
381        msg = ''
382        while True:
383            student_record,msg = self.getStudentRecord(mapping)
384            if msg:
385                break
386            student_id = student_record.id
387            level_id = mapping['level_id']
388            code = mapping['code']
389            key = "%(student_id)s|%(level_id)s|%(code)s" % vars()
390            if self.course_results.getRecordByKey(key) is None:
391                msg =  "no course-result with %(key)s" % vars()
392                break
393            self.course_results.deleteRecord(key)
394            break
395        return key,msg,mapping
396    ###)
397
398###)
399
400class CertificateCourseImport(WAeUPImport):###(
401    name = "certificate_course"
402    plural_name = "%ss" % name
403    commit_after = 100000
404
405    def create(self,mapping):
406        if getattr(self,'_v_courses',None) is None:
407            res = self.courses_catalog()
408            self._v_courses= [course.code for course in res]
409        if getattr(self,'_v_ceritficates',None) is None:
410            res = self.portal_catalog(portal_type = "Certificate")
411            self._v_certificates = {}
412            for cert in res:
413                self._v_certificates[cert.getId] = cert.getObject()
414        msg = ''
415        while True:
416            certificate_course_id = mapping.get('code')
417            if certificate_course_id not in self._v_courses:
418                msg =  "No Course with ID: %s" % certificate_course_id
419                break
420            cert_id = mapping['certificate_code']
421            cert = self._v_certificates.get(cert_id,None)
422            if cert is None:
423                msg =  "No Certificate with ID: %s" % cert_id
424                break
425            level_id = mapping.get('level')
426            level = getattr(cert,level_id,None)
427            if level is None:
428                cert.invokeFactory('StudyLevel', level_id)
429                level = getattr(cert,level_id,None)
430            elif hasattr(level,certificate_course_id):
431                msg =  "Duplicate CertificateCourse ID: %(certificate_course_id)s " % vars()
432                msg += "in %(cert_id)s/ %(level_id)s" % vars()
433                break
434            level.invokeFactory('CertificateCourse', certificate_course_id)
435            c = getattr(level,certificate_course_id)
436            c.getContent().edit(mapping=mapping)
437            break
438        return certificate_course_id,msg,mapping
439    ###)
440
441class DepartmentImport(WAeUPImport):###(
442    name = "department"
443    plural_name = "%ss" % name
444    commit_after = 100000
445   
446
447    def create(self,mapping):###(
448        "create a department in the correct faculty"
449        fid = mapping['faculty_code']
450        msg = ''
451        if getattr(self,'_v_faculties',None) is None:
452            res = self.portal_catalog(portal_type = "Faculty")
453            self._v_faculties = {}
454            for f in res:
455                self._v_faculties[f.getId] = f.getObject()
456        while True:
457            f = self._v_faculties.get(fid,None)
458            if f is None:
459                msg =  "No Faculty with ID: %s" % fid
460                break
461            else:
462                did = mapping.get('code')
463                d = getattr(f,did,None)
464                if d is None or d.portal_type == "Faculty":
465                    #logger.info('Creating Department %(code)s, %(title)s' % mapping)
466                    try:
467                        f.invokeFactory('Department', did)
468                    except BadRequest,E:
469                        msg =  "%s" % E
470                        break
471                    d = getattr(f,did)
472                    d.invokeFactory('CoursesFolder','courses')
473                    courses = getattr(d,'courses')
474                    dict = {'Title': 'Courses'}
475                    courses.getContent().edit(mapping=dict)
476                    d.invokeFactory('CertificatesFolder','certificates')
477                    certificates = getattr(d,'certificates')
478                    dict = {'Title': 'Certificates'}
479                    certificates.getContent().edit(mapping=dict)
480                    d.getContent().edit(mapping=mapping)
481            break
482        return did,msg,mapping
483    ###)
484
485    def edit(self,mapping): ###(
486        "create a department in the correct faculty"
487        academics_folder = self.portal_url.getPortalObject().campus.academics
488        fid = mapping['faculty_code']
489        did = mapping.get('code')
490        msg = ''
491        while True:
492            try:
493                d = getattr(getattr(academics_folder,fid),did,None)
494            except KeyError:
495                msg =  "Department %s or Faculty %s wrong" % (did,fid)
496                break
497            else:
498                if d is None or d.portal_type == "Faculty":
499                    #logger.info('Editing Department %(code)s, %(title)s' % mapping)
500                    d.getContent().edit(mapping=mapping)
501            break
502        return did,msg,mapping
503    ###)
504###)
505
506class FacultyImport(WAeUPImport):###(
507    name = "faculty"
508    plural_name = "faculties"
509    commit_after = 100
510
511    def create(self,mapping): ###(
512        "create a faculty"
513        academics_folder = self.portal_url.getPortalObject().campus.academics
514        fid = mapping['code']
515        msg = ''
516        while True:
517            if getattr(academics_folder,fid,None) is not None:
518                msg =  "Faculty with ID: %s exists" % fid
519                break
520            logger.info('Creating Faculty %(code)s, %(title)s' % mapping)
521            try:
522                academics_folder.invokeFactory('Faculty', fid)
523            except BadRequest,E:
524                msg =  "%s" % E
525                break
526            f = getattr(academics_folder,fid,None)
527            f.getContent().edit(mapping=mapping)
528            break
529        return fid,msg,mapping
530        ###)
531
532    def edit(self,mapping): ###(
533        "edit a faculty"
534        academics_folder = self.portal_url.getPortalObject().campus.academics
535        fid = mapping['code']
536        msg = ''
537        while True:
538            f = getattr(academics_folder,fid,None)
539            if f is None:
540                msg =  "Faculty with ID: %s does not exist" % fid
541            f.getContent().edit(mapping=mapping)
542            break
543        return fid,msg,mapping
544    ###)
545###)
546
547class StudentImport(WAeUPImport):###(
548    name = "student"
549    plural_name = "%ss" % name
550    commit_after = 100
551   
552    field2types_student = {   ###(
553                      'StudentApplication':
554                          {'id': 'application',
555                           'title': 'Application Data',
556                           'wf_transition_return': 'close',
557                           'wf_transition_admit': 'remain',
558                           'fields':
559                             ('jamb_reg_no',
560                              'entry_mode',
561                              'entry_session',
562                              'jamb_score',
563                              'app_email',
564                              'jamb_age',
565                              'jamb_state',
566                              'jamb_lga',
567                              'jamb_sex',
568                              )
569                              },
570                      #'StudentPume':
571                      #    {'id': 'pume',
572                      #     'title': 'Pume Data',
573                      #     'wf_transition_return': 'close',
574                      #     'wf_transition_admit': 'close',
575                      #     'fields':
576                      #       ('pume_score',
577                      #        )
578                      #        },
579                      'StudentClearance':
580                          {'id': 'clearance',
581                           'title': 'Clearance/Eligibility Record',
582                           'wf_transition_return': 'close',
583                           'wf_transition_admit': 'remain',
584                           'fields':
585                             ('matric_no',
586                              'nationality',
587                              'lga',
588                              'birthday',
589                              )
590                              },
591                         'StudentPersonal':
592                          {'id': 'personal',
593                           'title': 'Personal Data',
594                           'wf_transition_return': 'open',
595                           'wf_transition_admit': 'remain',
596                           'fields':
597                             ('firstname',
598                              'middlename',
599                              'lastname',
600                              'sex',
601                              'email',
602                              'phone',
603                              'perm_address',
604                              )
605                              },
606                         'StudentStudyCourse':
607                          {'id': 'study_course',
608                           'title': 'Study Course',
609                           'wf_transition_return': 'open',
610                           'wf_transition_admit': 'remain',
611                           'fields':
612                             ('study_course',
613                              'current_level',
614                              'current_session',
615                              'current_mode',
616                              'current_verdict',
617                              'previous_verdict',
618                              )
619                              },
620                         # 'StudentStudyLevel':
621                         #  {'id': 'current_level',
622                         #   'title': '',
623                         #   'wf_transition_return': 'open',
624                         #   'wf_transition_admit': 'remain',
625                         #   'fields':
626                         #     ('verdict',
627                         #      'session',
628                         #      )
629                         #      },
630                         'PaymentsFolder':
631                          {'id': 'payments',
632                           'title': 'Payments',
633                           'wf_transition_return': 'open',
634                           'wf_transition_admit': 'open',
635                           'fields':
636                             ()
637                              },
638                         }
639    ###)
640
641    def create(self,mapping): ###(
642        "create student records due import"
643        logger = logging.getLogger('WAeUPTool.mass_create_student')
644        students_folder = self.portal_url.getPortalObject().campus.students
645        jamb_reg_no = mapping.get('jamb_reg_no',None)
646        msg = ''
647        while True:
648            if jamb_reg_no:
649                res = self.students_catalog(jamb_reg_no = jamb_reg_no)
650                if res:
651                    msg = "jamb_reg_no exists"
652                    break
653            matric_no = mapping.get('matric_no',None)
654            if matric_no:
655                res = self.students_catalog(matric_no = matric_no)
656                if res:
657                    msg = "matric_no exists"
658                    break
659            student_id = self.waeup_tool.generateStudentId('?')
660            students_folder.invokeFactory('Student', student_id)
661            student_obj = getattr(students_folder,student_id)
662            f2t = self.field2types_student
663            d = {}
664            transition = mapping.get('reg_transition','admit')
665            if transition not in ('admit','return'):
666                msg = "no valid transition provided"
667                break
668            for pt in f2t.keys():
669                student_obj.invokeFactory(pt,f2t[pt]['id'])
670                sub_obj = getattr(student_obj,f2t[pt]['id'])
671                sub_doc = sub_obj.getContent()
672                d['Title'] = f2t[pt]['title']
673                for field in f2t[pt]['fields']:
674                    d[field] = mapping.get(field,'')
675   
676                if pt == "StudentApplication":
677                    #d['jamb_sex']  = 'M'
678                    #if mapping.get('sex'):
679                    #    d['jamb_sex']  = 'F'
680                    d['jamb_firstname'] = mapping.get('firstname',None)
681                    d['jamb_middlename'] = mapping.get('middlename',None)
682                    d['jamb_lastname'] = mapping.get('lastname',None)
683   
684                # if pt == "StudyCourse":
685                #     for von,zu in (('entry_mode','current_mode'),
686                #                    ('entry_session','current_session')):
687                #         if mapping.get(zu,None) is None and mapping.get(von,None) is not None:
688                #             d[zu] = mapping[von]
689                sub_doc.edit(mapping = d)
690   
691                #import pdb;pdb.set_trace()
692                new_state = f2t[pt]['wf_transition_%(transition)s' % vars()]
693                if new_state != "remain":
694                    self.portal_workflow.doActionFor(sub_obj,new_state,dest_container=sub_obj)
695            self.portal_workflow.doActionFor(student_obj,transition)
696            student_obj.manage_setLocalRoles(student_id, ['Owner',])
697            break
698        return student_id,msg,mapping
699    ###)
700
701    def edit(self,mapping):
702        wftool = self.portal_workflow
703        "edit student records due import"
704        logger = logging.getLogger('WAeUPTool.mass_edit_student')
705        students_folder = self.portal_url.getPortalObject().campus.students
706        student_id = mapping.get('id',None)
707        jamb_reg_no = mapping.get('jamb_reg_no',None)
708        matric_no = mapping.get('matric_no',None)
709        editable_keys = mapping.keys()
710        msg = ''
711        while True:
712            if student_id:
713                res = self.students_catalog(id = student_id)
714                if not res:
715                    msg = "no student with id %s" % student_id
716                    break
717                student_record = res[0]
718                if matric_no and student_record.matric_no:
719                    if  matric_no != student_record.matric_no:
720                        msg = "old matric_no %s overwritten with %s" % (student_record.matric_no,matric_no)
721                        #logger.info("%s, old matric_no %s overwritten with %s" % (student_record.id,student_record.matric_no,matric_no))
722                if jamb_reg_no and student_record.jamb_reg_no:
723                    if jamb_reg_no != student_record.jamb_reg_no:
724                        msg = "old reg_no %s overwritten with %s" % (student_record.jamb_reg_no,jamb_reg_no)
725                        #logger.info("%s, old reg_no %s overwritten with %s" % (student_record.id,student_record.jamb_reg_no,jamb_reg_no))
726            elif jamb_reg_no:
727                res = self.students_catalog(jamb_reg_no = jamb_reg_no)
728                if not res:
729                    msg = "no student with jamb_reg_no %s" % jamb_reg_no
730                    break
731                student_record = res[0]
732                editable_keys.remove('jamb_reg_no')
733            elif matric_no:
734                res = self.students_catalog(matric_no = matric_no)
735                if not res:
736                    msg = "no student with matric_no %s" % matric_no
737                    break
738                student_record = res[0]
739                editable_keys.remove('matric_no')
740            ## included only to change wf state from admitted to returning
741            #if student_record.review_state not in ('admitted','objection_raised'):
742            #    return '%s' % student_record.id ,"student is not in state admitted or objection_raised"
743            ## end inclusion
744            student_id = student_record.id
745            student_obj = getattr(students_folder,student_id)
746            f2t = self.field2types_student
747            d = {}
748            any_change = False
749            #special treatment for StudentStudyLevel
750            d['verdict']  = mapping.get('current_verdict','')
751            d['session']  = mapping.get('current_session','')
752            current_level = mapping.get('current_level','')
753            while d['session'] and d['verdict'] and current_level:
754                sub_obj = getattr(student_obj,'study_course',None)
755                if sub_obj is None:
756                    break
757                level_obj = getattr(sub_obj,current_level,None)
758                if  level_obj is None:
759                    break
760                any_change = True
761                level_obj.getContent().edit(mapping = d)
762                try:
763                    wftool.doActionFor(level_obj,'close')
764                except:
765                    pass
766                break
767            for pt in f2t.keys():
768                #if pt == "StudentApplication":
769                #    d['jamb_sex']  = 'M'
770                #    if mapping.get('sex'):
771                #        d['jamb_sex']  = 'F'
772                intersect = set(f2t[pt]['fields']).intersection(set(editable_keys))
773                if intersect and pt not in ('StudentStudyLevel',):
774                    object_id = f2t[pt]['id']
775                    sub_obj = getattr(student_obj,object_id,None)
776                    if sub_obj is None:
777                        try:
778                            student_obj.invokeFactory(pt,object_id)
779                        except:
780                            continue
781                        sub_obj = getattr(student_obj,object_id)
782                        if f2t[pt]['title'] != '':
783                            d['Title'] = f2t[pt]['title']
784                    sub_doc = sub_obj.getContent()
785                    for field in intersect:
786                        changed = False
787                        if getattr(sub_doc,field,None) != mapping.get(field,''):
788                            any_change = True
789                            changed = True
790                            d[field] = mapping.get(field,'')
791                        if changed:
792                            sub_doc.edit(mapping = d)
793            ## included only to change wf state from admitted to returning
794            #    if student_record.review_state in ('admitted','objection_raised'):
795            #        new_state = f2t[pt]['wf_transition_return']
796            #        sub_obj = getattr(student_obj,f2t[pt]['id'],None)
797            #        if sub_obj and new_state != "remain":
798            #            try:
799            #                self.portal_workflow.doActionFor(sub_obj,new_state,dest_container=sub_obj)
800            #            except:
801            #                #logger.info('%s, wf transition %s of %s failed' % (student_id,new_state,sub_obj.id))
802            #                pass
803            #if student_record.review_state in ('admitted','objection_raised'):
804            #    wfaction = 'return'
805            #    try:
806            #        self.portal_workflow.doActionFor(student_obj,wfaction)
807            #        logger.info('%s, wf state changed' % student_id)
808            #        any_change = True
809            #    except:
810            #        logger.info('%s, wf transition failed, old state = %s' % (student_id,student_record.review_state))
811            #        pass
812            ## end inclusion
813            break
814        # if not any_change:
815        #     msg = 'not modified'
816        return student_id,msg,mapping
817    ###)
818
819class VerdictImport(WAeUPImport):###(
820    """ VerdictImport """
821    name = "verdict"
822    plural_name = "%ss" % name
823    commit_after = 100000
824    required_modes = ('create','edit')
825   
826    def edit(self,mapping):
827        "edit student verdicts"
828        wftool = self.portal_workflow
829        logger = logging.getLogger('WAeUPTool.mass_edit_verdict')
830        students_folder = self.portal_url.getPortalObject().campus.students
831        student_id = mapping.get('id',None)
832        matric_no = mapping.get('matric_no',None)
833        editable_keys = mapping.keys()
834        while True:
835            key = ''
836            msg = ''
837            if student_id:
838                student_record = self.students_catalog.getRecordByKey(student_id)
839                if student_record is None:
840                    #return '',"no student with id %s" % student_id
841                    msg = "no student with id %s" % student_id
842                    break
843                if matric_no and student_record.matric_no and matric_no != student_record.matric_no:
844                    msg = 'student %s: matric_no %s does not match %s' % (student_record.id,
845                                                                          student_record.matric_no,
846                                                                          matric_no)
847                    break
848                mapping['matric_no'] = student_record.matric_no
849            elif matric_no:
850                res = self.students_catalog(matric_no = matric_no)
851                if not res:
852                    msg = "no student with matric_no %s" % matric_no
853                    break
854                student_record = res[0]
855                editable_keys.remove('matric_no')
856            else:
857                msg = "no id or matric_no specified"
858                break
859            student_id = student_record.id
860            mapping['id'] = student_id
861            d = {}
862            #import pdb;pdb.set_trace()
863            any_change = False
864            #special treatment for StudentStudyLevel
865            current_session = d['session'] = mapping.get('current_session','')
866            if current_session and student_record.session != current_session:
867                msg = 'student %s: imported session %s does not match current_session %s' % (student_id,
868                                                                                            current_session,
869                                                                                            student_record.session)
870                break
871            current_level = mapping.get('current_level','')
872            if not current_level.isdigit():
873                msg = 'student %s: imported level is empty' % (student_id,)
874                break
875            if current_level and student_record.level != current_level:
876                msg = 'student %s: imported level %s does not match current_level %s' % (student_id,
877                                                                                        current_level,
878                                                                                        student_record.level)
879                break
880            student_review_state =  student_record.review_state
881            if student_review_state == 'deactivated':
882                msg = "student %s in review_state %s" % (student_id, student_review_state)
883                break
884            if student_review_state not in ('courses_validated','returning'):
885                msg = "student %s in wrong review_state %s" % (student_id, student_review_state)
886                break
887            student_obj = getattr(students_folder,student_id)
888            # f2t = self.field2types_student
889            study_course_obj = getattr(student_obj,'study_course',None)
890            if study_course_obj is None:
891                msg = 'student %s: no study_course object' % student_id
892                break
893            level_obj = getattr(study_course_obj,current_level,None)
894            if  level_obj is None:
895                msg = 'student %s: no study_level object for level %s' % (student_id,
896                                                                                current_level)
897                break
898            verdict = d['verdict'] = d['current_verdict']  = mapping.get('current_verdict','')
899   
900            #if verdict == student_record.verdict:
901            #    msg = 'student %s: verdict already set to %s' % (student_id,
902            #                                                            verdict)
903   
904            level_review_state = wftool.getInfoFor(level_obj,'review_state',None)
905            if level_review_state != "closed":
906                wftool.doActionFor(level_obj,'close')
907                # msg = 'student %s: level %s is not closed' % (student_id,
908                #                                                      current_level)
909   
910            study_course_obj.getContent().edit(mapping = d)
911            level_obj.getContent().edit(mapping = d)
912            if student_review_state != "returning":
913                wftool.doActionFor(student_obj,'return')
914            # try:
915            #     wftool.doActionFor(level_obj,'close')
916            # except:
917            #     pass
918            break
919        return student_id,msg,mapping
920    ###)
921
Note: See TracBrowser for help on using the repository browser.