From 63bd553de60bed81c4f20d6decc85ee33f644d92 Mon Sep 17 00:00:00 2001
From: Julien Muchembled <jm@nexedi.com>
Date: Tue, 26 Oct 2010 19:28:36 +0000
Subject: [PATCH] New Specialise Equivalence Tester

Behaviour of legacy composition is also slightly changed:
During composition of a delivery line, a model line on the delivery now has
priority over all specialise values reachable from the delivery line.

git-svn-id: https://svn.erp5.org/repos/public/erp5/sandbox/amount_generator@39544 20353a03-c40f-0410-a6d1-a30d3c3de9de
---
 .../allowed_content_types.xml                 |   2 +
 ...late_portal_type_allowed_content_type_list |   2 +
 bt5/erp5_core                                 |   1 +
 .../allowed_content_types.xml                 |   3 +
 ...late_portal_type_allowed_content_type_list |   3 +
 bt5/erp5_mysql_innodb_catalog                 |   1 +
 .../predicate.xml                             |  93 ++++++++++++
 .../Specialise%20Divergence%20Tester/view.xml |  93 ++++++++++++
 .../Specialise%20Divergence%20Tester.xml      | 138 ++++++++++++++++++
 .../workflow_chain_type.xml                   |   4 +
 .../bt/template_action_path_list              |   2 +
 .../bt/template_portal_type_id_list           |   1 +
 .../template_portal_type_workflow_chain_list  |   1 +
 .../specialise_tester.xml                     |  12 +-
 .../specialise_tester.xml                     |  12 +-
 .../specialise_tester.xml                     |  12 +-
 .../specialise_tester.xml                     |  12 +-
 .../specialise_tester.xml                     |  12 +-
 .../specialise_tester.xml                     |  12 +-
 .../specialise_tester.xml                     |  12 +-
 .../specialise_tester.xml                     |  12 +-
 .../allowed_content_types.xml                 |   3 +
 ...late_portal_type_allowed_content_type_list |   3 +
 .../Document/SpecialiseEquivalenceTester.py   |  49 +++++++
 product/ERP5/mixin/composition.py             |  64 ++++----
 25 files changed, 454 insertions(+), 105 deletions(-)
 create mode 120000 bt5/erp5_core
 create mode 120000 bt5/erp5_mysql_innodb_catalog
 create mode 100644 bt5/erp5_simulation/ActionTemplateItem/portal_types/Specialise%20Divergence%20Tester/predicate.xml
 create mode 100644 bt5/erp5_simulation/ActionTemplateItem/portal_types/Specialise%20Divergence%20Tester/view.xml
 create mode 100644 bt5/erp5_simulation/PortalTypeTemplateItem/portal_types/Specialise%20Divergence%20Tester.xml
 create mode 100644 product/ERP5/Document/SpecialiseEquivalenceTester.py

diff --git a/bt5/erp5_accounting/PortalTypeAllowedContentTypeTemplateItem/allowed_content_types.xml b/bt5/erp5_accounting/PortalTypeAllowedContentTypeTemplateItem/allowed_content_types.xml
index 5acecb2eaa..0218e43c49 100644
--- a/bt5/erp5_accounting/PortalTypeAllowedContentTypeTemplateItem/allowed_content_types.xml
+++ b/bt5/erp5_accounting/PortalTypeAllowedContentTypeTemplateItem/allowed_content_types.xml
@@ -40,6 +40,7 @@
   <item>DateTime Divergence Tester</item>
   <item>Float Divergence Tester</item>
   <item>Net Converted Quantity Divergence Tester</item>
+  <item>Specialise Divergence Tester</item>
   <item>String Divergence Tester</item>
   <item>Variation Divergence Tester</item>
  </portal_type>
@@ -55,6 +56,7 @@
   <item>Mapped Property</item>
   <item>Net Converted Quantity Divergence Tester</item>
   <item>Predicate</item>
+  <item>Specialise Divergence Tester</item>
   <item>String Divergence Tester</item>
   <item>Variation Divergence Tester</item>
  </portal_type>
diff --git a/bt5/erp5_accounting/bt/template_portal_type_allowed_content_type_list b/bt5/erp5_accounting/bt/template_portal_type_allowed_content_type_list
index 755a0988b5..3fadde5fd2 100644
--- a/bt5/erp5_accounting/bt/template_portal_type_allowed_content_type_list
+++ b/bt5/erp5_accounting/bt/template_portal_type_allowed_content_type_list
@@ -22,6 +22,7 @@ Invoice Root Simulation Rule | Category Membership Divergence Tester
 Invoice Root Simulation Rule | DateTime Divergence Tester
 Invoice Root Simulation Rule | Float Divergence Tester
 Invoice Root Simulation Rule | Net Converted Quantity Divergence Tester
