Do not force value for single list on multi-value field
Fields based on multi-value must not be forced to the single value of a list. Closes #12737
This commit is contained in:
1 parent
ba7badec6e
commit
e58a569f23
9 files changed
+33
-13
No files matched your search
+2
-2
@@ -2755,12 +2755,12 @@
|
||||
}
|
||||
return this.simplify(this.merge(result));
|
||||
},
|
||||
unique_value: function(domain) {
|
||||
unique_value: function(domain, single_value=true) {
|
||||
if ((domain instanceof Array) &&
|
||||
(domain.length == 1)) {
|
||||
let [name, operator, value, ...model] = domain[0];
|
||||
if (operator == '=' ||
|
||||
(operator == 'in' && value.length == 1)) {
|
||||
(single_value && operator == 'in' && value.length == 1)) {
|
||||
value = operator == '=' ? value : value[0];
|
||||
var count = 0;
|
||||
if (model.length && name.endsWith('.id')) {
|
||||
|
||||
+7
-2
@@ -1556,6 +1556,7 @@
|
||||
|
||||
Sao.field.Field = Sao.class_(Object, {
|
||||
_default: null,
|
||||
_single_value: true,
|
||||
init: function(description) {
|
||||
this.description = description;
|
||||
this.name = description.name;
|
||||
@@ -1728,12 +1729,13 @@
|
||||
} else {
|
||||
let [screen_domain, _] = this.get_domains(
|
||||
record, pre_validate);
|
||||
var uniques = inversion.unique_value(domain);
|
||||
var uniques = inversion.unique_value(
|
||||
domain, this._single_value);
|
||||
var unique = uniques[0];
|
||||
var leftpart = uniques[1];
|
||||
var value = uniques[2];
|
||||
let unique_from_screen = inversion.unique_value(
|
||||
screen_domain)[0];
|
||||
screen_domain, this._single_value)[0];
|
||||
if (this._is_empty(record) &&
|
||||
!is_required &&
|
||||
!is_invisible &&
|
||||
@@ -1821,6 +1823,7 @@
|
||||
|
||||
Sao.field.MultiSelection = Sao.class_(Sao.field.Selection, {
|
||||
_default: null,
|
||||
_single_value: false,
|
||||
get: function(record) {
|
||||
var value = Sao.field.MultiSelection._super.get.call(this, record);
|
||||
if (jQuery.isEmptyObject(value)) {
|
||||
@@ -2203,6 +2206,7 @@
|
||||
Sao.field.One2Many._super.init.call(this, description);
|
||||
},
|
||||
_default: null,
|
||||
_single_value: false,
|
||||
_set_value: function(record, value, default_, modified) {
|
||||
this._set_default_value(record);
|
||||
var group = record._values[this.name];
|
||||
@@ -2813,6 +2817,7 @@
|
||||
|
||||
Sao.field.Dict = Sao.class_(Sao.field.Field, {
|
||||
_default: {},
|
||||
_single_value: false,
|
||||
init: function(description) {
|
||||
Sao.field.Dict._super.init.call(this, description);
|
||||
this.schema_model = new Sao.Model(description.schema_model);
|
||||
|
||||
@@ -879,11 +879,13 @@
|
||||
visible_columns -= 1;
|
||||
column.set_visible(false);
|
||||
} else {
|
||||
const field = this.screen.model.fields[name];
|
||||
var inv_domain = inversion.domain_inversion(domain, name);
|
||||
if (typeof inv_domain != 'boolean') {
|
||||
inv_domain = inversion.simplify(inv_domain);
|
||||
}
|
||||
var unique = inversion.unique_value(inv_domain)[0];
|
||||
var unique = inversion.unique_value(
|
||||
inv_domain, field._single_value)[0];
|
||||
if (unique && jQuery.isEmptyObject(this.children_field)) {
|
||||
visible_columns -= 1;
|
||||
column.set_visible(false);
|
||||
|
||||
@@ -2813,6 +2813,7 @@
|
||||
QUnit.ok(compare(unique_value(domain), [false, null, null]));
|
||||
domain = [['a', 'in', [1]]];
|
||||
QUnit.ok(compare(unique_value(domain), [true, 'a', 1]));
|
||||
QUnit.ok(compare(unique_value(domain, false), [false, null, null]));
|
||||
domain = [['a', 'in', [1, 2]]];
|
||||
QUnit.ok(compare(unique_value(domain), [false, null, null]));
|
||||
domain = [['a', 'in', []]];
|
||||
|
||||
@@ -424,13 +424,14 @@ def concat(*domains, **kwargs):
|
||||
return simplify(merge(result))
|
||||
|
||||
|
||||
def unique_value(domain):
|
||||
def unique_value(domain, single_value=True):
|
||||
"Return if unique, the field and the value"
|
||||
if (isinstance(domain, list)
|
||||
and len(domain) == 1):
|
||||
name, operator, value, *model = domain[0]
|
||||
if operator == '=' or (operator == 'in' and len(value) == 1):
|
||||
value = value if operator == '=' else value[0]
|
||||
if (operator == '='
|
||||
or (single_value and operator == 'in' and len(value) == 1)):
|
||||
value = value if operator == '=' and single_value else value[0]
|
||||
count = 0
|
||||
if model and name.endswith('.id'):
|
||||
count = 1
|
||||
|
||||
@@ -30,6 +30,7 @@ class Field(object):
|
||||
set_client: save the value from the widget
|
||||
'''
|
||||
_default = None
|
||||
_single_value = True
|
||||
|
||||
@staticmethod
|
||||
def get_field(ctype):
|
||||
@@ -111,8 +112,10 @@ class Field(object):
|
||||
invalid = 'domain'
|
||||
else:
|
||||
screen_domain, _ = self.domains_get(record, pre_validate)
|
||||
unique, leftpart, value = unique_value(domain)
|
||||
unique_from_screen, _, _ = unique_value(screen_domain)
|
||||
unique, leftpart, value = unique_value(
|
||||
domain, single_value=self._single_value)
|
||||
unique_from_screen, _, _ = unique_value(
|
||||
screen_domain, single_value=self._single_value)
|
||||
if (self._is_empty(record)
|
||||
and not is_required
|
||||
and not is_invisible
|
||||
@@ -248,6 +251,7 @@ class SelectionField(Field):
|
||||
class MultiSelectionField(SelectionField):
|
||||
|
||||
_default = None
|
||||
_single_value = False
|
||||
|
||||
def get(self, record):
|
||||
value = super().get(record)
|
||||
@@ -601,6 +605,7 @@ class O2MField(Field):
|
||||
'''
|
||||
|
||||
_default = None
|
||||
_single_value = False
|
||||
|
||||
def __init__(self, attrs):
|
||||
super(O2MField, self).__init__(attrs)
|
||||
@@ -1112,6 +1117,7 @@ class BinaryField(Field):
|
||||
class DictField(Field):
|
||||
|
||||
_default = {}
|
||||
_single_value = False
|
||||
|
||||
def __init__(self, attrs):
|
||||
super(DictField, self).__init__(attrs)
|
||||
|
||||
@@ -1132,10 +1132,12 @@ class ViewTree(View):
|
||||
elif name == self.screen.exclude_field:
|
||||
column.set_visible(False)
|
||||
else:
|
||||
field = self.group.fields.get(name)
|
||||
inv_domain = domain_inversion(domain, name)
|
||||
if not isinstance(inv_domain, bool):
|
||||
inv_domain = simplify(inv_domain)
|
||||
unique, _, _ = unique_value(inv_domain)
|
||||
unique, _, _ = unique_value(
|
||||
inv_domain, single_value=field._single_value)
|
||||
column.set_visible(not unique or bool(self.children_field))
|
||||
if self.children_field:
|
||||
for i, column in enumerate(self.treeview.get_columns()):
|
||||
|
||||
@@ -830,6 +830,8 @@ class DomainInversionTestCase(unittest.TestCase):
|
||||
|
||||
domain = [['a', 'in', [1]]]
|
||||
self.assertEqual(unique_value(domain), (True, 'a', 1))
|
||||
self.assertEqual(
|
||||
unique_value(domain, single_value=False), (False, None, None))
|
||||
|
||||
domain = [['a', 'in', [1, 2]]]
|
||||
self.assertEqual(unique_value(domain), (False, None, None))
|
||||
|
||||
@@ -424,12 +424,13 @@ def concat(*domains, **kwargs):
|
||||
return simplify(merge(result))
|
||||
|
||||
|
||||
def unique_value(domain):
|
||||
def unique_value(domain, single_value=True):
|
||||
"Return if unique, the field and the value"
|
||||
if (isinstance(domain, list)
|
||||
and len(domain) == 1):
|
||||
name, operator, value, *model = domain[0]
|
||||
if operator == '=' or (operator == 'in' and len(value) == 1):
|
||||
if (operator == '='
|
||||
or (single_value and operator == 'in' and len(value) == 1)):
|
||||
value = value if operator == '=' else value[0]
|
||||
count = 0
|
||||
if model and name.endswith('.id'):
|
||||
|
||||
Reference in new issue
Block a user