source: WAeUP_SRP/trunk/WAeUPImport.py @ 3984

Last change on this file since 3984 was 3984, checked in by Henrik Bettermann, 16 years ago

export student_study_levels
export payments
create file for reimport

  • Property svn:keywords set to Id
File size: 65.6 KB
RevLine 
[3172]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 3984 2009-02-26 22:22:07Z 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
[3277]28from OFS.SimpleItem import SimpleItem
[3172]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
[3277]35from Products.CMFCore.ActionProviderBase import ActionProviderBase
[3172]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
[3277]40from Products.CMFCore.utils import UniqueObject
[3172]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
[3314]53NO_KEY = '----'
[3316]54IGNORE = 'ignore'
[3277]55class WAeUPImport(UniqueObject, SimpleItem, ActionProviderBase): ###(
[3172]56    """ WAeUPImport """
57    required_modes = ('create',)
58
[3277]59    def __init__(self,waeup_tool): ###(
60        self.students_folder = waeup_tool.portal_url.getPortalObject().campus.students
[3172]61        self.member = member = waeup_tool.portal_membership.getAuthenticatedMember()
[3320]62        self.import_date = DateTime.DateTime()
63        self.imported_by = str(member)
64        #self.current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
[3172]65        self.waeup_tool = waeup_tool
[3248]66        self.academics_folder = waeup_tool.portal_url.getPortalObject().campus.academics
[3172]67        self.schema_tool = getToolByName(waeup_tool, 'portal_schemas')
68        self.layout_tool = getToolByName(waeup_tool, 'portal_layouts')
[3842]69        self.types_tool = getToolByName(waeup_tool, 'portal_types')
[3172]70        self.portal_workflow = getToolByName(waeup_tool, 'portal_workflow')
71        self.portal_url = getToolByName(waeup_tool, 'portal_url')
[3178]72        self.portal_catalog = waeup_tool.portal_catalog
[3822]73        self.portal_directories = waeup_tool.portal_directories
[3172]74        self.students_catalog = waeup_tool.students_catalog
75        self.courses_catalog = waeup_tool.courses_catalog
76        self.course_results = waeup_tool.course_results
[3984]77        self.payments_catalog = waeup_tool.payments_catalog
[3250]78        self.applicants_catalog = waeup_tool.applicants_catalog
[3191]79        #self.mode = mode
80        # self.import_method = getattr(self, '%s' % mode,None)
[3172]81        errors = []
[3191]82        # if self.import_method is None:
83        #     errors.append('No importer method %s' % mode)
[3178]84        self.pending_path = "%s/import/%s.pending" % (i_home,self.plural_name)
85        self.pending_tmp = "%s/import/%s.pending.tmp" % (i_home,self.plural_name)
86        self.pending_backup = "%s/import/%s.pending.old" % (i_home,self.plural_name)
[3172]87        self.pending_fn = os.path.split(self.pending_path)[1]
[3178]88        self.imported_path = "%s/import/%s.imported" % (i_home,self.plural_name)
[3172]89        self.imported_fn = os.path.split(self.imported_path)[1]
90        iname = "import_%s" % self.name
[3249]91        self.logger = logging.getLogger('WAeUPImport.%sImport' % self.plural_name.capitalize())
[3172]92        self.schema = self.schema_tool._getOb(iname,None)
[3250]93        #self.pending_schema = self.schema_tool._getOb("%s_pending" % iname,None)
[3172]94        self.layout = self.layout_tool._getOb(iname,None)
[3250]95        while True:
96            if self.schema is None:
97                errors.append('no schema %s' % iname)
98            # if self.pending_schema is None:
99            #     self.pending_schema = self.schema
100            if self.layout is None:
101                errors.append('no such layout %s' % iname)
102            if errors:
103                break
104            self.data_keys = self.schema.keys()
105            self.csv_keys = self.schema.keys()
106            info = {}
107            info['imported_from'] = ''
[3326]108            info['import_record_no'] = 0
[3325]109            info['imported_by'] = self.imported_by
[3320]110            info['import_date'] = self.import_date.strftime("%d/%m/%y %H:%M:%S")
[3250]111            info['error'] = ''
112            self.info = info
113            self.csv_keys.extend(self.info)
114            self.validators = {}
115            for widget in self.layout.keys():
116                self.validators[widget] = self.layout[widget].validate
117            self.required_keys = {}
118            for mode in self.required_modes:
119                self.required_keys[mode] = [self.layout.getIdUnprefixed(id)
120                                    for id,widget in self.layout.objectItems()
121                                    if widget.is_required]
122            break
[3172]123        self.init_errors = ','.join(errors)
[3277]124    ###)
[3172]125
[3372]126    def findStudent(self,mode,student_id=None, matric_no=None, jamb_reg_no=None): ###(
127        student_record = None
128        msg = ''
129        key_used = ''
130        while True:
131            if student_id:
132                key_used = 'student_id'
133                res = self.students_catalog(id = student_id)
134                if not res:
135                    msg = "no student with id %s" % student_id
136                    break
137                student_record = res[0]
138                if matric_no and student_record.matric_no:
139                    if  matric_no != student_record.matric_no:
140                        msg = "old matric_no %s overwritten with %s" % (student_record.matric_no,matric_no)
141                        #logger.info("%s, old matric_no %s overwritten with %s" % (student_record.id,student_record.matric_no,matric_no))
142                if jamb_reg_no and student_record.jamb_reg_no:
143                    if jamb_reg_no != student_record.jamb_reg_no:
144                        msg = "old reg_no %s overwritten with %s" % (student_record.jamb_reg_no,jamb_reg_no)
145                        #logger.info("%s, old reg_no %s overwritten with %s" % (student_record.id,student_record.jamb_reg_no,jamb_reg_no))
146            elif jamb_reg_no:
147                key_used = 'jamb_reg_no'
148                res = self.students_catalog(jamb_reg_no = jamb_reg_no)
149                if res:
[3383]150                    if mode == 'create':
[3372]151                        msg = "jamb_reg_no exists"
152                        break
153                else:
154                    if mode == 'edit':
155                        msg = "no student with jamb_reg_no %s" % jamb_reg_no
156                        break
157                student_record = res[0]
158            elif matric_no:
159                key_used = 'matric_no'
160                res = self.students_catalog(matric_no = matric_no)
161                if not res:
162                    msg = "no student with matric_no %s" % matric_no
163                    break
164                student_record = res[0]
[3382]165            else:
[3383]166                msg = "neither id, matric_no nor reg_no specified"
[3372]167            break
168        d = {}
169        d['student_record'] = student_record
[3383]170        d['key_used'] = key_used
171        d['msg'] = msg
[3372]172        return d
173    ###)
174
[3277]175    def makeIdLists(self): ###(
[3172]176        pending_digests = []
177        pending = []
178        # pending_student_ids = []
179        # pending_matric_nos = []
180        # pending_reg_ns = []
181        if os.path.exists(self.pending_path):
182            datafile = open(self.pending_path,"r")
[3325]183            reader = csv.reader(datafile)
184            old_headline = reader.next()
185            #datafile.seek(0)
186            pending_csv_reader = csv.DictReader(datafile,old_headline,)
187            #pending_csv_reader.next() # skip headline
[3172]188            for item in pending_csv_reader:
189                digest = makeDigest(item,self.data_keys)
190                if digest not in pending_digests:
191                    pending_digests += digest,
192                    pending += item,
[3178]193            datafile.close()
[3268]194            #copy2(self.pending_path,self.pending_backup)
[3172]195        return pending, pending_digests
[3277]196    ###)
197
[3292]198    def checkHeadline(self,headline): ###(
[3315]199        """ check the headline of a csv file """
[3277]200        import_keys = [k.strip() for k in headline if not (k.strip().startswith('ignore')
201                                                        or k.strip() in self.info.keys())]
[3316]202        # import_keys = [k.strip() for k in headline if not (k.strip() in self.info.keys())]
[3277]203        diff2schema = set(import_keys).difference(set(self.schema.keys()))
204        diff2layout = set(import_keys).difference(set(self.layout.keys()))
205        #if diff2schema and diff2schema != set(['id',]):
206        if diff2schema:
207            return list(diff2schema)
208        return []
[3292]209    ###)
[3314]210
211    def getHeadlineFields(self,headline,values): ###(
[3315]212        """ check the headline of a csv file """
[3316]213        # import_keys = [k.strip() for k in headline if not (k.strip().startswith('ignore')
214        #                                                 or k.strip() in self.info.keys())]
215        import_keys = [k.strip() for k in headline if not (k.strip() in self.info.keys())]
[3347]216        info_keys = [k.strip() for k in headline if k.strip() in self.info.keys()]
[3314]217        si = set(import_keys)
218        ss = set(self.schema.keys())
[3315]219
[3314]220        invalid_keys = si - ss
221        keys = []
222        i = 0
[3316]223        duplicates = False
224        singels = []
225        msg = ''
226        while True:
227            if len(values) != len(import_keys):
[3347]228                if len(values) == len(import_keys) + len(info_keys):
229                    msg += "fields from pending file in headline"
230                else:
231                    msg += "%d fields in headline but %d values" % (len(import_keys),len(values))
[3316]232                break
233            for k in import_keys:
234                if k in singels:
[3318]235                    keys += (k,'%s' % k,values[i],'(duplicate)'),
[3325]236                    msg += ("duplicate %s," % k)
[3318]237                    keys[singels.index(k)] = (k,'%s' % k,values[singels.index(k)],'(duplicate)')
[3316]238                elif k in invalid_keys and not k.startswith(IGNORE):
[3318]239                    keys += (k,NO_KEY,values[i],'(invalid)'),
[3316]240                else:
241                    keys += (k,k,values[i],''),
242                i += 1
243                singels += k,
244            break
245        return msg,keys
[3314]246    ###)
[3172]247###)
248
249class ApplicationImport(WAeUPImport):###(
[3250]250    name = "application"
[3172]251    plural_name = "%ss" % name
252    commit_after = 1000
253
254    def create(self,mapping):###(
255        reg_no = mapping.get('reg_no')
256        msg = ''
257        while True:
258            try:
259                self.applicants_catalog.addRecord(**mapping)
260            except ValueError:
261                msg =  "applicant record with reg_no %s already exists" % reg_no
262            break
263        return reg_no,msg,mapping
264    ###)
265
266    def edit(self,mapping):###(
267        reg_no = mapping.get('reg_no')
268        status = mapping.get('status')
269        msg = ''
270        while True:
271            res = self.applicants_catalog(reg_no = reg_no)
272            if len(res):
273                if res[0].status == 'created' and status != 'created':
274                    msg =  "student object with id %s for %s already created, status cannot be changed" % (res[0].student_id, reg_no)
275                elif status == 'created' and res[0].status != 'created':
276                    msg =  "student object for %s has not yet been created, status cannot be set to 'created'" % (reg_no)
277                else:
278                    self.applicants_catalog.modifyRecord(**mapping)
279            else:
280                msg =  "applicant record with reg_no %s does not exist" % reg_no
281            break
282        return reg_no,msg,mapping
283    ###)
284
285###)
286
287class CertificateImport(WAeUPImport):###(
288    name = "certificate"
289    plural_name = "%ss" % name
290    commit_after = 100000
291
292    def create(self,mapping):###(
293        if getattr(self,'_v_certificate_list',None) is None:
294            self._v_certificate_list = []
295        if getattr(self,'_v_department_certificates',None) is None:
[3248]296            departments = self.portal_catalog(portal_type = "Department")
[3172]297            self._v_department_certificates = {}
[3355]298            for department  in departments:
299                certificates_container = getattr(department.getObject(),"certificates",None)
300                self._v_department_certificates[department.getId] = {'container': certificates_container,
301                                                            'certificates': certificates_container.objectIds(),
302                                                            }
[3248]303        department_id = mapping['department_code']
[3172]304        msg = ''
[3248]305        certificate_id = mapping.get('code')
[3172]306        while True:
[3248]307            department_certificates = self._v_department_certificates.get(department_id,None)
308            if department_certificates is None:
309                msg =  "No Department with ID: %s" % department_id
[3172]310                break
[3355]311            certificates_container = department_certificates['container']
312            certificates = department_certificates['certificates']
[3172]313            if certificate_id in self._v_certificate_list:
[3248]314                msg =  "Duplicate Certificate ID: %s" % department_id
[3172]315                break
[3355]316            if certificate_id in certificates:
[3248]317                msg =  "Duplicate Certificate ID: %s" % department_id
[3172]318                break
319            try:
[3355]320                certificates_container.invokeFactory('Certificate', certificate_id)
[3172]321            except BadRequest,E:
322                msg =  "%s" % E
323                break
324            self._v_certificate_list.append(certificate_id)
[3355]325            certificate = getattr(certificates_container,certificate_id)
326            certificate.getContent().edit(mapping=mapping)
[3172]327            break
328        return certificate_id,msg,mapping
329    ###)
330
331    def edit(self,mapping):###(
332        certificate_id = mapping.get('code')
333        res = self.portal_catalog(id=certificate_id)
334        msg = ''
335        while True:
336            if not res:
[3233]337                msg =  "no certificate with id: %s" % certificate_id
[3172]338                break
339            c = res[0].getObject()
340            c.getContent().edit(mapping=mapping)
341            break
342        return certificate_id,msg,mapping
343    ###)
344###)
345
346class CourseImport(WAeUPImport):###(
347    name = "course"
348    plural_name = "%ss" % name
349    commit_after = 1000
350
351    def create(self,mapping):###(
352        if getattr(self,'_v_course_list',None) is None:
353            self._v_course_list = []
[3179]354        if getattr(self,'_v_department_courses',None) is None:
355            departments = self.portal_catalog(portal_type = "Department")
[3172]356            self._v_department_courses = {}
[3179]357            for department in departments:
[3355]358                courses_container = getattr(department.getObject(),"courses",None)
359                if courses_container is not None:
360                    self._v_department_courses[department.getId] = {'container': courses_container,
361                                                                    'courses': courses_container.objectIds(),
362                                                                   }
[3179]363        department_id = mapping['department_code']
364        course_id = mapping.get('code','')
[3172]365        msg = ''
366        while True:
[3179]367            department_courses = self._v_department_courses.get(department_id,None)
368            if department_courses is None:
[3233]369                msg =  "no department with id: %(department_id)s" % vars()
[3172]370                break
[3355]371            courses_container = department_courses['container']
372            courses = department_courses['courses']
[3172]373            if course_id in self._v_course_list:
[3233]374                msg =  "duplicate course id: %(course_id)s" % vars()
[3172]375                break
[3355]376            if course_id in courses:
[3233]377                msg =  "course %(course_id)s already exists in department %(department_id)s" % vars()
[3172]378                break
379            try:
[3355]380                courses_container.invokeFactory('Course', course_id)
[3172]381            except BadRequest,E:
382                msg =  "%s" % E
383                break
384            self._v_course_list.append(course_id)
[3355]385            course = getattr(courses_container,course_id)
[3179]386            course.getContent().edit(mapping=mapping)
[3172]387            break
388        return course_id,msg,mapping
389    ###)
390
391    def edit(self,mapping): ###(
[3179]392        course_id = mapping.get('code','')
[3248]393        course = self.courses_catalog.getRecordByKey(course_id)
[3355]394        msg = ''
[3172]395        while True:
[3248]396            if course is None:
[3233]397                msg =  "no course with id: %s" % course_id
[3172]398                break
[3355]399            course_object = getattr(getattr(getattr(getattr(self.academics_folder,course.faculty),
400                                    course.department),
401                                    'courses'),
402                                    course_id)
[3248]403            course_object.getContent().edit(mapping=mapping)
[3172]404            break
405        return course_id,msg,mapping
406    ###)
[3823]407
408    def remove(self,mapping): ###(
409        course_id = mapping.get('code','')
410        course = self.courses_catalog.getRecordByKey(course_id)
411        msg = ''
412        while True:
413            if course is None:
414                msg =  "no course with id: %s" % course_id
415                break
416            courses = getattr(getattr(getattr(self.academics_folder,course.faculty),
417                                    course.department),
418                                    'courses')
419            courses.manage_delObjects((course_id),)     
420            break
421        return course_id,msg,mapping
422    ###)   
423   
[3172]424###)
425
426class CourseResultImport(WAeUPImport):###(
427    """ CourseresultImport """
428    name = "course_result"
429    plural_name = "%ss" % name
430    commit_after = 1000000
[3233]431    required_modes = ('create','edit','remove')
[3172]432
433    def create(self,mapping):###(
434        students_folder = self.portal_url.getPortalObject().campus.students
435        if getattr(self,'_v_courses',None) is None:
436            res = self.courses_catalog()
437            self._v_courses = {}
438            for brain in res:
439                self._v_courses[brain.code] = brain
440        if getattr(self,'_v_level_created',None) is None:
441            self._v_level_created = []
[3372]442        if getattr(self,'_v_student_study_course',None) is None:
443            self._v_student_study_course = {}
[3172]444        msg = ''
445        key = ''
[3372]446        matric_no = mapping.get('matric_no','')
447        id = mapping.get('id','')
[3172]448        while True:
449            course_id = mapping.get('code')
450            if course_id not in self._v_courses.keys():
[3233]451                msg = "no course with id: %s" % course_id
[3172]452                break
[3372]453            result = self.findStudent('create',student_id=id,matric_no=matric_no)
454            msg = result['msg']
455            if msg:
456                break
457            student_record = result['student_record']
458            student_id = mapping['student_id']  = student_record.id
459            level_id = mapping.get('level_id','')
460            code = mapping.get('code','')
461            level_ident = "%(student_id)s_%(level_id)s" % vars()
462            if level_ident not in self._v_level_created:
463                context = self._v_student_study_course.get(student_id,None)
464                if context is None:
465                    try:
466                        context = getattr(getattr(students_folder,
467                                                "%(student_id)s" % vars()),
468                                        'study_course')
469                        self._v_student_study_course[student_id] = context
470                    except:
471                        msg = "could not create level %(level_id)s for %(student_id)s" % vars()
472                        break
473                if level_id not in context.objectIds():
474                    context.invokeFactory('StudentStudyLevel',"%(level_id)s" % vars())
475                    level = getattr(context,"%(level_id)s" % vars())
476                    self.portal_workflow.doActionFor(level,'open')
[3485]477                    session_id = mapping.get('session_id','')
478                    if session_id:
479                        level.getContent().edit(mapping={'session': "%s" % session_id,})
[3372]480                    self.portal_workflow.doActionFor(level,'close')
481                    self._v_level_created += level_ident,
482            mapping['key'] = key = "%(student_id)s|%(level_id)s|%(code)s" % vars()
[3431]483            #overwrite semester and credits in create mode
[3372]484            for k in ('semester','credits',):
485                mapping[k] = getattr(self._v_courses[course_id],k)
486            try:
487                self.course_results.addRecord(**mapping)
488            except ValueError:
489                msg = "course result already exists: %s" % key
490            break
491        return key,msg,mapping
492    ###)
493
[3374]494    def edit(self,mapping): ###(
[3372]495        msg = ''
496        key = ''
497        matric_no = mapping.get('matric_no','')
[3374]498        id = mapping.get('id','')
[3372]499        while True:
500            result = self.findStudent('edit',student_id=id,matric_no=matric_no)
501            msg = result['msg']
[3172]502            if msg:
503                break
[3372]504            student_record = result['student_record']
[3336]505            student_id = student_record.id
[3248]506            level_id = mapping.get('level_id','')
507            code = mapping.get('code','')
[3431]508            #code = mapping['code']
[3172]509            mapping['key'] = key = "%(student_id)s|%(level_id)s|%(code)s" % vars()
[3330]510            if self.course_results.getRecordByKey(key) is None:
511                msg =  "no course result with key %(key)s" % vars()
512                break
513            self.course_results.modifyRecord(**mapping)
[3172]514            break
515        return key,msg,mapping
516    ###)
517
[3195]518    def remove(self,mapping):###(
[3233]519        key = ''
[3172]520        msg = ''
[3374]521        matric_no = mapping.get('matric_no','')
522        id = mapping.get('id','')
[3172]523        while True:
[3374]524            result = self.findStudent('edit',student_id=id,matric_no=matric_no)
525            msg = result['msg']
[3172]526            if msg:
527                break
[3374]528            student_record = result['student_record']
[3172]529            student_id = student_record.id
[3248]530            level_id = mapping.get('level_id','')
531            code = mapping.get('code','')
[3172]532            key = "%(student_id)s|%(level_id)s|%(code)s" % vars()
533            if self.course_results.getRecordByKey(key) is None:
[3233]534                msg =  "no course result with key %(key)s" % vars()
[3172]535                break
536            self.course_results.deleteRecord(key)
537            break
538        return key,msg,mapping
539    ###)
540###)
541
542class CertificateCourseImport(WAeUPImport):###(
543    name = "certificate_course"
544    plural_name = "%ss" % name
[3741]545    commit_after = 1000
[3219]546    required_modes = ('create','edit')
[3172]547
548    def create(self,mapping):
549        if getattr(self,'_v_courses',None) is None:
550            res = self.courses_catalog()
551            self._v_courses= [course.code for course in res]
552        if getattr(self,'_v_ceritficates',None) is None:
553            res = self.portal_catalog(portal_type = "Certificate")
554            self._v_certificates = {}
555            for cert in res:
556                self._v_certificates[cert.getId] = cert.getObject()
557        msg = ''
558        while True:
559            certificate_course_id = mapping.get('code')
560            if certificate_course_id not in self._v_courses:
[3233]561                msg =  "no course with id: %s" % certificate_course_id
[3172]562                break
563            cert_id = mapping['certificate_code']
564            cert = self._v_certificates.get(cert_id,None)
565            if cert is None:
[3233]566                msg =  "no certificate with id: %s" % cert_id
[3172]567                break
568            level_id = mapping.get('level')
569            level = getattr(cert,level_id,None)
570            if level is None:
571                cert.invokeFactory('StudyLevel', level_id)
572                level = getattr(cert,level_id,None)
573            elif hasattr(level,certificate_course_id):
[3233]574                msg =  "duplicate certificate course id: %(certificate_course_id)s " % vars()
[3172]575                msg += "in %(cert_id)s/ %(level_id)s" % vars()
576                break
577            level.invokeFactory('CertificateCourse', certificate_course_id)
578            c = getattr(level,certificate_course_id)
579            c.getContent().edit(mapping=mapping)
580            break
581        return certificate_course_id,msg,mapping
582    ###)
583
584class DepartmentImport(WAeUPImport):###(
585    name = "department"
586    plural_name = "%ss" % name
[3178]587    commit_after = 1000
[3207]588
[3172]589    def create(self,mapping):###(
590        "create a department in the correct faculty"
[3178]591        faculty_id = mapping['faculty_code']
[3172]592        msg = ''
593        if getattr(self,'_v_faculties',None) is None:
[3549]594            res = self.portal_catalog(portal_type = "Faculty")
[3172]595            self._v_faculties = {}
596            for f in res:
597                self._v_faculties[f.getId] = f.getObject()
[3178]598        department_id = mapping.get('code','')
[3172]599        while True:
[3178]600            faculty = self._v_faculties.get(faculty_id,None)
601            if faculty is None:
[3233]602                msg =  "no faculty with id: %s" % faculty_id
[3172]603                break
604            else:
[3178]605                d = getattr(faculty,department_id,None)
[3172]606                if d is None or d.portal_type == "Faculty":
607                    try:
[3178]608                        faculty.invokeFactory('Department', department_id)
[3172]609                    except BadRequest,E:
610                        msg =  "%s" % E
611                        break
[3178]612                    d = getattr(faculty,department_id)
[3172]613                    d.invokeFactory('CoursesFolder','courses')
614                    courses = getattr(d,'courses')
615                    dict = {'Title': 'Courses'}
616                    courses.getContent().edit(mapping=dict)
617                    d.invokeFactory('CertificatesFolder','certificates')
618                    certificates = getattr(d,'certificates')
619                    dict = {'Title': 'Certificates'}
620                    certificates.getContent().edit(mapping=dict)
621                    d.getContent().edit(mapping=mapping)
622            break
[3178]623        return department_id,msg,mapping
[3172]624    ###)
625
626    def edit(self,mapping): ###(
[3178]627        "edit a department in the correct faculty"
[3172]628        academics_folder = self.portal_url.getPortalObject().campus.academics
[3178]629        faculty_id = mapping['faculty_code']
630        department_id = mapping.get('code','')
[3172]631        msg = ''
632        while True:
633            try:
[3178]634                d = getattr(getattr(academics_folder,faculty_id),department_id,None)
[3172]635            except KeyError:
[3233]636                msg =  "department %s or faculty %s wrong" % (department_id,faculty_id)
[3172]637                break
[3178]638            if d is None or d.portal_type == "Faculty":
[3233]639                msg =  "department %s not found" % (department_id)
[3178]640                break
641            d.getContent().edit(mapping=mapping)
[3172]642            break
[3178]643        return department_id,msg,mapping
[3172]644    ###)
645###)
646
647class FacultyImport(WAeUPImport):###(
648    name = "faculty"
[3177]649    plural_name = "faculties"
[3172]650    commit_after = 100
[3548]651   
[3172]652
653    def create(self,mapping): ###(
654        "create a faculty"
655        academics_folder = self.portal_url.getPortalObject().campus.academics
[3178]656        faculty_id = mapping.get('code','')
[3172]657        msg = ''
658        while True:
[3178]659            if faculty_id in academics_folder.objectIds():
[3233]660                msg =  "faculty with id: %s exists" % faculty_id
[3172]661                break
662            try:
[3178]663                academics_folder.invokeFactory('Faculty', faculty_id)
[3172]664            except BadRequest,E:
665                msg =  "%s" % E
666                break
[3178]667            f = getattr(academics_folder,faculty_id,None)
[3172]668            f.getContent().edit(mapping=mapping)
[3177]669            break
[3178]670        return faculty_id,msg,mapping
[3172]671        ###)
672
673    def edit(self,mapping): ###(
674        "edit a faculty"
675        academics_folder = self.portal_url.getPortalObject().campus.academics
[3178]676        faculty_id = mapping['code']
[3172]677        msg = ''
678        while True:
[3178]679            f = getattr(academics_folder,faculty_id,None)
[3172]680            if f is None:
[3233]681                msg =  "faculty with id: %s does not exist" % faculty_id
[3172]682            f.getContent().edit(mapping=mapping)
[3177]683            break
[3178]684        return faculty_id,msg,mapping
[3172]685    ###)
686###)
687
688class StudentImport(WAeUPImport):###(
689    name = "student"
690    plural_name = "%ss" % name
691    commit_after = 100
[3207]692
[3172]693    field2types_student = {   ###(
694                      'StudentApplication':
695                          {'id': 'application',
[3481]696                           #'title': 'Application Data',
[3172]697                           'wf_transition_return': 'close',
698                           'wf_transition_admit': 'remain',
[3726]699                           'wf_transition_graduate': 'close',
[3738]700                           'wf_transition_pay_school_fee': 'close',
[3820]701                           'wf_transition_validate_courses': 'close',
[3172]702                           'fields':
703                             ('jamb_reg_no',
704                              'entry_mode',
705                              'entry_session',
706                              'jamb_score',
707                              'app_email',
708                              'jamb_age',
709                              'jamb_state',
710                              'jamb_lga',
711                              'jamb_sex',
712                              )
713                              },
714                      #'StudentPume':
715                      #    {'id': 'pume',
716                      #     'title': 'Pume Data',
717                      #     'wf_transition_return': 'close',
718                      #     'wf_transition_admit': 'close',
719                      #     'fields':
720                      #       ('pume_score',
721                      #        )
722                      #        },
723                      'StudentClearance':
724                          {'id': 'clearance',
[3481]725                           #'title': 'Clearance/Eligibility Record',
[3172]726                           'wf_transition_return': 'close',
727                           'wf_transition_admit': 'remain',
[3726]728                           'wf_transition_graduate': 'close',
[3738]729                           'wf_transition_pay_school_fee': 'close',
[3820]730                           'wf_transition_validate_courses': 'close',
[3172]731                           'fields':
732                             ('matric_no',
733                              'nationality',
734                              'lga',
735                              'birthday',
736                              )
737                              },
738                         'StudentPersonal':
739                          {'id': 'personal',
[3481]740                           #'title': 'Personal Data',
[3172]741                           'wf_transition_return': 'open',
742                           'wf_transition_admit': 'remain',
[3726]743                           'wf_transition_graduate': 'close',
[3738]744                           'wf_transition_pay_school_fee': 'open',
[3820]745                           'wf_transition_validate_courses': 'open',
[3172]746                           'fields':
747                             ('firstname',
748                              'middlename',
749                              'lastname',
750                              'sex',
751                              'email',
752                              'phone',
753                              'perm_address',
754                              )
755                              },
756                         'StudentStudyCourse':
757                          {'id': 'study_course',
[3481]758                           #'title': 'Study Course',
[3172]759                           'wf_transition_return': 'open',
760                           'wf_transition_admit': 'remain',
[3726]761                           'wf_transition_graduate': 'close',
[3738]762                           'wf_transition_pay_school_fee': 'open',
[3820]763                           'wf_transition_validate_courses': 'open',
[3172]764                           'fields':
765                             ('study_course',
766                              'current_level',
767                              'current_session',
[3780]768                              'current_mode',  #is no longer used and visible but can still be imported
[3172]769                              'current_verdict',
770                              'previous_verdict',
771                              )
772                              },
773                         # 'StudentStudyLevel':
774                         #  {'id': 'current_level',
775                         #   'title': '',
776                         #   'wf_transition_return': 'open',
777                         #   'wf_transition_admit': 'remain',
778                         #   'fields':
779                         #     ('verdict',
780                         #      'session',
781                         #      )
782                         #      },
783                         'PaymentsFolder':
784                          {'id': 'payments',
[3481]785                           #'title': 'Payments',
[3172]786                           'wf_transition_return': 'open',
787                           'wf_transition_admit': 'open',
[3726]788                           'wf_transition_graduate': 'close',
[3738]789                           'wf_transition_pay_school_fee': 'open',
[3820]790                           'wf_transition_validate_courses': 'open',
[3172]791                           'fields':
792                             ()
793                              },
794                         }
795    ###)
796
797    def create(self,mapping): ###(
798        "create student records due import"
[3726]799        logger = logging.getLogger('WAeUPImport.StudentImport.create')
[3172]800        students_folder = self.portal_url.getPortalObject().campus.students
801        jamb_reg_no = mapping.get('jamb_reg_no',None)
[3185]802        matric_no = mapping.get('matric_no',None)
[3705]803        entry_mode = mapping.get('entry_mode',None)
[3172]804        msg = ''
[3185]805        student_id = mapping.get('id',None)
[3172]806        while True:
[3185]807            if student_id:
808                msg = "student_id must not be specified in create mode"
809                break
[3705]810            if jamb_reg_no and not entry_mode == 'transfer':
[3172]811                res = self.students_catalog(jamb_reg_no = jamb_reg_no)
812                if res:
[3404]813                    msg = "jamb_reg_no already assigned to student %s" % res[0].id
[3172]814                    break
815            if matric_no:
816                res = self.students_catalog(matric_no = matric_no)
817                if res:
[3404]818                    msg = "matric_no already assigned to student %s" % res[0].id
[3172]819                    break
[3208]820            if not matric_no and not jamb_reg_no:
[3185]821                msg = "jamb_reg_no or matric_no must be specified"
822                break
[3172]823            student_id = self.waeup_tool.generateStudentId('?')
824            students_folder.invokeFactory('Student', student_id)
825            student_obj = getattr(students_folder,student_id)
826            f2t = self.field2types_student
827            d = {}
828            transition = mapping.get('reg_transition','admit')
[3984]829            if transition not in ('admit','return','pay_school_fee','validate_courses','graduate'):
[3172]830                msg = "no valid transition provided"
831                break
832            for pt in f2t.keys():
833                student_obj.invokeFactory(pt,f2t[pt]['id'])
834                sub_obj = getattr(student_obj,f2t[pt]['id'])
835                sub_doc = sub_obj.getContent()
[3481]836                #d['Title'] = f2t[pt]['title']
[3172]837                for field in f2t[pt]['fields']:
838                    d[field] = mapping.get(field,'')
[3207]839
[3172]840                if pt == "StudentApplication":
841                    #d['jamb_sex']  = 'M'
842                    #if mapping.get('sex'):
843                    #    d['jamb_sex']  = 'F'
844                    d['jamb_firstname'] = mapping.get('firstname',None)
845                    d['jamb_middlename'] = mapping.get('middlename',None)
846                    d['jamb_lastname'] = mapping.get('lastname',None)
[3207]847
[3172]848                # if pt == "StudyCourse":
849                #     for von,zu in (('entry_mode','current_mode'),
850                #                    ('entry_session','current_session')):
851                #         if mapping.get(zu,None) is None and mapping.get(von,None) is not None:
852                #             d[zu] = mapping[von]
853                sub_doc.edit(mapping = d)
[3207]854
[3172]855                #import pdb;pdb.set_trace()
856                new_state = f2t[pt]['wf_transition_%(transition)s' % vars()]
857                if new_state != "remain":
858                    self.portal_workflow.doActionFor(sub_obj,new_state,dest_container=sub_obj)
859            self.portal_workflow.doActionFor(student_obj,transition)
860            student_obj.manage_setLocalRoles(student_id, ['Owner',])
[3179]861            mapping['id'] = student_id
[3172]862            break
863        return student_id,msg,mapping
864    ###)
865
[3822]866    def remove(self,mapping): ###(
867        "remove student records due import"
868        logger = logging.getLogger('WAeUPImport.StudentImport.remove')
869        students_folder = self.portal_url.getPortalObject().campus.students
870        stdir = self.portal_directories.students
871        student_id = mapping.get('id',None)
872        msg = ''
873        export_file = "%s/export/students_removed.csv" % (i_home)
[3984]874        reimport_file = "%s/export/students_for_reimport.csv" % (i_home)
[3822]875       
[3984]876        toexport_for_reimport = {
877       
878                    'personal': 
879                             ('firstname',
880                              'middlename',
881                              'lastname',
882                              'sex',
883                              'email',
884                              'phone',
885                              'perm_address',
886                              ),
887                    'clearance':
888                              ('matric_no',
889                              'nationality',
890                              'lga',
891                              'birthday',
892                              ),
893                    'application':
894                             ('jamb_reg_no',
895                              'entry_mode',
896                              'entry_session',
897                              'jamb_score',
898                              'app_email',
899                              'jamb_age',
900                              'jamb_state',
901                              'jamb_lga',
902                              'jamb_sex',
903                              ),
904                    'study_course':
905                              ('study_course',
906                              'current_level',
907                              'current_session',
908                              'current_verdict',
909                              'previous_verdict',
910                              )
911                   }
[3842]912
[3863]913        sub_types = ['StudentApplication','StudentClearance','StudentPersonal','StudentStudyCourse']
[3842]914        non_image_keys = {}
915        for i in sub_types:
916            pt_ob = getattr(self.types_tool,i)
917            sub_schemas = pt_ob.schemas
918            for i in sub_schemas:
919                if i.startswith('student_'):
920                    schema = getattr(self.schema_tool,i)
921                    field_id = i.replace('student_','')
922                    non_image_keys[field_id] = [key for key in schema.keys()
923                                     if schema[key].meta_type != "CPS Image Field"]       
924        toexport = non_image_keys
925
926        #import pdb;pdb.set_trace()   
[3822]927        while True:
928            if hasattr(students_folder,student_id):
929                # begin export
930                line = []
[3984]931                fields = ['student_id','reg_state','password']
932                line_for_reimport = []
933                fields_for_reimport = ['student_id','reg_state','password','import_mode']               
934                #fields = []
935                #for f in self.students_catalog.schema():
936                #    fields.append(f)               
[3822]937                for k in toexport.keys():
938                    for f in toexport[k]:
939                        fields.append(f)
[3984]940                for k in toexport_for_reimport.keys():
941                    for f in toexport_for_reimport[k]:
942                        fields_for_reimport.append(f)                       
[3842]943                if True:    #not os.path.exists(export_file):       
[3822]944                    headline = ','.join(fields)
945                    open(export_file,"a").write(headline +'\n')
[3984]946                    headline_for_reimport = ','.join(fields_for_reimport)                   
947                    open(reimport_file,"a").write(headline_for_reimport +'\n')                   
[3822]948                format = '"%(' + ')s","%('.join(fields) + ')s"'
[3984]949                format_for_reimport = '"%(' + ')s","%('.join(fields_for_reimport) + ')s"'
[3822]950                res = self.students_catalog(id = student_id)
951                student = res[0]
952                student_obj = getattr(students_folder,student_id)
[3984]953                #d = student.getFormattedStudentEntry(student)
954                d = {'student_id':student_id,'reg_state':student.review_state,'import_mode':'create'}
[3822]955                for k in toexport.keys()[0:]:
956                    try:
957                        object = getattr(student_obj,k)
958                        object_doc = object.getContent()
959                    except:
960                        continue
961                    for f in toexport[k]:
962                        d[f] = getattr(object_doc,f,'')
[3863]963                if hasattr(stdir, student_id):
964                    d['password'] = self.waeup_tool.getCredential(student_id)
965                    stdir.deleteEntry(student_id)
966                self.waeup_tool.removePictureFolder(student_id)       
[3822]967                line.append(format % d)
968                open(export_file,"a").write('\n'.join(line) +'\n')
[3984]969                line_for_reimport.append(format_for_reimport % d)
970                open(reimport_file,"a").write('\n'.join(line_for_reimport) +'\n')               
[3841]971                self.course_results.getExportRemoveAllCourses(student_id = student_id, export = True, remove = True)
[3984]972#                self.course_results.getExportRemoveAllCourses(student_id = student_id, export = True, remove = False)
973                self.payments_catalog.getExportRemoveAllPayments(student_id = student_id, export = True, remove = True)
974#                self.payments_catalog.getExportRemoveAllPayments(student_id = student_id, export = True, remove = False)
975                self.waeup_tool.exportAllStudyLevels(student_id = student_id)
[3822]976                # end export
977                students_folder.manage_delObjects((student_id),)         
978            else:
979                msg = "Student object not found"
980                break
[3863]981     
[3822]982            break
983        return student_id,msg,mapping     
984
985
[3179]986    def edit(self,mapping): ###(
[3402]987        "edit student records due import"
[3172]988        wftool = self.portal_workflow
[3726]989        logger = logging.getLogger('WAeUPImport.StudentImport.edit')
[3172]990        students_folder = self.portal_url.getPortalObject().campus.students
991        student_id = mapping.get('id',None)
992        jamb_reg_no = mapping.get('jamb_reg_no',None)
993        matric_no = mapping.get('matric_no',None)
994        editable_keys = mapping.keys()
995        msg = ''
996        while True:
997            if student_id:
998                res = self.students_catalog(id = student_id)
999                if not res:
1000                    msg = "no student with id %s" % student_id
1001                    break
1002                student_record = res[0]
1003                if matric_no and student_record.matric_no:
[3705]1004                    if  matric_no != student_record.matric_no and not matric_no == 'transferred':
[3402]1005                        res = self.students_catalog(matric_no = matric_no)
1006                        if res:
[3404]1007                            msg = "matric_no already assigned to student %s" % res[0].id
[3402]1008                            break
[3172]1009                        msg = "old matric_no %s overwritten with %s" % (student_record.matric_no,matric_no)
1010                        #logger.info("%s, old matric_no %s overwritten with %s" % (student_record.id,student_record.matric_no,matric_no))
1011                if jamb_reg_no and student_record.jamb_reg_no:
1012                    if jamb_reg_no != student_record.jamb_reg_no:
[3404]1013                        res = self.students_catalog(jamb_reg_no = jamb_reg_no)
1014                        if res:
1015                            msg = "jamb_reg_no already assigned to student %s" % res[0].id
[3431]1016                            break
[3404]1017                        msg = "old jamb_reg_no %s overwritten with %s" % (student_record.jamb_reg_no,jamb_reg_no)
[3172]1018                        #logger.info("%s, old reg_no %s overwritten with %s" % (student_record.id,student_record.jamb_reg_no,jamb_reg_no))
1019            elif jamb_reg_no:
1020                res = self.students_catalog(jamb_reg_no = jamb_reg_no)
1021                if not res:
1022                    msg = "no student with jamb_reg_no %s" % jamb_reg_no
1023                    break
1024                student_record = res[0]
1025                editable_keys.remove('jamb_reg_no')
1026            elif matric_no:
1027                res = self.students_catalog(matric_no = matric_no)
1028                if not res:
1029                    msg = "no student with matric_no %s" % matric_no
1030                    break
1031                student_record = res[0]
1032                editable_keys.remove('matric_no')
1033            student_id = student_record.id
1034            student_obj = getattr(students_folder,student_id)
1035            f2t = self.field2types_student
1036            d = {}
1037            any_change = False
1038            #special treatment for StudentStudyLevel
1039            d['verdict']  = mapping.get('current_verdict','')
1040            d['session']  = mapping.get('current_session','')
1041            current_level = mapping.get('current_level','')
[3726]1042            transition = mapping.get('reg_transition',None)
[3820]1043            # the validate_courses import transition is not really useful because it does not execute validate_courses.py
1044            if transition and transition not in ('admit','return','graduate','pay_school_fee','validate_courses'):
[3726]1045                msg = "no valid transition provided"
1046                break     
[3172]1047            while d['session'] and d['verdict'] and current_level:
1048                sub_obj = getattr(student_obj,'study_course',None)
1049                if sub_obj is None:
1050                    break
1051                level_obj = getattr(sub_obj,current_level,None)
1052                if  level_obj is None:
1053                    break
1054                any_change = True
1055                level_obj.getContent().edit(mapping = d)
1056                try:
1057                    wftool.doActionFor(level_obj,'close')
1058                except:
1059                    pass
1060                break
[3726]1061           
[3172]1062            for pt in f2t.keys():
1063                #if pt == "StudentApplication":
1064                #    d['jamb_sex']  = 'M'
1065                #    if mapping.get('sex'):
1066                #        d['jamb_sex']  = 'F'
1067                intersect = set(f2t[pt]['fields']).intersection(set(editable_keys))
[3726]1068                #import pdb;pdb.set_trace()
1069                object_id = f2t[pt]['id']
1070                sub_obj = getattr(student_obj,object_id,None)
[3172]1071                if intersect and pt not in ('StudentStudyLevel',):
1072                    if sub_obj is None:
1073                        try:
1074                            student_obj.invokeFactory(pt,object_id)
1075                        except:
1076                            continue
1077                        sub_obj = getattr(student_obj,object_id)
[3481]1078                        #if f2t[pt]['title'] != '':
1079                        #    d['Title'] = f2t[pt]['title']
[3172]1080                    sub_doc = sub_obj.getContent()
1081                    for field in intersect:
1082                        changed = False
1083                        if getattr(sub_doc,field,None) != mapping.get(field,''):
1084                            any_change = True
1085                            changed = True
1086                            d[field] = mapping.get(field,'')
1087                        if changed:
1088                            sub_doc.edit(mapping = d)
[3726]1089                if transition:
1090                    new_state = f2t[pt]['wf_transition_%(transition)s' % vars()]
1091                    if new_state != "remain":
1092                        try:
1093                            self.portal_workflow.doActionFor(sub_obj,new_state,dest_container=sub_obj)
1094                        except:
1095                            pass
1096            if transition:
1097                try:
1098                    self.portal_workflow.doActionFor(student_obj,transition)
1099                except:
1100                    msg = "reg_transition not allowed"
[3172]1101            break
1102        return student_id,msg,mapping
1103    ###)
[3179]1104###)
[3172]1105
[3372]1106class StudentStudyLevelImport(WAeUPImport):###(
1107    """ StudentStudyLevelImport """
1108    name = "student_study_level"
1109    plural_name = "%ss" % name
1110    commit_after = 1000000
1111    required_modes = ('create',)
1112
[3381]1113    def create(self,mapping): ###(
[3372]1114        "edit student levels and create StudentStudyLevel object if not existent"
1115        wftool = self.portal_workflow
1116        logger = logging.getLogger('WAeUPTool.mass_create_level')
1117        students_folder = self.portal_url.getPortalObject().campus.students
1118        student_id = mapping.get('id',None)
1119        matric_no = mapping.get('matric_no',None)
1120        editable_keys = mapping.keys()
1121        key = ''
1122        msg = ''
1123        while True:
1124            result = self.findStudent('create',student_id=student_id,matric_no=matric_no)
1125            msg = result['msg']
1126            if msg:
1127                break
1128            student_record = result['student_record']
1129            student_id = student_record.id
1130            mapping['id'] = student_id
1131            session = mapping.get('session','')
1132            level = key = mapping.get('code','')
1133            if not level.isdigit():
1134                msg = 'student %s: imported level is empty' % (student_id,)
1135                break
[3381]1136            study_course_obj = getattr(getattr(students_folder,student_id),'study_course',None)
[3372]1137            if study_course_obj is None:
1138                msg = 'student %s: no study_course object' % student_id
1139                break
1140            level_obj = getattr(study_course_obj,level,None)
1141            if  level_obj is None:
1142                # The only difference to the edit method is that we create a StudentStudyLevel object
1143                try:
1144                    study_course_obj.invokeFactory('StudentStudyLevel',"%s" % level)
1145                    level_obj = getattr(context,"%s" % level)
1146                except:
1147                    continue
1148            level_obj.getContent().edit(mapping = mapping)
1149            level_review_state = wftool.getInfoFor(level_obj,'review_state',None)
1150            if level_review_state != "closed":
1151                wftool.doActionFor(level_obj,'close')
1152            break
1153        return key,msg,mapping
1154    ###)
1155
1156    def edit(self,mapping): ###(
1157        "edit student levels"
1158        wftool = self.portal_workflow
1159        logger = logging.getLogger('WAeUPTool.mass_edit_level')
1160        students_folder = self.portal_url.getPortalObject().campus.students
1161        student_id = mapping.get('id',None)
1162        matric_no = mapping.get('matric_no',None)
1163        key = ''
1164        msg = ''
1165        while True:
1166            result = self.findStudent('create',student_id=student_id,matric_no=matric_no)
1167            msg = result['msg']
1168            if msg:
1169                break
1170            student_record = result['student_record']
1171            student_id = student_record.id
1172            mapping['id'] = student_id
[3381]1173            session = mapping.get('session','')
1174            level = key = mapping.get('code','')
[3372]1175            #import pdb;pdb.set_trace()
1176            if not level.isdigit():
1177                msg = 'student %s: imported level is empty' % (student_id,)
1178                break
[3381]1179            study_course_obj = getattr(getattr(students_folder,student_id),'study_course',None)
[3372]1180            if study_course_obj is None:
1181                msg = 'student %s: no study_course object' % student_id
1182                break
1183            level_obj = getattr(study_course_obj,level,None)
1184            if  level_obj is None:
1185                msg = 'student %s: no study_level object for level %s' % (student_id,level)
1186                break
1187            level_obj.getContent().edit(mapping = mapping)
1188            break
1189        return key,msg,mapping
1190    ###)
[3381]1191###)
[3372]1192
[3172]1193class VerdictImport(WAeUPImport):###(
1194    """ VerdictImport """
1195    name = "verdict"
1196    plural_name = "%ss" % name
[3977]1197    commit_after = 1000
[3172]1198    required_modes = ('create','edit')
[3249]1199
[3372]1200    def create(self,mapping): ###(
[3243]1201        "edit student verdicts and create StudentStudyLevel object if not existent"
1202        wftool = self.portal_workflow
1203        logger = logging.getLogger('WAeUPTool.mass_edit_verdict')
1204        students_folder = self.portal_url.getPortalObject().campus.students
1205        student_id = mapping.get('id',None)
1206        matric_no = mapping.get('matric_no',None)
1207        editable_keys = mapping.keys()
[3372]1208        key = ''
[3243]1209        while True:
[3372]1210            result = self.findStudent('create',student_id=student_id,matric_no=matric_no)
1211            #student_record,msg = self.getStudentRecord(mapping)
1212            msg = result['msg']
1213            if msg:
1214                break
1215            student_record = result['student_record']
1216            student_id = student_record.id
1217            mapping['id'] = student_id
1218            d = {}
1219            #import pdb;pdb.set_trace()
1220            any_change = False
1221            #special treatment for StudentStudyLevel
1222            current_session = d['session'] = mapping.get('current_session','')
1223            if current_session and student_record.session != current_session:
1224                msg = 'student %s: imported session %s does not match current_session %s' % (student_id,
1225                                                                                            current_session,
1226                                                                                            student_record.session)
1227                break
1228            current_level = mapping.get('current_level','')
1229            if not current_level.isdigit():
1230                msg = 'student %s: imported level is empty' % (student_id,)
1231                break
1232            if current_level and student_record.level != current_level:
1233                msg = 'student %s: imported level %s does not match current_level %s' % (student_id,
1234                                                                                        current_level,
1235                                                                                        student_record.level)
1236                break
1237            student_review_state =  student_record.review_state
1238            if student_review_state == 'deactivated':
1239                msg = "student %s in review_state %s" % (student_id, student_review_state)
1240                break
1241            if student_review_state not in ('courses_validated','returning'):
1242                msg = "student %s in wrong review_state %s" % (student_id, student_review_state)
1243                break
1244            student_obj = getattr(students_folder,student_id)
1245            # f2t = self.field2types_student
1246            study_course_obj = getattr(student_obj,'study_course',None)
1247            if study_course_obj is None:
1248                msg = 'student %s: no study_course object' % student_id
1249                break
1250            level_obj = getattr(study_course_obj,current_level,None)
1251
1252            if  level_obj is None:
1253                # The only difference to the edit method is that we create a StudentStudyLevel object
1254                try:
1255                    study_course_obj.invokeFactory('StudentStudyLevel',"%s" % current_level)
1256                    level_obj = getattr(context,"%s" % current_level)
1257                    level_obj.portal_workflow.doActionFor(level,'open')
1258                except:
1259                    continue
1260                #msg = 'student %s: no study_level object for level %s' % (student_id,
1261                #                                                                current_level)
1262                #break
1263
1264            verdict = d['verdict'] = d['current_verdict']  = mapping.get('current_verdict','')
1265
1266            #if verdict == student_record.verdict:
1267            #    msg = 'student %s: verdict already set to %s' % (student_id,
1268            #                                                            verdict)
1269
1270            level_review_state = wftool.getInfoFor(level_obj,'review_state',None)
1271            if level_review_state != "closed":
1272                wftool.doActionFor(level_obj,'close')
1273                # msg = 'student %s: level %s is not closed' % (student_id,
1274                #                                                      current_level)
1275
1276            study_course_obj.getContent().edit(mapping = d)
1277            level_obj.getContent().edit(mapping = d)
1278            if student_review_state != "returning":
1279                wftool.doActionFor(student_obj,'return')
1280            # try:
1281            #     wftool.doActionFor(level_obj,'close')
1282            # except:
1283            #     pass
1284            break
1285        return student_id,msg,mapping
1286    ###)
1287
[3207]1288
[3372]1289    def edit(self,mapping): ###(
1290        "edit student verdicts"
1291        wftool = self.portal_workflow
1292        logger = logging.getLogger('WAeUPTool.mass_edit_verdict')
1293        students_folder = self.portal_url.getPortalObject().campus.students
1294        student_id = mapping.get('id',None)
1295        matric_no = mapping.get('matric_no',None)
1296        editable_keys = mapping.keys()
1297        key = ''
1298        while True:
1299            result = self.findStudent('edit',student_id=student_id,matric_no=matric_no)
1300            #student_record,msg = self.getStudentRecord(mapping)
1301            msg = result['msg']
1302            if msg:
1303                break
1304            student_record = result['student_record']
1305            key_used = result['key_used']
[3375]1306            if key_used in editable_keys:
[3374]1307                editable_keys.remove(key_used)
[3372]1308            student_id = student_record.id
1309            mapping['id'] = student_id
1310            d = {}
1311            #import pdb;pdb.set_trace()
1312            any_change = False
1313            #special treatment for StudentStudyLevel
1314            current_session = d['session'] = mapping.get('current_session','')
1315            if current_session and student_record.session != current_session:
1316                msg = 'student %s: imported session %s does not match current_session %s' % (student_id,
1317                                                                                            current_session,
1318                                                                                            student_record.session)
1319                break
1320            current_level = mapping.get('current_level','')
1321            if not current_level.isdigit():
1322                msg = 'student %s: imported level is empty' % (student_id,)
1323                break
1324            if current_level and student_record.level != current_level:
1325                msg = 'student %s: imported level %s does not match current_level %s' % (student_id,
1326                                                                                        current_level,
1327                                                                                        student_record.level)
1328                break
1329            student_review_state =  student_record.review_state
1330            if student_review_state == 'deactivated':
1331                msg = "student %s in review_state %s" % (student_id, student_review_state)
1332                break
1333            if student_review_state not in ('courses_validated','returning'):
1334                msg = "student %s in wrong review_state %s" % (student_id, student_review_state)
1335                break
1336            student_obj = getattr(students_folder,student_id)
1337            # f2t = self.field2types_student
1338            study_course_obj = getattr(student_obj,'study_course',None)
1339            if study_course_obj is None:
1340                msg = 'student %s: no study_course object' % student_id
1341                break
1342            level_obj = getattr(study_course_obj,current_level,None)
1343            if  level_obj is None:
1344                msg = 'student %s: no study_level object for level %s' % (student_id,
1345                                                                                current_level)
1346                break
1347            verdict = d['verdict'] = d['current_verdict']  = mapping.get('current_verdict','')
[3243]1348
[3372]1349            #if verdict == student_record.verdict:
1350            #    msg = 'student %s: verdict already set to %s' % (student_id,
1351            #                                                            verdict)
1352
1353            level_review_state = wftool.getInfoFor(level_obj,'review_state',None)
1354            if level_review_state != "closed":
1355                wftool.doActionFor(level_obj,'close')
1356                # msg = 'student %s: level %s is not closed' % (student_id,
1357                #                                                      current_level)
1358
1359            study_course_obj.getContent().edit(mapping = d)
1360            level_obj.getContent().edit(mapping = d)
1361            if student_review_state != "returning":
1362                wftool.doActionFor(student_obj,'return')
1363            # try:
1364            #     wftool.doActionFor(level_obj,'close')
1365            # except:
1366            #     pass
1367            break
1368        return student_id,msg,mapping
1369    ###)
1370
1371    def edit_old(self,mapping): ###(
[3172]1372        "edit student verdicts"
1373        wftool = self.portal_workflow
1374        logger = logging.getLogger('WAeUPTool.mass_edit_verdict')
1375        students_folder = self.portal_url.getPortalObject().campus.students
1376        student_id = mapping.get('id',None)
1377        matric_no = mapping.get('matric_no',None)
1378        editable_keys = mapping.keys()
[3372]1379        key = ''
[3172]1380        while True:
1381            msg = ''
1382            if student_id:
1383                student_record = self.students_catalog.getRecordByKey(student_id)
1384                if student_record is None:
1385                    #return '',"no student with id %s" % student_id
1386                    msg = "no student with id %s" % student_id
1387                    break
1388                if matric_no and student_record.matric_no and matric_no != student_record.matric_no:
1389                    msg = 'student %s: matric_no %s does not match %s' % (student_record.id,
1390                                                                          student_record.matric_no,
1391                                                                          matric_no)
1392                    break
1393                mapping['matric_no'] = student_record.matric_no
1394            elif matric_no:
1395                res = self.students_catalog(matric_no = matric_no)
1396                if not res:
1397                    msg = "no student with matric_no %s" % matric_no
1398                    break
1399                student_record = res[0]
1400                editable_keys.remove('matric_no')
1401            else:
1402                msg = "no id or matric_no specified"
1403                break
1404            student_id = student_record.id
1405            mapping['id'] = student_id
1406            d = {}
1407            #import pdb;pdb.set_trace()
1408            any_change = False
1409            #special treatment for StudentStudyLevel
1410            current_session = d['session'] = mapping.get('current_session','')
1411            if current_session and student_record.session != current_session:
1412                msg = 'student %s: imported session %s does not match current_session %s' % (student_id,
1413                                                                                            current_session,
1414                                                                                            student_record.session)
1415                break
1416            current_level = mapping.get('current_level','')
1417            if not current_level.isdigit():
1418                msg = 'student %s: imported level is empty' % (student_id,)
1419                break
1420            if current_level and student_record.level != current_level:
1421                msg = 'student %s: imported level %s does not match current_level %s' % (student_id,
1422                                                                                        current_level,
1423                                                                                        student_record.level)
1424                break
1425            student_review_state =  student_record.review_state
1426            if student_review_state == 'deactivated':
1427                msg = "student %s in review_state %s" % (student_id, student_review_state)
1428                break
1429            if student_review_state not in ('courses_validated','returning'):
1430                msg = "student %s in wrong review_state %s" % (student_id, student_review_state)
1431                break
1432            student_obj = getattr(students_folder,student_id)
1433            # f2t = self.field2types_student
1434            study_course_obj = getattr(student_obj,'study_course',None)
1435            if study_course_obj is None:
1436                msg = 'student %s: no study_course object' % student_id
1437                break
1438            level_obj = getattr(study_course_obj,current_level,None)
1439            if  level_obj is None:
1440                msg = 'student %s: no study_level object for level %s' % (student_id,
1441                                                                                current_level)
1442                break
1443            verdict = d['verdict'] = d['current_verdict']  = mapping.get('current_verdict','')
[3207]1444
[3172]1445            #if verdict == student_record.verdict:
1446            #    msg = 'student %s: verdict already set to %s' % (student_id,
1447            #                                                            verdict)
[3207]1448
[3172]1449            level_review_state = wftool.getInfoFor(level_obj,'review_state',None)
1450            if level_review_state != "closed":
1451                wftool.doActionFor(level_obj,'close')
1452                # msg = 'student %s: level %s is not closed' % (student_id,
1453                #                                                      current_level)
[3207]1454
[3172]1455            study_course_obj.getContent().edit(mapping = d)
1456            level_obj.getContent().edit(mapping = d)
1457            if student_review_state != "returning":
1458                wftool.doActionFor(student_obj,'return')
1459            # try:
1460            #     wftool.doActionFor(level_obj,'close')
1461            # except:
1462            #     pass
1463            break
1464        return student_id,msg,mapping
1465    ###)
[3372]1466###)
Note: See TracBrowser for help on using the repository browser.