From bdec8612fe6476eaaa3233a4b62fc019c7611aa1 Mon Sep 17 00:00:00 2001
From: Arnaud Fontaine <arnaud.fontaine@nexedi.com>
Date: Wed, 20 Apr 2022 12:02:24 +0200
Subject: [PATCH] py3: DCWorkflow is python2-only so make ERP5Site creation
 work on Python3 WITH_LEGACY_WORKFLOW=False.

ERP5 Workflow implementation should ideally not depend on DCWorkflow at all so
that legacy DCWorkflow can be disabled for Python2 but this would require much
more work.
---
 .../ERP5/Interactor/PortalTypeClassInteractor.py | 16 +++++++++-------
 product/ERP5/__init__.py                         |  4 +++-
 product/ERP5Type/Core/Workflow.py                |  4 ++--
 product/ERP5Type/Tool/WorkflowTool.py            | 14 ++++++++++++++
 product/ERP5Type/ZopePatch.py                    | 11 ++++++++---
 product/ERP5Type/__init__.py                     |  6 +++++-
 product/ERP5Type/patches/DCWorkflow.py           |  3 ++-
 product/ERP5Type/patches/StateChangeInfoPatch.py |  3 +++
 product/ERP5Type/patches/States.py               |  3 +++
 product/ERP5Type/patches/WorkflowTool.py         |  3 +++
 product/ERP5Type/patches/Worklists.py            |  3 +++
 11 files changed, 55 insertions(+), 15 deletions(-)

diff --git a/product/ERP5/Interactor/PortalTypeClassInteractor.py b/product/ERP5/Interactor/PortalTypeClassInteractor.py
index 7f25645733..69ae82bd35 100644
--- a/product/ERP5/Interactor/PortalTypeClassInteractor.py
+++ b/product/ERP5/Interactor/PortalTypeClassInteractor.py
@@ -37,13 +37,15 @@ class PortalTypeClassInteractor(Interactor):
     and dynamic properties.
   """
   def install(self):
-    from Products.DCWorkflow.Transitions import Transitions
-    self.on(Transitions.addTransition).doAfter(self.resetDynamic)
-    self.on(Transitions.deleteTransitions).doAfter(self.resetDynamic)
-    from Products.DCWorkflow.Transitions import TransitionDefinition
-    self.on(TransitionDefinition.setProperties).doAfter(self.resetDynamic)
-    from Products.DCWorkflow.Variables import Variables
-    self.on(Variables.setStateVar).doAfter(self.resetDynamic)
+    from Products.ERP5Type import WITH_LEGACY_WORKFLOW
+    if WITH_LEGACY_WORKFLOW:
+      from Products.DCWorkflow.Transitions import Transitions
+      self.on(Transitions.addTransition).doAfter(self.resetDynamic)
+      self.on(Transitions.deleteTransitions).doAfter(self.resetDynamic)
+      from Products.DCWorkflow.Transitions import TransitionDefinition
+      self.on(TransitionDefinition.setProperties).doAfter(self.resetDynamic)
+      from Products.DCWorkflow.Variables import Variables
+      self.on(Variables.setStateVar).doAfter(self.resetDynamic)
 
     from Products.Localizer.Localizer import Localizer
     self.on(Localizer.add_language).doAfter(self.resetDynamic)
diff --git a/product/ERP5/__init__.py b/product/ERP5/__init__.py
index 4ef347005d..14e4497425 100644
--- a/product/ERP5/__init__.py
+++ b/product/ERP5/__init__.py
@@ -81,7 +81,9 @@ def initialize( context ):
                                                    'WorkflowException')
 
   # Make sure InteactionWorkflow is visible in UI
-  import Products.ERP5.InteractionWorkflow
+  from Products.ERP5Type import WITH_LEGACY_WORKFLOW
+  if WITH_LEGACY_WORKFLOW:
+    import Products.ERP5.InteractionWorkflow
 
 # backward compatibility names
 XML = None
diff --git a/product/ERP5Type/Core/Workflow.py b/product/ERP5Type/Core/Workflow.py
index 72b0ce3929..578572a0f7 100644
--- a/product/ERP5Type/Core/Workflow.py
+++ b/product/ERP5Type/Core/Workflow.py
@@ -91,8 +91,6 @@ from Products.DCWorkflow.utils import Message as _
 from Products.ERP5Type import Permissions
 from Products.ERP5Type.Cache import CachingMethod
 from Products.ERP5Type.Globals import PersistentMapping, InitializeClass
-from Products.ERP5Type.patches.WorkflowTool import (SECURITY_PARAMETER_ID,
-                                                    WORKLIST_METADATA_KEY)
 from Products.ERP5Type.Utils import convertToMixedCase
 from Products.ERP5Type.XMLObject import XMLObject
 from Products.ERP5Type.Core.WorkflowTransition import (TRIGGER_AUTOMATIC,
@@ -509,6 +507,8 @@ class Workflow(XMLObject):
     security_manager = getSecurityManager()
     workflow_id = self.getId()
     workflow_title = self.getTitle()
+    from Products.ERP5Type.Tool.WorkflowTool import (SECURITY_PARAMETER_ID,
+                                                     WORKLIST_METADATA_KEY)
     for worklist_definition in worklist_value_list:
       action_box_name = worklist_definition.getActionName()
       guard_role_list = worklist_definition.getGuardRoleList()
diff --git a/product/ERP5Type/Tool/WorkflowTool.py b/product/ERP5Type/Tool/WorkflowTool.py
index 1f2a940546..5327c5675d 100644
--- a/product/ERP5Type/Tool/WorkflowTool.py
+++ b/product/ERP5Type/Tool/WorkflowTool.py
@@ -75,6 +75,20 @@ class WorkflowTool(BaseTool, OriginalWorkflowTool):
     'DublinCore',
   )
 
+  def _isBootstrapRequired(self):
+    """
+    Required by synchronizeDynamicModules() to bootstrap an empty site and
+    thus create portal_components
+    """
+    return False
+
+  def _bootstrap(self):
+    """
+    Required by synchronizeDynamicModules() to bootstrap an empty site and
+    thus create portal_components
+    """
+    pass
+
   def filtered_meta_types(self, user=None):
     return False
 
diff --git a/product/ERP5Type/ZopePatch.py b/product/ERP5Type/ZopePatch.py
index fe0efe8da0..0359900846 100644
--- a/product/ERP5Type/ZopePatch.py
+++ b/product/ERP5Type/ZopePatch.py
@@ -19,6 +19,7 @@
 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
 # FOR A PARTICULAR PURPOSE
 ##############################################################################
+import six
 
 from Products.ERP5Type import WITH_LEGACY_WORKFLOW
 
@@ -64,7 +65,8 @@ from Products.ERP5Type.patches import PythonScript
 from Products.ERP5Type.patches import MailHost
 from Products.ERP5Type.patches import http_server
 from Products.ERP5Type.patches import memcache_client
-from Products.ERP5Type.patches import StateChangeInfoPatch
+if WITH_LEGACY_WORKFLOW:
+  from Products.ERP5Type.patches import StateChangeInfoPatch
 from Products.ERP5Type.patches import transforms
 from Products.ERP5Type.patches import OFSPdata
 from Products.ERP5Type.patches import make_hidden_input
@@ -80,7 +82,9 @@ from Products.ERP5Type.patches import zopecontenttype
 from Products.ERP5Type.patches import OFSImage
 from Products.ERP5Type.patches import _transaction
 from Products.ERP5Type.patches import default_zpublisher_encoding
-from Products.ERP5Type.patches import DCWorkflowGraph
+if six.PY2:
+  # DCWorkflowGraph is dead since 2011, so no py3 version
+  from Products.ERP5Type.patches import DCWorkflowGraph
 from Products.ERP5Type.patches import SourceCodeEditorZMI
 from Products.ERP5Type.patches import CachingPolicyManager
 from Products.ERP5Type.patches import AcceleratedHTTPCacheManager
@@ -100,5 +104,6 @@ from Products.ERP5Type.patches import urllib_opener
 # These symbols are required for backward compatibility
 from Products.ERP5Type.patches.PropertyManager import ERP5PropertyManager
 from Products.ERP5Type.Core.Workflow import ValidationFailed
-from Products.ERP5Type.patches.DCWorkflow import ERP5TransitionDefinition
+if WITH_LEGACY_WORKFLOW:
+  from Products.ERP5Type.patches.DCWorkflow import ERP5TransitionDefinition
 from Products.ERP5Type.patches.BTreeFolder2 import ERP5BTreeFolder2Base
diff --git a/product/ERP5Type/__init__.py b/product/ERP5Type/__init__.py
index f52e57f778..ce98ba9a45 100644
--- a/product/ERP5Type/__init__.py
+++ b/product/ERP5Type/__init__.py
@@ -36,7 +36,11 @@ from .patches import python, pylint, globalrequest
 from zLOG import LOG, INFO
 DISPLAY_BOOT_PROCESS = False
 
-WITH_LEGACY_WORKFLOW = True # BBB
+if six.PY3:
+  # DCWorkflow python2-only
+  WITH_LEGACY_WORKFLOW = False
+else:
+  WITH_LEGACY_WORKFLOW = True
 
 # We have a name conflict with source_reference and destination_reference,
 # which are at the same time property accessors for 'source_reference'
diff --git a/product/ERP5Type/patches/DCWorkflow.py b/product/ERP5Type/patches/DCWorkflow.py
index 0eacac706f..6ae7387da6 100644
--- a/product/ERP5Type/patches/DCWorkflow.py
+++ b/product/ERP5Type/patches/DCWorkflow.py
@@ -13,7 +13,8 @@
 #
 ##############################################################################
 
-# WITH_LEGACY_WORKFLOW
+from Products.ERP5Type import WITH_LEGACY_WORKFLOW
+assert WITH_LEGACY_WORKFLOW
 
 ## ERP5 Workflow: This must go before any Products.DCWorkflow imports as this
 ## patch createExprContext() from-imported in several of its modules
diff --git a/product/ERP5Type/patches/StateChangeInfoPatch.py b/product/ERP5Type/patches/StateChangeInfoPatch.py
index 3ebe14266f..82fe8f5547 100644
--- a/product/ERP5Type/patches/StateChangeInfoPatch.py
+++ b/product/ERP5Type/patches/StateChangeInfoPatch.py
@@ -26,6 +26,9 @@
 #
 ##############################################################################
 
+from Products.ERP5Type import WITH_LEGACY_WORKFLOW
+assert WITH_LEGACY_WORKFLOW
+
 from Products.DCWorkflow.Expression import StateChangeInfo
 from Products.PythonScripts.Utility import allow_class
 allow_class(StateChangeInfo)
diff --git a/product/ERP5Type/patches/States.py b/product/ERP5Type/patches/States.py
index b8d7360577..2528a65caf 100644
--- a/product/ERP5Type/patches/States.py
+++ b/product/ERP5Type/patches/States.py
@@ -12,6 +12,9 @@
 #
 ##############################################################################
 
+from Products.ERP5Type import WITH_LEGACY_WORKFLOW
+assert WITH_LEGACY_WORKFLOW
+
 # State types patch for DCWorkflow
 from Products.DCWorkflow.States import StateDefinition
 from Products.ERP5Type.Globals import DTMLFile
diff --git a/product/ERP5Type/patches/WorkflowTool.py b/product/ERP5Type/patches/WorkflowTool.py
index f413d788f3..65ad7d5ffc 100644
--- a/product/ERP5Type/patches/WorkflowTool.py
+++ b/product/ERP5Type/patches/WorkflowTool.py
@@ -13,6 +13,9 @@
 #
 ##############################################################################
 
+from Products.ERP5Type import WITH_LEGACY_WORKFLOW
+assert WITH_LEGACY_WORKFLOW
+
 from zLOG import LOG, WARNING
 from types import StringTypes
 
diff --git a/product/ERP5Type/patches/Worklists.py b/product/ERP5Type/patches/Worklists.py
index 9aa6e77532..0178e68649 100644
--- a/product/ERP5Type/patches/Worklists.py
+++ b/product/ERP5Type/patches/Worklists.py
@@ -1,3 +1,6 @@
+from Products.ERP5Type import WITH_LEGACY_WORKFLOW
+assert WITH_LEGACY_WORKFLOW
+
 from Products.DCWorkflow.Worklists import Worklists
 from Products.DCWorkflow.Worklists import WorklistDefinition
 from Products.ERP5Type.Permissions import ManagePortal
-- 
2.30.9