source: WAeUP_SRP/base/WAeUPImport.py @ 3219

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

check if required fields are present in data-record

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