start work on complex services/events (e.g. conferences)
git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@4150 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
808acafb72
commit
5c6f26e2ec
3 changed files with 153 additions and 34 deletions
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2009 Helmut Merz helmutm@cy55.de
|
||||
# Copyright (c) 2011 Helmut Merz helmutm@cy55.de
|
||||
#
|
||||
# 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
|
||||
|
@ -174,6 +174,16 @@ class IServiceManager(Interface):
|
|||
|
||||
services = Attribute('A collection of services managed by this object.')
|
||||
|
||||
def getServices():
|
||||
""" Return a collection of all services directly assigned
|
||||
to this service manager.
|
||||
"""
|
||||
|
||||
def getAllServices():
|
||||
""" Return a collection of all services belonging
|
||||
to this service manager.
|
||||
"""
|
||||
|
||||
def isActive():
|
||||
""" Return True if object is active, e.g. based on effective/expiration
|
||||
dates or workflow state.
|
||||
|
@ -214,11 +224,17 @@ class IService(Interface):
|
|||
vocabulary=serviceCategories,
|
||||
default='event',
|
||||
required=False,)
|
||||
bookable = schema.Bool(
|
||||
title=_(u'May people register for this service'),
|
||||
description=_(u'When this field is checked participants '
|
||||
u'may directly register for this service.'),
|
||||
default=True,
|
||||
required=False,)
|
||||
allowRegWithNumber = schema.Bool(
|
||||
title=_(u'Allow registration with number'),
|
||||
description=_(u'When this field is checked more than one '
|
||||
'object (participant) may be assigned with one '
|
||||
'registration by entering a corresponding number.'),
|
||||
u'object (participant) may be assigned with one '
|
||||
u'registration by entering a corresponding number.'),
|
||||
required=False,)
|
||||
presetRegistrationField = schema.Bool(
|
||||
title=_(u'Preset Registration Field'),
|
||||
|
@ -232,9 +248,9 @@ class IService(Interface):
|
|||
allowDirectRegistration = schema.Bool(
|
||||
title=_(u'Allow direct registration'),
|
||||
description=_(u'When this field is checked participants '
|
||||
'may register themselves directly on the page '
|
||||
'with the service description; otherwise registration '
|
||||
'is only possible on a registration template.'),
|
||||
u'may register themselves directly on the page '
|
||||
u'with the service description; otherwise registration '
|
||||
u'is only possible on a registration template.'),
|
||||
required=False,)
|
||||
externalId = schema.TextLine(
|
||||
title=_(u'External ID'),
|
||||
|
@ -247,49 +263,49 @@ class IService(Interface):
|
|||
capacity = schema.Int(
|
||||
title=_(u'Capacity'),
|
||||
description=_(u'The capacity (maximum number of clients) '
|
||||
'of this service; a negative number means: '
|
||||
'no restriction, i.e. unlimited capacity.'),
|
||||
u'of this service; a negative number means: '
|
||||
u'no restriction, i.e. unlimited capacity.'),
|
||||
required=False,)
|
||||
waitingList = schema.Bool(
|
||||
title=_(u'Waiting list'),
|
||||
description=_(u'Check this field if participants beyond the '
|
||||
'capacity of the service should be kept in a '
|
||||
'waiting list.'),
|
||||
u'capacity of the service should be kept in a '
|
||||
u'waiting list.'),
|
||||
required=False,)
|
||||
location = schema.TextLine(
|
||||
title=_(u'Location information'),
|
||||
description=_(u'Basic location information or '
|
||||
'start point for transport services.'),
|
||||
u'start point for transport services.'),
|
||||
required=False,)
|
||||
locationUrl = schema.TextLine(
|
||||
title=_(u'URL for location'),
|
||||
description=_(u'Web address (URL) with more information '
|
||||
'about the location.'),
|
||||
u'about the location.'),
|
||||
required=False,)
|
||||
location2 = schema.TextLine(
|
||||
title=_(u'Location information (2)'),
|
||||
description=_(u'Additional location information or '
|
||||
'end point for transport services.'),
|
||||
u'end point for transport services.'),
|
||||
required=False,)
|
||||
location2Url = schema.TextLine(
|
||||
title=_(u'URL for location (2)'),
|
||||
description=_(u'Web address (URL) with more information '
|
||||
'about the location.'),
|
||||
u'about the location.'),
|
||||
required=False,)
|
||||
webAddress = schema.TextLine(
|
||||
title=_(u'Web address'),
|
||||
description=_(u'Web address (URL) for more information '
|
||||
'about the service.'),
|
||||
u'about the service.'),
|
||||
required=False,)
|
||||
info = schema.TextLine(
|
||||
title=_(u'Additional information'),
|
||||
description=_(u'Name/title of a document or web page that '
|
||||
'offers additional information.'),
|
||||
u'offers additional information.'),
|
||||
required=False,)
|
||||
infoUrl = schema.TextLine(
|
||||
title=_(u'URL for additional information'),
|
||||
description=_(u'Web address (URL) of a document or web page that '
|
||||
'offers additional information.'),
|
||||
u'offers additional information.'),
|
||||
required=False,)
|
||||
|
||||
availableCapacity = Attribute('Available capacity, i.e. number of seats '
|
||||
|
@ -325,6 +341,57 @@ class IService(Interface):
|
|||
""" Remove the client from this service's registrations.
|
||||
"""
|
||||
|
||||
def getSubservices():
|
||||
""" Return a collection of immediate sub-services.
|
||||
"""
|
||||
|
||||
def addSubservice(service):
|
||||
""" Add the service given as a sub-service to this service.
|
||||
"""
|
||||
|
||||
def removeSubservice(service):
|
||||
""" Remove the sub-service given.
|
||||
"""
|
||||
|
||||
def getParentService():
|
||||
""" Return the immediate parent service if present, or None otherwise.
|
||||
"""
|
||||
|
||||
def getServiceCollections():
|
||||
""" Return a collection of service collection this service is assgned to.
|
||||
"""
|
||||
|
||||
|
||||
collectionTypes = SimpleVocabulary((
|
||||
SimpleTerm('day', 'day', u'Day'),
|
||||
SimpleTerm('track', 'track', u'Track'),
|
||||
))
|
||||
|
||||
class IServiceCollection(IService):
|
||||
""" A service that provides a substructure element of a compound service,
|
||||
e.g. a conference track or a conference day.
|
||||
"""
|
||||
|
||||
collectionType = schema.Choice(
|
||||
title=_(u'Type'),
|
||||
description=_(u'The type of '
|
||||
'this service collection, e.g. a day or a track.'),
|
||||
vocabulary=collectionTypes,
|
||||
default='day',
|
||||
required=False,)
|
||||
|
||||
def getAssignedServices():
|
||||
""" Return a collection of services assigned to this collection.
|
||||
"""
|
||||
|
||||
def assignService(service):
|
||||
""" Assign a service to this collection.
|
||||
"""
|
||||
|
||||
def deassignService(service):
|
||||
""" Remove a service from this collection.
|
||||
"""
|
||||
|
||||
|
||||
class IScheduledService(IService):
|
||||
""" A service that starts at a certain date/time and
|
||||
|
@ -346,20 +413,6 @@ class IScheduledService(IService):
|
|||
duration = Attribute('Time delta between start and end date/time.')
|
||||
|
||||
|
||||
class ICompoundService(IService):
|
||||
""" A service that consists of a set of sub-services, e.g. a conference,
|
||||
a course or a multi-day seminar.
|
||||
Sub-services may be other compound services or simple services;
|
||||
in addition there may be service parts additional strucure elements.
|
||||
"""
|
||||
|
||||
|
||||
class IServicePart(IService):
|
||||
""" A service that provides a substructure element of a compound service,
|
||||
e.g. a conference track or a conference day.
|
||||
"""
|
||||
|
||||
|
||||
class IClient(Interface):
|
||||
""" An fairly abstract interface for objects to be used as clients
|
||||
for services.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2009 Helmut Merz helmutm@cy55.de
|
||||
# Copyright (c) 2011 Helmut Merz helmutm@cy55.de
|
||||
#
|
||||
# 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
|
||||
|
@ -45,6 +45,7 @@ from cybertools.util.jeep import Jeep
|
|||
from cybertools.util.randomname import generateName
|
||||
from cybertools.organize.interfaces import IServiceManager
|
||||
from cybertools.organize.interfaces import IService, IScheduledService
|
||||
from cybertools.organize.interfaces import IServiceCollection
|
||||
from cybertools.organize.interfaces import IRegistration, IRegistrationTemplate
|
||||
from cybertools.organize.interfaces import IClientRegistrations
|
||||
|
||||
|
@ -94,8 +95,15 @@ class Service(object):
|
|||
|
||||
registrationsFactory = OOBTree
|
||||
registrationFactory = PersistentRegistration
|
||||
subservicesFactory = Jeep
|
||||
collectionsFactory = set
|
||||
|
||||
manager = None
|
||||
parent = None
|
||||
subservices = None
|
||||
collections = None
|
||||
|
||||
bookable = True
|
||||
category = None
|
||||
location = locationUrl = externalId = u''
|
||||
cost = 0.0
|
||||
|
@ -110,6 +118,10 @@ class Service(object):
|
|||
self.capacity = capacity
|
||||
if self.registrationsFactory is not None:
|
||||
self.registrations = self.registrationsFactory()
|
||||
if self.subservicesFactory is not None:
|
||||
self.subservices = self.subservicesFactory()
|
||||
if self.collectionsFactory is not None:
|
||||
self.collections = self.collectionsFactory()
|
||||
self.classification = []
|
||||
for k, v in kw.items():
|
||||
setattr(self, k, v)
|
||||
|
@ -120,6 +132,21 @@ class Service(object):
|
|||
def getManager(self):
|
||||
return self.manager
|
||||
|
||||
def getSubservices(self):
|
||||
return self.subservices.values()
|
||||
|
||||
def addSubservice(self, service):
|
||||
self.subservices.append(service)
|
||||
|
||||
def removeSubservice(self, service):
|
||||
del self.subservices[service.name]
|
||||
|
||||
def getParentService(self):
|
||||
return self.parent
|
||||
|
||||
def getServiceCollections(self):
|
||||
return self.collections.values()
|
||||
|
||||
def getClassification(self):
|
||||
return self.classification
|
||||
|
||||
|
@ -220,6 +247,30 @@ class ScheduledService(Service):
|
|||
return getattr(self.getManager(), 'end', None)
|
||||
|
||||
|
||||
class ServiceCollection(ScheduledService):
|
||||
|
||||
implements(IServiceCollection)
|
||||
|
||||
assignmentsFactory = set
|
||||
|
||||
assignments = None
|
||||
collectionType = u'day'
|
||||
|
||||
def __init__(self, name=None, title=u'', capacity=-1, **kw):
|
||||
super(ServiceCollection, self).__init__(name, title, capacity, kw)
|
||||
if self.assignmentsFactory is not None:
|
||||
self.assignments = self.assignmentsFactory()
|
||||
|
||||
def getAssignedServices(self):
|
||||
return self.assignments
|
||||
|
||||
def assignService(self, service):
|
||||
self.assignments.add(service)
|
||||
|
||||
def deassignService(self, service):
|
||||
self.assignments.remove(service)
|
||||
|
||||
|
||||
# registration stuff
|
||||
|
||||
class RegistrationTemplate(object):
|
||||
|
|
|
@ -327,8 +327,8 @@ registered for them.
|
|||
|
||||
>>> clientNames = [client1Name, client2Name, client3Name]
|
||||
|
||||
>>> for service in workshop.getServices():
|
||||
... for cn, reg in sorted(service.registrations.items()):
|
||||
>>> for svc in workshop.getServices():
|
||||
... for cn, reg in sorted(svc.registrations.items()):
|
||||
... print 'client-%i: ' % (clientNames.index(cn)+1), reg.service.name
|
||||
client-1: event1
|
||||
client-3: event2
|
||||
|
@ -745,6 +745,21 @@ Removal of services and clients
|
|||
1
|
||||
|
||||
|
||||
Compound Services
|
||||
=================
|
||||
|
||||
Let's set up a new service manager with a fairly complicated multi-day
|
||||
conference that is organized in parallel tracks.
|
||||
|
||||
>>> conference = site['conference'] = service.ServiceManager()
|
||||
>>> conference.__parent__ = site
|
||||
>>> conference.__name__ = 'conference'
|
||||
|
||||
>>> main = service.Service('conf_main', manager=conference,
|
||||
... title=u'Conference', capacity=5)
|
||||
>>> conference.services.append(main)
|
||||
|
||||
|
||||
Fin de partie
|
||||
=============
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue