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:
Cédric Krier committed 2023-11-14 00:00:15 +01:00
1 parent ba7badec6e
commit e58a569f23
9 files changed
+33 -13

No files matched your search

+2 -2
View File
@@ -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
View File
@@ -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);
+3 -1
View File
@@ -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);
+1
View File
@@ -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', []]];
+4 -3
View File
@@ -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()):
+2
View File
@@ -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))
+3 -2
View File
@@ -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'):