diff --git a/product/ERP5/Document/BalanceTransaction.py b/product/ERP5/Document/BalanceTransaction.py
new file mode 100644
index 0000000000000000000000000000000000000000..6045103d0e3a6b6fc42aaaa6ff5e6849dc6e40da
--- /dev/null
+++ b/product/ERP5/Document/BalanceTransaction.py
@@ -0,0 +1,399 @@
+##############################################################################
+#
+# Copyright (c) 2007 Nexedi SA and Contributors. All Rights Reserved.
+#                    Jerome Perrin <jerome@nexedi.com>
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsability 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
+# garantees and support are strongly adviced 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+##############################################################################
+
+from UserDict import UserDict
+
+from AccessControl import ClassSecurityInfo
+from Products.ERP5Type import Permissions, PropertySheet, Constraint, Interface
+from Products.ERP5.Document.Inventory import Inventory
+from Products.ERP5.Document.AccountingTransaction import AccountingTransaction
+
+
+class InventoryKey(UserDict):
+  """Class to use as a key when defining inventory dicts.
+  """
+  def __init__(self, **kw):
+    self.data = {}
+    self.data.update(kw)
+
+  def clear(self):
+    raise TypeError, 'InventoryKey are immutable'
+  
+  def pop(self, keys, *args):
+    raise TypeError, 'InventoryKey are immutable'
+  
+  def update(self, dict=None, **kwargs):
+    raise TypeError, 'InventoryKey are immutable'
+  
+  def __delitem__(self, key):
+    raise TypeError, 'InventoryKey are immutable'
+  
+  def __setitem__(self, key, item):
+    raise TypeError, 'InventoryKey are immutable'
+  
+  def setdefault(self, key, failobj=None):
+    if key in self.data:
+      return self.data[key]
+    raise TypeError, 'InventoryKey are immutable'
+
+  def __hash__(self):
+    return hash(tuple(self.items()))
+
+
+class BalanceTransaction(AccountingTransaction, Inventory):
+  """Balance Transaction 
+  """
+
+  # CMF Type Definition
+  meta_type = 'ERP5 Balance Transaction'
+  portal_type = 'Balance Transaction'
+  add_permission = Permissions.AddPortalContent
+  isPortalContent = 1
+  isRADContent = 1
+  isDelivery = 1
+    
+  #__implements__ = ( Interface.Inventory, )
+
+  # Declarative security
+  security = ClassSecurityInfo()
+  security.declareObjectProtected(Permissions.AccessContentsInformation)
+
+  # Default Properties
+  property_sheets = ( PropertySheet.Base
+                    , PropertySheet.XMLObject
+                    , PropertySheet.CategoryCore
+                    , PropertySheet.DublinCore
+                    , PropertySheet.Task
+                    , PropertySheet.Arrow
+                    , PropertySheet.Movement
+                    , PropertySheet.Delivery
+                    , PropertySheet.Amount
+                    , PropertySheet.Reference
+                    , PropertySheet.PaymentCondition
+                    )
+
+  def _getGroupByNodeMovementList(self):
+    """Returns movements that implies only grouping by node."""
+    movement_list = []
+    for movement in self.getMovementList():
+      if not (movement.getSourceSection() or
+                movement.getDestinationPayment()):
+        movement_list.append(movement)
+    return movement_list
+
+  def _getGroupByPaymentMovementList(self):
+    """Returns movements that implies grouping by node and payment"""
+    movement_list = []
+    for movement in self.getMovementList():
+      if movement.getDestinationPayment():
+        movement_list.append(movement)
+    return movement_list
+
+  def _getGroupByMirrorSectionMovementList(self):
+    """Returns movements that implies only grouping by node and mirror section"""
+    movement_list = []
+    for movement in self.getMovementList():
+      if movement.getSourceSection():
+        movement_list.append(movement)
+    return movement_list
+
+
+  def _getCurrentStockDict(self):
+    """Looks the current stock by calling getInventoryList, and building a
+    dictionnary of InventoryKey
+    """
+    current_stock = dict()
+    getInventoryList = self.getPortalObject()\
+                            .portal_simulation.getInventoryList
+    default_inventory_params = dict(
+                        at_date=self.getStartDate(),
+                        section_uid=self.getDestinationSectionUid(),
+                        simulation_state=('delivered', ))
+
+    # node
+    for movement in self._getGroupByNodeMovementList():
+      node_uid = movement.getDestinationUid()
+      section_uid = movement.getDestinationSectionUid()
+
+      stock_list = current_stock.setdefault(
+                         InventoryKey(node_uid=node_uid,
+                                      section_uid=section_uid), [])
+      for inventory in getInventoryList(
+                              node_uid=node_uid,
+                              group_by_node=1,
+                              group_by_resource=1,
+                              **default_inventory_params):
+        stock_list.append(
+              dict(destination_uid=node_uid,
+                   destination_section_uid=section_uid,
+                   resource_uid=inventory.resource_uid,
+                   quantity=inventory.total_quantity,
+                   total_price=inventory.total_price, ))
+    
+    # mirror section
+    for movement in self._getGroupByMirrorSectionMovementList():
+      node_uid = movement.getDestinationUid()
+      section_uid = movement.getDestinationSectionUid()
+      mirror_section_uid = movement.getSourceSectionUid()
+
+      stock_list = current_stock.setdefault(
+                         InventoryKey(node_uid=node_uid,
+                                      mirror_section_uid=mirror_section_uid,
+                                      section_uid=section_uid), [])
+      for inventory in getInventoryList(
+                              node_uid=node_uid,
+                              mirror_section_uid=mirror_section_uid,
+                              group_by_node=1,
+                              group_by_mirror_section=1,
+                              group_by_resource=1,
+                              **default_inventory_params):
+        stock_list.append(
+              dict(destination_uid=node_uid,
+                   destination_section_uid=section_uid,
+                   source_section_uid=mirror_section_uid,
+                   resource_uid=inventory.resource_uid,
+                   quantity=inventory.total_quantity,
+                   total_price=inventory.total_price, ))
+
+    # payment
+    for movement in self._getGroupByPaymentMovementList():
+      node_uid = movement.getDestinationUid()
+      payment_uid = movement.getDestinationPaymentUid()
+      section_uid = movement.getDestinationSectionUid()
+
+      stock_list = current_stock.setdefault(
+                         InventoryKey(node_uid=node_uid,
+                                      section_uid=section_uid,
+                                      payment_uid=payment_uid), [])
+      for inventory in getInventoryList(
+                              node_uid=node_uid,
+                              group_by_node=1,
+                              group_by_payment=1,
+                              group_by_resource=1,
+                              **default_inventory_params):
+        stock_list.append(
+              dict(destination_uid=node_uid,
+                   destination_section_uid=section_uid,
+                   destination_payment_uid=payment_uid,
+                   resource_uid=inventory.resource_uid,
+                   quantity=inventory.total_quantity,
+                   total_price=inventory.total_price, ))
+
+    return current_stock
+
+
+  def _getNewStockDict(self):
+    """Looks the new stock on lines in this inventory, and building a
+    dictionnary of InventoryKey
+    """
+    new_stock = dict()
+    # node
+    for movement in self._getGroupByNodeMovementList():
+      node_uid = movement.getDestinationUid()
+      section_uid = movement.getDestinationSectionUid()
+
+      stock_list = new_stock.setdefault(
+                 InventoryKey(node_uid=node_uid,
+                              section_uid=section_uid), [])
+      stock_list.append(
+              dict(destination_uid=node_uid,
+                   destination_section_uid=section_uid,
+                   resource_uid=movement.getResourceUid(),
+                   quantity=movement.getQuantity(),
+                   total_price=movement\
+                    .getDestinationInventoriatedTotalAssetPrice(), ))
+    
+    # mirror section
+    for movement in self._getGroupByMirrorSectionMovementList():
+      node_uid = movement.getDestinationUid()
+      section_uid = movement.getDestinationSectionUid()
+      mirror_section_uid = movement.getSourceSectionUid()
+
+      stock_list = new_stock.setdefault(
+                 InventoryKey(node_uid=node_uid,
+                              mirror_section_uid=mirror_section_uid,
+                              section_uid=section_uid), [])
+      stock_list.append(
+              dict(destination_uid=node_uid,
+                   destination_section_uid=section_uid,
+                   source_section_uid=mirror_section_uid,
+                   resource_uid=movement.getResourceUid(),
+                   quantity=movement.getQuantity(),
+                   total_price=movement\
+                    .getDestinationInventoriatedTotalAssetPrice(), ))
+    
+    # payment
+    for movement in self._getGroupByPaymentMovementList():
+      node_uid = movement.getDestinationUid()
+      section_uid = movement.getDestinationSectionUid()
+      payment_uid = movement.getDestinationPaymentUid()
+
+      stock_list = new_stock.setdefault(
+                 InventoryKey(node_uid=node_uid,
+                              payment_uid=payment_uid,
+                              section_uid=section_uid), [])
+      stock_list.append(
+              dict(destination_uid=node_uid,
+                   destination_section_uid=section_uid,
+                   destination_payment_uid=payment_uid,
+                   resource_uid=movement.getResourceUid(),
+                   quantity=movement.getQuantity(),
+                   total_price=movement\
+                    .getDestinationInventoriatedTotalAssetPrice(), ))
+    
+    return new_stock
+
+
+  def _computeStockDifferenceList(self, current_stock_dict, new_stock_dict):
+    """Compute the difference between the result of _getCurrentStockDict and
+    _getNewStockDict. Returns a list of dictionnaries with similar keys that
+    the ones on inventory brains (node, section, mirror_section ...)
+    """
+    def computeStockDifference(current_stock_list, new_stock_list):
+      # helper function to compute difference between two stock lists.
+      if not current_stock_list:
+        return new_stock_list
+      
+      stock_diff_list = current_stock_list[::] # deep copy ?
+
+      for new_stock in new_stock_list:
+        matching_diff = None
+        for diff in stock_diff_list:
+          for prop in [k for k in diff.keys() if k not in ('quantity',
+                          'total_price')]:
+            if diff[prop] != new_stock.get(prop):
+              break
+          else:
+            matching_diff = diff
+        
+        # matching_diff are negated later
+        if matching_diff:
+          matching_diff['quantity'] -= new_stock['quantity']
+          # Matching_diff and new_stock must be consistent.
+          # both with total price or none.
+          if matching_diff['total_price'] and new_stock['total_price']:
+            matching_diff['total_price'] -= new_stock['total_price']
+        else:
+          stock_diff_list.append(new_stock)
+
+      # we were doing with reversed calculation, so negate deltas again.
+      # Also we remove stocks that have 0 quantity and price.
+      return [negateStock(s) for s in stock_diff_list
+              if s['quantity'] and s['total_price']]
+
+    def negateStock(stock):
+      negated_stock = stock.copy()
+      negated_stock['quantity'] = -stock['quantity']
+      if stock['total_price']:
+        negated_stock['total_price'] = -stock['total_price']
+      return negated_stock
+
+    delta_list = []
+    for current_stock_key, current_stock_value_list in \
+                            current_stock_dict.items():
+      if current_stock_key in new_stock_dict:
+        delta_list.extend(computeStockDifference(
+                              current_stock_value_list,
+                              new_stock_dict[current_stock_key]))
+      else:
+        delta_list.extend(
+            [negateStock(s) for s in current_stock_value_list])
+    
+    # now add every thing in new stock which was not in current stock
+    for new_stock_key, new_stock_value_list in \
+                                new_stock_dict.items():
+      if new_stock_key not in current_stock_dict:
+        delta_list.extend(new_stock_value_list)
+
+    return delta_list
+
+
+  def _getTempObjectFactory(self):
+    """Returns the factory method that will create temp object.
+
+    This method must return a function that accepts properties keywords
+    arguments and returns a temp object edited with those properties.
+    """
+    from Products.ERP5Type.Document import newTempBalanceTransactionLine
+
+    def factory(*args, **kw):
+      doc = newTempBalanceTransactionLine(self, self.getId(),
+                                         uid=self.getUid())
+      destination_total_asset_price = kw.pop('total_price', None)
+      if destination_total_asset_price is not None:
+        kw['destination_total_asset_price'] = destination_total_asset_price
+      doc._edit(*args, **kw)
+      return doc
+
+    return factory
+
+
+  security.declarePrivate('alternateReindexObject')
+  def alternateReindexObject(self, **kw):
+    """This method is called when an inventory object is included in a
+    group of catalogged objects.
+    """
+    return self.immediateReindexObject(**kw)
+
+
+  def immediateReindexObject(self, **kw):
+    """Reindexes the object.
+    This is different indexing that the default Inventory indexing, because
+    we want to take into account that lines in this balance transaction to
+    represent the balance of an account (node) with different parameters,
+    based on the account_type of those accounts:
+      - on standards accounts: it's simply the balance for node, section
+       (and maybe resource, like all of thoses)
+      - on payable / receivable accounts: for node, section and mirror
+        section
+      - on bank accounts: for node, section and payment
+
+    Also this uses total_price (and quantity), and ignores variations and
+    subvariations as it does not exist in accounting.
+    """
+    current_stock_dict = self._getCurrentStockDict()
+    new_stock_dict = self._getNewStockDict()
+    diff_list = self._computeStockDifferenceList(
+                                    current_stock_dict,
+                                    new_stock_dict)
+
+    temp_object_factory = self._getTempObjectFactory()
+    stock_object_list = []
+    add_obj = stock_object_list.append
+    for diff in diff_list:
+      add_obj(temp_object_factory(**diff))
+
+    # Catalog this transaction as a standard document
+    object_list = [self]
+    self.portal_catalog.catalogObjectList(object_list)
+    
+    # Catalog differences calculated from lines
+    self.portal_catalog.catalogObjectList(stock_object_list,
+         method_id_list=('z_catalog_stock_list',),
+         disable_cache=1, check_uid=0)
+
diff --git a/product/ERP5/Document/BalanceTransactionLine.py b/product/ERP5/Document/BalanceTransactionLine.py
new file mode 100644
index 0000000000000000000000000000000000000000..8d45fb3ea1c75101200f5c5bffa43b434634f758
--- /dev/null
+++ b/product/ERP5/Document/BalanceTransactionLine.py
@@ -0,0 +1,58 @@
+##############################################################################
+#
+# Copyright (c) 2007 Nexedi SA and Contributors. All Rights Reserved.
+#                    Jerome Perrin <jerome@nexedi.com>
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsability 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
+# garantees and support are strongly adviced 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+##############################################################################
+
+from AccessControl import ClassSecurityInfo
+
+from Products.ERP5Type import Permissions, PropertySheet, Interface
+from Products.ERP5.Document.AccountingTransactionLine import \
+                      AccountingTransactionLine
+from Products.ERP5.Document.InventoryLine import InventoryLine
+
+
+class BalanceTransactionLine(AccountingTransactionLine, InventoryLine):
+  """A balance transaction line inherits price handling from accounting
+  transaction line, and indexing from inventory line.
+  """
+
+  meta_type = 'ERP5 Balance Transaction Line'
+  portal_type = 'Balance Transaction Line'
+  add_permission = Permissions.AddPortalContent
+  isPortalContent = 1
+  isRADContent = 1
+  isIndexable = 0
+
+  # Declarative security
+  security = ClassSecurityInfo()
+  security.declareObjectProtected(Permissions.AccessContentsInformation)
+
+  reindexObject = InventoryLine.reindexObject
+  recursiveReindexObject = InventoryLine.recursiveReindexObject
+  immediateReindexObject = InventoryLine.immediateReindexObject
+  recursiveImmediateReindexObject = \
+              InventoryLine.recursiveImmediateReindexObject
+
diff --git a/product/ERP5/tests/testAccounting.py b/product/ERP5/tests/testAccounting.py
index eb3c3675e636c1f6d52610adb5a05f1c7b5b9fc0..44e96b6d7c362cfa8de5b9b988a6c1b324dc8196 100644
--- a/product/ERP5/tests/testAccounting.py
+++ b/product/ERP5/tests/testAccounting.py
@@ -36,7 +36,6 @@ from Products.ERP5Type.tests.utils import reindex
 from Products.DCWorkflow.DCWorkflow import ValidationFailed
 from AccessControl.SecurityManagement import newSecurityManager
 from Products.ERP5Type.tests.Sequence import Sequence, SequenceList
