diff --git a/product/ERP5Type/Dynamic/portaltypeclass.py b/product/ERP5Type/Dynamic/portaltypeclass.py
new file mode 100644
index 0000000000000000000000000000000000000000..c378ffd80764c0429092be36a7179eb4c9303d56
--- /dev/null
+++ b/product/ERP5Type/Dynamic/portaltypeclass.py
@@ -0,0 +1,13 @@
+from zLOG import LOG, ERROR, BLATHER
+
+def resetDynamicDocuments(context, slave=False):
+  """
+  Allow resetting all classes to ghost state, most likely done after
+  adding and removing mixins on the fly
+
+  Nodes just trying to catch up with state of classes without wanting
+  to invalidate them globally should set slave=True.
+  """
+  LOG("ERP5Type.Dynamic", 0, "Resetting dynamic classes")
+  # stub
+  return
diff --git a/product/ERP5Type/Tool/TypesTool.py b/product/ERP5Type/Tool/TypesTool.py
index f68ef3cbceeec529f1883dd67fa7876c29dbb024..9f8505b93e68d22f08a09511fad21a29819b4578 100644
--- a/product/ERP5Type/Tool/TypesTool.py
+++ b/product/ERP5Type/Tool/TypesTool.py
@@ -212,6 +212,13 @@ class TypesTool(TypeProvider):
       return res
 
 
+  security.declareProtected(Permissions.ModifyPortalContent,
+                            'resetDynamicDocuments')
+  def resetDynamicDocuments(self):
+    """Resets all dynamic documents: force reloading erp.* classes"""
+    from Products.ERP5Type.Dynamic.portaltypeclass import resetDynamicDocuments
+    resetDynamicDocuments(self)
+
   security.declareProtected(Permissions.AddPortalContent,
                             'manage_addTypeInformation')
   def manage_addTypeInformation(self, add_meta_type, id=None,