source: WAeUP_SRP/trunk/WAeUPTool.py @ 1753

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

session_results_view without accessing returning_import
not_imported file format corrected

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