Commit 6e758ade authored by Julien Muchembled's avatar Julien Muchembled

Several fixes to solvers

parent 8a551780
...@@ -63,15 +63,14 @@ class AcceptSolver(SolverMixin, ConfigurableMixin, XMLObject): ...@@ -63,15 +63,14 @@ class AcceptSolver(SolverMixin, ConfigurableMixin, XMLObject):
Adopt new property to simulation movements, with keeping the Adopt new property to simulation movements, with keeping the
original one recorded. original one recorded.
""" """
configuration_dict = self.getConfigurationPropertyDict() portal = self.getPortalObject()
solved_property_list = configuration_dict.get('tested_property_list', None) solved_property_list = self.getConfigurationPropertyDict() \
.get('tested_property_list')
if solved_property_list is None: if solved_property_list is None:
portal_type = self.getPortalObject().portal_types.getTypeInfo(self) solved_property_list = \
solved_property_list = portal_type.getTestedPropertyList() portal.portal_types.getTypeInfo(self).getTestedPropertyList()
if 1: with self.defaultActivateParameterDict(activate_kw, True):
for simulation_movement in self.getDeliveryValueList(): for simulation_movement in self.getDeliveryValueList():
if activate_kw is not None:
simulation_movement.setDefaultActivateParameterDict(activate_kw)
movement = simulation_movement.getDeliveryValue() movement = simulation_movement.getDeliveryValue()
value_dict = {} value_dict = {}
base_category_set = set(movement.getBaseCategoryList()) base_category_set = set(movement.getBaseCategoryList())
...@@ -89,16 +88,13 @@ class AcceptSolver(SolverMixin, ConfigurableMixin, XMLObject): ...@@ -89,16 +88,13 @@ class AcceptSolver(SolverMixin, ConfigurableMixin, XMLObject):
new_value = movement.getProperty(solved_property) new_value = movement.getProperty(solved_property)
# XXX hard coded # XXX hard coded
if solved_property == 'quantity': if solved_property == 'quantity':
new_quantity = new_value * simulation_movement.getDeliveryRatio() new_value *= simulation_movement.getDeliveryRatio()
value_dict.update({'quantity':new_quantity}) value_dict[solved_property] = new_value
else:
value_dict.update({solved_property:new_value})
for property_id, value in value_dict.iteritems(): for property_id, value in value_dict.iteritems():
if not simulation_movement.isPropertyRecorded(property_id): if not simulation_movement.isPropertyRecorded(property_id):
simulation_movement.recordProperty(property_id) simulation_movement.recordProperty(property_id)
simulation_movement.setMappedProperty(property_id, value) simulation_movement.setMappedProperty(property_id, value)
simulation_movement.expand(activate_kw=activate_kw) simulation_movement.expand(activate_kw=activate_kw)
# Finish solving # Finish solving
if self.getPortalObject().portal_workflow.isTransitionPossible( if portal.portal_workflow.isTransitionPossible(self, 'succeed'):
self, 'succeed'):
self.succeed() self.succeed()
...@@ -93,11 +93,10 @@ class QuantitySplitSolver(SolverMixin, ConfigurableMixin, XMLObject): ...@@ -93,11 +93,10 @@ class QuantitySplitSolver(SolverMixin, ConfigurableMixin, XMLObject):
new_id = "%s_split_%s" % (simulation_movement.getId(), split_index) new_id = "%s_split_%s" % (simulation_movement.getId(), split_index)
# Copy at same level # Copy at same level
kw = _getPropertyAndCategoryList(simulation_movement) kw = _getPropertyAndCategoryList(simulation_movement)
kw.update({'portal_type':simulation_movement.getPortalType(), kw.update(delivery=None, quantity=split_quantity)
'id':new_id, new_movement = applied_rule.newContent(
'delivery':None, new_id, simulation_movement.getPortalType(),
'quantity':split_quantity}) activate_kw=activate_kw, **kw)
new_movement = applied_rule.newContent(activate_kw=activate_kw, **kw)
# Dirty code until IPropertyRecordable is revised. # Dirty code until IPropertyRecordable is revised.
# Merge original simulation movement recorded property to new one. # Merge original simulation movement recorded property to new one.
recorded_property_dict = simulation_movement._getRecordedPropertyDict(None) recorded_property_dict = simulation_movement._getRecordedPropertyDict(None)
...@@ -106,8 +105,6 @@ class QuantitySplitSolver(SolverMixin, ConfigurableMixin, XMLObject): ...@@ -106,8 +105,6 @@ class QuantitySplitSolver(SolverMixin, ConfigurableMixin, XMLObject):
if new_movement_recorded_property_dict is None: if new_movement_recorded_property_dict is None:
new_movement_recorded_property_dict = new_movement._recorded_property_dict = PersistentMapping() new_movement_recorded_property_dict = new_movement._recorded_property_dict = PersistentMapping()
new_movement_recorded_property_dict.update(recorded_property_dict) new_movement_recorded_property_dict.update(recorded_property_dict)
if activate_kw is not None:
new_movement.setDefaultActivateParameterDict(activate_kw)
# record zero quantity property, because this was originally zero. # record zero quantity property, because this was originally zero.
# without this, splitanddefer after accept decision does not work # without this, splitanddefer after accept decision does not work
# properly. # properly.
...@@ -123,6 +120,8 @@ class QuantitySplitSolver(SolverMixin, ConfigurableMixin, XMLObject): ...@@ -123,6 +120,8 @@ class QuantitySplitSolver(SolverMixin, ConfigurableMixin, XMLObject):
if stop_date is not None: if stop_date is not None:
new_movement.recordProperty('stop_date') new_movement.recordProperty('stop_date')
new_movement.setStopDate(stop_date) new_movement.setStopDate(stop_date)
if activate_kw:
new_movement.setDefaultActivateParameterDict({})
# XXX we need to call expand on both simulation_movement and new_movement here? # XXX we need to call expand on both simulation_movement and new_movement here?
# simulation_movement.expand(activate_kw=activate_kw) # simulation_movement.expand(activate_kw=activate_kw)
# new_movement.expand(activate_kw=activate_kw) # new_movement.expand(activate_kw=activate_kw)
......
...@@ -63,52 +63,44 @@ class TradeModelSolver(AcceptSolver): ...@@ -63,52 +63,44 @@ class TradeModelSolver(AcceptSolver):
Adopt new values to simulation movements, with keeping the original Adopt new values to simulation movements, with keeping the original
one recorded, and then update Trade Model related lines accordingly. one recorded, and then update Trade Model related lines accordingly.
""" """
configuration_dict = self.getConfigurationPropertyDict() portal = self.getPortalObject()
portal_type = self.getPortalObject().portal_types.getTypeInfo(self) solved_property_list = self.getConfigurationPropertyDict() \
solved_property_list = configuration_dict.get('tested_property_list', .get('tested_property_list')
portal_type.getTestedPropertyList()) if solved_property_list is None:
delivery_dict = {} solved_property_list = \
portal.portal_types.getTypeInfo(self).getTestedPropertyList()
delivery_dict = {} # {movement: simulation_movement_list}
for simulation_movement in self.getDeliveryValueList(): for simulation_movement in self.getDeliveryValueList():
delivery_dict.setdefault(simulation_movement.getDeliveryValue(), delivery_dict.setdefault(simulation_movement.getDeliveryValue(),
[]).append(simulation_movement) []).append(simulation_movement)
# Here, items of delivery_list should be movements, not deliveries.
delivery_set = set()
solved_movement_list = delivery_dict.iterkeys()
for movement in solved_movement_list:
delivery = movement.getRootDeliveryValue()
delivery_set.add(delivery)
all_movement_list = sum([x.getMovementList() for x in delivery_set], [])
# First, separate movements into invoice lines and trade model # First, separate movements into invoice lines and trade model
# related lines. # related lines.
# XXX is there any better way than using rule's reference? # XXX is there any better way than using rule's reference?
trade_model_related_movement_list = [] trade_model_related_movement_dict = {}
for movement in all_movement_list: for delivery in set(movement.getRootDeliveryValue()
if movement in solved_movement_list: for movement in delivery_dict):
continue for movement in delivery.getMovementList():
applied_rule = movement.getDeliveryRelatedValue().getParentValue() simulation_movement_list = delivery_dict.get(movement) or \
# hard coded reference name movement.getDeliveryRelatedValueList()
if applied_rule.getSpecialiseReference() == 'default_trade_model_rule': applied_rule = simulation_movement_list[0].getParentValue()
trade_model_related_movement_list.append(movement) # hard coded reference name
if applied_rule.getSpecialiseReference() == 'default_trade_model_rule':
trade_model_related_movement_dict[movement] = simulation_movement_list
if 1: with self.defaultActivateParameterDict(activate_kw, True):
# Second, apply changes on invoice lines to simulation movements, # Second, apply changes on invoice lines to simulation movements,
# then expand. # then expand.
for movement, simulation_movement_list in delivery_dict.iteritems(): for movement, simulation_movement_list in delivery_dict.iteritems():
if movement in trade_model_related_movement_list: if movement in trade_model_related_movement_dict:
continue continue
for simulation_movement in simulation_movement_list: for simulation_movement in simulation_movement_list:
if activate_kw is not None:
simulation_movement.setDefaultActivateParameterDict(activate_kw)
value_dict = {} value_dict = {}
for solved_property in solved_property_list: for solved_property in solved_property_list:
new_value = movement.getProperty(solved_property) new_value = movement.getProperty(solved_property)
if solved_property == 'quantity': if solved_property == 'quantity':
new_quantity = new_value * simulation_movement.getDeliveryRatio() new_value *= simulation_movement.getDeliveryRatio()
value_dict.update({'quantity':new_quantity}) value_dict[solved_property] = new_value
else:
value_dict.update({solved_property:new_value})
for property_id, value in value_dict.iteritems(): for property_id, value in value_dict.iteritems():
if not simulation_movement.isPropertyRecorded(property_id): if not simulation_movement.isPropertyRecorded(property_id):
simulation_movement.recordProperty(property_id) simulation_movement.recordProperty(property_id)
...@@ -117,33 +109,28 @@ class TradeModelSolver(AcceptSolver): ...@@ -117,33 +109,28 @@ class TradeModelSolver(AcceptSolver):
# Third, adopt changes on trade model related lines. # Third, adopt changes on trade model related lines.
# XXX non-linear case is not yet supported. # XXX non-linear case is not yet supported.
for movement in trade_model_related_movement_list: for movement, simulation_movement_list in \
if activate_kw is not None: trade_model_related_movement_dict.iteritems():
movement.setDefaultActivateParameterDict(activate_kw)
for solved_property in solved_property_list: for solved_property in solved_property_list:
if solved_property == 'quantity': if solved_property == 'quantity':
simulation_movement_list = movement.getDeliveryRelatedValueList() total_quantity = sum(x.getQuantity()
total_quantity = sum( for x in simulation_movement_list)
[x.getQuantity() for x in simulation_movement_list])
movement.setQuantity(total_quantity) movement.setQuantity(total_quantity)
for simulation_movement in simulation_movement_list: for simulation_movement in simulation_movement_list:
quantity = simulation_movement.getQuantity() quantity = simulation_movement.getQuantity()
if total_quantity != 0.0: if total_quantity:
delivery_ratio = quantity / total_quantity delivery_ratio = quantity / total_quantity
else: else:
delivery_ratio = 1.0 / len(simulation_movement_list) delivery_ratio = 1.0 / len(simulation_movement_list)
delivery_error = total_quantity * delivery_ratio - quantity delivery_error = total_quantity * delivery_ratio - quantity
simulation_movement.edit(delivery_ratio=delivery_ratio, simulation_movement.edit(delivery_ratio=delivery_ratio,
delivery_error=delivery_error, delivery_error=delivery_error)
activate_kw=activate_kw)
else: else:
# XXX TODO we need to support multiple values for categories or # XXX TODO we need to support multiple values for categories or
# list type property. # list type property.
simulation_movement = movement.getDeliveryRelatedValue()
movement.setProperty(solved_property, movement.setProperty(solved_property,
simulation_movement.getProperty(solved_property)) simulation_movement_list[0].getProperty(solved_property))
# Finish solving # Finish solving
if self.getPortalObject().portal_workflow.isTransitionPossible( if portal.portal_workflow.isTransitionPossible(self, 'succeed'):
self, 'succeed'):
self.succeed() self.succeed()
...@@ -95,10 +95,12 @@ class UnifySolver(AcceptSolver): ...@@ -95,10 +95,12 @@ class UnifySolver(AcceptSolver):
Adopt new property value to simulation movements and their deliveries, Adopt new property value to simulation movements and their deliveries,
while keeping the original one recorded. while keeping the original one recorded.
""" """
portal = self.getPortalObject()
configuration_dict = self.getConfigurationPropertyDict() configuration_dict = self.getConfigurationPropertyDict()
portal_type = self.getPortalObject().portal_types.getTypeInfo(self) solved_property_list = configuration_dict.get('tested_property_list')
solved_property_list = configuration_dict.get('tested_property_list', if solved_property_list is None:
portal_type.getTestedPropertyList()) solved_property_list = \
portal.portal_types.getTypeInfo(self).getTestedPropertyList()
# XXX it does not support multiple tested properties. # XXX it does not support multiple tested properties.
solved_property = solved_property_list[0] solved_property = solved_property_list[0]
delivery_dict = {} delivery_dict = {}
...@@ -115,18 +117,15 @@ class UnifySolver(AcceptSolver): ...@@ -115,18 +117,15 @@ class UnifySolver(AcceptSolver):
)) ))
if activate_kw is not None: if activate_kw is not None:
movement.setDefaultActivateParameterDict(activate_kw) movement.setDefaultActivateParameterDict(activate_kw)
new_value = configuration_dict.get('value') value = configuration_dict.get('value')
movement.setProperty(solved_property, new_value) movement.setProperty(solved_property, value)
for simulation_movement in simulation_movement_set: for simulation_movement in simulation_movement_set:
if activate_kw is not None: if activate_kw is not None:
simulation_movement.setDefaultActivateParameterDict(activate_kw) simulation_movement.setDefaultActivateParameterDict(activate_kw)
value_dict = {solved_property:new_value} if not simulation_movement.isPropertyRecorded(solved_property):
for property_id, value in value_dict.iteritems(): simulation_movement.recordProperty(solved_property)
if not simulation_movement.isPropertyRecorded(property_id): simulation_movement.setMappedProperty(solved_property, value)
simulation_movement.recordProperty(property_id)
simulation_movement.setMappedProperty(property_id, value)
simulation_movement.expand(activate_kw=activate_kw) simulation_movement.expand(activate_kw=activate_kw)
# Finish solving # Finish solving
if self.getPortalObject().portal_workflow.isTransitionPossible( if portal.portal_workflow.isTransitionPossible(self, 'succeed'):
self, 'succeed'):
self.succeed() self.succeed()
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