diff --git a/bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/scripts/validateTransaction.xml b/bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/scripts/validateTransaction.xml
index f643ca13f57c0e022f08b2d61df8cc2907bc0b45..f5c327f2a000cd42bdff500eb6ae228bb37ef014 100644
--- a/bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/scripts/validateTransaction.xml
+++ b/bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/scripts/validateTransaction.xml
@@ -74,11 +74,10 @@
 """\n
 \n
 from Products.DCWorkflow.DCWorkflow import ValidationFailed\n
+from Products.ERP5Type.Message import Message\n
 \n
 transaction = state_change[\'object\']\n
-N_ = transaction.Base_translateString\n
-def raiseError(msg) :\n
-  raise ValidationFailed(N_(msg))\n
+N_ = lambda msg, **kw: Message(\'erp5_ui\', msg, **kw)\n
 \n
 # do we have to check transaction is in openned periods ?\n
 skip_period_validation = state_change[\'kwargs\'].get(\n
@@ -98,7 +97,7 @@ if source_section is not None and \\\n
   source_section = source_section.getMappingRelatedValue(\n
             portal_type = \'Organisation\')\n
 if source_section is None:\n
-  raiseError(\'Source Section is not Defined.\')\n
+  raise ValidationFailed(\'Source Section is not Defined.\')\n
 \n
 destination_section = transaction.getDestinationSectionValue(\n
        portal_type = [\'Organisation\', \'Person\', \'Category\'])\n
@@ -108,18 +107,18 @@ if destination_section is not None and \\\n
             portal_type = \'Organisation\')\n
 # if it\'s not an invoice, then we can validate without destination\n
 if destination_section is None and check_destination :\n
-  raiseError(\'Destination Section is not Defined.\')\n
+  raise ValidationFailed(\'Destination Section is not Defined.\')\n
 \n
 currency = transaction.getResource(portal_type = \'Currency\')\n
 if not currency :\n
-  raiseError(\'Currency is not Defined.\')\n
+  raise ValidationFailed(\'Currency is not Defined.\')\n
 \n
 # XXX manually default start date to stop date\n
 if not transaction.getStartDate() and transaction.getStopDate():\n
   transaction.setStartDate(transaction.getStopDate())\n
 \n
 if not transaction.getStartDate() :\n
-  raiseError(\'Date is not Defined\')\n
+  raise ValidationFailed(\'Date is not Defined\')\n
 else:\n
   if not skip_period_validation :\n
     valid_date = False\n
@@ -142,8 +141,8 @@ else:\n
       if apd.getStartDate().Date() <= transaction_date.Date() <= apd.getStopDate().Date():\n
         valid_date = True\n
     if not valid_date :\n
-      raiseError("Date is not in an openned Accounting Period "\n
-                 "for source section")\n
+      raise ValidationFailed("Date is not in an openned Accounting Period "\n
+                             "for source section")\n
     # do the same for destination section \n
     if check_destination :\n
       valid_date = False\n
@@ -162,8 +161,8 @@ else:\n
         if apd.getStartDate().Date() <= transaction_date.Date() <= apd.getStopDate().Date():\n
           valid_date = True\n
       if not valid_date :\n
-        raiseError("Date is not in an openned Accounting Period "+\n
-                   "for destination section")\n
+        raise ValidationFailed("Date is not in an openned Accounting Period "\n
+                               "for destination section")\n
 
 
 ]]></string> </value>
@@ -235,11 +234,12 @@ else:\n
                             <string>state_change</string>
                             <string>Products.DCWorkflow.DCWorkflow</string>
                             <string>ValidationFailed</string>
+                            <string>Products.ERP5Type.Message</string>
+                            <string>Message</string>
                             <string>_getitem_</string>
                             <string>transaction</string>
-                            <string>_getattr_</string>
                             <string>N_</string>
-                            <string>raiseError</string>
+                            <string>_getattr_</string>
                             <string>skip_period_validation</string>
                             <string>transition</string>
                             <string>check_destination</string>
diff --git a/bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/scripts/validateTransactionLines.xml b/bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/scripts/validateTransactionLines.xml
index 2fac3eb5725c8bf223189faa8764a5d33413267a..cf4ed5a0a32d3aadb4ddd46be92a2a487a7286da 100644
--- a/bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/scripts/validateTransactionLines.xml
+++ b/bt5/erp5_accounting/WorkflowTemplateItem/portal_workflow/accounting_workflow/scripts/validateTransactionLines.xml
@@ -68,26 +68,36 @@
         </item>
         <item>
             <key> <string>_body</string> </key>
-            <value> <string>"""\n
-  Validate Transaction Lines for source and destination section.\n
+            <value> <string>"""Validate Transaction Lines for source and destination section.\n
 """\n
 \n
 from Products.DCWorkflow.DCWorkflow import ValidationFailed\n
+from Products.ERP5Type.Message import Message\n
 \n
 SOURCE, DESTINATION = (\'source\', \'destination\')\n
-\n
-error_message = \'\'\n
 transaction = state_change[\'object\']\n
-N_ = transaction.Base_translateString\n
+N_ = lambda msg, **kw: Message(\'erp5_ui\', msg, **kw)\n
 \n
 # first of all, validate the transaction itself\n
 container.validateTransaction(state_change)\n
 \n
 # Get sections.\n
-source_section      = transaction.getSourceSection(     portal_type = [\'Person\', \'Organisation\',\'Category\'])\n
-destination_section = transaction.getDestinationSection(portal_type = [\'Person\', \'Organisation\',\'Category\'])\n
+source_section = transaction.getSourceSectionValue(\n
+                        portal_type=[\'Person\', \'Organisation\'])\n
+destination_section = transaction.getDestinationSectionValue(\n
+                        portal_type=[\'Person\', \'Organisation\'])\n
+\n
+# do we want to check validity for destination as well?\n
+check_for_destination = 0\n
+if source_section is not None and destination_section is not None:\n
+  source_section_group = source_section.getGroup().lstrip(\'group/\').split(\'/\')\n
+  destination_section_group = destination_section\\\n
+                                  .getGroup().lstrip(\'group/\').split(\'/\')\n
+  if destination_section_group and source_section_group and \\\n
+      destination_section_group[0] == source_section_group[0]:\n
+    check_for_destination = 1\n
 \n
-source_sum      = 0\n
+source_sum = 0\n
 destination_sum = 0\n
 \n
 # Check transaction lines\n
@@ -96,10 +106,14 @@ if transaction.getPortalType() not in (\'Balance Transaction\',) :\n
          filter={ \'portal_type\':\n
                transaction.getPortalAccountingMovementTypeList()})\n
   for transaction_line in accounting_transaction_line_list:\n
-    if source_section != destination_section :\n
-      source_quantity      = transaction_line.getSourceInventoriatedTotalAssetPrice()      or 0\n
-      destination_quantity = transaction_line.getDestinationInventoriatedTotalAssetPrice() or 0\n
-    else :\n
+    # XXX would source_section != destination_section work here ?\n
+    if source_section is not None and destination_section is not None and\\\n
+            source_section.getUid() != destination_section.getUid():\n
+      source_quantity = transaction_line\\\n
+                            .getSourceInventoriatedTotalAssetPrice() or 0\n
+      destination_quantity = transaction_line\\\n
+                          .getDestinationInventoriatedTotalAssetPrice() or 0\n
+    else:\n
       destination_quantity = source_quantity = ((transaction_line\\\n
                   .getSourceInventoriatedTotalAssetPrice() or 0) + \\\n
           (transaction_line.getDestinationInventoriatedTotalAssetPrice() or 0))\n
@@ -110,72 +124,108 @@ if transaction.getPortalType() not in (\'Balance Transaction\',) :\n
     if transaction_line.getSource(     portal_type = \'Account\') is None and \\\n
        transaction_line.getDestination(portal_type = \'Account\') is None and \\\n
        transaction_line.getQuantity() != 0:\n
-      raise ValidationFailed, N_("Action failed: no account defined for line \'${line_id}\'."\n
-                                , mapping = {\'line_id\': transaction_line.getId()}\n
-                                )\n
+      raise ValidationFailed, N_(\n
+            "Action failed: no account defined for line \'${line_id}\'.",\n
+             mapping = {\'line_id\': transaction_line.getId()} )\n
 \n
     for side in (SOURCE, DESTINATION) :\n
       if side == SOURCE:\n
-        account          = transaction_line.getSourceValue(portal_type = \'Account\')\n
+        account = transaction_line.getSourceValue(portal_type=\'Account\')\n
         payment          = transaction_line.getSourcePaymentValue()\n
-        third_party_path = transaction_line.getDestinationSection()\n
         third_party      = transaction_line.getDestinationSectionValue()\n
       else:\n
-        account          = transaction_line.getDestinationValue(portal_type = \'Account\')\n
+        account = transaction_line.getDestinationValue(portal_type=\'Account\')\n
         payment          = transaction_line.getDestinationPaymentValue()\n
-        third_party_path = transaction_line.getSourceSection()\n
         third_party      = transaction_line.getSourceSectionValue()\n
 \n
       if account is None:\n
         continue\n
 \n
       if account.getValidationState() != \'validated\':\n
-          raise ValidationFailed, N_("Action failed: account \'${account_title}\' is not opened."\n
-                                    , mapping = {\'account_title\': unicode(account.getTranslatedTitle(), \'utf8\')}\n
-                                    )\n
-\n
+          raise ValidationFailed, N_(\n
+                  "Action failed: account \'${account_title}\' is not opened.",\n
+                   mapping = {\'account_title\':\n
+                              unicode(account.getTranslatedTitle(), \'utf8\')})\n
+                              \n
       # Test third party related-data\n
       if account.getAccountTypeId() in ("receivable", "payable"):\n
         # Test existence\n
-        if third_party_path in (None, \'\'):\n
-          raise ValidationFailed, N_("Action failed: no third party defined for line \'${line}\'."\n
-                                    , mapping = {\'line\': transaction_line.getId()}\n
-                                    )\n
-        if third_party not in (None, \'\') and third_party.getPortalType() in [\'Person\', \'Organisation\']:\n
-          # Test state\n
+        if third_party is None:\n
+          raise ValidationFailed, N_(\n
+               "Action failed: no third party defined for line \'${line}\'.",\n
+               mapping = {\'line\': transaction_line.getId()} )\n
+        if third_party is not None and third_party.getPortalType() \\\n
+                                          in [\'Person\', \'Organisation\']:\n
+          # Test state :(\n
           if third_party.getValidationState() != \'validated\':\n
-            raise ValidationFailed, N_("Action failed: third party \'${third_party_name}\' is not validated."\n
-                                      , mapping = {\'third_party_name\': unicode(third_party.getTranslatedTitle(), \'utf8\')}\n
-                                      )\n
+            raise ValidationFailed, N_(\n
+                "Action failed: third party \'${third_party_name}\' is not "\n
+                "validated.",\n
+                 mapping = {\'third_party_name\':\n
+                        unicode(third_party.getTranslatedTitle(), \'utf8\')} )\n
           # Test region\n
-          # Note: This test is normally handle by the entity workflow which don\'t allow validation of entity\n
-          #       until region is set. So if the previous condition is not verified, the previous test\n
-          #       catch it. We add this redundent test for easy upgrade of previous ERP5 accounting system.\n
-          if third_party.getRegion() in (None, \'\'):\n
-            raise ValidationFailed, N_("Action failed: third party \'${third_party_name}\' has no region."\n
-                                      , mapping = {\'third_party_name\': unicode(third_party.getTranslatedTitle(), \'utf8\')}\n
-                                      )\n
-\n
-      if (side == SOURCE) and account.isMemberOf("account_type/asset/cash/bank"):\n
-        if payment in (None, ""):\n
-          raise ValidationFailed, N_("Action failed: no bank account defined for line \'${line}\'."\n
-                                    , mapping = {\'line\': transaction_line.getId()}\n
-                                    )\n
-        elif hasattr(payment, \'getPriceCurrency\')   and \\\n
-             payment.getPriceCurrency() is not None and \\\n
-             payment.getPriceCurrency() != transaction_line.getResource():\n
-          raise ValidationFailed, N_("Action failed: bank account for line \'${line}\' "+\n
-                                     \'uses ${bank_account_currency} as default currency.\'\n
-                                    , mapping = { \'line\'                 : transaction_line.getId()\n
-                                                , \'bank_account_currency\': unicode(payment.getPriceCurrencyValue().getReference(), \'utf8\')\n
-                                                }\n
-                                    )\n
+          # Note: This test is normally handle by the entity workflow which\n
+          # don\'t allow validation of entity until region is set. So if the\n
+          # previous condition is not verified, the previous test catch it. We\n
+          # add this redundent test for easy upgrade of previous ERP5\n
+          # accounting system.\n
+          if not third_party.getRegion():\n
+            raise ValidationFailed, N_(\n
+              "Action failed: third party \'${third_party_name}\' has no "\n
+              "region.",\n
+              mapping = {\'third_party_name\':\n
+                    unicode(third_party.getTranslatedTitle(), \'utf8\')})\n
 \n
+      if (side == SOURCE) and account.isMemberOf(\n
+                                  "account_type/asset/cash/bank"):\n
+        # XXX we must check for source only if we are intersted in the\n
+        # accounting for source. Today, payment transaction cannot be validated\n
+        # if they do not have a source, so this check is not needed yet.\n
+        if payment is None:\n
+          raise ValidationFailed, N_(\n
+           "Action failed: no source bank account defined for line \'${line}\'.",\n
+            mapping = {\'line\': transaction_line.getId()} )\n
+        else:\n
+          bank_account_currency = payment.getProperty(\'price_currency\')\n
+          if bank_account_currency is not None and \\\n
+                bank_account_currency != transaction_line.getResource():\n
+            raise ValidationFailed, N_(\n
+                  "Action failed: source bank account for line \'${line}\' "\\\n
+                  "uses ${bank_account_currency} as default currency.",\n
+                     mapping = { \'line\' : transaction_line.getId(),\n
+                                 \'bank_account_currency\':\n
+                     unicode(payment.getPriceCurrencyReference(), \'utf8\')})\n
+      \n
+      if (side == DESTINATION) and account.isMemberOf(\n
+                                  "account_type/asset/cash/bank"):\n
+        # we check account for destination section only if we are interested in\n
+        # the accounting for this entity.\n
+        if not check_for_destination:\n
+          continue\n
+        if payment is None:\n
+          raise ValidationFailed, N_(\n
+                "Action failed: no destination bank account defined for"\n
+                " line \'${line}\'.",\n
+                mapping = {\'line\': transaction_line.getId()} )\n
+        else:\n
+          bank_account_currency = payment.getProperty(\'price_currency\')\n
+          if bank_account_currency is not None and \\\n
+                bank_account_currency != transaction_line.getResource():\n
+            raise ValidationFailed, N_(\n
+                  "Action failed: bank account for line \'${line}\' "\\\n
+                  "uses ${bank_account_currency} as default currency.",\n
+                     mapping = { \'line\' : transaction_line.getId(),\n
+                                 \'bank_account_currency\':\n
+                     unicode(payment.getPriceCurrencyReference(), \'utf8\')})\n
+    \n
+  # TODO: should use currency precision instead of hardcoding 100 !\n
   if int(source_sum*100) != 0:\n
-    raise ValidationFailed, N_(\'Action failed: transaction is not balanced for source section.\')\n
+    raise ValidationFailed, N_(\n
+            \'Action failed: transaction is not balanced for source section.\')\n
 \n
   if int(destination_sum*100) != 0:\n
-    raise ValidationFailed, N_(\'Action failed: transaction is not balanced for destination section.\')\n
+    raise ValidationFailed, N_(\n
+        \'Action failed: transaction is not balanced for destination section.\')\n
 \n
 transaction.AccountingTransaction_deleteEmptyLines(redirect=0)\n
 </string> </value>
@@ -247,31 +297,34 @@ transaction.AccountingTransaction_deleteEmptyLines(redirect=0)\n
                             <string>state_change</string>
                             <string>Products.DCWorkflow.DCWorkflow</string>
                             <string>ValidationFailed</string>
+                            <string>Products.ERP5Type.Message</string>
+                            <string>Message</string>
                             <string>_getiter_</string>
                             <string>SOURCE</string>
                             <string>DESTINATION</string>
-                            <string>error_message</string>
                             <string>_getitem_</string>
                             <string>transaction</string>
-                            <string>_getattr_</string>
                             <string>N_</string>
+                            <string>_getattr_</string>
                             <string>container</string>
                             <string>source_section</string>
                             <string>destination_section</string>
+                            <string>check_for_destination</string>
+                            <string>None</string>
+                            <string>source_section_group</string>
+                            <string>destination_section_group</string>
                             <string>source_sum</string>
                             <string>destination_sum</string>
                             <string>accounting_transaction_line_list</string>
                             <string>transaction_line</string>
                             <string>source_quantity</string>
                             <string>destination_quantity</string>
-                            <string>None</string>
                             <string>side</string>
                             <string>account</string>
                             <string>payment</string>
-                            <string>third_party_path</string>
                             <string>third_party</string>
                             <string>unicode</string>
-                            <string>hasattr</string>
+                            <string>bank_account_currency</string>
                             <string>int</string>
                           </tuple>
                         </value>
diff --git a/bt5/erp5_accounting/bt/revision b/bt5/erp5_accounting/bt/revision
index dc7b54ad014355b948b93c4c6c5891da053d5fdd..aaa6442fe902e96a5233b136b973b96a4011fc18 100644
--- a/bt5/erp5_accounting/bt/revision
+++ b/bt5/erp5_accounting/bt/revision
@@ -1 +1 @@
-33
\ No newline at end of file
+41
\ No newline at end of file