Commit d8c7e3f9 authored by wenjie.zheng's avatar wenjie.zheng

lazy_class use _getOb instead getattr, remove unnecessary commentaries.

parent 70ad0fcb
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -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()
......
......@@ -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
......
##############################################################################
#
# 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)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment