source: WAeUP_SRP/base/WAeUPImport.py @ 3245

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

I hope this soves ticket #103 fce.

  • Property svn:keywords set to Id
File size: 45.8 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 3243 2008-02-27 06:56:25Z 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 create(self,mapping):
863        "edit student verdicts and create StudentStudyLevel object if not existent"
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
931            if  level_obj is None:
932                # The only difference to the edit method is that we create a StudentStudyLevel object
933                try:
934                    study_course_obj.invokeFactory('StudentStudyLevel',"%s" % current_level)
935                    level_obj = getattr(context,"%s" % current_level)
936                    level_obj.portal_workflow.doActionFor(level,'open')
937                except:
938                    continue             
939                #msg = 'student %s: no study_level object for level %s' % (student_id,
940                #                                                                current_level)
941                #break
942
943            verdict = d['verdict'] = d['current_verdict']  = mapping.get('current_verdict','')
944
945            #if verdict == student_record.verdict:
946            #    msg = 'student %s: verdict already set to %s' % (student_id,
947            #                                                            verdict)
948
949            level_review_state = wftool.getInfoFor(level_obj,'review_state',None)
950            if level_review_state != "closed":
951                wftool.doActionFor(level_obj,'close')
952                # msg = 'student %s: level %s is not closed' % (student_id,
953                #                                                      current_level)
954
955            study_course_obj.getContent().edit(mapping = d)
956            level_obj.getContent().edit(mapping = d)
957            if student_review_state != "returning":
958                wftool.doActionFor(student_obj,'return')
959            # try:
960            #     wftool.doActionFor(level_obj,'close')
961            # except:
962            #     pass
963            break
964        return student_id,msg,mapping   
965
966
967    def edit(self,mapping):
968        "edit student verdicts"
969        wftool = self.portal_workflow
970        logger = logging.getLogger('WAeUPTool.mass_edit_verdict')
971        students_folder = self.portal_url.getPortalObject().campus.students
972        student_id = mapping.get('id',None)
973        matric_no = mapping.get('matric_no',None)
974        editable_keys = mapping.keys()
975        while True:
976            key = ''
977            msg = ''
978            if student_id:
979                student_record = self.students_catalog.getRecordByKey(student_id)
980                if student_record is None:
981                    #return '',"no student with id %s" % student_id
982                    msg = "no student with id %s" % student_id
983                    break
984                if matric_no and student_record.matric_no and matric_no != student_record.matric_no:
985                    msg = 'student %s: matric_no %s does not match %s' % (student_record.id,
986                                                                          student_record.matric_no,
987                                                                          matric_no)
988                    break
989                mapping['matric_no'] = student_record.matric_no
990            elif matric_no:
991                res = self.students_catalog(matric_no = matric_no)
992                if not res:
993                    msg = "no student with matric_no %s" % matric_no
994                    break
995                student_record = res[0]
996                editable_keys.remove('matric_no')
997            else:
998                msg = "no id or matric_no specified"
999                break
1000            student_id = student_record.id
1001            mapping['id'] = student_id
1002            d = {}
1003            #import pdb;pdb.set_trace()
1004            any_change = False
1005            #special treatment for StudentStudyLevel
1006            current_session = d['session'] = mapping.get('current_session','')
1007            if current_session and student_record.session != current_session:
1008                msg = 'student %s: imported session %s does not match current_session %s' % (student_id,
1009                                                                                            current_session,
1010                                                                                            student_record.session)
1011                break
1012            current_level = mapping.get('current_level','')
1013            if not current_level.isdigit():
1014                msg = 'student %s: imported level is empty' % (student_id,)
1015                break
1016            if current_level and student_record.level != current_level:
1017                msg = 'student %s: imported level %s does not match current_level %s' % (student_id,
1018                                                                                        current_level,
1019                                                                                        student_record.level)
1020                break
1021            student_review_state =  student_record.review_state
1022            if student_review_state == 'deactivated':
1023                msg = "student %s in review_state %s" % (student_id, student_review_state)
1024                break
1025            if student_review_state not in ('courses_validated','returning'):
1026                msg = "student %s in wrong review_state %s" % (student_id, student_review_state)
1027                break
1028            student_obj = getattr(students_folder,student_id)
1029            # f2t = self.field2types_student
1030            study_course_obj = getattr(student_obj,'study_course',None)
1031            if study_course_obj is None:
1032                msg = 'student %s: no study_course object' % student_id
1033                break
1034            level_obj = getattr(study_course_obj,current_level,None)
1035            if  level_obj is None:
1036                msg = 'student %s: no study_level object for level %s' % (student_id,
1037                                                                                current_level)
1038                break
1039            verdict = d['verdict'] = d['current_verdict']  = mapping.get('current_verdict','')
1040
1041            #if verdict == student_record.verdict:
1042            #    msg = 'student %s: verdict already set to %s' % (student_id,
1043            #                                                            verdict)
1044
1045            level_review_state = wftool.getInfoFor(level_obj,'review_state',None)
1046            if level_review_state != "closed":
1047                wftool.doActionFor(level_obj,'close')
1048                # msg = 'student %s: level %s is not closed' % (student_id,
1049                #                                                      current_level)
1050
1051            study_course_obj.getContent().edit(mapping = d)
1052            level_obj.getContent().edit(mapping = d)
1053            if student_review_state != "returning":
1054                wftool.doActionFor(student_obj,'return')
1055            # try:
1056            #     wftool.doActionFor(level_obj,'close')
1057            # except:
1058            #     pass
1059            break
1060        return student_id,msg,mapping
1061    ###)
1062
Note: See TracBrowser for help on using the repository browser.