+Invoice Root Simulation Rule | Specialise Divergence Tester
 Invoice Root Simulation Rule | String Divergence Tester
 Invoice Root Simulation Rule | Variation Divergence Tester
 Organisation | Accounting Period
@@ -33,6 +34,7 @@ Payment Simulation Rule | Float Divergence Tester
 Payment Simulation Rule | Mapped Property
 Payment Simulation Rule | Net Converted Quantity Divergence Tester
 Payment Simulation Rule | Predicate
+Payment Simulation Rule | Specialise Divergence Tester
 Payment Simulation Rule | String Divergence Tester
 Payment Simulation Rule | Variation Divergence Tester
 Payment Transaction | Accounting Transaction Line
diff --git a/bt5/erp5_core b/bt5/erp5_core
new file mode 120000
index 0000000000..d5ad302d4a
--- /dev/null
+++ b/bt5/erp5_core
@@ -0,0 +1 @@
+../products/ERP5/bootstrap/erp5_core
\ No newline at end of file
diff --git a/bt5/erp5_invoicing/PortalTypeAllowedContentTypeTemplateItem/allowed_content_types.xml b/bt5/erp5_invoicing/PortalTypeAllowedContentTypeTemplateItem/allowed_content_types.xml
index 8ca1e89c6e..1f97afe5b7 100644
--- a/bt5/erp5_invoicing/PortalTypeAllowedContentTypeTemplateItem/allowed_content_types.xml
+++ b/bt5/erp5_invoicing/PortalTypeAllowedContentTypeTemplateItem/allowed_content_types.xml
@@ -9,6 +9,7 @@
   <item>Float Divergence Tester</item>
   <item>Mapped Property</item>
   <item>Net Converted Quantity Divergence Tester</item>
+  <item>Specialise Divergence Tester</item>
   <item>String Divergence Tester</item>
   <item>Variation Divergence Tester</item>
  </portal_type>
@@ -20,6 +21,7 @@
   <item>Mapped Property</item>
   <item>Net Converted Quantity Divergence Tester</item>
   <item>Predicate</item>
+  <item>Specialise Divergence Tester</item>
   <item>String Divergence Tester</item>
   <item>Variation Divergence Tester</item>
  </portal_type>
@@ -34,6 +36,7 @@
   <item>Float Divergence Tester</item>
   <item>Mapped Property</item>
   <item>Net Converted Quantity Divergence Tester</item>
+  <item>Specialise Divergence Tester</item>
   <item>String Divergence Tester</item>
   <item>Variation Divergence Tester</item>
  </portal_type>
diff --git a/bt5/erp5_invoicing/bt/template_portal_type_allowed_content_type_list b/bt5/erp5_invoicing/bt/template_portal_type_allowed_content_type_list
index 3d2e2ea725..8187ab66d1 100644
--- a/bt5/erp5_invoicing/bt/template_portal_type_allowed_content_type_list
+++ b/bt5/erp5_invoicing/bt/template_portal_type_allowed_content_type_list
@@ -5,6 +5,7 @@ Invoice Simulation Rule | DateTime Divergence Tester
 Invoice Simulation Rule | Float Divergence Tester
 Invoice Simulation Rule | Mapped Property
 Invoice Simulation Rule | Net Converted Quantity Divergence Tester
+Invoice Simulation Rule | Specialise Divergence Tester
 Invoice Simulation Rule | String Divergence Tester
 Invoice Simulation Rule | Variation Divergence Tester
 Invoice Transaction Simulation Rule | Accounting Rule Cell
@@ -14,6 +15,7 @@ Invoice Transaction Simulation Rule | Float Divergence Tester
 Invoice Transaction Simulation Rule | Mapped Property
 Invoice Transaction Simulation Rule | Net Converted Quantity Divergence Tester
 Invoice Transaction Simulation Rule | Predicate
+Invoice Transaction Simulation Rule | Specialise Divergence Tester
 Invoice Transaction Simulation Rule | String Divergence Tester
 Invoice Transaction Simulation Rule | Variation Divergence Tester
 Rule Tool | Invoice Simulation Rule
@@ -24,5 +26,6 @@ Trade Model Simulation Rule | DateTime Divergence Tester
 Trade Model Simulation Rule | Float Divergence Tester
 Trade Model Simulation Rule | Mapped Property
 Trade Model Simulation Rule | Net Converted Quantity Divergence Tester
+Trade Model Simulation Rule | Specialise Divergence Tester
 Trade Model Simulation Rule | String Divergence Tester
 Trade Model Simulation Rule | Variation Divergence Tester
