state handling for service registrations
git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@2123 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
c701a05d9e
commit
89510875c9
5 changed files with 107 additions and 36 deletions
|
@ -59,11 +59,13 @@ class Field(Component):
|
|||
def name(self):
|
||||
return self.__name__
|
||||
|
||||
@property
|
||||
def defaultValue(self):
|
||||
def getDefaultValue(self):
|
||||
if callable(self.default):
|
||||
return self.default()
|
||||
return self.default
|
||||
def setDefaultValue(self, value):
|
||||
self.default = value
|
||||
defaultValue = property(getDefaultValue, setDefaultValue)
|
||||
|
||||
@property
|
||||
def fieldRenderer(self):
|
||||
|
|
|
@ -32,6 +32,7 @@ from cybertools.organize.interfaces import serviceCategories
|
|||
from cybertools.composer.interfaces import IInstance
|
||||
from cybertools.composer.schema.browser.common import BaseView as SchemaBaseView
|
||||
from cybertools.composer.schema.interfaces import IClientFactory
|
||||
from cybertools.stateful.interfaces import IStateful
|
||||
from cybertools.util.format import formatDate
|
||||
|
||||
|
||||
|
@ -97,6 +98,7 @@ class ServiceManagerView(BaseView):
|
|||
first = tpl
|
||||
return first
|
||||
|
||||
#@Lazy - Zope 2.9 compatibility
|
||||
def registrationUrl(self):
|
||||
tpl = self.getRegistrationTemplate()
|
||||
return self.getUrlForObject(tpl)
|
||||
|
@ -170,7 +172,8 @@ class CheckoutView(ServiceManagerView):
|
|||
return True # TODO: error, redirect to overview
|
||||
regs = IClientRegistrations(client).getRegistrations()
|
||||
for reg in regs:
|
||||
pass # set state to submitted,
|
||||
stateful = IStateful(reg)
|
||||
stateful.doTransition(('submit', 'change'))
|
||||
# send mail
|
||||
# find thank you message and redirect to it
|
||||
params = '?message=thankyou&id=' + self.clientName
|
||||
|
@ -190,6 +193,7 @@ class ServiceView(BaseView):
|
|||
man = context.getManager()
|
||||
return ServiceManagerView(man, self.request).getRegistrationTemplate()
|
||||
|
||||
#@Lazy - Zope 2.9 compatibility
|
||||
def registrationUrl(self):
|
||||
tpl = self.getRegistrationTemplate()
|
||||
return self.getUrlForObject(tpl)
|
||||
|
@ -213,6 +217,12 @@ class ServiceView(BaseView):
|
|||
instance = IInstance(client)
|
||||
return instance.applyTemplate()
|
||||
|
||||
def getRegistrationInfo(self, reg):
|
||||
registration = self.getRegistrations()[reg]
|
||||
state = IStateful(registration).getStateObject()
|
||||
return dict(number=registration.number,
|
||||
state=state.name, stateTitle=state.title)
|
||||
|
||||
def update(self):
|
||||
newClient = False
|
||||
nextUrl = None
|
||||
|
|
|
@ -33,6 +33,7 @@ from zope.interface import implements, Interface
|
|||
from cybertools.composer.interfaces import IInstance
|
||||
from cybertools.composer.rule.base import RuleManager, EventType
|
||||
from cybertools.composer.schema.interfaces import IClientManager, IClient
|
||||
from cybertools.stateful.base import StatefulAdapter
|
||||
from cybertools.stateful.definition import registerStatesDefinition
|
||||
from cybertools.stateful.definition import StatesDefinition
|
||||
from cybertools.stateful.definition import State, Transition
|
||||
|
@ -97,11 +98,30 @@ class ServiceManager(RuleManager):
|
|||
return self.rules
|
||||
|
||||
|
||||
class Registration(object):
|
||||
|
||||
implements(IRegistration)
|
||||
|
||||
number = 1
|
||||
|
||||
def __init__(self, client, service, number=1):
|
||||
self.client = client
|
||||
self.service = service
|
||||
self.timeStamp = int(time())
|
||||
self.number = number
|
||||
|
||||
|
||||
class PersistentRegistration(Registration, Persistent):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class Service(object):
|
||||
|
||||
implements(IService)
|
||||
|
||||
registrationsFactory = OOBTree
|
||||
registrationFactory = PersistentRegistration
|
||||
|
||||
manager = None
|
||||
category = None
|
||||
|
@ -150,9 +170,9 @@ class Service(object):
|
|||
reg = self.registrations[clientName]
|
||||
if number != reg.number:
|
||||
reg.number = number
|
||||
self.registrations[clientName] = reg # persistence hack
|
||||
#self.registrations[clientName] = reg # persistence hack
|
||||
return reg
|
||||
reg = Registration(client, self, number)
|
||||
reg = self.registrationFactory(client, self, number)
|
||||
self.registrations[clientName] = reg
|
||||
return reg
|
||||
#if self.availableCapacity:
|
||||
|
@ -184,20 +204,7 @@ class ScheduledService(Service):
|
|||
return getattr(self.getManager(), 'end', None)
|
||||
|
||||
|
||||
# registration
|
||||
|
||||
class Registration(object):
|
||||
|
||||
implements(IRegistration)
|
||||
|
||||
number = 1
|
||||
|
||||
def __init__(self, client, service, number=1):
|
||||
self.client = client
|
||||
self.service = service
|
||||
self.timeStamp = int(time())
|
||||
self.number = number
|
||||
|
||||
# registration stuff
|
||||
|
||||
class RegistrationTemplate(object):
|
||||
|
||||
|
@ -253,7 +260,6 @@ class ClientRegistrations(object):
|
|||
service.unregister(self.context)
|
||||
|
||||
def getRegistrations(self):
|
||||
# TODO: restrict to services on this template
|
||||
regs = getattr(self.context, self.registrationsAttributeName, [])
|
||||
if self.template is not None:
|
||||
svcs = self.template.getServices().values()
|
||||
|
@ -261,19 +267,26 @@ class ClientRegistrations(object):
|
|||
return regs
|
||||
|
||||
|
||||
# registration states definition
|
||||
# registration states
|
||||
|
||||
registrationStates = 'organize.service.registration'
|
||||
|
||||
registerStatesDefinition(
|
||||
StatesDefinition('organize.service.registration',
|
||||
StatesDefinition(registrationStates,
|
||||
State('temporary', 'temporary', ('submit', 'cancel',)),
|
||||
State('submitted', 'submitted', ('retract', 'setwaiting', 'confirm', 'reject',)),
|
||||
State('submitted', 'submitted',
|
||||
('change', 'retract', 'setwaiting', 'confirm', 'reject',)),
|
||||
State('cancelled', 'cancelled', ('submit',)),
|
||||
State('retracted', 'retracted', ('submit',)),
|
||||
State('waiting', 'waiting', ('retract', 'confirm', 'reject',)),
|
||||
State('confirmed', 'confirmed', ('retract', 'reject',)),
|
||||
State('rejected', 'rejected', ('retract', 'setwaiting', 'confirm',)),
|
||||
State('waiting', 'waiting',
|
||||
('change', 'retract', 'confirm', 'reject',)),
|
||||
State('confirmed', 'confirmed',
|
||||
('change', 'retract', 'reject',)),
|
||||
State('rejected', 'rejected',
|
||||
('change', 'retract', 'setwaiting', 'confirm',)),
|
||||
Transition('cancel', 'Cancel registration', 'cancelled'),
|
||||
Transition('submit', 'Submit registration', 'submitted'),
|
||||
Transition('change', 'Change registration', 'submitted'),
|
||||
Transition('retract', 'Retract registration', 'retracted'),
|
||||
Transition('setwaiting', 'Set on waiting list', 'waiting'),
|
||||
Transition('confirm', 'Confirm registration', 'confirmed'),
|
||||
|
@ -282,7 +295,14 @@ registerStatesDefinition(
|
|||
))
|
||||
|
||||
|
||||
# event types
|
||||
class StatefulRegistration(StatefulAdapter):
|
||||
|
||||
component.adapts(IRegistration)
|
||||
|
||||
statesDefinition = registrationStates
|
||||
|
||||
|
||||
# event types for rule-based processing
|
||||
|
||||
eventTypes = Jeep((
|
||||
EventType('service.checkout'),
|
||||
|
@ -297,3 +317,11 @@ def clientRemoved(obj, event):
|
|||
regs = IClientRegistrations(obj)
|
||||
for r in regs.getRegistrations():
|
||||
r.service.unregister(obj)
|
||||
|
||||
def serviceRemoved(obj, event):
|
||||
""" Handle removal of a service.
|
||||
"""
|
||||
for r in obj.registrations.values():
|
||||
regs = IClientRegistrations(r.client)
|
||||
regs.unregister([obj])
|
||||
|
||||
|
|
|
@ -47,11 +47,18 @@ class Stateful(object):
|
|||
state = self.getState()
|
||||
return self.getStatesDefinition().states[state]
|
||||
|
||||
def doTransition(self, transition):
|
||||
""" execute transition.
|
||||
"""
|
||||
def doTransition(self, transition, historyInfo=None):
|
||||
sd = self.getStatesDefinition()
|
||||
sd.doTransitionFor(self, transition)
|
||||
if isinstance(transition, basestring):
|
||||
sd.doTransitionFor(self, transition)
|
||||
return
|
||||
available = [t.name for t in sd.getAvailableTransitionsFor(self)]
|
||||
for tr in transition:
|
||||
if tr in available:
|
||||
sd.doTransitionFor(self, tr)
|
||||
return
|
||||
raise ValueError("None of the transitions '%s' is available for state '%s'."
|
||||
% (repr(transition), self.getState()))
|
||||
|
||||
def getAvailableTransitions(self):
|
||||
sd = self.getStatesDefinition()
|
||||
|
|
|
@ -50,18 +50,42 @@ class IStateful(Interface):
|
|||
"""
|
||||
|
||||
def getStateObject():
|
||||
""" Return the state (an IState implementation) of the object.
|
||||
""" Return the state (an IState implementation) of the context object.
|
||||
"""
|
||||
|
||||
def doTransition(transition):
|
||||
def doTransition(transition, historyInfo=None):
|
||||
""" Execute a transition; the transition is specified by its name.
|
||||
|
||||
The ``transition`` argument may be an iterable; in this case
|
||||
its elements will be checked against the available transitions
|
||||
and the first one that's available will be executed.
|
||||
|
||||
The ``historyInfo`` argument is an arbitrary object that will be
|
||||
used for recording the transition execution in the history
|
||||
(only if the context object is adaptable to IHistorizable).
|
||||
"""
|
||||
|
||||
def getAvailableTransitions():
|
||||
""" Return the transitions for this object that are available in
|
||||
the current state. The implementation of the returned transition
|
||||
objects is not specified, they may be action dictionaries or
|
||||
special Transition objects.
|
||||
the current state. The returned transition objects should
|
||||
provide the ITransition interface.
|
||||
"""
|
||||
|
||||
|
||||
class IHistorizable(Interface):
|
||||
""" An object that may record history information, e.g. when
|
||||
performing a state transition.
|
||||
"""
|
||||
|
||||
def record(info):
|
||||
""" Record the information given (typically a mapping) with the
|
||||
object.
|
||||
"""
|
||||
|
||||
def recordTransition(stateFrom, stateTo, transition, historyInfo=None):
|
||||
""" Record the state transition characterized by the arguments
|
||||
(names of the states and the transition), optionally
|
||||
supplemented by the additional history information given.
|
||||
"""
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue