Fix Form.proxifyField creating inconsistent proxy fields
When Form.proxifyField is used to make a proxy field from a field which has only a TALES and no value, it creates a proxy field with inconsistent internal data structures where has_value method does not work as expected. As a consequence, proxy fields to list fields are often broken in the ods/odt rendering.
Here is a scenario to reproduce the problem:
- add
Base_viewDummyFieldLibraryERP5 Form - add a
LinesField, with idyour_test_base_field. Changesizeto 1 (not really required but I did this in screenshots here) - add another
LinesField, with idyour_test_fieldand in this field: - So far, when this is rendered as ODS, everything is fine:
this is also what we see in html style view:
- use the proxify action, to make
your_test_fieldbe a proxy field toyour_test_base_field
- result of proxify action looks good, both for values:
and for TALES:
- but after this rendering the form with ODS becomes broken:
even though it looks fine with html views.
erp5_ods_style knows how to render list fields and it uses the "display" (two) and not the "value" (2), this is done here with a check depending on field.has_value("items").
has_value is implemented like this for proxy fields:
def has_value(self, id):
"""
Return true if the field defines such a value.
"""
result = None
if (id in self.widget.property_names) or \
(not self.is_delegated(id)):
result = ZMIField.has_value(self, id)
else:
proxy_field = self.getTemplateField()
if proxy_field is not None:
result = proxy_field.has_value(id)
return result
and like this for traditional fields:
def has_value(self, id):
"""Return true if the field defines such a value.
"""
if self.values.has_key(id) or self.form.has_field(id):
return 1
else:
return 0
when the value is defined on the proxy field and not delegated to template field, the condition is self.values.has_key(id).
But Form.proxifyField when transforming a traditional field in a proxy field does not keep the id in self.values if it's only needed in self.tales. This is the root cause of this problem, if we inspect the field, it is something like this:
(Pdb) self
<ProxyField at /erp5/portal_skins/custom/Base_viewDummyFieldLibrary/your_test_field>
(Pdb) pp self.tales
{'field_id': '',
'form_id': '',
'items': <Products.Formulator.TALESField.TALESMethod object at 0x7ffa705c7450 oid 0x572626 in <Connection at 7ffa42c1a610>>}
(Pdb) pp self.values
{'default': '2',
'field_id': 'your_test_base_field',
'form_id': 'Base_viewDummyFieldLibrary',
'title': 'Test Field'}
(Pdb) self.has_value('items')
0
(Pdb)
If we edit the proxy field, it will repair itself, because the proxy field edit method maintain self.tales and self.values consistent, but this is not the case withForm.proxifyField, which mutate directly .tales and .values and can make them have different keys - which is not supposed to happen.
The problem is that most of the proxy fields we have have been generated by Form.proxifyField, so for most of our fields the XML data of business template has this inconsistency. We could have took the easy way and make change ProxyField.has_value to understand this case, but it's probably better to fix the data.
erp5_hal_json also uses field.has_value in some places, so it's better to fix at field level and not to address this in erp5_ods_style and erp5_odt_style.
These changes:
- add a little more test coverage for
ProxyField.has_value( at first I thought the problem was only inhas_value) - Fix
Form.proxifyField - add a
ProxyField.checkConsistencyto check that.valuesand.talesare in sync - or more exactly that all entries from.talesare also in.values, because this is what cause the problem withhas_value. - re-export all proxy fields after cleaning up their
.valuesand.tales, usingcheckConsistency(fixit=True)on all proxy fields.