\ No newline at end of file
diff --git a/bt5/erp5_mysql_innodb_catalog b/bt5/erp5_mysql_innodb_catalog
new file mode 120000
index 0000000000..584213458d
--- /dev/null
+++ b/bt5/erp5_mysql_innodb_catalog
@@ -0,0 +1 @@
+../products/ERP5/bootstrap/erp5_mysql_innodb_catalog
\ No newline at end of file
diff --git a/bt5/erp5_simulation/ActionTemplateItem/portal_types/Specialise%20Divergence%20Tester/predicate.xml b/bt5/erp5_simulation/ActionTemplateItem/portal_types/Specialise%20Divergence%20Tester/predicate.xml
new file mode 100644
index 0000000000..799d6ae209
--- /dev/null
+++ b/bt5/erp5_simulation/ActionTemplateItem/portal_types/Specialise%20Divergence%20Tester/predicate.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <tuple>
+        <global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
+        <tuple/>
+      </tuple>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>action</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
+            </value>
+        </item>
+        <item>
+            <key> <string>categories</string> </key>
+            <value>
+              <tuple>
+                <string>action_type/object_view</string>
+                <string>portal_types/Trade Quantity Divergence Tester/1</string>
+                <string>portal_types/Float Divergence Tester/3</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>category</string> </key>
+            <value> <string>object_view</string> </value>
+        </item>
+        <item>
+            <key> <string>condition</string> </key>
+            <value> <string></string> </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>icon</string> </key>
+            <value> <string></string> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>predicate</string> </value>
+        </item>
+        <item>
+            <key> <string>permissions</string> </key>
+            <value>
+              <tuple>
+                <string>View</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Action Information</string> </value>
+        </item>
+        <item>
+            <key> <string>priority</string> </key>
+            <value> <float>2.0</float> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>Predicate</string> </value>
+        </item>
+        <item>
+            <key> <string>visible</string> </key>
+            <value> <int>1</int> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="2" aka="AAAAAAAAAAI=">
+    <pickle>
+      <tuple>
+        <global name="Expression" module="Products.CMFCore.Expression"/>
+        <tuple/>
+      </tuple>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>text</string> </key>
+            <value> <string>string:${object_url}/Predicate_view</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_simulation/ActionTemplateItem/portal_types/Specialise%20Divergence%20Tester/view.xml b/bt5/erp5_simulation/ActionTemplateItem/portal_types/Specialise%20Divergence%20Tester/view.xml
new file mode 100644
index 0000000000..ab3322cf6d
--- /dev/null
+++ b/bt5/erp5_simulation/ActionTemplateItem/portal_types/Specialise%20Divergence%20Tester/view.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <tuple>
+        <global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
+        <tuple/>
+      </tuple>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>action</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
+            </value>
+        </item>
+        <item>
+            <key> <string>categories</string> </key>
+            <value>
+              <tuple>
+                <string>action_type/object_view</string>
+                <string>portal_types/Float Divergence Tester/1</string>
+                <string>portal_types/Float Divergence Tester/1</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>category</string> </key>
+            <value> <string>object_view</string> </value>
+        </item>
+        <item>
+            <key> <string>condition</string> </key>
+            <value> <string></string> </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>icon</string> </key>
+            <value> <string></string> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>view</string> </value>
+        </item>
+        <item>
+            <key> <string>permissions</string> </key>
+            <value>
+              <tuple>
+                <string>View</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Action Information</string> </value>
+        </item>
+        <item>
+            <key> <string>priority</string> </key>
+            <value> <float>1.0</float> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>View</string> </value>
+        </item>
+        <item>
+            <key> <string>visible</string> </key>
+            <value> <int>1</int> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="2" aka="AAAAAAAAAAI=">
+    <pickle>
+      <tuple>
+        <global name="Expression" module="Products.CMFCore.Expression"/>
+        <tuple/>
+      </tuple>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>text</string> </key>
+            <value> <string>string:${object_url}/Tester_view</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_simulation/PortalTypeTemplateItem/portal_types/Specialise%20Divergence%20Tester.xml b/bt5/erp5_simulation/PortalTypeTemplateItem/portal_types/Specialise%20Divergence%20Tester.xml
new file mode 100644
index 0000000000..047dd74ef8
--- /dev/null
+++ b/bt5/erp5_simulation/PortalTypeTemplateItem/portal_types/Specialise%20Divergence%20Tester.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <tuple>
+        <global name="ERP5TypeInformation" module="Products.ERP5Type.ERP5Type"/>
+        <tuple/>
+      </tuple>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_property_domain_dict</string> </key>
+            <value>
+              <dictionary>
+                <item>
+                    <key> <string>short_title</string> </key>
+                    <value>
+                      <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
+                    </value>
+                </item>
+                <item>
+                    <key> <string>title</string> </key>
+                    <value>
+                      <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
+                    </value>
+                </item>
+              </dictionary>
+            </value>
+        </item>
+        <item>
+            <key> <string>acquire_local_roles</string> </key>
+            <value> <int>1</int> </value>
+        </item>
+        <item>
+            <key> <string>content_icon</string> </key>
+            <value> <string>document.gif</string> </value>
+        </item>
+        <item>
+            <key> <string>content_meta_type</string> </key>
+            <value> <string>ERP5 Divergence Tester</string> </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>factory</string> </key>
+            <value> <string>addSpecialiseEquivalenceTester</string> </value>
+        </item>
+        <item>
+            <key> <string>filter_content_types</string> </key>
+            <value> <int>1</int> </value>
+        </item>
+        <item>
+            <key> <string>group_list</string> </key>
+            <value>
+              <tuple>
+                <string>divergence_tester</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>Specialise Divergence Tester</string> </value>
+        </item>
+        <item>
+            <key> <string>init_script</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>permission</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string></string> </value>
+        </item>
+        <item>
+            <key> <string>type_class</string> </key>
+            <value> <string>SpecialiseEquivalenceTester</string> </value>
+        </item>
+        <item>
+            <key> <string>type_mixin</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="2" aka="AAAAAAAAAAI=">
+    <pickle>
+      <tuple>
+        <global name="TranslationInformation" module="Products.ERP5Type.TranslationProviderBase"/>
+        <tuple/>
+      </tuple>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>domain_name</string> </key>
+            <value> <string>erp5_content</string> </value>
+        </item>
+        <item>
+            <key> <string>property_name</string> </key>
+            <value> <string>short_title</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="3" aka="AAAAAAAAAAM=">
+    <pickle>
+      <tuple>
+        <global name="TranslationInformation" module="Products.ERP5Type.TranslationProviderBase"/>
+        <tuple/>
+      </tuple>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>domain_name</string> </key>
+            <value> <string>erp5_content</string> </value>
+        </item>
+        <item>
+            <key> <string>property_name</string> </key>
+            <value> <string>title</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_simulation/PortalTypeWorkflowChainTemplateItem/workflow_chain_type.xml b/bt5/erp5_simulation/PortalTypeWorkflowChainTemplateItem/workflow_chain_type.xml
index 6748c265a0..6a751f6a22 100644
--- a/bt5/erp5_simulation/PortalTypeWorkflowChainTemplateItem/workflow_chain_type.xml
+++ b/bt5/erp5_simulation/PortalTypeWorkflowChainTemplateItem/workflow_chain_type.xml
@@ -23,6 +23,10 @@
   <type>Solver Type</type>
   <workflow>edit_workflow, validation_workflow</workflow>
  </chain>
