source: WAeUP_SRP/trunk/WAeUPTool.py @ 1771

Last change on this file since 1771 was 1759, checked in by Henrik Bettermann, 18 years ago

makeStudentData must not change catalog
makeStudentData must set current_session

  • Property svn:keywords set to Id
File size: 34.4 KB
RevLine 
[197]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: WAeUPTool.py 1759 2007-05-08 21:43:38Z henrik $
[1174]20"""The WAeUP Tool Box.
[197]21"""
22
23from AccessControl import ClassSecurityInfo
[828]24from Acquisition import aq_inner
25from Acquisition import aq_parent
26from Globals import DTMLFile
27from Globals import InitializeClass
28from OFS.SimpleItem import SimpleItem
[197]29
[1747]30from Products.CPSSchemas.DataStructure import DataStructure
31from Products.CPSSchemas.DataModel import DataModel
32from Products.CPSSchemas.StorageAdapter import MappingStorageAdapter
[828]33from Products.CMFCore.ActionProviderBase import ActionProviderBase
34from Products.CMFCore.permissions import View
35from Products.ZCatalog.ZCatalog import ZCatalog
36from Products.CMFCore.permissions import ModifyPortalContent
[197]37from Products.CMFCore.utils import UniqueObject
[1194]38from Products.CMFCore.URLTool import URLTool
[1747]39from Products.CMFCore.utils import getToolByName
[1151]40from Students import makeCertificateCode
[1285]41from Globals import package_home,INSTANCE_HOME
42p_home = package_home(globals())
43i_home = INSTANCE_HOME
[1620]44import DateTime
45import logging
[1170]46import transaction
[1620]47import csv,re,os
[1707]48from Products.AdvancedQuery import Eq, Between, Le,In
[197]49
[1707]50def getObject(object,name):
51    if object.hasObject(name):
52        return getattr(object,name)
53    return None
[1720]54
[828]55class WAeUPTool(UniqueObject, SimpleItem, ActionProviderBase):
[197]56    """WAeUP tool"""
57
[828]58    id = 'waeup_tool'
[197]59    meta_type = 'WAeUP Tool'
[828]60    _actions = ()
[197]61
62    security = ClassSecurityInfo()
[828]63    security.declareObjectProtected(View)
[197]64
[828]65    manage_options = ( ActionProviderBase.manage_options
66                     + SimpleItem.manage_options
67                     )
68
[1707]69    def rwrite(self,s):
70        response = self.REQUEST.RESPONSE
71        response.setHeader('Content-type','text/html; charset=ISO-8859-15')
72        response.write("%s<br />\r\n" % s)
[1174]73
[1720]74    security.declareProtected(ModifyPortalContent,'openLog')
[1716]75    def openLog(self,name):
76        """open a log file"""
77        version = 1
78        path = "%s/log/%s_%d.log" % (i_home,name,version)
79        while os.path.exists(path):
80            version += 1
81            path = "%s/log/%s_%d.log" % (i_home,name,version)
82        log = open(path,"w")
83        return log
84
[1720]85    security.declareProtected(ModifyPortalContent,'writeLog')
[1716]86    def writeLog(self,logfile,s):
87        """write to the log file"""
88        logfile.write(s)
89
[1720]90
[1151]91    def generateStudentId(self,letter): ###(
92        import random
93        r = random
[1194]94        ##if letter not in ('ABCDEFGIHKLMNOPQRSTUVWXY'):
95        if letter == '?':
[1151]96            letter= r.choice('ABCDEFGHKLMNPQRSTUVWXY')
97        sid = "%c%d" % (letter,r.randint(99999,1000000))
[1720]98        students = self.portal_url.getPortalObject().campus.students
[1721]99##        while hasattr(students, sid):
100##            sid = "%c%d" % (letter,r.randint(99999,1000000))
101        while self.students_catalog(id = sid):
[1720]102            sid = "%c%d" % (letter,r.randint(99999,1000000))
[1151]103        return sid
[1460]104    ###)
[1415]105
106    def generatePassword(self,s=None): ###(
107        import random
108        r = random
109        ##if letter not in ('ABCDEFGIHKLMNOPQRSTUVWXY'):
110        if s is None:
111            s = 'abcdefghklmnpqrstuvwxy23456789'
112        pw = ''
113        while len(pw) < 6:
114            pw += r.choice(s)
115        return pw
[1151]116    ###)
[828]117
[1261]118    security.declareProtected(ModifyPortalContent,'getCredential') ###(
[1250]119    def getCredential(self,student_id):
120        "return a student password"
121        student_entry = getattr(self.portal_directories.students,student_id,None)
122        if student_entry is None:
123            return None
[1263]124        return getattr(student_entry,"password","not set")
[1261]125    ###)
[1250]126
[1460]127    security.declarePublic('checkPassword') ###(
[1467]128    def checkPassword(self,student_id,password):
[1460]129        "return a student password"
130        student_entry = getattr(self.portal_directories.students,student_id,None)
131        if student_entry is None:
132            return False
133        return getattr(student_entry,"password","not set") == password
134    ###)
135
[1467]136    security.declarePublic('editPassword') ###(
137    def editPassword(self,student_id,password):
138        "edit a student password"
139        student_entry = getattr(self.portal_directories.students,student_id,None)
140        if student_entry is None:
[1571]141            return
[1467]142        setattr(student_entry,'password',password)
143    ###)
144
[1647]145    security.declareProtected(View,'doCommit') ###(
[1401]146    def doCommit(self,logger=None):
147        "commit some transactions"
148        transaction.commit()
149    ###)
150
[1285]151    security.declarePublic('loadStudentFoto') ###(
152    def loadStudentFoto(self,student):
153        "return a student passport picture"
154        app_doc = student.application.getContent()
155        clear = student.clearance
156        clear_doc = clear.getContent()
157        matric_no = clear_doc.matric_no.upper()
[1286]158        picture1 ="%s/import/pictures_returning/%s.jpg" % (i_home,matric_no)
159        picture2 ="%s/import/pictures_returning/%s.JPG" % (i_home,matric_no)
[1285]160        #import pdb;pdb.set_trace()
[1286]161        if os.path.exists(picture1):
162            file = open(picture1)
163        elif os.path.exists(picture2):
[1287]164            file = open(picture2)
[1286]165        else:
[1287]166            return "passport picture not found %s" % picture1
[1286]167
[1285]168        outfile = file.read()
169        app_doc.manage_addFile('passport',
170                               file=outfile,
171                               title="%s.jpg" % matric_no)
[1286]172        return "successfully loaded passport picture"
[1285]173    ###)
174
[1170]175    security.declareProtected(ModifyPortalContent,'createOne') ###(
[1194]176    def createOne(self,students_folder,student_brain,letter,commit=False):
177        sid = self.waeup_tool.generateStudentId(letter)
[1170]178        students_folder.invokeFactory('Student', sid)
179        student = getattr(students_folder,sid)
180        self.portal_workflow.doActionFor(student,'return')
181        student.manage_setLocalRoles(sid, ['Owner',])
182        matric_no = student_brain.matric_no
183        jamb_reg_no = student_brain.Entryregno
184        self.students_catalog.addRecord(id = sid,
185                                           matric_no = matric_no,
186                                           jamb_reg_no = jamb_reg_no,
187                                           sex = student_brain.Sex == "F",
188                                           name = "%s %s %s" % (student_brain.Firstname,
189                                                                student_brain.Middlename,
190                                                                student_brain.Lastname)
191                                        )
192        if commit:
193            transaction.commit()
194        return sid,jamb_reg_no
195    ###)
196
[1752]197    security.declareProtected(ModifyPortalContent,'addStudent') ###(
198    def addStudent(self,dict):
[1415]199        students_folder = self.portal_url.getPortalObject().campus.students
200        sid = self.waeup_tool.generateStudentId('?')
201        students_folder.invokeFactory('Student', sid)
202        student_obj = getattr(students_folder,sid)
203        password = self.generatePassword()
204        self.makeStudentMember(sid,password)
[1728]205        f2t = self.student_field2types
206        for pt in f2t.keys():
207            student_obj.invokeFactory(pt,f2t[pt]['id'])
208            sub_obj = getattr(student_obj,f2t[pt]['id'])
209            sub_doc = sub_obj.getContent()
210            self.portal_workflow.doActionFor(sub_obj,'open',dest_container=sub_obj)
211            d = {'Title': f2t[pt]['title']}
212            for field in f2t[pt]['fields']:
[1749]213                d[field] = dict.get(field,'')
[1728]214            if pt == 'StudentPersonal':
215                d['sex'] = dict.get('sex') == 'F'
216            sub_doc.edit(mapping = d)
217            self.portal_workflow.doActionFor(sub_obj,'close',dest_container=sub_obj)
[1749]218
[1728]219        entry_session = dict.get('entry_session')
[1415]220        wfaction = 'return'
[1728]221        if entry_session == self.getSessionId():
[1415]222            wfaction = 'admit'
223        self.portal_workflow.doActionFor(student_obj,wfaction)
224        student_obj.manage_setLocalRoles(sid, ['Owner',])
225        return sid,password
226    ###)
227
[1151]228    security.declarePublic('getCertificateBrain') ###(
229    def getCertificateBrain(self,cert_id):
230        "do it"
231        res = ZCatalog.searchResults(self.portal_catalog,
232                                {'portal_type':"Certificate",
233                                      'id': cert_id})
234        if res:
235            return res[0]
236        return None
237    ###)
[1160]238
[1756]239    security.declareProtected(ModifyPortalContent,'get_csv_filenames') ###(
240    def get_csv_filenames(self):
241        "do it"
[1759]242        files = [file for file in os.listdir("%s/import/" % (i_home))
[1756]243                 if file.endswith('.csv') and file.find('imported') == -1]
244        return files
245    ###)
246
[1151]247    security.declarePublic('findStudentByMatricelNo') ###(
248    def findStudentByMatricelNo(self,matric_no):
249        "do it"
250        res = ZCatalog.searchResults(self.portal_catalog,
251                                {'portal_type':"StudentClearance",
252                                 'SearchableText': matric_no})
253        if res:
254            return res[0]
255        return None
256    ###)
257
258    security.declarePublic('makeStudentMember') ###(
259    def makeStudentMember(self,sid,password='uNsEt'):
260        """make the student a member"""
261        membership = self.portal_membership
262        membership.addMember(sid,
263                             password ,
264                             roles=('Member',
265                                     'Student',
266                                     ),
267                             domains='',
268                             properties = {'memberareaCreationFlag': False,
269                                           'homeless': True},)
270        member = membership.getMemberById(sid)
271        self.portal_registration.afterAdd(member, sid, password, None)
[1261]272        #self.manage_setLocalRoles(sid, ['Owner',])
[1151]273    ###)
[1160]274
[1151]275    security.declarePublic('makeStudentData') ###(
[1158]276    def makeStudentData(self,student_id,email=None,phone_nr=None):
[1151]277        "create Datastructure for a returning Student"
[1406]278        #import pdb;pdb.set_trace()
[1571]279        logger = logging.getLogger('WAeUPTool.makeStudentData')
[1151]280        students_folder = self.portal_url.getPortalObject().campus.students
281        res = self.students_catalog(id=student_id)
282        if res:
283            st = res[0]
284        res = self.returning_import(matric_no = st.matric_no)
285        if res:
[1160]286            student = res[0]
[1580]287        logger.info('%s creates data structure' % student_id)
[1401]288        s_results = self.results_import(matric_no = st.matric_no)
289        lnr = self.getLevelFromResultsCosCode(s_results)
290        level = "%d00" % lnr
[1695]291        verdict,eligible = self.getVerdict(s_results[0].Verdict)
292        if eligible:
[1401]293            level = "%d00" % (lnr + 1)
294##        level = s_results[0].Level
295##        for result in s_results:
296##            if level != result.Level:
297##                logger.info('"%s", "Levels differ","%s != %s"' % (student_id,level,result.Level))
[1171]298        #student should not be allowed to perform this transition
[1174]299        #wftool = self.portal_workflow
300        #wftool.doActionFor(student,'return')
[1151]301        certcode_org = student.Coursemajorcode
302        certcode = makeCertificateCode(certcode_org)
303        certificate_brain = self.getCertificateBrain(certcode)
304        if not certificate_brain:
305            em = 'Certificate %s org-code %s not found\n' % (certcode, certcode_org)
306            logger.info(em)
307        matric_no = student.matric_no
308        sid = student_id
309        student_obj = getattr(students_folder,sid)
310        student_obj.invokeFactory('StudentApplication','application')
311        application = student_obj.application
[1169]312        self.portal_workflow.doActionFor(application,'open',dest_container=application)
[1151]313        da = {'Title': 'Application Data'}
314        student_obj.invokeFactory('StudentPersonal','personal')
315        da['jamb_reg_no'] = student.Entryregno
[1462]316        em = self.getEntryMode(student.Entryregno)
[1460]317##        em = student.Mode_of_Entry
318##        if em in ('DIRECT', 'DIRECT ENTRY',):
319##            em = 'DE'
320##        elif em in ('U.M.E', 'UNE',):
321##            em = 'UME'
322##        elif not em:
323##            em = "unknown"
[1401]324        da['entry_mode'] = em
[1151]325        personal = student_obj.personal
326        self.portal_workflow.doActionFor(personal,'open',dest_container=personal)
327        dp = {'Title': 'Personal Data'}
328        student_obj.invokeFactory('StudentClearance','clearance')
329        clearance = student_obj.clearance
[1169]330        self.portal_workflow.doActionFor(clearance,'open',dest_container=clearance)
[1151]331        dc = {'Title': 'Clearance/Eligibility Record'}
332        dc['matric_no'] = matric_no
333        state = student.State
334        lga = student.LGA
335        if state and lga:
336            lga =  state + ' / ' + lga
337        else:
338            lga = "None"
[1174]339        da['jamb_lga'] = dc['lga'] = lga
[1173]340        da['app_email'] = dp['email'] = email
341        da['app_mobile'] = dp['phone'] = phone_nr
[1411]342        dp['firstname'] = student.Firstname
343        dp['middlename'] = student.Middlename
344        dp['lastname'] = student.Lastname
345        da['jamb_lastname'] = "%s %s %s" % (student.Firstname,student.Middlename,student.Lastname)
[1174]346        da['jamb_sex'] = student.Sex
[1151]347        dp['sex'] = student.Sex == 'F'
348        dp['perm_address'] = student.Permanent_Address
349        application.getContent().edit(mapping=da)
[1169]350        self.portal_workflow.doActionFor(application,'close',dest_container=application)
[1151]351        personal.getContent().edit(mapping=dp)
352        clearance.getContent().edit(mapping=dc)
[1169]353        self.portal_workflow.doActionFor(clearance,'close',dest_container=clearance)
[1759]354##        catd = {}
355##        catd['id'] = sid
356##        catd['entry_mode']= da['entry_mode']
357##        catd['matric_no'] = matric_no
358##        catd['jamb_reg_no'] = da['jamb_reg_no']
359##        catd['name'] = "%(firstname)s %(middlename)s %(lastname)s" % dp
360##        catd['sex'] = dp['sex']
361##        catd['level'] = level
362##        catd['verdict'] = verdict
363##        if certificate_brain:
364##            cpath = certificate_brain.getPath().split('/')
365##            catd['faculty'] = cpath[-4]
366##            catd['department'] = cpath[-3]
367##            catd['course'] = certcode
368##        self.students_catalog.modifyRecord(**catd)
[1151]369        #
370        # Study Course
371        #
372        student_obj.invokeFactory('StudentStudyCourse','study_course')
373        studycourse = student_obj.study_course
374        self.portal_workflow.doActionFor(studycourse,'open',dest_container=studycourse)
375        dsc = {}
376        dsc['study_course'] = certcode
[1401]377        dsc['current_level'] = level
378        dsc['current_verdict'] = verdict
[1759]379        dsc['current_session'] = '06'
[1151]380        studycourse.getContent().edit(mapping=dsc)
381        #
382        # Level
383        #
[1198]384##        l = getattr(studycourse,level,None)
385##        if l is None:
386##            studycourse.invokeFactory('StudentStudyLevel', level)
387##            l = getattr(studycourse, level)
388##            self.portal_workflow.doActionFor(l,'open',dest_container=l)
389##            l.getContent().edit(mapping={'Title': "Level %s" % level})
[1194]390###)
[1160]391
[1194]392    security.declarePublic('makeStudentLevel') ###(
393    def makeStudentLevel(self,student_id):
394        "create the StudyLevel for a returning Student"
395        #import pdb;pdb.set_trace()
[1571]396        logger = logging.getLogger('WAeUPTool.makeStudentLevel')
[1194]397        students_folder = self.portal_url.getPortalObject().campus.students
398        res = self.students_catalog(id=student_id)
399        if res:
400            st = res[0]
401        course = st.course
402        matric_no = st.matric_no
403        level = st.level
404        res = self.results_import(matric_no = matric_no)
405        if res:
406            results = res
[1571]407        logger.info('%s creating Level %s' % (student_id,level))
[1194]408        #
409        # Level
410        #
411        student_obj = getattr(self.portal_url.getPortalObject().campus.students,student_id)
412        studycourse = getattr(student_obj,"study_course",None)
413        self.portal_workflow.doActionFor(studycourse,'close_for_edit',dest_container=studycourse)
414        l = getattr(studycourse,level,None)
415        if l is None:
416            studycourse.invokeFactory('StudentStudyLevel', level)
417            l = getattr(studycourse, level)
418            self.portal_workflow.doActionFor(l,'open',dest_container=l)
419            l.getContent().edit(mapping={'Title': "Level %s" % level})
420        ###)
421
[1151]422    security.declarePublic('getAccommodationInfo') ###(
[828]423    def getAccommodationInfo(self,bed):
424        """return Accommodation Info"""
425        info = {}
426        hall,block,room,letter = bed.split('_')
427        res = ZCatalog.searchResults(self.portal_catalog,portal_type="AccoHall",id=hall)
428        if res and len(res) == 1:
429            hall_brain = res[0]
430            hall_doc = hall_brain.getObject().getContent()
431        else:
432            return info
433        info['hall_title'] = hall_brain.Title
434        info['maintenance_code'] = hall_doc.maintenance_code
435        res = ZCatalog.searchResults(self.portal_catalog,portal_type="ScratchCardBatch")
436        batch_doc = None
437        for brain in res:
438            if brain.id.startswith(info['maintenance_code']):
439                batch_doc = brain.getObject().getContent()
440                break
441        if batch_doc is None:
442            info['maintenance_fee'] = None
443        else:
444            info['maintenance_fee'] = batch_doc.cost
445        return info
[1151]446    ###)
[828]447
[1151]448    security.declareProtected(ModifyPortalContent,'deleteAllCourses') ###(
449    def deleteAllCourses(self,department="All"):
450        ''' delete the courses'''
451        pm = self.portal_membership
452        member = pm.getAuthenticatedMember()
[1160]453
[1151]454        if str(member) not in ("henrik","joachim"):
455            return "not possible"
456        if department == "All":
457            res = self.portal_catalog({'meta_type': 'Department'})
458        if len(res) < 1:
459            return "No Departments found"
[1160]460
[1151]461        deleted = []
462        for dep in res:
463            cf = dep.getObject().courses
464            if cf:
465                cf.manage_delObjects(ids=cf.objectIds())
466                deleted.append("deleted Courses in %s" % dep.getId)
467        return "\r".join(deleted)
[1160]468    ###)
[1151]469
[1572]470    security.declareProtected(ModifyPortalContent,'getLogfileLines') ###(
471    def getLogfileLines(self,filename="event.log",numlines=20):
472        """Get last NUMLINES lines of logfile FILENAME.
[1160]473
[1572]474        Return last lines' of a file in the instances logfile directory as
475        a list. The number of returned lines equals `numlines' or less. If
476        less than `numlines' lines are available, the whole file ist
477        returned. If the file can not be opened or some other error
478        occurs, empty list is returend.
479        """
480        result = []
481        lines_hit = 0
482
483        # We only handle files in instances' log directory...
484        logpath = os.path.join(i_home, "log")
485        filename = str(os.path.abspath( os.path.join( logpath, filename )))
486        if not filename.startswith( logpath ):
487            # Attempt to access file outside log-dir...
488            return []
489
490        try:
491            fd = file( filename, "rb" )
492        except IOError:
493            return []
494        if not fd:
495            return []
496
497        if os.linesep == None:
498            linesep = '\n'
499        else:
500            linesep = os.linesep
501
502        # Try to find 'numlines' times a lineseparator, searching from end
503        # and moving to the beginning of file...
504        fd.seek( 0, 2) # Move to end of file...
505        while lines_hit < numlines:
506            if fd.read(1) == linesep[-1]: # This moves filedescriptor
507                                          # one step forward...
508                lines_hit += 1
509            try:
510                fd.seek( -2, 1) # Go two bytes back from current pos...
511            except IOError:
512                # We cannot go back two bytes. Maybe the file is too small...
513                break
514        fd.seek(2,1)
515
516        # Read all lines from current position...
517        result = fd.readlines()
518        # Remove line endings...
519        result = [x.strip() for x in result]
520        fd.close()
521        return result
522    ###)
523
[1700]524    security.declareProtected(ModifyPortalContent,"getCallbacksFromLog")###(
[1665]525    def getCallbacksFromLog(self,filename):
526        """fix Online Payment Transactions from Z2.log entries"""
527        import transaction
528        import random
529        from cgi import parse_qs
530        from urlparse import urlparse
531        #from pdb import set_trace
532        wftool = self.portal_workflow
533        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
534        students_folder = self.portal_url.getPortalObject().campus.students
535        s = r'(?P<client_ip>\S+) - (?P<member_id>\S+) \['
536        s += r'(?P<date>.*)\] "(?P<get>.*)" (?P<codes>\d+ \d+) "'
537        s += r'(?P<intersw>.*)" "(?P<agent>.*)"'
538        data = re.compile(s)
539        start = True
540        tr_count = 1
541        total = 0
542        #name = 'pume_results'
543        #name = 'epaymentsuccessful_z2log2'
544        name = filename
545        no_import = []
546        imported = []
547        logger = logging.getLogger('WAeUPTool.getFailedTransactions')
548        try:
549            transactions = open("%s/import/%s" % (i_home,name),"rb").readlines()
550        except:
551            logger.error('Error reading %s' % name)
552            return
553        tas = []
554        for line in transactions:
555            dict = {}
556            items = data.search(line)
557            dict['idict'] = idict = items.groupdict()
558            #print idict
559            #from pdb import set_trace;set_trace()
560            urlparsed = urlparse(idict['get'][4:])
561            #print urlparsed
562            path = urlparsed[2].split('/')
563            dict['student_id'] = student_id = path[8]
564            dict['payment_id'] = payment_id = path[10]
565            dict['qs_dict'] = qs_dict = parse_qs(urlparsed[4])
566            tas.append(dict)
567            tr_count += 1
568        return tas
569    ###)
570
[1620]571    security.declareProtected(ModifyPortalContent,"importOnlinePaymentTransactions")###(
572    def importOnlinePaymentTransactions(self):
573        """load Online Payment Transactions from CSV values"""
574        import transaction
575        import random
576        #from pdb import set_trace
577        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
[1625]578        opt = self.online_payments_import
[1620]579        students_folder = self.portal_url.getPortalObject().campus.students
580        start = True
581        tr_count = 1
582        total = 0
583        #name = 'pume_results'
584        name = 'OnlineTransactions'
585        no_import = []
586        imported = []
587        logger = logging.getLogger('WAeUPTool.importOnlinePaymentTransactions')
588        try:
589            transactions = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
590        except:
591            logger.error('Error reading %s.csv' % name)
592            return
593        for pay_transaction in transactions:
594            if start:
595                start = False
596                logger.info('Start loading from %s.csv' % name)
597                s = ','.join(['"%s"' % fn for fn in pay_transaction.keys()])
598                no_import.append('%s,"Error"' % s)
599                format = ','.join(['"%%(%s)s"' % fn for fn in pay_transaction.keys()])
600                format_error = format + ',"%(Error)s"'
601            data = {}
[1644]602
[1643]603            # format of the first file sent from Tayo
604            #data['datetime'] = date = DateTime.DateTime(pay_transaction['Date'])
605            #data['student_id'] = student_id = pay_transaction['Payer ID']
606            #data['order_id'] = order_id = pay_transaction['Order ID (Tranx Ref)']
607            #data['response_code'] = response_code = pay_transaction['Resp Code']
608            #data['amount'] = amount = pay_transaction['Amount']
[1644]609
[1643]610            # format of the second file sent from Tayo
611            data['datetime'] = date = 0
[1625]612            data['student_id'] = student_id = pay_transaction['Payer ID']
613            data['order_id'] = order_id = pay_transaction['Order ID (Tranx Ref)']
[1644]614            data['response_code'] = response_code = '00'
615            data['amount'] = amount = pay_transaction['Amount']
616
[1620]617            dup = False
618            if response_code == "12":
619                continue
620            try:
621                opt.addRecord(**data)
622            except ValueError:
623                dup = True
624            #from pdb import set_trace;set_trace()
625            if dup:
626                if response_code == "00":
627                    opt.modifyRecord(**data)
628                else:
[1674]629                    pay_transaction['Error'] = "Duplicate order_id"
[1620]630                    no_import.append( format_error % pay_transaction)
[1674]631                    logger.info("duplicate order_id %(order_id)s for %(student_id)s %(response_code)s" % data)
[1620]632                    continue
633            tr_count += 1
634            if tr_count > 1000:
635                if len(no_import) > 0:
636                    open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
637                             '\n'.join(no_import) + '\n')
638                    no_import = []
[1645]639                em = '%d transactions committed\n' % (tr_count)
[1620]640                transaction.commit()
641                regs = []
642                logger.info(em)
643                total += tr_count
644                tr_count = 0
645        open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
646                                                '\n'.join(no_import))
647        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
648    ###)
649
[1756]650    student_field2types = {   ###(
651                      'StudentApplication':
652                          {'id': 'application',
653                           'title': 'Application Data',
654                           'wf_state': 'close',
655                           'fields':
656                             ('jamb_reg_no',
657                              'entry_mode',
658                              #'entry_level',
659                              'entry_session',
660                              'jamb_score',
661                              'email',
662                              'phone',
663                              )
664                              },
665                      'StudentPume':
666                          {'id': 'pume',
667                           'title': 'Pume Data',
668                           'wf_state': 'close',
669                           'fields':
670                             ('pume_score',
671                              )
672                              },
673                      'StudentClearance':
674                          {'id': 'clearance',
675                           'title': 'Clearance Data',
676                           'wf_state': 'close',
677                           'fields':
678                             ('matric_no',
679                              'nationality',
680                              'lga',
681                              )
682                              },
683                         'StudentPersonal':
684                          {'id': 'personal',
685                           'title': 'Personal Data',
686                           'wf_state': 'close',
687                           'fields':
688                             ('firstname',
689                              'middlename',
690                              'lastname',
691                              'sex',
692                              'email',
693                              'phone',
694                              'perm_address',
695                              )
696                              },
697                         'StudentStudyCourse':
698                          {'id': 'study_course',
699                           'title': 'Study Course',
700                           'wf_state': 'close',
701                           'fields':
702                             ('study_course',
703                              'current_level',
704                              'current_session',
705                              'current_mode',
706                              'current_verdict',
707                              )
708                              },
709                         }
710    ###)
711
712
[1752]713    security.declareProtected(ModifyPortalContent,'import_student') ###(
714    def import_student(self,dict):
[1747]715        "create a students data"
716        logger = logging.getLogger('WAeUPTool.create_student')
717        students_folder = self.portal_url.getPortalObject().campus.students
718        jamb_reg_no = dict.get('jamb_reg_no',None)
719        if jamb_reg_no:
720            res = self.students_catalog(jamb_reg_no = jamb_reg_no)
721            if res:
[1749]722                return '',"jamb_reg_no exists"
[1747]723        matric_no = dict.get('matric_no',None)
724        if matric_no:
725            res = self.students_catalog(matric_no = matric_no)
726            if res:
[1749]727                return '',"matric_no exists"
[1747]728        sid = self.waeup_tool.generateStudentId('?')
729        students_folder.invokeFactory('Student', sid)
730        student_obj = getattr(students_folder,sid)
731        f2t = self.student_field2types
732        for pt in f2t.keys():
733            student_obj.invokeFactory(pt,f2t[pt]['id'])
734            sub_obj = getattr(student_obj,f2t[pt]['id'])
735            sub_doc = sub_obj.getContent()
736            self.portal_workflow.doActionFor(sub_obj,'open',dest_container=sub_obj)
737            d = {'Title': f2t[pt]['title']}
738            for field in f2t[pt]['fields']:
[1749]739                d[field] = dict.get(field,'')
[1747]740            if pt == 'StudentPersonal':
741                d['sex'] = dict.get('sex') == 'F'
742            sub_doc.edit(mapping = d)
[1758]743            new_state = f2t[pt]['wf_state']
744            if new_state != "remain":
745                self.portal_workflow.doActionFor(sub_obj,new_state,dest_container=sub_obj)
[1752]746        wfaction = 'return'
747        self.portal_workflow.doActionFor(student_obj,wfaction)
[1747]748        student_obj.manage_setLocalRoles(sid, ['Owner',])
749        return sid,''
750    ###)
751
[1730]752    security.declareProtected(ModifyPortalContent,"importData")###(
[1747]753    def importData(self,filename,name):
[1730]754        """load data from CSV values"""
755        import transaction
756        import random
[1747]757        logger = logging.getLogger('WAeUPTool.importData')
[1730]758        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
759        students_folder = self.portal_url.getPortalObject().campus.students
760        start = True
761        tr_count = 1
[1756]762        total_imported = 0
763        total_not_imported = 0
[1730]764        total = 0
[1749]765        iname = "import_%s" % name
[1747]766        stool = getToolByName(self, 'portal_schemas')
767        ltool = getToolByName(self, 'portal_layouts')
768        schema = stool._getOb(iname)
[1730]769        if schema is None:
[1756]770            em = 'No such schema import_%s' % iname
[1747]771            logger.error('No such schema import_%s' % iname)
[1756]772            return em
[1747]773        layout = ltool._getOb(iname)
[1730]774        if layout is None:
[1756]775            em = 'No such layout import_%s' % iname
776            logger.error(em)
777            return em
[1730]778        validators = {}
779        for widget in layout.keys():
[1749]780            validators[widget] = layout[widget].validate
[1752]781        creator = getattr(self, 'import_%s' % name,None)
[1747]782        if creator is None:
[1756]783            em = 'No creator function create_%s' % name
784            logger.error(em)
785            return em
[1747]786        not_imported = []
[1730]787        imported = []
788        try:
[1747]789            items = csv.DictReader(open("%s/import/%s.csv" % (i_home,filename),"rb"))
[1730]790        except:
[1756]791            em = 'Error reading %s.csv' % filename
792            logger.error(em)
793            return em
[1730]794        for item in items:
795            tr_count += 1
796            if start:
797                start = False
[1747]798                adapters = [MappingStorageAdapter(schema, item)]
799                dm = DataModel(item, adapters,context=self)
[1753]800                logger.info('Start importing from %s.csv' % filename)
[1730]801                import_keys = item.keys()
802                diff_set = set(import_keys).difference(set(schema.keys()))
803                if diff_set:
804                    logger.error('%s not in schema.' % diff_set)
805                    return
806                diff_set = set(import_keys).difference(set(layout.keys()))
807                if diff_set:
808                    logger.error('%s not in layout.' % diff_set)
809                    return
[1753]810                s = ','.join(['"%s"' % fn for fn in import_keys])
[1756]811                open("%s/import/%s_imported%s.csv" % (i_home,filename,current),"a").write(s + '\n')
812                open("%s/import/%s_not_imported%s.csv" % (i_home,filename,current),"a").write('%s,"Error"' %s + '\n')
[1730]813                format = ','.join(['"%%(%s)s"' % fn for fn in import_keys])
814                format_error = format + ',"%(Error)s"'
[1756]815                #from pdb import set_trace; set_trace()
816                format = '"%(id)s",'+ format
[1747]817            ds = DataStructure(data=item,datamodel=dm)
818            error_string = ""
[1730]819            for k in import_keys:
[1747]820                if not validators[k](ds):
821                    error_string += " %s : %s" % (k,ds.getError(k))
822            if not error_string:
[1756]823                item.update(dm)
824                item['id'],error = creator(item)
[1747]825                if error:
826                    error_string += error
827            if error_string:
828                item['Error'] = error_string
829                not_imported.append(format_error % item)
[1756]830                total_not_imported += 1
[1747]831            else:
[1756]832                imported.append(format % item)
833                total_imported += 1
834            total += 1
[1730]835            if tr_count > 1000:
[1747]836                if len(not_imported) > 0:
837                    open("%s/import/%s_not_imported%s.csv" % (i_home,filename,current),"a").write(
838                             '\n'.join(not_imported) + '\n')
839                    not_imported = []
840                if len(imported) > 0:
841                    open("%s/import/%s_imported%s.csv" % (i_home,filename,current),"a").write(
842                             '\n'.join(not_imported) + '\n')
843                    imported = []
[1730]844                em = '%d transactions committed\n' % (tr_count)
845                transaction.commit()
846                regs = []
847                logger.info(em)
848                tr_count = 0
[1756]849        if len(imported) > 0:
[1747]850            open("%s/import/%s_imported%s.csv" % (i_home,filename,current),"a").write(
851                                                '\n'.join(imported))
[1756]852        if len(not_imported) > 0:
[1747]853            open("%s/import/%s_not_imported%s.csv" % (i_home,filename,current),"a").write(
854                                                '\n'.join(not_imported))
[1759]855        em = "Imported: %d, not imported: %d of total %d" % (total_imported,total_not_imported,total)
[1756]856        logger.info(em)
857        return em
[1730]858    ###)
859
[828]860InitializeClass(WAeUPTool)
Note: See TracBrowser for help on using the repository browser.