[gen] Optimisations, bugfixes and refactorings.
This commit is contained in:
parent
822e1a7c63
commit
f0c1f69573
|
@ -270,8 +270,7 @@ class Ref(Field):
|
||||||
<x if="refField.name != 'title'">
|
<x if="refField.name != 'title'">
|
||||||
<x var="zobj=tied.o; obj=tied; layoutType='cell';
|
<x var="zobj=tied.o; obj=tied; layoutType='cell';
|
||||||
innerRef=True; field=refField"
|
innerRef=True; field=refField"
|
||||||
if="zobj.showField(field.name, \
|
if="field.isShowable(zobj, 'result')">:field.pxRender</x>
|
||||||
layoutType='result')">:field.pxRender</x>
|
|
||||||
</x>
|
</x>
|
||||||
</td>
|
</td>
|
||||||
<td if="checkboxes" class="cbCell">
|
<td if="checkboxes" class="cbCell">
|
||||||
|
|
|
@ -331,7 +331,7 @@ class Transition:
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
def trigger(self, transitionName, obj, wf, comment, doAction=True,
|
def trigger(self, transitionName, obj, wf, comment, doAction=True,
|
||||||
doNotify=True, doHistory=True, doSay=True):
|
doNotify=True, doHistory=True, doSay=True, reindex=True):
|
||||||
'''This method triggers this transition on p_obj. The transition is
|
'''This method triggers this transition on p_obj. The transition is
|
||||||
supposed to be triggerable (call to self.isTriggerable must have been
|
supposed to be triggerable (call to self.isTriggerable must have been
|
||||||
performed before calling this method). If p_doAction is False, the
|
performed before calling this method). If p_doAction is False, the
|
||||||
|
@ -341,7 +341,9 @@ class Transition:
|
||||||
transition has been triggered will not be launched. If p_doHistory is
|
transition has been triggered will not be launched. If p_doHistory is
|
||||||
False, there will be no trace from this transition triggering in the
|
False, there will be no trace from this transition triggering in the
|
||||||
workflow history. If p_doSay is False, we consider the transition is
|
workflow history. If p_doSay is False, we consider the transition is
|
||||||
trigger programmatically, and no message is returned to the user.'''
|
trigger programmatically, and no message is returned to the user.
|
||||||
|
If p_reindex is False, object reindexing will be performed by the
|
||||||
|
calling method.'''
|
||||||
# Create the workflow_history dict if it does not exist.
|
# Create the workflow_history dict if it does not exist.
|
||||||
if not hasattr(obj.aq_base, 'workflow_history'):
|
if not hasattr(obj.aq_base, 'workflow_history'):
|
||||||
from persistent.mapping import PersistentMapping
|
from persistent.mapping import PersistentMapping
|
||||||
|
@ -368,12 +370,12 @@ class Transition:
|
||||||
if not doHistory: comment = '_invisible_'
|
if not doHistory: comment = '_invisible_'
|
||||||
obj.addHistoryEvent(action, review_state=targetStateName,
|
obj.addHistoryEvent(action, review_state=targetStateName,
|
||||||
comments=comment)
|
comments=comment)
|
||||||
# Reindex the object if required. Not only security-related indexes
|
|
||||||
# (Allowed, State) need to be updated here.
|
|
||||||
if not obj.isTemporary(): obj.reindex()
|
|
||||||
# Execute the related action if needed
|
# Execute the related action if needed
|
||||||
msg = ''
|
msg = ''
|
||||||
if doAction and self.action: msg = self.executeAction(obj, wf)
|
if doAction and self.action: msg = self.executeAction(obj, wf)
|
||||||
|
# Reindex the object if required. Not only security-related indexes
|
||||||
|
# (Allowed, State) need to be updated here.
|
||||||
|
if reindex and not obj.isTemporary(): obj.reindex()
|
||||||
# Send notifications if needed
|
# Send notifications if needed
|
||||||
if doNotify and self.notify and obj.getTool(True).mailEnabled:
|
if doNotify and self.notify and obj.getTool(True).mailEnabled:
|
||||||
sendNotification(obj.appy(), self, transitionName, wf)
|
sendNotification(obj.appy(), self, transitionName, wf)
|
||||||
|
@ -382,10 +384,21 @@ class Transition:
|
||||||
if not msg: msg = obj.translate('object_saved')
|
if not msg: msg = obj.translate('object_saved')
|
||||||
obj.say(msg)
|
obj.say(msg)
|
||||||
|
|
||||||
|
def onUiRequest(self, obj, wf, name, rq):
|
||||||
|
'''Executed when a user wants to trigger this transition from the UI.'''
|
||||||
|
tool = obj.getTool()
|
||||||
|
# Is this transition triggerable?
|
||||||
|
if not self.isTriggerable(obj, wf):
|
||||||
|
raise Exception('Transition "%s" can\'t be triggered.' % name)
|
||||||
|
# Trigger the transition
|
||||||
|
self.trigger(name, obj, wf, rq.get('comment', ''), reindex=False)
|
||||||
|
# Reindex obj if required.
|
||||||
|
if not obj.isTemporary(): obj.reindex()
|
||||||
|
return tool.goto(obj.getUrl(rq['HTTP_REFERER']))
|
||||||
|
|
||||||
class UiTransition:
|
class UiTransition:
|
||||||
'''Represents a widget that displays a transition.'''
|
'''Represents a widget that displays a transition.'''
|
||||||
|
pxView = Px('''
|
||||||
pxView = Px('''<x>
|
|
||||||
<!-- Real button -->
|
<!-- Real button -->
|
||||||
<input if="transition.mayTrigger" type="button" class="button"
|
<input if="transition.mayTrigger" type="button" class="button"
|
||||||
var2="label=transition.title"
|
var2="label=transition.title"
|
||||||
|
@ -397,11 +410,10 @@ class UiTransition:
|
||||||
|
|
||||||
<!-- Fake button, explaining why the transition can't be triggered -->
|
<!-- Fake button, explaining why the transition can't be triggered -->
|
||||||
<input if="not transition.mayTrigger" type="button"
|
<input if="not transition.mayTrigger" type="button"
|
||||||
class="fakeButton button" var2="label=transition.title"
|
class="fake button" var2="label=transition.title"
|
||||||
style=":'%s; %s' % (url('fake', bg=True),
|
style=":'%s; %s' % (url('fake', bg=True),
|
||||||
ztool.getButtonWidth(label))"
|
ztool.getButtonWidth(label))"
|
||||||
value=":label" title=":'%s: %s' % (label, transition.reason)"/>
|
value=":label" title=":transition.reason"/>''')
|
||||||
</x>''')
|
|
||||||
|
|
||||||
def __init__(self, name, transition, obj, mayTrigger, ):
|
def __init__(self, name, transition, obj, mayTrigger, ):
|
||||||
self.name = name
|
self.name = name
|
||||||
|
@ -419,7 +431,7 @@ class UiTransition:
|
||||||
if not mayTrigger:
|
if not mayTrigger:
|
||||||
self.mayTrigger = False
|
self.mayTrigger = False
|
||||||
self.reason = mayTrigger.msg
|
self.reason = mayTrigger.msg
|
||||||
# Require by the UiGroup.
|
# Required by the UiGroup.
|
||||||
self.colspan = 1
|
self.colspan = 1
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
|
@ -663,16 +663,6 @@ class BaseMixin:
|
||||||
self.REQUEST.set(field.name, '')
|
self.REQUEST.set(field.name, '')
|
||||||
return self.edit()
|
return self.edit()
|
||||||
|
|
||||||
def showField(self, name, layoutType='view'):
|
|
||||||
'''Must I show field named p_name on this p_layoutType ?'''
|
|
||||||
return self.getAppyType(name).isShowable(self, layoutType)
|
|
||||||
|
|
||||||
def getMethod(self, methodName):
|
|
||||||
'''Returns the method named p_methodName.'''
|
|
||||||
# If I write "self.aq_base" instead of self, acquisition will be
|
|
||||||
# broken on returned object.
|
|
||||||
return getattr(self, methodName, None)
|
|
||||||
|
|
||||||
def getCreateFolder(self):
|
def getCreateFolder(self):
|
||||||
'''When an object must be created from this one through a Ref field, we
|
'''When an object must be created from this one through a Ref field, we
|
||||||
must know where to put the newly create object: within this one if it
|
must know where to put the newly create object: within this one if it
|
||||||
|
@ -847,55 +837,6 @@ class BaseMixin:
|
||||||
return klass.styles[elem]
|
return klass.styles[elem]
|
||||||
return elem
|
return elem
|
||||||
|
|
||||||
def getTransitions(self, includeFake=True, includeNotShowable=False,
|
|
||||||
grouped=True):
|
|
||||||
'''This method returns info about transitions (as UiTransition
|
|
||||||
instances) that one can trigger from the user interface.
|
|
||||||
* if p_includeFake is True, it retrieves transitions that the user
|
|
||||||
can't trigger, but for which he needs to know for what reason he
|
|
||||||
can't trigger it;
|
|
||||||
* if p_includeNotShowable is True, it includes transitions for which
|
|
||||||
show=False. Indeed, because "showability" is only a UI concern,
|
|
||||||
and not a security concern, in some cases it has sense to set
|
|
||||||
includeNotShowable=True, because those transitions are triggerable
|
|
||||||
from a security point of view.
|
|
||||||
* If p_grouped is True, transitions are grouped according to their
|
|
||||||
"group" attribute, in a similar way to fields or searches.
|
|
||||||
'''
|
|
||||||
res = []
|
|
||||||
groups = {} # The already encountered groups of transitions.
|
|
||||||
wfPage = gen.Page('workflow')
|
|
||||||
wf = self.getWorkflow()
|
|
||||||
currentState = self.State(name=False)
|
|
||||||
# Loop on every transition
|
|
||||||
for name in dir(wf):
|
|
||||||
transition = getattr(wf, name)
|
|
||||||
if (transition.__class__.__name__ != 'Transition'): continue
|
|
||||||
# Filter transitions that do not have currentState as start state
|
|
||||||
if not transition.hasState(currentState, True): continue
|
|
||||||
# Check if the transition can be triggered
|
|
||||||
mayTrigger = transition.isTriggerable(self, wf)
|
|
||||||
# Compute the condition that will lead to including or not this
|
|
||||||
# transition
|
|
||||||
if not includeFake:
|
|
||||||
includeIt = mayTrigger
|
|
||||||
else:
|
|
||||||
includeIt = mayTrigger or isinstance(mayTrigger, gen.No)
|
|
||||||
if not includeNotShowable:
|
|
||||||
includeIt = includeIt and transition.isShowable(wf, self)
|
|
||||||
if not includeIt: continue
|
|
||||||
# Create the UiTransition instance.
|
|
||||||
info = UiTransition(name, transition, self, mayTrigger)
|
|
||||||
# Add the transition into the result.
|
|
||||||
if not transition.group or not grouped:
|
|
||||||
res.append(info)
|
|
||||||
else:
|
|
||||||
# Insert the UiGroup instance corresponding to transition.group.
|
|
||||||
uiGroup = transition.group.insertInto(res, groups, wfPage,
|
|
||||||
self.__class__.__name__, content='transitions')
|
|
||||||
uiGroup.addElement(info)
|
|
||||||
return res
|
|
||||||
|
|
||||||
def getAppyPhases(self, currentOnly=False, layoutType='view'):
|
def getAppyPhases(self, currentOnly=False, layoutType='view'):
|
||||||
'''Gets the list of phases that are defined for this content type. If
|
'''Gets the list of phases that are defined for this content type. If
|
||||||
p_currentOnly is True, the search is limited to the phase where the
|
p_currentOnly is True, the search is limited to the phase where the
|
||||||
|
@ -965,10 +906,10 @@ class BaseMixin:
|
||||||
if hasattr(appyObj, 'getSubTitle'): return appyObj.getSubTitle()
|
if hasattr(appyObj, 'getSubTitle'): return appyObj.getSubTitle()
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def notifyWorkflowCreated(self):
|
# Workflow methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
'''This method is called every time an object is created, be it temp or
|
def initializeWorkflow(self):
|
||||||
not. The objective here is to initialise workflow-related data on
|
'''Called when an object is created, be it temp or not, for initializing
|
||||||
the object.'''
|
workflow-related data on the object.'''
|
||||||
wf = self.getWorkflow()
|
wf = self.getWorkflow()
|
||||||
# Get the initial workflow state
|
# Get the initial workflow state
|
||||||
initialState = self.State(name=False)
|
initialState = self.State(name=False)
|
||||||
|
@ -994,6 +935,55 @@ class BaseMixin:
|
||||||
stateName = stateName or self.State()
|
stateName = stateName or self.State()
|
||||||
return '%s_%s' % (self.getWorkflow(name=True), stateName)
|
return '%s_%s' % (self.getWorkflow(name=True), stateName)
|
||||||
|
|
||||||
|
def getTransitions(self, includeFake=True, includeNotShowable=False,
|
||||||
|
grouped=True):
|
||||||
|
'''This method returns info about transitions (as UiTransition
|
||||||
|
instances) that one can trigger from the user interface.
|
||||||
|
* if p_includeFake is True, it retrieves transitions that the user
|
||||||
|
can't trigger, but for which he needs to know for what reason he
|
||||||
|
can't trigger it;
|
||||||
|
* if p_includeNotShowable is True, it includes transitions for which
|
||||||
|
show=False. Indeed, because "showability" is only a UI concern,
|
||||||
|
and not a security concern, in some cases it has sense to set
|
||||||
|
includeNotShowable=True, because those transitions are triggerable
|
||||||
|
from a security point of view.
|
||||||
|
* If p_grouped is True, transitions are grouped according to their
|
||||||
|
"group" attribute, in a similar way to fields or searches.
|
||||||
|
'''
|
||||||
|
res = []
|
||||||
|
groups = {} # The already encountered groups of transitions.
|
||||||
|
wfPage = gen.Page('workflow')
|
||||||
|
wf = self.getWorkflow()
|
||||||
|
currentState = self.State(name=False)
|
||||||
|
# Loop on every transition
|
||||||
|
for name in dir(wf):
|
||||||
|
transition = getattr(wf, name)
|
||||||
|
if (transition.__class__.__name__ != 'Transition'): continue
|
||||||
|
# Filter transitions that do not have currentState as start state
|
||||||
|
if not transition.hasState(currentState, True): continue
|
||||||
|
# Check if the transition can be triggered
|
||||||
|
mayTrigger = transition.isTriggerable(self, wf)
|
||||||
|
# Compute the condition that will lead to including or not this
|
||||||
|
# transition
|
||||||
|
if not includeFake:
|
||||||
|
includeIt = mayTrigger
|
||||||
|
else:
|
||||||
|
includeIt = mayTrigger or isinstance(mayTrigger, gen.No)
|
||||||
|
if not includeNotShowable:
|
||||||
|
includeIt = includeIt and transition.isShowable(wf, self)
|
||||||
|
if not includeIt: continue
|
||||||
|
# Create the UiTransition instance.
|
||||||
|
info = UiTransition(name, transition, self, mayTrigger)
|
||||||
|
# Add the transition into the result.
|
||||||
|
if not transition.group or not grouped:
|
||||||
|
res.append(info)
|
||||||
|
else:
|
||||||
|
# Insert the UiGroup instance corresponding to transition.group.
|
||||||
|
uiGroup = transition.group.insertInto(res, groups, wfPage,
|
||||||
|
self.__class__.__name__, content='transitions')
|
||||||
|
uiGroup.addElement(info)
|
||||||
|
return res
|
||||||
|
|
||||||
def applyUserIdChange(self, oldId, newId):
|
def applyUserIdChange(self, oldId, newId):
|
||||||
'''A user whose ID was p_oldId has now p_newId. If the old ID was
|
'''A user whose ID was p_oldId has now p_newId. If the old ID was
|
||||||
mentioned in self's local roles, update it to the new ID. This
|
mentioned in self's local roles, update it to the new ID. This
|
||||||
|
@ -1156,34 +1146,20 @@ class BaseMixin:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def onExecuteAction(self):
|
def onExecuteAction(self):
|
||||||
'''This method is called every time a user wants to execute an Appy
|
'''Called when a user wants to execute an Appy action on an object.'''
|
||||||
action on an object.'''
|
|
||||||
rq = self.REQUEST
|
rq = self.REQUEST
|
||||||
return self.getAppyType(rq['fieldName']).onUiRequest(self, rq)
|
return self.getAppyType(rq['fieldName']).onUiRequest(self, rq)
|
||||||
|
|
||||||
def trigger(self, transitionName, comment='', doAction=True, doNotify=True,
|
|
||||||
doHistory=True, doSay=True, noSecurity=False):
|
|
||||||
'''Triggers transition named p_transitionName.'''
|
|
||||||
# Check that this transition exists.
|
|
||||||
wf = self.getWorkflow()
|
|
||||||
if not hasattr(wf, transitionName) or \
|
|
||||||
getattr(wf, transitionName).__class__.__name__ != 'Transition':
|
|
||||||
raise 'Transition "%s" was not found.' % transitionName
|
|
||||||
# Is this transition triggerable?
|
|
||||||
transition = getattr(wf, transitionName)
|
|
||||||
if not transition.isTriggerable(self, wf, noSecurity=noSecurity):
|
|
||||||
raise 'Transition "%s" can\'t be triggered.' % transitionName
|
|
||||||
# Trigger the transition
|
|
||||||
transition.trigger(transitionName, self, wf, comment, doAction=doAction,
|
|
||||||
doNotify=doNotify, doHistory=doHistory, doSay=doSay)
|
|
||||||
|
|
||||||
def onTrigger(self):
|
def onTrigger(self):
|
||||||
'''This method is called whenever a user wants to trigger a workflow
|
'''Called when a user wants to trigger a transition on an object.'''
|
||||||
transition on an object.'''
|
|
||||||
rq = self.REQUEST
|
rq = self.REQUEST
|
||||||
self.trigger(rq['workflow_action'], comment=rq.get('comment', ''))
|
wf = self.getWorkflow()
|
||||||
self.reindex()
|
# Get the transition
|
||||||
return self.goto(self.getUrl(rq['HTTP_REFERER']))
|
name = rq['transition']
|
||||||
|
transition = getattr(wf, name, None)
|
||||||
|
if not transition or (transition.__class__.__name__ != 'Transition'):
|
||||||
|
raise Exception('Transition "%s" not found.' % name)
|
||||||
|
return transition.onUiRequest(self, wf, name, rq)
|
||||||
|
|
||||||
def getRolesFor(self, permission):
|
def getRolesFor(self, permission):
|
||||||
'''Gets, according to the workflow, the roles that are currently granted
|
'''Gets, according to the workflow, the roles that are currently granted
|
||||||
|
|
|
@ -70,7 +70,7 @@ input.button { color: #666666; height: 20px; width: 130px;
|
||||||
cursor:pointer; font-size: 90%; padding-left: 10px;
|
cursor:pointer; font-size: 90%; padding-left: 10px;
|
||||||
background-color: white; background-repeat: no-repeat;
|
background-color: white; background-repeat: no-repeat;
|
||||||
background-position: 5% 25%; box-shadow: 2px 2px 2px #888888}
|
background-position: 5% 25%; box-shadow: 2px 2px 2px #888888}
|
||||||
.fakeButton { background-color: #e6e6e6 !important ; cursor:help !important }
|
.fake { background-color: #e6e6e6 !important ; cursor:help !important }
|
||||||
.buttons { margin-left: 4px }
|
.buttons { margin-left: 4px }
|
||||||
.message { position: absolute; top: -40px; left: 50%; font-size: 90%;
|
.message { position: absolute; top: -40px; left: 50%; font-size: 90%;
|
||||||
width: 600px; border: 1px #F0C36D solid; padding: 6px;
|
width: 600px; border: 1px #F0C36D solid; padding: 6px;
|
||||||
|
@ -99,7 +99,7 @@ td.search { padding-top: 8px }
|
||||||
.content { padding: 14px 14px 9px 15px; background-color: #f1f1f1 }
|
.content { padding: 14px 14px 9px 15px; background-color: #f1f1f1 }
|
||||||
.popup { display: none; position: absolute; top: 30%; left: 35%;
|
.popup { display: none; position: absolute; top: 30%; left: 35%;
|
||||||
width: 350px; z-index : 100; background: white; padding: 8px;
|
width: 350px; z-index : 100; background: white; padding: 8px;
|
||||||
border: 1px solid grey }
|
border: 1px solid grey; box-shadow: 2px 2px 2px #888888}
|
||||||
.dropdown { display:none; position: absolute; border: 1px solid #cccccc;
|
.dropdown { display:none; position: absolute; border: 1px solid #cccccc;
|
||||||
background-color: white; padding: 3px 4px 0 }
|
background-color: white; padding: 3px 4px 0 }
|
||||||
.dropdownMenu { cursor: pointer; padding-right: 4px; font-size: 93% }
|
.dropdownMenu { cursor: pointer; padding-right: 4px; font-size: 93% }
|
||||||
|
|
|
@ -529,10 +529,8 @@ function submitAppyForm(button) {
|
||||||
// Function used for triggering a workflow transition
|
// Function used for triggering a workflow transition
|
||||||
function triggerTransition(formId, transitionId, msg) {
|
function triggerTransition(formId, transitionId, msg) {
|
||||||
var theForm = document.getElementById(formId);
|
var theForm = document.getElementById(formId);
|
||||||
theForm.workflow_action.value = transitionId;
|
theForm.transition.value = transitionId;
|
||||||
if (!msg) {
|
if (!msg) { theForm.submit(); }
|
||||||
theForm.submit();
|
|
||||||
}
|
|
||||||
else { // Ask the user to confirm.
|
else { // Ask the user to confirm.
|
||||||
askConfirm('form', formId, msg, true);
|
askConfirm('form', formId, msg, true);
|
||||||
}
|
}
|
||||||
|
|
BIN
gen/ui/search.png
Normal file
BIN
gen/ui/search.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 297 B |
|
@ -46,7 +46,7 @@ def createObject(folder, id, className, appName, wf=True, noSecurity=False):
|
||||||
obj.modified = obj.created
|
obj.modified = obj.created
|
||||||
from persistent.mapping import PersistentMapping
|
from persistent.mapping import PersistentMapping
|
||||||
obj.__ac_local_roles__ = PersistentMapping({ userId: ['Owner'] })
|
obj.__ac_local_roles__ = PersistentMapping({ userId: ['Owner'] })
|
||||||
if wf: obj.notifyWorkflowCreated()
|
if wf: obj.initializeWorkflow()
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
|
@ -347,7 +347,7 @@ class ToolWrapper(AbstractWrapper):
|
||||||
<!-- Any other field -->
|
<!-- Any other field -->
|
||||||
<x if="field.name != 'title'">
|
<x if="field.name != 'title'">
|
||||||
<x var="layoutType='cell'; innerRef=True"
|
<x var="layoutType='cell'; innerRef=True"
|
||||||
if="zobj.showField(field.name, 'result')">:field.pxRender</x>
|
if="field.isShowable(zobj, 'result')">:field.pxRender</x>
|
||||||
</x>''')
|
</x>''')
|
||||||
|
|
||||||
# Show query results as a list.
|
# Show query results as a list.
|
||||||
|
|
|
@ -366,7 +366,7 @@ class AbstractWrapper(object):
|
||||||
var2="formId='trigger_%s' % targetObj.UID()" method="post"
|
var2="formId='trigger_%s' % targetObj.UID()" method="post"
|
||||||
id=":formId" action=":targetObj.absolute_url() + '/do'">
|
id=":formId" action=":targetObj.absolute_url() + '/do'">
|
||||||
<input type="hidden" name="action" value="Trigger"/>
|
<input type="hidden" name="action" value="Trigger"/>
|
||||||
<input type="hidden" name="workflow_action"/>
|
<input type="hidden" name="transition"/>
|
||||||
<!-- Input field for storing the comment coming from the popup -->
|
<!-- Input field for storing the comment coming from the popup -->
|
||||||
<textarea id="comment" name="comment" cols="30" rows="3"
|
<textarea id="comment" name="comment" cols="30" rows="3"
|
||||||
style="display:none"></textarea>
|
style="display:none"></textarea>
|
||||||
|
@ -854,13 +854,17 @@ class AbstractWrapper(object):
|
||||||
return self.o.translate(label, mapping, domain, language=language,
|
return self.o.translate(label, mapping, domain, language=language,
|
||||||
format=format)
|
format=format)
|
||||||
|
|
||||||
def do(self, transition, comment='', doAction=True, doNotify=True,
|
def do(self, name, comment='', doAction=True, doNotify=True, doHistory=True,
|
||||||
doHistory=True, noSecurity=False):
|
noSecurity=False):
|
||||||
'''This method allows to trigger on p_self a workflow p_transition
|
'''Triggers on p_self a transition named p_name programmatically.'''
|
||||||
programmatically. See doc in self.o.do.'''
|
o = self.o
|
||||||
return self.o.trigger(transition, comment, doAction=doAction,
|
wf = o.getWorkflow()
|
||||||
doNotify=doNotify, doHistory=doHistory,
|
tr = getattr(wf, name, None)
|
||||||
doSay=False, noSecurity=noSecurity)
|
if not tr or (tr.__class__.__name__ != 'Transition'):
|
||||||
|
raise Exception('Transition "%s" not found.' % name)
|
||||||
|
return tr.trigger(name, o, wf, comment, doAction=doAction,
|
||||||
|
doNotify=doNotify, doHistory=doHistory, doSay=False,
|
||||||
|
noSecurity=noSecurity)
|
||||||
|
|
||||||
def log(self, message, type='info'): return self.o.log(message, type)
|
def log(self, message, type='info'): return self.o.log(message, type)
|
||||||
def say(self, message, type='info'): return self.o.say(message, type)
|
def say(self, message, type='info'): return self.o.say(message, type)
|
||||||
|
|
Loading…
Reference in a new issue