source: main/waeup.kofa/trunk/src/waeup/kofa/hostels/interfaces.py @ 13533

Last change on this file since 13533 was 13533, checked in by Henrik Bettermann, 9 years ago

Reserve bed so that it cannot be automatically booked by someone else.

  • Property svn:keywords set to Id
File size: 8.7 KB
Line 
1## $Id: interfaces.py 13533 2015-12-03 20:04:17Z henrik $
2##
3## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
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 02111-1307 USA
17##
18from  grok import getSite
19from datetime import datetime
20from zope.component import getUtility
21from zope.catalog.interfaces import ICatalog
22from zope.interface import invariant, Invalid, Attribute, Interface
23from zope import schema
24from waeup.kofa.interfaces import (
25    IKofaObject, academic_sessions_vocab, registration_states_vocab)
26from waeup.kofa.interfaces import MessageFactory as _
27from waeup.kofa.hostels.vocabularies import (
28    bed_letters, blocks, SpecialHandlingSource,
29    NOT_OCCUPIED)
30
31# Define a validation method for sort ids
32class NotASortId(schema.ValidationError):
33    __doc__ = u"Invalid sort_id"
34
35def validate_sort_id(value):
36    if not value < 1000:
37        raise NotASortId(value)
38    return True
39
40class IHostelsContainer(IKofaObject):
41    """A container for hostel objects.
42    """
43
44    expired = Attribute('True if current datetime is in application period.')
45    statistics = Attribute('Bed category statistics')
46
47    startdate = schema.Datetime(
48        title = _(u'Hostel Allocation Start Date'),
49        required = False,
50        description = _('Example: ') + u'2011-12-01 18:30:00+01:00',
51        )
52
53    enddate = schema.Datetime(
54        title = _(u'Hostel Allocation Closing Date'),
55        required = False,
56        description = _('Example: ') + u'2011-12-31 23:59:59+01:00',
57        )
58
59    accommodation_session = schema.Choice(
60        title = _(u'Booking Session'),
61        source = academic_sessions_vocab,
62        default = datetime.now().year,
63        required = False,
64        readonly = False,
65        )
66
67    accommodation_states = schema.List(
68        title = _(u'Allowed States'),
69        value_type = schema.Choice(
70            vocabulary = registration_states_vocab,
71            ),
72        default = [],
73        )
74
75    def clearAllHostels():
76        """Clear all hostels.
77        """
78
79    def addHostel(hostel):
80        """Add a hostel.
81        """
82
83    def releaseExpiredAllocations(n):
84        """Release bed if bed allocation has expired. Allocation expires
85        after `n` days if maintenance fee has not been paid.
86        """
87
88    def writeLogMessage(view, message):
89        """Add an INFO message to hostels.log.
90        """
91
92class IHostel(IKofaObject):
93    """Representation of a hostel.
94    """
95
96    bed_statistics = Attribute('Number of booked and total beds')
97
98    def clearHostel():
99        """Remove all beds.
100        """
101
102    def updateBeds():
103        """Fill hostel with beds or update beds.
104        """
105
106    hostel_id = schema.TextLine(
107        title = _(u'Hostel Id'),
108        )
109
110    sort_id = schema.Int(
111        title = _(u'Sort Id'),
112        required = True,
113        default = 10,
114        constraint=validate_sort_id,
115        )
116
117    hostel_name = schema.TextLine(
118        title = _(u'Hostel Name'),
119        required = True,
120        default = u'Hall 1',
121        )
122
123    floors_per_block = schema.Int(
124        title = _(u'Floors per Block'),
125        required = True,
126        default = 1,
127        )
128
129    rooms_per_floor = schema.Int(
130        title = _(u'Rooms per Floor'),
131        required = True,
132        default = 2,
133        )
134
135    blocks_for_female = schema.List(
136        title = _(u'Blocks for Female Students'),
137        value_type = schema.Choice(
138            vocabulary = blocks
139            ),
140        default = [],
141        )
142
143    blocks_for_male = schema.List(
144        title = _(u'Blocks for Male Students'),
145        value_type = schema.Choice(
146            vocabulary = blocks
147            ),
148        default = [],
149        )
150
151    beds_for_pre= schema.List(
152        title = _(u'Beds for Pre-Study Students'),
153        value_type = schema.Choice(
154            vocabulary = bed_letters
155            ),
156        default = [],
157        )
158
159    beds_for_fresh = schema.List(
160        title = _(u'Beds for Fresh Students'),
161        value_type = schema.Choice(
162            vocabulary = bed_letters
163            ),
164        default = [],
165        )
166
167    beds_for_returning = schema.List(
168        title = _(u'Beds for Returning Students'),
169        value_type = schema.Choice(
170            vocabulary = bed_letters
171            ),
172        default = [],
173        )
174
175    beds_for_final = schema.List(
176        title = _(u'Beds for Final Year Students'),
177        value_type = schema.Choice(
178            vocabulary = bed_letters
179            ),
180        default = [],
181        )
182
183    beds_for_all = schema.List(
184        title = _(u'Beds without category'),
185        value_type = schema.Choice(
186            vocabulary = bed_letters
187            ),
188        default = [],
189        )
190
191    special_handling = schema.Choice(
192        title = _(u'Special Handling'),
193        source = SpecialHandlingSource(),
194        required = True,
195        default = u'regular',
196        )
197
198    maint_fee = schema.Float(
199        title = _(u'Rent'),
200        default = 0.0,
201        required = False,
202        )
203
204    @invariant
205    def blocksOverlap(hostel):
206        bfe = hostel.blocks_for_female
207        bma = hostel.blocks_for_male
208        if set(bfe).intersection(set(bma)):
209            raise Invalid(_('Female and male blocks overlap.'))
210
211    @invariant
212    def bedsOverlap(hostel):
213        beds = (hostel.beds_for_fresh +
214                hostel.beds_for_returning +
215                hostel.beds_for_final +
216                hostel.beds_for_pre +
217                hostel.beds_for_all)
218        if len(beds) != len(set(beds)):
219            raise Invalid(_('Bed categories overlap.'))
220
221    def writeLogMessage(view, message):
222        """Add an INFO message to hostels.log.
223        """
224
225class IBed(IKofaObject):
226    """Representation of a bed.
227    """
228
229    coordinates = Attribute('Coordinates tuple derived from bed_id')
230    hall = Attribute('Hall id, for exporter only')
231    block = Attribute('Block letter, for exporter only')
232    room = Attribute('Room number, for exporter only')
233    bed = Attribute('Bed letter, for exporter only')
234    special_handling = Attribute('Special handling code, for exporter only')
235    sex = Attribute('Sex, for exporter only')
236    bt = Attribute('Last part of bed type, for exporter only')
237
238    def bookBed(student_id):
239        """Book a bed for a student.
240        """
241
242    def switchReservation():
243        """Reserves bed or relases reserved bed respectively.
244        """
245
246    def releaseBedIfMaintenanceNotPaid():
247        """Release bed if maintenance fee has not been paid on time.
248        Reserve bed so that it cannot be automatically booked by someone else.
249        """
250
251    bed_id = schema.TextLine(
252        title = _(u'Bed Id'),
253        required = True,
254        default = u'',
255        )
256
257    bed_type = schema.TextLine(
258        title = _(u'Bed Type'),
259        required = True,
260        default = u'',
261        )
262
263    bed_number = schema.Int(
264        title = _(u'Bed Number'),
265        required = True,
266        )
267
268    owner = schema.TextLine(
269        title = _(u'Owner (Student)'),
270        description = _('Enter valid student id.'),
271        required = True,
272        default = u'',
273        )
274
275    @invariant
276    def allowed_owners(bed):
277        if bed.owner == NOT_OCCUPIED:
278            return
279        catalog = getUtility(ICatalog, name='students_catalog')
280        accommodation_session = getSite()['hostels'].accommodation_session
281        students = catalog.searchResults(current_session=(
282            accommodation_session,accommodation_session))
283        student_ids = [student.student_id for student in students]
284        if not bed.owner in student_ids:
285            raise Invalid(_(
286                "Either student does not exist or student "
287                "is not in accommodation session."))
288        catalog = getUtility(ICatalog, name='beds_catalog')
289        beds = catalog.searchResults(owner=(bed.owner,bed.owner))
290        if len(beds):
291            allocated_bed = [bed.bed_id for bed in beds][0]
292            raise Invalid(_(
293                "This student resides in bed ${a}.",
294                mapping = {'a':allocated_bed}))
295
296    def writeLogMessage(view, message):
297        """Add an INFO message to hostels.log.
298        """
299
300class IHostelsUtils(Interface):
301    """A collection of methods which are subject to customization.
302    """
303
304    def getBedStatistics():
305        """Return bed statistics.
306        """
Note: See TracBrowser for help on using the repository browser.