+ <chain>
+  <type>Specialise Divergence Tester</type>
+  <workflow>edit_workflow</workflow>
+ </chain>
  <chain>
   <type>String Divergence Tester</type>
   <workflow>edit_workflow</workflow>
diff --git a/bt5/erp5_simulation/bt/template_action_path_list b/bt5/erp5_simulation/bt/template_action_path_list
index 9339859355..10ee8bb7eb 100644
--- a/bt5/erp5_simulation/bt/template_action_path_list
+++ b/bt5/erp5_simulation/bt/template_action_path_list
@@ -22,6 +22,8 @@ Solver Type | solver_view
 Solver Type | translation_view
 Solver Type | update_local_roles
 Solver Type | view
+Specialise Divergence Tester | predicate
+Specialise Divergence Tester | view
 String Divergence Tester | configuration
 String Divergence Tester | predicate
 String Divergence Tester | view
diff --git a/bt5/erp5_simulation/bt/template_portal_type_id_list b/bt5/erp5_simulation/bt/template_portal_type_id_list
index 61ccc83dd5..26ec611f48 100644
--- a/bt5/erp5_simulation/bt/template_portal_type_id_list
+++ b/bt5/erp5_simulation/bt/template_portal_type_id_list
@@ -7,5 +7,6 @@ Solver Process
 Solver Process Tool
 Solver Tool
 Solver Type
+Specialise Divergence Tester
 String Divergence Tester
 Variation Divergence Tester
\ No newline at end of file
diff --git a/bt5/erp5_simulation/bt/template_portal_type_workflow_chain_list b/bt5/erp5_simulation/bt/template_portal_type_workflow_chain_list
index fb8e52234f..f7efdb91ec 100644
--- a/bt5/erp5_simulation/bt/template_portal_type_workflow_chain_list
+++ b/bt5/erp5_simulation/bt/template_portal_type_workflow_chain_list
@@ -5,5 +5,6 @@ Net Converted Quantity Divergence Tester | edit_workflow
 Solver Process | solver_process_workflow
 Solver Type | edit_workflow
 Solver Type | validation_workflow
+Specialise Divergence Tester | edit_workflow
 String Divergence Tester | edit_workflow
 Variation Divergence Tester | edit_workflow
