Commit 62956b95 authored by Gabriel Monnerat's avatar Gabriel Monnerat

Add constraint to be possible call checkConsistency recursively to specific portal type

To backward compatibility, this constraint was enabled to portal types that are required call checkConsistency recursively

Portal types with recursive checkConsistency: Leave Request, Group Calendar, Group Presence Period, Presence Period, Person and Accounting Transaction

Also, added test to check the constraint RecursiveCheckConsistencyConstraint
parent c25c6cd3
......@@ -4,6 +4,7 @@
</portal_type>
<portal_type id="Accounting Transaction">
<item>AccountingTransactionConstraint</item>
<item>RecursiveCheckConsistencyConstraint</item>
</portal_type>
<portal_type id="Accounting Transaction Line">
<item>AccountingTransactionLineConstraint</item>
......
......@@ -11,3 +11,4 @@ Purchase Invoice Transaction Line | AccountingTransactionLineConstraint
Purchase Invoice Transaction | AccountingTransactionConstraint
Sale Invoice Transaction Line | AccountingTransactionLineConstraint
Sale Invoice Transaction | AccountingTransactionConstraint
Accounting Transaction | RecursiveCheckConsistencyConstraint
\ No newline at end of file
......@@ -8,6 +8,7 @@
</portal_type>
<portal_type id="Person">
<item>DefaultImage</item>
<item>RecursiveCheckConsistencyConstraint</item>
</portal_type>
<portal_type id="Preference">
<item>TelephonePreference</item>
......
1062
\ No newline at end of file
1063
\ No newline at end of file
......@@ -2,5 +2,6 @@ Notification Message | ItemAggregation
Notification Message | Reference
Organisation | DefaultImage
Person | DefaultImage
Person | RecursiveCheckConsistencyConstraint
Preference | TelephonePreference
Query | TextDocument
\ No newline at end of file
<property_sheet_list>
<portal_type id="Group Calendar">
<item>RecursiveCheckConsistencyConstraint</item>
</portal_type>
<portal_type id="Group Presence Period">
<item>RecursiveCheckConsistencyConstraint</item>
</portal_type>
<portal_type id="Leave Request">
<item>RecursiveCheckConsistencyConstraint</item>
</portal_type>
<portal_type id="Presence Request">
<item>RecursiveCheckConsistencyConstraint</item>
</portal_type>
<portal_type id="System Preference">
<item>CalendarPreference</item>
</portal_type>
......
369
\ No newline at end of file
370
\ No newline at end of file
Group Calendar | RecursiveCheckConsistencyConstraint
Group Presence Period | RecursiveCheckConsistencyConstraint
Leave Request | RecursiveCheckConsistencyConstraint
Presence Request | RecursiveCheckConsistencyConstraint
System Preference | CalendarPreference
\ No newline at end of file
......@@ -89,6 +89,8 @@
<item>Dynamic Category Property</item>
<item>Property Existence Constraint</item>
<item>Property Type Validity Constraint</item>
<item>Recursive Check Consistency Constraint</item>
<item>Script Constraint</item>
<item>Standard Property</item>
<item>String Attribute Match Constraint</item>
<item>TALES Constraint</item>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Base Type" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_property_domain_dict</string> </key>
<value>
<dictionary>
<item>
<key> <string>short_title</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>content_icon</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>A Recursive Check Consistency Constraint calls checkConsistency recursively </string> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<tuple>
<string>constraint</string>
</tuple>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Recursive Check Consistency Constraint</string> </value>
</item>
<item>
<key> <string>init_script</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>permission</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Base Type</string> </value>
</item>
<item>
<key> <string>type_class</string> </key>
<value> <string>RecursiveCheckConsistencyConstraint</string> </value>
</item>
<item>
<key> <string>type_interface</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>type_mixin</string> </key>
<value>
<tuple/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="TranslationInformation" module="Products.ERP5Type.TranslationProviderBase"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>domain_name</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>property_name</string> </key>
<value> <string>short_title</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="TranslationInformation" module="Products.ERP5Type.TranslationProviderBase"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>domain_name</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>property_name</string> </key>
<value> <string>title</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -127,6 +127,10 @@
<type>Property Type Validity Constraint</type>
<workflow>dynamic_class_generation_interaction_workflow</workflow>
</chain>
<chain>
<type>Recursive Check Consistency Constraint</type>
<workflow>dynamic_class_generation_interaction_workflow</workflow>
</chain>
<chain>
<type>Standard Property</type>
<workflow>dynamic_class_generation_interaction_workflow</workflow>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ERP5Form" module="Products.ERP5Form.Form"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>action</string> </key>
<value> <string>Base_edit</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>edit_order</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>enctype</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<list>
<string>left</string>
<string>right</string>
<string>center</string>
<string>bottom</string>
<string>hidden</string>
</list>
</value>
</item>
<item>
<key> <string>groups</string> </key>
<value>
<dictionary>
<item>
<key> <string>bottom</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>center</string> </key>
<value>
<list>
<string>my_description</string>
</list>
</value>
</item>
<item>
<key> <string>hidden</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>left</string> </key>
<value>
<list>
<string>my_id</string>
<string>my_reference</string>
</list>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list/>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>RecursiveCheckConsistencyConstraint_view</string> </value>
</item>
<item>
<key> <string>method</string> </key>
<value> <string>POST</string> </value>
</item>
<item>
<key> <string>name</string> </key>
<value> <string>RecursiveCheckConsistencyConstraint_view</string> </value>
</item>
<item>
<key> <string>pt</string> </key>
<value> <string>form_view</string> </value>
</item>
<item>
<key> <string>row_length</string> </key>
<value> <int>4</int> </value>
</item>
<item>
<key> <string>stored_encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Recursive Check Consistency Constraint</string> </value>
</item>
<item>
<key> <string>unicode_mode</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>update_action</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>update_action_title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_description</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_description</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>delegated_message_list</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_id</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_id_as_reference</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_reference</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_read_only_reference</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Name</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
41154
\ No newline at end of file
41155
\ No newline at end of file
......@@ -48,6 +48,8 @@ Property Sheet | Content Existence Constraint
Property Sheet | Dynamic Category Property
Property Sheet | Property Existence Constraint
Property Sheet | Property Type Validity Constraint
Property Sheet | Recursive Check Consistency Constraint
Property Sheet | Script Constraint
Property Sheet | Standard Property
Property Sheet | String Attribute Match Constraint
Property Sheet | TALES Constraint
......
......@@ -62,6 +62,7 @@ Property Sheet Tool
Property Type Validity Constraint
Python Script
Ram Cache
Recursive Check Consistency Constraint
Role Information
Rule Tool
SQL Non Continuous Increasing Id Generator
......
......@@ -38,6 +38,7 @@ Property Existence Constraint | dynamic_class_generation_interaction_workflow
Property Sheet Tool | dynamic_class_generation_interaction_workflow
Property Sheet | dynamic_class_generation_interaction_workflow
Property Type Validity Constraint | dynamic_class_generation_interaction_workflow
Recursive Check Consistency Constraint | dynamic_class_generation_interaction_workflow
Standard Property | dynamic_class_generation_interaction_workflow
String Attribute Match Constraint | dynamic_class_generation_interaction_workflow
System Preference | edit_workflow
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Property Sheet" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_count</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>_mt_index</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>_tree</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>RecursiveCheckConsistencyConstraint</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Property Sheet</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Length" module="BTrees.Length"/>
</pickle>
<pickle> <int>0</int> </pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Recursive Check Consistency Constraint" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_identity_criterion</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>_range_criterion</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Call checkConsistency recursively</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>recursive_check_consistency_constraint</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Recursive Check Consistency Constraint</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
73
\ No newline at end of file
74
\ No newline at end of file
......@@ -191,3 +191,4 @@ Workflow
XMLObject
AttributeBlacklistedConstraint
CaptchaPreference
RecursiveCheckConsistencyConstraint
##############################################################################
#
# Copyright (c) 2014 Nexedi SARL and Contributors. All Rights Reserved.
# Gabriel Monnerat <gabriel@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly advised to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from Products.ERP5Type.mixin.constraint import ConstraintMixin
class RecursiveCheckConsistencyConstraint(ConstraintMixin):
"""
"""
meta_type = 'ERP5 Recursive Check Consistency Constraint'
portal_type = 'Recursive Check Consistency Constraint'
def _checkConsistency(self, obj, fixit=0, filter=None):
"""Calls checkConsistency on obj subdocuments"""
error_list = []
for subdocument in obj.objectValues():
error_list.extend(subdocument.checkConsistency(fixit=fixit, filter=filter))
return error_list
......@@ -1581,6 +1581,64 @@ class TestConstraint(PropertySheetTestCase):
sequence_list.play(self)
def test_RecursiveCheckConsistencyConstraint(self):
"""
Check that by default checkConsistency are not recursive and assiging
RecursiveCheckConsistencyConstraint to the portal type, checkConsistency
is called in all sub objects.
"""
portal = self.portal
script_id = "Organisation_checkCustomReference"
skin_folder = portal.portal_skins.custom
custom_script = getattr(skin_folder, script_id, None)
if custom_script is None:
skin_folder.manage_addProduct['PythonScripts'].manage_addPythonScript(script_id)
custom_script = getattr(skin_folder, script_id)
script_body = "error_list = []\n" + \
"reference = context.getReference()\n" + \
"if reference and not reference.startswith('old_'):\n" + \
" kw = {'relative_url': context.getRelativeUrl(), 'reference': reference}\n" + \
" error_list.append('%(relative_url)s <> %(reference)s -> old_%(reference)s' % kw)\n" + \
" if fixit:\n" + \
" context.setReference('old_%s' % reference)\nreturn error_list"
custom_script.ZPythonScript_edit('fixit=False, **kw', script_body)
property_sheet = portal.portal_property_sheets.newContent(
id="CustomOrganisationReferenceConstraint",
portal_type="Property Sheet")
script_constraint = property_sheet.newContent(
id="reference_constraint",
script_id=script_id,
portal_type="Script Constraint")
self.tic()
organisation = portal.organisation_module.newContent(
reference="org_reference",
portal_type="Organisation")
self.tic()
self.assertEquals(organisation.checkConsistency(), [])
organisation_portal_type = portal.portal_types['Organisation']
organisation_portal_type.setTypePropertySheetList(
organisation_portal_type.getTypePropertySheetList() + \
['CustomOrganisationReferenceConstraint',])
self.tic()
self.assertNotEquals(organisation.checkConsistency(), [])
self.assertEquals(portal.organisation_module.checkConsistency(), [])
organisation_module_portal_type = portal.portal_types['Organisation Module']
original_property_sheet_list = \
organisation_module_portal_type.getTypePropertySheetList()
organisation_module_portal_type.setTypePropertySheetList(
original_property_sheet_list + ['RecursiveCheckConsistencyConstraint',])
self.tic()
message_list = [m.message for m in \
portal.organisation_module.checkConsistency()]
self.assertNotEquals(message_list, [])
self.assertTrue(organisation.getRelativeUrl() in " ".join(message_list),
"%s not in %s"% (organisation.getRelativeUrl(), message_list))
organisation_module_portal_type.setTypePropertySheetList(
original_property_sheet_list)
self.tic()
self.assertEquals(portal.organisation_module.checkConsistency(), [])
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestConstraint))
......
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