Commit a151a379 authored by Nicolas Évrard's avatar Nicolas Évrard
Browse files

Do not validate domain on empty fields unless they're required

parent 8a7031c7e3f8
* Do not validate domain and enforce uniqueness for empty fields unless they're required
* Display the number of selected records on xxx2Many
Version 6.6.0 - 2022-10-31
......
......@@ -1651,7 +1651,9 @@
return true;
}
var invalid = false;
this.get_state_attrs(record).domain_readonly = false;
var state_attrs = this.get_strate_attrs(record);
Please register or sign in to reply
var is_required = Boolean(parseInt(state_attrs.required, 10));
state_attrs.domain_readonly = false;
var inversion = new Sao.common.DomainInversion();
var domain = inversion.simplify(this.validation_domains(record,
pre_validate));
......@@ -1667,7 +1669,9 @@
} else if (Sao.common.compare(domain, [['id', '=', null]])) {
invalid = 'domain';
} else {
let [screen_domain, _] = this.get_domains(
record, pre_validate);
var uniques = inversion.unique_value(domain);
var unique = uniques[0];
var leftpart = uniques[1];
var value = uniques[2];
......@@ -1670,8 +1674,14 @@
var uniques = inversion.unique_value(domain);
var unique = uniques[0];
var leftpart = uniques[1];
var value = uniques[2];
if (unique) {
let unique_from_screen = inversion.unique_value(
screen_domain)[0];
if (this._is_empty(record) &&
!is_required &&
!unique_from_screen) {
// Do nothing
} else if (unique) {
// If the inverted domain is so constraint that only one
// value is possible we should use it. But we must also pay
// attention to the fact that the original domain might be
......@@ -1706,8 +1716,7 @@
}
if (setdefault && !pre_validate) {
this.set_client(record, value);
this.get_state_attrs(record).domain_readonly =
domain_readonly;
state_attrs.domain_readonly = domain_readonly;
}
}
if (!inversion.eval_domain(domain,
......@@ -1715,7 +1724,7 @@
invalid = domain;
}
}
this.get_state_attrs(record).invalid = invalid;
state_attrs.invalid = invalid;
return !invalid;
}
});
......
* Do not validate domain and enforce uniqueness for empty fields unless they're required
* Display the number of selected records on xxx2Many
Version 6.6.0 - 2022-10-31
......
......@@ -95,4 +95,6 @@
def validate(self, record, softvalidation=False, pre_validate=None):
if self.attrs.get('readonly'):
return True
state_attrs = self.get_state_attrs(record)
is_required = bool(int(state_attrs.get('required') or 0))
invalid = False
......@@ -98,5 +100,5 @@
invalid = False
self.get_state_attrs(record)['domain_readonly'] = False
state_attrs['domain_readonly'] = False
domain = simplify(self.validation_domains(record, pre_validate))
if not softvalidation:
if not self.check_required(record):
......@@ -107,4 +109,5 @@
elif domain == [('id', '=', None)]:
invalid = 'domain'
else:
screen_domain, _ = self.domains_get(record, pre_validate)
unique, leftpart, value = unique_value(domain)
......@@ -110,5 +113,10 @@
unique, leftpart, value = unique_value(domain)
if unique:
unique_from_screen, _, _ = unique_value(screen_domain)
if (self._is_empty(record)
and not is_required
and not unique_from_screen):
pass
elif unique:
# If the inverted domain is so constraint that only one value
# is possible we should use it. But we must also pay attention
# to the fact that the original domain might be a 'OR' domain
......@@ -132,7 +140,6 @@
setdefault = False
if setdefault and not pre_validate:
self.set_client(record, value)
self.get_state_attrs(record)['domain_readonly'] = (
domain_readonly)
state_attrs['domain_readonly'] = domain_readonly
if not eval_domain(domain, EvalEnvironment(record)):
invalid = domain
......@@ -137,6 +144,6 @@
if not eval_domain(domain, EvalEnvironment(record)):
invalid = domain
self.get_state_attrs(record)['invalid'] = invalid
state_attrs['invalid'] = invalid
return not invalid
def set(self, record, value):
......
* Do not validate domain for empty fields
* Warn about implicit save() of unsaved relation
* Raise error message with record name and field in check_xml_record
* Cache RPC call for class method selection
......
......@@ -49,6 +49,8 @@
A :ref:`domain <topics-domain>` constraint that is applied on the field
value.
The domain is enforced unless the field value is ``None``.
.. note::
For :class:`Reference` field it is a dictionary that contains the domain
......
......@@ -1292,7 +1292,9 @@
relations.update(*(getattr(r, field.name) for r in records))
else:
# Cache alignment is not a problem
relations = set(records)
relations = {
r for r in records
if getattr(r, field.name) is not None}
relations.discard(None)
return relations
......
......@@ -194,6 +194,14 @@
'test.modelstorage.eval_environment', 'many2one', "One2Many")
class ModelStorageDomainNotRequired(ModelSQL):
"Model for domain on not required field"
__name__ = 'test.modelstorage.domain_not_required'
domain_not_required = fields.Integer(
"Domain Not Required", domain=[('domain_not_required', '>', 0)])
def register(module):
Pool.register(
ModelStorage,
......@@ -213,4 +221,5 @@
ModelStorageRelationDomain2,
ModelStorageRelationDomain2Target,
ModelStorageEvalEnvironment,
ModelStorageDomainNotRequired,
module=module, type_='model')
......@@ -582,6 +582,22 @@
cm.exception.domain[1]['relation2']['relation_fields']['value'])
@with_transaction()
def test_domain_not_required_validation(self):
"Test domain validation on not required"
pool = Pool()
Model = pool.get('test.modelstorage.domain_not_required')
Model.create([{'domain_not_required': None}])
@with_transaction()
def test_domain_not_required_invalid(self):
"Test invalid domain on not required"
pool = Pool()
Model = pool.get('test.modelstorage.domain_not_required')
with self.assertRaises(DomainValidationError):
Model.create([{'domain_not_required': 0}])
@with_transaction()
def test_check_xml_record_without_record(self):
"Test check_xml_record without record"
pool = Pool()
......
Supports Markdown
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