source: WAeUP_SRP/base/WAeUPImport.py @ 3236

Last change on this file since 3236 was 3233, checked in by Henrik Bettermann, 17 years ago

Da waren zwei dicke Fehler im Import für Kursergebnisse drin. Bitte schaue dir meine Veränderungen mal an.

  • Property svn:keywords set to Id
File size: 40.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 3233 2008-02-26 09:11:28Z henrik $
20"""The WAeUP Tool Box.
21"""
22
23#from AccessControl import ClassSecurityInfo
24#from Acquisition import aq_inner
25#from Acquisition import aq_parent
26#from Globals import DTMLFile
27#from Globals import InitializeClass
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','remove')
287
288    def getStudentRecord(self,mapping): ###(
289        id_field_found = False
290        msg = ''
291        for id_key in ('id','matric_no'):
292            id_field = mapping.get(id_key,'')
293            if id_field:
294                if id_field_found:
295                    msg = "%s must not be provided" % id_key
296                    break
297                search_key = id_key
298                search_field = id_field
299                id_field_found = True
300        #if search_key == "student_id":
301        #    search_key = 'id'
302        if not id_field_found:
303            msg = "neither id nor matric_no provided"
304            return None,msg
305        query = Eq(search_key,search_field)
306        res = self.students_catalog.evalAdvancedQuery(query)
307        student_record = None
308        if res:
309            student_record = res[0]
310            if search_key == "matric_no":
311                mapping['id'] = student_record.id
312            elif search_key == "id":
313                mapping['matric_no'] = student_record.matric_no
314        else:
315            msg = "no student with %(search_key)s %(search_field)s" % vars()
316        return student_record,msg
317    ###)
318
319    def create(self,mapping):###(
320        students_folder = self.portal_url.getPortalObject().campus.students
321        if getattr(self,'_v_courses',None) is None:
322            res = self.courses_catalog()
323            self._v_courses = {}
324            for brain in res:
325                self._v_courses[brain.code] = brain
326        if getattr(self,'_v_level_created',None) is None:
327            self._v_level_created = []
328        msg = ''
329        key = ''
330        while True:
331            course_id = mapping.get('code')
332            if course_id not in self._v_courses.keys():
333                msg = "no course with id: %s" % course_id
334                break
335            student_record,msg = self.getStudentRecord(mapping)
336            if msg:
337                break
338            student_id = student_record.id
339            level_id = mapping['level_id']
340            code = mapping['code']
341            if student_id not in self._v_level_created:
342                try:
343                    context = getattr(getattr(students_folder,
344                                            "%(student_id)s" % vars()),
345                                    'study_course')
346                except:
347                    msg = "could not create level %(level_id)s for %(student_id)s" % vars()
348                    break
349                if level_id not in context.objectIds():
350                    context.invokeFactory('StudentStudyLevel',"%(level_id)s" % vars())
351                    level = getattr(context,"%(level_id)s" % vars())
352                    self.portal_workflow.doActionFor(level,'open')
353                    # the session string must not be copied into the level object
354                    current_verdict = getattr(student_record,'current_verdict','')
355                    current_session = getattr(student_record,'current_session','')
356                    if current_verdict and student_record.current_level == level_id:
357                        level.getContent().edit(mapping={'verdict': "%s" %
358                                                        current_verdict,
359                                                        'session': "%s" %
360                                                        current_session,
361                                                        })
362                        self.portal_workflow.doActionFor(level,'close')
363                self._v_level_created += student_id,
364            mapping['key'] = key = "%(student_id)s|%(level_id)s|%(code)s" % vars()
365            for k in ('semester','credits',):
366                mapping[k] = getattr(self._v_courses[course_id],k)
367            try:
368                self.course_results.addRecord(**mapping)
369            except ValueError:
370                msg = "course result already exists: %s" % key
371            break
372        return key,msg,mapping
373    ###)
374
375    def edit(self,mapping): ###(
376        #import pdb;pdb.set_trace()
377        msg = ''
378        key = ''
379        while True:
380            student_record,msg = self.getStudentRecord(mapping)
381            if msg:
382                break
383            if not mapping.get('level_id',''):
384                msg =  "level_id is missing"
385                break
386            if not mapping.get('code',''):
387                msg =  "code is missing"
388                break             
389            student_id = student_record.id
390            level_id = mapping['level_id']
391            code = mapping['code']
392            mapping['key'] = key = "%(student_id)s|%(level_id)s|%(code)s" % vars()
393            break
394        try:
395            self.course_results.modifyRecord(**mapping)
396        except KeyError:
397            msg = "no course result with key %s" % key
398        return key,msg,mapping
399    ###)
400
401    def remove(self,mapping):###(
402        key = ''
403        msg = ''
404        while True:
405            student_record,msg = self.getStudentRecord(mapping)
406            if msg:
407                break
408            if not mapping.get('level_id',''):
409                msg =  "level_id is missing"
410                break
411            if not mapping.get('code',''):
412                msg =  "code is missing"
413                break               
414            student_id = student_record.id
415            level_id = mapping['level_id']
416            code = mapping['code']
417            key = "%(student_id)s|%(level_id)s|%(code)s" % vars()
418            if self.course_results.getRecordByKey(key) is None:
419                msg =  "no course result with key %(key)s" % vars()
420                break
421            self.course_results.deleteRecord(key)
422            break
423        return key,msg,mapping
424    ###)
425
426###)
427
428class CertificateCourseImport(WAeUPImport):###(
429    name = "certificate_course"
430    plural_name = "%ss" % name
431    commit_after = 100000
432    required_modes = ('create','edit')
433
434    def create(self,mapping):
435        if getattr(self,'_v_courses',None) is None:
436            res = self.courses_catalog()
437            self._v_courses= [course.code for course in res]
438        if getattr(self,'_v_ceritficates',None) is None:
439            res = self.portal_catalog(portal_type = "Certificate")
440            self._v_certificates = {}
441            for cert in res:
442                self._v_certificates[cert.getId] = cert.getObject()
443        msg = ''
444        while True:
445            certificate_course_id = mapping.get('code')
446            if certificate_course_id not in self._v_courses:
447                msg =  "no course with id: %s" % certificate_course_id
448                break
449            cert_id = mapping['certificate_code']
450            cert = self._v_certificates.get(cert_id,None)
451            if cert is None:
452                msg =  "no certificate with id: %s" % cert_id
453                break
454            level_id = mapping.get('level')
455            level = getattr(cert,level_id,None)
456            if level is None:
457                cert.invokeFactory('StudyLevel', level_id)
458                level = getattr(cert,level_id,None)
459            elif hasattr(level,certificate_course_id):
460                msg =  "duplicate certificate course id: %(certificate_course_id)s " % vars()
461                msg += "in %(cert_id)s/ %(level_id)s" % vars()
462                break
463            level.invokeFactory('CertificateCourse', certificate_course_id)
464            c = getattr(level,certificate_course_id)
465            c.getContent().edit(mapping=mapping)
466            break
467        return certificate_course_id,msg,mapping
468    ###)
469
470class DepartmentImport(WAeUPImport):###(
471    name = "department"
472    plural_name = "%ss" % name
473    commit_after = 1000
474
475    def create(self,mapping):###(
476        "create a department in the correct faculty"
477        faculty_id = mapping['faculty_code']
478        msg = ''
479        if getattr(self,'_v_faculties',None) is None:
480            res = self.portal_catalog(portal_type = "Department")
481            self._v_faculties = {}
482            for f in res:
483                self._v_faculties[f.getId] = f.getObject()
484        department_id = mapping.get('code','')
485        while True:
486            faculty = self._v_faculties.get(faculty_id,None)
487            if faculty is None:
488                msg =  "no faculty with id: %s" % faculty_id
489                break
490            else:
491                d = getattr(faculty,department_id,None)
492                if d is None or d.portal_type == "Faculty":
493                    try:
494                        faculty.invokeFactory('Department', department_id)
495                    except BadRequest,E:
496                        msg =  "%s" % E
497                        break
498                    d = getattr(faculty,department_id)
499                    d.invokeFactory('CoursesFolder','courses')
500                    courses = getattr(d,'courses')
501                    dict = {'Title': 'Courses'}
502                    courses.getContent().edit(mapping=dict)
503                    d.invokeFactory('CertificatesFolder','certificates')
504                    certificates = getattr(d,'certificates')
505                    dict = {'Title': 'Certificates'}
506                    certificates.getContent().edit(mapping=dict)
507                    d.getContent().edit(mapping=mapping)
508            break
509        return department_id,msg,mapping
510    ###)
511
512    def edit(self,mapping): ###(
513        "edit a department in the correct faculty"
514        academics_folder = self.portal_url.getPortalObject().campus.academics
515        faculty_id = mapping['faculty_code']
516        department_id = mapping.get('code','')
517        msg = ''
518        while True:
519            try:
520                d = getattr(getattr(academics_folder,faculty_id),department_id,None)
521            except KeyError:
522                msg =  "department %s or faculty %s wrong" % (department_id,faculty_id)
523                break
524            if d is None or d.portal_type == "Faculty":
525                msg =  "department %s not found" % (department_id)
526                break
527            d.getContent().edit(mapping=mapping)
528            break
529        return department_id,msg,mapping
530    ###)
531###)
532
533class FacultyImport(WAeUPImport):###(
534    name = "faculty"
535    plural_name = "faculties"
536    commit_after = 100
537
538    def create(self,mapping): ###(
539        "create a faculty"
540        academics_folder = self.portal_url.getPortalObject().campus.academics
541        faculty_id = mapping.get('code','')
542        msg = ''
543        while True:
544            if faculty_id in academics_folder.objectIds():
545                msg =  "faculty with id: %s exists" % faculty_id
546                break
547            logger.info('Creating Faculty %(code)s, %(title)s' % mapping)
548            try:
549                academics_folder.invokeFactory('Faculty', faculty_id)
550            except BadRequest,E:
551                msg =  "%s" % E
552                break
553            f = getattr(academics_folder,faculty_id,None)
554            f.getContent().edit(mapping=mapping)
555            break
556        return faculty_id,msg,mapping
557        ###)
558
559    def edit(self,mapping): ###(
560        "edit a faculty"
561        academics_folder = self.portal_url.getPortalObject().campus.academics
562        faculty_id = mapping['code']
563        msg = ''
564        while True:
565            f = getattr(academics_folder,faculty_id,None)
566            if f is None:
567                msg =  "faculty with id: %s does not exist" % faculty_id
568            f.getContent().edit(mapping=mapping)
569            break
570        return faculty_id,msg,mapping
571    ###)
572###)
573
574class StudentImport(WAeUPImport):###(
575    name = "student"
576    plural_name = "%ss" % name
577    commit_after = 100
578
579    field2types_student = {   ###(
580                      'StudentApplication':
581                          {'id': 'application',
582                           'title': 'Application Data',
583                           'wf_transition_return': 'close',
584                           'wf_transition_admit': 'remain',
585                           'fields':
586                             ('jamb_reg_no',
587                              'entry_mode',
588                              'entry_session',
589                              'jamb_score',
590                              'app_email',
591                              'jamb_age',
592                              'jamb_state',
593                              'jamb_lga',
594                              'jamb_sex',
595                              )
596                              },
597                      #'StudentPume':
598                      #    {'id': 'pume',
599                      #     'title': 'Pume Data',
600                      #     'wf_transition_return': 'close',
601                      #     'wf_transition_admit': 'close',
602                      #     'fields':
603                      #       ('pume_score',
604                      #        )
605                      #        },
606                      'StudentClearance':
607                          {'id': 'clearance',
608                           'title': 'Clearance/Eligibility Record',
609                           'wf_transition_return': 'close',
610                           'wf_transition_admit': 'remain',
611                           'fields':
612                             ('matric_no',
613                              'nationality',
614                              'lga',
615                              'birthday',
616                              )
617                              },
618                         'StudentPersonal':
619                          {'id': 'personal',
620                           'title': 'Personal Data',
621                           'wf_transition_return': 'open',
622                           'wf_transition_admit': 'remain',
623                           'fields':
624                             ('firstname',
625                              'middlename',
626                              'lastname',
627                              'sex',
628                              'email',
629                              'phone',
630                              'perm_address',
631                              )
632                              },
633                         'StudentStudyCourse':
634                          {'id': 'study_course',
635                           'title': 'Study Course',
636                           'wf_transition_return': 'open',
637                           'wf_transition_admit': 'remain',
638                           'fields':
639                             ('study_course',
640                              'current_level',
641                              'current_session',
642                              'current_mode',
643                              'current_verdict',
644                              'previous_verdict',
645                              )
646                              },
647                         # 'StudentStudyLevel':
648                         #  {'id': 'current_level',
649                         #   'title': '',
650                         #   'wf_transition_return': 'open',
651                         #   'wf_transition_admit': 'remain',
652                         #   'fields':
653                         #     ('verdict',
654                         #      'session',
655                         #      )
656                         #      },
657                         'PaymentsFolder':
658                          {'id': 'payments',
659                           'title': 'Payments',
660                           'wf_transition_return': 'open',
661                           'wf_transition_admit': 'open',
662                           'fields':
663                             ()
664                              },
665                         }
666    ###)
667
668    def create(self,mapping): ###(
669        "create student records due import"
670        logger = logging.getLogger('WAeUPTool.mass_create_student')
671        students_folder = self.portal_url.getPortalObject().campus.students
672        jamb_reg_no = mapping.get('jamb_reg_no',None)
673        matric_no = mapping.get('matric_no',None)
674        msg = ''
675        student_id = mapping.get('id',None)
676        while True:
677            if student_id:
678                msg = "student_id must not be specified in create mode"
679                break
680            if jamb_reg_no:
681                res = self.students_catalog(jamb_reg_no = jamb_reg_no)
682                if res:
683                    msg = "jamb_reg_no exists"
684                    break
685            if matric_no:
686                res = self.students_catalog(matric_no = matric_no)
687                if res:
688                    msg = "matric_no exists"
689                    break
690            if not matric_no and not jamb_reg_no:
691                msg = "jamb_reg_no or matric_no must be specified"
692                break
693            student_id = self.waeup_tool.generateStudentId('?')
694            students_folder.invokeFactory('Student', student_id)
695            student_obj = getattr(students_folder,student_id)
696            f2t = self.field2types_student
697            d = {}
698            transition = mapping.get('reg_transition','admit')
699            if transition not in ('admit','return'):
700                msg = "no valid transition provided"
701                break
702            for pt in f2t.keys():
703                student_obj.invokeFactory(pt,f2t[pt]['id'])
704                sub_obj = getattr(student_obj,f2t[pt]['id'])
705                sub_doc = sub_obj.getContent()
706                d['Title'] = f2t[pt]['title']
707                for field in f2t[pt]['fields']:
708                    d[field] = mapping.get(field,'')
709
710                if pt == "StudentApplication":
711                    #d['jamb_sex']  = 'M'
712                    #if mapping.get('sex'):
713                    #    d['jamb_sex']  = 'F'
714                    d['jamb_firstname'] = mapping.get('firstname',None)
715                    d['jamb_middlename'] = mapping.get('middlename',None)
716                    d['jamb_lastname'] = mapping.get('lastname',None)
717
718                # if pt == "StudyCourse":
719                #     for von,zu in (('entry_mode','current_mode'),
720                #                    ('entry_session','current_session')):
721                #         if mapping.get(zu,None) is None and mapping.get(von,None) is not None:
722                #             d[zu] = mapping[von]
723                sub_doc.edit(mapping = d)
724
725                #import pdb;pdb.set_trace()
726                new_state = f2t[pt]['wf_transition_%(transition)s' % vars()]
727                if new_state != "remain":
728                    self.portal_workflow.doActionFor(sub_obj,new_state,dest_container=sub_obj)
729            self.portal_workflow.doActionFor(student_obj,transition)
730            student_obj.manage_setLocalRoles(student_id, ['Owner',])
731            mapping['id'] = student_id
732            break
733        return student_id,msg,mapping
734    ###)
735
736    def edit(self,mapping): ###(
737        wftool = self.portal_workflow
738        "edit student records due import"
739        logger = logging.getLogger('WAeUPTool.mass_edit_student')
740        students_folder = self.portal_url.getPortalObject().campus.students
741        student_id = mapping.get('id',None)
742        jamb_reg_no = mapping.get('jamb_reg_no',None)
743        matric_no = mapping.get('matric_no',None)
744        editable_keys = mapping.keys()
745        msg = ''
746        while True:
747            if student_id:
748                res = self.students_catalog(id = student_id)
749                if not res:
750                    msg = "no student with id %s" % student_id
751                    break
752                student_record = res[0]
753                if matric_no and student_record.matric_no:
754                    if  matric_no != student_record.matric_no:
755                        msg = "old matric_no %s overwritten with %s" % (student_record.matric_no,matric_no)
756                        #logger.info("%s, old matric_no %s overwritten with %s" % (student_record.id,student_record.matric_no,matric_no))
757                if jamb_reg_no and student_record.jamb_reg_no:
758                    if jamb_reg_no != student_record.jamb_reg_no:
759                        msg = "old reg_no %s overwritten with %s" % (student_record.jamb_reg_no,jamb_reg_no)
760                        #logger.info("%s, old reg_no %s overwritten with %s" % (student_record.id,student_record.jamb_reg_no,jamb_reg_no))
761            elif jamb_reg_no:
762                res = self.students_catalog(jamb_reg_no = jamb_reg_no)
763                if not res:
764                    msg = "no student with jamb_reg_no %s" % jamb_reg_no
765                    break
766                student_record = res[0]
767                editable_keys.remove('jamb_reg_no')
768            elif matric_no:
769                res = self.students_catalog(matric_no = matric_no)
770                if not res:
771                    msg = "no student with matric_no %s" % matric_no
772                    break
773                student_record = res[0]
774                editable_keys.remove('matric_no')
775            ## included only to change wf state from admitted to returning
776            #if student_record.review_state not in ('admitted','objection_raised'):
777            #    return '%s' % student_record.id ,"student is not in state admitted or objection_raised"
778            ## end inclusion
779            student_id = student_record.id
780            student_obj = getattr(students_folder,student_id)
781            f2t = self.field2types_student
782            d = {}
783            any_change = False
784            #special treatment for StudentStudyLevel
785            d['verdict']  = mapping.get('current_verdict','')
786            d['session']  = mapping.get('current_session','')
787            current_level = mapping.get('current_level','')
788            while d['session'] and d['verdict'] and current_level:
789                sub_obj = getattr(student_obj,'study_course',None)
790                if sub_obj is None:
791                    break
792                level_obj = getattr(sub_obj,current_level,None)
793                if  level_obj is None:
794                    break
795                any_change = True
796                level_obj.getContent().edit(mapping = d)
797                try:
798                    wftool.doActionFor(level_obj,'close')
799                except:
800                    pass
801                break
802            for pt in f2t.keys():
803                #if pt == "StudentApplication":
804                #    d['jamb_sex']  = 'M'
805                #    if mapping.get('sex'):
806                #        d['jamb_sex']  = 'F'
807                intersect = set(f2t[pt]['fields']).intersection(set(editable_keys))
808                if intersect and pt not in ('StudentStudyLevel',):
809                    object_id = f2t[pt]['id']
810                    sub_obj = getattr(student_obj,object_id,None)
811                    if sub_obj is None:
812                        try:
813                            student_obj.invokeFactory(pt,object_id)
814                        except:
815                            continue
816                        sub_obj = getattr(student_obj,object_id)
817                        if f2t[pt]['title'] != '':
818                            d['Title'] = f2t[pt]['title']
819                    sub_doc = sub_obj.getContent()
820                    for field in intersect:
821                        changed = False
822                        if getattr(sub_doc,field,None) != mapping.get(field,''):
823                            any_change = True
824                            changed = True
825                            d[field] = mapping.get(field,'')
826                        if changed:
827                            sub_doc.edit(mapping = d)
828            ## included only to change wf state from admitted to returning
829            #    if student_record.review_state in ('admitted','objection_raised'):
830            #        new_state = f2t[pt]['wf_transition_return']
831            #        sub_obj = getattr(student_obj,f2t[pt]['id'],None)
832            #        if sub_obj and new_state != "remain":
833            #            try:
834            #                self.portal_workflow.doActionFor(sub_obj,new_state,dest_container=sub_obj)
835            #            except:
836            #                #logger.info('%s, wf transition %s of %s failed' % (student_id,new_state,sub_obj.id))
837            #                pass
838            #if student_record.review_state in ('admitted','objection_raised'):
839            #    wfaction = 'return'
840            #    try:
841            #        self.portal_workflow.doActionFor(student_obj,wfaction)
842            #        logger.info('%s, wf state changed' % student_id)
843            #        any_change = True
844            #    except:
845            #        logger.info('%s, wf transition failed, old state = %s' % (student_id,student_record.review_state))
846            #        pass
847            ## end inclusion
848            break
849        # if not any_change:
850        #     msg = 'not modified'
851        return student_id,msg,mapping
852    ###)
853###)
854
855class VerdictImport(WAeUPImport):###(
856    """ VerdictImport """
857    name = "verdict"
858    plural_name = "%ss" % name
859    commit_after = 100000
860    required_modes = ('create','edit')
861
862    def edit(self,mapping):
863        "edit student verdicts"
864        wftool = self.portal_workflow
865        logger = logging.getLogger('WAeUPTool.mass_edit_verdict')
866        students_folder = self.portal_url.getPortalObject().campus.students
867        student_id = mapping.get('id',None)
868        matric_no = mapping.get('matric_no',None)
869        editable_keys = mapping.keys()
870        while True:
871            key = ''
872            msg = ''
873            if student_id:
874                student_record = self.students_catalog.getRecordByKey(student_id)
875                if student_record is None:
876                    #return '',"no student with id %s" % student_id
877                    msg = "no student with id %s" % student_id
878                    break
879                if matric_no and student_record.matric_no and matric_no != student_record.matric_no:
880                    msg = 'student %s: matric_no %s does not match %s' % (student_record.id,
881                                                                          student_record.matric_no,
882                                                                          matric_no)
883                    break
884                mapping['matric_no'] = student_record.matric_no
885            elif matric_no:
886                res = self.students_catalog(matric_no = matric_no)
887                if not res:
888                    msg = "no student with matric_no %s" % matric_no
889                    break
890                student_record = res[0]
891                editable_keys.remove('matric_no')
892            else:
893                msg = "no id or matric_no specified"
894                break
895            student_id = student_record.id
896            mapping['id'] = student_id
897            d = {}
898            #import pdb;pdb.set_trace()
899            any_change = False
900            #special treatment for StudentStudyLevel
901            current_session = d['session'] = mapping.get('current_session','')
902            if current_session and student_record.session != current_session:
903                msg = 'student %s: imported session %s does not match current_session %s' % (student_id,
904                                                                                            current_session,
905                                                                                            student_record.session)
906                break
907            current_level = mapping.get('current_level','')
908            if not current_level.isdigit():
909                msg = 'student %s: imported level is empty' % (student_id,)
910                break
911            if current_level and student_record.level != current_level:
912                msg = 'student %s: imported level %s does not match current_level %s' % (student_id,
913                                                                                        current_level,
914                                                                                        student_record.level)
915                break
916            student_review_state =  student_record.review_state
917            if student_review_state == 'deactivated':
918                msg = "student %s in review_state %s" % (student_id, student_review_state)
919                break
920            if student_review_state not in ('courses_validated','returning'):
921                msg = "student %s in wrong review_state %s" % (student_id, student_review_state)
922                break
923            student_obj = getattr(students_folder,student_id)
924            # f2t = self.field2types_student
925            study_course_obj = getattr(student_obj,'study_course',None)
926            if study_course_obj is None:
927                msg = 'student %s: no study_course object' % student_id
928                break
929            level_obj = getattr(study_course_obj,current_level,None)
930            if  level_obj is None:
931                msg = 'student %s: no study_level object for level %s' % (student_id,
932                                                                                current_level)
933                break
934            verdict = d['verdict'] = d['current_verdict']  = mapping.get('current_verdict','')
935
936            #if verdict == student_record.verdict:
937            #    msg = 'student %s: verdict already set to %s' % (student_id,
938            #                                                            verdict)
939
940            level_review_state = wftool.getInfoFor(level_obj,'review_state',None)
941            if level_review_state != "closed":
942                wftool.doActionFor(level_obj,'close')
943                # msg = 'student %s: level %s is not closed' % (student_id,
944                #                                                      current_level)
945
946            study_course_obj.getContent().edit(mapping = d)
947            level_obj.getContent().edit(mapping = d)
948            if student_review_state != "returning":
949                wftool.doActionFor(student_obj,'return')
950            # try:
951            #     wftool.doActionFor(level_obj,'close')
952            # except:
953            #     pass
954            break
955        return student_id,msg,mapping
956    ###)
957
Note: See TracBrowser for help on using the repository browser.