diff --git a/product/ERP5/Document/Rule.py b/product/ERP5/Document/Rule.py
index a847b1a95339d0cf492b28aee74e3e92bfc63443..5ef9d776afef2a592b864ea1776d251448fcc0dc 100644
--- a/product/ERP5/Document/Rule.py
+++ b/product/ERP5/Document/Rule.py
@@ -352,7 +352,11 @@ class Rule(Predicate, XMLObject):
       p_matched_list = []
       for movement in non_matched_list:
         for prop in self.getMatchingPropertyList():
-          if prevision.get(prop) != movement.getProperty(prop):
+          if movement.isPropertyRecorded(prop):
+            movement_value = movement.getRecordedProperty(prop)
+          else:
+            movement_value = movement.getProperty(prop)
+          if prevision.get(prop) != movement_value:
             break
         else:
           p_matched_list.append(movement)
@@ -362,7 +366,10 @@ class Rule(Predicate, XMLObject):
         # Check the quantity
         m_quantity = 0.0
         for movement in p_matched_list:
-          m_quantity += movement.getQuantity()
+          if movement.isPropertyRecorded('quantity'):
+            m_quantity += movement.getRecordedProperty('quantity')
+          else:
+            m_quantity += movement.getQuantity()
         if m_quantity != prevision.get('quantity'):
           # special case - quantity
           if movement.isPropertyForced('quantity'):
@@ -391,7 +398,11 @@ class Rule(Predicate, XMLObject):
               + deletable_movement_list):
             prop_dict = modify_dict.setdefault(movement.getId(), {})
             for k, v in prevision.items():
