diff --git a/composer/schema/README.txt b/composer/schema/README.txt index bf0a073..840469a 100644 --- a/composer/schema/README.txt +++ b/composer/schema/README.txt @@ -51,8 +51,8 @@ Field types >>> from cybertools.composer.schema.interfaces import fieldTypes >>> sorted(t.token for t in fieldTypes) - ['checkbox', 'checkboxes', 'date', 'display', 'dropdown', 'email', - 'fileupload', 'html', 'list', 'number', 'password', 'radiobuttons', + ['checkbox', 'checkboxes', 'date', 'display', 'dropdown', 'email', 'explanation', + 'fileupload', 'heading', 'html', 'list', 'number', 'password', 'radiobuttons', 'spacer', 'textarea', 'textline'] >>> from zope.schema.vocabulary import SimpleVocabulary diff --git a/composer/schema/browser/schema.py b/composer/schema/browser/schema.py index f0afd7a..78121e2 100644 --- a/composer/schema/browser/schema.py +++ b/composer/schema/browser/schema.py @@ -25,8 +25,11 @@ $Id$ from zope import component from zope.cachedescriptors.property import Lazy -from cybertools.composer.schema.browser.common import BaseView from cybertools.composer.interfaces import IInstance +from cybertools.composer.rule.base import Event +from cybertools.composer.rule.interfaces import IRuleManager +from cybertools.composer.schema.browser.common import BaseView +from cybertools.composer.schema.client import eventTypes, getCheckoutRule from cybertools.composer.schema.interfaces import IClientFactory from cybertools.composer.schema.schema import FormState @@ -101,3 +104,60 @@ class SchemaView(BaseView): self.request.response.redirect(self.getNextUrl()) return False + +class FormManagerView(BaseView): + + isManageMode = False + + def getCustomView(self): + if self.isManageMode: + return None + viewName = self.context.getViewName() + if viewName: + return component.getMultiAdapter((self.context, self.request), + name=viewName) + return None + + @Lazy + def manager(self): + return self.context + + def overview(self): + return [] + + +class CheckoutView(BaseView): + + def getClient(self): + clientName = self.getClientName() + if clientName is None: + return None + return self.context.getClients().get(clientName) + + def getClientData(self): + client = self.getClient() + if client is None: + return {} + instance = IInstance(client) + data = instance.applyTemplate() + return data + + def update(self): + data = self.getClientData() + if data.get('errors'): + return True + form = self.request.form + clientName = self.getClientName() + if not form.get('action'): + return True # TODO: error, redirect to overview + client = self.getClient() + if client is None: + return True # TODO: error, redirect to overview + # send mail + rm = IRuleManager(self.context) + rm.addRule(getCheckoutRule(self.context.senderEmail)) + result = rm.handleEvent(Event(eventTypes['client.checkout'], + client, self.request)) + #params = '?message=thankyou&id=' + self.clientName + #self.request.response.redirect(self.url + '/checkout.html' + params) + return False diff --git a/composer/schema/client.py b/composer/schema/client.py index 458899b..8c7dd4a 100644 --- a/composer/schema/client.py +++ b/composer/schema/client.py @@ -29,6 +29,8 @@ from zope.component import adapts from zope.interface import implements from cybertools.composer.message.base import MessageManager +from cybertools.composer.rule.base import RuleManager, EventType +from cybertools.composer.rule.base import Rule, Action from cybertools.composer.schema.interfaces import IClient from cybertools.composer.schema.interfaces import IClientManager, IClientFactory from cybertools.util.jeep import Jeep @@ -113,3 +115,31 @@ class MessageManagerAdapter(MessageManager): def messages(self): return self.context.messages + +class RuleManagerAdapter(RuleManager): + + adapts(IClientManager) + + def __init__(self, context): + self.context = context + + +eventTypes = Jeep(( + EventType('client.checkout'), +)) + + +def getCheckoutRule(sender): + """ A rule for sending a confirmation message, provided by default. + """ + checkoutRule = Rule('checkout') + checkoutRule.events.append(eventTypes['client.checkout']) + checkoutRule.actions.append(Action('sendmail', + parameters=dict(sender=sender, + messageName='feedback_text'))) + checkoutRule.actions.append(Action('redirect', + parameters=dict(viewName='message_view.html', + messageName='feedback_html', + clearClient=True))) + return checkoutRule + diff --git a/composer/schema/interfaces.py b/composer/schema/interfaces.py index 1670688..bf6dbc4 100644 --- a/composer/schema/interfaces.py +++ b/composer/schema/interfaces.py @@ -106,8 +106,12 @@ fieldTypes = SimpleVocabulary(( instanceName='checkboxes'), FieldType('calculated', 'display', u'Calculated Value', instanceName='calculated'), + FieldType('heading', 'heading', u'Fieldgroup Heading', + fieldRenderer='field_heading', storeData=False), FieldType('spacer', 'spacer', u'Spacer', fieldRenderer='field_spacer', storeData=False), + FieldType('explanation', 'explanation', u'Explanation', + fieldRenderer='field_explanation', storeData=False), )) # TODO: move this to organize.service... (???) @@ -121,6 +125,12 @@ standardFieldNames = SimpleVocabulary(( # TODO: on organize.service: extend this list, e.g. with 'totalCost' )) +defaultValueTypes = SimpleVocabulary(( + SimpleTerm('string', 'string', 'String'), + SimpleTerm('tales', 'tales', 'TAL expression'), +)) + + class IField(IComponent): """ May be used for data entry or display. """ @@ -155,6 +165,13 @@ class IField(IComponent): description=_(u'Value with which to pre-set the field contents. ' 'Use this also for populating a calculated field.'), required=False,) + defaultValueType = schema.Choice( + title=_(u'Default type'), + description=_(u'The type of the default, i.e. a fixed string ' + u'or an expression that is used to calculate the value.'), + required=False, + default='string', + vocabulary=defaultValueTypes) required = schema.Bool( title=_(u'Required'), description=_(u'Must a value be entered into this field?'),