-from Products.ERP5.Document.Delivery import Delivery
 from DateTime import DateTime
 
 SOURCE = 'source'
@@ -169,7 +168,7 @@ class AccountingTestCase(ERP5TypeTestCase):
                    self.person_module):
       for doc in module.objectValues():
         doc.validate()
-    
+
     # and the preference enabled
     preference = self.portal.portal_preferences.accounting_zuite_preference
     pref.manage_addLocalRoles(self.username, ('Auditor', ))
@@ -223,7 +222,7 @@ class TestClosingPeriod(AccountingTestCase):
   def test_createBalanceOnNode(self):
     period = self.section.newContent(portal_type='Accounting Period')
     period.setStartDate(DateTime(2006, 1, 1))
-    period.setStartDate(DateTime(2006, 12, 31))
+    period.setStopDate(DateTime(2006, 12, 31))
 
     transaction1 = self._makeOne(
         start_date=DateTime(2006, 1, 1),
@@ -309,7 +308,7 @@ class TestClosingPeriod(AccountingTestCase):
     organisation_module = self.organisation_module
     period = self.section.newContent(portal_type='Accounting Period')
     period.setStartDate(DateTime(2006, 1, 1))
-    period.setStartDate(DateTime(2006, 12, 31))
+    period.setStopDate(DateTime(2006, 12, 31))
 
     transaction1 = self._makeOne(
         start_date=DateTime(2006, 1, 1),
@@ -403,7 +402,7 @@ class TestClosingPeriod(AccountingTestCase):
     organisation_module = self.organisation_module
     period = self.section.newContent(portal_type='Accounting Period')
     period.setStartDate(DateTime(2006, 1, 1))
-    period.setStartDate(DateTime(2006, 12, 31))
+    period.setStopDate(DateTime(2006, 12, 31))
 
     bank1 = self.section.newContent(
                     id='bank1', reference='bank1',
@@ -529,7 +528,7 @@ class TestClosingPeriod(AccountingTestCase):
     organisation_module = self.organisation_module
     period = self.section.newContent(portal_type='Accounting Period')
     period.setStartDate(DateTime(2006, 1, 1))
-    period.setStartDate(DateTime(2006, 12, 31))
+    period.setStopDate(DateTime(2006, 12, 31))
 
     transaction1 = self._makeOne(
         start_date=DateTime(2006, 1, 1),
@@ -645,7 +644,7 @@ class TestClosingPeriod(AccountingTestCase):
     # open a period for our section
     period = self.section.newContent(portal_type='Accounting Period')
     period.setStartDate(DateTime(2006, 1, 1))
-    period.setStartDate(DateTime(2006, 12, 31))
+    period.setStopDate(DateTime(2006, 12, 31))
     self.assertEquals('draft', period.getSimulationState())
     self.portal.portal_workflow.doActionFor(period, 'start_action')
     self.assertEquals('started', period.getSimulationState())
@@ -702,7 +701,7 @@ class TestClosingPeriod(AccountingTestCase):
     """
     period1 = self.section.newContent(portal_type='Accounting Period')
     period1.setStartDate(DateTime(2006, 1, 1))
-    period1.setStartDate(DateTime(2006, 12, 31))
+    period1.setStopDate(DateTime(2006, 12, 31))
     period1.start()
     
     transaction1 = self._makeOne(
@@ -733,17 +732,17 @@ class TestClosingPeriod(AccountingTestCase):
     
     period2 = self.section.newContent(portal_type='Accounting Period')
     period2.setStartDate(DateTime(2007, 1, 1))
-    period2.setStartDate(DateTime(2007, 12, 31))
+    period2.setStopDate(DateTime(2007, 12, 31))
     period2.start()
 
     transaction2 = self._makeOne(
         start_date=DateTime(2007, 1, 2),
         portal_type='Accounting Transaction',
         simulation_state='delivered',
-        lines=(dict(destination_value=self.account_module.equity,
-                    destination_debit=100),
-               dict(destination_value=pl_account,
-                    destination_credit=100)))
+        lines=(dict(source_value=self.account_module.equity,
+                    source_debit=100),
+               dict(source_value=pl_account,
+                    source_credit=100)))
     transaction3 = self._makeOne(
         start_date=DateTime(2007, 1, 3),
         portal_type='Purchase Invoice Transaction',
@@ -753,7 +752,7 @@ class TestClosingPeriod(AccountingTestCase):
                     destination_debit=300),
                dict(destination_value=self.account_module.payable,
                     destination_credit=300)))
-    period2.stop()
+
     period2.AccountingPeriod_createBalanceTransaction(
                 profit_and_loss_account=pl_account.getRelativeUrl())
     balance_transaction_list = [tr for tr in 
@@ -798,7 +797,7 @@ class TestClosingPeriod(AccountingTestCase):
     """
     period = self.section.newContent(portal_type='Accounting Period')
     period.setStartDate(DateTime(2006, 1, 1))
-    period.setStartDate(DateTime(2006, 12, 31))
+    period.setStopDate(DateTime(2006, 12, 31))
     pl_account = self.portal.account_module.newContent(
                     portal_type='Account',
                     account_type='equity',
@@ -824,6 +823,7 @@ class TestClosingPeriod(AccountingTestCase):
                               portal_type='Balance Transaction')
     self.assertEquals(1, len(balance_transaction_list))
     balance_transaction = balance_transaction_list[0]
+    balance_transaction.alternateReindexObject()
     movement_list = balance_transaction.getMovementList()
     self.assertEquals(2, len(movement_list))
 
@@ -838,6 +838,114 @@ class TestClosingPeriod(AccountingTestCase):
     self.assertEquals(500, stock_movement_list[0].getDestinationCredit())
     
 
+  def test_InventoryIndexingNodeAndMirrorSection(self):
+    # Balance Transactions are indexed as Inventories.
+    transaction1 = self._makeOne(
+        start_date=DateTime(2006, 1, 1),
+        portal_type='Sale Invoice Transaction',
+        destination_section_value=self.organisation_module.client_1,
+        simulation_state='delivered',
+        lines=(dict(source_value=self.account_module.receivable,
+                    source_debit=100),
+               dict(source_value=self.account_module.goods_sales,
+                    source_credit=100)))
+
+    balance = self.accounting_module.newContent(
+                          portal_type='Balance Transaction',
+                          destination_section_value=self.section,
+                          start_date=DateTime(2006, 12, 31),
+                          resource_value=self.currency_module.euro,)
+    balance.newContent(
+                portal_type='Balance Transaction Line',
+                destination_value=self.account_module.receivable,
+                source_section_value=self.organisation_module.client_1,
+                destination_debit=100,)
+    balance.newContent(
+                portal_type='Balance Transaction Line',
+                destination_value=self.account_module.stocks,
+                destination_credit=100,)
+    balance.stop()
+    balance.deliver()
+    balance.immediateReindexObject()
+
+    # now check inventory
+    stool = self.getSimulationTool()
+    # the account 'receivable' has a balance of 100
+    node_uid = self.account_module.receivable.getUid()
+    self.assertEquals(100, stool.getInventory(
+                              section_uid=self.section.getUid(),
+                              node_uid=node_uid))
+    self.assertEquals(100, stool.getInventory(
+                    section_uid=self.section.getUid(),
+                    mirror_section_uid=self.organisation_module.client_1.getUid(),
+                    node_uid=node_uid))
+    self.assertEquals(100, stool.getInventoryAssetPrice(
+                    section_uid=self.section.getUid(),
+                    node_uid=node_uid))
+    # and only one movement is returned by getMovementHistoryList
+    self.assertEquals(1, len(stool.getMovementHistoryList(
+                    section_uid=self.section.getUid(),
+                    node_uid=node_uid)))
+    
+    # the account 'goods_sales' has a balance of -100
+    node_uid = self.account_module.goods_sales.getUid()
+    self.assertEquals(-100, stool.getInventory(
+                              section_uid=self.section.getUid(),
+                              node_uid=node_uid))
+
+    # the account 'stocks' has a balance of -100
+    node_uid = self.account_module.stocks.getUid()
+    self.assertEquals(-100, stool.getInventory(
+                              section_uid=self.section.getUid(),
+                              node_uid=node_uid))
+
+
+  def test_InventoryIndexingNodeDiffOnNode(self):
+    # Balance Transactions are indexed as Inventories.
+    transaction1 = self._makeOne(
+        start_date=DateTime(2006, 1, 1),
+        portal_type='Accounting Transaction',
+        simulation_state='delivered',
+        lines=(dict(source_value=self.account_module.receivable,
+                    source_debit=100),
+               dict(source_value=self.account_module.stocks,
+                    source_credit=100)))
+
+    balance = self.accounting_module.newContent(
+                          portal_type='Balance Transaction',
+                          destination_section_value=self.section,
+                          start_date=DateTime(2006, 12, 31),
+                          resource_value=self.currency_module.euro,)
+    balance.newContent(
+                portal_type='Balance Transaction Line',
+                destination_value=self.account_module.receivable,
+                destination_debit=150,)
+    balance.newContent(
+                portal_type='Balance Transaction Line',
+                destination_value=self.account_module.stocks,
+                destination_credit=90,)
+    balance.stop()
+    get_transaction().commit()
+    self.tic()
+    
+    stool = self.portal.portal_simulation
+    # the account 'receivable' has a balance of 150
+    node_uid = self.account_module.receivable.getUid()
+    self.assertEquals(150, stool.getInventory(
+                              section_uid=self.section.getUid(),
+                              node_uid=node_uid))
+    # movement history list shows 2 movements, the initial with qty 100, and
+    # the balance with quantity 50
+
+    # the account 'stocks' has a balance of -100
+    node_uid = self.account_module.stocks.getUid()
+    self.assertEquals(-90, stool.getInventory(
+                              section_uid=self.section.getUid(),
+                              node_uid=node_uid))
+    
+
+
+
 class TestAccounting(ERP5TypeTestCase):
   """The first test for Accounting
   """