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
|
# 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
|
# 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.')
|
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():
|
def isActive():
|
||||||
""" Return True if object is active, e.g. based on effective/expiration
|
""" Return True if object is active, e.g. based on effective/expiration
|
||||||
dates or workflow state.
|
dates or workflow state.
|
||||||
|
@ -214,11 +224,17 @@ class IService(Interface):
|
||||||
vocabulary=serviceCategories,
|
vocabulary=serviceCategories,
|
||||||
default='event',
|
default='event',
|
||||||
required=False,)
|
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(
|
allowRegWithNumber = schema.Bool(
|
||||||
title=_(u'Allow registration with number'),
|
title=_(u'Allow registration with number'),
|
||||||
description=_(u'When this field is checked more than one '
|
description=_(u'When this field is checked more than one '
|
||||||
'object (participant) may be assigned with one '
|
u'object (participant) may be assigned with one '
|
||||||
'registration by entering a corresponding number.'),
|
u'registration by entering a corresponding number.'),
|
||||||
required=False,)
|
required=False,)
|
||||||
presetRegistrationField = schema.Bool(
|
presetRegistrationField = schema.Bool(
|
||||||
title=_(u'Preset Registration Field'),
|
title=_(u'Preset Registration Field'),
|
||||||
|
@ -232,9 +248,9 @@ class IService(Interface):
|
||||||
allowDirectRegistration = schema.Bool(
|
allowDirectRegistration = schema.Bool(
|
||||||
title=_(u'Allow direct registration'),
|
title=_(u'Allow direct registration'),
|
||||||
description=_(u'When this field is checked participants '
|
description=_(u'When this field is checked participants '
|
||||||
'may register themselves directly on the page '
|
u'may register themselves directly on the page '
|
||||||
'with the service description; otherwise registration '
|
u'with the service description; otherwise registration '
|
||||||
'is only possible on a registration template.'),
|
u'is only possible on a registration template.'),
|
||||||
required=False,)
|
required=False,)
|
||||||
externalId = schema.TextLine(
|
externalId = schema.TextLine(
|
||||||
title=_(u'External ID'),
|
title=_(u'External ID'),
|
||||||
|
@ -247,49 +263,49 @@ class IService(Interface):
|
||||||
capacity = schema.Int(
|
capacity = schema.Int(
|
||||||
title=_(u'Capacity'),
|
title=_(u'Capacity'),
|
||||||
description=_(u'The capacity (maximum number of clients) '
|
description=_(u'The capacity (maximum number of clients) '
|
||||||
'of this service; a negative number means: '
|
u'of this service; a negative number means: '
|
||||||
'no restriction, i.e. unlimited capacity.'),
|
u'no restriction, i.e. unlimited capacity.'),
|
||||||
required=False,)
|
required=False,)
|
||||||
waitingList = schema.Bool(
|
waitingList = schema.Bool(
|
||||||
title=_(u'Waiting list'),
|
title=_(u'Waiting list'),
|
||||||
description=_(u'Check this field if participants beyond the '
|
description=_(u'Check this field if participants beyond the '
|
||||||
'capacity of the service should be kept in a '
|
u'capacity of the service should be kept in a '
|
||||||
'waiting list.'),
|
u'waiting list.'),
|
||||||
required=False,)
|
required=False,)
|
||||||
location = schema.TextLine(
|
location = schema.TextLine(
|
||||||
title=_(u'Location information'),
|
title=_(u'Location information'),
|
||||||
description=_(u'Basic location information or '
|
description=_(u'Basic location information or '
|
||||||
'start point for transport services.'),
|
u'start point for transport services.'),
|
||||||
required=False,)
|
required=False,)
|
||||||
locationUrl = schema.TextLine(
|
locationUrl = schema.TextLine(
|
||||||
title=_(u'URL for location'),
|
title=_(u'URL for location'),
|
||||||
description=_(u'Web address (URL) with more information '
|
description=_(u'Web address (URL) with more information '
|
||||||
'about the location.'),
|
u'about the location.'),
|
||||||
required=False,)
|
required=False,)
|
||||||
location2 = schema.TextLine(
|
location2 = schema.TextLine(
|
||||||
title=_(u'Location information (2)'),
|
title=_(u'Location information (2)'),
|
||||||
description=_(u'Additional location information or '
|
description=_(u'Additional location information or '
|
||||||
'end point for transport services.'),
|
u'end point for transport services.'),
|
||||||
required=False,)
|
required=False,)
|
||||||
location2Url = schema.TextLine(
|
location2Url = schema.TextLine(
|
||||||
title=_(u'URL for location (2)'),
|
title=_(u'URL for location (2)'),
|
||||||
description=_(u'Web address (URL) with more information '
|
description=_(u'Web address (URL) with more information '
|
||||||
'about the location.'),
|
u'about the location.'),
|
||||||
required=False,)
|
required=False,)
|
||||||
webAddress = schema.TextLine(
|
webAddress = schema.TextLine(
|
||||||
title=_(u'Web address'),
|
title=_(u'Web address'),
|
||||||
description=_(u'Web address (URL) for more information '
|
description=_(u'Web address (URL) for more information '
|
||||||
'about the service.'),
|
u'about the service.'),
|
||||||
required=False,)
|
required=False,)
|
||||||
info = schema.TextLine(
|
info = schema.TextLine(
|
||||||
title=_(u'Additional information'),
|
title=_(u'Additional information'),
|
||||||
description=_(u'Name/title of a document or web page that '
|
description=_(u'Name/title of a document or web page that '
|
||||||
'offers additional information.'),
|
u'offers additional information.'),
|
||||||
required=False,)
|
required=False,)
|
||||||
infoUrl = schema.TextLine(
|
infoUrl = schema.TextLine(
|
||||||
title=_(u'URL for additional information'),
|
title=_(u'URL for additional information'),
|
||||||
description=_(u'Web address (URL) of a document or web page that '
|
description=_(u'Web address (URL) of a document or web page that '
|
||||||
'offers additional information.'),
|
u'offers additional information.'),
|
||||||
required=False,)
|
required=False,)
|
||||||
|
|
||||||
availableCapacity = Attribute('Available capacity, i.e. number of seats '
|
availableCapacity = Attribute('Available capacity, i.e. number of seats '
|
||||||
|
@ -325,6 +341,57 @@ class IService(Interface):
|
||||||
""" Remove the client from this service's registrations.
|
""" 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):
|
class IScheduledService(IService):
|
||||||
""" A service that starts at a certain date/time and
|
""" 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.')
|
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):
|
class IClient(Interface):
|
||||||
""" An fairly abstract interface for objects to be used as clients
|
""" An fairly abstract interface for objects to be used as clients
|
||||||
for services.
|
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
|
# 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
|
# 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.util.randomname import generateName
|
||||||
from cybertools.organize.interfaces import IServiceManager
|
from cybertools.organize.interfaces import IServiceManager
|
||||||
from cybertools.organize.interfaces import IService, IScheduledService
|
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 IRegistration, IRegistrationTemplate
|
||||||
from cybertools.organize.interfaces import IClientRegistrations
|
from cybertools.organize.interfaces import IClientRegistrations
|
||||||
|
|
||||||
|
@ -94,8 +95,15 @@ class Service(object):
|
||||||
|
|
||||||
registrationsFactory = OOBTree
|
registrationsFactory = OOBTree
|
||||||
registrationFactory = PersistentRegistration
|
registrationFactory = PersistentRegistration
|
||||||
|
subservicesFactory = Jeep
|
||||||
|
collectionsFactory = set
|
||||||
|
|
||||||
manager = None
|
manager = None
|
||||||
|
parent = None
|
||||||
|
subservices = None
|
||||||
|
collections = None
|
||||||
|
|
||||||
|
bookable = True
|
||||||
category = None
|
category = None
|
||||||
location = locationUrl = externalId = u''
|
location = locationUrl = externalId = u''
|
||||||
cost = 0.0
|
cost = 0.0
|
||||||
|
@ -110,6 +118,10 @@ class Service(object):
|
||||||
self.capacity = capacity
|
self.capacity = capacity
|
||||||
if self.registrationsFactory is not None:
|
if self.registrationsFactory is not None:
|
||||||
self.registrations = self.registrationsFactory()
|
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 = []
|
self.classification = []
|
||||||
for k, v in kw.items():
|
for k, v in kw.items():
|
||||||
setattr(self, k, v)
|
setattr(self, k, v)
|
||||||
|
@ -120,6 +132,21 @@ class Service(object):
|
||||||
def getManager(self):
|
def getManager(self):
|
||||||
return self.manager
|
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):
|
def getClassification(self):
|
||||||
return self.classification
|
return self.classification
|
||||||
|
|
||||||
|
@ -220,6 +247,30 @@ class ScheduledService(Service):
|
||||||
return getattr(self.getManager(), 'end', None)
|
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
|
# registration stuff
|
||||||
|
|
||||||
class RegistrationTemplate(object):
|
class RegistrationTemplate(object):
|
||||||
|
|
|
@ -327,8 +327,8 @@ registered for them.
|
||||||
|
|
||||||
>>> clientNames = [client1Name, client2Name, client3Name]
|
>>> clientNames = [client1Name, client2Name, client3Name]
|
||||||
|
|
||||||
>>> for service in workshop.getServices():
|
>>> for svc in workshop.getServices():
|
||||||
... for cn, reg in sorted(service.registrations.items()):
|
... for cn, reg in sorted(svc.registrations.items()):
|
||||||
... print 'client-%i: ' % (clientNames.index(cn)+1), reg.service.name
|
... print 'client-%i: ' % (clientNames.index(cn)+1), reg.service.name
|
||||||
client-1: event1
|
client-1: event1
|
||||||
client-3: event2
|
client-3: event2
|
||||||
|
@ -745,6 +745,21 @@ Removal of services and clients
|
||||||
1
|
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
|
Fin de partie
|
||||||
=============
|
=============
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue