source: WAeUP_SRP/trunk/Accommodation.py @ 7657

Last change on this file since 7657 was 5630, checked in by Henrik Bettermann, 14 years ago

Remove patch.

  • Property svn:keywords set to Id
File size: 13.7 KB
RevLine 
[103]1#-*- mode: python; mode: fold -*-
2from Globals import InitializeClass
3from AccessControl import ClassSecurityInfo
4
5from Products.CMFCore.utils import UniqueObject, getToolByName
6from Products.CMFCore.permissions import View
7from Products.CMFCore.permissions import ModifyPortalContent
[575]8from Products.CPSCore.CPSBase import CPSBase_adder, CPSBaseFolder
9#from Products.CPSCore.CPSBase import CPSBaseDocument as BaseDocument
10from Products.CPSDocument.CPSDocument import CPSDocument
11from Products.CPSCore.CPSBase import CPSBaseBTreeFolder as BaseBTreeFolder
[2845]12from Products.WAeUP_SRP.WAeUPTables import AccommodationTable,NOT_OCCUPIED
[1410]13import logging
14import csv,re,os
[623]15import Globals
16import DateTime
[638]17import re
[623]18p_home = Globals.package_home(globals())
19i_home = Globals.INSTANCE_HOME
[103]20
[2845]21
[103]22class AccoFolder(CPSDocument): ###(
23    """
[575]24    WAeUP AccoFolder containing Accommodation halls
[103]25    """
26    meta_type = 'AccoFolder'
27    portal_type = meta_type
28    security = ClassSecurityInfo()
[630]29
[575]30    security.declareProtected(View,"Title")
31    def Title(self):
32        """compose title"""
[630]33        return "Accommodation Section"
[575]34
[404]35    security.declareProtected(ModifyPortalContent,"generateFreeBedsList") ###(
36    def generateFreeBedsList(self):
37        """
38        generate the free Bedslist.
39        """
[3870]40        logger = logging.getLogger('Accommodation.AccoFolder.generateFreeBedsList')
41        member = self.portal_membership.getAuthenticatedMember()
42        logger.info('%s generated bed list' % member)
[3043]43        bed_list = self.portal_accommodation
[623]44        l = self.portal_catalog({'meta_type': "AccoHall"})
[404]45        halls = []
[623]46        generated = []
[5208]47        generated.append('"Bed","BedType"' % vars())
[5207]48        modified = []
49        modified.append('"Bed","BedType","Student"' % vars())
[626]50        beds_generated = []
[404]51        for h in l:
52            halls.append(h.getObject())
53        for hall in halls:
[623]54            #import pdb;pdb.set_trace()
[2845]55            hall_doc = hall.getContent()
[626]56            hall_gen = {}
[630]57            hall_gen['name'] = hall.Title
[626]58            count = 0
[5207]59            modified_count = 0
[2845]60            reserved = [(r.split('/')[0],int(r.split('/')[1])) for r in re.split(',|\.| ',hall_doc.reserved_rooms)
[714]61                                     if r]
[3870]62            #import pdb;pdb.set_trace()                         
[2845]63            #for block in range(1,int(hall_doc.nr_of_blocks)+1):
64            # for block in 'ABCDEFGHIJ'[:int(hall_doc.nr_of_blocks)]:
[3043]65            blocks_for_female = getattr(hall_doc,'blocks_for_female',[])
66            blocks_for_male = getattr(hall_doc,'blocks_for_male',[])
67            beds_for_fresh = getattr(hall_doc,'beds_for_fresh',[])
68            beds_for_pre = getattr(hall_doc,'beds_for_pre',[])
[3870]69            beds_for_returning = getattr(hall_doc,'beds_for_returning',[])
[3043]70            beds_for_final = getattr(hall_doc,'beds_for_final',[])
71            if set(blocks_for_female).intersection(set(blocks_for_male)):
[2823]72                return self.accommodation.acco_folder_view(beds_generated=beds_generated)
[3043]73            for block in blocks_for_female + blocks_for_male:
[934]74                sex = 'male'
[3043]75                if block in blocks_for_female:
[934]76                    sex = 'female'
[2845]77                for floor in range(1,int(hall_doc.nr_of_floors)+1):
78                    for room in range(1,int(hall_doc.rooms_per_floor)+1):
[3786]79                        for bed in 'ABCDEFGHIKLMNOPQRSTUVWXYZ'[:int(hall_doc.beds_per_room)]:
[404]80                            room_nr = floor*100 + room
[3784]81                            bt = 'all'
[714]82                            if (block,room_nr) in reserved:
[623]83                                bt = "reserved"
[2845]84                            elif hall_doc.special_handling and not hall_doc.special_handling.startswith("no"):
85                                bt = hall_doc.special_handling
[3043]86                            elif bed in beds_for_fresh:
[407]87                                bt = 'fr'
[3043]88                            elif bed in beds_for_pre:
[2421]89                                bt = 'pr'
[3043]90                            elif bed in beds_for_final:
[407]91                                bt = 'fi'
[3870]92                            elif bed in beds_for_returning:
93                                bt = 're'                               
[2845]94                            if hall_doc.special_handling.startswith("no_"):
95                                bt += "_" + hall_doc.special_handling[3:]
[575]96                            bt = "%(sex)s_%(bt)s" % vars()
[926]97                            uid = '%s_%s_%d_%s' % (hall.getId(),block,room_nr,bed)
[2845]98                            d = {}
99                            d['bed'] = uid
100                            d['bed_type'] = bt
[2867]101                            d['sort_id'] = getattr(hall_doc,'sort_id',0)
[2845]102                            d['hall'] = hall.getId()
[3043]103                            bed_record = bed_list.getRecordByKey(uid)
104                            if bed_record is None:
105                                d['student'] = NOT_OCCUPIED
106                                bed_list.addRecord(**d)
[626]107                                count +=1
108                                generated.append('"%(uid)s","%(bt)s"' % vars())
[3043]109                            elif bed_record.bed_type != bt:
[5208]110                                st = bed_record.student
[3043]111                                bed_list.modifyRecord(**d)
[5208]112                                modified.append('"%(uid)s","%(bt)s","%(st)s"' % vars())
[5207]113                                modified_count += 1
[626]114                                pass
[5625]115                            # fix for ticket futminna 133, can be removed after implementation
116                            # of new allocation module
[5630]117                            #if bed_record and bed_record.student=='':
118                            #    d['student'] = NOT_OCCUPIED
119                            #    bed_list.modifyRecord(**d)
120                            #    modified.append('"%(uid)s","%(bt)s","not_occupied"' % vars())
121                            #    modified_count += 1                               
[626]122            hall_gen['count']= count
[5207]123            hall_gen['modified_count']= modified_count
[626]124            beds_generated.append(hall_gen)
[623]125        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
[3870]126        open("%s/export/bedlist_%s.csv" % (i_home,current),"w+").write('\n'.join(generated))
[5207]127        open("%s/export/bedlist_modified_%s.csv" % (i_home,current),"w+").write('\n'.join(modified))
[650]128        return self.accommodation.acco_folder_view(beds_generated=beds_generated)
[3043]129    ###)
[152]130
[1410]131    security.declareProtected(ModifyPortalContent,"importReservedBeds")###(
132    def importReservedBeds(self):
133        """load Reserved Beds from CSV"""
134        import transaction
135        import random
136        current = DateTime.DateTime().strftime("%d-%m-%y_%H_%M_%S")
137        students_folder = self.portal_url.getPortalObject().campus.students
138        acco_folder = self.portal_url.getPortalObject().campus.accommodation
139        tr_count = 1
140        total = 0
141        name = 'ReservedBeds'
142        accommodation = self.portal_accommodation
143        students_cat = self.students_catalog
144        no_import = []
145        imported = []
[1571]146        logger = logging.getLogger('Accommodation.AccoFolder.importReservedBeds')
[1410]147        try:
148            beds = csv.DictReader(open("%s/import/%s.csv" % (i_home,name),"rb"))
149        except:
150            logger.error('Error reading %s.csv' % name)
151            return
152        halls = {}
153        start = True
154        for bed in beds:
155            if start:
156                start = False
157                logger.info('start loading from %s.csv' % name)
158                s = ','.join(['"%s"' % fn for fn in bed.keys()])
159                imported.append(s)
160                no_import.append('%s,"Error"' % s)
161                format = ','.join(['"%%(%s)s"' % fn for fn in bed.keys()])
162                format_error = format + ',"%(Error)s"'
163                no_certificate = "no certificate %s" % format
[5221]164            student_id = bed.get('id')
[1410]165            matric_no = bed.get('matric_no')
166            jamb_reg_no = bed.get('jamb_reg_no')
[5221]167            if student_id != '':
168                res = students_cat(id = student_id)
169                if not res:
170                    bed['Error'] = "No such student"
171                    no_import.append( format_error % bed)
172                    continue
173                student = res[0]
174            elif matric_no != '':
[1410]175                res = students_cat(matric_no = matric_no)
176                if not res:
177                    bed['Error'] = "No such student"
178                    no_import.append( format_error % bed)
179                    continue
180                student = res[0]
181            elif jamb_reg_no != '':
182                res = students_cat(jamb_reg_no = jamb_reg_no)
183                if not res:
184                    bed['Error'] = "No such student"
185                    no_import.append( format_error % bed)
186                    continue
187                student = res[0]
188            else:
[5221]189                bed['Error'] = "No student identification number provided"
[1410]190                no_import.append( format_error % bed)
191                continue
192            sid = student.id
193            names = bed.get('name').split()
194            n = 0
195            for na in names:
196                if na.endswith(','):
197                    names[n] = na[:-1]
[5219]198                names[n] = names[n].upper()
[1410]199                n += 1
200            s_names = student.name.split()
201            found = False
202            for sn in s_names:
203                if sn.upper() in names:
204                    found = True
205                    break
206            if not found:
207                bed['Error'] = "Name mismatch %s %s" % (str(names),str(s_names))
208                no_import.append( format_error % bed)
209                continue
210            hall = bed.get('hall')
211            if hall not in halls.keys():
212                hall_object = getattr(acco_folder,hall, None)
213                if hall_object is None:
214                    bed['Error'] = "No such hall"
215                    no_import.append( format_error % bed)
216                    continue
[1571]217                halls[hall] = hall_doc = hall_object.getContent()
[1410]218            bid = "%(hall)s_%(block)s_%(room)s_%(bed)s" % bed
219            res = accommodation(bed = bid)
220            psm = ''
221            while True:
222                if not res:
223                    psm = "No bed with this id"
224                    break
225                bed_brain = res[0]
226                if not bed_brain.bed_type.endswith("reserved"):
227                    psm = "Not a reserved bed"
228                    break
[3406]229                if bed_brain.student and bed_brain.student != NOT_OCCUPIED:
[1410]230                    psm = "Bed %s already reserved for %s" % (bid,bed_brain.student)
231                    break
232                if student.sex and not bed.get('block') in hall_doc.blocks_for_female:
233                    psm = "Sex does not match %s" % bid
234                    break
235                break
236            if psm != '':
237                bed['Error'] = psm
238                no_import.append( format_error % bed)
239                continue
[1449]240            already = accommodation(student=sid)
241            if already:
[3422]242                accommodation.modifyRecord(bed=already[0].bed,student=NOT_OCCUPIED)
[1449]243                student_obj = getattr(students_folder, student.id)
[2454]244                acco_id = "accommodation_%s" % self.getSessionId()[0]
[1449]245                if acco_id in student_obj.objectIds():
246                    acco_doc = getattr(student_obj, acco_id).getContent()
[3423]247                    info = self.getAccommodationInfo(sid)
[3422]248                    status = info['student_status']
[3424]249                    acco_doc.edit(mapping={'bed': bid,'student_status' : status})
[1449]250                    member = self.portal_membership.getAuthenticatedMember()
[1571]251                    logger.info('%s changed reserved bed %s for %s' % (member,bid,sid))
[1410]252            accommodation.modifyRecord(bed = bid, student = sid)
253            imported.append( format % bed)
254            tr_count += 1
255            if tr_count > 1000:
256                if len(no_import) > 0:
257                    open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
258                             '\n'.join(no_import) + '\n')
259                    no_import = []
260                open("%s/import/%simported%s.csv" % (i_home,name,current),"a").write(
261                                            '\n'.join(no_import) + "\n")
262                imported = []
263                em = '%d transactions commited total %s\n' % (tr_count,total)
264                transaction.commit()
265                regs = []
266                logger.info(em)
267                total += tr_count
268                tr_count = 0
269        #from pdb import set_trace;set_trace()
270        open("%s/import/%simported%s.csv" % (i_home,name,current),"a").write(
271                                            '\n'.join(imported))
272        open("%s/import/%s_not_imported%s.csv" % (i_home,name,current),"a").write(
273                                                '\n'.join(no_import))
[1449]274        logger.info('finished loading from %s.csv' % name)
[1410]275        return self.REQUEST.RESPONSE.redirect("%s" % self.REQUEST.get('URL1'))
276
[1571]277
[103]278InitializeClass(AccoFolder)
279
280def addAccoFolder(container, id, REQUEST=None, **kw):
281    """Add a AccoFolder."""
282    ob = AccoFolder(id, **kw)
283    return CPSBase_adder(container, ob, REQUEST=REQUEST)
284###)
285
[2845]286###)
287
[622]288class AccoHall(CPSDocument): ###(
[103]289    """
[2845]290    WAeUP AccoHall
[103]291    """
[622]292    meta_type = 'AccoHall'
[103]293    portal_type = meta_type
294    security = ClassSecurityInfo()
[575]295
[404]296    security.declareProtected(View,"Title") ###(
[152]297    def Title(self):
298        """compose title"""
299        content = self.getContent()
300        heading = getattr(content,'heading',None)
301        if heading is None:
302            return self.title
303        return heading
[1393]304    ###)
[404]305
[622]306InitializeClass(AccoHall)
[103]307
[1571]308
[622]309def addAccoHall(container, id, REQUEST=None, **kw):
310    """Add a AccoHall."""
311    ob = AccoHall(id, **kw)
[103]312    return CPSBase_adder(container, ob, REQUEST=REQUEST)
313###)
Note: See TracBrowser for help on using the repository browser.