Commit 104b4f48 authored by Alexandre Boeglin's avatar Alexandre Boeglin

Added the ability to add a TALES expression as a condition to Constraints

(except PropertyTypeValidity, as it is implicitly defined for all Document
Types).

Currently, it is only tested in PropertyExistence test (but the logic is the
same in each constraint).


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@10316 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 8f445236
......@@ -39,6 +39,7 @@ class AttributeEquality(PropertyExistence):
'description' : 'Title must be "ObjectTitle"',
'type' : 'AttributeEquality',
'title' : 'ObjectTitle',
'condition' : 'python: object.getPortalType() == 'Foo',
},
"""
......@@ -49,6 +50,8 @@ class AttributeEquality(PropertyExistence):
We will make sure that each non None constraint_definition is
satisfied (equality)
"""
if not self._checkConstraintCondition(obj):
return []
errors = PropertyExistence.checkConsistency(self, obj, fixit=fixit)
for attribute_name, attribute_value in self.constraint_definition.items():
error_message = None
......
......@@ -42,6 +42,7 @@ class CategoryAcquiredMembershipArity(Constraint):
'max_arity' : '1',
'portal_type' : ('Organisation', ),
'base_category' : ('source',)
'condition' : 'python: object.getPortalType() == 'Foo',
},
"""
......@@ -53,6 +54,8 @@ class CategoryAcquiredMembershipArity(Constraint):
are defined the minimum and the maximum arity, and the
list of objects we wants to check the arity.
"""
if not self._checkConstraintCondition(obj):
return []
errors = []
# Retrieve values inside de PropertySheet (_constraints)
base_category = self.constraint_definition['base_category']
......
......@@ -39,6 +39,7 @@ class CategoryExistence(Constraint):
'type' : 'CategoryExistence',
'portal_type' : ('Person', 'Organisation')
'causality' : None,
'condition' : 'python: object.getPortalType() == 'Foo',
},
"""
......@@ -47,6 +48,8 @@ class CategoryExistence(Constraint):
This is the check method, we return a list of string,
each string corresponds to an error.
"""
if not self._checkConstraintCondition(obj):
return []
errors = []
# For each attribute name, we check if defined
for base_category in self.constraint_definition.keys():
......
......@@ -42,6 +42,7 @@ class CategoryMembershipArity(Constraint):
'max_arity' : '1',
'portal_type' : ('Organisation', ),
'base_category' : ('source',)
'condition' : 'python: object.getPortalType() == 'Foo',
},
"""
......@@ -53,6 +54,8 @@ class CategoryMembershipArity(Constraint):
are defined the minimum and the maximum arity, and the
list of objects we wants to check the arity.
"""
if not self._checkConstraintCondition(obj):
return []
errors = []
# Retrieve values inside de PropertySheet (_constraints)
base_category = self.constraint_definition['base_category']
......
......@@ -43,6 +43,7 @@ class CategoryRelatedMembershipArity(Constraint):
'max_arity' : '1',
'portal_type' : ('Applied Rule', ),
'base_category' : ('causality',)
'condition' : 'python: object.getPortalType() == 'Foo',
},
"""
......@@ -54,6 +55,8 @@ class CategoryRelatedMembershipArity(Constraint):
are defined the minimum and the maximum arity, and the
list of objects we wants to check the arity.
"""
if not self._checkConstraintCondition(obj):
return []
errors = []
# Retrieve values inside de PropertySheet (_constraints)
base_category = self.constraint_definition['base_category']
......
......@@ -28,13 +28,15 @@
#
##############################################################################
from Products.CMFCore.Expression import Expression
class Constraint:
"""
Default Constraint implementation
"""
def __init__(self, id=None, description=None, type=None,
**constraint_definition):
condition=None, **constraint_definition):
"""
Remove unwanted attributes from constraint definition and keep
them as instance attributes
......@@ -42,6 +44,7 @@ class Constraint:
self.id = id
self.description = description
self.type = type
self.condition = condition
self.constraint_definition = constraint_definition
def edit(self, id=None, description=None, type=None,
......@@ -66,6 +69,21 @@ class Constraint:
104, error_message, self.description)
return error
def _checkConstraintCondition(self, obj):
"""
method that will check if the TALES condition is true.
It should be called by checkConsistency, which should ignore
constraints if TALES is False
"""
from Products.ERP5Type.Utils import createExpressionContext
condition = getattr(self, 'condition', None)
if condition not in (None, ''):
expression = Expression(condition)
econtext = createExpressionContext(obj)
if not expression(econtext):
return 0 # a condition was defined and is False
return 1 # no condition or a True condition was defined
def checkConsistency(self, obj, fixit=0):
"""
Default method is to return no error.
......
......@@ -43,6 +43,7 @@ class PortalTypeClass(Constraint):
'description' : 'The __class__ must be the same as the portal'\
' type definition',
'type' : 'PortalTypeClass',
'condition' : 'python: object.getPortalType() == 'Foo',
},
"""
......@@ -51,6 +52,8 @@ class PortalTypeClass(Constraint):
This is the check method, we return a list of string,
each string corresponds to an error.
"""
if not self._checkConstraintCondition(obj):
return []
errors = []
types_tool = getToolByName(obj, 'portal_types')
type_info = types_tool._getOb(obj.getPortalType(), None)
......
......@@ -40,6 +40,7 @@ class PropertyExistence(Constraint):
'description' : 'Property price must be defined',
'type' : 'PropertyExistence',
'price' : None,
'condition' : 'python: object.getPortalType() == 'Foo',
},
"""
......@@ -48,6 +49,8 @@ class PropertyExistence(Constraint):
This is the check method, we return a list of string,
each string corresponds to an error.
"""
if not self._checkConstraintCondition(obj):
return []
errors = []
# For each attribute name, we check if defined
for property_id in self.constraint_definition.keys():
......
......@@ -324,6 +324,32 @@ class TestConstraint(ERP5TypeTestCase):
description='propertyExistence test',
not_defined_property=None)
def stepCreatePropertyExistence1TrueCondition(self, sequence=None,
sequence_list=None, **kw):
"""
Create a PropertyExistence Constraint with a true condition
"""
self._createGenericConstraint(sequence,
klass_name='PropertyExistence',
id='property_existence',
description='propertyExistence test',
not_defined_property=None,
condition='python: object.getPortalType()' \
+ ' == "%s"' % self.object_portal_type)
def stepCreatePropertyExistence1FalseCondition(self, sequence=None,
sequence_list=None, **kw):
"""
Create a PropertyExistence Constraint with a false condition
"""
self._createGenericConstraint(sequence,
klass_name='PropertyExistence',
id='property_existence',
description='propertyExistence test',
not_defined_property=None,
condition='python: object.getPortalType()' \
+ ' == "False_PortalTypeXXX123"')
def stepCreatePropertyExistence2(self, sequence=None,
sequence_list=None, **kw):
"""
......@@ -357,6 +383,24 @@ class TestConstraint(ERP5TypeTestCase):
CheckIfConstraintFailed \
'
sequence_list.addSequenceString(sequence_string)
# Test Constraint with property not defined in PropertySheet and true
# condition
sequence_string = '\
CreateObject \
CreatePropertyExistence1TrueCondition \
CallCheckConsistency \
CheckIfConstraintFailed \
'
sequence_list.addSequenceString(sequence_string)
# Test Constraint with property not defined in PropertySheet and false
# condition
sequence_string = '\
CreateObject \
CreatePropertyExistence1FalseCondition \
CallCheckConsistency \
CheckIfConstraintSucceeded \
'
sequence_list.addSequenceString(sequence_string)
# Test Constraint with property defined on object
# With None value
sequence_string = '\
......
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