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