source: main/waeup.sirp/trunk/src/waeup/sirp/hostels/hostel.py @ 7005

Last change on this file since 7005 was 7003, checked in by Henrik Bettermann, 13 years ago

We have to call notify(grok.ObjectModifiedEvent?(self)) to update the catalog when only an attribute is changed.

Only one bed per student is allowed.

  • Property svn:keywords set to Id
File size: 7.1 KB
Line 
1## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
2## This program is free software; you can redistribute it and/or modify
3## it under the terms of the GNU General Public License as published by
4## the Free Software Foundation; either version 2 of the License, or
5## (at your option) any later version.
6##
7## This program is distributed in the hope that it will be useful,
8## but WITHOUT ANY WARRANTY; without even the implied warranty of
9## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10## GNU General Public License for more details.
11##
12## You should have received a copy of the GNU General Public License
13## along with this program; if not, write to the Free Software
14## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15##
16"""
17These are the hostels.
18"""
19import grok
20from zope.event import notify
21from datetime import datetime
22from grok import index
23from waeup.sirp.utils.helpers import attrs_to_fields
24from waeup.sirp.hostels.interfaces import IHostel, IBed
25
26NOT_OCCUPIED = u'not occupied'
27
28class Hostel(grok.Container):
29    """This is a hostel.
30    """
31    grok.implements(IHostel)
32    grok.provides(IHostel)
33
34    def loggerInfo(self, ob_class, comment=None):
35        target = self.__name__
36        return grok.getSite()['hostels'].logger_info(ob_class,target,comment)
37
38    def addBed(self, bed):
39        """Add a bed.
40        """
41        if not IBed.providedBy(bed):
42            raise TypeError(
43                'Hostels contain only IBed instances')
44        self[bed.bed_id] = bed
45        return
46
47    def updateBeds(self):
48        """Fill hostel with beds or update beds.
49        """
50        added_counter = 0
51        modified_counter = 0
52        removed_counter = 0
53        modified_beds = u''
54
55        # Remove all empty beds. Occupied beds remain in hostel!
56        keys = list(self.keys()) # create list copy
57        for key in keys:
58            if self[key].owner == NOT_OCCUPIED:
59                del self[key]
60                self._p_changed = True
61                removed_counter += 1
62            else:
63                self[key].bed_number = 9999
64        remaining = len(keys) - removed_counter
65
66        blocks_for_female = getattr(self,'blocks_for_female',[])
67        blocks_for_male = getattr(self,'blocks_for_male',[])
68        beds_for_fresh = getattr(self,'beds_for_fresh',[])
69        beds_for_pre = getattr(self,'beds_for_pre',[])
70        beds_for_returning = getattr(self,'beds_for_returning',[])
71        beds_for_final = getattr(self,'beds_for_final',[])
72        beds_for_all = getattr(self,'beds_for_all',[])
73        beds_reserved = getattr(self,'beds_reserved',[])
74        all_blocks = blocks_for_female + blocks_for_male
75        all_beds = (beds_for_pre + beds_for_fresh +
76            beds_for_returning + beds_for_final + beds_for_all)
77        for block in all_blocks:
78            sex = 'male'
79            if block in blocks_for_female:
80                sex = 'female'
81            for floor in range(1,int(self.floors_per_block)+1):
82                for room in range(1,int(self.rooms_per_floor)+1):
83                    for bed in all_beds:
84                        room_nr = floor*100 + room
85                        bt = 'all'
86                        if '%s_%s_%s' % (block,room_nr,bed) in beds_reserved:
87                            bt = "reserved"
88                        elif bed in beds_for_fresh:
89                            bt = 'fr'
90                        elif bed in beds_for_pre:
91                            bt = 'pr'
92                        elif bed in beds_for_final:
93                            bt = 'fi'
94                        elif bed in beds_for_returning:
95                            bt = 're'
96                        bt = u'%s_%s_%s' % (self.special_handling,sex,bt)
97                        uid = u'%s_%s_%d_%s' % (self.hostel_id,block,room_nr,bed)
98                        if self.has_key(uid):
99                            bed = self[uid]
100                            # Renumber remaining beds
101                            bed.bed_number = len(self) + 1 - remaining
102                            remaining -= 1
103                            if bed.bed_type != bt:
104                                bed.bed_type = bt
105                                modified_counter += 1
106                                modified_beds += '%s ' % uid
107                        else:
108                            bed = Bed()
109                            bed.bed_id = uid
110                            bed.bed_type = bt
111                            bed.bed_number = len(self) + 1 - remaining
112                            bed.owner = NOT_OCCUPIED
113                            self.addBed(bed)
114                            added_counter +=1
115        return removed_counter, added_counter, modified_counter, modified_beds
116
117Hostel = attrs_to_fields(Hostel)
118
119class Bed(grok.Container):
120    """This is a bed.
121    """
122    grok.implements(IBed)
123    grok.provides(IBed)
124
125    def getBedCoordinates(self):
126        """Determine the coordinates from the bed_id.
127        """
128        return self.bed_id.split('_')
129
130    def bookBed(self, student_id):
131        if self.owner == NOT_OCCUPIED:
132            self.owner = student_id
133            notify(grok.ObjectModifiedEvent(self))
134            return None
135        else:
136            return self.owner
137
138    def switchReservation(self):
139        """Reserves or unreserve bed respectively.
140        """
141        sh, sex, bt = self.bed_type.split('_')
142        hostel_id, block, room_nr, bed = self.getBedCoordinates()
143        hostel = self.__parent__
144        beds_for_fresh = getattr(hostel,'beds_for_fresh',[])
145        beds_for_pre = getattr(hostel,'beds_for_pre',[])
146        beds_for_returning = getattr(hostel,'beds_for_returning',[])
147        beds_for_final = getattr(hostel,'beds_for_final',[])
148        bed_string = u'%s_%s_%s' % (block, room_nr, bed)
149        if bt == 'reserved':
150            bt = 'all'
151            if bed in beds_for_fresh:
152                bt = 'fr'
153            elif bed in beds_for_pre:
154                bt = 'pr'
155            elif bed in beds_for_final:
156                bt = 'fi'
157            elif bed in beds_for_returning:
158                bt = 're'
159            bt = u'%s_%s_%s' % (sh, sex, bt)
160            hostel.beds_reserved.remove(bed_string)
161            message = u'unreserved'
162        else:
163            bt = u'%s_%s_reserved' % (sh, sex)
164            hostel.beds_reserved.append(bed_string)
165            # Comment of Martijn:
166            # If you have a non-Persistent subobject (like a list) and you change it,
167            # you need to manually flag the persistence machinery on the object that
168            # its subobject changed, with _p_changed. This is only necessary if some
169            # of the objects are not sublclasses of Persistent. For common built-in
170            # collections in Python such as list and dictionary there are replacements
171            # (PersistentList, PersistentMapping), and more advanced building blocks
172            # for indexes (BTrees), that don't have this issue.
173            hostel._p_changed = True
174            message = u'reserved'
175        self.bed_type = bt
176        return message
177
178    def loggerInfo(self, ob_class, comment=None):
179        target = self.__name__
180        return grok.getSite()['hostels'].logger_info(ob_class,target,comment)
181
182Bed = attrs_to_fields(Bed)
Note: See TracBrowser for help on using the repository browser.