[Erp5-report] r27347 - in /erp5/trunk/products/ERP5: Document/ tests/

nobody at svn.erp5.org nobody at svn.erp5.org
Wed Jun 3 12:51:19 CEST 2009


Author: yusuke
Date: Wed Jun  3 12:51:13 2009
New Revision: 27347

URL: http://svn.erp5.org?rev=27347&view=rev
Log:
support feature to make different movement when expanding but the movement
already exists and frozen.

Modified:
    erp5/trunk/products/ERP5/Document/TransformationRule.py
    erp5/trunk/products/ERP5/tests/testMRP.py

Modified: erp5/trunk/products/ERP5/Document/TransformationRule.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/Document/TransformationRule.py?rev=27347&r1=27346&r2=27347&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/Document/TransformationRule.py [utf8] (original)
+++ erp5/trunk/products/ERP5/Document/TransformationRule.py [utf8] Wed Jun  3 12:51:13 2009
@@ -39,11 +39,6 @@
 from Products.ERP5Type.Errors import TransformationRuleError
 
 class TransformationMovementFactory:
-
-  referable_product_attr_name_list = ['resource',
-                                      'quantity', 'quantity_unit',
-                                      'variation_category_list',
-                                      'variation_property_dict']
   def __init__(self):
     self.product = None # base information to use for making movements
     self.produced_list = list()
@@ -55,19 +50,71 @@
   def requestConsumed(self, **consumed):
     self.consumed_list.append(consumed)
 
+  def _getCausalityList(self, causality=None, causality_value=None,
+                        causality_list=None, causality_value_list=None,
+                        **kw):
+    if causality is not None:
+      return [causality]
+    elif causality_value is not None:
+      return [causality_value.getRelativeUrl()]
+    elif causality_list is not None:
+      return causality_list
+    elif causality_value_list is not None:
+      return [causality_value.getRelativeUrl()
+              for causality_value in causality_value_list]
+
   def makeMovements(self, applied_rule):
     """
     make movements under the applied_rule by requests
     """
-    request_list = ((self.produced_list, -1),
-                    ( self.consumed_list, 1))
-    for (request_list, rate) in request_list:
+    movement_dict = {}
+    for movement in applied_rule.objectValues(
+        portal_type="Simulation Movement"):
+      key = tuple(sorted(movement.getCausalityList()))
+      movement_dict[key] = movement
+
+    """
+    produced quantity should be represented by minus quantity on movement.
+    because plus quantity is consumed.
+    """ 
+    for (request_list, sign) in ((self.produced_list, -1),
+                                 (self.consumed_list, 1)):
       for request in request_list:
         d = self.product.copy()
         d.update(request)
-        d['quantity'] *= rate
-        movement = applied_rule.newContent(portal_type="Simulation Movement")
-        movement.edit(**d)
+        d['quantity'] *= sign
+
+        # get movement by causality
+        key = tuple(sorted(self._getCausalityList(**request)))
+        movement = movement_dict.get(key, None)
+        # when no exist
+        if movement is None:
+          movement = applied_rule.newContent(portal_type="Simulation Movement")
+        # update
+        if movement.isFrozen():
+          self.makeDifferentMovement(movement, **d)
+        else:
+          movement.edit(**d)
+
+  def _requestNetQuantity(self, request):
+    quantity = request.get('quantity', None)
+    efficiency = request.get('efficiency', None)
+    if efficiency in (0, 0.0, None, ''):
+      efficiency = 1.0
+    return float(quantity) / efficiency
+
+  def makeDifferentMovement(self, movement, **request):
+    """
+    make different movement, which is based on original movement.
+    this implementation just focus about quantity.
+    """
+    applied_rule = movement.getParentValue()
+    request['quantity'] = self._requestNetQuantity(request)\
+                          - movement.getNetQuantity()
+    if request['quantity'] != 0:
+      diff_movement = applied_rule.newContent(portal_type="Simulation Movement")
+      diff_movement.edit(**request)
+
 
 class TransformationRuleMixin(Base):
   security = ClassSecurityInfo()

Modified: erp5/trunk/products/ERP5/tests/testMRP.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/tests/testMRP.py?rev=27347&r1=27346&r2=27347&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/tests/testMRP.py [utf8] (original)
+++ erp5/trunk/products/ERP5/tests/testMRP.py [utf8] Wed Jun  3 12:51:13 2009
@@ -278,6 +278,44 @@
                                   movement.getQuantity())])
     self.assertEquals(expected_value_set, movement_value_set)
 
+    """
+    test case of difference when any movement are frozen
+    by using above result
+    """
+    # update relation
+    self.stepTic()
+
+    for movement in movement_list:
+      movement.edit(quantity=1)
+      # XXX change state isFrozen of movement to 1,
+      #     but I think this way might be wrong.
+      movement._baseSetFrozen(1)
+
+    # re-expand
+    rule.expand(applied_rule)
+
+    # assertion
+    expected_value_set = set([
+      (('business_process_module/2/p2',), 'product_module/2', 'mrp/p2', 1), # Frozen
+      (('business_process_module/2/p2',), 'product_module/2', 'mrp/p2', 29),
+      (('business_process_module/2/p2',), 'product_module/3', 'mrp/p2', 1), # Frozen
+      (('business_process_module/2/p2',), 'product_module/3', 'mrp/p2', 9),
+      (('business_process_module/2/p3',), 'product_module/4', 'mrp/p3', 1), # Frozen
+      (('business_process_module/2/p3',), 'product_module/4', 'mrp/p3', 39),
+      (('business_process_module/2/p3',), 'product_module/5', 'mrp/p3', 1), # Frozen
+      (('business_process_module/2/p3',), 'product_module/5', 'mrp/p3', 9),
+      (('business_process_module/2/p2', 'business_process_module/2/p3'), 'product_module/1', None, 1), # Frozen
+      (('business_process_module/2/p2', 'business_process_module/2/p3'), 'product_module/1', None, -11)])
+    movement_list = applied_rule.objectValues()
+    self.assertEquals(len(expected_value_set), len(movement_list))
+    movement_value_set = set([])
+    for movement in movement_list:
+      movement_value_set |= set([(tuple(movement.getCausalityList()),
+                                  movement.getResource(),
+                                  movement.getTradePhase(),
+                                  movement.getQuantity())])
+    self.assertEquals(expected_value_set, movement_value_set)
+
 def test_suite():
   suite = unittest.TestSuite()
   suite.addTest(unittest.makeSuite(TestMRPImplementation))




More information about the Erp5-report mailing list