Commit 0f8f6a55 authored by Yusei Tahara's avatar Yusei Tahara

Fix two bugs. First bug was that `Proxify` did not delegate value when...

Fix two bugs. First bug was that `Proxify` did not delegate value when original value was not empty string but an empty list or false value. Second one is that `Unproxify` did not copy delegated values when the root template field was an old field instance and did not have recently added properties.
Add `keep empty value` option. If this option is true, then emply property will not be delegated and will be kept as empty.


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@27706 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 5eabc37b
...@@ -88,6 +88,29 @@ def copyMethod(value): ...@@ -88,6 +88,29 @@ def copyMethod(value):
value = TALESMethod(value._text) value = TALESMethod(value._text)
return value return value
def getFieldDict(field, value_type):
result = {}
if field.meta_type=='ProxyField':
if value_type=='values':
get_method = getattr(field, 'get_recursive_orig_value')
elif value_type=='tales':
get_method = getattr(field, 'get_recursive_tales')
else:
raise ValueError, 'value_type must be values or tales'
template_field = field.getRecursiveTemplateField()
for ui_field_id in template_field.form.fields.keys():
result[ui_field_id] = get_method(ui_field_id)
else:
if value_type=='values':
get_method = getattr(field, 'get_orig_value')
elif value_type=='tales':
get_method = getattr(field, 'get_tales')
else:
raise ValueError, 'value_type must be values or tales'
for ui_field_id in field.form.fields.keys():
result[ui_field_id] = get_method(ui_field_id)
return result
class StaticValue: class StaticValue:
""" """
...@@ -880,18 +903,26 @@ class ERP5Form(ZMIForm, ZopePageTemplate): ...@@ -880,18 +903,26 @@ class ERP5Form(ZMIForm, ZopePageTemplate):
return [f for f in self.objectValues() if f.meta_type == 'ProxyField'] return [f for f in self.objectValues() if f.meta_type == 'ProxyField']
security.declareProtected('Change Formulator Forms', 'proxifyField') security.declareProtected('Change Formulator Forms', 'proxifyField')
def proxifyField(self, field_dict=None, force_delegate=False, REQUEST=None): def proxifyField(self, field_dict=None, force_delegate=False,
keep_empty_value=False, REQUEST=None):
"""Convert fields to proxy fields """Convert fields to proxy fields
If the field value is different from the proxyfield value, the value is If the field value is not empty and different from the proxyfield
kept on the proxyfield, otherwise it is delegated. If you specify value, the value is kept on the proxyfield, otherwise it is delegated.
force_delegate, values will be delegated even if they are different If you specify force_delegate, values will be delegated even if they
are different. And if you specify keep_empty_value, then empty values
will not be delegated(force_delegate option is high priority).
""" """
from Products.ERP5Form.ProxyField import ProxyWidget from Products.ERP5Form.ProxyField import ProxyWidget
def copy(_dict): def copy(field, value_type):
new_dict = {} new_dict = {}
for key, value in _dict.items(): for key, value in getFieldDict(field, value_type).iteritems():
if value=='': if (keep_empty_value is False and
(value=='' or
value==0 or
(isinstance(value, (tuple, list)) and len(value)==0)
)
):
continue continue
if isinstance(aq_base(value), (Method, TALESMethod)): if isinstance(aq_base(value), (Method, TALESMethod)):
value = copyMethod(value) value = copyMethod(value)
...@@ -952,10 +983,10 @@ class ERP5Form(ZMIForm, ZopePageTemplate): ...@@ -952,10 +983,10 @@ class ERP5Form(ZMIForm, ZopePageTemplate):
target_field = proxy_field.getTemplateField() target_field = proxy_field.getTemplateField()
# copy data # copy data
new_values = remove_same_value(copy(old_field.values), new_values = remove_same_value(copy(old_field, 'values'),
target_field.values) getFieldDict(target_field, 'values'))
new_tales = remove_same_value(copy(old_field.tales), new_tales = remove_same_value(copy(old_field, 'tales'),
target_field.tales) getFieldDict(target_field, 'tales'))
if target_field.meta_type=='ProxyField': if target_field.meta_type=='ProxyField':
for i in new_values.keys(): for i in new_values.keys():
...@@ -1001,20 +1032,14 @@ class ERP5Form(ZMIForm, ZopePageTemplate): ...@@ -1001,20 +1032,14 @@ class ERP5Form(ZMIForm, ZopePageTemplate):
psyco.bind(_exec) psyco.bind(_exec)
security.declareProtected('Change Formulator Forms', 'unProxifyField') security.declareProtected('Change Formulator Forms', 'unProxifyField')
def unProxifyField(self, field_dict=None, REQUEST=None): def unProxifyField(self, field_dict=None, copy_delegated_values=False,
REQUEST=None):
""" """
Convert proxy fields to fields Convert proxy fields to fields
""" """
def copy(field, value_type): def copy(field, value_type):
mapping_dict = {'values' : 'get_recursive_orig_value',
'tales' : 'get_recursive_tales'}
new_dict = {} new_dict = {}
key_list = getattr(field.getRecursiveTemplateField(), value_type).keys() for key, value in getFieldDict(field, value_type).iteritems():
for key in key_list:
method_id = mapping_dict[value_type]
value = getattr(field, method_id)(key)
if value=='':
continue
if isinstance(aq_base(value), (Method, TALESMethod)): if isinstance(aq_base(value), (Method, TALESMethod)):
value = copyMethod(value) value = copyMethod(value)
elif value is not None and not isinstance(value, elif value is not None and not isinstance(value,
......
...@@ -5,15 +5,19 @@ ...@@ -5,15 +5,19 @@
<p class="form-help"> <p class="form-help">
Proxify non-proxy fields.<br/> Proxify non-proxy fields.<br/>
This tool will keep values on fields if they are different from the target This tool will keep values on fields if they are not empty value and
field.<br/> different from the target field.<br/>
If you don't want this behaviour, check the <em>Delegate values</em> checkbox If you don't want this behaviour, check the <em>Delegate values</em> checkbox
below and all values will be delegated to the proxy target. below and all values will be delegated to the proxy target.<br/>
If you want to keep empty values('' or () or [] or 0) after proxify, check
the <em>Keep empty values</em> checkbox below and all empty values will not be
delegated. (Delegate values option is high priority.)
</p> </p>
<form action="proxifyField" method="POST"> <form action="proxifyField" method="POST">
Delegate values <input type="checkbox" name="force_delegate"> <br/> Delegate values <input type="checkbox" name="force_delegate"> <br/>
Keep empty values <input type="checkbox" name="keep_empty_value"> <br/>
<table border="2"> <table border="2">
<tr> <tr>
......
...@@ -66,8 +66,14 @@ class TestProxify(unittest.TestCase): ...@@ -66,8 +66,14 @@ class TestProxify(unittest.TestCase):
base_view = self.base_view = self.container.Base_view base_view = self.base_view = self.container.Base_view
base_view.manage_addField('my_string_field', 'String Field', 'StringField') base_view.manage_addField('my_string_field', 'String Field', 'StringField')
base_view.manage_addField('my_list_field', 'List Field', 'ListField') base_view.manage_addField('my_list_field', 'List Field', 'ListField')
base_view.manage_addField('my_relation_string_field', 'Old Relation String Field', 'RelationStringField')
base_view.manage_addField('my_gender', 'Gender', 'ListField')
base_view.my_string_field.values['display_width'] = 30 base_view.my_string_field.values['display_width'] = 30
base_view.my_list_field.values['size'] = 1 base_view.my_list_field.values['size'] = 1
base_view.my_gender.values['items'] = [('Male', 'Male'), ('Female', 'Female')]
# old instance does not have recently added properties.
del base_view.my_relation_string_field.values['proxy_listbox_ids']
del base_view.my_relation_string_field.values['relation_form_id']
# address view # address view
self.container._setObject('Address_view', self.container._setObject('Address_view',
...@@ -83,25 +89,29 @@ class TestProxify(unittest.TestCase): ...@@ -83,25 +89,29 @@ class TestProxify(unittest.TestCase):
person_view = self.person_view = self.container.Person_view person_view = self.person_view = self.container.Person_view
person_view.manage_addField('my_name', 'Name', 'StringField') person_view.manage_addField('my_name', 'Name', 'StringField')
person_view.manage_addField('my_default_region', 'Country', 'ListField') person_view.manage_addField('my_default_region', 'Country', 'ListField')
person_view.my_name.values['size'] = 20 person_view.my_name.values['display_maxwidth'] = 20
person_view.my_default_region.values['size'] = 1 person_view.my_default_region.values['size'] = 1
person_view.my_default_region.tales['items'] = TALESMethod('here/portal_categories/region/getCategoryChildTranslatedLogicalPathItemList') person_view.my_default_region.tales['items'] = TALESMethod('here/portal_categories/region/getCategoryChildTranslatedLogicalPathItemList')
person_view.my_default_region.values['scrap_variable'] = 'obsolete' person_view.my_default_region.values['scrap_variable'] = 'obsolete'
person_view.manage_addField('my_career_subordination_title', 'Organisation', 'RelationStringField')
person_view.my_career_subordination_title.values['base_category'] = 'subordination'
person_view.my_career_subordination_title.values['portal_type'] = [('Organisation', 'Organisation')]
person_view.my_career_subordination_title.values['proxy_listbox_ids'] = [('OrganisationModule_viewOrganisationList/listbox', 'Organisation')]
global request global request
request = DummyRequest() request = DummyRequest()
def test_single_level_proxify(self): def test_single_level_proxify(self):
# StringField
self.person_view.proxifyField({'my_name':'Base_view.my_string_field'}) self.person_view.proxifyField({'my_name':'Base_view.my_string_field'})
field = self.person_view.my_name field = self.person_view.my_name
self.assertEqual(field.meta_type, 'ProxyField') self.assertEqual(field.meta_type, 'ProxyField')
self.assertEqual(field.get_value('form_id'), 'Base_view') self.assertEqual(field.get_value('form_id'), 'Base_view')
self.assertEqual(field.get_value('field_id'), 'my_string_field') self.assertEqual(field.get_value('field_id'), 'my_string_field')
self.assertEqual(field.is_delegated('title'), False) self.assertEqual(field.is_delegated('title'), False)
self.assertEqual(field.get_value('title'), 'Name') self.assertEqual(field.get_value('title'), 'Name')
self.assertEqual(field.is_delegated('size'), False) self.assertEqual(field.is_delegated('display_maxwidth'), False)
self.assertEqual(field.get_value('size'), 20) self.assertEqual(field.get_value('display_maxwidth'), 20)
self.assertEqual(field.is_delegated('enabled'), True) self.assertEqual(field.is_delegated('enabled'), True)
self.assertEqual(field.get_value('enabled'), 1) self.assertEqual(field.get_value('enabled'), 1)
self.assertEqual(field.is_delegated('description'), True) self.assertEqual(field.is_delegated('description'), True)
...@@ -112,6 +122,17 @@ class TestProxify(unittest.TestCase): ...@@ -112,6 +122,17 @@ class TestProxify(unittest.TestCase):
template_field.values['description'] = 'Description' template_field.values['description'] = 'Description'
self.assertEqual(field.get_value('description'), 'Description') self.assertEqual(field.get_value('description'), 'Description')
purgeFieldValueCache()
# ListField
self.person_view.manage_addField('my_gender', 'Gender', 'ListField')
self.person_view.proxifyField({'my_gender':'Base_view.my_gender'})
field = self.person_view.my_gender
self.assertEqual(field.is_delegated('title'), True)
self.assertEqual(field.get_value('title'), 'Gender')
self.assertEqual(field.is_delegated('items'), True)
self.assertEqual(field.get_value('items'), [('Male', 'Male'), ('Female', 'Female')])
def test_multi_level_proxify(self): def test_multi_level_proxify(self):
self.address_view.proxifyField({'my_region':'Base_view.my_list_field'}) self.address_view.proxifyField({'my_region':'Base_view.my_list_field'})
self.person_view.proxifyField({'my_default_region':'Address_view.my_region'}) self.person_view.proxifyField({'my_default_region':'Address_view.my_region'})
...@@ -167,7 +188,53 @@ class TestProxify(unittest.TestCase): ...@@ -167,7 +188,53 @@ class TestProxify(unittest.TestCase):
self.assertEqual(field.get_tales('items')._text, self.assertEqual(field.get_tales('items')._text,
'here/portal_categories/region/getCategoryChildTranslatedLogicalPathItemList') 'here/portal_categories/region/getCategoryChildTranslatedLogicalPathItemList')
#Test unproxify with old instance.
#Proxify First
self.person_view.proxifyField({'my_career_subordination_title':'Base_view.my_relation_string_field'})
purgeFieldValueCache()
#UnProxify
self.person_view.unProxifyField({'my_career_subordination_title':'on'})
field = self.person_view.my_career_subordination_title
self.assertEqual(field.meta_type, 'RelationStringField')
self.assertEqual(field.get_value('title'), 'Organisation')
self.assertEqual(field.get_value('proxy_listbox_ids'), [('OrganisationModule_viewOrganisationList/listbox', 'Organisation')])
def test_suite(): def test_suite():
suite = unittest.TestSuite() suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestProxify)) suite.addTest(unittest.makeSuite(TestProxify))
return suite return suite
def get_field_data(field):
from Products.Formulator.MethodField import Method
value_dict = {}
tales_dict = {}
if field.meta_type=='ProxyField':
template_field = field.getRecursiveTemplateField()
for ui_field_id in template_field.form.fields.keys():
value = field.get_recursive_orig_value(ui_field_id)
if isinstance(value, Method):
value = value.method_name
tales = field.get_recursive_tales(ui_field_id)
if tales:
tales_text = tales._text
else:
tales_text = ''
value_dict[ui_field_id] = value
tales_dict[ui_field_id] = tales_text
else:
for ui_field_id in field.form.fields.keys():
value = field.get_orig_value(ui_field_id)
if isinstance(value, Method):
value = value.method_name
tales = field.get_tales(ui_field_id)
if tales:
tales_text = tales._text
else:
tales_text = ''
value_dict[ui_field_id] = value
tales_dict[ui_field_id] = tales_text
return value_dict, tales_dict
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