view for registrations listing for feedback message; improvements of registration forms
git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@2176 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
be088b1f63
commit
7f184927bd
9 changed files with 77 additions and 26 deletions
|
@ -11,7 +11,7 @@ Message Management
|
|||
|
||||
>>> messageText = '''Dear $person.firstname $person.lastname,
|
||||
... You have been registered for the following $services.
|
||||
... $@@list_registrations
|
||||
... $@@list_registrations_text
|
||||
... $footer
|
||||
... '''
|
||||
|
||||
|
@ -27,7 +27,7 @@ Message interpolation
|
|||
>>> t = MessageTemplate(messageText)
|
||||
>>> print t.safe_substitute({
|
||||
... 'person.firstname': 'John', 'person.lastname': 'Smith',
|
||||
... '@@list_registrations': '0815: Python Introduction',
|
||||
... '@@list_registrations_text': '0815: Python Introduction',
|
||||
... 'services': 'events',
|
||||
... 'footer': 'Regards, $sender'})
|
||||
Dear John Smith,
|
||||
|
@ -43,9 +43,9 @@ Working with message instances
|
|||
>>> mi = MessageInstance(None, manager.messages['feedback_text'], manager)
|
||||
>>> for key, value in mi.applyTemplate().items():
|
||||
... print key + ':', value
|
||||
subjectLine:
|
||||
text: Dear $person.firstname $person.lastname,
|
||||
You have been registered for the following events.
|
||||
$@@list_registrations
|
||||
$@@list_registrations_text
|
||||
Best regards, Jack
|
||||
<BLANKLINE>
|
||||
subjectLine:
|
||||
|
|
|
@ -42,16 +42,20 @@ class MessageInstance(Instance):
|
|||
self.manager = manager
|
||||
|
||||
def applyTemplate(self, data=None, **kw):
|
||||
data = DataProvider(self)
|
||||
text = MessageTemplate(self.template.text).safe_substitute(data)
|
||||
if data is None:
|
||||
data = {}
|
||||
dp = DataProvider(self, data)
|
||||
text = MessageTemplate(self.template.text).safe_substitute(dp)
|
||||
subject = self.template.subjectLine
|
||||
return Jeep((('subjectLine', subject), ('text', text)))
|
||||
data.update(dict(subjectLine=subject, text=text))
|
||||
return data
|
||||
|
||||
|
||||
class DataProvider(object):
|
||||
|
||||
def __init__(self, context):
|
||||
def __init__(self, context, data):
|
||||
self.context = context
|
||||
self.data = data
|
||||
|
||||
def __getitem__(self, key):
|
||||
client = self.context.client
|
||||
|
@ -61,8 +65,9 @@ class DataProvider(object):
|
|||
viewName = key[2:]
|
||||
if client is None:
|
||||
return '$' + key
|
||||
request = self.data.get('request') or TestRequest()
|
||||
view = component.queryMultiAdapter(
|
||||
(client.manager, TestRequest()), name=viewName)
|
||||
(client.manager, request), name=viewName)
|
||||
if view is not None:
|
||||
return view()
|
||||
else:
|
||||
|
@ -72,7 +77,7 @@ class DataProvider(object):
|
|||
# (client, messageManager.messages[key]), IInstance)
|
||||
mi = MessageInstance(client, messageManager.messages[key],
|
||||
messageManager)
|
||||
return mi.applyTemplate().text
|
||||
return mi.applyTemplate()['text']
|
||||
elif '.' in key:
|
||||
if client is None:
|
||||
return '$' + key
|
||||
|
|
|
@ -34,4 +34,4 @@ Rule-based Execution of Actions
|
|||
>>> client = Client()
|
||||
|
||||
>>> manager.handleEvent(Event(checkoutEvent, client))
|
||||
[{}]
|
||||
[{'request': None}]
|
||||
|
|
|
@ -99,11 +99,12 @@ class Event(object):
|
|||
|
||||
implements(IEvent)
|
||||
|
||||
def __init__(self, eventType, context=None):
|
||||
def __init__(self, eventType, context=None, request=None):
|
||||
self.eventType = eventType
|
||||
self.name = eventType.name
|
||||
self.title = eventType.title
|
||||
self.context = context
|
||||
self.request = request
|
||||
|
||||
|
||||
# conditions
|
||||
|
|
|
@ -43,7 +43,7 @@ class RuleInstance(Instance):
|
|||
cond = component.getAdapter(self, ICondition, name=c)
|
||||
if not cond():
|
||||
continue
|
||||
data = {}
|
||||
data = dict(request=self.event.request)
|
||||
for action in self.template.actions:
|
||||
handler = component.getAdapter(self, IActionHandler,
|
||||
name=action.handlerName)
|
||||
|
|
|
@ -96,6 +96,8 @@ class IEvent(Interface):
|
|||
name = Attribute('The name by which the event will be identified.')
|
||||
title = Attribute('A human readable title or label.')
|
||||
context = Attribute('An object that is associated with the event.')
|
||||
request = Attribute('Optional: the browser request that is associated '
|
||||
'with the event.')
|
||||
|
||||
|
||||
class ICondition(Interface):
|
||||
|
|
|
@ -37,7 +37,8 @@ class MailActionHandler(ActionHandler):
|
|||
client = self.context.context
|
||||
clientData = IInstance(client).applyTemplate()
|
||||
recipient = clientData['standard.email']
|
||||
msg = self.prepareMessage(data.subjectLine, data.text, sender, recipient)
|
||||
msg = self.prepareMessage(data['subjectLine'], data['text'],
|
||||
sender, recipient)
|
||||
data['mailInfo'] = self.sendMail(msg.as_string(), sender, [recipient])
|
||||
return data
|
||||
|
||||
|
|
|
@ -118,15 +118,15 @@ class ServiceManagerView(BaseView):
|
|||
result = []
|
||||
classific = []
|
||||
category = None
|
||||
maxLevel = 0
|
||||
svcs = sorted((svc.getCategory(), idx, svc)
|
||||
for idx, svc in enumerate(self.context.getServices()))
|
||||
for cat, idx, svc in svcs:
|
||||
if includeCategories and cat not in includeCategories:
|
||||
continue
|
||||
level = 0
|
||||
if cat != category:
|
||||
term = serviceCategories.getTermByToken(cat)
|
||||
result.append(dict(isHeadline=True, level=0, title=term.title,
|
||||
result.append(dict(isHeadline=True, level=level, title=term.title,
|
||||
name=cat,
|
||||
object=None))
|
||||
category = cat
|
||||
|
@ -141,10 +141,8 @@ class ServiceManagerView(BaseView):
|
|||
title=element.title,
|
||||
object=element.object,
|
||||
view=None))
|
||||
classific = clsf
|
||||
if level > maxLevel:
|
||||
maxLevel = level
|
||||
result.append(dict(isHeadline=False, level=maxLevel+1,
|
||||
classific = clsf[:idx+1]
|
||||
result.append(dict(isHeadline=False, level=level+1,
|
||||
name=svc.getName(),
|
||||
title=svc.title or svc.getName(),
|
||||
fromTo=self.getFromTo(svc),
|
||||
|
@ -190,12 +188,27 @@ class CheckoutView(ServiceManagerView):
|
|||
# send mail
|
||||
rm = IRuleManager(self.manager)
|
||||
rm.addRule(getCheckoutRule(self.manager.senderEmail))
|
||||
rm.handleEvent(Event(eventTypes['service.checkout'], client))
|
||||
rm.handleEvent(Event(eventTypes['service.checkout'], client, self.request))
|
||||
# find thank you message and redirect to it
|
||||
params = '?message=thankyou&id=' + self.clientName
|
||||
self.request.response.redirect(self.url + '/checkout.html' + params)
|
||||
return False
|
||||
|
||||
def listRegistrationsText(self):
|
||||
client = self.getClient()
|
||||
if client is None:
|
||||
return 'Error: no client given.'
|
||||
result = []
|
||||
regs = IClientRegistrations(client)
|
||||
regs = sorted(regs.getRegistrations(), key=self.sortKey)
|
||||
for reg in regs:
|
||||
service = reg.service
|
||||
line = '%-30s %27s' % (service.title, self.getFromTo(service))
|
||||
if service.allowRegWithNumber:
|
||||
line += ' %4i' % reg.number
|
||||
result.append(line)
|
||||
return '\n'.join(result)
|
||||
|
||||
|
||||
class ServiceView(BaseView):
|
||||
|
||||
|
@ -215,6 +228,16 @@ class ServiceView(BaseView):
|
|||
tpl = self.getRegistrationTemplate()
|
||||
return self.getUrlForObject(tpl)
|
||||
|
||||
def allowRegistration(self):
|
||||
context = self.context
|
||||
if not context.allowDirectRegistration:
|
||||
return False
|
||||
return (self.capacityAvailable()
|
||||
or self.getClientName() in context.registrations)
|
||||
|
||||
def capacityAvailable(self):
|
||||
return not self.context.capacity or self.context.availableCapacity
|
||||
|
||||
def getClientData(self):
|
||||
clientName = self.getClientName()
|
||||
if clientName is None:
|
||||
|
@ -271,7 +294,9 @@ class ServiceView(BaseView):
|
|||
nextUrl = self.getSchemaUrl()
|
||||
regs = self.state = IClientRegistrations(client)
|
||||
try:
|
||||
number = int(form.get('number', 1))
|
||||
number = int(form.get('number', 0))
|
||||
if number < 0:
|
||||
number = 0
|
||||
except ValueError:
|
||||
number = 1
|
||||
regs.validate(clientName, [self.context], [number])
|
||||
|
@ -318,6 +343,13 @@ class RegistrationTemplateView(BaseView):
|
|||
def sortKey(self, svc):
|
||||
return (svc.category, svc.getClassification(), svc.start)
|
||||
|
||||
def allowRegistration(self, service):
|
||||
return (self.capacityAvailable(service)
|
||||
or service in self.getRegisteredServices())
|
||||
|
||||
def capacityAvailable(self, service):
|
||||
return not service.capacity or service.availableCapacity
|
||||
|
||||
def getRegistrations(self):
|
||||
clientName = self.getClientName()
|
||||
if not clientName:
|
||||
|
@ -330,8 +362,11 @@ class RegistrationTemplateView(BaseView):
|
|||
regs.template = self.context
|
||||
return regs.getRegistrations()
|
||||
|
||||
def getRegisteredServices(self):
|
||||
return [r.service for r in self.getRegistrations()]
|
||||
|
||||
def getRegisteredServicesTokens(self):
|
||||
return [r.service.token for r in self.getRegistrations()]
|
||||
return [s.token for s in self.getRegisteredServices()]
|
||||
|
||||
def getRegistrationsDict(self):
|
||||
return dict((r.service.token, r) for r in self.getRegistrations())
|
||||
|
@ -377,7 +412,7 @@ class RegistrationTemplateView(BaseView):
|
|||
try:
|
||||
value = int(form.get('service.' + token, 0))
|
||||
except ValueError:
|
||||
value = 1
|
||||
value = 0
|
||||
if value > 0:
|
||||
newServices.append(svc)
|
||||
numbers.append(value)
|
||||
|
|
|
@ -39,6 +39,7 @@ 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
|
||||
from cybertools.stateful.interfaces import IStateful
|
||||
from cybertools.util.jeep import Jeep
|
||||
from cybertools.util.randomname import generateName
|
||||
from cybertools.organize.interfaces import IServiceManager
|
||||
|
@ -179,9 +180,11 @@ class Service(object):
|
|||
if clientName in self.registrations:
|
||||
del self.registrations[clientName]
|
||||
|
||||
def getNumberRegistered(self):
|
||||
def getNumberRegistered(self, ignoreTemporary=True):
|
||||
result = 0
|
||||
for r in self.registrations.values():
|
||||
if ignoreTemporary and IStateful(r).state == 'temporary':
|
||||
continue
|
||||
result += r.number
|
||||
return result
|
||||
|
||||
|
@ -277,7 +280,11 @@ class ClientRegistrations(object):
|
|||
for svc, n in zip(services, numbers):
|
||||
if clientName:
|
||||
oldReg = svc.registrations.get(clientName, None)
|
||||
oldN = oldReg and oldReg.number or 0
|
||||
if oldReg is None or IStateful(oldReg).state == 'temporary':
|
||||
# availableCapacity does not consider temporary registrations
|
||||
oldN = 0
|
||||
else:
|
||||
oldN = oldReg.number or 0
|
||||
else:
|
||||
oldN = 0
|
||||
if svc.capacity and svc.capacity > 0 and svc.availableCapacity < n - oldN:
|
||||
|
|
Loading…
Add table
Reference in a new issue