From 1f6bf21445aeb40e63bc35965eb50d74bb3fe18d Mon Sep 17 00:00:00 2001 From: Julien Muchembled <jm@nexedi.com> Date: Thu, 30 Dec 2010 19:31:15 +0000 Subject: [PATCH] MovementGroup.getAveragePrice: avoid useless calculations when all prices are equal What could happen otherwise: >>> a = 0.4 * 6 * 5; a 12.000000000000002 >>> b = 1.6 * 3; b 4.8000000000000007 >>> c = 0.05; c 0.050000000000000003 >>> (a * c + b * c) / (a + b) 0.049999999999999989 git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@41891 20353a03-c40f-0410-a6d1-a30d3c3de9de --- product/ERP5/MovementGroup.py | 44 +++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/product/ERP5/MovementGroup.py b/product/ERP5/MovementGroup.py index 33c52423af..ec535a29c2 100644 --- a/product/ERP5/MovementGroup.py +++ b/product/ERP5/MovementGroup.py @@ -401,10 +401,11 @@ class FakeMovement: """ Return average price """ - total_quantity = self.getAddQuantity() - if total_quantity != 0: - return (self.getAddPrice() / total_quantity) - return 0.0 + price_dict = self._getPriceDict() + if len(price_dict) == 1: + return price_dict.keys()[0] + return sum(price * quantity for price, quantity in price_dict.items()) / \ + float(sum(price_dict.values())) def getAddQuantity(self): """ @@ -412,28 +413,35 @@ class FakeMovement: """ total_quantity = 0 for movement in self.getMovementList(): - if getattr(movement, 'getMappedProperty', None) is not None: - quantity = movement.getMappedProperty('quantity') - else: + getMappedProperty = getattr(movement, 'getMappedProperty', None) + if getMappedProperty is None: quantity = movement.getQuantity() - if quantity != None: + else: + quantity = getMappedProperty('quantity') + if quantity: total_quantity += quantity return total_quantity + def _getPriceDict(self): + price_dict = {} + for movement in self.getMovementList(): + getMappedProperty = getattr(movement, 'getMappedProperty', None) + if getMappedProperty is None: + quantity = movement.getQuantity() + else: + quantity = getMappedProperty('quantity') + if quantity: + price = movement.getPrice() or 0 + quantity += price_dict.setdefault(price, 0) + price_dict[price] = quantity + return price_dict + def getAddPrice(self): """ Return total price """ - total_price = 0 - for movement in self.getMovementList(): - if getattr(movement, 'getMappedProperty', None) is not None: - quantity = movement.getMappedProperty('quantity') - else: - quantity = movement.getQuantity() - price = movement.getPrice() - if (quantity is not None) and (price is not None): - total_price += (quantity * price) - return total_price + price_dict = self._getPriceDict() + return sum(price * quantity for price, quantity in price_dict.items()) def recursiveReindexObject(self): """ -- 2.30.9