\ No newline at end of file
diff --git a/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_delivery_root_simulation_rule/specialise_tester.xml b/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_delivery_root_simulation_rule/specialise_tester.xml
index ae1dfa6b6f..51d2c358ec 100644
--- a/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_delivery_root_simulation_rule/specialise_tester.xml
+++ b/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_delivery_root_simulation_rule/specialise_tester.xml
@@ -3,7 +3,7 @@
   <record id="1" aka="AAAAAAAAAAE=">
     <pickle>
       <tuple>
-        <global name="CategoryMembershipEquivalenceTester" module="Products.ERP5Type.Document.CategoryMembershipEquivalenceTester"/>
+        <global name="SpecialiseEquivalenceTester" module="Products.ERP5Type.Document.SpecialiseEquivalenceTester"/>
         <tuple/>
       </tuple>
     </pickle>
@@ -33,15 +33,7 @@
         </item>
         <item>
             <key> <string>portal_type</string> </key>
-            <value> <string>Category Membership Divergence Tester</string> </value>
-        </item>
-        <item>
-            <key> <string>tested_property</string> </key>
-            <value>
-              <tuple>
-                <string>specialise</string>
-              </tuple>
-            </value>
+            <value> <string>Specialise Divergence Tester</string> </value>
         </item>
         <item>
             <key> <string>title</string> </key>
diff --git a/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_delivery_simulation_rule/specialise_tester.xml b/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_delivery_simulation_rule/specialise_tester.xml
index ae1dfa6b6f..51d2c358ec 100644
--- a/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_delivery_simulation_rule/specialise_tester.xml
+++ b/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_delivery_simulation_rule/specialise_tester.xml
@@ -3,7 +3,7 @@
   <record id="1" aka="AAAAAAAAAAE=">
     <pickle>
       <tuple>
-        <global name="CategoryMembershipEquivalenceTester" module="Products.ERP5Type.Document.CategoryMembershipEquivalenceTester"/>
+        <global name="SpecialiseEquivalenceTester" module="Products.ERP5Type.Document.SpecialiseEquivalenceTester"/>
         <tuple/>
       </tuple>
     </pickle>
@@ -33,15 +33,7 @@
         </item>
         <item>
             <key> <string>portal_type</string> </key>
-            <value> <string>Category Membership Divergence Tester</string> </value>
-        </item>
-        <item>
-            <key> <string>tested_property</string> </key>
-            <value>
-              <tuple>
-                <string>specialise</string>
-              </tuple>
-            </value>
+            <value> <string>Specialise Divergence Tester</string> </value>
         </item>
         <item>
             <key> <string>title</string> </key>
diff --git a/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_invoice_root_simulation_rule/specialise_tester.xml b/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_invoice_root_simulation_rule/specialise_tester.xml
index ae1dfa6b6f..51d2c358ec 100644
--- a/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_invoice_root_simulation_rule/specialise_tester.xml
+++ b/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_invoice_root_simulation_rule/specialise_tester.xml
@@ -3,7 +3,7 @@
   <record id="1" aka="AAAAAAAAAAE=">
     <pickle>
       <tuple>
-        <global name="CategoryMembershipEquivalenceTester" module="Products.ERP5Type.Document.CategoryMembershipEquivalenceTester"/>
+        <global name="SpecialiseEquivalenceTester" module="Products.ERP5Type.Document.SpecialiseEquivalenceTester"/>
         <tuple/>
       </tuple>
     </pickle>
@@ -33,15 +33,7 @@
         </item>
         <item>
             <key> <string>portal_type</string> </key>
-            <value> <string>Category Membership Divergence Tester</string> </value>
-        </item>
-        <item>
-            <key> <string>tested_property</string> </key>
-            <value>
-              <tuple>
-                <string>specialise</string>
-              </tuple>
-            </value>
+            <value> <string>Specialise Divergence Tester</string> </value>
         </item>
         <item>
             <key> <string>title</string> </key>
diff --git a/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_invoice_simulation_rule/specialise_tester.xml b/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_invoice_simulation_rule/specialise_tester.xml
index ae1dfa6b6f..51d2c358ec 100644
--- a/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_invoice_simulation_rule/specialise_tester.xml
+++ b/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_invoice_simulation_rule/specialise_tester.xml
@@ -3,7 +3,7 @@
   <record id="1" aka="AAAAAAAAAAE=">
     <pickle>
       <tuple>
-        <global name="CategoryMembershipEquivalenceTester" module="Products.ERP5Type.Document.CategoryMembershipEquivalenceTester"/>
+        <global name="SpecialiseEquivalenceTester" module="Products.ERP5Type.Document.SpecialiseEquivalenceTester"/>
         <tuple/>
       </tuple>
     </pickle>
@@ -33,15 +33,7 @@
         </item>
         <item>
             <key> <string>portal_type</string> </key>
-            <value> <string>Category Membership Divergence Tester</string> </value>
-        </item>
-        <item>
-            <key> <string>tested_property</string> </key>
-            <value>
-              <tuple>
-                <string>specialise</string>
-              </tuple>
-            </value>
+            <value> <string>Specialise Divergence Tester</string> </value>
         </item>
         <item>
             <key> <string>title</string> </key>
diff --git a/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_invoice_transaction_simulation_rule/specialise_tester.xml b/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_invoice_transaction_simulation_rule/specialise_tester.xml
index ae1dfa6b6f..51d2c358ec 100644
--- a/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_invoice_transaction_simulation_rule/specialise_tester.xml
+++ b/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_invoice_transaction_simulation_rule/specialise_tester.xml
@@ -3,7 +3,7 @@
   <record id="1" aka="AAAAAAAAAAE=">
     <pickle>
       <tuple>
-        <global name="CategoryMembershipEquivalenceTester" module="Products.ERP5Type.Document.CategoryMembershipEquivalenceTester"/>
+        <global name="SpecialiseEquivalenceTester" module="Products.ERP5Type.Document.SpecialiseEquivalenceTester"/>
         <tuple/>
       </tuple>
     </pickle>
@@ -33,15 +33,7 @@
         </item>
         <item>
             <key> <string>portal_type</string> </key>
-            <value> <string>Category Membership Divergence Tester</string> </value>
-        </item>
-        <item>
-            <key> <string>tested_property</string> </key>
-            <value>
-              <tuple>
-                <string>specialise</string>
-              </tuple>
-            </value>
+            <value> <string>Specialise Divergence Tester</string> </value>
         </item>
         <item>
             <key> <string>title</string> </key>
diff --git a/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_order_root_simulation_rule/specialise_tester.xml b/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_order_root_simulation_rule/specialise_tester.xml
index ae1dfa6b6f..51d2c358ec 100644
--- a/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_order_root_simulation_rule/specialise_tester.xml
+++ b/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_order_root_simulation_rule/specialise_tester.xml
@@ -3,7 +3,7 @@
   <record id="1" aka="AAAAAAAAAAE=">
     <pickle>
       <tuple>
-        <global name="CategoryMembershipEquivalenceTester" module="Products.ERP5Type.Document.CategoryMembershipEquivalenceTester"/>
+        <global name="SpecialiseEquivalenceTester" module="Products.ERP5Type.Document.SpecialiseEquivalenceTester"/>
         <tuple/>
       </tuple>
     </pickle>
@@ -33,15 +33,7 @@
         </item>
         <item>
             <key> <string>portal_type</string> </key>
-            <value> <string>Category Membership Divergence Tester</string> </value>
-        </item>
-        <item>
-            <key> <string>tested_property</string> </key>
-            <value>
-              <tuple>
-                <string>specialise</string>
-              </tuple>
-            </value>
+            <value> <string>Specialise Divergence Tester</string> </value>
         </item>
         <item>
             <key> <string>title</string> </key>
diff --git a/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_payment_simulation_rule/specialise_tester.xml b/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_payment_simulation_rule/specialise_tester.xml
index ae1dfa6b6f..51d2c358ec 100644
--- a/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_payment_simulation_rule/specialise_tester.xml
+++ b/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_payment_simulation_rule/specialise_tester.xml
@@ -3,7 +3,7 @@
   <record id="1" aka="AAAAAAAAAAE=">
     <pickle>
       <tuple>
-        <global name="CategoryMembershipEquivalenceTester" module="Products.ERP5Type.Document.CategoryMembershipEquivalenceTester"/>
+        <global name="SpecialiseEquivalenceTester" module="Products.ERP5Type.Document.SpecialiseEquivalenceTester"/>
         <tuple/>
       </tuple>
     </pickle>
@@ -33,15 +33,7 @@
         </item>
         <item>
             <key> <string>portal_type</string> </key>
-            <value> <string>Category Membership Divergence Tester</string> </value>
-        </item>
-        <item>
-            <key> <string>tested_property</string> </key>
-            <value>
-              <tuple>
-                <string>specialise</string>
-              </tuple>
-            </value>
+            <value> <string>Specialise Divergence Tester</string> </value>
         </item>
         <item>
             <key> <string>title</string> </key>
diff --git a/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_trade_model_simulation_rule/specialise_tester.xml b/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_trade_model_simulation_rule/specialise_tester.xml
index ae1dfa6b6f..51d2c358ec 100644
--- a/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_trade_model_simulation_rule/specialise_tester.xml
+++ b/bt5/erp5_simulation_test/PathTemplateItem/portal_rules/new_trade_model_simulation_rule/specialise_tester.xml
@@ -3,7 +3,7 @@
   <record id="1" aka="AAAAAAAAAAE=">
     <pickle>
       <tuple>
