Commit 2c525e57 authored by Jérome Perrin's avatar Jérome Perrin

core: handle price 0 or None in Inventory API

The methods used in indexing did not make a difference between the case
where the price is None (ie. price is not set) or where the price is
set to 0 - in both cases this was saved as NULL in stock.total_price
column. This is incorrect, we need to keep the distinction between
these two cases also for inventory calculation.
We had some places where we select IFNULL(stock.total_price, 0) to work
around this, we don't plan to change the existing ones for now, but
while discussing on nexedi/erp5!1974
we concluded that a newly idenfified case of a problem consequence of
these NULL should be handled by fixing the indexation. To benefit from
the fix, impacted instances will have to reindex documents present in
the stock table with stock.total_price is null.
parent 850f446b
Pipeline #36064 failed with stage
in 0 seconds
...@@ -422,7 +422,7 @@ class Movement(XMLObject, Amount, CompositionMixin, AmountGeneratorMixin): ...@@ -422,7 +422,7 @@ class Movement(XMLObject, Amount, CompositionMixin, AmountGeneratorMixin):
quantity = self.getQuantity() quantity = self.getQuantity()
if quantity : if quantity :
source_asset_price = self.getSourceAssetPrice() source_asset_price = self.getSourceAssetPrice()
if source_asset_price : if source_asset_price is not None:
return source_asset_price * - quantity return source_asset_price * - quantity
return None return None
...@@ -466,7 +466,7 @@ class Movement(XMLObject, Amount, CompositionMixin, AmountGeneratorMixin): ...@@ -466,7 +466,7 @@ class Movement(XMLObject, Amount, CompositionMixin, AmountGeneratorMixin):
quantity = self.getQuantity() quantity = self.getQuantity()
if quantity : if quantity :
destination_asset_price = self.getDestinationAssetPrice() destination_asset_price = self.getDestinationAssetPrice()
if destination_asset_price : if destination_asset_price is not None:
return destination_asset_price * quantity return destination_asset_price * quantity
return None return None
...@@ -520,7 +520,7 @@ class Movement(XMLObject, Amount, CompositionMixin, AmountGeneratorMixin): ...@@ -520,7 +520,7 @@ class Movement(XMLObject, Amount, CompositionMixin, AmountGeneratorMixin):
def _getAssetPrice(self,section,date): def _getAssetPrice(self,section,date):
price = self.getPrice() price = self.getPrice()
if section is None or not price or getattr( if section is None or price is None or getattr(
section.aq_base, 'getPriceCurrencyValue', None section.aq_base, 'getPriceCurrencyValue', None
) is None: ) is None:
return price return price
......
...@@ -1708,7 +1708,7 @@ class TestMovementHistoryList(InventoryAPITestCase): ...@@ -1708,7 +1708,7 @@ class TestMovementHistoryList(InventoryAPITestCase):
# default is an empty list # default is an empty list
self.assertEqual(0, len(mvt_history_list)) self.assertEqual(0, len(mvt_history_list))
def testDefault0(self): def testDefaultNone(self):
self._makeMovement() self._makeMovement()
getMovementHistoryList = self.getSimulationTool().getMovementHistoryList getMovementHistoryList = self.getSimulationTool().getMovementHistoryList
mvt_history_list = getMovementHistoryList( mvt_history_list = getMovementHistoryList(
...@@ -1718,6 +1718,32 @@ class TestMovementHistoryList(InventoryAPITestCase): ...@@ -1718,6 +1718,32 @@ class TestMovementHistoryList(InventoryAPITestCase):
# If a movement have no price, None is returned # If a movement have no price, None is returned
self.assertEqual(None, mvt_history_list[0].total_price) self.assertEqual(None, mvt_history_list[0].total_price)
def testPriceZero(self):
self._makeMovement(quantity=1, price=0)
getMovementHistoryList = self.getSimulationTool().getMovementHistoryList
self.assertEqual(
[(b.total_quantity, b.total_price) for b in getMovementHistoryList(section_uid=self.section.getUid())],
[(1, 0), ]
)
self.assertEqual(
[(b.total_quantity, b.total_price) for b in getMovementHistoryList(section_uid=self.mirror_section.getUid())],
[(-1, 0), ]
)
def testPriceNone(self):
self._makeMovement(quantity=1, price=None)
getMovementHistoryList = self.getSimulationTool().getMovementHistoryList
mvt_history_list = getMovementHistoryList(
section_uid=self.section.getUid(),)
self.assertEqual(
[(b.total_quantity, b.total_price) for b in getMovementHistoryList(section_uid=self.section.getUid())],
[(1, None), ]
)
self.assertEqual(
[(b.total_quantity, b.total_price) for b in getMovementHistoryList(section_uid=self.mirror_section.getUid())],
[(-1, None), ]
)
def testMovementBothSides(self): def testMovementBothSides(self):
"""Movement History List returns movement from both sides""" """Movement History List returns movement from both sides"""
getMovementHistoryList = self.getSimulationTool().getMovementHistoryList getMovementHistoryList = self.getSimulationTool().getMovementHistoryList
......
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