Commit 58bf5663 authored by Julien Muchembled's avatar Julien Muchembled

Equivalence testers: refactoring

git-svn-id: https://svn.erp5.org/repos/public/erp5/sandbox/amount_generator@39543 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 78f5044a
...@@ -26,11 +26,9 @@ ...@@ -26,11 +26,9 @@
# #
############################################################################## ##############################################################################
import zope.interface
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Products.ERP5.Document.Predicate import Predicate from Products.ERP5.Document.Predicate import Predicate
from Products.ERP5Type import Permissions, PropertySheet, interfaces from Products.ERP5Type import Permissions, PropertySheet
from Products.ERP5.mixin.equivalence_tester import EquivalenceTesterMixin from Products.ERP5.mixin.equivalence_tester import EquivalenceTesterMixin
class CategoryMembershipEquivalenceTester(Predicate, EquivalenceTesterMixin): class CategoryMembershipEquivalenceTester(Predicate, EquivalenceTesterMixin):
...@@ -56,8 +54,9 @@ class CategoryMembershipEquivalenceTester(Predicate, EquivalenceTesterMixin): ...@@ -56,8 +54,9 @@ class CategoryMembershipEquivalenceTester(Predicate, EquivalenceTesterMixin):
, PropertySheet.SolverSelection , PropertySheet.SolverSelection
) )
# Declarative interfaces @staticmethod
zope.interface.implements( interfaces.IEquivalenceTester, ) def _getTestedPropertyValue(movement, property):
return movement.getPropertyList(property)
def _compare(self, prevision_movement, decision_movement): def _compare(self, prevision_movement, decision_movement):
""" """
...@@ -69,8 +68,10 @@ class CategoryMembershipEquivalenceTester(Predicate, EquivalenceTesterMixin): ...@@ -69,8 +68,10 @@ class CategoryMembershipEquivalenceTester(Predicate, EquivalenceTesterMixin):
lambda x:False)(tested_property): lambda x:False)(tested_property):
decision_value = decision_movement.getRecordedProperty(tested_property) decision_value = decision_movement.getRecordedProperty(tested_property)
else: else:
decision_value = decision_movement.getPropertyList(tested_property) decision_value = self._getTestedPropertyValue(decision_movement,
prevision_value = prevision_movement.getPropertyList(tested_property) tested_property)
prevision_value = self._getTestedPropertyValue(prevision_movement,
tested_property)
# XXX do we have configurable parameter for this divergence tester ? # XXX do we have configurable parameter for this divergence tester ?
# like ambiguity... # like ambiguity...
...@@ -80,34 +81,3 @@ class CategoryMembershipEquivalenceTester(Predicate, EquivalenceTesterMixin): ...@@ -80,34 +81,3 @@ class CategoryMembershipEquivalenceTester(Predicate, EquivalenceTesterMixin):
'The values of ${property_name} category are different between decision and prevision.', 'The values of ${property_name} category are different between decision and prevision.',
dict(property_name=tested_property)) dict(property_name=tested_property))
return None return None
def generateHashKey(self, movement):
"""
Returns a hash key which can be used to optimise the
matching algorithm between movements. The purpose
of this hash key is to reduce the size of lists of
movements which need to be compared using the compare
method (quadratic complexity).
If decision_movement is a simulation movement, use
the recorded properties instead of the native ones.
"""
tested_property = self.getTestedProperty()
if movement.isPropertyRecorded(tested_property):
value = movement.getRecordedProperty(tested_property)
else:
value = movement.getPropertyList(tested_property)
return '%s/%r' % (tested_property, value)
def getUpdatablePropertyDict(self, prevision_movement, decision_movement):
"""
Returns a list of properties to update on decision_movement
prevision_movement so that next call to compare returns True.
prevision_movement -- a simulation movement (prevision)
decision_movement -- a delivery movement (decision)
"""
tested_property = self.getTestedProperty()
prevision_value = prevision_movement.getPropertyList(tested_property)
return {tested_property:prevision_value}
...@@ -26,12 +26,10 @@ ...@@ -26,12 +26,10 @@
# #
############################################################################## ##############################################################################
import zope.interface
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from DateTime import DateTime from DateTime import DateTime
from Products.ERP5.Document.Predicate import Predicate from Products.ERP5.Document.Predicate import Predicate
from Products.ERP5Type import Permissions, PropertySheet, interfaces from Products.ERP5Type import Permissions, PropertySheet
from Products.ERP5.mixin.equivalence_tester import EquivalenceTesterMixin from Products.ERP5.mixin.equivalence_tester import EquivalenceTesterMixin
class DateTimeEquivalenceTester(Predicate, EquivalenceTesterMixin): class DateTimeEquivalenceTester(Predicate, EquivalenceTesterMixin):
...@@ -58,9 +56,6 @@ class DateTimeEquivalenceTester(Predicate, EquivalenceTesterMixin): ...@@ -58,9 +56,6 @@ class DateTimeEquivalenceTester(Predicate, EquivalenceTesterMixin):
PropertySheet.SolverSelection PropertySheet.SolverSelection
) )
# Declarative interfaces
zope.interface.implements(interfaces.IEquivalenceTester,)
def _compare(self, prevision_movement, decision_movement): def _compare(self, prevision_movement, decision_movement):
""" """
If prevision_movement and decision_movement don't match, it returns a If prevision_movement and decision_movement don't match, it returns a
...@@ -71,8 +66,10 @@ class DateTimeEquivalenceTester(Predicate, EquivalenceTesterMixin): ...@@ -71,8 +66,10 @@ class DateTimeEquivalenceTester(Predicate, EquivalenceTesterMixin):
lambda x:False)(tested_property): lambda x:False)(tested_property):
decision_value = decision_movement.getRecordedProperty(tested_property) decision_value = decision_movement.getRecordedProperty(tested_property)
else: else:
decision_value = decision_movement.getProperty(tested_property) or DateTime(0) decision_value = self._getTestedPropertyValue(
prevision_value = prevision_movement.getProperty(tested_property) or DateTime(0) decision_movement, tested_property) or DateTime(0)
prevision_value = self._getTestedPropertyValue(
prevision_movement, tested_property) or DateTime(0)
delta = decision_value - prevision_value delta = decision_value - prevision_value
# XXX we should use appropriate property sheets and getter methods # XXX we should use appropriate property sheets and getter methods
...@@ -95,16 +92,3 @@ class DateTimeEquivalenceTester(Predicate, EquivalenceTesterMixin): ...@@ -95,16 +92,3 @@ class DateTimeEquivalenceTester(Predicate, EquivalenceTesterMixin):
'The difference of ${property_name} between decision and prevision is larger than ${value}.', 'The difference of ${property_name} between decision and prevision is larger than ${value}.',
dict(property_name=tested_property, dict(property_name=tested_property,
value=absolute_tolerance_max)) value=absolute_tolerance_max))
def getUpdatablePropertyDict(self, prevision_movement, decision_movement):
"""
Returns a list of properties to update on decision_movement
prevision_movement so that next call to compare returns True.
prevision_movement -- a simulation movement (prevision)
decision_movement -- a delivery movement (decision)
"""
tested_property = self.getTestedProperty()
prevision_value = prevision_movement.getProperty(tested_property)
return {tested_property:prevision_value}
...@@ -28,11 +28,9 @@ ...@@ -28,11 +28,9 @@
# #
############################################################################## ##############################################################################
import zope.interface
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Products.ERP5.Document.Predicate import Predicate from Products.ERP5.Document.Predicate import Predicate
from Products.ERP5Type import Permissions, PropertySheet, interfaces from Products.ERP5Type import Permissions, PropertySheet
from Products.ERP5.mixin.equivalence_tester import EquivalenceTesterMixin from Products.ERP5.mixin.equivalence_tester import EquivalenceTesterMixin
class FloatEquivalenceTester(Predicate, EquivalenceTesterMixin): class FloatEquivalenceTester(Predicate, EquivalenceTesterMixin):
...@@ -56,9 +54,6 @@ class FloatEquivalenceTester(Predicate, EquivalenceTesterMixin): ...@@ -56,9 +54,6 @@ class FloatEquivalenceTester(Predicate, EquivalenceTesterMixin):
, PropertySheet.DecimalOption , PropertySheet.DecimalOption
) )
# Declarative interfaces
zope.interface.implements( interfaces.IEquivalenceTester, )
def _compare(self, prevision_movement, decision_movement): def _compare(self, prevision_movement, decision_movement):
""" """
If prevision_movement and decision_movement don't match, it returns a If prevision_movement and decision_movement don't match, it returns a
...@@ -69,8 +64,10 @@ class FloatEquivalenceTester(Predicate, EquivalenceTesterMixin): ...@@ -69,8 +64,10 @@ class FloatEquivalenceTester(Predicate, EquivalenceTesterMixin):
lambda x:False)(tested_property): lambda x:False)(tested_property):
decision_value = decision_movement.getRecordedProperty(tested_property) decision_value = decision_movement.getRecordedProperty(tested_property)
else: else:
decision_value = self._getPropertyValue(decision_movement, tested_property) or 0.0 decision_value = self._getTestedPropertyValue(decision_movement,
prevision_value = self._getPropertyValue(prevision_movement, tested_property) or 0.0 tested_property) or 0.0
prevision_value = self._getTestedPropertyValue(prevision_movement,
tested_property) or 0.0
# use delivery_ratio if specified # use delivery_ratio if specified
if self.getProperty('use_delivery_ratio') and \ if self.getProperty('use_delivery_ratio') and \
...@@ -173,19 +170,3 @@ class FloatEquivalenceTester(Predicate, EquivalenceTesterMixin): ...@@ -173,19 +170,3 @@ class FloatEquivalenceTester(Predicate, EquivalenceTesterMixin):
ROUND_DOWN) ROUND_DOWN)
return Decimal(str(value)).quantize(Decimal(self.getDecimalExponent()), return Decimal(str(value)).quantize(Decimal(self.getDecimalExponent()),
rounding=rounding_option) rounding=rounding_option)
def getUpdatablePropertyDict(self, prevision_movement, decision_movement):
"""
Returns a list of properties to update on decision_movement
prevision_movement so that next call to compare returns True.
prevision_movement -- a simulation movement (prevision)
decision_movement -- a delivery movement (decision)
"""
tested_property = self.getTestedProperty()
prevision_value = self._getPropertyValue(prevision_movement, tested_property)
return {tested_property:prevision_value}
def _getPropertyValue(self, document, property):
return document.getProperty(property)
...@@ -28,11 +28,9 @@ ...@@ -28,11 +28,9 @@
# #
############################################################################## ##############################################################################
import zope.interface
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Products.ERP5.Document.Predicate import Predicate from Products.ERP5.Document.Predicate import Predicate
from Products.ERP5Type import Permissions, PropertySheet, interfaces from Products.ERP5Type import Permissions, PropertySheet
from Products.ERP5.mixin.equivalence_tester import EquivalenceTesterMixin from Products.ERP5.mixin.equivalence_tester import EquivalenceTesterMixin
class StringEquivalenceTester(Predicate, EquivalenceTesterMixin): class StringEquivalenceTester(Predicate, EquivalenceTesterMixin):
...@@ -58,10 +56,6 @@ class StringEquivalenceTester(Predicate, EquivalenceTesterMixin): ...@@ -58,10 +56,6 @@ class StringEquivalenceTester(Predicate, EquivalenceTesterMixin):
, PropertySheet.SolverSelection , PropertySheet.SolverSelection
) )
# Declarative interfaces
zope.interface.implements( interfaces.IEquivalenceTester, )
def _compare(self, prevision_movement, decision_movement): def _compare(self, prevision_movement, decision_movement):
""" """
If prevision_movement and decision_movement don't match, it returns a If prevision_movement and decision_movement don't match, it returns a
...@@ -72,8 +66,10 @@ class StringEquivalenceTester(Predicate, EquivalenceTesterMixin): ...@@ -72,8 +66,10 @@ class StringEquivalenceTester(Predicate, EquivalenceTesterMixin):
lambda x:False)(tested_property): lambda x:False)(tested_property):
decision_value = decision_movement.getRecordedProperty(tested_property) decision_value = decision_movement.getRecordedProperty(tested_property)
else: else:
decision_value = decision_movement.getProperty(tested_property) decision_value = self._getTestedPropertyValue(decision_movement,
prevision_value = prevision_movement.getProperty(tested_property) tested_property)
prevision_value = self._getTestedPropertyValue(prevision_movement,
tested_property)
# XXX do we have configurable parameter for this divergence tester ? # XXX do we have configurable parameter for this divergence tester ?
# like ambiguity... # like ambiguity...
...@@ -83,16 +79,3 @@ class StringEquivalenceTester(Predicate, EquivalenceTesterMixin): ...@@ -83,16 +79,3 @@ class StringEquivalenceTester(Predicate, EquivalenceTesterMixin):
'The value of ${property_name} is different between decision and prevision.', 'The value of ${property_name} is different between decision and prevision.',
dict(property_name=tested_property)) dict(property_name=tested_property))
return None return None
def getUpdatablePropertyDict(self, prevision_movement, decision_movement):
"""
Returns a list of properties to update on decision_movement
prevision_movement so that next call to compare returns True.
prevision_movement -- a simulation movement (prevision)
decision_movement -- a delivery movement (decision)
"""
tested_property = self.getTestedProperty()
prevision_value = prevision_movement.getProperty(tested_property)
return {tested_property:prevision_value}
...@@ -26,11 +26,9 @@ ...@@ -26,11 +26,9 @@
# #
############################################################################## ##############################################################################
import zope.interface
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Products.ERP5.Document.Predicate import Predicate from Products.ERP5.Document.Predicate import Predicate
from Products.ERP5Type import Permissions, PropertySheet, interfaces from Products.ERP5Type import Permissions, PropertySheet
from Products.ERP5.mixin.equivalence_tester import EquivalenceTesterMixin from Products.ERP5.mixin.equivalence_tester import EquivalenceTesterMixin
class VariationEquivalenceTester(Predicate, EquivalenceTesterMixin): class VariationEquivalenceTester(Predicate, EquivalenceTesterMixin):
...@@ -56,9 +54,6 @@ class VariationEquivalenceTester(Predicate, EquivalenceTesterMixin): ...@@ -56,9 +54,6 @@ class VariationEquivalenceTester(Predicate, EquivalenceTesterMixin):
, PropertySheet.SolverSelection , PropertySheet.SolverSelection
) )
# Declarative interfaces
zope.interface.implements( interfaces.IEquivalenceTester, )
def _compare(self, prevision_movement, decision_movement): def _compare(self, prevision_movement, decision_movement):
""" """
If prevision_movement and decision_movement don't match, it returns a If prevision_movement and decision_movement don't match, it returns a
...@@ -70,8 +65,10 @@ class VariationEquivalenceTester(Predicate, EquivalenceTesterMixin): ...@@ -70,8 +65,10 @@ class VariationEquivalenceTester(Predicate, EquivalenceTesterMixin):
lambda x:False)(tested_property): lambda x:False)(tested_property):
decision_value = decision_movement.getRecordedProperty(tested_property) decision_value = decision_movement.getRecordedProperty(tested_property)
else: else:
decision_value = decision_movement.getProperty(tested_property) decision_value = self._getTestedPropertyValue(decision_movement,
prevision_value = prevision_movement.getProperty(tested_property) tested_property)
prevision_value = self._getTestedPropertyValue(prevision_movement,
tested_property)
if isinstance(prevision_value, (list, tuple)): if isinstance(prevision_value, (list, tuple)):
result = sorted(decision_value) == sorted(prevision_value) result = sorted(decision_value) == sorted(prevision_value)
...@@ -105,7 +102,8 @@ class VariationEquivalenceTester(Predicate, EquivalenceTesterMixin): ...@@ -105,7 +102,8 @@ class VariationEquivalenceTester(Predicate, EquivalenceTesterMixin):
if movement.isPropertyRecorded(tested_property): if movement.isPropertyRecorded(tested_property):
value_list.append(movement.getRecordedProperty(tested_property)) value_list.append(movement.getRecordedProperty(tested_property))
else: else:
value_list.append(movement.getProperty(tested_property)) value_list.append(self._getTestedPropertyValue(movement,
tested_property))
return 'variation/%r' % (value_list) return 'variation/%r' % (value_list)
def getUpdatablePropertyDict(self, prevision_movement, decision_movement): def getUpdatablePropertyDict(self, prevision_movement, decision_movement):
...@@ -117,9 +115,7 @@ class VariationEquivalenceTester(Predicate, EquivalenceTesterMixin): ...@@ -117,9 +115,7 @@ class VariationEquivalenceTester(Predicate, EquivalenceTesterMixin):
decision_movement -- a delivery movement (decision) decision_movement -- a delivery movement (decision)
""" """
property_dict = {} get = self._getTestedPropertyValue
for tested_property in ('variation_category_list', return dict((tested_property, get(prevision_movement, tested_property))
'variation_property_dict'): for tested_property in ('variation_category_list',
prevision_value = prevision_movement.getProperty(tested_property) 'variation_property_dict'))
property_dict[tested_property] = prevision_value
return property_dict
...@@ -91,6 +91,13 @@ class EquivalenceTesterMixin: ...@@ -91,6 +91,13 @@ class EquivalenceTesterMixin:
mapping=mapping mapping=mapping
) )
@staticmethod
def _getTestedPropertyValue(movement, property):
"""
Getter returning the value for the given tested property
"""
return movement.getProperty(property)
def generateHashKey(self, movement): def generateHashKey(self, movement):
""" """
Returns a hash key which can be used to optimise the Returns a hash key which can be used to optimise the
...@@ -106,7 +113,7 @@ class EquivalenceTesterMixin: ...@@ -106,7 +113,7 @@ class EquivalenceTesterMixin:
if movement.isPropertyRecorded(tested_property): if movement.isPropertyRecorded(tested_property):
value = movement.getRecordedProperty(tested_property) value = movement.getRecordedProperty(tested_property)
else: else:
value = movement.getProperty(tested_property) value = self._getTestedPropertyValue(movement, tested_property)
return '%s/%r' % (tested_property, value) return '%s/%r' % (tested_property, value)
def compare(self, prevision_movement, decision_movement): def compare(self, prevision_movement, decision_movement):
...@@ -193,7 +200,7 @@ class EquivalenceTesterMixin: ...@@ -193,7 +200,7 @@ class EquivalenceTesterMixin:
""" """
raise NotImplementedError raise NotImplementedError
def getUpdatablePropertyDict(prevision_movement, decision_movement): def getUpdatablePropertyDict(self, prevision_movement, decision_movement):
""" """
Returns a list of properties to update on decision_movement Returns a list of properties to update on decision_movement
prevision_movement so that next call to compare returns True. prevision_movement so that next call to compare returns True.
...@@ -202,4 +209,6 @@ class EquivalenceTesterMixin: ...@@ -202,4 +209,6 @@ class EquivalenceTesterMixin:
decision_movement -- a delivery movement (decision) decision_movement -- a delivery movement (decision)
""" """
raise NotImplementedError tested_property = self.getTestedProperty()
return {tested_property: self._getTestedPropertyValue(prevision_movement,
tested_property)}
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