source: WAeUP_SRP/base/WAeUPImport.py @ 3192

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

first version with import_mode per line, please copy xml files to okene.

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