From 0f33633e00aebd5a9f16337fa2964d098475e0c9 Mon Sep 17 00:00:00 2001
From: Nicolas Dumazet <nicolas.dumazet@nexedi.com>
Date: Tue, 2 Feb 2010 10:18:37 +0000
Subject: [PATCH] Quantity Unit Definitions: Performance &
 backward-compatibility (2/2)

* Add a (failing) test where the old system is used for quantities
* Use a cached Python Script to keep the universal quantity definitions:
  * erp5_content_long
  * delete the cache when a global quantity definition is changed via an
    interaction workflow on Definitions
  * Use the catalog to retrieve the global definitions
  * If no Quantity Definitions are defined _at all_, then it falls
    back and uses the properties on categories



git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@32167 20353a03-c40f-0410-a6d1-a30d3c3de9de
---
 product/ERP5/Document/Resource.py      | 26 +----------
 product/ERP5/tests/testInventoryAPI.py | 61 ++++++++++++++++++++++++++
 2 files changed, 63 insertions(+), 24 deletions(-)

diff --git a/product/ERP5/Document/Resource.py b/product/ERP5/Document/Resource.py
index fafb43a069..9394604e0e 100644
--- a/product/ERP5/Document/Resource.py
+++ b/product/ERP5/Document/Resource.py
@@ -852,29 +852,6 @@ class Resource(XMLMatrix, Variated):
         if len(result) == 1:
           return result[0]
 
-    def _getGlobalQuantityUnitDefinitionDict(self):
-      # XXX this info could be cached, as it is the same for all Resources
-      result = {}
-      module = self.getPortalObject().quantity_unit_conversion_module
-      for definition_list in module.objectValues(portal_type= \
-          'Quantity Unit Conversion Group'):
-        standard_quantity_unit_uid = definition_list.getQuantityUnitUid()
-        if standard_quantity_unit_uid is None:
-          continue
-
-        result[standard_quantity_unit_uid] = (None, 1.0)
-        for definition in definition_list.objectValues(portal_type= \
-            'Quantity Unit Conversion Definition'):
-          unit_uid = definition.getQuantityUnitUid()
-          if unit_uid is None:
-            continue
-          quantity = definition.getQuantity()
-          if not quantity:
-            continue
-          result[unit_uid] = (definition.getUid(), quantity)
-
-      return result
-
     def _getQuantityUnitDefinitionDict(self):
       """
       Returns a dictionary representing the Unit Definitions that hold
@@ -889,7 +866,8 @@ class Resource(XMLMatrix, Variated):
             For example, if mass/g is the global standard quantity_unit, all
             definitions for mass/* will be expressed in grams.
       """
-      global_definition_dict = self._getGlobalQuantityUnitDefinitionDict()
+      global_definition_dict = self.\
+          QuantityUnitConversionModule_getUniversalDefinitionDict()
 
       result = global_definition_dict.copy()
       for definition_list in self.objectValues(portal_type= \
diff --git a/product/ERP5/tests/testInventoryAPI.py b/product/ERP5/tests/testInventoryAPI.py
index 0b0f9d482a..b66e1d3d42 100644
--- a/product/ERP5/tests/testInventoryAPI.py
+++ b/product/ERP5/tests/testInventoryAPI.py
@@ -2409,6 +2409,7 @@ class BaseTestUnitConversion(InventoryAPITestCase):
     InventoryAPITestCase.afterSetUp(self)
 
     self.setUpUnitDefinition()
+    self._safeTic()
 
   def makeMovement(self, quantity, resource, *variation, **kw):
     m = self._makeMovement(quantity=quantity, resource_value=resource,
@@ -2671,6 +2672,65 @@ class TestUnitConversionDefinition(BaseTestUnitConversion):
                       self.resource_bylot_overriding\
                           .convertQuantity(1, "unit/lot", "unit/unit"))
 
+class TestUnitConversionBackwardCompatibility(BaseTestUnitConversion):
+  QUANTITY_UNIT_DICT = {
+    # base: (reference, dict_of_others)
+    'mass':   ('kilogram', dict(gram=0.001)),
+  }
+  METRIC_TYPE_CATEGORY_LIST = (
+    'mass/net',
+  )
+  def setUpUnitDefinition(self):
+    # bypass Unit Definition setup
+    mass_category = self.portal.portal_categories.quantity_unit.mass
+    mass_category.gram.setProperty('quantity', 0.001)
+    mass_category.kilogram.setProperty('quantity', 1)
+
+    pass
+
+  def testBackwardCompatibility(self):
+    delivery_rule = self.getRuleTool().default_delivery_rule
+    delivery_rule.validate()
+
+    resource = self.portal.product_module.newContent(
+                      portal_type='Product',
+                      quantity_unit_list=('mass/gram',
+                                          'mass/kilogram'),)
+    node = self.portal.organisation_module.newContent(
+                      portal_type='Organisation')
+    delivery = self.portal.purchase_packing_list_module.newContent(
+                      portal_type='Purchase Packing List',
+                      start_date='2010-01-26',
+                      price_currency='currency_module/EUR',
+                      destination_value=node,
+                      destination_section_value=node)
+    delivery.newContent(portal_type='Purchase Packing List Line',
+                        resource_value=resource,
+                        quantity=10,
+                        quantity_unit='mass/gram')
+    delivery.newContent(portal_type='Purchase Packing List Line',
+                        resource_value=resource,
+                        quantity=3,
+                        quantity_unit='mass/kilogram')
+    delivery.confirm()
+    delivery.start()
+    delivery.stop()
+    transaction.commit()
+    self.tic()
+
+    # inventories of that resource are indexed in grams
+    self.assertEquals(3010,
+        self.portal.portal_simulation.getCurrentInventory(
+          resource_uid=resource.getUid(),
+          node_uid=node.getUid()))
+
+    # converted inventory also works
+    self.assertEquals(3.01,
+        self.portal.portal_simulation.getCurrentInventory(
+          quantity_unit='mass/kilogram',
+          resource_uid=resource.getUid(),
+          node_uid=node.getUid()))
+
 def test_suite():
   suite = unittest.TestSuite()
   suite.addTest(unittest.makeSuite(TestInventory))
@@ -2682,6 +2742,7 @@ def test_suite():
   suite.addTest(unittest.makeSuite(TestInventoryDocument))
   suite.addTest(unittest.makeSuite(TestUnitConversion))
   suite.addTest(unittest.makeSuite(TestUnitConversionDefinition))
+  suite.addTest(unittest.makeSuite(TestUnitConversionBackwardCompatibility))
   return suite
 
 # vim: foldmethod=marker
-- 
2.30.9