Interaction.py 9.24 KB
Newer Older
Jean-Paul Smets's avatar
Jean-Paul Smets committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
##############################################################################
#
# Copyright (c) 2003 Nexedi SARL and Contributors. All Rights Reserved.
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
##############################################################################
""" Interaction in a web-configurable workflow.

$Id$
"""

from OFS.SimpleItem import SimpleItem
from Globals import DTMLFile, PersistentMapping
from Acquisition import aq_inner, aq_parent
import Globals
from AccessControl import ClassSecurityInfo

30
from Products.ERP5Type.Permissions import ManagePortal
Jean-Paul Smets's avatar
Jean-Paul Smets committed
31 32 33 34

from Products.DCWorkflow.ContainerTab import ContainerTab
from Products.DCWorkflow.Guard import Guard
from Products.DCWorkflow.Expression import Expression
35
from Products.DCWorkflow.Transitions import TRIGGER_WORKFLOW_METHOD
Jean-Paul Smets's avatar
Jean-Paul Smets committed
36 37

from Products.ERP5 import _dtmldir
38
from Products.ERP5Type.Base import _aq_reset
Jean-Paul Smets's avatar
Jean-Paul Smets committed
39 40 41 42 43 44 45 46 47 48

class InteractionDefinition (SimpleItem):
    meta_type = 'Workflow Interaction'

    security = ClassSecurityInfo()
    security.declareObjectProtected(ManagePortal)

    title = ''
    description = ''
    new_state_id = ''
Jean-Paul Smets's avatar
Jean-Paul Smets committed
49
    trigger_type = TRIGGER_WORKFLOW_METHOD
Jean-Paul Smets's avatar
Jean-Paul Smets committed
50 51 52 53 54
    guard = None
    actbox_name = ''
    actbox_url = ''
    actbox_category = 'workflow'
    var_exprs = None  # A mapping.
Jean-Paul Smets's avatar
Jean-Paul Smets committed
55 56 57
    script_name = ()  # Executed before transition
    after_script_name = ()  # Executed after transition
    activate_script_name = ()  # Executed as activity
58 59
    method_id = ()
    portal_type_filter = None
60
    once_per_transaction = False
Jean-Paul Smets's avatar
Jean-Paul Smets committed
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116

    manage_options = (
        {'label': 'Properties', 'action': 'manage_properties'},
        {'label': 'Variables', 'action': 'manage_variables'},
        )

    def __init__(self, id):
        self.id = id

    def getId(self):
        return self.id

    def getGuardSummary(self):
        res = None
        if self.guard is not None:
            res = self.guard.getSummary()
        return res

    def getGuard(self):
        if self.guard is not None:
            return self.guard
        else:
            return Guard().__of__(self)  # Create a temporary guard.

    def getVarExprText(self, id):
        if not self.var_exprs:
            return ''
        else:
            expr = self.var_exprs.get(id, None)
            if expr is not None:
                return expr.text
            else:
                return ''

    def getWorkflow(self):
        return aq_parent(aq_inner(aq_parent(aq_inner(self))))

    def getAvailableStateIds(self):
        return self.getWorkflow().states.keys()

    def getAvailableScriptIds(self):
        return self.getWorkflow().scripts.keys()

    def getAvailableVarIds(self):
        return self.getWorkflow().variables.keys()

    _properties_form = DTMLFile('interaction_properties', _dtmldir)

    def manage_properties(self, REQUEST, manage_tabs_message=None):
        '''
        '''
        return self._properties_form(REQUEST,
                                     management_view='Properties',
                                     manage_tabs_message=manage_tabs_message,
                                     )

Jean-Paul Smets's avatar
Jean-Paul Smets committed
117 118
    def setProperties(self, title,
                      portal_type_filter=None,
119
                      trigger_type=TRIGGER_WORKFLOW_METHOD,
120
                      once_per_transaction=False,
Jean-Paul Smets's avatar
Jean-Paul Smets committed
121 122 123
                      script_name=(),
                      after_script_name=(),
                      activate_script_name=(),
Jean-Paul Smets's avatar
Jean-Paul Smets committed
124 125
                      actbox_name='', actbox_url='',
                      actbox_category='workflow',
126
                      method_id=(),
Jean-Paul Smets's avatar
Jean-Paul Smets committed
127
                      props=None, REQUEST=None, description=''):
Jean-Paul Smets's avatar
Jean-Paul Smets committed
128
        """
Jean-Paul Smets's avatar
Jean-Paul Smets committed
129 130 131
          Update transition properties
          XXX - then make sure that method_id is WorkflowMethod for portal_type_filter
          XXX - this will likely require dynamic
Jean-Paul Smets's avatar
Jean-Paul Smets committed
132
        """
