## $Id: interfaces.py 17313 2023-01-25 08:52:51Z henrik $
##
## Copyright (C) 2011 Uli Fouquet & Henrik Bettermann
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##
from grok import getSite
from datetime import datetime
from zope.component import getUtility
from zope.catalog.interfaces import ICatalog
from zope.interface import invariant, Invalid, Attribute, Interface
from zope import schema
from waeup.kofa.interfaces import (
IKofaObject, academic_sessions_vocab, registration_states_vocab)
from waeup.kofa.interfaces import MessageFactory as _
from waeup.kofa.hostels.vocabularies import (
bed_letters, blocks, SpecialHandlingSource,
NOT_OCCUPIED)
from waeup.kofa.students.interfaces import IStudentsUtils
# Define a validation method for sort ids
[docs]class NotASortId(schema.ValidationError):
__doc__ = u"Invalid sort_id"
[docs]def validate_sort_id(value):
if not value < 1000:
raise NotASortId(value)
return True
[docs]class IHostelsContainer(IKofaObject):
"""A container for hostel objects.
"""
expired = Attribute('True if current datetime is in application period.')
statistics = Attribute('Bed category statistics')
startdate = schema.Datetime(
title = _(u'Hostel Allocation Start Date'),
required = False,
description = _('Example: ') + u'2011-12-01 18:30:00+01:00',
)
enddate = schema.Datetime(
title = _(u'Hostel Allocation Closing Date'),
required = False,
description = _('Example: ') + u'2011-12-31 23:59:59+01:00',
)
accommodation_session = schema.Choice(
title = _(u'Booking Session'),
source = academic_sessions_vocab,
#default = datetime.now().year,
required = False,
readonly = False,
)
accommodation_states = schema.List(
title = _(u'Allowed States'),
value_type = schema.Choice(
vocabulary = registration_states_vocab,
),
defaultFactory=list,
)
allocation_expiration = schema.Int(
title = _(u'Allocation Expiration Time (days)'),
description = _(
'Number of days after which allocation is being annulled'),
required = False,
)
def clearAllHostels():
"""Clear all hostels.
"""
def addHostel(hostel):
"""Add a hostel.
"""
def releaseExpiredAllocations(n):
"""Release bed if bed allocation has expired. Allocation expires
after `n` days if maintenance fee has not been paid.
"""
def writeLogMessage(view, message):
"""Add an INFO message to hostels.log.
"""
[docs]class IHostel(IKofaObject):
"""Representation of a hostel.
"""
bed_statistics = Attribute('Number of booked and total beds')
def clearHostel():
"""Remove all beds.
"""
def updateBeds():
"""Fill hostel with beds or update beds.
"""
hostel_id = schema.TextLine(
title = _(u'Hostel Id'),
)
sort_id = schema.Int(
title = _(u'Sort Id'),
required = True,
default = 10,
constraint=validate_sort_id,
)
hostel_name = schema.TextLine(
title = _(u'Hostel Name'),
required = True,
default = u'Hall 1',
)
floors_per_block = schema.Int(
title = _(u'Floors per Block'),
required = True,
default = 1,
)
rooms_per_floor = schema.Int(
title = _(u'Rooms per Floor'),
required = True,
default = 2,
)
blocks_for_female = schema.List(
title = _(u'Blocks for Female Students'),
value_type = schema.Choice(
vocabulary = blocks
),
defaultFactory=list,
)
blocks_for_male = schema.List(
title = _(u'Blocks for Male Students'),
value_type = schema.Choice(
vocabulary = blocks
),
defaultFactory=list,
)
beds_for_pre= schema.List(
title = _(u'Beds for Pre-Study Students'),
value_type = schema.Choice(
vocabulary = bed_letters
),
defaultFactory=list,
)
beds_for_fresh = schema.List(
title = _(u'Beds for Fresh Students'),
value_type = schema.Choice(
vocabulary = bed_letters
),
defaultFactory=list,
)
beds_for_returning = schema.List(
title = _(u'Beds for Returning Students'),
value_type = schema.Choice(
vocabulary = bed_letters
),
defaultFactory=list,
)
beds_for_final = schema.List(
title = _(u'Beds for Final Year Students'),
value_type = schema.Choice(
vocabulary = bed_letters
),
defaultFactory=list,
)
beds_for_all = schema.List(
title = _(u'Beds without category'),
value_type = schema.Choice(
vocabulary = bed_letters
),
defaultFactory=list,
)
special_handling = schema.Choice(
title = _(u'Special Handling'),
source = SpecialHandlingSource(),
required = True,
default = u'regular',
)
maint_fee = schema.Float(
title = _(u'Rent'),
default = 0.0,
required = False,
)
@invariant
def blocksOverlap(hostel):
bfe = hostel.blocks_for_female
bma = hostel.blocks_for_male
if set(bfe).intersection(set(bma)):
raise Invalid(_('Female and male blocks overlap.'))
@invariant
def bedsOverlap(hostel):
beds = (hostel.beds_for_fresh +
hostel.beds_for_returning +
hostel.beds_for_final +
hostel.beds_for_pre +
hostel.beds_for_all)
if len(beds) != len(set(beds)):
raise Invalid(_('Bed categories overlap.'))
def writeLogMessage(view, message):
"""Add an INFO message to hostels.log.
"""
[docs]class IBed(IKofaObject):
"""Representation of a bed.
"""
coordinates = Attribute('Coordinates tuple derived from bed_id')
hall = Attribute('Hall id, for exporter only')
block = Attribute('Block letter, for exporter only')
room = Attribute('Room number, for exporter only')
bed = Attribute('Bed letter, for exporter only')
special_handling = Attribute('Special handling code, for exporter only')
sex = Attribute('Sex, for exporter only')
bt = Attribute('Last part of bed type, for exporter only')
def bookBed(student_id):
"""Book a bed for a student.
"""
def switchBed(switch_type):
"""Switches reservation or blockade.
"""
def releaseBedIfMaintenanceNotPaid():
"""Release bed if maintenance fee has not been paid on time.
Reserve bed so that it cannot be automatically booked by someone else.
"""
bed_id = schema.TextLine(
title = _(u'Bed Id'),
required = True,
default = u'',
)
bed_type = schema.TextLine(
title = _(u'Bed Type'),
required = True,
default = u'',
)
bed_number = schema.Int(
title = _(u'Bed Number'),
required = True,
)
owner = schema.TextLine(
title = _(u'Owner (Student)'),
description = _('Enter valid student id.'),
required = True,
default = u'',
)
@invariant
def allowed_owners(bed):
if bed.owner == NOT_OCCUPIED:
return
catalog = getUtility(ICatalog, name='students_catalog')
accommodation_span = getUtility(IStudentsUtils).ACCOMMODATION_SPAN
accommodation_session = getSite()['hostels'].accommodation_session
students = catalog.searchResults(current_session=(
accommodation_session-accommodation_span,accommodation_session))
student_ids = [student.student_id for student in students]
if not bed.owner in student_ids:
raise Invalid(_(
"Either student does not exist or student "
"is not eligible to book accommodation."))
catalog = getUtility(ICatalog, name='beds_catalog')
beds = catalog.searchResults(owner=(bed.owner,bed.owner))
if len(beds):
allocated_bed = [bed.bed_id for bed in beds][0]
raise Invalid(_(
"This student resides in bed ${a}.",
mapping = {'a':allocated_bed}))
def writeLogMessage(view, message):
"""Add an INFO message to hostels.log.
"""
[docs]class IHostelsUtils(Interface):
"""A collection of methods which are subject to customization.
"""
def getBedStatistics():
"""Return bed statistics.
"""