-              if k not in ('quantity',) and v != movement.getProperty(k):
+              if movement.isPropertyRecorded(k):
+                movement_value = movement.getRecordedProperty(k)
+              else:
+                movement_value = movement.getProperty(k)
+              if k not in ('quantity',) and v != movement_value:
                 if movement.isPropertyForced(k):
                   # support compensation if not prevent_compensation
                   LOG('%s:%s' % (self.getRelativeUrl(), movement.getRelativeUrl()), WARNING,
@@ -460,7 +471,11 @@ class Rule(Predicate, XMLObject):
       p_matched_list = []
       for movement in non_matched_list:
         for prop in matching_property_list:
-          if prevision.get(prop) != movement.getProperty(prop):
+          if movement.isPropertyRecorded(prop):
+            movement_value = movement.getRecordedProperty(prop)
+          else:
+            movement_value = movement.getProperty(prop)
+          if prevision.get(prop) != movement_value:
             break
         else:
           p_matched_list.append(movement)
@@ -473,7 +488,10 @@ class Rule(Predicate, XMLObject):
         # Check the quantity
         m_quantity = 0.0
         for movement in p_matched_list:
-          m_quantity += movement.getQuantity()#getCorrectedQuantity()
+          if movement.isPropertyRecorded('quantity'):
+            m_quantity += movement.getRecordedProperty('quantity')
+          else:
+            m_quantity += movement.getQuantity()
         if m_quantity != prevision.get('quantity'):
           q_diff = prevision.get('quantity') - m_quantity
           # try to find a movement that can be edited
@@ -498,14 +516,22 @@ class Rule(Predicate, XMLObject):
             prop_dict = modify_dict.setdefault(movement.getId(), {})
             for prop in ('start_date', 'stop_date'):
               #XXX should be >= 15
-              if prevision.get(prop) != movement.getProperty(prop):
+              if movement.isPropertyRecorded(prop):
+                movement_value = movement.getRecordedProperty(prop)
+              else:
+                movement_value = movement.getProperty(prop)
+              if prevision.get(prop) != movement_value:
                 prop_dict[prop] = prevision.get(prop)
                 break
 
             for k, v in prevision.items():
-              if k not in ('quantity', 'start_date', 'stop_date') and\
-                      v != movement.getProperty(k):
-                prop_dict.setdefault(k, v)
+              if k not in ('quantity', 'start_date', 'stop_date'):
+                if movement.isPropertyRecorded(k):
+                  movement_value = movement.getRecordedProperty(k)
+                else:
+                  movement_value = movement.getProperty(k)
+                if v != movement_value:
+                  prop_dict.setdefault(k, v)
 
         # update movement lists
         for movement in p_matched_list:
diff --git a/product/ERP5/TargetSolver/CopyAndPropagate.py b/product/ERP5/TargetSolver/CopyAndPropagate.py
index 2036316b3286996c5e337073ab991d30186cd2e2..c88dab55f7322df822d1b8786b2f7f715d2bca73 100644
--- a/product/ERP5/TargetSolver/CopyAndPropagate.py
+++ b/product/ERP5/TargetSolver/CopyAndPropagate.py
@@ -51,6 +51,7 @@ class CopyAndPropagate(TargetSolver):
     value_dict = {}
     quantity_ratio = None
     if scope == 'quantity':
+      property_id = 'quantity'
       new_quantity = simulation_movement.getDeliveryQuantity() * \
                      simulation_movement.getDeliveryRatio()
       old_quantity = simulation_movement.getQuantity()
@@ -70,10 +71,14 @@ class CopyAndPropagate(TargetSolver):
       value_dict[property_id] = new_value
     self._solveRecursively(simulation_movement,
                            quantity_ratio=quantity_ratio,
-                           value_dict=value_dict)
+                           value_dict=value_dict,
+                           property_id=property_id)
+    # XXX can we use activity for further expand?
+    simulation_movement.expand()
 
   def _solveRecursively(self, simulation_movement, is_last_movement=1,
-                        quantity_ratio=None, value_dict=None):
+                        quantity_ratio=None, value_dict=None,
+                        property_id=None):
     """
       Update value of the current simulation movement, and update
       his parent movement.
@@ -88,8 +93,6 @@ class CopyAndPropagate(TargetSolver):
       value_dict['delivery_error'] = quantity_error
       value_dict['quantity'] = quantity
 
-    simulation_movement.edit(**value_dict)
-
     applied_rule = simulation_movement.getParentValue()
     parent_movement = applied_rule.getParentValue()
     if parent_movement.getPortalType() == 'Simulation Movement' and \
@@ -97,4 +100,9 @@ class CopyAndPropagate(TargetSolver):
       # backtrack to the parent movement while it is not frozen
       self._solveRecursively(parent_movement, is_last_movement=0,
                              quantity_ratio=quantity_ratio,
-                             value_dict=value_dict)
+                             value_dict=value_dict,
+                             property_id=property_id)
+    else:
+      if not simulation_movement.isPropertyRecorded(property_id):
+        simulation_movement.recordProperty(property_id)
+    simulation_movement.edit(**value_dict)
diff --git a/product/ERP5/TargetSolver/SplitAndDefer.py b/product/ERP5/TargetSolver/SplitAndDefer.py
index ea77e934438b2744f46f478b7aa552f3041732b2..ac4da9e14c1f78be89b07429afb848455636ee5d 100644
--- a/product/ERP5/TargetSolver/SplitAndDefer.py
+++ b/product/ERP5/TargetSolver/SplitAndDefer.py
@@ -75,8 +75,6 @@ class SplitAndDefer(CopyToTarget):
         movement_dict.update(
           portal_type="Simulation Movement",
           id=new_id,
-          start_date=self.start_date,
-          stop_date=self.stop_date,
           quantity=movement_quantity - new_movement_quantity,
           activate_kw=self.activate_kw,
           order=simulation_movement.getOrder(),
@@ -92,6 +90,10 @@ class SplitAndDefer(CopyToTarget):
               # might be wrong
               forced_property_list.append(prop)
         new_movement = applied_rule.newContent(**movement_dict)
+        new_movement.recordProperty('start_date')
+        new_movement.recordProperty('stop_date')
+        new_movement.edit(start_date=self.start_date,
+                          stop_date=self.stop_date)
         new_movement.activate(**self.additional_parameters).expand()
         # XXX: start and stop date have to be forced on movement too
         forced_property_list.extend(['start_date', 'stop_date'])
@@ -106,8 +108,8 @@ class SplitAndDefer(CopyToTarget):
                         portal_type="Simulation Movement",
                         id=new_id,
                         efficiency=simulation_movement.getEfficiency(),
-                        start_date=self.start_date,
-                        stop_date=self.stop_date,
+                        start_date=simulation_movement.getStartDate(),
+                        stop_date=simulation_movement.getStopDate(),
                         order=simulation_movement.getOrder(),
 
                         resource=simulation_movement.getResource(),
@@ -135,11 +137,16 @@ class SplitAndDefer(CopyToTarget):
                         activate_kw=self.activate_kw,
                         **self.additional_parameters
       )
+      new_movement.recordProperty('start_date')
+      new_movement.recordProperty('stop_date')
+      new_movement.edit(start_date=self.start_date,
+                        stop_date=self.stop_date)
       new_movement.activate(**self.additional_parameters).expand()
       # adopt new quantity on original simulation movement
       simulation_movement.edit(quantity=new_movement_quantity)
     simulation_movement.setDefaultActivateParameters(**self.activate_kw)
     simulation_movement.activate(**self.additional_parameters).expand()
+    simulation_movement.aq_parent.expand()
 
     # SplitAndDefer solves the divergence at the current level, no need to
     # backtrack.
diff --git a/product/ERP5/TargetSolver/SplitQuantity.py b/product/ERP5/TargetSolver/SplitQuantity.py
index 9bd9de19170a73b9cd6c65331d6de114b66c92af..08f2a50794779ea166448336935badbd21e35a34 100644
--- a/product/ERP5/TargetSolver/SplitQuantity.py
+++ b/product/ERP5/TargetSolver/SplitQuantity.py
@@ -54,8 +54,8 @@ class SplitQuantity(CopyToTarget):
       portal_type = "Simulation Movement",
       id = new_id,
       efficiency = simulation_movement.getEfficiency(),
-      start_date = self.start_date,
-      stop_date = self.stop_date,
+      start_date=simulation_movement.getStartDate(),
+      stop_date=simulation_movement.getStopDate(),
       # XXX resource
       order = simulation_movement.getOrder(),
       quantity = self.quantity,
@@ -66,6 +66,10 @@ class SplitQuantity(CopyToTarget):
       activate_kw = self.activate_kw,
       **self.additional_parameters
     )
+    new_movement.recordProperty('start_date')
+    new_movement.recordProperty('stop_date')
+    new_movement.edit(start_date=self.start_date,
+                      stop_date=self.stop_date)
     simulation_movement.setDefaultActivateParameters(**self.activate_kw)
     simulation_movement.edit (
       quantity = (simulation_movement.getQuantity() - self.quantity)