133 134 135 136
        if type(method_id) is type(''):
            self.method_id = method_id.split()
        else:
            self.method_id = method_id
137 138 139 140 141 142 143 144
        if portal_type_filter is not None and 'None' in portal_type_filter:
          portal_type_filter = None
        if 'None' in after_script_name:
          after_script_name = ()
        if 'None' in activate_script_name:
          activate_script_name = ()
        if 'None' in script_name:
          script_name = ()
Jean-Paul Smets's avatar
Jean-Paul Smets committed
145
        self.portal_type_filter = portal_type_filter
Jean-Paul Smets's avatar
Jean-Paul Smets committed
146 147 148
        self.title = str(title)
        self.description = str(description)
        self.trigger_type = int(trigger_type)
149
        self.once_per_transaction = bool(once_per_transaction)
150 151 152
        self.script_name = script_name
        self.after_script_name = after_script_name
        self.activate_script_name = activate_script_name
Jean-Paul Smets's avatar
Jean-Paul Smets committed
153 154 155 156 157 158 159 160
        g = Guard()
        if g.changeFromProperties(props or REQUEST):
            self.guard = g
        else:
            self.guard = None
        self.actbox_name = str(actbox_name)
        self.actbox_url = str(actbox_url)
        self.actbox_category = str(actbox_category)
161 162
        # reset _aq_dynamic method cache.
        _aq_reset()
Jean-Paul Smets's avatar
Jean-Paul Smets committed
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
        if REQUEST is not None:
            return self.manage_properties(REQUEST, 'Properties changed.')

    _variables_form = DTMLFile('interaction_variables', _dtmldir)

    def manage_variables(self, REQUEST, manage_tabs_message=None):
        '''
        '''
        return self._variables_form(REQUEST,
                                     management_view='Variables',
                                     manage_tabs_message=manage_tabs_message,
                                     )

    def getVariableExprs(self):
        ''' get variable exprs for management UI
        '''
        ve = self.var_exprs
        if ve is None:
            return []
        else:
            ret = []
            for key in ve.keys():
                ret.append((key,self.getVarExprText(key)))
            return ret
    
    def getWorkflowVariables(self):
        ''' get all variables that are available form
            workflow and not handled yet.
        '''
        wf_vars = self.getAvailableVarIds()
        if self.var_exprs is None:
                return wf_vars
        ret = []
        for vid in wf_vars:
            if not self.var_exprs.has_key(vid):
                ret.append(vid)
        return ret

    def addVariable(self, id, text, REQUEST=None):
        '''
        Add a variable expression.
        '''
        if self.var_exprs is None:
            self.var_exprs = PersistentMapping()
        
        expr = None
        if text:
          expr = Expression(str(text))
        self.var_exprs[id] = expr
        
        if REQUEST is not None:
            return self.manage_variables(REQUEST, 'Variable added.')
    
    def deleteVariables(self,ids=[],REQUEST=None):
        ''' delete a WorkflowVariable from State
        '''
        ve = self.var_exprs
        for id in ids:
            if ve.has_key(id):
                del ve[id]
                
        if REQUEST is not None:
            return self.manage_variables(REQUEST, 'Variables deleted.')

    def setVariables(self, ids=[], REQUEST=None):
        ''' set values for Variables set by this state
        '''
        if self.var_exprs is None:
            self.var_exprs = PersistentMapping()
 
        ve = self.var_exprs
 
        if REQUEST is not None:
            for id in ve.keys():
                fname = 'varexpr_%s' % id

                val = REQUEST[fname]
                expr = None
                if val:
                    expr = Expression(str(REQUEST[fname]))
                ve[id] = expr

            return self.manage_variables(REQUEST, 'Variables changed.')

Globals.InitializeClass(InteractionDefinition)


class Interaction (ContainerTab):

    meta_type = 'Workflow Interaction'

    security = ClassSecurityInfo()
    security.declareObjectProtected(ManagePortal)

    all_meta_types = ({'name':InteractionDefinition.meta_type,
                       'action':'addInteraction',
                       },)

    _manage_interaction = DTMLFile('interactions', _dtmldir)

    def manage_main(self, REQUEST, manage_tabs_message=None):
        '''
        '''
        return self._manage_interaction(
            REQUEST,
            management_view='Interactions',
            manage_tabs_message=manage_tabs_message,
            )

    def addInteraction(self, id, REQUEST=None):
        '''
        '''
        tdef = InteractionDefinition(id)
        self._setObject(id, tdef)
        if REQUEST is not None:
            return self.manage_main(REQUEST, 'Interaction added.')

    def deleteInteractions(self, ids, REQUEST=None):
        '''
        '''
        for id in ids:
            self._delObject(id)
        if REQUEST is not None:
            return self.manage_main(REQUEST, 'Interaction(s) removed.')

Globals.InitializeClass(Interaction)