Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
138
Merge Requests
138
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
nexedi
erp5
Commits
9f2212cf
Commit
9f2212cf
authored
Dec 16, 2014
by
wenjie.zheng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ERP5WorkflowMethod class created, correct all workflow5 indacation to ERP5Workflow.
parent
6dbab7ce
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
221 additions
and
97 deletions
+221
-97
product/ERP5Type/Base.py
product/ERP5Type/Base.py
+197
-70
product/ERP5Type/ERP5Type.py
product/ERP5Type/ERP5Type.py
+7
-6
product/ERP5Type/dynamic/lazy_class.py
product/ERP5Type/dynamic/lazy_class.py
+7
-11
product/ERP5Workflow/Document/Workflow.py
product/ERP5Workflow/Document/Workflow.py
+10
-10
No files found.
product/ERP5Type/Base.py
View file @
9f2212cf
...
...
@@ -109,6 +109,7 @@ _MARKER = []
global
registered_workflow_method_set
wildcard_interaction_method_id_match
=
re
.
compile
(
r'[[.?*+{(\\]'
).
search
workflow_method_registry
=
[]
# XXX A set() would be better but would require a hash in WorkflowMethod class
erp5workflow_method_registry
=
[]
def
resetRegisteredWorkflowMethod
(
portal_type
=
None
):
"""
...
...
@@ -117,8 +118,14 @@ def resetRegisteredWorkflowMethod(portal_type=None):
for
method
in
workflow_method_registry
:
method
.
reset
(
portal_type
=
portal_type
)
class
WorkflowMethod
(
Method
):
def
resetRegisteredERP5WorkflowMethod
(
portal_type
=
None
):
"""
TODO: unwrap workflow methos which were standard methods initially
"""
for
method
in
erp5workflow_method_registry
:
method
.
reset
(
portal_type
=
portal_type
)
class
ERP5WorkflowMethod
(
Method
):
def
__init__
(
self
,
method
,
id
=
None
,
reindex
=
1
):
"""
method - a callable object or a method
...
...
@@ -182,7 +189,7 @@ class WorkflowMethod(Method):
for
wf_id
,
transition_list
in
invoke_once_dict
.
iteritems
():
valid_transition_list
=
[]
for
transition_id
in
transition_list
:
once_transition_key
=
(
'Products.ERP5Type.Base.WorkflowMethod.__call__'
,
once_transition_key
=
(
'Products.ERP5Type.Base.
ERP5
WorkflowMethod.__call__'
,
wf_id
,
transition_id
,
instance_path
)
once_transition_dict
[(
wf_id
,
transition_id
)]
=
once_transition_key
if
once_transition_key
not
in
transactional_variable
:
...
...
@@ -198,32 +205,132 @@ class WorkflowMethod(Method):
if
not
candidate_transition_item_list
:
return
apply
(
self
.
__dict__
[
'_m'
],
(
instance
,)
+
args
,
kw
)
#=============== Workflow5 Project, Wenjie, Dec 2014 =====================
### Access the ERP5Type workflow_list
if
instance
.
getTypeInfo
().
getTypeWorkflowList
()
!=
[]:
if
instance
.
getTypeInfo
().
getTypeWorkflowList
():
wf5_module
=
instance
.
getPortalObject
().
getDefaultModule
(
portal_type
=
"Workflow"
)
### Build the list of method which is call and will be invoked.
valid_transition_item_list
=
[]
for
wf_id
,
transition_list
in
candidate_transition_item_list
:
valid_list
=
[]
for
transition_id
in
transition_list
:
if
wf5_module
.
_getOb
(
wf_id
).
is
Workflow5
MethodSupported
(
instance
,
wf5_module
.
_getOb
(
wf_id
).
_getOb
(
transition_id
)):
if
wf5_module
.
_getOb
(
wf_id
).
is
ERP5Workflow
MethodSupported
(
instance
,
wf5_module
.
_getOb
(
wf_id
).
_getOb
(
transition_id
)):
#if wf5_module._getOb(wf_id)._getOb(transition_id) in instance.getCategoryStateValue().getDestinationValueList():
valid_list
.
append
(
transition_id
)
once_transition_key
=
once_transition_dict
.
get
((
wf_id
,
transition_id
))
transactional_variable
[
once_transition_key
]
=
1
else
:
raise
UnsupportedWorkflowMethod
(
instance
,
wf_id
,
transition_id
)
#else: ### don't do anything if no supported
#
raise UnsupportedWorkflowMethod(instance, wf_id, transition_id)
if
valid_list
:
valid_transition_item_list
.
append
((
wf_id
,
valid_list
))
### Execute method
for
wf_id
,
transition_list
in
valid_transition_item_list
:
for
tr
in
transition_list
:
#raise NotImplementedError (tr)
method5
=
wf5_module
.
_getOb
(
wf_id
).
_getOb
(
tr
)
method5
.
execute
(
instance
)
#=================================== wf5 =================================
def
registerERP5TransitionAlways
(
self
,
portal_type
,
workflow_id
,
transition_id
):
"""
Transitions registered as always will be invoked always
"""
transition_list
=
self
.
_invoke_always
.
setdefault
(
portal_type
,
{}).
setdefault
(
workflow_id
,
[])
if
transition_id
not
in
transition_list
:
transition_list
.
append
(
transition_id
)
self
.
registerERP5
()
def
registerERP5TransitionOncePerTransaction
(
self
,
portal_type
,
workflow_id
,
transition_id
):
"""
Transitions registered as one per transactions will be invoked
only once per transaction
"""
transition_list
=
self
.
_invoke_once
.
setdefault
(
portal_type
,
{}).
setdefault
(
workflow_id
,
[])
if
transition_id
not
in
transition_list
:
transition_list
.
append
(
transition_id
)
self
.
registerERP5
()
def
registerERP5
(
self
):
"""
Registers the method so that _aq_reset may later reset it
"""
erp5workflow_method_registry
.
append
(
self
)
class
WorkflowMethod
(
Method
):
def
__init__
(
self
,
method
,
id
=
None
,
reindex
=
1
):
"""
method - a callable object or a method
id - the workflow transition id. This is useful
to emulate "old" CMF behaviour but is
somehow inconsistent with the new registration based
approach implemented here.
We store id as _transition_id and use it
to register the transition for each portal
type and each workflow for which it is
applicable.
"""
self
.
_m
=
method
if
id
is
None
:
self
.
_transition_id
=
method
.
__name__
else
:
self
.
_transition_id
=
id
# Only publishable methods can be published as interactions
# A pure private method (ex. _doNothing) can not be published
# This is intentional to prevent methods such as submit, share to
# be called from a URL. If someone can show that this way
# is wrong (ex. for remote operation of a site), let us know.
if
not
method
.
__name__
.
startswith
(
'_'
):
self
.
__name__
=
method
.
__name__
for
func_id
in
[
'func_code'
,
'func_defaults'
,
'func_dict'
,
'func_doc'
,
'func_globals'
,
'func_name'
]:
setattr
(
self
,
func_id
,
getattr
(
method
,
func_id
,
None
))
self
.
_invoke_once
=
{}
self
.
_invoke_always
=
{}
# Store in a dict all workflow IDs which require to
# invoke wrapWorkflowMethod at every call
# during the same transaction
def
getTransitionId
(
self
):
return
self
.
_transition_id
def
__call__
(
self
,
instance
,
*
args
,
**
kw
):
"""
Invoke the wrapped method, and deal with the results.
"""
if
getattr
(
self
,
'__name__'
,
None
)
in
(
'getPhysicalPath'
,
'getId'
):
# To prevent infinite recursion, 2 methods must have special treatment
# this is clearly not the best way to implement this but it is
# already better than what we had. I (JPS) would prefer to use
# critical sections in this part of the code and a
# thread variable which tells in which semantic context the code
# should be executed. - XXX
return
self
.
_m
(
instance
,
*
args
,
**
kw
)
# Build a list of transitions which may need to be invoked
instance_path
=
instance
.
getPhysicalPath
()
portal_type
=
instance
.
portal_type
transactional_variable
=
getTransactionalVariable
()
invoke_once_dict
=
self
.
_invoke_once
.
get
(
portal_type
,
{})
valid_invoke_once_item_list
=
[]
# Only keep those transitions which were never invoked
once_transition_dict
=
{}
# New implementation does not use any longer wrapWorkflowMethod
# but directly calls the workflow methods
for
wf_id
,
transition_list
in
invoke_once_dict
.
iteritems
():
valid_transition_list
=
[]
for
transition_id
in
transition_list
:
once_transition_key
=
(
'Products.ERP5Type.Base.WorkflowMethod.__call__'
,
wf_id
,
transition_id
,
instance_path
)
once_transition_dict
[(
wf_id
,
transition_id
)]
=
once_transition_key
if
once_transition_key
not
in
transactional_variable
:
valid_transition_list
.
append
(
transition_id
)
if
valid_transition_list
:
valid_invoke_once_item_list
.
append
((
wf_id
,
valid_transition_list
))
candidate_transition_item_list
=
valid_invoke_once_item_list
+
\
self
.
_invoke_always
.
get
(
portal_type
,
{}).
items
()
#LOG('candidate_transition_item_list %s' % self.__name__, 0, str(candidate_transition_item_list))
# Try to return immediately if there are no transition to invoke
if
not
candidate_transition_item_list
:
return
apply
(
self
.
__dict__
[
'_m'
],
(
instance
,)
+
args
,
kw
)
# Prepare a list of transitions which should be invoked.
# This list is based on the results of isWorkflowMethodSupported.
...
...
@@ -231,69 +338,66 @@ class WorkflowMethod(Method):
# Otherwise, an exception is raised if the workflow transition does not
# exist from the current state, or if the guard rejects it.
try
:
try
:
wf
=
getattr
(
instance
.
getPortalObject
(),
'portal_workflow'
)
# portal_workflow is a list!
except
AttributeError
:
wf
=
getattr
(
instance
.
getPortalObject
(),
'portal_workflow'
)
# portal_workflow is a list!
except
AttributeError
:
# XXX instance is unwrapped(no acquisition)
# XXX I must think that what is a correct behavior.(Yusei)
return
self
.
_m
(
instance
,
*
args
,
**
kw
)
return
self
.
_m
(
instance
,
*
args
,
**
kw
)
valid_transition_item_list
=
[]
for
wf_id
,
transition_list
in
candidate_transition_item_list
:
valid_list
=
[]
candidate_workflow
=
wf
[
wf_id
]
for
transition_id
in
transition_list
:
if
candidate_workflow
.
isWorkflowMethodSupported
(
instance
,
transition_id
):
valid_list
.
append
(
transition_id
)
once_transition_key
=
once_transition_dict
.
get
((
wf_id
,
transition_id
))
if
once_transition_key
:
valid_transition_item_list
=
[]
for
wf_id
,
transition_list
in
candidate_transition_item_list
:
valid_list
=
[]
candidate_workflow
=
wf
[
wf_id
]
for
transition_id
in
transition_list
:
if
candidate_workflow
.
isWorkflowMethodSupported
(
instance
,
transition_id
):
valid_list
.
append
(
transition_id
)
once_transition_key
=
once_transition_dict
.
get
((
wf_id
,
transition_id
))
if
once_transition_key
:
# a run-once transition, prevent it from running again in
# the same transaction
transactional_variable
[
once_transition_key
]
=
1
elif
candidate_workflow
.
__class__
.
__name__
==
'DCWorkflowDefinition'
:
raise
UnsupportedWorkflowMethod
(
instance
,
wf_id
,
transition_id
)
# XXX Keep the log for projects that needs to comment out
# the previous line.
LOG
(
"WorkflowMethod.__call__"
,
ERROR
,
transactional_variable
[
once_transition_key
]
=
1
elif
candidate_workflow
.
__class__
.
__name__
==
'DCWorkflowDefinition'
:
raise
UnsupportedWorkflowMethod
(
instance
,
wf_id
,
transition_id
)
# XXX Keep the log for projects that needs to comment out
# the previous line.
LOG
(
"WorkflowMethod.__call__"
,
ERROR
,
"Transition %s/%s on %r is ignored. Current state is %r."
%
(
wf_id
,
transition_id
,
instance
,
candidate_workflow
.
_getWorkflowStateOf
(
instance
,
id_only
=
1
)))
if
valid_list
:
valid_transition_item_list
.
append
((
wf_id
,
valid_list
))
if
valid_list
:
valid_transition_item_list
.
append
((
wf_id
,
valid_list
))
#LOG('valid_transition_item_list %s' % self.__name__, 0, str(valid_transition_item_list))
# Call whatever must be called before changing states
for
wf_id
,
transition_list
in
valid_transition_item_list
:
wf
[
wf_id
].
notifyBefore
(
instance
,
transition_list
,
args
=
args
,
kw
=
kw
)
for
wf_id
,
transition_list
in
valid_transition_item_list
:
wf
[
wf_id
].
notifyBefore
(
instance
,
transition_list
,
args
=
args
,
kw
=
kw
)
# Compute expected result
result
=
apply
(
self
.
__dict__
[
'_m'
],
(
instance
,)
+
args
,
kw
)
result
=
apply
(
self
.
__dict__
[
'_m'
],
(
instance
,)
+
args
,
kw
)
# Change the state of statefull workflows
for
wf_id
,
transition_list
in
valid_transition_item_list
:
try
:
wf
[
wf_id
].
notifyWorkflowMethod
(
instance
,
transition_list
,
args
=
args
,
kw
=
kw
)
except
ObjectDeleted
:
# Re-raise with a different result.
raise
ObjectDeleted
(
result
)
except
ObjectMoved
,
ex
:
# Re-raise with a different result.
raise
ObjectMoved
(
ex
.
getNewObject
(),
result
)
for
wf_id
,
transition_list
in
valid_transition_item_list
:
try
:
wf
[
wf_id
].
notifyWorkflowMethod
(
instance
,
transition_list
,
args
=
args
,
kw
=
kw
)
except
ObjectDeleted
:
# Re-raise with a different result.
raise
ObjectDeleted
(
result
)
except
ObjectMoved
,
ex
:
# Re-raise with a different result.
raise
ObjectMoved
(
ex
.
getNewObject
(),
result
)
# Call whatever must be called after changing states
for
wf_id
,
transition_list
in
valid_transition_item_list
:
# /product/ERP5/InteractionWorkflow.py, update value, provide info
wf
[
wf_id
].
notifySuccess
(
instance
,
transition_list
,
result
,
args
=
args
,
kw
=
kw
)
for
wf_id
,
transition_list
in
valid_transition_item_list
:
# /product/ERP5/InteractionWorkflow.py, update value, provide info
wf
[
wf_id
].
notifySuccess
(
instance
,
transition_list
,
result
,
args
=
args
,
kw
=
kw
)
# Return result finally
return
result
return
result
# Interactions should not be disabled during normal operation. Only in very
# rare and specific cases like data migration. That's why it is implemented
# with temporary monkey-patching, instead of slowing down __call__ with yet
# another condition.
except
:
pass
_do_interaction
=
__call__
_no_interaction_lock
=
threading
.
Lock
()
_no_interaction_log
=
None
...
...
@@ -378,6 +482,7 @@ def _aq_reset():
class
PropertyHolder
(
object
):
isRADContent
=
1
WORKFLOW_METHOD_MARKER
=
(
'Base._doNothing'
,)
ERP5WORKFLOW_METHOD_MARKER
=
(
'Base._doNothing'
,)
RESERVED_PROPERTY_SET
=
set
((
'_constraints'
,
'_properties'
,
'_categories'
,
'__implements__'
,
'property_sheets'
,
'__ac_permissions__'
,
...
...
@@ -387,6 +492,7 @@ class PropertyHolder(object):
self
.
__name__
=
name
self
.
security
=
ClassSecurityInfo
()
# We create a new security info object
self
.
workflow_method_registry
=
{}
self
.
erp5workflow_method_registry
=
{}
self
.
_categories
=
[]
self
.
_properties
=
[]
...
...
@@ -414,6 +520,23 @@ class PropertyHolder(object):
wf_id
,
tr_id
)
def
registerERP5WorkflowMethod
(
self
,
id
,
wf_id
,
tr_id
,
once_per_transaction
=
0
):
portal_type
=
self
.
portal_type
ERP5workflow_method
=
getattr
(
self
,
id
,
None
)
if
ERP5workflow_method
is
None
:
# XXX: We should pass 'tr_id' as second parameter.
ERP5workflow_method
=
ERP5WorkflowMethod
(
Base
.
_doNothing
)
setattr
(
self
,
id
,
ERP5workflow_method
)
if
once_per_transaction
:
ERP5workflow_method
.
registerERP5TransitionOncePerTransaction
(
portal_type
,
wf_id
,
tr_id
)
else
:
ERP5workflow_method
.
registerERP5TransitionAlways
(
portal_type
,
wf_id
,
tr_id
)
def
declareProtected
(
self
,
permission
,
accessor_name
):
"""
It is possible to gain 30% of accessor RAM footprint
...
...
@@ -461,12 +584,26 @@ class PropertyHolder(object):
or
(
isinstance
(
x
[
1
],
types
.
TupleType
)
and
x
[
1
]
is
PropertyHolder
.
WORKFLOW_METHOD_MARKER
)]
def
getERP5WorkflowMethodItemList
(
self
):
"""
Return a list of tuple (id, method) for every workflow method
"""
return
[
x
for
x
in
self
.
_getPropertyHolderItemList
()
if
isinstance
(
x
[
1
],
ERP5WorkflowMethod
)
or
(
isinstance
(
x
[
1
],
types
.
TupleType
)
and
x
[
1
]
is
PropertyHolder
.
ERP5WORKFLOW_METHOD_MARKER
)]
def
getWorkflowMethodIdList
(
self
):
"""
Return the list of workflow method IDs
"""
return
[
x
[
0
]
for
x
in
self
.
getWorkflowMethodItemList
()]
def
getERP5WorkflowMethodIdList
(
self
):
"""
Return the list of workflow method IDs
"""
return
[
x
[
0
]
for
x
in
self
.
getERP5WorkflowMethodItemList
()]
def
_getClassDict
(
self
,
klass
,
inherited
=
1
,
local
=
1
):
"""
Return a dict for every property of a class
...
...
@@ -522,26 +659,26 @@ def getClassPropertyList(klass):
if
p
not
in
ps_list
])
return
ps_list
# ===================
Workflow5
Project, Wenjie, Dec 2014 ======================
# ===================
ERP5Workflow
Project, Wenjie, Dec 2014 ======================
### this function will be used in /product/ERP5Type/dynamic/lazy_class.py
### in generatePortalTypeAccessors()
def
intializePortalTypeERP5WorkflowMethod
(
ptype_klass
,
portal_
workflow5
):
### portal_
workflow5
is the entire ERP5Workflow module, need to access the
def
intializePortalTypeERP5WorkflowMethod
(
ptype_klass
,
portal_
ERP5Workflow
):
### portal_
ERP5Workflow
is the entire ERP5Workflow module, need to access the
### workflow_list from instance's portal type. So only the related erp5 workflow will be used.
wf5_module
=
aq_inner
(
portal_
workflow5
)
portal_type
=
portal_
workflow5
.
getPortalObject
().
getDefaultModule
(
portal_type
=
"portal_types"
)
wf5_module
=
aq_inner
(
portal_
ERP5Workflow
)
portal_type
=
portal_
ERP5Workflow
.
getPortalObject
().
getDefaultModule
(
portal_type
=
"portal_types"
)
pt
=
portal_type
.
_getOb
(
ptype_klass
.
__name__
)
#raise NotImplementedError (portal_type)
#raise NotImplementedError (wf5_module)#<Workflow Module at workflow_module>
### creat workflow method:
for
workflow5
in
pt
.
workflow_list
:
for
tr
in
wf5_module
.
_getOb
(
workflow5
).
objectValues
(
portal_type
=
"Transition"
):
for
ERP5Workflow
in
pt
.
workflow_list
:
for
tr
in
wf5_module
.
_getOb
(
ERP5Workflow
).
objectValues
(
portal_type
=
"Transition"
):
tr_id
=
tr
.
id
method_id
=
convertToMixedCase
(
tr_id
)
wf_id
=
workflow5
ptype_klass
.
registerWorkflowMethod
(
method_id
,
wf_id
,
tr_id
,
0
)
wf_id
=
ERP5Workflow
ptype_klass
.
register
ERP5
WorkflowMethod
(
method_id
,
wf_id
,
tr_id
,
0
)
#ptype_klass.security.declareProtected(Permissions.AccessContentsInformation,
# method_id)
#ptype_klass.registerWorkflowMethod(method_id, wf_id, tr_id)
...
...
@@ -552,18 +689,6 @@ def intializePortalTypeERP5WorkflowMethod(ptype_klass, portal_workflow5):
# method_id)
# ptype_klass.registerWorkflowMethod(method_id, wf_id, tr_id, 0)
# continue
""" ### useless at this stage, dec 2014
# Wrap method
if not callable(method):
LOG('initializePortalTypeERP5WorkflowMethods', 100,
'WARNING! Can not initialize %s on %s' %
\
(method_id, portal_type))
continue
if not isinstance(method, WorkflowMethod):
method = WorkflowMethod(method)
setattr(ptype_klass, method_id, method)
#ptype_klass.registerWorkflowMethod(method_id, wf_id, tr_id)
"""
#method.registerTransitionAlways(portal_type, wf_id, tr_id)
# =================== WF5 ======================================================
...
...
@@ -3529,3 +3654,5 @@ class TempBase(Base):
# allow_class(TempBase) in ERP5Type/Document/__init__.py will trample our
# ClassSecurityInfo with one that doesn't declare our public methods
InitializeClass
(
TempBase
)
product/ERP5Type/ERP5Type.py
View file @
9f2212cf
...
...
@@ -418,13 +418,14 @@ class ERP5TypeInformation(XMLObject,
for
workflow
in
workflow_tool
.
getWorkflowsFor
(
ob
):
workflow
.
notifyCreated
(
ob
)
### Project WORKFLOW5 , WENJIE , 2014 ###
for
workflow5
in
self
.
getTypeWorkflowList
():
# =========== Project ERP5Workflow , WENJIE , 2014 ================================
### workflow_list need to be defined somewhere.
### exp: ERP5Workflow in Person module won't work at this situation.
for
ERP5Workflow
in
self
.
getTypeWorkflowList
():
workflow_module
=
portal
.
getDefaultModule
(
portal_type
=
"Workflow"
)
workflow5
=
workflow_module
.
_getOb
(
workflow5
)
workflow5
.
initializeDocument
(
ob
)
ERP5Workflow
=
workflow_module
.
_getOb
(
ERP5Workflow
)
ERP5Workflow
.
initializeDocument
(
ob
)
# =========== WF5 ==============================================================
if
not
temp_object
:
init_script
=
self
.
getTypeInitScriptId
()
...
...
product/ERP5Type/dynamic/lazy_class.py
View file @
9f2212cf
...
...
@@ -266,26 +266,22 @@ class PortalTypeMetaClass(GhostBaseMetaClass, PropertyHolder):
else
:
initializePortalTypeDynamicWorkflowMethods
(
cls
,
portal_workflow
)
# ================== Workflow5 Project, Wenjie, Dec 2014 =======================
### the ERP5Workflow list is defined in ERP5Type, only try to get erp5workflow
### when it's an erp5workflow related type.
# ================== ERP5Workflow Project, Wenjie, Dec 2014 =======================
portal_type
=
site
.
getDefaultModule
(
portal_type
=
"portal_types"
)
### try to get workflow_list from related types then initialize the class of types
try
:
pt
=
portal_type
.
_getOb
(
cls
.
__name__
)
#raise NotImplemented (pt)
if
hasattr
(
pt
,
'workflow_list'
):
#if cls.__name__ == "Object Type": # Has to be redifined
portal_workflow5
=
site
.
getDefaultModule
(
portal_type
=
"Workflow"
)
#raise NotImplementedError (portal_workflow5) #<Workflow Module at workflow_module>
#raise NotImplementedError (cls.__module__) #<class 'erp5.portal_type.Category Property'>
if
portal_workflow5
is
None
:
### Get ERP5Workflow Module
portal_ERP5Workflow
=
site
.
getDefaultModule
(
portal_type
=
"Workflow"
)
if
portal_ERP5Workflow
is
None
:
LOG
(
"ERP5Type.Dynamic"
,
WARNING
,
"no
workflow5
methods for %s"
"no
ERP5Workflow
methods for %s"
%
cls
.
__name__
)
else
:
intializePortalTypeERP5WorkflowMethod
(
cls
,
portal_workflow5
)
### Generate Workflow Method
intializePortalTypeERP5WorkflowMethod
(
cls
,
portal_ERP5Workflow
)
except
:
pass
# ================== WF5 =======================================================
...
...
product/ERP5Workflow/Document/Workflow.py
View file @
9f2212cf
...
...
@@ -55,7 +55,7 @@ class Workflow(XMLObject):
isRADContent
=
1
### register the variable given by "base category value"
#state_var = 'state'
### In DCworkflow; state/transition can be registered inside workflow
### In DCworkflow; state/transition can be registered inside workflow
# Declarative security
security
=
ClassSecurityInfo
()
...
...
@@ -143,25 +143,25 @@ class Workflow(XMLObject):
transition
=
transition
,
transition_url
=
transition_url
,
state
=
state
)
# ==========
Workflow5
Project, Wenjie, Dec 2014 ===============================
def
is
Workflow5
MethodSupported
(
self
,
document
,
transition
):
s
tate
=
self
.
_getWorkflow5
StateOf
(
document
)
if
s
tate
is
None
:
# ==========
ERP5Workflow
Project, Wenjie, Dec 2014 ===============================
def
is
ERP5Workflow
MethodSupported
(
self
,
document
,
transition
):
s
def
=
self
.
_getERP5Workflow
StateOf
(
document
)
if
s
def
is
None
:
return
0
if
transition
in
s
tate
.
getDestinationValueList
():
if
transition
in
s
def
.
getDestinationValueList
():
return
1
return
0
### get workflow state from base category value:
def
_get
Workflow5
StateOf
(
self
,
ob
):
def
_get
ERP5Workflow
StateOf
(
self
,
ob
):
bc_id
=
self
.
getStateBaseCategory
()
state_path
=
ob
.
getCategoryList
()
state_path
=
state_path
[
0
].
lstrip
(
"%s/"
%
bc_id
)
###
if
state_path
is
not
None
:
s
tate
=
self
.
restrictedTraverse
(
state_path
)
else
:
s
tate
=
None
return
s
tate
s
def
=
self
.
restrictedTraverse
(
state_path
)
else
:
s
def
=
None
return
s
def
# =========== WF5 ==============================================================
###########
## Graph ##
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment