source: WAeUP_SRP/trunk/WAeUPImport.py @ 4543

Last change on this file since 4543 was 4531, checked in by Henrik Bettermann, 15 years ago

restore picture () folder if student id is given (not yet tested)

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