From abe902946653b03529c9e98aae9c4690849c9721 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9rome=20Perrin?= <jerome@nexedi.com>
Date: Wed, 20 Aug 2008 16:01:18 +0000
Subject: [PATCH] grouping reference is now guessed automatically when passing
 stop transition it's removed unconditionnally when passing stopped -> started
 transition

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@23071 20353a03-c40f-0410-a6d1-a30d3c3de9de
---
 ...salityGroupedAccountingTransactionList.xml | 170 ++++++++++++++++++
 .../scripts/guessGroupingReference.xml        | 150 ++++++++++++++++
 .../scripts/resetGroupingReference.xml        |   5 +-
 .../accounting_workflow/states/stopped.xml    |   2 +-
 .../transitions/restart.xml                   |  67 +++++++
 .../transitions/restart_action.xml            |   2 +-
 .../accounting_workflow/transitions/stop.xml  |   2 +-
 bt5/erp5_accounting/bt/revision               |   2 +-
 product/ERP5/tests/testAccounting.py          | 116 ++++++++----
 9 files changed, 475 insertions(+), 41 deletions(-)
 create mode 100644 bt5/erp5_accounting/SkinTemplateItem/portal_skins/erp5_accounting/AccountingTransaction_getCausalityGroupedAccountingTransactionList.xml
 create mode 100644 bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/scripts/guessGroupingReference.xml
 create mode 100644 bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/transitions/restart.xml

diff --git a/bt5/erp5_accounting/SkinTemplateItem/portal_skins/erp5_accounting/AccountingTransaction_getCausalityGroupedAccountingTransactionList.xml b/bt5/erp5_accounting/SkinTemplateItem/portal_skins/erp5_accounting/AccountingTransaction_getCausalityGroupedAccountingTransactionList.xml
new file mode 100644
index 0000000000..5ef19f7c7c
--- /dev/null
+++ b/bt5/erp5_accounting/SkinTemplateItem/portal_skins/erp5_accounting/AccountingTransaction_getCausalityGroupedAccountingTransactionList.xml
@@ -0,0 +1,170 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <tuple>
+        <global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
+        <tuple/>
+      </tuple>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>Python_magic</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>Script_magic</string> </key>
+            <value> <int>3</int> </value>
+        </item>
+        <item>
+            <key> <string>__ac_local_roles__</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>_bind_names</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
+                </klass>
+                <tuple/>
+                <state>
+                  <dictionary>
+                    <item>
+                        <key> <string>_asgns</string> </key>
+                        <value>
+                          <dictionary>
+                            <item>
+                                <key> <string>name_container</string> </key>
+                                <value> <string>container</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_context</string> </key>
+                                <value> <string>context</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_m_self</string> </key>
+                                <value> <string>script</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_subpath</string> </key>
+                                <value> <string>traverse_subpath</string> </value>
+                            </item>
+                          </dictionary>
+                        </value>
+                    </item>
+                  </dictionary>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>_body</string> </key>
+            <value> <string>"""Returns the group of accounting transaction related by causality\n
+"""\n
+portal = context.getPortalObject()\n
+accounting_transaction_type_list = \\\n
+              portal.getPortalAccountingTransactionTypeList()\n
+accounting_transaction_set = {}\n
+accounting_transaction_set[context] = 1\n
+\n
+# Add all causality transactions\n
+for accounting_transaction in [context] + context.getCausalityValueList(\n
+                  portal_type=accounting_transaction_type_list):\n
+  accounting_transaction_set[accounting_transaction] = 1\n
+  for related_causality in accounting_transaction.getCausalityRelatedValueList(\n
+              portal_type=accounting_transaction_type_list):\n
+    if related_causality.getSimulationState() not in (\'cancelled\', \'deleted\'):\n
+      accounting_transaction_set[related_causality] = 1\n
+\n
+return accounting_transaction_set.keys()\n
+</string> </value>
+        </item>
+        <item>
+            <key> <string>_code</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>_filepath</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>_owner</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>_params</string> </key>
+            <value> <string></string> </value>
+        </item>
+        <item>
+            <key> <string>errors</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>func_code</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="FuncCode" module="Shared.DC.Scripts.Signature"/>
+                </klass>
+                <tuple/>
+                <state>
+                  <dictionary>
+                    <item>
+                        <key> <string>co_argcount</string> </key>
+                        <value> <int>0</int> </value>
+                    </item>
+                    <item>
+                        <key> <string>co_varnames</string> </key>
+                        <value>
+                          <tuple>
+                            <string>_getattr_</string>
+<string>context</string>
+                            <string>portal</string>
+                            <string>accounting_transaction_type_list</string>
+                            <string>accounting_transaction_set</string>
+                            <string>_write_</string>
+                            <string>_getiter_</string>
+                            <string>accounting_transaction</string>
+                            <string>related_causality</string>
+                          </tuple>
+                        </value>
+                    </item>
+                  </dictionary>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>func_defaults</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>AccountingTransaction_getCausalityGroupedAccountingTransactionList</string> </value>
+        </item>
+        <item>
+            <key> <string>warnings</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/scripts/guessGroupingReference.xml b/bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/scripts/guessGroupingReference.xml
new file mode 100644
index 0000000000..438920433d
--- /dev/null
+++ b/bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/scripts/guessGroupingReference.xml
@@ -0,0 +1,150 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <tuple>
+        <global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
+        <tuple/>
+      </tuple>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>Python_magic</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>Script_magic</string> </key>
+            <value> <int>3</int> </value>
+        </item>
+        <item>
+            <key> <string>__ac_local_roles__</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>_bind_names</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
+                </klass>
+                <tuple/>
+                <state>
+                  <dictionary>
+                    <item>
+                        <key> <string>_asgns</string> </key>
+                        <value>
+                          <dictionary>
+                            <item>
+                                <key> <string>name_container</string> </key>
+                                <value> <string>container</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_context</string> </key>
+                                <value> <string>context</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_m_self</string> </key>
+                                <value> <string>script</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_subpath</string> </key>
+                                <value> <string>traverse_subpath</string> </value>
+                            </item>
+                          </dictionary>
+                        </value>
+                    </item>
+                  </dictionary>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>_body</string> </key>
+            <value> <string>portal = sci.getPortal()\n
+\n
+# if we allow grouping with different quantities, we cannot group here\n
+# (because the script will group everything)\n
+if portal.portal_preferences.getPreference(\n
+               \'preferred_grouping_with_different_quantities\', 0):\n
+  return\n
+\n
+sci[\'object\'].AccountingTransaction_guessGroupedLines()\n
+</string> </value>
+        </item>
+        <item>
+            <key> <string>_code</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>_filepath</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>_params</string> </key>
+            <value> <string>sci</string> </value>
+        </item>
+        <item>
+            <key> <string>errors</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>func_code</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="FuncCode" module="Shared.DC.Scripts.Signature"/>
+                </klass>
+                <tuple/>
+                <state>
+                  <dictionary>
+                    <item>
+                        <key> <string>co_argcount</string> </key>
+                        <value> <int>1</int> </value>
+                    </item>
+                    <item>
+                        <key> <string>co_varnames</string> </key>
+                        <value>
+                          <tuple>
+                            <string>sci</string>
+                            <string>_getattr_</string>
+                            <string>portal</string>
+                            <string>_getitem_</string>
+                          </tuple>
+                        </value>
+                    </item>
+                  </dictionary>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>func_defaults</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>guessGroupingReference</string> </value>
+        </item>
+        <item>
+            <key> <string>warnings</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/scripts/resetGroupingReference.xml b/bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/scripts/resetGroupingReference.xml
index 5bba431899..91c2267ac6 100644
--- a/bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/scripts/resetGroupingReference.xml
+++ b/bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/scripts/resetGroupingReference.xml
@@ -65,8 +65,7 @@
         </item>
         <item>
             <key> <string>_body</string> </key>
-            <value> <string>"""When transaction is restarted, we\'ll check if we have to break existing\n
-grouping references on lines.\n
+            <value> <string>"""When transaction is restarted, we\'ll break existing grouping references on lines.\n
 """\n
 transaction = sci[\'object\']\n
 for line in transaction.getMovementList(\n
@@ -75,7 +74,7 @@ for line in transaction.getMovementList(\n
     line.activate(after_path_and_method_id=(\n
                   (transaction.getPath(), (\'recursiveImmediateReindexObject\', \'immediateReindexObject\')),\n
                   (line.getPath(), (\'recursiveImmediateReindexObject\', \'immediateReindexObject\')),),\n
-    ).AccountingTransactionLine_resetGroupingReference(keep_if_valid_group=1)\n
+    ).AccountingTransactionLine_resetGroupingReference()\n
 </string> </value>
         </item>
         <item>
diff --git a/bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/states/stopped.xml b/bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/states/stopped.xml
index 49e839e0dd..6119d567e1 100644
--- a/bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/states/stopped.xml
+++ b/bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/states/stopped.xml
@@ -41,8 +41,8 @@
                 <string>cancel_accounting_action</string>
                 <string>deliver</string>
                 <string>deliver_action</string>
+                <string>restart</string>
                 <string>restart_action</string>
-                <string>start</string>
               </tuple>
             </value>
         </item>
diff --git a/bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/transitions/restart.xml b/bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/transitions/restart.xml
new file mode 100644
index 0000000000..944e433566
--- /dev/null
+++ b/bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/transitions/restart.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <tuple>
+        <global name="TransitionDefinition" module="Products.DCWorkflow.Transitions"/>
+        <tuple/>
+      </tuple>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>__ac_local_roles__</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>actbox_category</string> </key>
+            <value> <string>workflow</string> </value>
+        </item>
+        <item>
+            <key> <string>actbox_name</string> </key>
+            <value> <string></string> </value>
+        </item>
+        <item>
+            <key> <string>actbox_url</string> </key>
+            <value> <string></string> </value>
+        </item>
+        <item>
+            <key> <string>after_script_name</string> </key>
+            <value> <string>resetGroupingReference</string> </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value> <string>Go back to started state, and remove existing grouping references on this transaction and other related.</string> </value>
+        </item>
+        <item>
+            <key> <string>guard</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>restart</string> </value>
+        </item>
+        <item>
+            <key> <string>new_state_id</string> </key>
+            <value> <string>started</string> </value>
+        </item>
+        <item>
+            <key> <string>script_name</string> </key>
+            <value> <string></string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string></string> </value>
+        </item>
+        <item>
+            <key> <string>trigger_type</string> </key>
+            <value> <int>2</int> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/transitions/restart_action.xml b/bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/transitions/restart_action.xml
index f50b859556..3cd5a6b7c4 100644
--- a/bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/transitions/restart_action.xml
+++ b/bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/transitions/restart_action.xml
@@ -29,7 +29,7 @@
         </item>
         <item>
             <key> <string>after_script_name</string> </key>
-            <value> <string>start</string> </value>
+            <value> <string>restart</string> </value>
         </item>
         <item>
             <key> <string>description</string> </key>
diff --git a/bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/transitions/stop.xml b/bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/transitions/stop.xml
index 83c070396c..ea356398a1 100644
--- a/bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/transitions/stop.xml
+++ b/bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/transitions/stop.xml
@@ -29,7 +29,7 @@
         </item>
         <item>
             <key> <string>after_script_name</string> </key>
-            <value> <string>resetGroupingReference</string> </value>
+            <value> <string>guessGroupingReference</string> </value>
         </item>
         <item>
             <key> <string>description</string> </key>
diff --git a/bt5/erp5_accounting/bt/revision b/bt5/erp5_accounting/bt/revision
index e8cbd7d8fc..191829efad 100644
--- a/bt5/erp5_accounting/bt/revision
+++ b/bt5/erp5_accounting/bt/revision
@@ -1 +1 @@
-734
\ No newline at end of file
+735
\ No newline at end of file
diff --git a/product/ERP5/tests/testAccounting.py b/product/ERP5/tests/testAccounting.py
index ebd9f3d559..11b6295ad3 100644
--- a/product/ERP5/tests/testAccounting.py
+++ b/product/ERP5/tests/testAccounting.py
@@ -1705,7 +1705,7 @@ class TestAccountingExport(AccountingTestCase):
 class TestTransactions(AccountingTestCase):
   """Test behaviours and utility scripts for Accounting Transactions.
   """
-
+  
   def test_SourceDestinationReference(self):
     # Check that source reference and destination reference are filled
     # automatically.
@@ -2068,8 +2068,7 @@ class TestTransactions(AccountingTestCase):
     self.failUnless(other_section_line.getGroupingReference())
     self.failUnless(other_letter_line.getGroupingReference())
 
-
-  def test_ResetGroupingReferenceAfterRestart(self):
+  def test_automatically_setting_grouping_reference(self):
     invoice = self._makeOne(
                title='First Invoice',
                destination_section_value=self.organisation_module.client_1,
@@ -2077,60 +2076,109 @@ class TestTransactions(AccountingTestCase):
                            source_debit=100),
                       dict(source_value=self.account_module.receivable,
                            source_credit=100,
-                           id='line_with_grouping_reference',
-                           grouping_reference='A'),))
-    
-    invoice_line = invoice.line_with_grouping_reference
+                           id='line_for_grouping_reference',)))
+    invoice_line = invoice.line_for_grouping_reference
 
     payment = self._makeOne(
                title='First Invoice Payment',
                portal_type='Payment Transaction',
                simulation_state='delivered',
+               causality_value=invoice,
                source_payment_value=self.section.newContent(
                                             portal_type='Bank Account'),
                destination_section_value=self.organisation_module.client_1,
                lines=(dict(source_value=self.account_module.receivable,
-                           id='line_with_grouping_reference',
-                           grouping_reference='A',
+                           id='line_for_grouping_reference',
                            source_debit=100),
                       dict(source_value=self.account_module.bank,
                            source_credit=100,)))
-    payment_line = payment.line_with_grouping_reference
-    invoice.stop()
+    payment_line = payment.line_for_grouping_reference
     
-    self.portal.portal_workflow.doActionFor(invoice, 'restart_action')
-    get_transaction().commit()
-    self.tic()
-    self.portal.portal_workflow.doActionFor(invoice, 'stop_action')
-    get_transaction().commit()
-    self.tic()
-    # we still have a grouping reference at this point, because the line was
-    # not modified, so the group is still valid
+    self.failIf(invoice_line.getGroupingReference())
+    self.failIf(payment_line.getGroupingReference())
+    
+    # lines match, they are automatically grouped
+    invoice.stop()
     self.failUnless(invoice_line.getGroupingReference())
     self.failUnless(payment_line.getGroupingReference())
-    
-    self.portal.portal_workflow.doActionFor(invoice, 'restart_action')
+  
+    # when restarting, grouping is removed
+    invoice.restart()
     get_transaction().commit()
     self.tic()
-    # try again, after modifying lines.
-    for line in invoice.getMovementList():
-      line.setQuantity(line.getQuantity() * 1.5)
-    # Now the group is no longer valid, so passing stop transaction again will
-    # ungroup lines.
-    self.portal.portal_workflow.doActionFor(invoice, 'stop_action')
-    
-    # this is done with activities, because we need an up to date catalog to
-    # check if the group is still valid, so we do this in an activity after
-    # this document indexing.
+    self.failIf(invoice_line.getGroupingReference())
+    self.failIf(payment_line.getGroupingReference())
+    invoice.stop()
     self.failUnless(invoice_line.getGroupingReference())
     self.failUnless(payment_line.getGroupingReference())
+
+  def test_automatically_setting_grouping_reference_only_related(self):
+    invoice = self._makeOne(
+               title='First Invoice',
+               destination_section_value=self.organisation_module.client_1,
+               lines=(dict(source_value=self.account_module.goods_purchase,
+                           source_debit=100),
+                      dict(source_value=self.account_module.receivable,
+                           source_credit=100,
+                           id='line_for_grouping_reference',)))
+    invoice_line = invoice.line_for_grouping_reference
+
+    payment = self._makeOne(
+               title='First Invoice Payment',
+               portal_type='Payment Transaction',
+               simulation_state='delivered',
+               # payment is not related with invoice, so no automatic grouping
+               # will occur
+               source_payment_value=self.section.newContent(
+                                            portal_type='Bank Account'),
+               destination_section_value=self.organisation_module.client_1,
+               lines=(dict(source_value=self.account_module.receivable,
+                           id='line_for_grouping_reference',
+                           source_debit=100),
+                      dict(source_value=self.account_module.bank,
+                           source_credit=100,)))
+    payment_line = payment.line_for_grouping_reference
     
-    # after activities invocation, grouping references have been removed
-    get_transaction().commit()
-    self.tic()
     self.failIf(invoice_line.getGroupingReference())
     self.failIf(payment_line.getGroupingReference())
+    
+    invoice.stop()
+    self.failIf(invoice_line.getGroupingReference())
+    self.failIf(payment_line.getGroupingReference())
+
+  def test_automatically_setting_grouping_reference_same_section(self):
+    invoice = self._makeOne(
+               title='First Invoice',
+               destination_section_value=self.organisation_module.client_1,
+               lines=(dict(source_value=self.account_module.goods_purchase,
+                           source_debit=100),
+                      dict(source_value=self.account_module.receivable,
+                           source_credit=100,
+                           id='line_for_grouping_reference',)))
+    invoice_line = invoice.line_for_grouping_reference
 
+    payment = self._makeOne(
+               title='First Invoice Payment',
+               portal_type='Payment Transaction',
+               simulation_state='delivered',
+               causality_value=invoice,
+               source_payment_value=self.section.newContent(
+                                            portal_type='Bank Account'),
+               destination_section_value=self.organisation_module.client_2,
+               lines=(dict(source_value=self.account_module.receivable,
+                           id='line_for_grouping_reference',
+                           source_debit=100),
+                      dict(source_value=self.account_module.bank,
+                           source_credit=100,)))
+    payment_line = payment.line_for_grouping_reference
+    
+    self.failIf(invoice_line.getGroupingReference())
+    self.failIf(payment_line.getGroupingReference())
+    
+    # different sections, no grouping
+    invoice.stop()
+    self.failIf(invoice_line.getGroupingReference())
+    self.failIf(payment_line.getGroupingReference())
 
 
 class TestAccountingWithSequences(ERP5TypeTestCase):
-- 
2.30.9