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
d8c7e3f9
Commit
d8c7e3f9
authored
Dec 16, 2014
by
wenjie.zheng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
lazy_class use _getOb instead getattr, remove unnecessary commentaries.
parent
70ad0fcb
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
3860 additions
and
3891 deletions
+3860
-3891
product/ERP5Type/Base.py
product/ERP5Type/Base.py
+3639
-3658
product/ERP5Type/ERP5Type.py
product/ERP5Type/ERP5Type.py
+0
-4
product/ERP5Type/dynamic/lazy_class.py
product/ERP5Type/dynamic/lazy_class.py
+3
-10
product/ERP5Workflow/Document/Workflow.py
product/ERP5Workflow/Document/Workflow.py
+218
-219
No files found.
product/ERP5Type/Base.py
View file @
d8c7e3f9
This source diff could not be displayed because it is too large. You can
view the blob
instead.
product/ERP5Type/ERP5Type.py
View file @
d8c7e3f9
...
...
@@ -418,14 +418,10 @@ class ERP5TypeInformation(XMLObject,
for
workflow
in
workflow_tool
.
getWorkflowsFor
(
ob
):
workflow
.
notifyCreated
(
ob
)
# =========== 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"
)
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 @
d8c7e3f9
...
...
@@ -266,25 +266,18 @@ class PortalTypeMetaClass(GhostBaseMetaClass, PropertyHolder):
else
:
initializePortalTypeDynamicWorkflowMethods
(
cls
,
portal_workflow
)
# ================== 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
pt
=
getattr
(
portal_type
,
cls
.
__name__
,
None
)
pt
=
portal_type
.
_getOb
(
cls
.
__name__
,
None
)
if
pt
is
not
None
:
#pt = portal_type._getOb(cls.__name__)
#raise NotImplemented (pt)
wf
=
getattr
(
pt
,
'workflow_list'
,
None
)
if
wf
is
not
None
:
### Get ERP5Workflow Module
workflow_list
=
getattr
(
pt
,
'workflow_list'
,
None
)
if
workflow_list
is
not
None
:
portal_ERP5Workflow
=
site
.
getDefaultModule
(
portal_type
=
"Workflow"
)
if
portal_ERP5Workflow
is
None
:
LOG
(
"ERP5Type.Dynamic"
,
WARNING
,
"no ERP5Workflow methods for %s"
%
cls
.
__name__
)
else
:
### Generate Workflow Method
intializePortalTypeERP5WorkflowMethod
(
cls
,
portal_ERP5Workflow
)
# ================== WF5 =======================================================
# portal type group methods, isNodeType, isResourceType...
from
Products.ERP5Type.ERP5Type
import
ERP5TypeInformation
...
...
product/ERP5Workflow/Document/Workflow.py
View file @
d8c7e3f9
##############################################################################
#
# Copyright (c) 2006 Nexedi SARL and Contributors. All Rights Reserved.
# Romain Courteaud <romain@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# 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.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from
AccessControl
import
ClassSecurityInfo
from
Acquisition
import
aq_inner
from
Acquisition
import
aq_parent
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5Type.XMLObject
import
XMLObject
from
Products.ERP5Type.Globals
import
PersistentMapping
from
Products.ERP5Type.Accessor
import
WorkflowState
from
Products.ERP5Type
import
Permissions
from
tempfile
import
mktemp
import
os
from
Products.DCWorkflowGraph.config
import
DOT_EXE
from
Products.DCWorkflowGraph.DCWorkflowGraph
import
bin_search
,
getGraph
from
Products.ERP5Type.Utils
import
UpperCase
from
Acquisition
import
aq_base
#import String
from
DateTime
import
DateTime
class
Workflow
(
XMLObject
):
"""
A ERP5 Workflow.
"""
meta_type
=
'ERP5 Workflow'
portal_type
=
'Workflow'
add_permission
=
Permissions
.
AddPortalContent
isPortalContent
=
1
isRADContent
=
1
### register the variable given by "base category value"
#state_var = 'state'
### In DCworkflow; state/transition can be registered inside workflow
# Declarative security
security
=
ClassSecurityInfo
()
security
.
declareObjectProtected
(
Permissions
.
AccessContentsInformation
)
# Declarative properties
property_sheets
=
(
PropertySheet
.
Base
,
PropertySheet
.
XMLObject
,
PropertySheet
.
CategoryCore
,
PropertySheet
.
DublinCore
,
PropertySheet
.
Workflow
,
)
def
initializeDocument
(
self
,
document
):
"""
Set initial state on the Document
"""
state_bc_id
=
self
.
getStateBaseCategory
()
document
.
setCategoryMembership
(
state_bc_id
,
self
.
getSource
())
object
=
self
.
getStateChangeInformation
(
document
,
self
.
getSourceValue
())
# Initialize workflow history
status_dict
=
{
state_bc_id
:
self
.
getSource
()}
variable_list
=
self
.
contentValues
(
portal_type
=
'Variable'
)
for
variable
in
variable_list
:
status_dict
[
variable
.
getTitle
()]
=
variable
.
getInitialValue
(
object
=
object
)
self
.
_updateWorkflowHistory
(
document
,
status_dict
)
def
_generateHistoryKey
(
self
):
"""
Generate a key used in the workflow history.
"""
return
self
.
getRelativeUrl
()
def
_updateWorkflowHistory
(
self
,
document
,
status_dict
):
"""
Change the state of the object.
"""
# Create history attributes if needed
if
getattr
(
aq_base
(
document
),
'workflow_history'
,
None
)
is
None
:
document
.
workflow_history
=
PersistentMapping
()
# XXX this _p_changed is apparently not necessary
document
.
_p_changed
=
1
# Add an entry for the workflow in the history
workflow_key
=
self
.
_generateHistoryKey
()
if
not
document
.
workflow_history
.
has_key
(
workflow_key
):
document
.
workflow_history
[
workflow_key
]
=
()
# Update history
document
.
workflow_history
[
workflow_key
]
+=
(
status_dict
,
)
# XXX this _p_changed marks the document modified, but the
# only the PersistentMapping is modified
document
.
_p_changed
=
1
# XXX this _p_changed is apparently not necessary
document
.
workflow_history
.
_p_changed
=
1
def
getCurrentStatusDict
(
self
,
document
):
"""
Get the current status dict.
"""
workflow_key
=
self
.
_generateHistoryKey
()
# Copy is requested
result
=
document
.
workflow_history
[
workflow_key
][
-
1
].
copy
()
return
result
def
getDateTime
(
self
):
"""
Return current date time.
"""
return
DateTime
()
def
getStateChangeInformation
(
self
,
document
,
state
,
transition
=
None
):
"""
Return an object used for variable tales expression.
"""
if
transition
is
None
:
transition_url
=
None
else
:
transition_url
=
transition
.
getRelativeUrl
()
return
self
.
asContext
(
document
=
document
,
transition
=
transition
,
transition_url
=
transition_url
,
state
=
state
)
# ========== ERP5Workflow Project, Wenjie, Dec 2014 ===============================
def
isERP5WorkflowMethodSupported
(
self
,
document
,
transition
):
sdef
=
self
.
_getERP5WorkflowStateOf
(
document
)
if
sdef
is
None
:
return
0
if
transition
in
sdef
.
getDestinationValueList
():
return
1
return
0
### get workflow state from base category value:
def
_getERP5WorkflowStateOf
(
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
:
sdef
=
self
.
restrictedTraverse
(
state_path
)
else
:
sdef
=
None
return
sdef
# =========== WF5 ==============================================================
###########
## Graph ##
############
getGraph
=
getGraph
def
getPOT
(
self
,
*
args
,
**
kwargs
):
"""
get the pot, copy from:
"dcworkfow2dot.py":http://awkly.org/Members/sidnei/weblog_storage/blog_27014
and Sidnei da Silva owns the copyright of the this function
"""
out
=
[]
transition_dict
=
{}
out
.
append
(
'digraph "%s" {'
%
self
.
getTitle
())
transition_with_init_state_list
=
[]
for
state
in
self
.
contentValues
(
portal_type
=
'State'
):
out
.
append
(
'%s [shape=box,label="%s",'
\
'style="filled",fillcolor="#ffcc99"];'
%
\
(
state
.
getId
(),
state
.
getTitle
()))
# XXX Use API instead of getDestinationValueList
for
available_transition
in
state
.
getDestinationValueList
():
transition_with_init_state_list
.
append
(
available_transition
.
getId
())
destination_state
=
available_transition
.
getDestinationValue
()
if
destination_state
is
None
:
# take care of 'remain in state' transitions
destination_state
=
state
#
key
=
(
state
.
getId
(),
destination_state
.
getId
())
value
=
transition_dict
.
get
(
key
,
[])
value
.
append
(
available_transition
.
getTitle
())
transition_dict
[
key
]
=
value
# iterate also on transitions, and add transitions with no initial state
for
transition
in
self
.
contentValues
(
portal_type
=
'Transition'
):
trans_id
=
transition
.
getId
()
if
trans_id
not
in
transition_with_init_state_list
:
destination_state
=
transition
.
getDestinationValue
()
if
destination_state
is
None
:
dest_state_id
=
None
else
:
dest_state_id
=
destination_state
.
getId
()
key
=
(
None
,
dest_state_id
)
value
=
transition_dict
.
get
(
key
,
[])
value
.
append
(
transition
.
getTitle
())
transition_dict
[
key
]
=
value
for
k
,
v
in
transition_dict
.
items
():
out
.
append
(
'%s -> %s [label="%s"];'
%
(
k
[
0
],
k
[
1
],
',
\
\
n'
.
join
(
v
)))
out
.
append
(
'}'
)
return
'
\
n
'
.
join
(
out
)
##############################################################################
#
# Copyright (c) 2006,2014 Nexedi SARL and Contributors. All Rights Reserved.
# Romain Courteaud <romain@nexedi.com>
# Wenjie Zheng <wenjie.zheng@tiolive.com>
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# 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.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from
AccessControl
import
ClassSecurityInfo
from
Acquisition
import
aq_inner
from
Acquisition
import
aq_parent
from
Products.ERP5Type
import
Permissions
,
PropertySheet
from
Products.ERP5Type.XMLObject
import
XMLObject
from
Products.ERP5Type.Globals
import
PersistentMapping
from
Products.ERP5Type.Accessor
import
WorkflowState
from
Products.ERP5Type
import
Permissions
from
tempfile
import
mktemp
import
os
from
Products.DCWorkflowGraph.config
import
DOT_EXE
from
Products.DCWorkflowGraph.DCWorkflowGraph
import
bin_search
,
getGraph
from
Products.ERP5Type.Utils
import
UpperCase
from
Acquisition
import
aq_base
from
DateTime
import
DateTime
class
Workflow
(
XMLObject
):
"""
A ERP5 Workflow.
"""
meta_type
=
'ERP5 Workflow'
portal_type
=
'Workflow'
add_permission
=
Permissions
.
AddPortalContent
isPortalContent
=
1
isRADContent
=
1
### register the variable given by "base category value"
#state_var = 'state'
### In DCworkflow; state/transition can be registered inside workflow
# Declarative security
security
=
ClassSecurityInfo
()
security
.
declareObjectProtected
(
Permissions
.
AccessContentsInformation
)
# Declarative properties
property_sheets
=
(
PropertySheet
.
Base
,
PropertySheet
.
XMLObject
,
PropertySheet
.
CategoryCore
,
PropertySheet
.
DublinCore
,
PropertySheet
.
Workflow
,
)
def
initializeDocument
(
self
,
document
):
"""
Set initial state on the Document
"""
state_bc_id
=
self
.
getStateBaseCategory
()
document
.
setCategoryMembership
(
state_bc_id
,
self
.
getSource
())
object
=
self
.
getStateChangeInformation
(
document
,
self
.
getSourceValue
())
# Initialize workflow history
status_dict
=
{
state_bc_id
:
self
.
getSource
()}
variable_list
=
self
.
contentValues
(
portal_type
=
'Variable'
)
for
variable
in
variable_list
:
status_dict
[
variable
.
getTitle
()]
=
variable
.
getInitialValue
(
object
=
object
)
self
.
_updateWorkflowHistory
(
document
,
status_dict
)
def
_generateHistoryKey
(
self
):
"""
Generate a key used in the workflow history.
"""
return
self
.
getRelativeUrl
()
def
_updateWorkflowHistory
(
self
,
document
,
status_dict
):
"""
Change the state of the object.
"""
# Create history attributes if needed
if
getattr
(
aq_base
(
document
),
'workflow_history'
,
None
)
is
None
:
document
.
workflow_history
=
PersistentMapping
()
# XXX this _p_changed is apparently not necessary
document
.
_p_changed
=
1
# Add an entry for the workflow in the history
workflow_key
=
self
.
_generateHistoryKey
()
if
not
document
.
workflow_history
.
has_key
(
workflow_key
):
document
.
workflow_history
[
workflow_key
]
=
()
# Update history
document
.
workflow_history
[
workflow_key
]
+=
(
status_dict
,
)
# XXX this _p_changed marks the document modified, but the
# only the PersistentMapping is modified
document
.
_p_changed
=
1
# XXX this _p_changed is apparently not necessary
document
.
workflow_history
.
_p_changed
=
1
def
getCurrentStatusDict
(
self
,
document
):
"""
Get the current status dict.
"""
workflow_key
=
self
.
_generateHistoryKey
()
# Copy is requested
result
=
document
.
workflow_history
[
workflow_key
][
-
1
].
copy
()
return
result
def
getDateTime
(
self
):
"""
Return current date time.
"""
return
DateTime
()
def
getStateChangeInformation
(
self
,
document
,
state
,
transition
=
None
):
"""
Return an object used for variable tales expression.
"""
if
transition
is
None
:
transition_url
=
None
else
:
transition_url
=
transition
.
getRelativeUrl
()
return
self
.
asContext
(
document
=
document
,
transition
=
transition
,
transition_url
=
transition_url
,
state
=
state
)
def
isERP5WorkflowMethodSupported
(
self
,
document
,
transition
):
sdef
=
self
.
_getERP5WorkflowStateOf
(
document
)
if
sdef
is
None
:
return
0
if
transition
in
sdef
.
getDestinationValueList
():
return
1
return
0
### get workflow state from base category value:
def
_getERP5WorkflowStateOf
(
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
:
sdef
=
self
.
restrictedTraverse
(
state_path
)
else
:
sdef
=
None
return
sdef
###########
## Graph ##
############
getGraph
=
getGraph
def
getPOT
(
self
,
*
args
,
**
kwargs
):
"""
get the pot, copy from:
"dcworkfow2dot.py":http://awkly.org/Members/sidnei/weblog_storage/blog_27014
and Sidnei da Silva owns the copyright of the this function
"""
out
=
[]
transition_dict
=
{}
out
.
append
(
'digraph "%s" {'
%
self
.
getTitle
())
transition_with_init_state_list
=
[]
for
state
in
self
.
contentValues
(
portal_type
=
'State'
):
out
.
append
(
'%s [shape=box,label="%s",'
\
'style="filled",fillcolor="#ffcc99"];'
%
\
(
state
.
getId
(),
state
.
getTitle
()))
# XXX Use API instead of getDestinationValueList
for
available_transition
in
state
.
getDestinationValueList
():
transition_with_init_state_list
.
append
(
available_transition
.
getId
())
destination_state
=
available_transition
.
getDestinationValue
()
if
destination_state
is
None
:
# take care of 'remain in state' transitions
destination_state
=
state
#
key
=
(
state
.
getId
(),
destination_state
.
getId
())
value
=
transition_dict
.
get
(
key
,
[])
value
.
append
(
available_transition
.
getTitle
())
transition_dict
[
key
]
=
value
# iterate also on transitions, and add transitions with no initial state
for
transition
in
self
.
contentValues
(
portal_type
=
'Transition'
):
trans_id
=
transition
.
getId
()
if
trans_id
not
in
transition_with_init_state_list
:
destination_state
=
transition
.
getDestinationValue
()
if
destination_state
is
None
:
dest_state_id
=
None
else
:
dest_state_id
=
destination_state
.
getId
()
key
=
(
None
,
dest_state_id
)
value
=
transition_dict
.
get
(
key
,
[])
value
.
append
(
transition
.
getTitle
())
transition_dict
[
key
]
=
value
for
k
,
v
in
transition_dict
.
items
():
out
.
append
(
'%s -> %s [label="%s"];'
%
(
k
[
0
],
k
[
1
],
',
\
\
n'
.
join
(
v
)))
out
.
append
(
'}'
)
return
'
\
n
'
.
join
(
out
)
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