-        <global name="CategoryMembershipEquivalenceTester" module="Products.ERP5Type.Document.CategoryMembershipEquivalenceTester"/>
+        <global name="SpecialiseEquivalenceTester" module="Products.ERP5Type.Document.SpecialiseEquivalenceTester"/>
         <tuple/>
       </tuple>
     </pickle>
@@ -33,15 +33,7 @@
         </item>
         <item>
             <key> <string>portal_type</string> </key>
-            <value> <string>Category Membership Divergence Tester</string> </value>
-        </item>
-        <item>
-            <key> <string>tested_property</string> </key>
-            <value>
-              <tuple>
-                <string>specialise</string>
-              </tuple>
-            </value>
+            <value> <string>Specialise Divergence Tester</string> </value>
         </item>
         <item>
             <key> <string>title</string> </key>
diff --git a/bt5/erp5_trade/PortalTypeAllowedContentTypeTemplateItem/allowed_content_types.xml b/bt5/erp5_trade/PortalTypeAllowedContentTypeTemplateItem/allowed_content_types.xml
index 6727c7ab1c..1328034583 100644
--- a/bt5/erp5_trade/PortalTypeAllowedContentTypeTemplateItem/allowed_content_types.xml
+++ b/bt5/erp5_trade/PortalTypeAllowedContentTypeTemplateItem/allowed_content_types.xml
@@ -21,6 +21,7 @@
   <item>DateTime Divergence Tester</item>
   <item>Float Divergence Tester</item>
   <item>Net Converted Quantity Divergence Tester</item>
+  <item>Specialise Divergence Tester</item>
   <item>String Divergence Tester</item>
   <item>Variation Divergence Tester</item>
  </portal_type>
@@ -29,6 +30,7 @@
   <item>DateTime Divergence Tester</item>
   <item>Float Divergence Tester</item>
   <item>Net Converted Quantity Divergence Tester</item>
+  <item>Specialise Divergence Tester</item>
   <item>String Divergence Tester</item>
   <item>Variation Divergence Tester</item>
  </portal_type>
@@ -67,6 +69,7 @@
   <item>DateTime Divergence Tester</item>
   <item>Float Divergence Tester</item>
   <item>Net Converted Quantity Divergence Tester</item>
+  <item>Specialise Divergence Tester</item>
   <item>String Divergence Tester</item>
   <item>Variation Divergence Tester</item>
  </portal_type>
diff --git a/bt5/erp5_trade/bt/template_portal_type_allowed_content_type_list b/bt5/erp5_trade/bt/template_portal_type_allowed_content_type_list
index f61d2784b3..fc5c657471 100644
--- a/bt5/erp5_trade/bt/template_portal_type_allowed_content_type_list
+++ b/bt5/erp5_trade/bt/template_portal_type_allowed_content_type_list
@@ -9,12 +9,14 @@ Delivery Root Simulation Rule | Category Membership Divergence Tester
 Delivery Root Simulation Rule | DateTime Divergence Tester
 Delivery Root Simulation Rule | Float Divergence Tester
 Delivery Root Simulation Rule | Net Converted Quantity Divergence Tester
+Delivery Root Simulation Rule | Specialise Divergence Tester
 Delivery Root Simulation Rule | String Divergence Tester
 Delivery Root Simulation Rule | Variation Divergence Tester
 Delivery Simulation Rule | Category Membership Divergence Tester
 Delivery Simulation Rule | DateTime Divergence Tester
 Delivery Simulation Rule | Float Divergence Tester
 Delivery Simulation Rule | Net Converted Quantity Divergence Tester
+Delivery Simulation Rule | Specialise Divergence Tester
 Delivery Simulation Rule | String Divergence Tester
 Delivery Simulation Rule | Variation Divergence Tester
 Internal Order Line | Internal Order Cell
@@ -33,6 +35,7 @@ Order Root Simulation Rule | Category Membership Divergence Tester
 Order Root Simulation Rule | DateTime Divergence Tester
 Order Root Simulation Rule | Float Divergence Tester
 Order Root Simulation Rule | Net Converted Quantity Divergence Tester
+Order Root Simulation Rule | Specialise Divergence Tester
 Order Root Simulation Rule | String Divergence Tester
 Order Root Simulation Rule | Variation Divergence Tester
 Preference | Sale Order
