Commit e2207068 authored by Sebastien Robin's avatar Sebastien Robin

- fix reindexing of Balance Transaction. There was following

  problem :
  1 - balance transaction A is indexed at date t1, a quantity
      diff of 1 is found on line a, so -1 is inserted into stock
  2 - for some reasons, a movement with date t2 with t2 < t1
      was not well indexed, after a reindex it is now correctly
      indexed
  3 - we reindex the balance transaction, thanks to to 2) there
      no diff any more, but due to bug the diff of -1 is not
      removed from the stock.
- add test for validating the fix of this bug

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@43307 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 1d050ffb
...@@ -32,6 +32,7 @@ from AccessControl import ClassSecurityInfo ...@@ -32,6 +32,7 @@ from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions, PropertySheet from Products.ERP5Type import Permissions, PropertySheet
from Products.ERP5.Document.Inventory import Inventory from Products.ERP5.Document.Inventory import Inventory
from Products.ERP5.Document.AccountingTransaction import AccountingTransaction from Products.ERP5.Document.AccountingTransaction import AccountingTransaction
import types
class InventoryKey(UserDict): class InventoryKey(UserDict):
...@@ -356,9 +357,7 @@ class BalanceTransaction(AccountingTransaction, Inventory): ...@@ -356,9 +357,7 @@ class BalanceTransaction(AccountingTransaction, Inventory):
# we were doing with reversed calculation, so negate deltas again. # we were doing with reversed calculation, so negate deltas again.
# Also we remove stocks that have 0 quantity and price. # Also we remove stocks that have 0 quantity and price.
return [negateStock(s) for s in stock_diff_list return [negateStock(s) for s in stock_diff_list]
if round(s['quantity'], precision) and
round(s['total_price'], precision)]
def negateStock(stock): def negateStock(stock):
negated_stock = stock.copy() negated_stock = stock.copy()
...@@ -394,6 +393,12 @@ class BalanceTransaction(AccountingTransaction, Inventory): ...@@ -394,6 +393,12 @@ class BalanceTransaction(AccountingTransaction, Inventory):
arguments and returns a temp object edited with those properties. arguments and returns a temp object edited with those properties.
""" """
from Products.ERP5Type.Document import newTempAccountingTransactionLine from Products.ERP5Type.Document import newTempAccountingTransactionLine
# When have to reindex temp objects with quantity 0 in
# order to update stock if delta become 0, but but redefining
# isAccountable we do not insert 0 lines in stock
def isAccountable(self):
return self.getProperty('total_price', 0) != 0 or \
self.getProperty('quantity', 0) != 0
def factory(*args, **kw): def factory(*args, **kw):
doc = newTempAccountingTransactionLine(self, kw.pop('id', self.getId()), doc = newTempAccountingTransactionLine(self, kw.pop('id', self.getId()),
uid=self.getUid()) uid=self.getUid())
...@@ -403,6 +408,7 @@ class BalanceTransaction(AccountingTransaction, Inventory): ...@@ -403,6 +408,7 @@ class BalanceTransaction(AccountingTransaction, Inventory):
if destination_total_asset_price is not None: if destination_total_asset_price is not None:
kw['destination_total_asset_price'] = destination_total_asset_price kw['destination_total_asset_price'] = destination_total_asset_price
doc._edit(*args, **kw) doc._edit(*args, **kw)
doc.isAccountable = types.MethodType(isAccountable, doc)
if relative_url: if relative_url:
......
...@@ -1292,6 +1292,7 @@ class TestClosingPeriod(AccountingTestCase): ...@@ -1292,6 +1292,7 @@ class TestClosingPeriod(AccountingTestCase):
# now check content of stock table # now check content of stock table
q = self.portal.erp5_sql_connection.manage_test q = self.portal.erp5_sql_connection.manage_test
# 3 lines, one with quantity 3.3, 2 with quantity 0
self.assertEquals(1, q( self.assertEquals(1, q(
"SELECT count(*) FROM stock WHERE portal_type=" "SELECT count(*) FROM stock WHERE portal_type="
"'Balance Transaction Line'")[0][0]) "'Balance Transaction Line'")[0][0])
...@@ -1915,9 +1916,11 @@ class TestClosingPeriod(AccountingTestCase): ...@@ -1915,9 +1916,11 @@ class TestClosingPeriod(AccountingTestCase):
section_uid=self.section.getUid(), section_uid=self.section.getUid(),
node_uid=node_uid)) node_uid=node_uid))
# and only one movement is returned by getMovementHistoryList # and only one movement is returned by getMovementHistoryList
self.assertEquals(1, len(stool.getMovementHistoryList( movement_history_list = stool.getMovementHistoryList(
section_uid=self.section.getUid(), section_uid=self.section.getUid(),
node_uid=node_uid))) node_uid=node_uid)
self.assertEquals(1, len(movement_history_list))
self.assertEquals([100], [x.total_price for x in movement_history_list])
# the account 'goods_sales' has a balance of -100 # the account 'goods_sales' has a balance of -100
node_uid = self.account_module.goods_sales.getUid() node_uid = self.account_module.goods_sales.getUid()
...@@ -1941,6 +1944,42 @@ class TestClosingPeriod(AccountingTestCase): ...@@ -1941,6 +1944,42 @@ class TestClosingPeriod(AccountingTestCase):
section_uid=self.section.getUid(), section_uid=self.section.getUid(),
node_uid=node_uid)) node_uid=node_uid))
# Now check that even if we change the old movement and we
# reindex the balance, the stock will still be the same
getInventoryList = self.portal.portal_simulation.getInventoryList
def getInventoryQuantityList():
quantity_list = [x.inventory for x in getInventoryList(
section_uid=self.section.getUid(),
node_uid=node_uid)]
quantity_list.sort()
return quantity_list
# 100 for the transaction, 0 for the balance
# because in the balance we put exactly what we have in stock
self.assertEquals(getInventoryQuantityList(),
[100])
def setQuantityOnTransaction1(quantity):
for line in transaction1.objectValues():
if line.getSourceDebit():
line.setSourceDebit(quantity)
if line.getSourceCredit():
line.setSourceCredit(quantity)
transaction.commit()
self.tic()
balance.reindexObject()
transaction.commit()
self.tic()
setQuantityOnTransaction1(99)
# 99 for the transaction, 1 for the balance
# because in the balance we have 100, which is 1 more
# than actual stock of 99
self.assertEquals(getInventoryQuantityList(),
[1, 99])
setQuantityOnTransaction1(100)
# Then finally we check that we have again same thing
# as initial conditions
self.assertEquals(getInventoryQuantityList(),
[100])
def test_InventoryIndexingNodeDiffOnNode(self): def test_InventoryIndexingNodeDiffOnNode(self):
# Balance Transactions are indexed as Inventories. # Balance Transactions are indexed as Inventories.
transaction1 = self._makeOne( transaction1 = self._makeOne(
...@@ -2231,9 +2270,12 @@ class TestClosingPeriod(AccountingTestCase): ...@@ -2231,9 +2270,12 @@ class TestClosingPeriod(AccountingTestCase):
self.assertEquals(-150, stool.getInventory( self.assertEquals(-150, stool.getInventory(
section_uid=self.section.getUid(), section_uid=self.section.getUid(),
node_uid=node_uid)) node_uid=node_uid))
self.assertEquals(2, len(stool.getMovementHistoryList( movement_history_list = stool.getMovementHistoryList(
section_uid=self.section.getUid(), section_uid=self.section.getUid(),
node_uid=node_uid))) node_uid=node_uid)
self.assertEquals(2, len(movement_history_list))
self.assertEquals([-50, -100], [x.total_quantity for x in \
movement_history_list])
def test_BalanceTransactionDateInInventoryAPI(self): def test_BalanceTransactionDateInInventoryAPI(self):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment