diff --git a/trytond/ir/translation.xml b/trytond/ir/translation.xml index 5c3f87decf..45bc5ad4b4 100644 --- a/trytond/ir/translation.xml +++ b/trytond/ir/translation.xml @@ -141,6 +141,16 @@ this repository contains the full copyright notices and license terms. --> ir + + selection_validation_record + en_US + error + The field "%s" on "%s" is not in the selection. + The field "%s" on "%s" is not in the selection. + ir + + time_format_validation_record en_US diff --git a/trytond/model/modelsql.py b/trytond/model/modelsql.py index 1e1cdc48c9..2f46d2422c 100644 --- a/trytond/model/modelsql.py +++ b/trytond/model/modelsql.py @@ -297,23 +297,6 @@ class ModelSQL(ModelStorage): upd2.append(FIELDS[field._type].sql_format(value)) else: upd_todo.append(fname) - if (hasattr(field, 'selection') - and field.selection - and value): - if field._type == 'reference': - if isinstance(value, basestring): - value = value.split(',')[0] - else: - value, _ = value - if isinstance(field.selection, (tuple, list)): - test = dict(field.selection) - else: - test = dict(getattr(cls, field.selection)()) - if value not in test: - raise Exception('ValidateError', - 'The value "%s" for the field "%s" ' - 'is not in the selection' - % (value, fname)) upd0 += ', create_uid, create_date' upd1 += ', %s, %s' upd2.append(Transaction().user) @@ -788,30 +771,6 @@ class ModelSQL(ModelStorage): upd_todo.append(field) else: updend.append(field) - if field in cls._fields \ - and hasattr(cls._fields[field], 'selection') \ - and cls._fields[field].selection \ - and values[field]: - if cls._fields[field]._type == 'reference': - if isinstance(values[field], basestring): - val = values[field].split(',')[0] - else: - val, _ = values[field] - else: - val = values[field] - if isinstance(cls._fields[field].selection, (tuple, list)): - if val not in dict(cls._fields[field].selection): - raise Exception('ValidateError', - 'The value "%s" for the field "%s" ' \ - 'is not in the selection' % \ - (val, field)) - else: - if val not in dict(getattr(cls, - cls._fields[field].selection)()): - raise Exception('ValidateError', - 'The value "%s" for the field "%s" ' \ - 'is not in the selection' % \ - (val, field)) upd0.append(('write_uid', '%s')) upd0.append(('write_date', '%s')) diff --git a/trytond/model/modelstorage.py b/trytond/model/modelstorage.py index 61519ce96d..5114d59d28 100644 --- a/trytond/model/modelstorage.py +++ b/trytond/model/modelstorage.py @@ -1059,6 +1059,28 @@ class ModelStorage(Model): digits_test(getattr(record, field_name), field.digits, field_name) + # validate selection + if hasattr(field, 'selection') and field.selection: + if isinstance(field.selection, (tuple, list)): + test = set(dict(field.selection).keys()) + else: + test = set(dict(getattr(cls, + field.selection)()).keys()) + # None and '' are equivalent + if '' in test or None in test: + test.add('') + test.add(None) + for record in records: + value = getattr(record, field_name) + if field._type == 'reference': + if isinstance(value, ModelStorage): + value = value.__class__.__name__ + elif value: + value, _ = value.split(',') + if value not in test: + cls.raise_user_error('selection_validation_record', + error_args=cls._get_error_args(field_name)) + def format_test(value, format, field_name): if not value: return diff --git a/trytond/res/user.py b/trytond/res/user.py index d30deaf96b..1e4abec61a 100644 --- a/trytond/res/user.py +++ b/trytond/res/user.py @@ -26,6 +26,7 @@ try: TIMEZONES = [(x, x) for x in pytz.common_timezones] except ImportError: TIMEZONES = [] +TIMEZONES += [(None, '')] __all__ = [ 'User', 'UserAction', 'UserGroup', 'Warning_', diff --git a/trytond/test/export_data.py b/trytond/test/export_data.py index 4f05b000c0..8c9f3c635b 100644 --- a/trytond/test/export_data.py +++ b/trytond/test/export_data.py @@ -29,9 +29,10 @@ class ExportData(ModelSQL): date = fields.Date('Date') datetime = fields.DateTime('DateTime') selection = fields.Selection([ - ('select1', 'Select 1'), - ('select2', 'Select 2'), - ], 'Selection') + (None, ''), + ('select1', 'Select 1'), + ('select2', 'Select 2'), + ], 'Selection') many2one = fields.Many2One('test.export_data.target', 'Many2One') many2many = fields.Many2Many('test.export_data.relation', @@ -39,8 +40,9 @@ class ExportData(ModelSQL): one2many = fields.One2Many('test.export_data.target', 'one2many', 'One2Many') reference = fields.Reference('Reference', [ - ('test.export_data.target', 'Target'), - ]) + (None, ''), + ('test.export_data.target', 'Target'), + ]) class ExportDataTarget2: diff --git a/trytond/test/import_data.py b/trytond/test/import_data.py index 0dd816bd88..1f62d9ae07 100644 --- a/trytond/test/import_data.py +++ b/trytond/test/import_data.py @@ -73,9 +73,10 @@ class ImportDataSelection(ModelSQL): "Import Data Selection" __name__ = 'test.import_data.selection' selection = fields.Selection([ - ('select1', 'Select 1'), - ('select2', 'Select 2'), - ], 'Selection') + (None, ''), + ('select1', 'Select 1'), + ('select2', 'Select 2'), + ], 'Selection') class ImportDataMany2OneTarget(ModelSQL): @@ -136,5 +137,6 @@ class ImportDataReference(ModelSQL): "Import Data Reference" __name__ = 'test.import_data.reference' reference = fields.Reference('Reference', [ - ('test.import_data.reference.selection', 'Test'), - ]) + (None, ''), + ('test.import_data.reference.selection', 'Test'), + ]) diff --git a/trytond/test/test.py b/trytond/test/test.py index b855fc341c..bd18f5f612 100644 --- a/trytond/test/test.py +++ b/trytond/test/test.py @@ -429,6 +429,7 @@ class One2ManyReferenceTarget(ModelSQL): __name__ = 'test.one2many_reference.target' name = fields.Char('Name', required=True) origin = fields.Reference('Origin', [ + (None, ''), ('test.one2many_reference', 'One2Many Reference'), ]) @@ -520,6 +521,7 @@ class Many2ManyReferenceRelation(ModelSQL): 'Many2Many Relation' __name__ = 'test.many2many_reference.relation' origin = fields.Reference('Origin', [ + (None, ''), ('test.many2many_reference', 'Many2Many Reference'), ]) target = fields.Many2One('test.many2many_reference.target', @@ -551,6 +553,7 @@ class Reference(ModelSQL): __name__ = 'test.reference' name = fields.Char('Name', required=True) reference = fields.Reference('Reference', selection=[ + (None, ''), ('test.reference.target', 'Target'), ]) @@ -566,6 +569,7 @@ class ReferenceRequired(ModelSQL): __name__ = 'test.reference_required' name = fields.Char('Name', required=True) reference = fields.Reference('Reference', selection=[ + (None, ''), ('test.reference.target', 'Target'), ], required=True) @@ -578,6 +582,7 @@ class Property(ModelSQL): 'Test Many2One')) numeric = fields.Property(fields.Numeric('Test Numeric')) selection = fields.Property(fields.Selection([ + (None, ''), ('option_a', 'Option A'), ('option_b', 'Option B') ], 'Test Selection'))