source: WAeUP_SRP/base/WAeUPImport.py @ 3173

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

import completely reworked.

  • 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 3172 2008-02-18 08:51:45Z 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 = "%ss" % name
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            return fid,msg,mapping
529        ###)
530
531    def edit(self,mapping): ###(
532        "edit a faculty"
533        academics_folder = self.portal_url.getPortalObject().campus.academics
534        fid = mapping['code']
535        msg = ''
536        while True:
537            f = getattr(academics_folder,fid,None)
538            if f is None:
539                msg =  "Faculty with ID: %s does not exist" % fid
540                break
541            f.getContent().edit(mapping=mapping)
542        return fid,msg,mapping
543    ###)
544###)
545
546class StudentImport(WAeUPImport):###(
547    name = "student"
548    plural_name = "%ss" % name
549    commit_after = 100
550   
551    field2types_student = {   ###(
552                      'StudentApplication':
553                          {'id': 'application',
554                           'title': 'Application Data',
555                           'wf_transition_return': 'close',
556                           'wf_transition_admit': 'remain',
557                           'fields':
558                             ('jamb_reg_no',
559                              'entry_mode',
560                              'entry_session',
561                              'jamb_score',
562                              'app_email',
563                              'jamb_age',
564                              'jamb_state',
565                              'jamb_lga',
566                              'jamb_sex',
567                              )
568                              },
569                      #'StudentPume':
570                      #    {'id': 'pume',
571                      #     'title': 'Pume Data',
572                      #     'wf_transition_return': 'close',
573                      #     'wf_transition_admit': 'close',
574                      #     'fields':
575                      #       ('pume_score',
576                      #        )
577                      #        },
578                      'StudentClearance':
579                          {'id': 'clearance',
580                           'title': 'Clearance/Eligibility Record',
581                           'wf_transition_return': 'close',
582                           'wf_transition_admit': 'remain',
583                           'fields':
584                             ('matric_no',
585                              'nationality',
586                              'lga',
587                              'birthday',
588                              )
589                              },
590                         'StudentPersonal':
591                          {'id': 'personal',
592                           'title': 'Personal Data',
593                           'wf_transition_return': 'open',
594                           'wf_transition_admit': 'remain',
595                           'fields':
596                             ('firstname',
597                              'middlename',
598                              'lastname',
599                              'sex',
600                              'email',
601                              'phone',
602                              'perm_address',
603                              )
604                              },
605                         'StudentStudyCourse':
606                          {'id': 'study_course',
607                           'title': 'Study Course',
608                           'wf_transition_return': 'open',
609                           'wf_transition_admit': 'remain',
610                           'fields':
611                             ('study_course',
612                              'current_level',
613                              'current_session',
614                              'current_mode',
615                              'current_verdict',
616                              'previous_verdict',
617                              )
618                              },
619                         # 'StudentStudyLevel':
620                         #  {'id': 'current_level',
621                         #   'title': '',
622                         #   'wf_transition_return': 'open',
623                         #   'wf_transition_admit': 'remain',
624                         #   'fields':
625                         #     ('verdict',
626                         #      'session',
627                         #      )
628                         #      },
629                         'PaymentsFolder':
630                          {'id': 'payments',
631                           'title': 'Payments',
632                           'wf_transition_return': 'open',
633                           'wf_transition_admit': 'open',
634                           'fields':
635                             ()
636                              },
637                         }
638    ###)
639
640    def create(self,mapping): ###(
641        "create student records due import"
642        logger = logging.getLogger('WAeUPTool.mass_create_student')
643        students_folder = self.portal_url.getPortalObject().campus.students
644        jamb_reg_no = mapping.get('jamb_reg_no',None)
645        msg = ''
646        while True:
647            if jamb_reg_no:
648                res = self.students_catalog(jamb_reg_no = jamb_reg_no)
649                if res:
650                    msg = "jamb_reg_no exists"
651                    break
652            matric_no = mapping.get('matric_no',None)
653            if matric_no:
654                res = self.students_catalog(matric_no = matric_no)
655                if res:
656                    msg = "matric_no exists"
657                    break
658            student_id = self.waeup_tool.generateStudentId('?')
659            students_folder.invokeFactory('Student', student_id)
660            student_obj = getattr(students_folder,student_id)
661            f2t = self.field2types_student
662            d = {}
663            transition = mapping.get('reg_transition','admit')
664            if transition not in ('admit','return'):
665                msg = "no valid transition provided"
666                break
667            for pt in f2t.keys():
668                student_obj.invokeFactory(pt,f2t[pt]['id'])
669                sub_obj = getattr(student_obj,f2t[pt]['id'])
670                sub_doc = sub_obj.getContent()
671                d['Title'] = f2t[pt]['title']
672                for field in f2t[pt]['fields']:
673                    d[field] = mapping.get(field,'')
674   
675                if pt == "StudentApplication":
676                    #d['jamb_sex']  = 'M'
677                    #if mapping.get('sex'):
678                    #    d['jamb_sex']  = 'F'
679                    d['jamb_firstname'] = mapping.get('firstname',None)
680                    d['jamb_middlename'] = mapping.get('middlename',None)
681                    d['jamb_lastname'] = mapping.get('lastname',None)
682   
683                # if pt == "StudyCourse":
684                #     for von,zu in (('entry_mode','current_mode'),
685                #                    ('entry_session','current_session')):
686                #         if mapping.get(zu,None) is None and mapping.get(von,None) is not None:
687                #             d[zu] = mapping[von]
688                sub_doc.edit(mapping = d)
689   
690                #import pdb;pdb.set_trace()
691                new_state = f2t[pt]['wf_transition_%(transition)s' % vars()]
692                if new_state != "remain":
693                    self.portal_workflow.doActionFor(sub_obj,new_state,dest_container=sub_obj)
694            self.portal_workflow.doActionFor(student_obj,transition)
695            student_obj.manage_setLocalRoles(student_id, ['Owner',])
696            break
697        return student_id,msg,mapping
698    ###)
699
700    def edit(self,mapping):
701        wftool = self.portal_workflow
702        "edit student records due import"
703        logger = logging.getLogger('WAeUPTool.mass_edit_student')
704        students_folder = self.portal_url.getPortalObject().campus.students
705        student_id = mapping.get('id',None)
706        jamb_reg_no = mapping.get('jamb_reg_no',None)
707        matric_no = mapping.get('matric_no',None)
708        editable_keys = mapping.keys()
709        msg = ''
710        while True:
711            if student_id:
712                res = self.students_catalog(id = student_id)
713                if not res:
714                    msg = "no student with id %s" % student_id
715                    break
716                student_record = res[0]
717                if matric_no and student_record.matric_no:
718                    if  matric_no != student_record.matric_no:
719                        msg = "old matric_no %s overwritten with %s" % (student_record.matric_no,matric_no)
720                        #logger.info("%s, old matric_no %s overwritten with %s" % (student_record.id,student_record.matric_no,matric_no))
721                if jamb_reg_no and student_record.jamb_reg_no:
722                    if jamb_reg_no != student_record.jamb_reg_no:
723                        msg = "old reg_no %s overwritten with %s" % (student_record.jamb_reg_no,jamb_reg_no)
724                        #logger.info("%s, old reg_no %s overwritten with %s" % (student_record.id,student_record.jamb_reg_no,jamb_reg_no))
725            elif jamb_reg_no:
726                res = self.students_catalog(jamb_reg_no = jamb_reg_no)
727                if not res:
728                    msg = "no student with jamb_reg_no %s" % jamb_reg_no
729                    break
730                student_record = res[0]
731                editable_keys.remove('jamb_reg_no')
732            elif matric_no:
733                res = self.students_catalog(matric_no = matric_no)
734                if not res:
735                    msg = "no student with matric_no %s" % matric_no
736                    break
737                student_record = res[0]
738                editable_keys.remove('matric_no')
739            ## included only to change wf state from admitted to returning
740            #if student_record.review_state not in ('admitted','objection_raised'):
741            #    return '%s' % student_record.id ,"student is not in state admitted or objection_raised"
742            ## end inclusion
743            student_id = student_record.id
744            student_obj = getattr(students_folder,student_id)
745            f2t = self.field2types_student
746            d = {}
747            any_change = False
748            #special treatment for StudentStudyLevel
749            d['verdict']  = mapping.get('current_verdict','')
750            d['session']  = mapping.get('current_session','')
751            current_level = mapping.get('current_level','')
752            while d['session'] and d['verdict'] and current_level:
753                sub_obj = getattr(student_obj,'study_course',None)
754                if sub_obj is None:
755                    break
756                level_obj = getattr(sub_obj,current_level,None)
757                if  level_obj is None:
758                    break
759                any_change = True
760                level_obj.getContent().edit(mapping = d)
761                try:
762                    wftool.doActionFor(level_obj,'close')
763                except:
764                    pass
765                break
766            for pt in f2t.keys():
767                #if pt == "StudentApplication":
768                #    d['jamb_sex']  = 'M'
769                #    if mapping.get('sex'):
770                #        d['jamb_sex']  = 'F'
771                intersect = set(f2t[pt]['fields']).intersection(set(editable_keys))
772                if intersect and pt not in ('StudentStudyLevel',):
773                    object_id = f2t[pt]['id']
774                    sub_obj = getattr(student_obj,object_id,None)
775                    if sub_obj is None:
776                        try:
777                            student_obj.invokeFactory(pt,object_id)
778                        except:
779                            continue
780                        sub_obj = getattr(student_obj,object_id)
781                        if f2t[pt]['title'] != '':
782                            d['Title'] = f2t[pt]['title']
783                    sub_doc = sub_obj.getContent()
784                    for field in intersect:
785                        changed = False
786                        if getattr(sub_doc,field,None) != mapping.get(field,''):
787                            any_change = True
788                            changed = True
789                            d[field] = mapping.get(field,'')
790                        if changed:
791                            sub_doc.edit(mapping = d)
792            ## included only to change wf state from admitted to returning
793            #    if student_record.review_state in ('admitted','objection_raised'):
794            #        new_state = f2t[pt]['wf_transition_return']
795            #        sub_obj = getattr(student_obj,f2t[pt]['id'],None)
796            #        if sub_obj and new_state != "remain":
797            #            try:
798            #                self.portal_workflow.doActionFor(sub_obj,new_state,dest_container=sub_obj)
799            #            except:
800            #                #logger.info('%s, wf transition %s of %s failed' % (student_id,new_state,sub_obj.id))
801            #                pass
802            #if student_record.review_state in ('admitted','objection_raised'):
803            #    wfaction = 'return'
804            #    try:
805            #        self.portal_workflow.doActionFor(student_obj,wfaction)
806            #        logger.info('%s, wf state changed' % student_id)
807            #        any_change = True
808            #    except:
809            #        logger.info('%s, wf transition failed, old state = %s' % (student_id,student_record.review_state))
810            #        pass
811            ## end inclusion
812            break
813        # if not any_change:
814        #     msg = 'not modified'
815        return student_id,msg,mapping
816    ###)
817
818class VerdictImport(WAeUPImport):###(
819    """ VerdictImport """
820    name = "verdict"
821    plural_name = "%ss" % name
822    commit_after = 100000
823    required_modes = ('create','edit')
824   
825    def edit(self,mapping):
826        "edit student verdicts"
827        wftool = self.portal_workflow
828        logger = logging.getLogger('WAeUPTool.mass_edit_verdict')
829        students_folder = self.portal_url.getPortalObject().campus.students
830        student_id = mapping.get('id',None)
831        matric_no = mapping.get('matric_no',None)
832        editable_keys = mapping.keys()
833        while True:
834            key = ''
835            msg = ''
836            if student_id:
837                student_record = self.students_catalog.getRecordByKey(student_id)
838                if student_record is None:
839                    #return '',"no student with id %s" % student_id
840                    msg = "no student with id %s" % student_id
841                    break
842                if matric_no and student_record.matric_no and matric_no != student_record.matric_no:
843                    msg = 'student %s: matric_no %s does not match %s' % (student_record.id,
844                                                                          student_record.matric_no,
845                                                                          matric_no)
846                    break
847                mapping['matric_no'] = student_record.matric_no
848            elif matric_no:
849                res = self.students_catalog(matric_no = matric_no)
850                if not res:
851                    msg = "no student with matric_no %s" % matric_no
852                    break
853                student_record = res[0]
854                editable_keys.remove('matric_no')
855            else:
856                msg = "no id or matric_no specified"
857                break
858            student_id = student_record.id
859            mapping['id'] = student_id
860            d = {}
861            #import pdb;pdb.set_trace()
862            any_change = False
863            #special treatment for StudentStudyLevel
864            current_session = d['session'] = mapping.get('current_session','')
865            if current_session and student_record.session != current_session:
866                msg = 'student %s: imported session %s does not match current_session %s' % (student_id,
867                                                                                            current_session,
868                                                                                            student_record.session)
869                break
870            current_level = mapping.get('current_level','')
871            if not current_level.isdigit():
872                msg = 'student %s: imported level is empty' % (student_id,)
873                break
874            if current_level and student_record.level != current_level:
875                msg = 'student %s: imported level %s does not match current_level %s' % (student_id,
876                                                                                        current_level,
877                                                                                        student_record.level)
878                break
879            student_review_state =  student_record.review_state
880            if student_review_state == 'deactivated':
881                msg = "student %s in review_state %s" % (student_id, student_review_state)
882                break
883            if student_review_state not in ('courses_validated','returning'):
884                msg = "student %s in wrong review_state %s" % (student_id, student_review_state)
885                break
886            student_obj = getattr(students_folder,student_id)
887            # f2t = self.field2types_student
888            study_course_obj = getattr(student_obj,'study_course',None)
889            if study_course_obj is None:
890                msg = 'student %s: no study_course object' % student_id
891                break
892            level_obj = getattr(study_course_obj,current_level,None)
893            if  level_obj is None:
894                msg = 'student %s: no study_level object for level %s' % (student_id,
895                                                                                current_level)
896                break
897            verdict = d['verdict'] = d['current_verdict']  = mapping.get('current_verdict','')
898   
899            #if verdict == student_record.verdict:
900            #    msg = 'student %s: verdict already set to %s' % (student_id,
901            #                                                            verdict)
902   
903            level_review_state = wftool.getInfoFor(level_obj,'review_state',None)
904            if level_review_state != "closed":
905                wftool.doActionFor(level_obj,'close')
906                # msg = 'student %s: level %s is not closed' % (student_id,
907                #                                                      current_level)
908   
909            study_course_obj.getContent().edit(mapping = d)
910            level_obj.getContent().edit(mapping = d)
911            if student_review_state != "returning":
912                wftool.doActionFor(student_obj,'return')
913            # try:
914            #     wftool.doActionFor(level_obj,'close')
915            # except:
916            #     pass
917            break
918        return student_id,msg,mapping
919    ###)
920
Note: See TracBrowser for help on using the repository browser.