source: WAeUP_SRP/base/WAeUPImport.py @ 3208

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

This is the correct Boolean logic. The last commit was only to quickly enable import of PT students.

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