diff --git a/product/ERP5/Document/SpecialiseEquivalenceTester.py b/product/ERP5/Document/SpecialiseEquivalenceTester.py
new file mode 100644
index 0000000000..b9e1250d53
--- /dev/null
+++ b/product/ERP5/Document/SpecialiseEquivalenceTester.py
@@ -0,0 +1,49 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+# Copyright (c) 2010 Nexedi SA and Contributors. All Rights Reserved.
+#          Julien Muchembled <jm@nexedi.com>
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsibility 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
+# guarantees and support are strongly advised 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+##############################################################################
+
+from Products.ERP5.Document.CategoryMembershipEquivalenceTester \
+  import CategoryMembershipEquivalenceTester
+
+class SpecialiseEquivalenceTester(CategoryMembershipEquivalenceTester):
+  """
+  The purpose of this divergence tester is to check the
+  consistency between delivery movement and simulation movement
+  for a specific category.
+  """
+  meta_type = 'ERP5 Specialise Equivalence Tester'
+  portal_type = 'Specialise Equivalence Tester'
+
+  tested_property = 'specialise'
+
+  @staticmethod
+  def _getTestedPropertyValue(movement, property):
+    if movement.getPortalType() == 'Simulation Movement':
+      return movement.getSpecialiseList()
+    # following line would work for prevision movements, but it is slower
+    return [x.getRelativeUrl()
+      for x in movement.getInheritedSpecialiseValueList()]
diff --git a/product/ERP5/mixin/composition.py b/product/ERP5/mixin/composition.py
index a08b5000b5..08032b4e02 100644
--- a/product/ERP5/mixin/composition.py
+++ b/product/ERP5/mixin/composition.py
@@ -199,39 +199,53 @@ class CompositionMixin:
   def _findEffectiveAndInitialModelList(self, specialise_type_list):
     start_date = self.getStartDate()
     stop_date = self.getStopDate()
-    effective_list = [self]
+    effective_list = []
     effective_set = set()
-    effective_index = 0
+    effective_index = -1
+    model_list = self.getInheritedSpecialiseValueList(specialise_type_list)
+    specialise_value_list = model_list
     while effective_index < len(effective_list):
-      # we don't use getSpecialiseValueList to avoid acquisition on the parent
-      model_list = effective_list[effective_index].getValueList('specialise',
-                                      portal_type=specialise_type_list or ())
-      if _LEGACY_SIMULATION and not effective_index: # XXX compatibility
-        effective_set.add(self)
-        specialise_value_list = model_list
-      if effective_set:
-        effective_index += 1
-      else: # first iteration
-        del effective_list[0]
-        specialise_value_list = model_list
+      if effective_index >= 0:
+        # we don't use getSpecialiseValueList to avoid acquisition on the parent
+        model_list = effective_list[effective_index].getValueList('specialise',
+                                        portal_type=specialise_type_list or ())
+      elif _LEGACY_SIMULATION:
+        parent = self
+        while isinstance(parent, CompositionMixin):
+          effective_list.append(parent)
+          parent = parent.getParentValue()
+        effective_index += len(effective_list)
+      effective_index += 1
       for model in model_list:
         model = _getEffectiveModel(model, start_date, stop_date)
         if model not in effective_set:
           effective_set.add(model)
           if 1: #model.test(self): # XXX
             effective_list.append(model)
-    # Inherit from parent only if empty, so that a child can override.
-    # This should not be an issue when a SO line is linked to transformation
-    # and the SO to a STC, because asComposedDocument should be called with
-    # different lists of portal types.
-    if _LEGACY_SIMULATION or not specialise_value_list:
-      parent = self.getParentValue()
-      if getattr(aq_base(parent), 'asComposedDocument', None) is not None:
-        parent = parent.asComposedDocument(specialise_type_list)
-        # return parent._effective_model_list, parent.getValueList('specialise')
-        specialise_value_list += parent.getValueList('specialise')
-        effective_list += [model for model in parent._effective_model_list
-                                 if model not in effective_set]
     return effective_list, specialise_value_list
 
+  security.declareProtected(Permissions.AccessContentsInformation,
+                            'getInheritedSpecialiseValueList')
+  def getInheritedSpecialiseValueList(self, specialise_type_list=None,
+                                      exclude_specialise_type_list=()):
+    """Get inherited specialise values
+
+    Values are inherited from parent only if portal types differ,
+    so that a child can override.
+    """
+    portal_type_set = set()
+    specialise_list = []
+    for value in self.getValueList('specialise'):
+      portal_type = value.getPortalType()
+      if not (portal_type in exclude_specialise_type_list or
+          specialise_type_list and portal_type not in specialise_type_list):
+        portal_type_set.add(portal_type)
+        specialise_list.append(value)
+    parent = self.getParentValue()
+    if isinstance(parent, CompositionMixin):
+      portal_type_set.update(exclude_specialise_type_list)
+      specialise_list += parent.getInheritedSpecialiseValueList(
+        specialise_type_list, portal_type_set)
+    return specialise_list
+
 del asComposedDocument # to be unhidden (and renamed ?) if needed
-- 
2.30.9